From ed4a6a7ca853253f9b86f3005d76345482a71283 Mon Sep 17 00:00:00 2001 From: Matt Roper Date: Tue, 23 Feb 2016 17:20:13 -0800 Subject: drm/i915: Add two-stage ILK-style watermark programming (v11) In addition to calculating final watermarks, let's also pre-calculate a set of intermediate watermark values at atomic check time. These intermediate watermarks are a combination of the watermarks for the old state and the new state; they should satisfy the requirements of both states which means they can be programmed immediately when we commit the atomic state (without waiting for a vblank). Once the vblank does happen, we can then re-program watermarks to the more optimal final value. v2: Significant rebasing/rewriting. v3: - Move 'need_postvbl_update' flag to CRTC state (Daniel) - Don't forget to check intermediate watermark values for validity (Maarten) - Don't due async watermark optimization; just do it at the end of the atomic transaction, after waiting for vblanks. We do want it to be async eventually, but adding that now will cause more trouble for Maarten's in-progress work. (Maarten) - Don't allocate space in crtc_state for intermediate watermarks on platforms that don't need it (gen9+). - Move WaCxSRDisabledForSpriteScaling:ivb into intel_begin_crtc_commit now that ilk_update_wm is gone. v4: - Add a wm_mutex to cover updates to intel_crtc->active and the need_postvbl_update flag. Since we don't have async yet it isn't terribly important yet, but might as well add it now. - Change interface to program watermarks. Platforms will now expose .initial_watermarks() and .optimize_watermarks() functions to do watermark programming. These should lock wm_mutex, copy the appropriate state values into intel_crtc->active, and then call the internal program watermarks function. v5: - Skip intermediate watermark calculation/check during initial hardware readout since we don't trust the existing HW values (and don't have valid values of our own yet). - Don't try to call .optimize_watermarks() on platforms that don't have atomic watermarks yet. (Maarten) v6: - Rebase v7: - Further rebase v8: - A few minor indentation and line length fixes v9: - Yet another rebase since Maarten's patches reworked a bunch of the code (wm_pre, wm_post, etc.) that this was previously based on. v10: - Move wm_mutex to dev_priv to protect against racing commits against disjoint CRTC sets. (Maarten) - Drop unnecessary clearing of cstate->wm.need_postvbl_update (Maarten) v11: - Now that we've moved to atomic watermark updates, make sure we call the proper function to program watermarks in {ironlake,haswell}_crtc_enable(); the failure to do so on the previous patch iteration led to us not actually programming the watermarks before turning on the CRTC, which was the cause of the underruns that the CI system was seeing. - Fix inverted logic for determining when to optimize watermarks. We were needlessly optimizing when the intermediate/optimal values were the same (harmless), but not actually optimizing when they differed (also harmless, but wasteful from a power/bandwidth perspective). Cc: Maarten Lankhorst Signed-off-by: Matt Roper Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1456276813-5689-1-git-send-email-matthew.d.roper@intel.com --- drivers/gpu/drm/i915/i915_dma.c | 1 + drivers/gpu/drm/i915/i915_drv.h | 13 ++- drivers/gpu/drm/i915/intel_atomic.c | 1 + drivers/gpu/drm/i915/intel_display.c | 97 +++++++++++++++++++-- drivers/gpu/drm/i915/intel_drv.h | 28 +++++- drivers/gpu/drm/i915/intel_pm.c | 162 ++++++++++++++++++++++++----------- 6 files changed, 244 insertions(+), 58 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 1c6d227aae7c..36c0cf131e93 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1010,6 +1010,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) mutex_init(&dev_priv->sb_lock); mutex_init(&dev_priv->modeset_restore_lock); mutex_init(&dev_priv->av_mutex); + mutex_init(&dev_priv->wm.wm_mutex); ret = i915_workqueues_init(dev_priv); if (ret < 0) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 10480939159c..671295523317 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -631,7 +631,11 @@ struct drm_i915_display_funcs { struct dpll *best_clock); int (*compute_pipe_wm)(struct intel_crtc *crtc, struct drm_atomic_state *state); - void (*program_watermarks)(struct intel_crtc_state *cstate); + int (*compute_intermediate_wm)(struct drm_device *dev, + struct intel_crtc *intel_crtc, + struct intel_crtc_state *newstate); + void (*initial_watermarks)(struct intel_crtc_state *cstate); + void (*optimize_watermarks)(struct intel_crtc_state *cstate); void (*update_wm)(struct drm_crtc *crtc); int (*modeset_calc_cdclk)(struct drm_atomic_state *state); void (*modeset_commit_cdclk)(struct drm_atomic_state *state); @@ -1980,6 +1984,13 @@ struct drm_i915_private { }; uint8_t max_level; + + /* + * Should be held around atomic WM register writing; also + * protects * intel_crtc->wm.active and + * cstate->wm.need_postvbl_update. + */ + struct mutex wm_mutex; } wm; struct i915_runtime_pm pm; diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c index 8e579a8505ac..6a661e796328 100644 --- a/drivers/gpu/drm/i915/intel_atomic.c +++ b/drivers/gpu/drm/i915/intel_atomic.c @@ -98,6 +98,7 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc) crtc_state->disable_cxsr = false; crtc_state->wm_changed = false; crtc_state->fb_changed = false; + crtc_state->wm.need_postvbl_update = false; return &crtc_state->base; } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8b7b8b64b008..79bf527e0a73 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4843,7 +4843,42 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state) intel_set_memory_cxsr(dev_priv, false); } - if (!needs_modeset(&pipe_config->base) && pipe_config->wm_changed) + /* + * IVB workaround: must disable low power watermarks for at least + * one frame before enabling scaling. LP watermarks can be re-enabled + * when scaling is disabled. + * + * WaCxSRDisabledForSpriteScaling:ivb + */ + if (pipe_config->disable_lp_wm) { + ilk_disable_lp_wm(dev); + intel_wait_for_vblank(dev, crtc->pipe); + } + + /* + * If we're doing a modeset, we're done. No need to do any pre-vblank + * watermark programming here. + */ + if (needs_modeset(&pipe_config->base)) + return; + + /* + * For platforms that support atomic watermarks, program the + * 'intermediate' watermarks immediately. On pre-gen9 platforms, these + * will be the intermediate values that are safe for both pre- and + * post- vblank; when vblank happens, the 'active' values will be set + * to the final 'target' values and we'll do this again to get the + * optimal watermarks. For gen9+ platforms, the values we program here + * will be the final target values which will get automatically latched + * at vblank time; no further programming will be necessary. + * + * If a platform hasn't been transitioned to atomic watermarks yet, + * we'll continue to update watermarks the old way, if flags tell + * us to. + */ + if (dev_priv->display.initial_watermarks != NULL) + dev_priv->display.initial_watermarks(pipe_config); + else if (pipe_config->wm_changed) intel_update_watermarks(&crtc->base); } @@ -4922,7 +4957,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) */ intel_crtc_load_lut(crtc); - intel_update_watermarks(crtc); + dev_priv->display.initial_watermarks(intel_crtc->config); intel_enable_pipe(intel_crtc); if (intel_crtc->config->has_pch_encoder) @@ -5021,7 +5056,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) if (!intel_crtc->config->has_dsi_encoder) intel_ddi_enable_transcoder_func(crtc); - intel_update_watermarks(crtc); + dev_priv->display.initial_watermarks(pipe_config); intel_enable_pipe(intel_crtc); if (intel_crtc->config->has_pch_encoder) @@ -11785,6 +11820,7 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state, struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct drm_plane *plane = plane_state->plane; struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_plane_state *old_plane_state = to_intel_plane_state(plane->state); int idx = intel_crtc->base.base.id, ret; @@ -11843,6 +11879,11 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state, pipe_config->wm_changed = true; } + /* Pre-gen9 platforms need two-step watermark updates */ + if (pipe_config->wm_changed && INTEL_INFO(dev)->gen < 9 && + dev_priv->display.optimize_watermarks) + to_intel_crtc_state(crtc_state)->wm.need_postvbl_update = true; + if (visible || was_visible) intel_crtc->atomic.fb_bits |= to_intel_plane(plane)->frontbuffer_bit; @@ -11954,8 +11995,29 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc, ret = 0; if (dev_priv->display.compute_pipe_wm) { ret = dev_priv->display.compute_pipe_wm(intel_crtc, state); - if (ret) + if (ret) { + DRM_DEBUG_KMS("Target pipe watermarks are invalid\n"); + return ret; + } + } + + if (dev_priv->display.compute_intermediate_wm && + !to_intel_atomic_state(state)->skip_intermediate_wm) { + if (WARN_ON(!dev_priv->display.compute_pipe_wm)) + return 0; + + /* + * Calculate 'intermediate' watermarks that satisfy both the + * old state and the new state. We can program these + * immediately. + */ + ret = dev_priv->display.compute_intermediate_wm(crtc->dev, + intel_crtc, + pipe_config); + if (ret) { + DRM_DEBUG_KMS("No valid intermediate pipe watermarks are possible\n"); return ret; + } } if (INTEL_INFO(dev)->gen >= 9) { @@ -13488,6 +13550,7 @@ static int intel_atomic_commit(struct drm_device *dev, struct drm_i915_private *dev_priv = dev->dev_private; struct drm_crtc_state *crtc_state; struct drm_crtc *crtc; + struct intel_crtc_state *intel_cstate; int ret = 0, i; bool hw_check = intel_state->modeset; unsigned long put_domains[I915_MAX_PIPES] = {}; @@ -13603,6 +13666,20 @@ static int intel_atomic_commit(struct drm_device *dev, if (intel_state->modeset) intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET); + /* + * Now that the vblank has passed, we can go ahead and program the + * optimal watermarks on platforms that need two-step watermark + * programming. + * + * TODO: Move this (and other cleanup) to an async worker eventually. + */ + for_each_crtc_in_state(state, crtc, crtc_state, i) { + intel_cstate = to_intel_crtc_state(crtc->state); + + if (dev_priv->display.optimize_watermarks) + dev_priv->display.optimize_watermarks(intel_cstate); + } + mutex_lock(&dev->struct_mutex); drm_atomic_helper_cleanup_planes(dev, state); mutex_unlock(&dev->struct_mutex); @@ -15273,7 +15350,7 @@ static void sanitize_watermarks(struct drm_device *dev) int i; /* Only supported on platforms that use atomic watermark design */ - if (!dev_priv->display.program_watermarks) + if (!dev_priv->display.optimize_watermarks) return; /* @@ -15294,6 +15371,13 @@ retry: if (WARN_ON(IS_ERR(state))) goto fail; + /* + * Hardware readout is the only time we don't want to calculate + * intermediate watermarks (since we don't trust the current + * watermarks). + */ + to_intel_atomic_state(state)->skip_intermediate_wm = true; + ret = intel_atomic_check(dev, state); if (ret) { /* @@ -15316,7 +15400,8 @@ retry: for_each_crtc_in_state(state, crtc, cstate, i) { struct intel_crtc_state *cs = to_intel_crtc_state(cstate); - dev_priv->display.program_watermarks(cs); + cs->wm.need_postvbl_update = true; + dev_priv->display.optimize_watermarks(cs); } drm_atomic_state_free(state); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 4c027d69fac9..5daf53c080e1 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -260,6 +260,12 @@ struct intel_atomic_state { struct intel_shared_dpll_config shared_dpll[I915_NUM_PLLS]; struct intel_wm_config wm_config; + + /* + * Current watermarks can't be trusted during hardware readout, so + * don't bother calculating intermediate watermarks. + */ + bool skip_intermediate_wm; }; struct intel_plane_state { @@ -510,13 +516,29 @@ struct intel_crtc_state { struct { /* - * optimal watermarks, programmed post-vblank when this state - * is committed + * Optimal watermarks, programmed post-vblank when this state + * is committed. */ union { struct intel_pipe_wm ilk; struct skl_pipe_wm skl; } optimal; + + /* + * Intermediate watermarks; these can be programmed immediately + * since they satisfy both the current configuration we're + * switching away from and the new configuration we're switching + * to. + */ + struct intel_pipe_wm intermediate; + + /* + * Platforms with two-step watermark programming will need to + * update watermark programming post-vblank to switch from the + * safe intermediate watermarks to the optimal final + * watermarks. + */ + bool need_postvbl_update; } wm; }; @@ -600,6 +622,7 @@ struct intel_crtc { struct intel_pipe_wm ilk; struct skl_pipe_wm skl; } active; + /* allow CxSR on this pipe */ bool cxsr_allowed; } wm; @@ -1565,6 +1588,7 @@ void skl_wm_get_hw_state(struct drm_device *dev); void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv, struct skl_ddb_allocation *ddb /* out */); uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config); +bool ilk_disable_lp_wm(struct drm_device *dev); int sanitize_rc6_option(const struct drm_device *dev, int enable_rc6); /* intel_sdvo.c */ diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 347d4df49a9b..ccdb5819134a 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2278,6 +2278,29 @@ static void skl_setup_wm_latency(struct drm_device *dev) intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency); } +static bool ilk_validate_pipe_wm(struct drm_device *dev, + struct intel_pipe_wm *pipe_wm) +{ + /* LP0 watermark maximums depend on this pipe alone */ + const struct intel_wm_config config = { + .num_pipes_active = 1, + .sprites_enabled = pipe_wm->sprites_enabled, + .sprites_scaled = pipe_wm->sprites_scaled, + }; + struct ilk_wm_maximums max; + + /* LP0 watermarks always use 1/2 DDB partitioning */ + ilk_compute_wm_maximums(dev, 0, &config, INTEL_DDB_PART_1_2, &max); + + /* At least LP0 must be valid */ + if (!ilk_validate_wm_level(0, &max, &pipe_wm->wm[0])) { + DRM_DEBUG_KMS("LP0 watermark invalid\n"); + return false; + } + + return true; +} + /* Compute new watermarks for the pipe */ static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc, struct drm_atomic_state *state) @@ -2292,10 +2315,6 @@ static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc, struct intel_plane_state *sprstate = NULL; struct intel_plane_state *curstate = NULL; int level, max_level = ilk_wm_max_level(dev); - /* LP0 watermark maximums depend on this pipe alone */ - struct intel_wm_config config = { - .num_pipes_active = 1, - }; struct ilk_wm_maximums max; cstate = intel_atomic_get_crtc_state(state, intel_crtc); @@ -2319,21 +2338,18 @@ static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc, curstate = to_intel_plane_state(ps); } - config.sprites_enabled = sprstate->visible; - config.sprites_scaled = sprstate->visible && + pipe_wm->pipe_enabled = cstate->base.active; + pipe_wm->sprites_enabled = sprstate->visible; + pipe_wm->sprites_scaled = sprstate->visible && (drm_rect_width(&sprstate->dst) != drm_rect_width(&sprstate->src) >> 16 || drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16); - pipe_wm->pipe_enabled = cstate->base.active; - pipe_wm->sprites_enabled = config.sprites_enabled; - pipe_wm->sprites_scaled = config.sprites_scaled; - /* ILK/SNB: LP2+ watermarks only w/o sprites */ if (INTEL_INFO(dev)->gen <= 6 && sprstate->visible) max_level = 1; /* ILK/SNB/IVB: LP1+ watermarks only w/o scaling */ - if (config.sprites_scaled) + if (pipe_wm->sprites_scaled) max_level = 0; ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate, @@ -2342,12 +2358,8 @@ static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc, if (IS_HASWELL(dev) || IS_BROADWELL(dev)) pipe_wm->linetime = hsw_compute_linetime_wm(dev, cstate); - /* LP0 watermarks always use 1/2 DDB partitioning */ - ilk_compute_wm_maximums(dev, 0, &config, INTEL_DDB_PART_1_2, &max); - - /* At least LP0 must be valid */ - if (!ilk_validate_wm_level(0, &max, &pipe_wm->wm[0])) - return -EINVAL; + if (!ilk_validate_pipe_wm(dev, pipe_wm)) + return false; ilk_compute_wm_reg_maximums(dev, 1, &max); @@ -2371,6 +2383,59 @@ static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc, return 0; } +/* + * Build a set of 'intermediate' watermark values that satisfy both the old + * state and the new state. These can be programmed to the hardware + * immediately. + */ +static int ilk_compute_intermediate_wm(struct drm_device *dev, + struct intel_crtc *intel_crtc, + struct intel_crtc_state *newstate) +{ + struct intel_pipe_wm *a = &newstate->wm.intermediate; + struct intel_pipe_wm *b = &intel_crtc->wm.active.ilk; + int level, max_level = ilk_wm_max_level(dev); + + /* + * Start with the final, target watermarks, then combine with the + * currently active watermarks to get values that are safe both before + * and after the vblank. + */ + *a = newstate->wm.optimal.ilk; + a->pipe_enabled |= b->pipe_enabled; + a->sprites_enabled |= b->sprites_enabled; + a->sprites_scaled |= b->sprites_scaled; + + for (level = 0; level <= max_level; level++) { + struct intel_wm_level *a_wm = &a->wm[level]; + const struct intel_wm_level *b_wm = &b->wm[level]; + + a_wm->enable &= b_wm->enable; + a_wm->pri_val = max(a_wm->pri_val, b_wm->pri_val); + a_wm->spr_val = max(a_wm->spr_val, b_wm->spr_val); + a_wm->cur_val = max(a_wm->cur_val, b_wm->cur_val); + a_wm->fbc_val = max(a_wm->fbc_val, b_wm->fbc_val); + } + + /* + * We need to make sure that these merged watermark values are + * actually a valid configuration themselves. If they're not, + * there's no safe way to transition from the old state to + * the new state, so we need to fail the atomic transaction. + */ + if (!ilk_validate_pipe_wm(dev, a)) + return -EINVAL; + + /* + * If our intermediate WM are identical to the final WM, then we can + * omit the post-vblank programming; only update if it's different. + */ + if (memcmp(a, &newstate->wm.optimal.ilk, sizeof(*a)) == 0) + newstate->wm.need_postvbl_update = false; + + return 0; +} + /* * Merge the watermarks from all active pipes for a specific level. */ @@ -2383,9 +2448,7 @@ static void ilk_merge_wm_level(struct drm_device *dev, ret_wm->enable = true; for_each_intel_crtc(dev, intel_crtc) { - const struct intel_crtc_state *cstate = - to_intel_crtc_state(intel_crtc->base.state); - const struct intel_pipe_wm *active = &cstate->wm.optimal.ilk; + const struct intel_pipe_wm *active = &intel_crtc->wm.active.ilk; const struct intel_wm_level *wm = &active->wm[level]; if (!active->pipe_enabled) @@ -2533,15 +2596,14 @@ static void ilk_compute_wm_results(struct drm_device *dev, /* LP0 register values */ for_each_intel_crtc(dev, intel_crtc) { - const struct intel_crtc_state *cstate = - to_intel_crtc_state(intel_crtc->base.state); enum pipe pipe = intel_crtc->pipe; - const struct intel_wm_level *r = &cstate->wm.optimal.ilk.wm[0]; + const struct intel_wm_level *r = + &intel_crtc->wm.active.ilk.wm[0]; if (WARN_ON(!r->enable)) continue; - results->wm_linetime[pipe] = cstate->wm.optimal.ilk.linetime; + results->wm_linetime[pipe] = intel_crtc->wm.active.ilk.linetime; results->wm_pipe[pipe] = (r->pri_val << WM0_PIPE_PLANE_SHIFT) | @@ -2748,7 +2810,7 @@ static void ilk_write_wm_values(struct drm_i915_private *dev_priv, dev_priv->wm.hw = *results; } -static bool ilk_disable_lp_wm(struct drm_device *dev) +bool ilk_disable_lp_wm(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -3643,11 +3705,9 @@ static void ilk_compute_wm_config(struct drm_device *dev, } } -static void ilk_program_watermarks(struct intel_crtc_state *cstate) +static void ilk_program_watermarks(struct drm_i915_private *dev_priv) { - struct drm_crtc *crtc = cstate->base.crtc; - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct drm_device *dev = dev_priv->dev; struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm; struct ilk_wm_maximums max; struct intel_wm_config config = {}; @@ -3678,28 +3738,28 @@ static void ilk_program_watermarks(struct intel_crtc_state *cstate) ilk_write_wm_values(dev_priv, &results); } -static void ilk_update_wm(struct drm_crtc *crtc) +static void ilk_initial_watermarks(struct intel_crtc_state *cstate) { - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); - - WARN_ON(cstate->base.active != intel_crtc->active); + struct drm_i915_private *dev_priv = to_i915(cstate->base.crtc->dev); + struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); - /* - * IVB workaround: must disable low power watermarks for at least - * one frame before enabling scaling. LP watermarks can be re-enabled - * when scaling is disabled. - * - * WaCxSRDisabledForSpriteScaling:ivb - */ - if (cstate->disable_lp_wm) { - ilk_disable_lp_wm(crtc->dev); - intel_wait_for_vblank(crtc->dev, intel_crtc->pipe); - } + mutex_lock(&dev_priv->wm.wm_mutex); + intel_crtc->wm.active.ilk = cstate->wm.intermediate; + ilk_program_watermarks(dev_priv); + mutex_unlock(&dev_priv->wm.wm_mutex); +} - intel_crtc->wm.active.ilk = cstate->wm.optimal.ilk; +static void ilk_optimize_watermarks(struct intel_crtc_state *cstate) +{ + struct drm_i915_private *dev_priv = to_i915(cstate->base.crtc->dev); + struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); - ilk_program_watermarks(cstate); + mutex_lock(&dev_priv->wm.wm_mutex); + if (cstate->wm.need_postvbl_update) { + intel_crtc->wm.active.ilk = cstate->wm.optimal.ilk; + ilk_program_watermarks(dev_priv); + } + mutex_unlock(&dev_priv->wm.wm_mutex); } static void skl_pipe_wm_active_state(uint32_t val, @@ -7076,9 +7136,13 @@ void intel_init_pm(struct drm_device *dev) dev_priv->wm.spr_latency[1] && dev_priv->wm.cur_latency[1]) || (!IS_GEN5(dev) && dev_priv->wm.pri_latency[0] && dev_priv->wm.spr_latency[0] && dev_priv->wm.cur_latency[0])) { - dev_priv->display.update_wm = ilk_update_wm; dev_priv->display.compute_pipe_wm = ilk_compute_pipe_wm; - dev_priv->display.program_watermarks = ilk_program_watermarks; + dev_priv->display.compute_intermediate_wm = + ilk_compute_intermediate_wm; + dev_priv->display.initial_watermarks = + ilk_initial_watermarks; + dev_priv->display.optimize_watermarks = + ilk_optimize_watermarks; } else { DRM_DEBUG_KMS("Failed to read display plane latency. " "Disable CxSR\n"); -- cgit v1.2.3 From c3454d575da162cd310d9b83696baefb29d10a70 Mon Sep 17 00:00:00 2001 From: Eric Engestrom Date: Mon, 29 Feb 2016 16:24:06 +0000 Subject: drm/i915: remove left over dead code ae80152ddad252f33893b92dd69f00cc53c5949f ("drm/i915: Rewrite VLV/CHV watermark code") removed everything that would have used those vars. Signed-off-by: Eric Engestrom Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1456763047-28828-1-git-send-email-eric.engestrom@imgtec.com --- drivers/gpu/drm/i915/intel_pm.c | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index ccdb5819134a..d33de954a2e4 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -487,20 +487,6 @@ static const struct intel_watermark_params g4x_cursor_wm_info = { .guard_size = 2, .cacheline_size = G4X_FIFO_LINE_SIZE, }; -static const struct intel_watermark_params valleyview_wm_info = { - .fifo_size = VALLEYVIEW_FIFO_SIZE, - .max_wm = VALLEYVIEW_MAX_WM, - .default_wm = VALLEYVIEW_MAX_WM, - .guard_size = 2, - .cacheline_size = G4X_FIFO_LINE_SIZE, -}; -static const struct intel_watermark_params valleyview_cursor_wm_info = { - .fifo_size = I965_CURSOR_FIFO, - .max_wm = VALLEYVIEW_CURSOR_MAX_WM, - .default_wm = I965_CURSOR_DFT_WM, - .guard_size = 2, - .cacheline_size = G4X_FIFO_LINE_SIZE, -}; static const struct intel_watermark_params i965_cursor_wm_info = { .fifo_size = I965_CURSOR_FIFO, .max_wm = I965_CURSOR_MAX_WM, -- cgit v1.2.3 From d9f8e52b22454a30aaaf26b7ef029598b30abf8e Mon Sep 17 00:00:00 2001 From: Eric Engestrom Date: Mon, 29 Feb 2016 16:24:07 +0000 Subject: drm/i915: remove dead code 79e539453b34e35f39299a899d263b0a1f1670bd ("DRM: i915: add mode setting support") added those variables but never used them. Signed-off-by: Eric Engestrom Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1456763047-28828-2-git-send-email-eric.engestrom@imgtec.com --- drivers/gpu/drm/i915/intel_tv.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 6745bad5bff0..d5570c859009 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -326,24 +326,12 @@ static const struct color_conversion sdtv_csc_yprpb = { .rv = 0x0100, .gv = 0x03ad, .bv = 0x074d, .av = 0x0200, }; -static const struct color_conversion sdtv_csc_rgb = { - .ry = 0x0000, .gy = 0x0f00, .by = 0x0000, .ay = 0x0166, - .ru = 0x0000, .gu = 0x0000, .bu = 0x0f00, .au = 0x0166, - .rv = 0x0f00, .gv = 0x0000, .bv = 0x0000, .av = 0x0166, -}; - static const struct color_conversion hdtv_csc_yprpb = { .ry = 0x05b3, .gy = 0x016e, .by = 0x0728, .ay = 0x0145, .ru = 0x07d5, .gu = 0x038b, .bu = 0x0100, .au = 0x0200, .rv = 0x0100, .gv = 0x03d1, .bv = 0x06bc, .av = 0x0200, }; -static const struct color_conversion hdtv_csc_rgb = { - .ry = 0x0000, .gy = 0x0f00, .by = 0x0000, .ay = 0x0166, - .ru = 0x0000, .gu = 0x0000, .bu = 0x0f00, .au = 0x0166, - .rv = 0x0f00, .gv = 0x0000, .bv = 0x0000, .av = 0x0166, -}; - static const struct video_levels component_levels = { .blank = 279, .black = 279, .burst = 0, }; -- cgit v1.2.3 From 3ba86073edcbe2be53d9862d5a3098f0ebf8ae9a Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Mon, 29 Feb 2016 09:18:57 +0100 Subject: drm/i915: Handle -EDEADLK in drm_atomic_commit from load-detect. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CI runs with DEBUG_WW_MUTEX_SLOWPATH, so -EDEADLK occurs a lot more. Handle the case where drm_atomic_commit fails with -EDEADLK correctly. Signed-off-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/56D3FEF1.6070306@linux.intel.com Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_display.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 79bf527e0a73..c803690293d7 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10577,7 +10577,8 @@ found: goto fail; } - if (drm_atomic_commit(state)) { + ret = drm_atomic_commit(state); + if (ret) { DRM_DEBUG_KMS("failed to set mode on load-detect pipe\n"); goto fail; } -- cgit v1.2.3 From c6a2ac712d7dee13c13e44c4c4184478853dcb37 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Fri, 26 Feb 2016 16:58:32 +0000 Subject: drm/i915: Execlists small cleanups and micro-optimisations Assorted changes in the areas of code cleanup, reduction of invariant conditional in the interrupt handler and lock contention and MMIO access optimisation. * Remove needless initialization. * Improve cache locality by reorganizing code and/or using branch hints to keep unexpected or error conditions out of line. * Favor busy submit path vs. empty queue. * Less branching in hot-paths. v2: * Avoid mmio reads when possible. (Chris Wilson) * Use natural integer size for csb indices. * Remove useless return value from execlists_update_context. * Extract 32-bit ppgtt PDPs update so it is out of line and shared with two callers. * Grab forcewake across all mmio operations to ease the load on uncore lock and use chepear mmio ops. v3: * Removed some more pointless u8 data types. * Removed unused return from execlists_context_queue. * Commit message updates. v4: * Unclumsify the unqueue if statement. (Chris Wilson) * Hide forcewake from the queuing function. (Chris Wilson) Version 3 now makes the irq handling code path ~20% smaller on 48-bit PPGTT hardware, and a little bit less elsewhere. Hot paths are mostly in-line now and hammering on the uncore spinlock is greatly reduced together with mmio traffic to an extent. Benchmarking with "gem_latency -n 100" (keep submitting batches with 100 nop instruction) shows approximately 4% higher throughput, 2% less CPU time and 22% smaller latencies. This was on a big-core while small-cores could benefit even more. Most likely reason for the improvements are the MMIO optimization and uncore lock traffic reduction. One odd result is with "gem_latency -n 0" (dispatching empty batches) which shows 5% more throughput, 8% less CPU time, 25% better producer and consumer latencies, but 15% higher dispatch latency which is yet unexplained. Signed-off-by: Tvrtko Ursulin Cc: Chris Wilson Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1456505912-22286-1-git-send-email-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/intel_lrc.c | 214 +++++++++++++++++--------------- drivers/gpu/drm/i915/intel_ringbuffer.h | 3 +- 2 files changed, 114 insertions(+), 103 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 6a978ce80244..27c9ee3f7372 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -270,6 +270,9 @@ logical_ring_init_platform_invariants(struct intel_engine_cs *ring) { struct drm_device *dev = ring->dev; + if (IS_GEN8(dev) || IS_GEN9(dev)) + ring->idle_lite_restore_wa = ~0; + ring->disable_lite_restore_wa = (IS_SKL_REVID(dev, 0, SKL_REVID_B0) || IS_BXT_REVID(dev, 0, BXT_REVID_A1)) && (ring->id == VCS || ring->id == VCS2); @@ -373,8 +376,6 @@ static void execlists_elsp_write(struct drm_i915_gem_request *rq0, rq0->elsp_submitted++; /* You must always write both descriptors in the order below. */ - spin_lock(&dev_priv->uncore.lock); - intel_uncore_forcewake_get__locked(dev_priv, FORCEWAKE_ALL); I915_WRITE_FW(RING_ELSP(ring), upper_32_bits(desc[1])); I915_WRITE_FW(RING_ELSP(ring), lower_32_bits(desc[1])); @@ -384,11 +385,18 @@ static void execlists_elsp_write(struct drm_i915_gem_request *rq0, /* ELSP is a wo register, use another nearby reg for posting */ POSTING_READ_FW(RING_EXECLIST_STATUS_LO(ring)); - intel_uncore_forcewake_put__locked(dev_priv, FORCEWAKE_ALL); - spin_unlock(&dev_priv->uncore.lock); } -static int execlists_update_context(struct drm_i915_gem_request *rq) +static void +execlists_update_context_pdps(struct i915_hw_ppgtt *ppgtt, u32 *reg_state) +{ + ASSIGN_CTX_PDP(ppgtt, reg_state, 3); + ASSIGN_CTX_PDP(ppgtt, reg_state, 2); + ASSIGN_CTX_PDP(ppgtt, reg_state, 1); + ASSIGN_CTX_PDP(ppgtt, reg_state, 0); +} + +static void execlists_update_context(struct drm_i915_gem_request *rq) { struct intel_engine_cs *ring = rq->ring; struct i915_hw_ppgtt *ppgtt = rq->ctx->ppgtt; @@ -396,19 +404,13 @@ static int execlists_update_context(struct drm_i915_gem_request *rq) reg_state[CTX_RING_TAIL+1] = rq->tail; - if (ppgtt && !USES_FULL_48BIT_PPGTT(ppgtt->base.dev)) { - /* True 32b PPGTT with dynamic page allocation: update PDP - * registers and point the unallocated PDPs to scratch page. - * PML4 is allocated during ppgtt init, so this is not needed - * in 48-bit mode. - */ - ASSIGN_CTX_PDP(ppgtt, reg_state, 3); - ASSIGN_CTX_PDP(ppgtt, reg_state, 2); - ASSIGN_CTX_PDP(ppgtt, reg_state, 1); - ASSIGN_CTX_PDP(ppgtt, reg_state, 0); - } - - return 0; + /* True 32b PPGTT with dynamic page allocation: update PDP + * registers and point the unallocated PDPs to scratch page. + * PML4 is allocated during ppgtt init, so this is not needed + * in 48-bit mode. + */ + if (ppgtt && !USES_FULL_48BIT_PPGTT(ppgtt->base.dev)) + execlists_update_context_pdps(ppgtt, reg_state); } static void execlists_submit_requests(struct drm_i915_gem_request *rq0, @@ -422,10 +424,10 @@ static void execlists_submit_requests(struct drm_i915_gem_request *rq0, execlists_elsp_write(rq0, rq1); } -static void execlists_context_unqueue(struct intel_engine_cs *ring) +static void execlists_context_unqueue__locked(struct intel_engine_cs *ring) { struct drm_i915_gem_request *req0 = NULL, *req1 = NULL; - struct drm_i915_gem_request *cursor = NULL, *tmp = NULL; + struct drm_i915_gem_request *cursor, *tmp; assert_spin_locked(&ring->execlist_lock); @@ -435,9 +437,6 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring) */ WARN_ON(!intel_irqs_enabled(ring->dev->dev_private)); - if (list_empty(&ring->execlist_queue)) - return; - /* Try to read in pairs */ list_for_each_entry_safe(cursor, tmp, &ring->execlist_queue, execlist_link) { @@ -452,37 +451,48 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring) req0 = cursor; } else { req1 = cursor; + WARN_ON(req1->elsp_submitted); break; } } - if (IS_GEN8(ring->dev) || IS_GEN9(ring->dev)) { + if (unlikely(!req0)) + return; + + if (req0->elsp_submitted & ring->idle_lite_restore_wa) { /* - * WaIdleLiteRestore: make sure we never cause a lite - * restore with HEAD==TAIL + * WaIdleLiteRestore: make sure we never cause a lite restore + * with HEAD==TAIL. + * + * Apply the wa NOOPS to prevent ring:HEAD == req:TAIL as we + * resubmit the request. See gen8_emit_request() for where we + * prepare the padding after the end of the request. */ - if (req0->elsp_submitted) { - /* - * Apply the wa NOOPS to prevent ring:HEAD == req:TAIL - * as we resubmit the request. See gen8_emit_request() - * for where we prepare the padding after the end of the - * request. - */ - struct intel_ringbuffer *ringbuf; + struct intel_ringbuffer *ringbuf; - ringbuf = req0->ctx->engine[ring->id].ringbuf; - req0->tail += 8; - req0->tail &= ringbuf->size - 1; - } + ringbuf = req0->ctx->engine[ring->id].ringbuf; + req0->tail += 8; + req0->tail &= ringbuf->size - 1; } - WARN_ON(req1 && req1->elsp_submitted); - execlists_submit_requests(req0, req1); } -static bool execlists_check_remove_request(struct intel_engine_cs *ring, - u32 request_id) +static void execlists_context_unqueue(struct intel_engine_cs *ring) +{ + struct drm_i915_private *dev_priv = ring->dev->dev_private; + + spin_lock(&dev_priv->uncore.lock); + intel_uncore_forcewake_get__locked(dev_priv, FORCEWAKE_ALL); + + execlists_context_unqueue__locked(ring); + + intel_uncore_forcewake_put__locked(dev_priv, FORCEWAKE_ALL); + spin_unlock(&dev_priv->uncore.lock); +} + +static unsigned int +execlists_check_remove_request(struct intel_engine_cs *ring, u32 request_id) { struct drm_i915_gem_request *head_req; @@ -492,33 +502,41 @@ static bool execlists_check_remove_request(struct intel_engine_cs *ring, struct drm_i915_gem_request, execlist_link); - if (head_req != NULL) { - if (intel_execlists_ctx_id(head_req->ctx, ring) == request_id) { - WARN(head_req->elsp_submitted == 0, - "Never submitted head request\n"); + if (!head_req) + return 0; - if (--head_req->elsp_submitted <= 0) { - list_move_tail(&head_req->execlist_link, - &ring->execlist_retired_req_list); - return true; - } - } - } + if (unlikely(intel_execlists_ctx_id(head_req->ctx, ring) != request_id)) + return 0; + + WARN(head_req->elsp_submitted == 0, "Never submitted head request\n"); + + if (--head_req->elsp_submitted > 0) + return 0; + + list_move_tail(&head_req->execlist_link, + &ring->execlist_retired_req_list); - return false; + return 1; } -static void get_context_status(struct intel_engine_cs *ring, - u8 read_pointer, - u32 *status, u32 *context_id) +static u32 +get_context_status(struct intel_engine_cs *ring, unsigned int read_pointer, + u32 *context_id) { struct drm_i915_private *dev_priv = ring->dev->dev_private; + u32 status; - if (WARN_ON(read_pointer >= GEN8_CSB_ENTRIES)) - return; + read_pointer %= GEN8_CSB_ENTRIES; + + status = I915_READ_FW(RING_CONTEXT_STATUS_BUF_LO(ring, read_pointer)); + + if (status & GEN8_CTX_STATUS_IDLE_ACTIVE) + return 0; - *status = I915_READ(RING_CONTEXT_STATUS_BUF_LO(ring, read_pointer)); - *context_id = I915_READ(RING_CONTEXT_STATUS_BUF_HI(ring, read_pointer)); + *context_id = I915_READ_FW(RING_CONTEXT_STATUS_BUF_HI(ring, + read_pointer)); + + return status; } /** @@ -532,30 +550,27 @@ void intel_lrc_irq_handler(struct intel_engine_cs *ring) { struct drm_i915_private *dev_priv = ring->dev->dev_private; u32 status_pointer; - u8 read_pointer; - u8 write_pointer; + unsigned int read_pointer, write_pointer; u32 status = 0; u32 status_id; - u32 submit_contexts = 0; + unsigned int submit_contexts = 0; + + spin_lock(&ring->execlist_lock); - status_pointer = I915_READ(RING_CONTEXT_STATUS_PTR(ring)); + spin_lock(&dev_priv->uncore.lock); + intel_uncore_forcewake_get__locked(dev_priv, FORCEWAKE_ALL); + + status_pointer = I915_READ_FW(RING_CONTEXT_STATUS_PTR(ring)); read_pointer = ring->next_context_status_buffer; write_pointer = GEN8_CSB_WRITE_PTR(status_pointer); if (read_pointer > write_pointer) write_pointer += GEN8_CSB_ENTRIES; - spin_lock(&ring->execlist_lock); - while (read_pointer < write_pointer) { + status = get_context_status(ring, ++read_pointer, &status_id); - get_context_status(ring, ++read_pointer % GEN8_CSB_ENTRIES, - &status, &status_id); - - if (status & GEN8_CTX_STATUS_IDLE_ACTIVE) - continue; - - if (status & GEN8_CTX_STATUS_PREEMPTED) { + if (unlikely(status & GEN8_CTX_STATUS_PREEMPTED)) { if (status & GEN8_CTX_STATUS_LITE_RESTORE) { if (execlists_check_remove_request(ring, status_id)) WARN(1, "Lite Restored request removed from queue\n"); @@ -563,37 +578,36 @@ void intel_lrc_irq_handler(struct intel_engine_cs *ring) WARN(1, "Preemption without Lite Restore\n"); } - if ((status & GEN8_CTX_STATUS_ACTIVE_IDLE) || - (status & GEN8_CTX_STATUS_ELEMENT_SWITCH)) { - if (execlists_check_remove_request(ring, status_id)) - submit_contexts++; - } + if (status & (GEN8_CTX_STATUS_ACTIVE_IDLE | + GEN8_CTX_STATUS_ELEMENT_SWITCH)) + submit_contexts += + execlists_check_remove_request(ring, status_id); } - if (ring->disable_lite_restore_wa) { - /* Prevent a ctx to preempt itself */ - if ((status & GEN8_CTX_STATUS_ACTIVE_IDLE) && - (submit_contexts != 0)) - execlists_context_unqueue(ring); - } else if (submit_contexts != 0) { - execlists_context_unqueue(ring); + if (submit_contexts) { + if (!ring->disable_lite_restore_wa || + (status & GEN8_CTX_STATUS_ACTIVE_IDLE)) + execlists_context_unqueue__locked(ring); } - spin_unlock(&ring->execlist_lock); - - if (unlikely(submit_contexts > 2)) - DRM_ERROR("More than two context complete events?\n"); - ring->next_context_status_buffer = write_pointer % GEN8_CSB_ENTRIES; /* Update the read pointer to the old write pointer. Manual ringbuffer * management ftw */ - I915_WRITE(RING_CONTEXT_STATUS_PTR(ring), - _MASKED_FIELD(GEN8_CSB_READ_PTR_MASK, - ring->next_context_status_buffer << 8)); + I915_WRITE_FW(RING_CONTEXT_STATUS_PTR(ring), + _MASKED_FIELD(GEN8_CSB_READ_PTR_MASK, + ring->next_context_status_buffer << 8)); + + intel_uncore_forcewake_put__locked(dev_priv, FORCEWAKE_ALL); + spin_unlock(&dev_priv->uncore.lock); + + spin_unlock(&ring->execlist_lock); + + if (unlikely(submit_contexts > 2)) + DRM_ERROR("More than two context complete events?\n"); } -static int execlists_context_queue(struct drm_i915_gem_request *request) +static void execlists_context_queue(struct drm_i915_gem_request *request) { struct intel_engine_cs *ring = request->ring; struct drm_i915_gem_request *cursor; @@ -630,8 +644,6 @@ static int execlists_context_queue(struct drm_i915_gem_request *request) execlists_context_unqueue(ring); spin_unlock_irq(&ring->execlist_lock); - - return 0; } static int logical_ring_invalidate_all_caches(struct drm_i915_gem_request *req) @@ -1550,7 +1562,7 @@ static int gen8_init_common_ring(struct intel_engine_cs *ring) { struct drm_device *dev = ring->dev; struct drm_i915_private *dev_priv = dev->dev_private; - u8 next_context_status_buffer_hw; + unsigned int next_context_status_buffer_hw; lrc_setup_hardware_status_page(ring, dev_priv->kernel_context->engine[ring->id].state); @@ -2013,6 +2025,7 @@ void intel_logical_ring_cleanup(struct intel_engine_cs *ring) ring->status_page.obj = NULL; } + ring->idle_lite_restore_wa = 0; ring->disable_lite_restore_wa = false; ring->ctx_desc_template = 0; @@ -2439,10 +2452,7 @@ populate_lr_context(struct intel_context *ctx, struct drm_i915_gem_object *ctx_o * With dynamic page allocation, PDPs may not be allocated at * this point. Point the unallocated PDPs to the scratch page */ - ASSIGN_CTX_PDP(ppgtt, reg_state, 3); - ASSIGN_CTX_PDP(ppgtt, reg_state, 2); - ASSIGN_CTX_PDP(ppgtt, reg_state, 1); - ASSIGN_CTX_PDP(ppgtt, reg_state, 0); + execlists_update_context_pdps(ppgtt, reg_state); } if (ring->id == RCS) { diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 566b0ae10ce0..dd910d30a380 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -271,7 +271,8 @@ struct intel_engine_cs { spinlock_t execlist_lock; struct list_head execlist_queue; struct list_head execlist_retired_req_list; - u8 next_context_status_buffer; + unsigned int next_context_status_buffer; + unsigned int idle_lite_restore_wa; bool disable_lite_restore_wa; u32 ctx_desc_template; u32 irq_keep_mask; /* bitmask for interrupts that should not be masked */ -- cgit v1.2.3 From 1d5bf5d9d9ef0c1e639d36178a224d83888c5a29 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 29 Feb 2016 22:10:33 +0200 Subject: drm/i915: Add missing NULL check before calling initial_watermarks Not all platforms set this callback, so NULL check it before calling it. v2: - Call intel_update_watermarks() on HSW+ where the callback is not set. (Matt) CC: Matt Roper Fixes: commit ed4a6a7ca853 ("drm/i915: Add two-stage ILK-style watermark programming (v11)") Signed-off-by: Imre Deak Link: http://patchwork.freedesktop.org/patch/msgid/1456776633-3401-1-git-send-email-imre.deak@intel.com Reviewed-by: Matt Roper --- drivers/gpu/drm/i915/intel_display.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c803690293d7..368d24728b16 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4957,7 +4957,8 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) */ intel_crtc_load_lut(crtc); - dev_priv->display.initial_watermarks(intel_crtc->config); + if (dev_priv->display.initial_watermarks != NULL) + dev_priv->display.initial_watermarks(intel_crtc->config); intel_enable_pipe(intel_crtc); if (intel_crtc->config->has_pch_encoder) @@ -5056,7 +5057,10 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) if (!intel_crtc->config->has_dsi_encoder) intel_ddi_enable_transcoder_func(crtc); - dev_priv->display.initial_watermarks(pipe_config); + if (dev_priv->display.initial_watermarks != NULL) + dev_priv->display.initial_watermarks(pipe_config); + else + intel_update_watermarks(crtc); intel_enable_pipe(intel_crtc); if (intel_crtc->config->has_pch_encoder) -- cgit v1.2.3 From 9106cf1747cc16ea5ef301a215e336f88e2ce1e8 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 15 Feb 2016 22:54:39 +0200 Subject: drm/i915: Account for the size of the chroma plane for the rotated gtt view MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The size of the rotated ggtt mapping ought to include the size of the chroma plane as well. Not a huge deal since we don't expose NV12 (or any pother planar format for that matter) yet. Cc: Tvrtko Ursulin Cc: Joonas Lahtinen Fixes: 89e3e1427629 ("drm/i915: Support NV12 in rotated GGTT mapping") Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1455569699-27905-2-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Tvrtko Ursulin Reviewed-by: Joonas Lahtinen --- drivers/gpu/drm/i915/i915_gem_gtt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 49e4f26b79d8..a1930f92199a 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -3634,7 +3634,7 @@ i915_ggtt_view_size(struct drm_i915_gem_object *obj, if (view->type == I915_GGTT_VIEW_NORMAL) { return obj->base.size; } else if (view->type == I915_GGTT_VIEW_ROTATED) { - return view->params.rotated.size; + return view->params.rotated.size + view->params.rotated.size_uv; } else if (view->type == I915_GGTT_VIEW_PARTIAL) { return view->params.partial.size << PAGE_SHIFT; } else { -- cgit v1.2.3 From 27ba39101404b694d4ae199fe7aa485ac693ba27 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 15 Feb 2016 22:54:40 +0200 Subject: drm/i915: s/tile_width/tile_width_bytes/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make if clear whether we're talking tile widths in bytes or in pixels. Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1455569699-27905-3-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 368d24728b16..dd681645acbc 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2225,8 +2225,8 @@ static unsigned int intel_tile_size(const struct drm_i915_private *dev_priv) return IS_GEN2(dev_priv) ? 2048 : 4096; } -static unsigned int intel_tile_width(const struct drm_i915_private *dev_priv, - uint64_t fb_modifier, unsigned int cpp) +static unsigned int intel_tile_width_bytes(const struct drm_i915_private *dev_priv, + uint64_t fb_modifier, unsigned int cpp) { switch (fb_modifier) { case DRM_FORMAT_MOD_NONE: @@ -2269,7 +2269,7 @@ unsigned int intel_tile_height(const struct drm_i915_private *dev_priv, return 1; else return intel_tile_size(dev_priv) / - intel_tile_width(dev_priv, fb_modifier, cpp); + intel_tile_width_bytes(dev_priv, fb_modifier, cpp); } unsigned int @@ -2288,7 +2288,7 @@ intel_fill_fb_ggtt_view(struct i915_ggtt_view *view, struct drm_framebuffer *fb, { struct drm_i915_private *dev_priv = to_i915(fb->dev); struct intel_rotation_info *info = &view->params.rotated; - unsigned int tile_size, tile_width, tile_height, cpp; + unsigned int tile_size, tile_width_bytes, tile_height, cpp; *view = i915_ggtt_view_normal; @@ -2309,19 +2309,19 @@ intel_fill_fb_ggtt_view(struct i915_ggtt_view *view, struct drm_framebuffer *fb, tile_size = intel_tile_size(dev_priv); cpp = drm_format_plane_cpp(fb->pixel_format, 0); - tile_width = intel_tile_width(dev_priv, fb->modifier[0], cpp); - tile_height = tile_size / tile_width; + tile_width_bytes = intel_tile_width_bytes(dev_priv, fb->modifier[0], cpp); + tile_height = tile_size / tile_width_bytes; - info->width_pages = DIV_ROUND_UP(fb->pitches[0], tile_width); + info->width_pages = DIV_ROUND_UP(fb->pitches[0], tile_width_bytes); info->height_pages = DIV_ROUND_UP(fb->height, tile_height); info->size = info->width_pages * info->height_pages * tile_size; if (info->pixel_format == DRM_FORMAT_NV12) { cpp = drm_format_plane_cpp(fb->pixel_format, 1); - tile_width = intel_tile_width(dev_priv, fb->modifier[1], cpp); - tile_height = tile_size / tile_width; + tile_width_bytes = intel_tile_width_bytes(dev_priv, fb->modifier[1], cpp); + tile_height = tile_size / tile_width_bytes; - info->width_pages_uv = DIV_ROUND_UP(fb->pitches[1], tile_width); + info->width_pages_uv = DIV_ROUND_UP(fb->pitches[1], tile_width_bytes); info->height_pages_uv = DIV_ROUND_UP(fb->height / 2, tile_height); info->size_uv = info->width_pages_uv * info->height_pages_uv * tile_size; } @@ -2458,18 +2458,18 @@ u32 intel_compute_tile_offset(struct drm_i915_private *dev_priv, unsigned int pitch) { if (fb_modifier != DRM_FORMAT_MOD_NONE) { - unsigned int tile_size, tile_width, tile_height; + unsigned int tile_size, tile_width_bytes, tile_height; unsigned int tile_rows, tiles; tile_size = intel_tile_size(dev_priv); - tile_width = intel_tile_width(dev_priv, fb_modifier, cpp); - tile_height = tile_size / tile_width; + tile_width_bytes = intel_tile_width_bytes(dev_priv, fb_modifier, cpp); + tile_height = tile_size / tile_width_bytes; tile_rows = *y / tile_height; *y %= tile_height; - tiles = *x / (tile_width/cpp); - *x %= tile_width/cpp; + tiles = *x / (tile_width_bytes/cpp); + *x %= tile_width_bytes/cpp; return tile_rows * pitch * tile_height + tiles * tile_size; } else { @@ -2931,7 +2931,7 @@ u32 intel_fb_stride_alignment(const struct drm_i915_private *dev_priv, } else { int cpp = drm_format_plane_cpp(pixel_format, 0); - return intel_tile_width(dev_priv, fb_modifier, cpp); + return intel_tile_width_bytes(dev_priv, fb_modifier, cpp); } } -- cgit v1.2.3 From 8d0deca8c6e0b25c409c6f4b2dc081596d7dffd9 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 15 Feb 2016 22:54:41 +0200 Subject: drm/i915: Pass 90/270 vs. 0/180 rotation info for intel_gen4_compute_page_offset() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The page aligned surface address calculation needs to know which way things are rotated. The contract now says that the caller must pass the rotate x/y coordinates, as well as the tile_height aligned stride in the tile_height direction. This will make it fairly simple to deal with 90/270 degree rotation on SKL+ where we have to deal with the rotated view into the GTT. v2: Pass rotation instead of bool even thoughwe only care about 0/180 vs. 90/270 v3: Introduce intel_tile_dims(), and don't mix up different units so much v4: Unconfuse bytes vs. pixels even more Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1455569699-27905-4-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 72 +++++++++++++++++++++++++----------- drivers/gpu/drm/i915/intel_drv.h | 3 +- drivers/gpu/drm/i915/intel_sprite.c | 18 +++++---- 3 files changed, 63 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index dd681645acbc..9cec8e2c0a0b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2272,6 +2272,20 @@ unsigned int intel_tile_height(const struct drm_i915_private *dev_priv, intel_tile_width_bytes(dev_priv, fb_modifier, cpp); } +/* Return the tile dimensions in pixel units */ +static void intel_tile_dims(const struct drm_i915_private *dev_priv, + unsigned int *tile_width, + unsigned int *tile_height, + uint64_t fb_modifier, + unsigned int cpp) +{ + unsigned int tile_width_bytes = + intel_tile_width_bytes(dev_priv, fb_modifier, cpp); + + *tile_width = tile_width_bytes / cpp; + *tile_height = intel_tile_size(dev_priv) / tile_width_bytes; +} + unsigned int intel_fb_align_height(struct drm_device *dev, unsigned int height, uint32_t pixel_format, uint64_t fb_modifier) @@ -2288,7 +2302,7 @@ intel_fill_fb_ggtt_view(struct i915_ggtt_view *view, struct drm_framebuffer *fb, { struct drm_i915_private *dev_priv = to_i915(fb->dev); struct intel_rotation_info *info = &view->params.rotated; - unsigned int tile_size, tile_width_bytes, tile_height, cpp; + unsigned int tile_size, tile_width, tile_height, cpp; *view = i915_ggtt_view_normal; @@ -2309,19 +2323,19 @@ intel_fill_fb_ggtt_view(struct i915_ggtt_view *view, struct drm_framebuffer *fb, tile_size = intel_tile_size(dev_priv); cpp = drm_format_plane_cpp(fb->pixel_format, 0); - tile_width_bytes = intel_tile_width_bytes(dev_priv, fb->modifier[0], cpp); - tile_height = tile_size / tile_width_bytes; + intel_tile_dims(dev_priv, &tile_width, &tile_height, + fb->modifier[0], cpp); - info->width_pages = DIV_ROUND_UP(fb->pitches[0], tile_width_bytes); + info->width_pages = DIV_ROUND_UP(fb->pitches[0], tile_width * cpp); info->height_pages = DIV_ROUND_UP(fb->height, tile_height); info->size = info->width_pages * info->height_pages * tile_size; if (info->pixel_format == DRM_FORMAT_NV12) { cpp = drm_format_plane_cpp(fb->pixel_format, 1); - tile_width_bytes = intel_tile_width_bytes(dev_priv, fb->modifier[1], cpp); - tile_height = tile_size / tile_width_bytes; + intel_tile_dims(dev_priv, &tile_width, &tile_height, + fb->modifier[1], cpp); - info->width_pages_uv = DIV_ROUND_UP(fb->pitches[1], tile_width_bytes); + info->width_pages_uv = DIV_ROUND_UP(fb->pitches[1], tile_width * cpp); info->height_pages_uv = DIV_ROUND_UP(fb->height / 2, tile_height); info->size_uv = info->width_pages_uv * info->height_pages_uv * tile_size; } @@ -2449,29 +2463,43 @@ static void intel_unpin_fb_obj(struct drm_framebuffer *fb, i915_gem_object_unpin_from_display_plane(obj, &view); } -/* Computes the linear offset to the base tile and adjusts x, y. bytes per pixel - * is assumed to be a power-of-two. */ +/* + * Computes the linear offset to the base tile and adjusts + * x, y. bytes per pixel is assumed to be a power-of-two. + * + * In the 90/270 rotated case, x and y are assumed + * to be already rotated to match the rotated GTT view, and + * pitch is the tile_height aligned framebuffer height. + */ u32 intel_compute_tile_offset(struct drm_i915_private *dev_priv, int *x, int *y, uint64_t fb_modifier, unsigned int cpp, - unsigned int pitch) + unsigned int pitch, + unsigned int rotation) { if (fb_modifier != DRM_FORMAT_MOD_NONE) { - unsigned int tile_size, tile_width_bytes, tile_height; - unsigned int tile_rows, tiles; + unsigned int tile_size, tile_width, tile_height; + unsigned int tile_rows, tiles, pitch_tiles; tile_size = intel_tile_size(dev_priv); - tile_width_bytes = intel_tile_width_bytes(dev_priv, fb_modifier, cpp); - tile_height = tile_size / tile_width_bytes; + intel_tile_dims(dev_priv, &tile_width, &tile_height, + fb_modifier, cpp); + + if (intel_rotation_90_or_270(rotation)) { + pitch_tiles = pitch / tile_height; + swap(tile_width, tile_height); + } else { + pitch_tiles = pitch / (tile_width * cpp); + } tile_rows = *y / tile_height; *y %= tile_height; - tiles = *x / (tile_width_bytes/cpp); - *x %= tile_width_bytes/cpp; + tiles = *x / tile_width; + *x %= tile_width; - return tile_rows * pitch * tile_height + tiles * tile_size; + return (tile_rows * pitch_tiles + tiles) * tile_size; } else { unsigned int alignment = intel_linear_alignment(dev_priv) - 1; unsigned int offset; @@ -2716,6 +2744,7 @@ static void i9xx_update_primary_plane(struct drm_plane *primary, u32 linear_offset; u32 dspcntr; i915_reg_t reg = DSPCNTR(plane); + unsigned int rotation = plane_state->base.rotation; int cpp = drm_format_plane_cpp(fb->pixel_format, 0); int x = plane_state->src.x1 >> 16; int y = plane_state->src.y1 >> 16; @@ -2782,13 +2811,13 @@ static void i9xx_update_primary_plane(struct drm_plane *primary, intel_crtc->dspaddr_offset = intel_compute_tile_offset(dev_priv, &x, &y, fb->modifier[0], cpp, - fb->pitches[0]); + fb->pitches[0], rotation); linear_offset -= intel_crtc->dspaddr_offset; } else { intel_crtc->dspaddr_offset = linear_offset; } - if (plane_state->base.rotation == BIT(DRM_ROTATE_180)) { + if (rotation == BIT(DRM_ROTATE_180)) { dspcntr |= DISPPLANE_ROTATE_180; x += (crtc_state->pipe_src_w - 1); @@ -2846,6 +2875,7 @@ static void ironlake_update_primary_plane(struct drm_plane *primary, u32 linear_offset; u32 dspcntr; i915_reg_t reg = DSPCNTR(plane); + unsigned int rotation = plane_state->base.rotation; int cpp = drm_format_plane_cpp(fb->pixel_format, 0); int x = plane_state->src.x1 >> 16; int y = plane_state->src.y1 >> 16; @@ -2889,9 +2919,9 @@ static void ironlake_update_primary_plane(struct drm_plane *primary, intel_crtc->dspaddr_offset = intel_compute_tile_offset(dev_priv, &x, &y, fb->modifier[0], cpp, - fb->pitches[0]); + fb->pitches[0], rotation); linear_offset -= intel_crtc->dspaddr_offset; - if (plane_state->base.rotation == BIT(DRM_ROTATE_180)) { + if (rotation == BIT(DRM_ROTATE_180)) { dspcntr |= DISPPLANE_ROTATE_180; if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) { diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 5daf53c080e1..af70f4934f34 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1199,7 +1199,8 @@ u32 intel_compute_tile_offset(struct drm_i915_private *dev_priv, int *x, int *y, uint64_t fb_modifier, unsigned int cpp, - unsigned int pitch); + unsigned int pitch, + unsigned int rotation); void intel_prepare_reset(struct drm_device *dev); void intel_finish_reset(struct drm_device *dev); void hsw_enable_pc8(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index a2582c455b36..7dc2b8b2a4ac 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -193,7 +193,7 @@ skl_update_plane(struct drm_plane *drm_plane, const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; u32 surf_addr; u32 tile_height, plane_offset, plane_size; - unsigned int rotation; + unsigned int rotation = plane_state->base.rotation; int x_offset, y_offset; int crtc_x = plane_state->dst.x1; int crtc_y = plane_state->dst.y1; @@ -213,7 +213,6 @@ skl_update_plane(struct drm_plane *drm_plane, plane_ctl |= skl_plane_ctl_format(fb->pixel_format); plane_ctl |= skl_plane_ctl_tiling(fb->modifier[0]); - rotation = plane_state->base.rotation; plane_ctl |= skl_plane_ctl_rotation(rotation); stride_div = intel_fb_stride_alignment(dev_priv, fb->modifier[0], @@ -351,6 +350,7 @@ vlv_update_plane(struct drm_plane *dplane, int plane = intel_plane->plane; u32 sprctl; u32 sprsurf_offset, linear_offset; + unsigned int rotation = dplane->state->rotation; int cpp = drm_format_plane_cpp(fb->pixel_format, 0); const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; int crtc_x = plane_state->dst.x1; @@ -425,10 +425,10 @@ vlv_update_plane(struct drm_plane *dplane, linear_offset = y * fb->pitches[0] + x * cpp; sprsurf_offset = intel_compute_tile_offset(dev_priv, &x, &y, fb->modifier[0], cpp, - fb->pitches[0]); + fb->pitches[0], rotation); linear_offset -= sprsurf_offset; - if (plane_state->base.rotation == BIT(DRM_ROTATE_180)) { + if (rotation == BIT(DRM_ROTATE_180)) { sprctl |= SP_ROTATE_180; x += src_w; @@ -493,6 +493,7 @@ ivb_update_plane(struct drm_plane *plane, enum pipe pipe = intel_plane->pipe; u32 sprctl, sprscale = 0; u32 sprsurf_offset, linear_offset; + unsigned int rotation = plane_state->base.rotation; int cpp = drm_format_plane_cpp(fb->pixel_format, 0); const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; int crtc_x = plane_state->dst.x1; @@ -558,10 +559,10 @@ ivb_update_plane(struct drm_plane *plane, linear_offset = y * fb->pitches[0] + x * cpp; sprsurf_offset = intel_compute_tile_offset(dev_priv, &x, &y, fb->modifier[0], cpp, - fb->pitches[0]); + fb->pitches[0], rotation); linear_offset -= sprsurf_offset; - if (plane_state->base.rotation == BIT(DRM_ROTATE_180)) { + if (rotation == BIT(DRM_ROTATE_180)) { sprctl |= SPRITE_ROTATE_180; /* HSW and BDW does this automagically in hardware */ @@ -634,6 +635,7 @@ ilk_update_plane(struct drm_plane *plane, int pipe = intel_plane->pipe; u32 dvscntr, dvsscale; u32 dvssurf_offset, linear_offset; + unsigned int rotation = plane_state->base.rotation; int cpp = drm_format_plane_cpp(fb->pixel_format, 0); const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; int crtc_x = plane_state->dst.x1; @@ -695,10 +697,10 @@ ilk_update_plane(struct drm_plane *plane, linear_offset = y * fb->pitches[0] + x * cpp; dvssurf_offset = intel_compute_tile_offset(dev_priv, &x, &y, fb->modifier[0], cpp, - fb->pitches[0]); + fb->pitches[0], rotation); linear_offset -= dvssurf_offset; - if (plane_state->base.rotation == BIT(DRM_ROTATE_180)) { + if (rotation == BIT(DRM_ROTATE_180)) { dvscntr |= DVS_ROTATE_180; x += src_w; -- cgit v1.2.3 From 29cf9491590119b9ebf1bf211bdd7a3cea4e040c Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 15 Feb 2016 22:54:42 +0200 Subject: drm/i915: Support for extra alignment for tiled surfaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SKL+ needs >4K alignment for tiled surfaces, so make intel_compute_page_offset() handle it. The way we do it is first we compute the closest tile boundary as before, and then figure out how many tiles we need to go to reach the desired alignment. The difference in the offset is then added into the x/y offsets. v2: Be less confusing wrt. units (pixels vs. bytes) (Daniel) v3: Use u32 for offsets Have intel_adjust_tile_offset() return the new offset (will be useful later) Add an offset_aligned variable (Daniel) Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1455569699-27905-5-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 50 ++++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9cec8e2c0a0b..f3ca95db82ba 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2463,6 +2463,35 @@ static void intel_unpin_fb_obj(struct drm_framebuffer *fb, i915_gem_object_unpin_from_display_plane(obj, &view); } +/* + * Adjust the tile offset by moving the difference into + * the x/y offsets. + * + * Input tile dimensions and pitch must already be + * rotated to match x and y, and in pixel units. + */ +static u32 intel_adjust_tile_offset(int *x, int *y, + unsigned int tile_width, + unsigned int tile_height, + unsigned int tile_size, + unsigned int pitch_tiles, + u32 old_offset, + u32 new_offset) +{ + unsigned int tiles; + + WARN_ON(old_offset & (tile_size - 1)); + WARN_ON(new_offset & (tile_size - 1)); + WARN_ON(new_offset > old_offset); + + tiles = (old_offset - new_offset) / tile_size; + + *y += tiles / pitch_tiles * tile_height; + *x += tiles % pitch_tiles * tile_width; + + return new_offset; +} + /* * Computes the linear offset to the base tile and adjusts * x, y. bytes per pixel is assumed to be a power-of-two. @@ -2478,6 +2507,12 @@ u32 intel_compute_tile_offset(struct drm_i915_private *dev_priv, unsigned int pitch, unsigned int rotation) { + u32 offset, offset_aligned, alignment; + + alignment = intel_surf_alignment(dev_priv, fb_modifier); + if (alignment) + alignment--; + if (fb_modifier != DRM_FORMAT_MOD_NONE) { unsigned int tile_size, tile_width, tile_height; unsigned int tile_rows, tiles, pitch_tiles; @@ -2499,16 +2534,21 @@ u32 intel_compute_tile_offset(struct drm_i915_private *dev_priv, tiles = *x / tile_width; *x %= tile_width; - return (tile_rows * pitch_tiles + tiles) * tile_size; - } else { - unsigned int alignment = intel_linear_alignment(dev_priv) - 1; - unsigned int offset; + offset = (tile_rows * pitch_tiles + tiles) * tile_size; + offset_aligned = offset & ~alignment; + intel_adjust_tile_offset(x, y, tile_width, tile_height, + tile_size, pitch_tiles, + offset, offset_aligned); + } else { offset = *y * pitch + *x * cpp; + offset_aligned = offset & ~alignment; + *y = (offset & alignment) / pitch; *x = ((offset & alignment) - *y * pitch) / cpp; - return offset & ~alignment; } + + return offset_aligned; } static int i9xx_format_to_fourcc(int format) -- cgit v1.2.3 From 3465c580afc86c066cc55842bae38ba3cb1acb99 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 15 Feb 2016 22:54:43 +0200 Subject: drm/i915: Don't pass plane+plane_state to intel_pin_and_fence_fb_obj() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit intel_pin_and_fence_fb_obj() only needs the framebuffer, and the desird rotation (to find the right GTT view for it), so no need to pass all kinds of plane stuff. The main motivation is to get rid of the uggy NULL plane_state handling due to fbdev. v2: Add a note why I really want this Signed-off-by: Ville Syrjälä Grumpily-Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1455569699-27905-6-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 41 +++++++++++++++--------------------- drivers/gpu/drm/i915/intel_drv.h | 5 ++--- drivers/gpu/drm/i915/intel_fbdev.c | 2 +- 3 files changed, 20 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f3ca95db82ba..bf65f1f191fe 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2297,8 +2297,9 @@ intel_fb_align_height(struct drm_device *dev, unsigned int height, } static void -intel_fill_fb_ggtt_view(struct i915_ggtt_view *view, struct drm_framebuffer *fb, - const struct drm_plane_state *plane_state) +intel_fill_fb_ggtt_view(struct i915_ggtt_view *view, + const struct drm_framebuffer *fb, + unsigned int rotation) { struct drm_i915_private *dev_priv = to_i915(fb->dev); struct intel_rotation_info *info = &view->params.rotated; @@ -2306,10 +2307,7 @@ intel_fill_fb_ggtt_view(struct i915_ggtt_view *view, struct drm_framebuffer *fb, *view = i915_ggtt_view_normal; - if (!plane_state) - return; - - if (!intel_rotation_90_or_270(plane_state->rotation)) + if (!intel_rotation_90_or_270(rotation)) return; *view = i915_ggtt_view_rotated; @@ -2374,9 +2372,8 @@ static unsigned int intel_surf_alignment(const struct drm_i915_private *dev_priv } int -intel_pin_and_fence_fb_obj(struct drm_plane *plane, - struct drm_framebuffer *fb, - const struct drm_plane_state *plane_state) +intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, + unsigned int rotation) { struct drm_device *dev = fb->dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -2389,7 +2386,7 @@ intel_pin_and_fence_fb_obj(struct drm_plane *plane, alignment = intel_surf_alignment(dev_priv, fb->modifier[0]); - intel_fill_fb_ggtt_view(&view, fb, plane_state); + intel_fill_fb_ggtt_view(&view, fb, rotation); /* Note that the w/a also requires 64 PTE of padding following the * bo. We currently fill all unused PTE with the shadow page and so @@ -2447,15 +2444,14 @@ err_pm: return ret; } -static void intel_unpin_fb_obj(struct drm_framebuffer *fb, - const struct drm_plane_state *plane_state) +static void intel_unpin_fb_obj(struct drm_framebuffer *fb, unsigned int rotation) { struct drm_i915_gem_object *obj = intel_fb_obj(fb); struct i915_ggtt_view view; WARN_ON(!mutex_is_locked(&obj->base.dev->struct_mutex)); - intel_fill_fb_ggtt_view(&view, fb, plane_state); + intel_fill_fb_ggtt_view(&view, fb, rotation); if (view.type == I915_GGTT_VIEW_NORMAL) i915_gem_object_unpin_fence(obj); @@ -3014,7 +3010,7 @@ u32 intel_plane_obj_offset(struct intel_plane *intel_plane, u64 offset; intel_fill_fb_ggtt_view(&view, intel_plane->base.state->fb, - intel_plane->base.state); + intel_plane->base.state->rotation); vma = i915_gem_obj_to_ggtt_view(obj, &view); if (WARN(!vma, "ggtt vma for display object not found! (view=%u)\n", @@ -10959,7 +10955,7 @@ static void intel_unpin_work_fn(struct work_struct *__work) struct drm_plane *primary = crtc->base.primary; mutex_lock(&dev->struct_mutex); - intel_unpin_fb_obj(work->old_fb, primary->state); + intel_unpin_fb_obj(work->old_fb, primary->state->rotation); drm_gem_object_unreference(&work->pending_flip_obj->base); if (work->flip_queued_req) @@ -11731,8 +11727,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, goto cleanup_pending; } - ret = intel_pin_and_fence_fb_obj(crtc->primary, fb, - crtc->primary->state); + ret = intel_pin_and_fence_fb_obj(fb, primary->state->rotation); if (ret) goto cleanup_pending; @@ -11782,7 +11777,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, return 0; cleanup_unpin: - intel_unpin_fb_obj(fb, crtc->primary->state); + intel_unpin_fb_obj(fb, crtc->primary->state->rotation); cleanup_pending: if (!IS_ERR_OR_NULL(request)) i915_gem_request_cancel(request); @@ -14004,7 +13999,7 @@ intel_prepare_plane_fb(struct drm_plane *plane, if (ret) DRM_DEBUG_KMS("failed to attach phys object\n"); } else { - ret = intel_pin_and_fence_fb_obj(plane, fb, new_state); + ret = intel_pin_and_fence_fb_obj(fb, new_state->rotation); } if (ret == 0) { @@ -14048,7 +14043,7 @@ intel_cleanup_plane_fb(struct drm_plane *plane, if (old_obj && (plane->type != DRM_PLANE_TYPE_CURSOR || !INTEL_INFO(dev)->cursor_needs_physical)) - intel_unpin_fb_obj(old_state->fb, old_state); + intel_unpin_fb_obj(old_state->fb, old_state->rotation); /* prepare_fb aborted? */ if ((old_obj && (old_obj->frontbuffer_bits & intel_plane->frontbuffer_bit)) || @@ -14056,7 +14051,6 @@ intel_cleanup_plane_fb(struct drm_plane *plane, i915_gem_track_fb(old_obj, obj, intel_plane->frontbuffer_bit); i915_gem_request_assign(&old_intel_state->wait_req, NULL); - } int @@ -16179,9 +16173,8 @@ void intel_modeset_gem_init(struct drm_device *dev) continue; mutex_lock(&dev->struct_mutex); - ret = intel_pin_and_fence_fb_obj(c->primary, - c->primary->fb, - c->primary->state); + ret = intel_pin_and_fence_fb_obj(c->primary->fb, + c->primary->state->rotation); mutex_unlock(&dev->struct_mutex); if (ret) { DRM_ERROR("failed to pin boot fb on pipe %d\n", diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index af70f4934f34..a3831f67e5b0 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1129,9 +1129,8 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector, void intel_release_load_detect_pipe(struct drm_connector *connector, struct intel_load_detect_pipe *old, struct drm_modeset_acquire_ctx *ctx); -int intel_pin_and_fence_fb_obj(struct drm_plane *plane, - struct drm_framebuffer *fb, - const struct drm_plane_state *plane_state); +int intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, + unsigned int rotation); struct drm_framebuffer * __intel_framebuffer_create(struct drm_device *dev, struct drm_mode_fb_cmd2 *mode_cmd, diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index 97a91e631915..ae9cf6fcb870 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -220,7 +220,7 @@ static int intelfb_create(struct drm_fb_helper *helper, * This also validates that any existing fb inherited from the * BIOS is suitable for own access. */ - ret = intel_pin_and_fence_fb_obj(NULL, &ifbdev->fb->base, NULL); + ret = intel_pin_and_fence_fb_obj(&ifbdev->fb->base, BIT(DRM_ROTATE_0)); if (ret) goto out_unlock; -- cgit v1.2.3 From 4f2d9934bd6ac73950832c96b385822846670668 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 15 Feb 2016 22:54:44 +0200 Subject: drm/i915: Pass drm_frambuffer to intel_compute_page_offset() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit intel_compute_page_offsets() gets passed a bunch of the framebuffer metadate sepearately. Just pass the framebuffer itself to make life simpler for the caller, and make it less likely they would make a mistake in the order of the arguments (as most as just unsigned ints and such). We still pass the pitch explicitly since for 90/270 degree rotation the caller has to pass in the right thing. Signed-off-by: Ville Syrjälä Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1455569699-27905-7-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 15 +++++++-------- drivers/gpu/drm/i915/intel_drv.h | 6 ++---- drivers/gpu/drm/i915/intel_sprite.c | 9 +++------ 3 files changed, 12 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index bf65f1f191fe..f742f049f643 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2496,13 +2496,14 @@ static u32 intel_adjust_tile_offset(int *x, int *y, * to be already rotated to match the rotated GTT view, and * pitch is the tile_height aligned framebuffer height. */ -u32 intel_compute_tile_offset(struct drm_i915_private *dev_priv, - int *x, int *y, - uint64_t fb_modifier, - unsigned int cpp, +u32 intel_compute_tile_offset(int *x, int *y, + const struct drm_framebuffer *fb, int plane, unsigned int pitch, unsigned int rotation) { + const struct drm_i915_private *dev_priv = to_i915(fb->dev); + uint64_t fb_modifier = fb->modifier[plane]; + unsigned int cpp = drm_format_plane_cpp(fb->pixel_format, plane); u32 offset, offset_aligned, alignment; alignment = intel_surf_alignment(dev_priv, fb_modifier); @@ -2845,8 +2846,7 @@ static void i9xx_update_primary_plane(struct drm_plane *primary, if (INTEL_INFO(dev)->gen >= 4) { intel_crtc->dspaddr_offset = - intel_compute_tile_offset(dev_priv, &x, &y, - fb->modifier[0], cpp, + intel_compute_tile_offset(&x, &y, fb, 0, fb->pitches[0], rotation); linear_offset -= intel_crtc->dspaddr_offset; } else { @@ -2953,8 +2953,7 @@ static void ironlake_update_primary_plane(struct drm_plane *primary, linear_offset = y * fb->pitches[0] + x * cpp; intel_crtc->dspaddr_offset = - intel_compute_tile_offset(dev_priv, &x, &y, - fb->modifier[0], cpp, + intel_compute_tile_offset(&x, &y, fb, 0, fb->pitches[0], rotation); linear_offset -= intel_crtc->dspaddr_offset; if (rotation == BIT(DRM_ROTATE_180)) { diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index a3831f67e5b0..5afc1b55449a 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1194,10 +1194,8 @@ void assert_fdi_rx_pll(struct drm_i915_private *dev_priv, void assert_pipe(struct drm_i915_private *dev_priv, enum pipe pipe, bool state); #define assert_pipe_enabled(d, p) assert_pipe(d, p, true) #define assert_pipe_disabled(d, p) assert_pipe(d, p, false) -u32 intel_compute_tile_offset(struct drm_i915_private *dev_priv, - int *x, int *y, - uint64_t fb_modifier, - unsigned int cpp, +u32 intel_compute_tile_offset(int *x, int *y, + const struct drm_framebuffer *fb, int plane, unsigned int pitch, unsigned int rotation); void intel_prepare_reset(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 7dc2b8b2a4ac..8821533561b1 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -423,8 +423,7 @@ vlv_update_plane(struct drm_plane *dplane, crtc_h--; linear_offset = y * fb->pitches[0] + x * cpp; - sprsurf_offset = intel_compute_tile_offset(dev_priv, &x, &y, - fb->modifier[0], cpp, + sprsurf_offset = intel_compute_tile_offset(&x, &y, fb, 0, fb->pitches[0], rotation); linear_offset -= sprsurf_offset; @@ -557,8 +556,7 @@ ivb_update_plane(struct drm_plane *plane, sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h; linear_offset = y * fb->pitches[0] + x * cpp; - sprsurf_offset = intel_compute_tile_offset(dev_priv, &x, &y, - fb->modifier[0], cpp, + sprsurf_offset = intel_compute_tile_offset(&x, &y, fb, 0, fb->pitches[0], rotation); linear_offset -= sprsurf_offset; @@ -695,8 +693,7 @@ ilk_update_plane(struct drm_plane *plane, dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h; linear_offset = y * fb->pitches[0] + x * cpp; - dvssurf_offset = intel_compute_tile_offset(dev_priv, &x, &y, - fb->modifier[0], cpp, + dvssurf_offset = intel_compute_tile_offset(&x, &y, fb, 0, fb->pitches[0], rotation); linear_offset -= dvssurf_offset; -- cgit v1.2.3 From 1663b9d6a26a4d118e497b0a1604948b0fb0c86e Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 15 Feb 2016 22:54:45 +0200 Subject: drm/i915: Reorganize intel_rotation_info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Throw out a bunch of unnecessary stuff from struct intel_rotation_info, and pull most of the remaining stuff to live under an array of per-color plane sub-structures. What still remains outside the sub-structure will be reorgranized later as well, but that requires more work elsewhere so leave it be for now. v2: Split the vma size == luma+chroma size fix to prep patch (Daniel) Signed-off-by: Ville Syrjälä Reviewed-by: Daniel Vetter (v1) Link: http://patchwork.freedesktop.org/patch/msgid/1455569699-27905-8-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/i915_gem_gtt.c | 35 +++++++++++++++-------------------- drivers/gpu/drm/i915/i915_gem_gtt.h | 11 ++++------- drivers/gpu/drm/i915/intel_display.c | 25 +++++++++++++++---------- drivers/gpu/drm/i915/intel_drv.h | 1 + 4 files changed, 35 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index a1930f92199a..a794bbdf9a46 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -3405,7 +3405,7 @@ static struct sg_table * intel_rotate_fb_obj_pages(struct intel_rotation_info *rot_info, struct drm_i915_gem_object *obj) { - unsigned int size_pages = rot_info->size >> PAGE_SHIFT; + unsigned int size_pages = rot_info->plane[0].width * rot_info->plane[0].height; unsigned int size_pages_uv; struct sg_page_iter sg_iter; unsigned long i; @@ -3423,7 +3423,7 @@ intel_rotate_fb_obj_pages(struct intel_rotation_info *rot_info, /* Account for UV plane with NV12. */ if (rot_info->pixel_format == DRM_FORMAT_NV12) - size_pages_uv = rot_info->size_uv >> PAGE_SHIFT; + size_pages_uv = rot_info->plane[1].width * rot_info->plane[1].height; else size_pages_uv = 0; @@ -3445,9 +3445,9 @@ intel_rotate_fb_obj_pages(struct intel_rotation_info *rot_info, /* Rotate the pages. */ sg = rotate_pages(page_addr_list, 0, - rot_info->width_pages, rot_info->height_pages, - rot_info->width_pages, - st, NULL); + rot_info->plane[0].width, rot_info->plane[0].height, + rot_info->plane[0].width, + st, NULL); /* Append the UV plane if NV12. */ if (rot_info->pixel_format == DRM_FORMAT_NV12) { @@ -3459,18 +3459,15 @@ intel_rotate_fb_obj_pages(struct intel_rotation_info *rot_info, rot_info->uv_start_page = uv_start_page; - rotate_pages(page_addr_list, uv_start_page, - rot_info->width_pages_uv, - rot_info->height_pages_uv, - rot_info->width_pages_uv, + rotate_pages(page_addr_list, rot_info->uv_start_page, + rot_info->plane[1].width, rot_info->plane[1].height, + rot_info->plane[1].width, st, sg); } - DRM_DEBUG_KMS( - "Created rotated page mapping for object size %zu (pitch=%u, height=%u, pixel_format=0x%x, %ux%u tiles, %u pages (%u plane 0)).\n", - obj->base.size, rot_info->pitch, rot_info->height, - rot_info->pixel_format, rot_info->width_pages, - rot_info->height_pages, size_pages + size_pages_uv, + DRM_DEBUG_KMS("Created rotated page mapping for object size %zu (%ux%u tiles, %u pages (%u plane 0)).\n", + obj->base.size, rot_info->plane[0].width, + rot_info->plane[0].height, size_pages + size_pages_uv, size_pages); drm_free_large(page_addr_list); @@ -3482,11 +3479,9 @@ err_sg_alloc: err_st_alloc: drm_free_large(page_addr_list); - DRM_DEBUG_KMS( - "Failed to create rotated mapping for object size %zu! (%d) (pitch=%u, height=%u, pixel_format=0x%x, %ux%u tiles, %u pages (%u plane 0))\n", - obj->base.size, ret, rot_info->pitch, rot_info->height, - rot_info->pixel_format, rot_info->width_pages, - rot_info->height_pages, size_pages + size_pages_uv, + DRM_DEBUG_KMS("Failed to create rotated mapping for object size %zu! (%d) (%ux%u tiles, %u pages (%u plane 0))\n", + obj->base.size, ret, rot_info->plane[0].width, + rot_info->plane[0].height, size_pages + size_pages_uv, size_pages); return ERR_PTR(ret); } @@ -3634,7 +3629,7 @@ i915_ggtt_view_size(struct drm_i915_gem_object *obj, if (view->type == I915_GGTT_VIEW_NORMAL) { return obj->base.size; } else if (view->type == I915_GGTT_VIEW_ROTATED) { - return view->params.rotated.size + view->params.rotated.size_uv; + return intel_rotation_info_size(&view->params.rotated) << PAGE_SHIFT; } else if (view->type == I915_GGTT_VIEW_PARTIAL) { return view->params.partial.size << PAGE_SHIFT; } else { diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index 8774f1ba46e7..dc208c05cd2c 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -135,16 +135,13 @@ enum i915_ggtt_view_type { }; struct intel_rotation_info { - unsigned int height; - unsigned int pitch; unsigned int uv_offset; uint32_t pixel_format; - uint64_t fb_modifier; - unsigned int width_pages, height_pages; - uint64_t size; - unsigned int width_pages_uv, height_pages_uv; - uint64_t size_uv; unsigned int uv_start_page; + struct { + /* tiles */ + unsigned int width, height; + } plane[2]; }; struct i915_ggtt_view { diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f742f049f643..0e7cb4d3cb34 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2296,6 +2296,17 @@ intel_fb_align_height(struct drm_device *dev, unsigned int height, return ALIGN(height, tile_height); } +unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info) +{ + unsigned int size = 0; + int i; + + for (i = 0 ; i < ARRAY_SIZE(rot_info->plane); i++) + size += rot_info->plane[i].width * rot_info->plane[i].height; + + return size; +} + static void intel_fill_fb_ggtt_view(struct i915_ggtt_view *view, const struct drm_framebuffer *fb, @@ -2312,11 +2323,7 @@ intel_fill_fb_ggtt_view(struct i915_ggtt_view *view, *view = i915_ggtt_view_rotated; - info->height = fb->height; - info->pixel_format = fb->pixel_format; - info->pitch = fb->pitches[0]; info->uv_offset = fb->offsets[1]; - info->fb_modifier = fb->modifier[0]; tile_size = intel_tile_size(dev_priv); @@ -2324,18 +2331,16 @@ intel_fill_fb_ggtt_view(struct i915_ggtt_view *view, intel_tile_dims(dev_priv, &tile_width, &tile_height, fb->modifier[0], cpp); - info->width_pages = DIV_ROUND_UP(fb->pitches[0], tile_width * cpp); - info->height_pages = DIV_ROUND_UP(fb->height, tile_height); - info->size = info->width_pages * info->height_pages * tile_size; + info->plane[0].width = DIV_ROUND_UP(fb->pitches[0], tile_width * cpp); + info->plane[0].height = DIV_ROUND_UP(fb->height, tile_height); if (info->pixel_format == DRM_FORMAT_NV12) { cpp = drm_format_plane_cpp(fb->pixel_format, 1); intel_tile_dims(dev_priv, &tile_width, &tile_height, fb->modifier[1], cpp); - info->width_pages_uv = DIV_ROUND_UP(fb->pitches[1], tile_width * cpp); - info->height_pages_uv = DIV_ROUND_UP(fb->height / 2, tile_height); - info->size_uv = info->width_pages_uv * info->height_pages_uv * tile_size; + info->plane[1].width = DIV_ROUND_UP(fb->pitches[1], tile_width * cpp); + info->plane[1].height = DIV_ROUND_UP(fb->height / 2, tile_height); } } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 5afc1b55449a..8b1d18795876 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1082,6 +1082,7 @@ void i915_audio_component_cleanup(struct drm_i915_private *dev_priv); /* intel_display.c */ extern const struct drm_plane_funcs intel_plane_funcs; +unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info); bool intel_has_pending_fb_unpin(struct drm_device *dev); int intel_pch_rawclk(struct drm_device *dev); int intel_hrawclk(struct drm_device *dev); -- cgit v1.2.3 From 11f20322e00fb48e53ac66d2889cec3341a8e814 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 15 Feb 2016 22:54:46 +0200 Subject: drm/i915: Move the NULL sg handling out from rotate_pages() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit rotate_pages() checks to see if it got called with a NULL sg, and then goes to extract it from sg->sgl. It always gets called with a NULL sg for the first plane, so moving the initial 'sg=st->sgl' assignment out into intel_rotate_fb_obj_pages() seems less special-casey. Signed-off-by: Ville Syrjälä Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1455569699-27905-9-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/i915_gem_gtt.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index a794bbdf9a46..7b8de85c5f76 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -3377,11 +3377,6 @@ rotate_pages(const dma_addr_t *in, unsigned int offset, unsigned int column, row; unsigned int src_idx; - if (!sg) { - st->nents = 0; - sg = st->sgl; - } - for (column = 0; column < width; column++) { src_idx = stride * (height - 1) + column; for (row = 0; row < height; row++) { @@ -3443,11 +3438,14 @@ intel_rotate_fb_obj_pages(struct intel_rotation_info *rot_info, i++; } + st->nents = 0; + sg = st->sgl; + /* Rotate the pages. */ sg = rotate_pages(page_addr_list, 0, rot_info->plane[0].width, rot_info->plane[0].height, rot_info->plane[0].width, - st, NULL); + st, sg); /* Append the UV plane if NV12. */ if (rot_info->pixel_format == DRM_FORMAT_NV12) { @@ -3459,10 +3457,10 @@ intel_rotate_fb_obj_pages(struct intel_rotation_info *rot_info, rot_info->uv_start_page = uv_start_page; - rotate_pages(page_addr_list, rot_info->uv_start_page, - rot_info->plane[1].width, rot_info->plane[1].height, - rot_info->plane[1].width, - st, sg); + sg = rotate_pages(page_addr_list, rot_info->uv_start_page, + rot_info->plane[1].width, rot_info->plane[1].height, + rot_info->plane[1].width, + st, sg); } DRM_DEBUG_KMS("Created rotated page mapping for object size %zu (%ux%u tiles, %u pages (%u plane 0)).\n", -- cgit v1.2.3 From 2d7a215f8b917067efc9999d3d733dbab37ada5c Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 15 Feb 2016 22:54:47 +0200 Subject: drm/i915: Embed rotation_info under intel_framebuffer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of repopulatin the rotation_info struct for the fb every time we try to use the fb, we can just populate it once when creating the fb, and later we can just copy the pre-populate struct into the gtt_view. Signed-off-by: Ville Syrjälä Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1455569699-27905-10-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 27 ++++++++++++++++----------- drivers/gpu/drm/i915/intel_drv.h | 1 + 2 files changed, 17 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0e7cb4d3cb34..a03c12ab3098 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2312,18 +2312,20 @@ intel_fill_fb_ggtt_view(struct i915_ggtt_view *view, const struct drm_framebuffer *fb, unsigned int rotation) { - struct drm_i915_private *dev_priv = to_i915(fb->dev); - struct intel_rotation_info *info = &view->params.rotated; - unsigned int tile_size, tile_width, tile_height, cpp; - - *view = i915_ggtt_view_normal; - - if (!intel_rotation_90_or_270(rotation)) - return; - - *view = i915_ggtt_view_rotated; + if (intel_rotation_90_or_270(rotation)) { + *view = i915_ggtt_view_rotated; + view->params.rotated = to_intel_framebuffer(fb)->rot_info; + } else { + *view = i915_ggtt_view_normal; + } +} - info->uv_offset = fb->offsets[1]; +static void +intel_fill_fb_info(struct drm_i915_private *dev_priv, + struct drm_framebuffer *fb) +{ + struct intel_rotation_info *info = &to_intel_framebuffer(fb)->rot_info; + unsigned int tile_size, tile_width, tile_height, cpp; tile_size = intel_tile_size(dev_priv); @@ -2339,6 +2341,7 @@ intel_fill_fb_ggtt_view(struct i915_ggtt_view *view, intel_tile_dims(dev_priv, &tile_width, &tile_height, fb->modifier[1], cpp); + info->uv_offset = fb->offsets[1]; info->plane[1].width = DIV_ROUND_UP(fb->pitches[1], tile_width * cpp); info->plane[1].height = DIV_ROUND_UP(fb->height / 2, tile_height); } @@ -14986,6 +14989,8 @@ static int intel_framebuffer_init(struct drm_device *dev, drm_helper_mode_fill_fb_struct(&intel_fb->base, mode_cmd); intel_fb->obj = obj; + intel_fill_fb_info(dev_priv, &intel_fb->base); + ret = drm_framebuffer_init(dev, &intel_fb->base, &intel_fb_funcs); if (ret) { DRM_ERROR("framebuffer init failed %d\n", ret); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 8b1d18795876..48f7e844f23a 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -118,6 +118,7 @@ enum intel_output_type { struct intel_framebuffer { struct drm_framebuffer base; struct drm_i915_gem_object *obj; + struct intel_rotation_info rot_info; }; struct intel_fbdev { -- cgit v1.2.3 From 1260f07e3e2ff0a9184918b59000713c33f71441 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 17 Feb 2016 21:41:08 +0200 Subject: drm/i915: Dump ddi_pll_sel in hex instead of decimal on HSW/BDW MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On HSW/BDW ddi_pll_sel is the actual register value. Let's dump it in hex so that people migth actually understand what it says. Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1455738073-14502-2-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak --- drivers/gpu/drm/i915/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a03c12ab3098..adc034a531b3 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12304,7 +12304,7 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc, pipe_config->dpll_hw_state.cfgcr1, pipe_config->dpll_hw_state.cfgcr2); } else if (HAS_DDI(dev)) { - DRM_DEBUG_KMS("ddi_pll_sel: %u; dpll_hw_state: wrpll: 0x%x spll: 0x%x\n", + DRM_DEBUG_KMS("ddi_pll_sel: 0x%x; dpll_hw_state: wrpll: 0x%x spll: 0x%x\n", pipe_config->ddi_pll_sel, pipe_config->dpll_hw_state.wrpll, pipe_config->dpll_hw_state.spll); -- cgit v1.2.3 From e3b247da89f0adb04010f9dad6a3e41ed085d24e Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 17 Feb 2016 21:41:09 +0200 Subject: drm/i915: Move the encoder vs. FDI dotclock check out from encoder .get_config() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently we check if the encoder's idea of dotclock agrees with what we calculated based on the FDI parameters. We do this in the encoder .get_config() hooks, which isn't so nice in case the BIOS (or some other outside party) made a mess of the state and we're just trying to take over. So as a prep step to being able sanitize such a bogus state, move the the sanity check to just after we've read out the entire state. If we then need to sanitize a bad state, it should be easier to move the sanity check to occur after sanitation instead of before it. Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1455738073-14502-3-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak --- drivers/gpu/drm/i915/intel_crt.c | 10 +------ drivers/gpu/drm/i915/intel_display.c | 57 ++++++++++++++++++++---------------- drivers/gpu/drm/i915/intel_dp.c | 11 ++----- drivers/gpu/drm/i915/intel_drv.h | 3 -- drivers/gpu/drm/i915/intel_hdmi.c | 3 -- drivers/gpu/drm/i915/intel_lvds.c | 8 +---- drivers/gpu/drm/i915/intel_sdvo.c | 4 +-- 7 files changed, 38 insertions(+), 58 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 505fc5cf26f8..7fe13bcce6fc 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -120,17 +120,9 @@ static unsigned int intel_crt_get_flags(struct intel_encoder *encoder) static void intel_crt_get_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { - struct drm_device *dev = encoder->base.dev; - int dotclock; - pipe_config->base.adjusted_mode.flags |= intel_crt_get_flags(encoder); - dotclock = pipe_config->port_clock; - - if (HAS_PCH_SPLIT(dev)) - ironlake_check_encoder_dotclock(pipe_config, dotclock); - - pipe_config->base.adjusted_mode.crtc_clock = dotclock; + pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock; } static void hsw_crt_get_config(struct intel_encoder *encoder, diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index adc034a531b3..992d4d568c11 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -224,12 +224,11 @@ static void intel_update_czclk(struct drm_i915_private *dev_priv) } static inline u32 /* units of 100MHz */ -intel_fdi_link_freq(struct drm_device *dev) +intel_fdi_link_freq(struct drm_i915_private *dev_priv) { - if (IS_GEN5(dev)) { - struct drm_i915_private *dev_priv = dev->dev_private; + if (IS_GEN5(dev_priv)) return (I915_READ(FDI_PLL_BIOS_0) & FDI_PLL_FB_CLOCK_MASK) + 2; - } else + else return 27; } @@ -6680,7 +6679,7 @@ retry: * Hence the bw of each lane in terms of the mode signal * is: */ - link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10; + link_bw = intel_fdi_link_freq(to_i915(dev)) * MHz(100)/KHz(1)/10; fdi_dotclock = adjusted_mode->crtc_clock; @@ -6692,8 +6691,7 @@ retry: intel_link_compute_m_n(pipe_config->pipe_bpp, lane, fdi_dotclock, link_bw, &pipe_config->fdi_m_n); - ret = ironlake_check_fdi_lanes(intel_crtc->base.dev, - intel_crtc->pipe, pipe_config); + ret = ironlake_check_fdi_lanes(dev, intel_crtc->pipe, pipe_config); if (ret == -EINVAL && pipe_config->pipe_bpp > 6*3) { pipe_config->pipe_bpp -= 2*3; DRM_DEBUG_KMS("fdi link bw constraint, reducing pipe bpp to %i\n", @@ -10831,19 +10829,18 @@ int intel_dotclock_calculate(int link_freq, static void ironlake_pch_clock_get(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { - struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); /* read out port_clock from the DPLL */ i9xx_crtc_clock_get(crtc, pipe_config); /* - * This value does not include pixel_multiplier. - * We will check that port_clock and adjusted_mode.crtc_clock - * agree once we know their relationship in the encoder's - * get_config() function. + * In case there is an active pipe without active ports, + * we may need some idea for the dotclock anyway. + * Calculate one based on the FDI configuration. */ pipe_config->base.adjusted_mode.crtc_clock = - intel_dotclock_calculate(intel_fdi_link_freq(dev) * 10000, + intel_dotclock_calculate(intel_fdi_link_freq(dev_priv) * 10000, &pipe_config->fdi_m_n); } @@ -12872,6 +12869,24 @@ intel_pipe_config_compare(struct drm_device *dev, return ret; } +static void intel_pipe_config_sanity_check(struct drm_i915_private *dev_priv, + const struct intel_crtc_state *pipe_config) +{ + if (pipe_config->has_pch_encoder) { + int fdi_dotclock = intel_dotclock_calculate(intel_fdi_link_freq(dev_priv) * 10000, + &pipe_config->fdi_m_n); + int dotclock = pipe_config->base.adjusted_mode.crtc_clock; + + /* + * FDI already provided one idea for the dotclock. + * Yell if the encoder disagrees. + */ + WARN(!intel_fuzzy_clock_check(fdi_dotclock, dotclock), + "FDI dotclock and encoder dotclock mismatch, fdi: %i, encoder: %i\n", + fdi_dotclock, dotclock); + } +} + static void check_wm_state(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -13045,6 +13060,8 @@ check_crtc_state(struct drm_device *dev, struct drm_atomic_state *old_state) if (!crtc->state->active) continue; + intel_pipe_config_sanity_check(dev_priv, pipe_config); + sw_config = to_intel_crtc_state(crtc->state); if (!intel_pipe_config_compare(dev, sw_config, pipe_config, false)) { @@ -13117,18 +13134,6 @@ intel_modeset_check_state(struct drm_device *dev, check_shared_dpll_state(dev); } -void ironlake_check_encoder_dotclock(const struct intel_crtc_state *pipe_config, - int dotclock) -{ - /* - * FDI already provided one idea for the dotclock. - * Yell if the encoder disagrees. - */ - WARN(!intel_fuzzy_clock_check(pipe_config->base.adjusted_mode.crtc_clock, dotclock), - "FDI dotclock and encoder dotclock mismatch, fdi: %i, encoder: %i\n", - pipe_config->base.adjusted_mode.crtc_clock, dotclock); -} - static void update_scanline_offset(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; @@ -16034,6 +16039,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) drm_calc_timestamping_constants(&crtc->base, &crtc->base.hwmode); update_scanline_offset(crtc); } + + intel_pipe_config_sanity_check(dev_priv, crtc->config); } } diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index f6e4a87a9892..75acb1d15184 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2422,7 +2422,6 @@ static void intel_dp_get_config(struct intel_encoder *encoder, struct drm_i915_private *dev_priv = dev->dev_private; enum port port = dp_to_dig_port(intel_dp)->port; struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); - int dotclock; tmp = I915_READ(intel_dp->output_reg); @@ -2472,13 +2471,9 @@ static void intel_dp_get_config(struct intel_encoder *encoder, pipe_config->port_clock = 270000; } - dotclock = intel_dotclock_calculate(pipe_config->port_clock, - &pipe_config->dp_m_n); - - if (HAS_PCH_SPLIT(dev_priv->dev) && port != PORT_A) - ironlake_check_encoder_dotclock(pipe_config, dotclock); - - pipe_config->base.adjusted_mode.crtc_clock = dotclock; + pipe_config->base.adjusted_mode.crtc_clock = + intel_dotclock_calculate(pipe_config->port_clock, + &pipe_config->dp_m_n); if (is_edp(intel_dp) && dev_priv->vbt.edp_bpp && pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) { diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 48f7e844f23a..859dfc5af28e 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1219,9 +1219,6 @@ void intel_dp_get_m_n(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config); void intel_dp_set_m_n(struct intel_crtc *crtc, enum link_m_n_set m_n); int intel_dotclock_calculate(int link_freq, const struct intel_link_m_n *m_n); -void -ironlake_check_encoder_dotclock(const struct intel_crtc_state *pipe_config, - int dotclock); bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state, int target_clock, intel_clock_t *best_clock); int chv_calc_dpll_params(int refclk, intel_clock_t *pll_clock); diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 80b44c054087..d8060e6251f8 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -952,9 +952,6 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder, if (pipe_config->pixel_multiplier) dotclock /= pipe_config->pixel_multiplier; - if (HAS_PCH_SPLIT(dev_priv->dev)) - ironlake_check_encoder_dotclock(pipe_config, dotclock); - pipe_config->base.adjusted_mode.crtc_clock = dotclock; } diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 30a8403a8f4f..b35342f7b969 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -109,7 +109,6 @@ static void intel_lvds_get_config(struct intel_encoder *encoder, struct drm_i915_private *dev_priv = dev->dev_private; struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); u32 tmp, flags = 0; - int dotclock; tmp = I915_READ(lvds_encoder->reg); if (tmp & LVDS_HSYNC_POLARITY) @@ -130,12 +129,7 @@ static void intel_lvds_get_config(struct intel_encoder *encoder, pipe_config->gmch_pfit.control |= tmp & PANEL_8TO6_DITHER_ENABLE; } - dotclock = pipe_config->port_clock; - - if (HAS_PCH_SPLIT(dev_priv->dev)) - ironlake_check_encoder_dotclock(pipe_config, dotclock); - - pipe_config->base.adjusted_mode.crtc_clock = dotclock; + pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock; } static void intel_pre_enable_lvds(struct intel_encoder *encoder) diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 4ecc076c4041..fae64bc93c1b 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -1398,12 +1398,10 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder, } dotclock = pipe_config->port_clock; + if (pipe_config->pixel_multiplier) dotclock /= pipe_config->pixel_multiplier; - if (HAS_PCH_SPLIT(dev)) - ironlake_check_encoder_dotclock(pipe_config, dotclock); - pipe_config->base.adjusted_mode.crtc_clock = dotclock; /* Cross check the port pixel multiplier with the sdvo encoder state. */ -- cgit v1.2.3 From 21a727b365f8617e9f57229f55c9712b13ab38a6 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 17 Feb 2016 21:41:10 +0200 Subject: drm/i915: Remove the SPLL==270Mhz assumption from intel_fdi_link_freq() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of assuming we've correctly set up SPLL to run at 270Mhz for FDI, let's use the port_clock from pipe_config which should be what we want. This would catch problems if someone misconfigures SPLL for whatever reason. Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1455738073-14502-4-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak --- drivers/gpu/drm/i915/intel_display.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 992d4d568c11..36c470f3c6e5 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -224,12 +224,15 @@ static void intel_update_czclk(struct drm_i915_private *dev_priv) } static inline u32 /* units of 100MHz */ -intel_fdi_link_freq(struct drm_i915_private *dev_priv) +intel_fdi_link_freq(struct drm_i915_private *dev_priv, + const struct intel_crtc_state *pipe_config) { - if (IS_GEN5(dev_priv)) - return (I915_READ(FDI_PLL_BIOS_0) & FDI_PLL_FB_CLOCK_MASK) + 2; + if (HAS_DDI(dev_priv)) + return pipe_config->port_clock; /* SPLL */ + else if (IS_GEN5(dev_priv)) + return ((I915_READ(FDI_PLL_BIOS_0) & FDI_PLL_FB_CLOCK_MASK) + 2) * 10000; else - return 27; + return 270000; } static const intel_limit_t intel_limits_i8xx_dac = { @@ -6679,7 +6682,7 @@ retry: * Hence the bw of each lane in terms of the mode signal * is: */ - link_bw = intel_fdi_link_freq(to_i915(dev)) * MHz(100)/KHz(1)/10; + link_bw = intel_fdi_link_freq(to_i915(dev), pipe_config); fdi_dotclock = adjusted_mode->crtc_clock; @@ -10840,7 +10843,7 @@ static void ironlake_pch_clock_get(struct intel_crtc *crtc, * Calculate one based on the FDI configuration. */ pipe_config->base.adjusted_mode.crtc_clock = - intel_dotclock_calculate(intel_fdi_link_freq(dev_priv) * 10000, + intel_dotclock_calculate(intel_fdi_link_freq(dev_priv, pipe_config), &pipe_config->fdi_m_n); } @@ -12873,7 +12876,7 @@ static void intel_pipe_config_sanity_check(struct drm_i915_private *dev_priv, const struct intel_crtc_state *pipe_config) { if (pipe_config->has_pch_encoder) { - int fdi_dotclock = intel_dotclock_calculate(intel_fdi_link_freq(dev_priv) * 10000, + int fdi_dotclock = intel_dotclock_calculate(intel_fdi_link_freq(dev_priv, pipe_config), &pipe_config->fdi_m_n); int dotclock = pipe_config->base.adjusted_mode.crtc_clock; -- cgit v1.2.3 From 64b46a06313634cf9ce5808ebd63dc82573be34c Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 17 Feb 2016 21:41:11 +0200 Subject: drm/i915: Make the LPT iclkip 20MHz case more generic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The reason for spcial casing 20MHz in the iclkip calculations is that it would overflow the 7 bit divisor value. Let's rewrite the special case to check for just that, and bump up auxdiv when needed. This makes the code work for freqeuencies close to but not exactly 20MHz. The real lower limit for auxdiv=0 is actually: 172800000/(0x7f+2)*64)=~20930 kHz, and below that we must resort to auxdiv=1. Actually this is all very theoretical since we limit the dotclock to min 25MHz with CRT on all platforms. 25Mhz is actually the documented limit in Bspec, so it seems we ought to never need to worry about the auxdiv=1 case. But no harm in having it. Cc: Paulo Zanoni Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1455738073-14502-5-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Paulo Zanoni Reviewed-by: Imre Deak --- drivers/gpu/drm/i915/intel_display.c | 40 +++++++++++++++++------------------- 1 file changed, 19 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 36c470f3c6e5..1f3552397689 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4030,37 +4030,35 @@ static void lpt_disable_iclkip(struct drm_i915_private *dev_priv) /* Program iCLKIP clock to the desired frequency */ static void lpt_program_iclkip(struct drm_crtc *crtc) { - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(crtc->dev); int clock = to_intel_crtc(crtc)->config->base.adjusted_mode.crtc_clock; u32 divsel, phaseinc, auxdiv, phasedir = 0; u32 temp; lpt_disable_iclkip(dev_priv); - /* 20MHz is a corner case which is out of range for the 7-bit divisor */ - if (clock == 20000) { - auxdiv = 1; - divsel = 0x41; - phaseinc = 0x20; - } else { - /* The iCLK virtual clock root frequency is in MHz, - * but the adjusted_mode->crtc_clock in in KHz. To get the - * divisors, it is necessary to divide one by another, so we - * convert the virtual clock precision to KHz here for higher - * precision. - */ + /* The iCLK virtual clock root frequency is in MHz, + * but the adjusted_mode->crtc_clock in in KHz. To get the + * divisors, it is necessary to divide one by another, so we + * convert the virtual clock precision to KHz here for higher + * precision. + */ + for (auxdiv = 0; auxdiv < 2; auxdiv++) { u32 iclk_virtual_root_freq = 172800 * 1000; u32 iclk_pi_range = 64; - u32 desired_divisor, msb_divisor_value, pi_value; + u32 desired_divisor; - desired_divisor = DIV_ROUND_CLOSEST(iclk_virtual_root_freq, clock); - msb_divisor_value = desired_divisor / iclk_pi_range; - pi_value = desired_divisor % iclk_pi_range; + desired_divisor = DIV_ROUND_CLOSEST(iclk_virtual_root_freq, + clock << auxdiv); + divsel = (desired_divisor / iclk_pi_range) - 2; + phaseinc = desired_divisor % iclk_pi_range; - auxdiv = 0; - divsel = msb_divisor_value - 2; - phaseinc = pi_value; + /* + * Near 20MHz is a corner case which is + * out of range for the 7-bit divisor + */ + if (divsel <= 0x7f) + break; } /* This should not happen with any sane values */ -- cgit v1.2.3 From 8802e5b6de51ebbedb8a03e816ca847d860e07f5 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 17 Feb 2016 21:41:12 +0200 Subject: drm/i915: Read out VGA dotclock properly on LPT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rather than assume the VGA dotclock is really the FDI based thing, let's read out the real thing via iclkip, and after readout it'll get to compare it with the FDI based number to make sure they're in sync. Cc: Paulo Zanoni Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1455738073-14502-6-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak --- drivers/gpu/drm/i915/i915_reg.h | 8 ++++++-- drivers/gpu/drm/i915/intel_crt.c | 4 ++++ drivers/gpu/drm/i915/intel_display.c | 37 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_drv.h | 1 + 4 files changed, 48 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index f76cbf3e5d1e..71abf5725495 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7362,9 +7362,11 @@ enum skl_disp_power_wells { /* SBI offsets */ #define SBI_SSCDIVINTPHASE 0x0200 #define SBI_SSCDIVINTPHASE6 0x0600 -#define SBI_SSCDIVINTPHASE_DIVSEL_MASK ((0x7f)<<1) +#define SBI_SSCDIVINTPHASE_DIVSEL_SHIFT 1 +#define SBI_SSCDIVINTPHASE_DIVSEL_MASK (0x7f<<1) #define SBI_SSCDIVINTPHASE_DIVSEL(x) ((x)<<1) -#define SBI_SSCDIVINTPHASE_INCVAL_MASK ((0x7f)<<8) +#define SBI_SSCDIVINTPHASE_INCVAL_SHIFT 8 +#define SBI_SSCDIVINTPHASE_INCVAL_MASK (0x7f<<8) #define SBI_SSCDIVINTPHASE_INCVAL(x) ((x)<<8) #define SBI_SSCDIVINTPHASE_DIR(x) ((x)<<15) #define SBI_SSCDIVINTPHASE_PROPAGATE (1<<0) @@ -7374,6 +7376,8 @@ enum skl_disp_power_wells { #define SBI_SSCCTL_PATHALT (1<<3) #define SBI_SSCCTL_DISABLE (1<<0) #define SBI_SSCAUXDIV6 0x0610 +#define SBI_SSCAUXDIV_FINALDIV2SEL_SHIFT 4 +#define SBI_SSCAUXDIV_FINALDIV2SEL_MASK (1<<4) #define SBI_SSCAUXDIV_FINALDIV2SEL(x) ((x)<<4) #define SBI_DBUFF0 0x2a00 #define SBI_GEN0 0x1f00 diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 7fe13bcce6fc..61eaac2f326d 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -128,6 +128,8 @@ static void intel_crt_get_config(struct intel_encoder *encoder, static void hsw_crt_get_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + intel_ddi_get_config(encoder, pipe_config); pipe_config->base.adjusted_mode.flags &= ~(DRM_MODE_FLAG_PHSYNC | @@ -135,6 +137,8 @@ static void hsw_crt_get_config(struct intel_encoder *encoder, DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC); pipe_config->base.adjusted_mode.flags |= intel_crt_get_flags(encoder); + + pipe_config->base.adjusted_mode.crtc_clock = lpt_get_iclkip(dev_priv); } /* Note: The caller is required to filter out dpms modes not supported by the diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 1f3552397689..44fcff0343f2 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4105,6 +4105,43 @@ static void lpt_program_iclkip(struct drm_crtc *crtc) I915_WRITE(PIXCLK_GATE, PIXCLK_GATE_UNGATE); } +int lpt_get_iclkip(struct drm_i915_private *dev_priv) +{ + u32 divsel, phaseinc, auxdiv; + u32 iclk_virtual_root_freq = 172800 * 1000; + u32 iclk_pi_range = 64; + u32 desired_divisor; + u32 temp; + + if ((I915_READ(PIXCLK_GATE) & PIXCLK_GATE_UNGATE) == 0) + return 0; + + mutex_lock(&dev_priv->sb_lock); + + temp = intel_sbi_read(dev_priv, SBI_SSCCTL6, SBI_ICLK); + if (temp & SBI_SSCCTL_DISABLE) { + mutex_unlock(&dev_priv->sb_lock); + return 0; + } + + temp = intel_sbi_read(dev_priv, SBI_SSCDIVINTPHASE6, SBI_ICLK); + divsel = (temp & SBI_SSCDIVINTPHASE_DIVSEL_MASK) >> + SBI_SSCDIVINTPHASE_DIVSEL_SHIFT; + phaseinc = (temp & SBI_SSCDIVINTPHASE_INCVAL_MASK) >> + SBI_SSCDIVINTPHASE_INCVAL_SHIFT; + + temp = intel_sbi_read(dev_priv, SBI_SSCAUXDIV6, SBI_ICLK); + auxdiv = (temp & SBI_SSCAUXDIV_FINALDIV2SEL_MASK) >> + SBI_SSCAUXDIV_FINALDIV2SEL_SHIFT; + + mutex_unlock(&dev_priv->sb_lock); + + desired_divisor = (divsel + 2) * iclk_pi_range + phaseinc; + + return DIV_ROUND_CLOSEST(iclk_virtual_root_freq, + desired_divisor << auxdiv); +} + static void ironlake_pch_transcoder_set_timings(struct intel_crtc *crtc, enum pipe pch_transcoder) { diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 859dfc5af28e..cb413e246267 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1181,6 +1181,7 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, int vlv_force_pll_on(struct drm_device *dev, enum pipe pipe, const struct dpll *dpll); void vlv_force_pll_off(struct drm_device *dev, enum pipe pipe); +int lpt_get_iclkip(struct drm_i915_private *dev_priv); /* modesetting asserts */ void assert_panel_unlocked(struct drm_i915_private *dev_priv, -- cgit v1.2.3 From debded848dee028d7f1f1e42a4e118df9636fb84 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 17 Feb 2016 21:41:13 +0200 Subject: drm/i915: Try to fix CRT port clock limits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LPT/WPT-H are limited to max 180 MHz CRT dotclock. Most other platforms have a limit of 350 MHz. Supposedly gen3 and gen4 go up to 400 MHz. VLV is a bit special since the docs are poor. Supposedly the DAC would be good up to 355 MHz, but currently we limit the DPLL to 270 MHz, so we'll have to limit the port clock to the same unless we change the DPLL limits. Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1455738073-14502-7-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak --- drivers/gpu/drm/i915/intel_crt.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 61eaac2f326d..583cae744a1a 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -218,18 +218,26 @@ intel_crt_mode_valid(struct drm_connector *connector, { struct drm_device *dev = connector->dev; int max_dotclk = to_i915(dev)->max_dotclk_freq; + int max_clock; - int max_clock = 0; if (mode->flags & DRM_MODE_FLAG_DBLSCAN) return MODE_NO_DBLESCAN; if (mode->clock < 25000) return MODE_CLOCK_LOW; - if (IS_GEN2(dev)) - max_clock = 350000; - else + if (HAS_PCH_LPT(dev)) + max_clock = 180000; + else if (IS_VALLEYVIEW(dev)) + /* + * 270 MHz due to current DPLL limits, + * DAC limit supposedly 355 MHz. + */ + max_clock = 270000; + else if (IS_GEN3(dev) || IS_GEN4(dev)) max_clock = 400000; + else + max_clock = 350000; if (mode->clock > max_clock) return MODE_CLOCK_HIGH; -- cgit v1.2.3 From f85db0590dd8601a1fc513a40dd002c3bdf56b84 Mon Sep 17 00:00:00 2001 From: "arun.siluvery@linux.intel.com" Date: Tue, 1 Mar 2016 11:24:36 +0000 Subject: drm/i915/error: Capture WA ctx batch in error state execute during context save/restore, good to have them in error state. v2: use wa_ctx->size and print only size values (Mika) v3: simplify conditions when recording and freeing object (Chris) v4: resolve checkpatch errors (Tvrtko) Cc: Tvrtko Ursulin Cc: Chris Wilson Cc: Mika Kuoppala Reviewed-by: Mika Kuoppala Signed-off-by: Arun Siluvery Signed-off-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1456831476-10782-1-git-send-email-arun.siluvery@linux.intel.com --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_gpu_error.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 671295523317..7d2b07fc1617 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -561,6 +561,8 @@ struct drm_i915_error_state { u32 *pages[0]; } *ringbuffer, *batchbuffer, *wa_batchbuffer, *ctx, *hws_page; + struct drm_i915_error_object *wa_ctx; + struct drm_i915_error_request { long jiffies; u32 seqno; diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 831895b8cb75..3b6bfbf35482 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -493,6 +493,28 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, } } + obj = error->ring[i].wa_ctx; + if (obj) { + u64 wa_ctx_offset = obj->gtt_offset; + u32 *wa_ctx_page = &obj->pages[0][0]; + struct intel_engine_cs *ring = &dev_priv->ring[RCS]; + u32 wa_ctx_size = (ring->wa_ctx.indirect_ctx.size + + ring->wa_ctx.per_ctx.size); + + err_printf(m, "%s --- WA ctx batch buffer = 0x%08llx\n", + dev_priv->ring[i].name, wa_ctx_offset); + offset = 0; + for (elt = 0; elt < wa_ctx_size; elt += 4) { + err_printf(m, "[%04x] %08x %08x %08x %08x\n", + offset, + wa_ctx_page[elt + 0], + wa_ctx_page[elt + 1], + wa_ctx_page[elt + 2], + wa_ctx_page[elt + 3]); + offset += 16; + } + } + if ((obj = error->ring[i].ctx)) { err_printf(m, "%s --- HW Context = 0x%08x\n", dev_priv->ring[i].name, @@ -585,6 +607,7 @@ static void i915_error_state_free(struct kref *error_ref) i915_error_object_free(error->ring[i].hws_page); i915_error_object_free(error->ring[i].ctx); kfree(error->ring[i].requests); + i915_error_object_free(error->ring[i].wa_ctx); } i915_error_object_free(error->semaphore_obj); @@ -1067,6 +1090,12 @@ static void i915_gem_record_rings(struct drm_device *dev, error->ring[i].hws_page = i915_error_ggtt_object_create(dev_priv, ring->status_page.obj); + if (ring->wa_ctx.obj) { + error->ring[i].wa_ctx = + i915_error_ggtt_object_create(dev_priv, + ring->wa_ctx.obj); + } + i915_gem_record_active_context(ring, error, &error->ring[i]); count = 0; -- cgit v1.2.3 From 2622d79bd9d18fd04b650234e6a218c5f95cf308 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 29 Feb 2016 22:49:02 +0200 Subject: drm/i915/skl: Fix power domain suspend sequence During system suspend we need to first disable power wells then unitialize the display core. In case power well support is disabled we did this in the wrong order, so fix this up. Fixes: d314cd43 ("drm/i915: fix handling of the disable_power_well module option") CC: stable@vger.kernel.org CC: Patrik Jakobsson Signed-off-by: Imre Deak Reviewed-by: Patrik Jakobsson Link: http://patchwork.freedesktop.org/patch/msgid/1456778945-5411-1-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/intel_runtime_pm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 4172e73212cd..6e54d978d9d4 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -2319,15 +2319,15 @@ void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume) */ void intel_power_domains_suspend(struct drm_i915_private *dev_priv) { - if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) - skl_display_core_uninit(dev_priv); - /* * Even if power well support was disabled we still want to disable * power wells while we are system suspended. */ if (!i915.disable_power_well) intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); + + if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) + skl_display_core_uninit(dev_priv); } /** -- cgit v1.2.3 From a37baf3b832b862d09e10067b7d2065b3b42a729 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 29 Feb 2016 22:49:03 +0200 Subject: drm/i915/gen9: Sanitize handling of allowed DC states We can simplify the conditions selecting the target DC state during runtime by calculating the allowed DC states in advance during driver loading. This also makes it easier to disable DC states depending on the i915.disable_power_well module option, added in the next patch. v2: - Print a debug message if the requested max DC value was adjusted due to a platform limit. Also debug print the calculated mask value. (Patrik) CC: Patrik Jakobsson Signed-off-by: Imre Deak Reviewed-by: Patrik Jakobsson Link: http://patchwork.freedesktop.org/patch/msgid/1456778945-5411-2-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_runtime_pm.c | 78 ++++++++++++++++++++++++--------- 2 files changed, 58 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 7d2b07fc1617..0e2fb5bdd0fb 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -756,6 +756,7 @@ struct intel_csr { i915_reg_t mmioaddr[8]; uint32_t mmiodata[8]; uint32_t dc_state; + uint32_t allowed_dc_mask; }; #define DEV_INFO_FOR_EACH_FLAG(func, sep) \ diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 6e54d978d9d4..30df9de25ccb 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -538,12 +538,8 @@ static void gen9_set_dc_state(struct drm_i915_private *dev_priv, uint32_t state) else mask |= DC_STATE_EN_UPTO_DC6; - WARN_ON_ONCE(state & ~mask); - - if (i915.enable_dc == 0) - state = DC_STATE_DISABLE; - else if (i915.enable_dc == 1 && state > DC_STATE_EN_UPTO_DC5) - state = DC_STATE_EN_UPTO_DC5; + if (WARN_ON_ONCE(state & ~dev_priv->csr.allowed_dc_mask)) + state &= dev_priv->csr.allowed_dc_mask; val = I915_READ(DC_STATE_EN); DRM_DEBUG_KMS("Setting DC state from %02x to %02x\n", @@ -659,8 +655,7 @@ static void gen9_disable_dc5_dc6(struct drm_i915_private *dev_priv) { assert_can_disable_dc5(dev_priv); - if ((IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) && - i915.enable_dc != 0 && i915.enable_dc != 1) + if (dev_priv->csr.allowed_dc_mask & DC_STATE_EN_UPTO_DC6) assert_can_disable_dc6(dev_priv); gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); @@ -839,26 +834,19 @@ static void gen9_dc_off_power_well_enable(struct drm_i915_private *dev_priv, static void gen9_dc_off_power_well_disable(struct drm_i915_private *dev_priv, struct i915_power_well *power_well) { - if ((IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) && - i915.enable_dc != 0 && i915.enable_dc != 1) + if (dev_priv->csr.allowed_dc_mask & DC_STATE_EN_UPTO_DC6) skl_enable_dc6(dev_priv); - else + else if (dev_priv->csr.allowed_dc_mask & DC_STATE_EN_UPTO_DC5) gen9_enable_dc5(dev_priv); } static void gen9_dc_off_power_well_sync_hw(struct drm_i915_private *dev_priv, struct i915_power_well *power_well) { - if (power_well->count > 0) { - gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); - } else { - if ((IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) && - i915.enable_dc != 0 && - i915.enable_dc != 1) - gen9_set_dc_state(dev_priv, DC_STATE_EN_UPTO_DC6); - else - gen9_set_dc_state(dev_priv, DC_STATE_EN_UPTO_DC5); - } + if (power_well->count > 0) + gen9_dc_off_power_well_enable(dev_priv, power_well); + else + gen9_dc_off_power_well_disable(dev_priv, power_well); } static void i9xx_always_on_power_well_noop(struct drm_i915_private *dev_priv, @@ -2023,6 +2011,52 @@ sanitize_disable_power_well_option(const struct drm_i915_private *dev_priv, return 1; } +static uint32_t get_allowed_dc_mask(const struct drm_i915_private *dev_priv, + int enable_dc) +{ + uint32_t mask; + int requested_dc; + int max_dc; + + if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) { + max_dc = 2; + mask = 0; + } else if (IS_BROXTON(dev_priv)) { + max_dc = 1; + /* + * DC9 has a separate HW flow from the rest of the DC states, + * not depending on the DMC firmware. It's needed by system + * suspend/resume, so allow it unconditionally. + */ + mask = DC_STATE_EN_DC9; + } else { + max_dc = 0; + mask = 0; + } + + if (enable_dc >= 0 && enable_dc <= max_dc) { + requested_dc = enable_dc; + } else if (enable_dc == -1) { + requested_dc = max_dc; + } else if (enable_dc > max_dc && enable_dc <= 2) { + DRM_DEBUG_KMS("Adjusting requested max DC state (%d->%d)\n", + enable_dc, max_dc); + requested_dc = max_dc; + } else { + DRM_ERROR("Unexpected value for enable_dc (%d)\n", enable_dc); + requested_dc = max_dc; + } + + if (requested_dc > 1) + mask |= DC_STATE_EN_UPTO_DC6; + if (requested_dc > 0) + mask |= DC_STATE_EN_UPTO_DC5; + + DRM_DEBUG_KMS("Allowed DC state mask %02x\n", mask); + + return mask; +} + #define set_power_wells(power_domains, __power_wells) ({ \ (power_domains)->power_wells = (__power_wells); \ (power_domains)->power_well_count = ARRAY_SIZE(__power_wells); \ @@ -2041,6 +2075,8 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv) i915.disable_power_well = sanitize_disable_power_well_option(dev_priv, i915.disable_power_well); + dev_priv->csr.allowed_dc_mask = get_allowed_dc_mask(dev_priv, + i915.enable_dc); BUILD_BUG_ON(POWER_DOMAIN_NUM > 31); -- cgit v1.2.3 From 66e2c4c39cc37beaccc24c9d14c75d627fce9cf4 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 29 Feb 2016 22:49:04 +0200 Subject: drm/i915/gen9: Disable DC states if power well support is disabled If power well support is disabled via the i915.disable_power_well module option we should never enable DC states. Currently we would enable DC states even in this case during system suspend, where we need to disable all power wells regardless of the disable_power_well option. CC: Patrik Jakobsson Signed-off-by: Imre Deak Reviewed-by: Patrik Jakobsson Link: http://patchwork.freedesktop.org/patch/msgid/1456778945-5411-3-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/intel_runtime_pm.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 30df9de25ccb..f0ca5134621e 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -2034,6 +2034,9 @@ static uint32_t get_allowed_dc_mask(const struct drm_i915_private *dev_priv, mask = 0; } + if (!i915.disable_power_well) + max_dc = 0; + if (enable_dc >= 0 && enable_dc <= max_dc) { requested_dc = enable_dc; } else if (enable_dc == -1) { -- cgit v1.2.3 From 5b773eb422f1671852f78548b18ec7c7de34b3cb Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 29 Feb 2016 22:49:05 +0200 Subject: drm/i915/gen9: Remove state asserts when disabling DC states Disabling the DC states when it's already disabled is a valid scenario, for example during HW state sanitization during driver loading and resuming or when DC states are disabled via the i915.enable_dc or disable_power_well option. CC: Patrik Jakobsson Signed-off-by: Imre Deak Reviewed-by: Patrik Jakobsson Link: http://patchwork.freedesktop.org/patch/msgid/1456778945-5411-4-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/intel_runtime_pm.c | 41 +-------------------------------- 1 file changed, 1 insertion(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index f0ca5134621e..09c52b1a3a54 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -458,8 +458,6 @@ static void assert_can_enable_dc9(struct drm_i915_private *dev_priv) static void assert_can_disable_dc9(struct drm_i915_private *dev_priv) { WARN(intel_irqs_enabled(dev_priv), "Interrupts not disabled yet.\n"); - WARN(!(I915_READ(DC_STATE_EN) & DC_STATE_EN_DC9), - "DC9 already programmed to be disabled.\n"); WARN(I915_READ(DC_STATE_EN) & DC_STATE_EN_UPTO_DC5, "DC5 still not disabled.\n"); @@ -602,18 +600,6 @@ static void assert_can_enable_dc5(struct drm_i915_private *dev_priv) assert_csr_loaded(dev_priv); } -static void assert_can_disable_dc5(struct drm_i915_private *dev_priv) -{ - /* - * During initialization, the firmware may not be loaded yet. - * We still want to make sure that the DC enabling flag is cleared. - */ - if (dev_priv->power_domains.initializing) - return; - - assert_rpm_wakelock_held(dev_priv); -} - static void gen9_enable_dc5(struct drm_i915_private *dev_priv) { assert_can_enable_dc5(dev_priv); @@ -638,29 +624,6 @@ static void assert_can_enable_dc6(struct drm_i915_private *dev_priv) assert_csr_loaded(dev_priv); } -static void assert_can_disable_dc6(struct drm_i915_private *dev_priv) -{ - /* - * During initialization, the firmware may not be loaded yet. - * We still want to make sure that the DC enabling flag is cleared. - */ - if (dev_priv->power_domains.initializing) - return; - - WARN_ONCE(!(I915_READ(DC_STATE_EN) & DC_STATE_EN_UPTO_DC6), - "DC6 already programmed to be disabled.\n"); -} - -static void gen9_disable_dc5_dc6(struct drm_i915_private *dev_priv) -{ - assert_can_disable_dc5(dev_priv); - - if (dev_priv->csr.allowed_dc_mask & DC_STATE_EN_UPTO_DC6) - assert_can_disable_dc6(dev_priv); - - gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); -} - void skl_enable_dc6(struct drm_i915_private *dev_priv) { assert_can_enable_dc6(dev_priv); @@ -673,8 +636,6 @@ void skl_enable_dc6(struct drm_i915_private *dev_priv) void skl_disable_dc6(struct drm_i915_private *dev_priv) { - assert_can_disable_dc6(dev_priv); - DRM_DEBUG_KMS("Disabling DC6\n"); gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); @@ -828,7 +789,7 @@ static bool gen9_dc_off_power_well_enabled(struct drm_i915_private *dev_priv, static void gen9_dc_off_power_well_enable(struct drm_i915_private *dev_priv, struct i915_power_well *power_well) { - gen9_disable_dc5_dc6(dev_priv); + gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); } static void gen9_dc_off_power_well_disable(struct drm_i915_private *dev_priv, -- cgit v1.2.3 From 32fff610f7cf05260300f6c18700e9e0ac5910fb Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Tue, 1 Mar 2016 17:04:01 +0100 Subject: drm/i915: Do not return unknown status when load detection is tested. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes the IGT test, which interprets unknown status as failed to acquire load detect pipe. Cc: Gabriel Feceoru Signed-off-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1456848241-6431-1-git-send-email-maarten.lankhorst@linux.intel.com Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_crt.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 583cae744a1a..5f12a195d55c 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -656,6 +656,8 @@ intel_crt_detect(struct drm_connector *connector, bool force) else if (INTEL_INFO(dev)->gen < 4) status = intel_crt_load_detect(crt, to_intel_crtc(connector->state->crtc)->pipe); + else if (i915.load_detect_test) + status = connector_status_disconnected; else status = connector_status_unknown; intel_release_load_detect_pipe(connector, &tmp, &ctx); -- cgit v1.2.3 From ca377809d657ea3ba249e97d073a7373e383ab6a Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Wed, 2 Mar 2016 12:10:31 +0000 Subject: drm/i915: Avoid snooping with userptr where not supported commit e5756c10d841ddb448293c849392f3d6b809561f Author: Imre Deak Date: Fri Aug 14 18:43:30 2015 +0300 drm/i915/bxt: don't allow cached GEM mappings on A stepping Added an exception of disallowing snooping for Broxton A stepping hardware but userptr was still enabling it regardless. Move the check to HAS_SNOOP now that it is used from multiple call sites and use it. v2: Userptr cannot be supported when it cannot be coherent and generalize the code better. (Chris Wilson) v3: Make has_snoop true only when !has_llc. (Chris Wilson) Signed-off-by: Tvrtko Ursulin Cc: Chris Wilson Cc: Imre Deak Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1456920631-34302-1-git-send-email-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/i915_dma.c | 4 ++++ drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_gem.c | 2 +- drivers/gpu/drm/i915/i915_gem_userptr.c | 7 +++++++ 4 files changed, 14 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 36c0cf131e93..4aa3db61a535 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -853,6 +853,10 @@ static void intel_device_info_runtime_init(struct drm_device *dev) else if (INTEL_INFO(dev)->gen >= 9) gen9_sseu_info_init(dev); + /* Snooping is broken on BXT A stepping. */ + info->has_snoop = !info->has_llc; + info->has_snoop &= !IS_BXT_REVID(dev, 0, BXT_REVID_A1); + DRM_DEBUG_DRIVER("slice total: %u\n", info->slice_total); DRM_DEBUG_DRIVER("subslice total: %u\n", info->subslice_total); DRM_DEBUG_DRIVER("subslice per slice: %u\n", info->subslice_per_slice); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0e2fb5bdd0fb..2cb0a411c10e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -786,6 +786,7 @@ struct intel_csr { func(overlay_needs_physical) sep \ func(supports_tv) sep \ func(has_llc) sep \ + func(has_snoop) sep \ func(has_ddi) sep \ func(has_fpga_dbg) @@ -2630,6 +2631,7 @@ struct drm_i915_cmd_table { #define HAS_BLT(dev) (INTEL_INFO(dev)->ring_mask & BLT_RING) #define HAS_VEBOX(dev) (INTEL_INFO(dev)->ring_mask & VEBOX_RING) #define HAS_LLC(dev) (INTEL_INFO(dev)->has_llc) +#define HAS_SNOOP(dev) (INTEL_INFO(dev)->has_snoop) #define HAS_WT(dev) ((IS_HASWELL(dev) || IS_BROADWELL(dev)) && \ __I915__(dev)->ellc_size) #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 3d31d3ac589e..b854af2c4141 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3949,7 +3949,7 @@ int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data, * cacheline, whereas normally such cachelines would get * invalidated. */ - if (IS_BXT_REVID(dev, 0, BXT_REVID_A1)) + if (!HAS_LLC(dev) && !HAS_SNOOP(dev)) return -ENODEV; level = I915_CACHE_LLC; diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index 4b09c840d493..54088a4d6498 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -758,6 +758,13 @@ i915_gem_userptr_ioctl(struct drm_device *dev, void *data, struct drm_file *file int ret; u32 handle; + if (!HAS_LLC(dev) && !HAS_SNOOP(dev)) { + /* We cannot support coherent userptr objects on hw without + * LLC and broken snooping. + */ + return -ENODEV; + } + if (args->flags & ~(I915_USERPTR_READ_ONLY | I915_USERPTR_UNSYNCHRONIZED)) return -EINVAL; -- cgit v1.2.3 From 933bfb44b228f26e09364d122576c8e938588d4f Mon Sep 17 00:00:00 2001 From: Sagar Arun Kamble Date: Mon, 8 Feb 2016 22:47:11 +0530 Subject: drm/i915: Hold RPM reference while setting freq limits through sysfs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This changes ensures device is active when frequency limits are changed. This is needed as we are writing to register RPNSWREQ in intel_set_rps. If not done, might lead to undesired errors like: [ 1965.189137] [drm:fw_domains_get] *ERROR* blitter: timed out waiting for forcewake ack to clear. v2: Added elaborate commit message. (Jani) Fixing RPM reference drop in early exit paths. (Ville) Signed-off-by: Sagar Arun Kamble Link: http://patchwork.freedesktop.org/patch/msgid/1454951831-11778-1-git-send-email-sagar.a.kamble@intel.com Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/i915_sysfs.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c index c6188dddb341..2d576b7ff299 100644 --- a/drivers/gpu/drm/i915/i915_sysfs.c +++ b/drivers/gpu/drm/i915/i915_sysfs.c @@ -370,6 +370,8 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev, flush_delayed_work(&dev_priv->rps.delayed_resume_work); + intel_runtime_pm_get(dev_priv); + mutex_lock(&dev_priv->rps.hw_lock); val = intel_freq_opcode(dev_priv, val); @@ -378,6 +380,7 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev, val > dev_priv->rps.max_freq || val < dev_priv->rps.min_freq_softlimit) { mutex_unlock(&dev_priv->rps.hw_lock); + intel_runtime_pm_put(dev_priv); return -EINVAL; } @@ -398,6 +401,8 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev, mutex_unlock(&dev_priv->rps.hw_lock); + intel_runtime_pm_put(dev_priv); + return count; } @@ -433,6 +438,8 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev, flush_delayed_work(&dev_priv->rps.delayed_resume_work); + intel_runtime_pm_get(dev_priv); + mutex_lock(&dev_priv->rps.hw_lock); val = intel_freq_opcode(dev_priv, val); @@ -441,6 +448,7 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev, val > dev_priv->rps.max_freq || val > dev_priv->rps.max_freq_softlimit) { mutex_unlock(&dev_priv->rps.hw_lock); + intel_runtime_pm_put(dev_priv); return -EINVAL; } @@ -457,6 +465,8 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev, mutex_unlock(&dev_priv->rps.hw_lock); + intel_runtime_pm_put(dev_priv); + return count; } -- cgit v1.2.3 From 1a426d6116467e09954289ee8c273e1bcc003adc Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Wed, 2 Mar 2016 12:36:03 +0100 Subject: drm/i915: Handle invalid ilk pipe watermarks correctly. This function returns an int, but when ilk_validate_pipe_wm fails it returns false, which is 0 (success). As a result invalid watermarks are applied, while they should have been rejected. Fix this by returning -EINVAL. Fixes: ed4a6a7ca853 ("drm/i915: Add two-stage ILK-style watermark programming (v11)") Cc: Matt Roper Signed-off-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1456918563-28696-1-git-send-email-maarten.lankhorst@linux.intel.com Reviewed-by: Matt Roper --- drivers/gpu/drm/i915/intel_pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index d33de954a2e4..7df5a6318c51 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2345,7 +2345,7 @@ static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc, pipe_wm->linetime = hsw_compute_linetime_wm(dev, cstate); if (!ilk_validate_pipe_wm(dev, pipe_wm)) - return false; + return -EINVAL; ilk_compute_wm_reg_maximums(dev, 1, &max); -- cgit v1.2.3 From d81f04c5ef5d6086e70656a32ff7c1b2bf998724 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Wed, 2 Mar 2016 12:38:06 +0100 Subject: drm/i915: Allow preservation of watermarks, v2. As Paulo has noted we can help bisectability by separating computing watermarks on a noop in 2 separate commits. This patch no longer clears the crtc watermark state, but recalculates it completely. Regardless whether a level is used the full values for each level are calculated. If a level is invalid wm[level].enable is unset. Changes since v1: - Only call ilk_validate_wm_level when level <= usable_level. (Ville) Signed-off-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/56D6D09E.5040007@linux.intel.com Reviewed-by: Paulo Zanoni --- drivers/gpu/drm/i915/intel_pm.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 7df5a6318c51..161c66b9dcdc 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2300,7 +2300,7 @@ static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc, struct intel_plane_state *pristate = NULL; struct intel_plane_state *sprstate = NULL; struct intel_plane_state *curstate = NULL; - int level, max_level = ilk_wm_max_level(dev); + int level, max_level = ilk_wm_max_level(dev), usable_level; struct ilk_wm_maximums max; cstate = intel_atomic_get_crtc_state(state, intel_crtc); @@ -2308,7 +2308,6 @@ static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc, return PTR_ERR(cstate); pipe_wm = &cstate->wm.optimal.ilk; - memset(pipe_wm, 0, sizeof(*pipe_wm)); for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { ps = drm_atomic_get_plane_state(state, @@ -2330,13 +2329,15 @@ static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc, (drm_rect_width(&sprstate->dst) != drm_rect_width(&sprstate->src) >> 16 || drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16); + usable_level = max_level; + /* ILK/SNB: LP2+ watermarks only w/o sprites */ if (INTEL_INFO(dev)->gen <= 6 && sprstate->visible) - max_level = 1; + usable_level = 1; /* ILK/SNB/IVB: LP1+ watermarks only w/o scaling */ if (pipe_wm->sprites_scaled) - max_level = 0; + usable_level = 0; ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate, pristate, sprstate, curstate, &pipe_wm->wm[0]); @@ -2350,20 +2351,22 @@ static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc, ilk_compute_wm_reg_maximums(dev, 1, &max); for (level = 1; level <= max_level; level++) { - struct intel_wm_level wm = {}; + struct intel_wm_level *wm = &pipe_wm->wm[level]; ilk_compute_wm_level(dev_priv, intel_crtc, level, cstate, - pristate, sprstate, curstate, &wm); + pristate, sprstate, curstate, wm); /* * Disable any watermark level that exceeds the * register maximums since such watermarks are * always invalid. */ - if (!ilk_validate_wm_level(level, &max, &wm)) - break; - - pipe_wm->wm[level] = wm; + if (level > usable_level) { + wm->enable = false; + } else if (!ilk_validate_wm_level(level, &max, wm)) { + wm->enable = false; + usable_level = level; + } } return 0; -- cgit v1.2.3 From e3bddded40e23a4a40f4cc7df65180a6041646dd Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Tue, 1 Mar 2016 11:07:22 +0100 Subject: drm/i915: Only recalculate wm's for planes part of the state, v2. Only planes that are part of the state should be used for recalculating watermarks. For planes not part of the state the previous patch allows us to re-use the old values since they're calculated even for levels that are not actively used. Changes since v1: - Remove big if from intel_crtc_atomic_check. - Remove extra newline. - Remove memset in ilk_compute_pipe_wm. Signed-off-by: Maarten Lankhorst Cc: Matt Roper Link: http://patchwork.freedesktop.org/patch/msgid/1456826842-32553-2-git-send-email-maarten.lankhorst@linux.intel.com Reviewed-by: Paulo Zanoni --- drivers/gpu/drm/i915/i915_drv.h | 3 +- drivers/gpu/drm/i915/intel_display.c | 2 +- drivers/gpu/drm/i915/intel_drv.h | 12 ++++++++ drivers/gpu/drm/i915/intel_pm.c | 59 ++++++++++++++++++++---------------- 4 files changed, 47 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 2cb0a411c10e..c8791f661dd1 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -631,8 +631,7 @@ struct drm_i915_display_funcs { int target, int refclk, struct dpll *match_clock, struct dpll *best_clock); - int (*compute_pipe_wm)(struct intel_crtc *crtc, - struct drm_atomic_state *state); + int (*compute_pipe_wm)(struct intel_crtc_state *cstate); int (*compute_intermediate_wm)(struct drm_device *dev, struct intel_crtc *intel_crtc, struct intel_crtc_state *newstate); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 44fcff0343f2..08c363127885 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12106,7 +12106,7 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc, ret = 0; if (dev_priv->display.compute_pipe_wm) { - ret = dev_priv->display.compute_pipe_wm(intel_crtc, state); + ret = dev_priv->display.compute_pipe_wm(pipe_config); if (ret) { DRM_DEBUG_KMS("Target pipe watermarks are invalid\n"); return ret; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index cb413e246267..6c0085496fca 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1628,6 +1628,18 @@ intel_atomic_get_crtc_state(struct drm_atomic_state *state, return to_intel_crtc_state(crtc_state); } + +static inline struct intel_plane_state * +intel_atomic_get_existing_plane_state(struct drm_atomic_state *state, + struct intel_plane *plane) +{ + struct drm_plane_state *plane_state; + + plane_state = drm_atomic_get_existing_plane_state(state, &plane->base); + + return to_intel_plane_state(plane_state); +} + int intel_atomic_setup_scalers(struct drm_device *dev, struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 161c66b9dcdc..f65e84137060 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -1996,11 +1996,18 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv, cur_latency *= 5; } - result->pri_val = ilk_compute_pri_wm(cstate, pristate, - pri_latency, level); - result->spr_val = ilk_compute_spr_wm(cstate, sprstate, spr_latency); - result->cur_val = ilk_compute_cur_wm(cstate, curstate, cur_latency); - result->fbc_val = ilk_compute_fbc_wm(cstate, pristate, result->pri_val); + if (pristate) { + result->pri_val = ilk_compute_pri_wm(cstate, pristate, + pri_latency, level); + result->fbc_val = ilk_compute_fbc_wm(cstate, pristate, result->pri_val); + } + + if (sprstate) + result->spr_val = ilk_compute_spr_wm(cstate, sprstate, spr_latency); + + if (curstate) + result->cur_val = ilk_compute_cur_wm(cstate, curstate, cur_latency); + result->enable = true; } @@ -2288,51 +2295,51 @@ static bool ilk_validate_pipe_wm(struct drm_device *dev, } /* Compute new watermarks for the pipe */ -static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc, - struct drm_atomic_state *state) +static int ilk_compute_pipe_wm(struct intel_crtc_state *cstate) { + struct drm_atomic_state *state = cstate->base.state; + struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); struct intel_pipe_wm *pipe_wm; - struct drm_device *dev = intel_crtc->base.dev; + struct drm_device *dev = state->dev; const struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc_state *cstate = NULL; struct intel_plane *intel_plane; - struct drm_plane_state *ps; struct intel_plane_state *pristate = NULL; struct intel_plane_state *sprstate = NULL; struct intel_plane_state *curstate = NULL; int level, max_level = ilk_wm_max_level(dev), usable_level; struct ilk_wm_maximums max; - cstate = intel_atomic_get_crtc_state(state, intel_crtc); - if (IS_ERR(cstate)) - return PTR_ERR(cstate); - pipe_wm = &cstate->wm.optimal.ilk; for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { - ps = drm_atomic_get_plane_state(state, - &intel_plane->base); - if (IS_ERR(ps)) - return PTR_ERR(ps); + struct intel_plane_state *ps; + + ps = intel_atomic_get_existing_plane_state(state, + intel_plane); + if (!ps) + continue; if (intel_plane->base.type == DRM_PLANE_TYPE_PRIMARY) - pristate = to_intel_plane_state(ps); + pristate = ps; else if (intel_plane->base.type == DRM_PLANE_TYPE_OVERLAY) - sprstate = to_intel_plane_state(ps); + sprstate = ps; else if (intel_plane->base.type == DRM_PLANE_TYPE_CURSOR) - curstate = to_intel_plane_state(ps); + curstate = ps; } pipe_wm->pipe_enabled = cstate->base.active; - pipe_wm->sprites_enabled = sprstate->visible; - pipe_wm->sprites_scaled = sprstate->visible && - (drm_rect_width(&sprstate->dst) != drm_rect_width(&sprstate->src) >> 16 || - drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16); + if (sprstate) { + pipe_wm->sprites_enabled = sprstate->visible; + pipe_wm->sprites_scaled = sprstate->visible && + (drm_rect_width(&sprstate->dst) != drm_rect_width(&sprstate->src) >> 16 || + drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16); + } + usable_level = max_level; /* ILK/SNB: LP2+ watermarks only w/o sprites */ - if (INTEL_INFO(dev)->gen <= 6 && sprstate->visible) + if (INTEL_INFO(dev)->gen <= 6 && pipe_wm->sprites_enabled) usable_level = 1; /* ILK/SNB/IVB: LP1+ watermarks only w/o scaling */ -- cgit v1.2.3 From 782d25cac6373457b9a1c8a5efcd9194eb97ba80 Mon Sep 17 00:00:00 2001 From: Deepak M Date: Mon, 15 Feb 2016 22:43:57 +0530 Subject: drm/i915/bxt: Additional MIPI clock divider form B0 stepping onwards The MIPI clock calculations for the addtional clock are revised from B0 stepping onwards, the bit definitions have changed compared to old stepping. v2: Fixing compilation warning. v3: Retained the old Macros (Jani) Signed-off-by: Deepak M Tested-by: Ramalingam C # BXT-T with Tianma panel Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1455556437-29267-1-git-send-email-m.deepak@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 96 +++++++++++++++++++----------------- drivers/gpu/drm/i915/intel_dsi_pll.c | 56 ++++++++++++++------- 2 files changed, 89 insertions(+), 63 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 71abf5725495..65f9bb9754ab 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7669,58 +7669,62 @@ enum skl_disp_power_wells { #define BXT_MIPI_DIV_SHIFT(port) \ _MIPI_PORT(port, BXT_MIPI1_DIV_SHIFT, \ BXT_MIPI2_DIV_SHIFT) -/* Var clock divider to generate TX source. Result must be < 39.5 M */ -#define BXT_MIPI1_ESCLK_VAR_DIV_MASK (0x3F << 26) -#define BXT_MIPI2_ESCLK_VAR_DIV_MASK (0x3F << 10) -#define BXT_MIPI_ESCLK_VAR_DIV_MASK(port) \ - _MIPI_PORT(port, BXT_MIPI1_ESCLK_VAR_DIV_MASK, \ - BXT_MIPI2_ESCLK_VAR_DIV_MASK) - -#define BXT_MIPI_ESCLK_VAR_DIV(port, val) \ - (val << BXT_MIPI_DIV_SHIFT(port)) + /* TX control divider to select actual TX clock output from (8x/var) */ -#define BXT_MIPI1_TX_ESCLK_SHIFT 21 -#define BXT_MIPI2_TX_ESCLK_SHIFT 5 +#define BXT_MIPI1_TX_ESCLK_SHIFT 26 +#define BXT_MIPI2_TX_ESCLK_SHIFT 10 #define BXT_MIPI_TX_ESCLK_SHIFT(port) \ _MIPI_PORT(port, BXT_MIPI1_TX_ESCLK_SHIFT, \ BXT_MIPI2_TX_ESCLK_SHIFT) -#define BXT_MIPI1_TX_ESCLK_FIXDIV_MASK (3 << 21) -#define BXT_MIPI2_TX_ESCLK_FIXDIV_MASK (3 << 5) +#define BXT_MIPI1_TX_ESCLK_FIXDIV_MASK (0x3F << 26) +#define BXT_MIPI2_TX_ESCLK_FIXDIV_MASK (0x3F << 10) #define BXT_MIPI_TX_ESCLK_FIXDIV_MASK(port) \ _MIPI_PORT(port, BXT_MIPI1_TX_ESCLK_FIXDIV_MASK, \ - BXT_MIPI2_TX_ESCLK_FIXDIV_MASK) -#define BXT_MIPI_TX_ESCLK_8XDIV_BY2(port) \ - (0x0 << BXT_MIPI_TX_ESCLK_SHIFT(port)) -#define BXT_MIPI_TX_ESCLK_8XDIV_BY4(port) \ - (0x1 << BXT_MIPI_TX_ESCLK_SHIFT(port)) -#define BXT_MIPI_TX_ESCLK_8XDIV_BY8(port) \ - (0x2 << BXT_MIPI_TX_ESCLK_SHIFT(port)) -/* RX control divider to select actual RX clock output from 8x*/ -#define BXT_MIPI1_RX_ESCLK_SHIFT 19 -#define BXT_MIPI2_RX_ESCLK_SHIFT 3 -#define BXT_MIPI_RX_ESCLK_SHIFT(port) \ - _MIPI_PORT(port, BXT_MIPI1_RX_ESCLK_SHIFT, \ - BXT_MIPI2_RX_ESCLK_SHIFT) -#define BXT_MIPI1_RX_ESCLK_FIXDIV_MASK (3 << 19) -#define BXT_MIPI2_RX_ESCLK_FIXDIV_MASK (3 << 3) -#define BXT_MIPI_RX_ESCLK_FIXDIV_MASK(port) \ - (3 << BXT_MIPI_RX_ESCLK_SHIFT(port)) -#define BXT_MIPI_RX_ESCLK_8X_BY2(port) \ - (1 << BXT_MIPI_RX_ESCLK_SHIFT(port)) -#define BXT_MIPI_RX_ESCLK_8X_BY3(port) \ - (2 << BXT_MIPI_RX_ESCLK_SHIFT(port)) -#define BXT_MIPI_RX_ESCLK_8X_BY4(port) \ - (3 << BXT_MIPI_RX_ESCLK_SHIFT(port)) -/* BXT-A WA: Always prog DPHY dividers to 00 */ -#define BXT_MIPI1_DPHY_DIV_SHIFT 16 -#define BXT_MIPI2_DPHY_DIV_SHIFT 0 -#define BXT_MIPI_DPHY_DIV_SHIFT(port) \ - _MIPI_PORT(port, BXT_MIPI1_DPHY_DIV_SHIFT, \ - BXT_MIPI2_DPHY_DIV_SHIFT) -#define BXT_MIPI_1_DPHY_DIVIDER_MASK (3 << 16) -#define BXT_MIPI_2_DPHY_DIVIDER_MASK (3 << 0) -#define BXT_MIPI_DPHY_DIVIDER_MASK(port) \ - (3 << BXT_MIPI_DPHY_DIV_SHIFT(port)) + BXT_MIPI2_TX_ESCLK_FIXDIV_MASK) +#define BXT_MIPI_TX_ESCLK_DIVIDER(port, val) \ + ((val & 0x3F) << BXT_MIPI_TX_ESCLK_SHIFT(port)) +/* RX upper control divider to select actual RX clock output from 8x */ +#define BXT_MIPI1_RX_ESCLK_UPPER_SHIFT 21 +#define BXT_MIPI2_RX_ESCLK_UPPER_SHIFT 5 +#define BXT_MIPI_RX_ESCLK_UPPER_SHIFT(port) \ + _MIPI_PORT(port, BXT_MIPI1_RX_ESCLK_UPPER_SHIFT, \ + BXT_MIPI2_RX_ESCLK_UPPER_SHIFT) +#define BXT_MIPI1_RX_ESCLK_UPPER_FIXDIV_MASK (3 << 21) +#define BXT_MIPI2_RX_ESCLK_UPPER_FIXDIV_MASK (3 << 5) +#define BXT_MIPI_RX_ESCLK_UPPER_FIXDIV_MASK(port) \ + _MIPI_PORT(port, BXT_MIPI1_RX_ESCLK_UPPER_FIXDIV_MASK, \ + BXT_MIPI2_RX_ESCLK_UPPER_FIXDIV_MASK) +#define BXT_MIPI_RX_ESCLK_UPPER_DIVIDER(port, val) \ + ((val & 3) << BXT_MIPI_RX_ESCLK_UPPER_SHIFT(port)) +/* 8/3X divider to select the actual 8/3X clock output from 8x */ +#define BXT_MIPI1_8X_BY3_SHIFT 19 +#define BXT_MIPI2_8X_BY3_SHIFT 3 +#define BXT_MIPI_8X_BY3_SHIFT(port) \ + _MIPI_PORT(port, BXT_MIPI1_8X_BY3_SHIFT, \ + BXT_MIPI2_8X_BY3_SHIFT) +#define BXT_MIPI1_8X_BY3_DIVIDER_MASK (3 << 19) +#define BXT_MIPI2_8X_BY3_DIVIDER_MASK (3 << 3) +#define BXT_MIPI_8X_BY3_DIVIDER_MASK(port) \ + _MIPI_PORT(port, BXT_MIPI1_8X_BY3_DIVIDER_MASK, \ + BXT_MIPI2_8X_BY3_DIVIDER_MASK) +#define BXT_MIPI_8X_BY3_DIVIDER(port, val) \ + ((val & 3) << BXT_MIPI_8X_BY3_SHIFT(port)) +/* RX lower control divider to select actual RX clock output from 8x */ +#define BXT_MIPI1_RX_ESCLK_LOWER_SHIFT 16 +#define BXT_MIPI2_RX_ESCLK_LOWER_SHIFT 0 +#define BXT_MIPI_RX_ESCLK_LOWER_SHIFT(port) \ + _MIPI_PORT(port, BXT_MIPI1_RX_ESCLK_LOWER_SHIFT, \ + BXT_MIPI2_RX_ESCLK_LOWER_SHIFT) +#define BXT_MIPI1_RX_ESCLK_LOWER_FIXDIV_MASK (3 << 16) +#define BXT_MIPI2_RX_ESCLK_LOWER_FIXDIV_MASK (3 << 0) +#define BXT_MIPI_RX_ESCLK_LOWER_FIXDIV_MASK(port) \ + _MIPI_PORT(port, BXT_MIPI1_RX_ESCLK_LOWER_FIXDIV_MASK, \ + BXT_MIPI2_RX_ESCLK_LOWER_FIXDIV_MASK) +#define BXT_MIPI_RX_ESCLK_LOWER_DIVIDER(port, val) \ + ((val & 3) << BXT_MIPI_RX_ESCLK_LOWER_SHIFT(port)) + +#define RX_DIVIDER_BIT_1_2 0x3 +#define RX_DIVIDER_BIT_3_4 0xC /* BXT MIPI mode configure */ #define _BXT_MIPIA_TRANS_HACTIVE 0x6B0F8 diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c index 70883c54cb0a..2451c84949bd 100644 --- a/drivers/gpu/drm/i915/intel_dsi_pll.c +++ b/drivers/gpu/drm/i915/intel_dsi_pll.c @@ -362,35 +362,57 @@ static void vlv_dsi_reset_clocks(struct intel_encoder *encoder, enum port port) /* Program BXT Mipi clocks and dividers */ static void bxt_dsi_program_clocks(struct drm_device *dev, enum port port) { - u32 tmp; - u32 divider; - u32 dsi_rate; - u32 pll_ratio; struct drm_i915_private *dev_priv = dev->dev_private; + u32 tmp; + u32 dsi_rate = 0; + u32 pll_ratio = 0; + u32 rx_div; + u32 tx_div; + u32 rx_div_upper; + u32 rx_div_lower; + u32 mipi_8by3_divider; /* Clear old configurations */ tmp = I915_READ(BXT_MIPI_CLOCK_CTL); tmp &= ~(BXT_MIPI_TX_ESCLK_FIXDIV_MASK(port)); - tmp &= ~(BXT_MIPI_RX_ESCLK_FIXDIV_MASK(port)); - tmp &= ~(BXT_MIPI_ESCLK_VAR_DIV_MASK(port)); - tmp &= ~(BXT_MIPI_DPHY_DIVIDER_MASK(port)); + tmp &= ~(BXT_MIPI_RX_ESCLK_UPPER_FIXDIV_MASK(port)); + tmp &= ~(BXT_MIPI_8X_BY3_DIVIDER_MASK(port)); + tmp &= ~(BXT_MIPI_RX_ESCLK_LOWER_FIXDIV_MASK(port)); /* Get the current DSI rate(actual) */ pll_ratio = I915_READ(BXT_DSI_PLL_CTL) & BXT_DSI_PLL_RATIO_MASK; dsi_rate = (BXT_REF_CLOCK_KHZ * pll_ratio) / 2; - /* Max possible output of clock is 39.5 MHz, program value -1 */ - divider = (dsi_rate / BXT_MAX_VAR_OUTPUT_KHZ) - 1; - tmp |= BXT_MIPI_ESCLK_VAR_DIV(port, divider); + /* + * tx clock should be <= 20MHz and the div value must be + * subtracted by 1 as per bspec + */ + tx_div = DIV_ROUND_UP(dsi_rate, 20000) - 1; + /* + * rx clock should be <= 150MHz and the div value must be + * subtracted by 1 as per bspec + */ + rx_div = DIV_ROUND_UP(dsi_rate, 150000) - 1; /* - * Tx escape clock must be as close to 20MHz possible, but should - * not exceed it. Hence select divide by 2 + * rx divider value needs to be updated in the + * two differnt bit fields in the register hence splitting the + * rx divider value accordingly */ - tmp |= BXT_MIPI_TX_ESCLK_8XDIV_BY2(port); + rx_div_lower = rx_div & RX_DIVIDER_BIT_1_2; + rx_div_upper = (rx_div & RX_DIVIDER_BIT_3_4) >> 2; + + /* As per bpsec program the 8/3X clock divider to the below value */ + if (dev_priv->vbt.dsi.config->is_cmd_mode) + mipi_8by3_divider = 0x2; + else + mipi_8by3_divider = 0x3; - tmp |= BXT_MIPI_RX_ESCLK_8X_BY3(port); + tmp |= BXT_MIPI_8X_BY3_DIVIDER(port, mipi_8by3_divider); + tmp |= BXT_MIPI_TX_ESCLK_DIVIDER(port, tx_div); + tmp |= BXT_MIPI_RX_ESCLK_LOWER_DIVIDER(port, rx_div_lower); + tmp |= BXT_MIPI_RX_ESCLK_UPPER_DIVIDER(port, rx_div_upper); I915_WRITE(BXT_MIPI_CLOCK_CTL, tmp); } @@ -513,9 +535,9 @@ static void bxt_dsi_reset_clocks(struct intel_encoder *encoder, enum port port) /* Clear old configurations */ tmp = I915_READ(BXT_MIPI_CLOCK_CTL); tmp &= ~(BXT_MIPI_TX_ESCLK_FIXDIV_MASK(port)); - tmp &= ~(BXT_MIPI_RX_ESCLK_FIXDIV_MASK(port)); - tmp &= ~(BXT_MIPI_ESCLK_VAR_DIV_MASK(port)); - tmp &= ~(BXT_MIPI_DPHY_DIVIDER_MASK(port)); + tmp &= ~(BXT_MIPI_RX_ESCLK_UPPER_FIXDIV_MASK(port)); + tmp &= ~(BXT_MIPI_8X_BY3_DIVIDER_MASK(port)); + tmp &= ~(BXT_MIPI_RX_ESCLK_LOWER_FIXDIV_MASK(port)); I915_WRITE(BXT_MIPI_CLOCK_CTL, tmp); I915_WRITE(MIPI_EOT_DISABLE(port), CLOCKSTOP); } -- cgit v1.2.3 From 3f177625ee896f5d3c62fa6a49554a9c0243bceb Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Thu, 3 Mar 2016 14:36:41 +0000 Subject: drm/i915: Add wait_for_us This is for callers who want micro-second precision but are not waiting from the atomic context. v2: * Fix atomic waits. (Dave Gordon) * Use USEC_PER_SEC and USEC_PER_MSEC. (Chris Wilson) Signed-off-by: Tvrtko Ursulin Cc: Dave Gordon Cc: Chris Wilson Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/intel_dp.c | 4 ++-- drivers/gpu/drm/i915/intel_drv.h | 15 ++++++++------- drivers/gpu/drm/i915/intel_psr.c | 3 ++- 3 files changed, 12 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 75acb1d15184..5a1387954793 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1792,11 +1792,11 @@ static void wait_panel_status(struct intel_dp *intel_dp, I915_READ(pp_stat_reg), I915_READ(pp_ctrl_reg)); - if (_wait_for((I915_READ(pp_stat_reg) & mask) == value, 5000, 10)) { + if (_wait_for((I915_READ(pp_stat_reg) & mask) == value, + 5 * USEC_PER_SEC, 10 * USEC_PER_MSEC)) DRM_ERROR("Panel status timeout: status %08x control %08x\n", I915_READ(pp_stat_reg), I915_READ(pp_ctrl_reg)); - } DRM_DEBUG_KMS("Wait complete\n"); } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 6c0085496fca..c2a62e9554b3 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -45,8 +45,8 @@ * having timed out, since the timeout could be due to preemption or similar and * we've never had a chance to check the condition before the timeout. */ -#define _wait_for(COND, MS, W) ({ \ - unsigned long timeout__ = jiffies + msecs_to_jiffies(MS) + 1; \ +#define _wait_for(COND, US, W) ({ \ + unsigned long timeout__ = jiffies + usecs_to_jiffies(US) + 1; \ int ret__ = 0; \ while (!(COND)) { \ if (time_after(jiffies, timeout__)) { \ @@ -55,7 +55,7 @@ break; \ } \ if ((W) && drm_can_sleep()) { \ - usleep_range((W)*1000, (W)*2000); \ + usleep_range((W), (W)*2); \ } else { \ cpu_relax(); \ } \ @@ -63,10 +63,11 @@ ret__; \ }) -#define wait_for(COND, MS) _wait_for(COND, MS, 1) -#define wait_for_atomic(COND, MS) _wait_for(COND, MS, 0) -#define wait_for_atomic_us(COND, US) _wait_for((COND), \ - DIV_ROUND_UP((US), 1000), 0) +#define wait_for(COND, MS) _wait_for((COND), (MS) * 1000, 1000) +#define wait_for_us(COND, US) _wait_for((COND), (US), 1) + +#define wait_for_atomic(COND, MS) _wait_for((COND), (MS) * 1000, 0) +#define wait_for_atomic_us(COND, US) _wait_for((COND), (US), 0) #define KHz(x) (1000 * (x)) #define MHz(x) KHz(1000 * (x)) diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index 0b42ada338c8..b1413beb00d1 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -507,7 +507,8 @@ static void hsw_psr_disable(struct intel_dp *intel_dp) /* Wait till PSR is idle */ if (_wait_for((I915_READ(EDP_PSR_STATUS_CTL) & - EDP_PSR_STATUS_STATE_MASK) == 0, 2000, 10)) + EDP_PSR_STATUS_STATE_MASK) == 0, + 2 * USEC_PER_SEC, 10 * USEC_PER_MSEC)) DRM_ERROR("Timed out waiting for PSR Idle State\n"); dev_priv->psr.active = false; -- cgit v1.2.3 From 8de1b23efaede0e355cba017992ab032e983c61c Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Thu, 3 Mar 2016 14:36:42 +0000 Subject: drm/i915/lrc: Do not wait atomically when stopping engines I do not see that this needs to be done atomically and up to one second is quite a long time to busy loop. Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/intel_lrc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 27c9ee3f7372..6fcbf6bb0479 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1062,7 +1062,7 @@ void intel_logical_ring_stop(struct intel_engine_cs *ring) /* TODO: Is this correct with Execlists enabled? */ I915_WRITE_MODE(ring, _MASKED_BIT_ENABLE(STOP_RING)); - if (wait_for_atomic((I915_READ_MODE(ring) & MODE_IDLE) != 0, 1000)) { + if (wait_for((I915_READ_MODE(ring) & MODE_IDLE) != 0, 1000)) { DRM_ERROR("%s :timed out trying to stop ring\n", ring->name); return; } -- cgit v1.2.3 From 643a24b6ecdcb3ed866cdf25a60df3d731504126 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Thu, 3 Mar 2016 14:36:43 +0000 Subject: drm/i915: Kconfig for extra driver debugging v2: Added a submenu based on an idea by Chris Wilson. Signed-off-by: Tvrtko Ursulin Cc: Chris Wilson Cc: Jani Nikula Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/Kconfig | 6 ++++++ drivers/gpu/drm/i915/Kconfig.debug | 12 ++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 drivers/gpu/drm/i915/Kconfig.debug (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig index 20a5d0455e19..29a32b11953b 100644 --- a/drivers/gpu/drm/i915/Kconfig +++ b/drivers/gpu/drm/i915/Kconfig @@ -56,3 +56,9 @@ config DRM_I915_USERPTR selected to enabled full userptr support. If in doubt, say "Y". + +menu "drm/i915 Debugging" +depends on DRM_I915 +depends on EXPERT +source drivers/gpu/drm/i915/Kconfig.debug +endmenu diff --git a/drivers/gpu/drm/i915/Kconfig.debug b/drivers/gpu/drm/i915/Kconfig.debug new file mode 100644 index 000000000000..649a562ddf17 --- /dev/null +++ b/drivers/gpu/drm/i915/Kconfig.debug @@ -0,0 +1,12 @@ +config DRM_I915_DEBUG + bool "Enable additional driver debugging" + depends on DRM_I915 + default n + help + Choose this option to turn on extra driver debugging that may affect + performance but will catch some internal issues. + + Recommended for driver developers only. + + If in doubt, say "N". + -- cgit v1.2.3 From 0351b93992aa463cc3e7f358ddec2709f9390756 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Thu, 3 Mar 2016 16:21:27 +0000 Subject: drm/i915: Do not lie about atomic timeout granularity Currently the wait_for_atomic_us only allows for a jiffie timeout granularity which is not nice towards callers requesting small micro-second timeouts. Re-implement it so micro-second timeout granularity is really supported and not just in the name of the macro. This has another beneficial side effect that it improves "gem_latency -n 100" results by approximately 2.5% (throughput and latencies) and 3% (CPU usage). (Note this improvement is relative to not yet merged execlist lock uncontention patch which moves the CSB MMIO outside this lock.) It also shrinks some hot functions like fw_domains_get by a tiny 3%. v2: * Warn when used from non-atomic context (if possible). * Warn on too long atomic waits. v3: * Added comment explaining CONFIG_PREEMPT_COUNT. * Fixed pre-processor indentation. (Chris Wilson) v4: * Commit msg update (gem_latency) and rebase. v5: * Commit message re-wording. * Added comment about no need for double cond check. (Chris Wilson) Signed-off-by: Tvrtko Ursulin Cc: Chris Wilson Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/intel_drv.h | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index c2a62e9554b3..d8b4916e000a 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -44,6 +44,10 @@ * contexts. Note that it's important that we check the condition again after * having timed out, since the timeout could be due to preemption or similar and * we've never had a chance to check the condition before the timeout. + * + * TODO: When modesetting has fully transitioned to atomic, the below + * drm_can_sleep() can be removed and in_atomic()/!in_atomic() asserts + * added. */ #define _wait_for(COND, US, W) ({ \ unsigned long timeout__ = jiffies + usecs_to_jiffies(US) + 1; \ @@ -66,8 +70,37 @@ #define wait_for(COND, MS) _wait_for((COND), (MS) * 1000, 1000) #define wait_for_us(COND, US) _wait_for((COND), (US), 1) -#define wait_for_atomic(COND, MS) _wait_for((COND), (MS) * 1000, 0) -#define wait_for_atomic_us(COND, US) _wait_for((COND), (US), 0) +/* If CONFIG_PREEMPT_COUNT is disabled, in_atomic() always reports false. */ +#if defined(CONFIG_DRM_I915_DEBUG) && defined(CONFIG_PREEMPT_COUNT) +# define _WAIT_FOR_ATOMIC_CHECK WARN_ON_ONCE(!in_atomic()) +#else +# define _WAIT_FOR_ATOMIC_CHECK do { } while (0) +#endif + +#define _wait_for_atomic(COND, US) ({ \ + unsigned long end__; \ + int ret__ = 0; \ + _WAIT_FOR_ATOMIC_CHECK; \ + BUILD_BUG_ON((US) > 50000); \ + end__ = (local_clock() >> 10) + (US) + 1; \ + while (!(COND)) { \ + if (time_after((unsigned long)(local_clock() >> 10), end__)) { \ + /* Unlike the regular wait_for(), this atomic variant \ + * cannot be preempted (and we'll just ignore the issue\ + * of irq interruptions) and so we know that no time \ + * has passed since the last check of COND and can \ + * immediately report the timeout. \ + */ \ + ret__ = -ETIMEDOUT; \ + break; \ + } \ + cpu_relax(); \ + } \ + ret__; \ +}) + +#define wait_for_atomic(COND, MS) _wait_for_atomic((COND), (MS) * 1000) +#define wait_for_atomic_us(COND, US) _wait_for_atomic((COND), (US)) #define KHz(x) (1000 * (x)) #define MHz(x) KHz(1000 * (x)) -- cgit v1.2.3 From 5ba001783ba6451fd3db0259d30549ca1fe91870 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Thu, 3 Mar 2016 14:36:45 +0000 Subject: drm/i915: Do not wait atomically for display clocks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Looks like this code does not need to wait atomically since it otherwise takes the mutex. Signed-off-by: Tvrtko Ursulin Cc: Ville Syrjälä Reviewed-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1457015805-23742-1-git-send-email-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 08c363127885..124342bdbe90 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9857,8 +9857,8 @@ static void broadwell_set_cdclk(struct drm_device *dev, int cdclk) val |= LCPLL_CD_SOURCE_FCLK; I915_WRITE(LCPLL_CTL, val); - if (wait_for_atomic_us(I915_READ(LCPLL_CTL) & - LCPLL_CD_SOURCE_FCLK_DONE, 1)) + if (wait_for_us(I915_READ(LCPLL_CTL) & + LCPLL_CD_SOURCE_FCLK_DONE, 1)) DRM_ERROR("Switching to FCLK failed\n"); val = I915_READ(LCPLL_CTL); @@ -9892,8 +9892,8 @@ static void broadwell_set_cdclk(struct drm_device *dev, int cdclk) val &= ~LCPLL_CD_SOURCE_FCLK; I915_WRITE(LCPLL_CTL, val); - if (wait_for_atomic_us((I915_READ(LCPLL_CTL) & - LCPLL_CD_SOURCE_FCLK_DONE) == 0, 1)) + if (wait_for_us((I915_READ(LCPLL_CTL) & + LCPLL_CD_SOURCE_FCLK_DONE) == 0, 1)) DRM_ERROR("Switching back to LCPLL failed\n"); mutex_lock(&dev_priv->rps.hw_lock); -- cgit v1.2.3 From e7dc33f332c7188a96722a69fe99c2de9ada3ff0 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 2 Mar 2016 17:22:13 +0200 Subject: drm/i915: Store rawclk_freq in dev_priv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Generalize rawclk handling by storing it in dev_priv. Presumably our hrawclk readout works at least for CTG and ELK since we've been using it for DP AUX on those platforms. There are no real docs anymore after configdb vanished, so the only reference is the public CTG GMCH spec. What bits are listed in that doc match our code. The ELK GMCH spec have no relevant details unfortunately. The PNV situation is less clear. Starting from commit aa17cdb4f836 ("drm/i915: initialize backlight max from VBT") we assume that the CTG/ELK hrawclk readout works for PNV as well. At least the results *seem* reasonable for one PNV machine (Lenovo Ideapad S10-3t). Sadly the PNV GMCH spec doesn't have the goods on the relevant register either. So let's keep assuming it works for PNV,ELK,CTG and read it out on those platforms. G33 also has hrawclk according to some notes in BSpec, but we don't actually need it for anything, so let's not even try to read it out there. v2: Rebase due to IS_VALLYVIEW vs. IS_CHERRYVIEW split Use KHz() all over, and kill off a few useless temp variables Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1456932138-14004-2-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_display.c | 55 ++++++++++++++++++++++-------------- drivers/gpu/drm/i915/intel_dp.c | 16 +++++------ drivers/gpu/drm/i915/intel_drv.h | 2 -- drivers/gpu/drm/i915/intel_panel.c | 42 +++++++++++++-------------- 5 files changed, 62 insertions(+), 54 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index c8791f661dd1..f37ac120a29d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1836,6 +1836,7 @@ struct drm_i915_private { unsigned int skl_boot_cdclk; unsigned int cdclk_freq, max_cdclk_freq, atomic_cdclk_freq; unsigned int max_dotclk_freq; + unsigned int rawclk_freq; unsigned int hpll_freq; unsigned int czclk_freq; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 124342bdbe90..dd9118ba3062 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -169,49 +169,61 @@ static int vlv_get_cck_clock_hpll(struct drm_i915_private *dev_priv, return DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, divider + 1); } -int -intel_pch_rawclk(struct drm_device *dev) +static int +intel_pch_rawclk(struct drm_i915_private *dev_priv) { - struct drm_i915_private *dev_priv = dev->dev_private; - - WARN_ON(!HAS_PCH_SPLIT(dev)); + return (I915_READ(PCH_RAWCLK_FREQ) & RAWCLK_FREQ_MASK) * 1000; +} - return I915_READ(PCH_RAWCLK_FREQ) & RAWCLK_FREQ_MASK; +static int +intel_vlv_hrawclk(struct drm_i915_private *dev_priv) +{ + return 200000; } -/* hrawclock is 1/4 the FSB frequency */ -int intel_hrawclk(struct drm_device *dev) +static int +intel_g4x_hrawclk(struct drm_i915_private *dev_priv) { - struct drm_i915_private *dev_priv = dev->dev_private; uint32_t clkcfg; - /* There is no CLKCFG reg in Valleyview. VLV hrawclk is 200 MHz */ - if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) - return 200; - + /* hrawclock is 1/4 the FSB frequency */ clkcfg = I915_READ(CLKCFG); switch (clkcfg & CLKCFG_FSB_MASK) { case CLKCFG_FSB_400: - return 100; + return 100000; case CLKCFG_FSB_533: - return 133; + return 133333; case CLKCFG_FSB_667: - return 166; + return 166667; case CLKCFG_FSB_800: - return 200; + return 200000; case CLKCFG_FSB_1067: - return 266; + return 266667; case CLKCFG_FSB_1333: - return 333; + return 333333; /* these two are just a guess; one of them might be right */ case CLKCFG_FSB_1600: case CLKCFG_FSB_1600_ALT: - return 400; + return 400000; default: - return 133; + return 133333; } } +static void intel_update_rawclk(struct drm_i915_private *dev_priv) +{ + if (HAS_PCH_SPLIT(dev_priv)) + dev_priv->rawclk_freq = intel_pch_rawclk(dev_priv); + else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + dev_priv->rawclk_freq = intel_vlv_hrawclk(dev_priv); + else if (IS_G4X(dev_priv) || IS_PINEVIEW(dev_priv)) + dev_priv->rawclk_freq = intel_g4x_hrawclk(dev_priv); + else + return; /* no rawclk on other platforms, or no need to know it */ + + DRM_DEBUG_DRIVER("rawclk rate: %d kHz\n", dev_priv->rawclk_freq); +} + static void intel_update_czclk(struct drm_i915_private *dev_priv) { if (!(IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))) @@ -15617,6 +15629,7 @@ void intel_modeset_init(struct drm_device *dev) } intel_update_czclk(dev_priv); + intel_update_rawclk(dev_priv); intel_update_cdclk(dev); intel_shared_dpll_init(dev); diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 5a1387954793..2625652afa9c 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -674,13 +674,13 @@ intel_dp_aux_wait_done(struct intel_dp *intel_dp, bool has_aux_irq) static uint32_t i9xx_get_aux_clock_divider(struct intel_dp *intel_dp, int index) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); - struct drm_device *dev = intel_dig_port->base.base.dev; + struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev); /* * The clock divider is based off the hrawclk, and would like to run at * 2MHz. So, take the hrawclk value and divide by 2 and use that */ - return index ? 0 : DIV_ROUND_CLOSEST(intel_hrawclk(dev), 2); + return index ? 0 : DIV_ROUND_CLOSEST(dev_priv->rawclk_freq, 2000); } static uint32_t ilk_get_aux_clock_divider(struct intel_dp *intel_dp, int index) @@ -692,12 +692,10 @@ static uint32_t ilk_get_aux_clock_divider(struct intel_dp *intel_dp, int index) if (index) return 0; - if (intel_dig_port->port == PORT_A) { + if (intel_dig_port->port == PORT_A) return DIV_ROUND_CLOSEST(dev_priv->cdclk_freq, 2000); - - } else { - return DIV_ROUND_CLOSEST(intel_pch_rawclk(dev), 2); - } + else + return DIV_ROUND_CLOSEST(dev_priv->rawclk_freq, 2000); } static uint32_t hsw_get_aux_clock_divider(struct intel_dp *intel_dp, int index) @@ -718,7 +716,7 @@ static uint32_t hsw_get_aux_clock_divider(struct intel_dp *intel_dp, int index) default: return 0; } } else { - return index ? 0 : DIV_ROUND_CLOSEST(intel_pch_rawclk(dev), 2); + return index ? 0 : DIV_ROUND_CLOSEST(dev_priv->rawclk_freq, 2000); } } @@ -5268,7 +5266,7 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, { struct drm_i915_private *dev_priv = dev->dev_private; u32 pp_on, pp_off, pp_div, port_sel = 0; - int div = HAS_PCH_SPLIT(dev) ? intel_pch_rawclk(dev) : intel_hrawclk(dev); + int div = dev_priv->rawclk_freq / 1000; i915_reg_t pp_on_reg, pp_off_reg, pp_div_reg, pp_ctrl_reg; enum port port = dp_to_dig_port(intel_dp)->port; const struct edp_power_seq *seq = &intel_dp->pps_delays; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index d8b4916e000a..cd0b4eacbddf 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1119,8 +1119,6 @@ void i915_audio_component_cleanup(struct drm_i915_private *dev_priv); extern const struct drm_plane_funcs intel_plane_funcs; unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info); bool intel_has_pending_fb_unpin(struct drm_device *dev); -int intel_pch_rawclk(struct drm_device *dev); -int intel_hrawclk(struct drm_device *dev); void intel_mark_busy(struct drm_device *dev); void intel_mark_idle(struct drm_device *dev); void intel_crtc_restore_mode(struct drm_crtc *crtc); diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 21ee6477bf98..5cf377507162 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -1251,16 +1251,14 @@ static u32 bxt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) static u32 spt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) { struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - u32 mul, clock; + u32 mul; if (I915_READ(SOUTH_CHICKEN1) & SPT_PWM_GRANULARITY) mul = 128; else mul = 16; - clock = MHz(24); - - return clock / (pwm_freq_hz * mul); + return MHz(24) / (pwm_freq_hz * mul); } /* @@ -1292,10 +1290,9 @@ static u32 lpt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) */ static u32 pch_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) { - struct drm_device *dev = connector->base.dev; - int clock = MHz(intel_pch_rawclk(dev)); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - return clock / (pwm_freq_hz * 128); + return KHz(dev_priv->rawclk_freq) / (pwm_freq_hz * 128); } /* @@ -1308,14 +1305,13 @@ static u32 pch_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) */ static u32 i9xx_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) { - struct drm_device *dev = connector->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); int clock; - if (IS_PINEVIEW(dev)) - clock = MHz(intel_hrawclk(dev)); + if (IS_PINEVIEW(dev_priv)) + clock = KHz(dev_priv->rawclk_freq); else - clock = 1000 * dev_priv->cdclk_freq; + clock = KHz(dev_priv->cdclk_freq); return clock / (pwm_freq_hz * 32); } @@ -1332,9 +1328,9 @@ static u32 i965_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) int clock; if (IS_G4X(dev_priv)) - clock = MHz(intel_hrawclk(dev)); + clock = KHz(dev_priv->rawclk_freq); else - clock = 1000 * dev_priv->cdclk_freq; + clock = KHz(dev_priv->cdclk_freq); return clock / (pwm_freq_hz * 128); } @@ -1346,19 +1342,21 @@ static u32 i965_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) */ static u32 vlv_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) { - struct drm_device *dev = connector->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - int clock; + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + int mul, clock; if ((I915_READ(CBR1_VLV) & CBR_PWM_CLOCK_MUX_SELECT) == 0) { - if (IS_CHERRYVIEW(dev)) - return KHz(19200) / (pwm_freq_hz * 16); + if (IS_CHERRYVIEW(dev_priv)) + clock = KHz(19200); else - return MHz(25) / (pwm_freq_hz * 16); + clock = MHz(25); + mul = 16; } else { - clock = intel_hrawclk(dev); - return MHz(clock) / (pwm_freq_hz * 128); + clock = KHz(dev_priv->rawclk_freq); + mul = 128; } + + return clock / (pwm_freq_hz * mul); } static u32 get_backlight_max_vbt(struct intel_connector *connector) -- cgit v1.2.3 From 6ffb1be708ccbefc1a833b3d7d186eefbcf5f12e Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 2 Mar 2016 17:22:14 +0200 Subject: drm/i915: Rename s/i9xx/g4x/ in DP code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit g4x is the first platform with DP support, so let's name the relevant functions as g4x_ instead i9xx_ to avoid confusion. Signed-off-by: Ville Syrjälä Reviewed-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1456932138-14004-3-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_dp.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 2625652afa9c..c9be57862613 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -671,7 +671,7 @@ intel_dp_aux_wait_done(struct intel_dp *intel_dp, bool has_aux_irq) return status; } -static uint32_t i9xx_get_aux_clock_divider(struct intel_dp *intel_dp, int index) +static uint32_t g4x_get_aux_clock_divider(struct intel_dp *intel_dp, int index) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev); @@ -735,10 +735,10 @@ static uint32_t skl_get_aux_clock_divider(struct intel_dp *intel_dp, int index) return index ? 0 : 1; } -static uint32_t i9xx_get_aux_send_ctl(struct intel_dp *intel_dp, - bool has_aux_irq, - int send_bytes, - uint32_t aux_clock_divider) +static uint32_t g4x_get_aux_send_ctl(struct intel_dp *intel_dp, + bool has_aux_irq, + int send_bytes, + uint32_t aux_clock_divider) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = intel_dig_port->base.base.dev; @@ -5866,12 +5866,12 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, else if (HAS_PCH_SPLIT(dev)) intel_dp->get_aux_clock_divider = ilk_get_aux_clock_divider; else - intel_dp->get_aux_clock_divider = i9xx_get_aux_clock_divider; + intel_dp->get_aux_clock_divider = g4x_get_aux_clock_divider; if (INTEL_INFO(dev)->gen >= 9) intel_dp->get_aux_send_ctl = skl_get_aux_send_ctl; else - intel_dp->get_aux_send_ctl = i9xx_get_aux_send_ctl; + intel_dp->get_aux_send_ctl = g4x_get_aux_send_ctl; if (HAS_DDI(dev)) intel_dp->prepare_link_retrain = intel_ddi_prepare_link_retrain; -- cgit v1.2.3 From 193709c1c4d2543eac5d49428db732837ebcf61f Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 2 Mar 2016 17:22:15 +0200 Subject: drm/i915: Use g4x_get_aux_clock_divider() for VLV/CHV MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the hrawclk frequency cached in dev_priv, we can simply use g4x_get_aux_clock_divider() for VLV/CHV. v2: Rebase due to IS_VALLYVIEW vs. IS_CHERRYVIEW split Signed-off-by: Ville Syrjälä Reviewed-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1456932138-14004-4-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_dp.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index c9be57862613..ddf35bd51ab6 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -720,11 +720,6 @@ static uint32_t hsw_get_aux_clock_divider(struct intel_dp *intel_dp, int index) } } -static uint32_t vlv_get_aux_clock_divider(struct intel_dp *intel_dp, int index) -{ - return index ? 0 : 100; -} - static uint32_t skl_get_aux_clock_divider(struct intel_dp *intel_dp, int index) { /* @@ -5859,8 +5854,6 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, /* intel_dp vfuncs */ if (INTEL_INFO(dev)->gen >= 9) intel_dp->get_aux_clock_divider = skl_get_aux_clock_divider; - else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) - intel_dp->get_aux_clock_divider = vlv_get_aux_clock_divider; else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) intel_dp->get_aux_clock_divider = hsw_get_aux_clock_divider; else if (HAS_PCH_SPLIT(dev)) -- cgit v1.2.3 From 35d38d1f17b853a014b500350ab3135790d47ef3 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 2 Mar 2016 17:22:16 +0200 Subject: drm/i915: Read out hrawclk from CCK on vlv/chv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently we assume that hrawclk is 200MHz on VLV/CHV. That should be true always, but just to avoid such asumptions we can read out the actual frequency from CCK. Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1456932138-14004-5-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_display.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 65f9bb9754ab..7dfc4007f3fa 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -786,6 +786,7 @@ enum skl_disp_power_wells { #define DSI_PLL_M1_DIV_MASK (0x1ff << 0) #define CCK_CZ_CLOCK_CONTROL 0x62 #define CCK_DISPLAY_CLOCK_CONTROL 0x6b +#define CCK_DISPLAY_REF_CLOCK_CONTROL 0x6c #define CCK_TRUNK_FORCE_ON (1 << 17) #define CCK_TRUNK_FORCE_OFF (1 << 16) #define CCK_FREQUENCY_STATUS (0x1f << 8) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index dd9118ba3062..62d36a7b3398 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -178,7 +178,8 @@ intel_pch_rawclk(struct drm_i915_private *dev_priv) static int intel_vlv_hrawclk(struct drm_i915_private *dev_priv) { - return 200000; + return vlv_get_cck_clock_hpll(dev_priv, "hrawclk", + CCK_DISPLAY_REF_CLOCK_CONTROL); } static int -- cgit v1.2.3 From a457f54b293c82fc6b222d9bc59fed4984321d84 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 2 Mar 2016 17:22:17 +0200 Subject: drm/i915: Clean up .get_aux_clock_divider() functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that the mess with AUX clock divder rounding is sorted out and we have both cdclk and rawclk cached in dev_priv, we can clean up the .get_aux_clock_divider() functions a bit. The main thing here is just calling ilk_get_aux_clock_divider() from hsw_get_aux_clock_divider() except for the LPT:H special case. We could go further and call g4x_get_aux_clock_divider() from ilk_get_aux_clock_divider() for the PCH ports, but I'm sure Jani would object, so leave that be. While at it repeat the comment where the AUX clock comes from in ilk_get_aux_clock_divider(). Signed-off-by: Ville Syrjälä Reviewed-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1456932138-14004-6-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_dp.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index ddf35bd51ab6..7a0f99db47b0 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -676,22 +676,29 @@ static uint32_t g4x_get_aux_clock_divider(struct intel_dp *intel_dp, int index) struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev); + if (index) + return 0; + /* * The clock divider is based off the hrawclk, and would like to run at - * 2MHz. So, take the hrawclk value and divide by 2 and use that + * 2MHz. So, take the hrawclk value and divide by 2000 and use that */ - return index ? 0 : DIV_ROUND_CLOSEST(dev_priv->rawclk_freq, 2000); + return DIV_ROUND_CLOSEST(dev_priv->rawclk_freq, 2000); } static uint32_t ilk_get_aux_clock_divider(struct intel_dp *intel_dp, int index) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); - struct drm_device *dev = intel_dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev); if (index) return 0; + /* + * The clock divider is based off the cdclk or PCH rawclk, and would + * like to run at 2MHz. So, take the cdclk or PCH rawclk value and + * divide by 2000 and use that + */ if (intel_dig_port->port == PORT_A) return DIV_ROUND_CLOSEST(dev_priv->cdclk_freq, 2000); else @@ -701,23 +708,18 @@ static uint32_t ilk_get_aux_clock_divider(struct intel_dp *intel_dp, int index) static uint32_t hsw_get_aux_clock_divider(struct intel_dp *intel_dp, int index) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); - struct drm_device *dev = intel_dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev); - if (intel_dig_port->port == PORT_A) { - if (index) - return 0; - return DIV_ROUND_CLOSEST(dev_priv->cdclk_freq, 2000); - } else if (HAS_PCH_LPT_H(dev_priv)) { + if (intel_dig_port->port != PORT_A && HAS_PCH_LPT_H(dev_priv)) { /* Workaround for non-ULT HSW */ switch (index) { case 0: return 63; case 1: return 72; default: return 0; } - } else { - return index ? 0 : DIV_ROUND_CLOSEST(dev_priv->rawclk_freq, 2000); } + + return ilk_get_aux_clock_divider(intel_dp, index); } static uint32_t skl_get_aux_clock_divider(struct intel_dp *intel_dp, int index) -- cgit v1.2.3 From 37f2248e3d422f0463800b574ea9288ede97cea2 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 2 Mar 2016 17:22:18 +0200 Subject: drm/i915: Use DIV_ROUND_CLOSEST for PWM calculations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Supposedly we would want to get the PWM output as close as possible to the target, so let's round to closest. Cc: Jani Nikula Suggested-by: Jani Nikula Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1456932138-14004-7-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/intel_panel.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 5cf377507162..0fe059bc7d80 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -1240,7 +1240,7 @@ static void intel_backlight_device_unregister(struct intel_connector *connector) */ static u32 bxt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) { - return KHz(19200) / pwm_freq_hz; + return DIV_ROUND_CLOSEST(KHz(19200), pwm_freq_hz); } /* @@ -1258,7 +1258,7 @@ static u32 spt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) else mul = 16; - return MHz(24) / (pwm_freq_hz * mul); + return DIV_ROUND_CLOSEST(MHz(24), pwm_freq_hz * mul); } /* @@ -1281,7 +1281,7 @@ static u32 lpt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) else clock = MHz(24); /* LPT:LP */ - return clock / (pwm_freq_hz * mul); + return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul); } /* @@ -1292,7 +1292,7 @@ static u32 pch_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) { struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - return KHz(dev_priv->rawclk_freq) / (pwm_freq_hz * 128); + return DIV_ROUND_CLOSEST(KHz(dev_priv->rawclk_freq), pwm_freq_hz * 128); } /* @@ -1313,7 +1313,7 @@ static u32 i9xx_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) else clock = KHz(dev_priv->cdclk_freq); - return clock / (pwm_freq_hz * 32); + return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 32); } /* @@ -1332,7 +1332,7 @@ static u32 i965_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) else clock = KHz(dev_priv->cdclk_freq); - return clock / (pwm_freq_hz * 128); + return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 128); } /* @@ -1356,7 +1356,7 @@ static u32 vlv_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) mul = 128; } - return clock / (pwm_freq_hz * mul); + return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul); } static u32 get_backlight_max_vbt(struct intel_connector *connector) -- cgit v1.2.3 From d431440cce2427dcdd665d936865fe802637b4c2 Mon Sep 17 00:00:00 2001 From: Tomas Elf Date: Wed, 2 Mar 2016 16:46:24 +0200 Subject: drm/i915: Generalise common GPU engine reset request/unrequest code GPU engine reset handshaking is something that is applicable to both full GPU reset and engine reset, which is something that is part of the upcoming TDR per-engine hang recovery patches. Break out the common engine reset request/unrequest code (originally written by Mika Kuoppala) for reuse later in the TDR enablement patch series. v2: correct indentation and drop unused returned value (Mika) v3: We have forcewake during reset so use *_FW reg access (Mika) Reviewed-by: Mika Kuoppala Signed-off-by: Tomas Elf Cc: Mika Kuoppala Signed-off-by: Arun Siluvery [Mika: Fixed format warning] Signed-off-by: Mika Kuoppala Link: http://patchwork.freedesktop.org/patch/msgid/1456929984-16323-1-git-send-email-mika.kuoppala@intel.com --- drivers/gpu/drm/i915/intel_uncore.c | 56 ++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 436d8f2b8682..d31447f6fa32 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -1531,13 +1531,40 @@ static int gen6_do_reset(struct drm_device *dev) return ret; } -static int wait_for_register(struct drm_i915_private *dev_priv, - i915_reg_t reg, - const u32 mask, - const u32 value, - const unsigned long timeout_ms) +static int wait_for_register_fw(struct drm_i915_private *dev_priv, + i915_reg_t reg, + const u32 mask, + const u32 value, + const unsigned long timeout_ms) { - return wait_for((I915_READ(reg) & mask) == value, timeout_ms); + return wait_for((I915_READ_FW(reg) & mask) == value, timeout_ms); +} + +static int gen8_request_engine_reset(struct intel_engine_cs *engine) +{ + int ret; + struct drm_i915_private *dev_priv = engine->dev->dev_private; + + I915_WRITE_FW(RING_RESET_CTL(engine->mmio_base), + _MASKED_BIT_ENABLE(RESET_CTL_REQUEST_RESET)); + + ret = wait_for_register_fw(dev_priv, + RING_RESET_CTL(engine->mmio_base), + RESET_CTL_READY_TO_RESET, + RESET_CTL_READY_TO_RESET, + 700); + if (ret) + DRM_ERROR("%s: reset request timeout\n", engine->name); + + return ret; +} + +static void gen8_unrequest_engine_reset(struct intel_engine_cs *engine) +{ + struct drm_i915_private *dev_priv = engine->dev->dev_private; + + I915_WRITE_FW(RING_RESET_CTL(engine->mmio_base), + _MASKED_BIT_DISABLE(RESET_CTL_REQUEST_RESET)); } static int gen8_do_reset(struct drm_device *dev) @@ -1546,26 +1573,15 @@ static int gen8_do_reset(struct drm_device *dev) struct intel_engine_cs *engine; int i; - for_each_ring(engine, dev_priv, i) { - I915_WRITE(RING_RESET_CTL(engine->mmio_base), - _MASKED_BIT_ENABLE(RESET_CTL_REQUEST_RESET)); - - if (wait_for_register(dev_priv, - RING_RESET_CTL(engine->mmio_base), - RESET_CTL_READY_TO_RESET, - RESET_CTL_READY_TO_RESET, - 700)) { - DRM_ERROR("%s: reset request timeout\n", engine->name); + for_each_ring(engine, dev_priv, i) + if (gen8_request_engine_reset(engine)) goto not_ready; - } - } return gen6_do_reset(dev); not_ready: for_each_ring(engine, dev_priv, i) - I915_WRITE(RING_RESET_CTL(engine->mmio_base), - _MASKED_BIT_DISABLE(RESET_CTL_REQUEST_RESET)); + gen8_unrequest_engine_reset(engine); return -EIO; } -- cgit v1.2.3 From 24a65e624bcdc726c7711ae90efeffaf0a8e9f32 Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Wed, 2 Mar 2016 16:48:29 +0200 Subject: drm/i915/hangcheck: Prevent long walks across full-ppgtt With full-ppgtt, it takes the GPU an eon to traverse the entire 256PiB address space, causing a loop to be detected. Under the current scheme, if ACTHD walks off the end of a batch buffer and into an empty address space, we "never" detect the hang. If we always increment the score as the ACTHD is progressing then we will eventually timeout (after ~46.5s (31 * 1.5s) without advancing onto a new batch). To counter act this, increase the amount we reduce the score for good batches, so that only a series of almost-bad batches trigger a full reset. DoS detection suffers slightly but series of long running shader tests will benefit. Based on a patch from Chris Wilson. Testcase: igt/drv_hangman/hangcheck-unterminated Cc: Daniele Ceraolo Spurio Cc: Chris Wilson Signed-off-by: Mika Kuoppala Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1456930109-21532-1-git-send-email-mika.kuoppala@intel.com --- drivers/gpu/drm/i915/i915_debugfs.c | 2 -- drivers/gpu/drm/i915/i915_gpu_error.c | 2 -- drivers/gpu/drm/i915/i915_irq.c | 17 +++++++---------- drivers/gpu/drm/i915/intel_ringbuffer.h | 2 -- 4 files changed, 7 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index a0f1bd711b53..15aacd0ee66f 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1367,8 +1367,6 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused) seq_printf(m, "\tACTHD = 0x%08llx [current 0x%08llx]\n", (long long)ring->hangcheck.acthd, (long long)acthd[i]); - seq_printf(m, "\tmax ACTHD = 0x%08llx\n", - (long long)ring->hangcheck.max_acthd); seq_printf(m, "\tscore = %d\n", ring->hangcheck.score); seq_printf(m, "\taction = %d\n", ring->hangcheck.action); diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 3b6bfbf35482..13b5f3aed01c 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -230,8 +230,6 @@ static const char *hangcheck_action_to_str(enum intel_ring_hangcheck_action a) return "wait"; case HANGCHECK_ACTIVE: return "active"; - case HANGCHECK_ACTIVE_LOOP: - return "active (loop)"; case HANGCHECK_KICK: return "kick"; case HANGCHECK_HUNG: diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index d1a46ef5ab3f..53e5104964b3 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3001,12 +3001,7 @@ head_stuck(struct intel_engine_cs *ring, u64 acthd) memset(ring->hangcheck.instdone, 0, sizeof(ring->hangcheck.instdone)); - if (acthd > ring->hangcheck.max_acthd) { - ring->hangcheck.max_acthd = acthd; - return HANGCHECK_ACTIVE; - } - - return HANGCHECK_ACTIVE_LOOP; + return HANGCHECK_ACTIVE; } if (!subunits_stuck(ring)) @@ -3083,6 +3078,7 @@ static void i915_hangcheck_elapsed(struct work_struct *work) #define BUSY 1 #define KICK 5 #define HUNG 20 +#define ACTIVE_DECAY 15 if (!i915.enable_hangcheck) return; @@ -3151,9 +3147,8 @@ static void i915_hangcheck_elapsed(struct work_struct *work) switch (ring->hangcheck.action) { case HANGCHECK_IDLE: case HANGCHECK_WAIT: - case HANGCHECK_ACTIVE: break; - case HANGCHECK_ACTIVE_LOOP: + case HANGCHECK_ACTIVE: ring->hangcheck.score += BUSY; break; case HANGCHECK_KICK: @@ -3172,10 +3167,12 @@ static void i915_hangcheck_elapsed(struct work_struct *work) * attempts across multiple batches. */ if (ring->hangcheck.score > 0) - ring->hangcheck.score--; + ring->hangcheck.score -= ACTIVE_DECAY; + if (ring->hangcheck.score < 0) + ring->hangcheck.score = 0; /* Clear head and subunit states on seqno movement */ - ring->hangcheck.acthd = ring->hangcheck.max_acthd = 0; + ring->hangcheck.acthd = 0; memset(ring->hangcheck.instdone, 0, sizeof(ring->hangcheck.instdone)); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index dd910d30a380..4b1439deb7fe 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -79,7 +79,6 @@ enum intel_ring_hangcheck_action { HANGCHECK_IDLE = 0, HANGCHECK_WAIT, HANGCHECK_ACTIVE, - HANGCHECK_ACTIVE_LOOP, HANGCHECK_KICK, HANGCHECK_HUNG, }; @@ -88,7 +87,6 @@ enum intel_ring_hangcheck_action { struct intel_ring_hangcheck { u64 acthd; - u64 max_acthd; u32 seqno; int score; enum intel_ring_hangcheck_action action; -- cgit v1.2.3 From 844a65636793d284526ff7d623ef477ed4473ab4 Mon Sep 17 00:00:00 2001 From: Matt Ranostay Date: Fri, 4 Mar 2016 22:55:25 -0800 Subject: iio: potentiometer: tpl0102: change i2c functionality return code Change i2c_check_functionality condition check return from ENOTSUPP to EOPNOTSUPP which is now the standard return code. Signed-off-by: Matt Ranostay Signed-off-by: Jonathan Cameron --- drivers/iio/potentiometer/tpl0102.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iio/potentiometer/tpl0102.c b/drivers/iio/potentiometer/tpl0102.c index 313124b6fd59..5c304d42d713 100644 --- a/drivers/iio/potentiometer/tpl0102.c +++ b/drivers/iio/potentiometer/tpl0102.c @@ -118,7 +118,7 @@ static int tpl0102_probe(struct i2c_client *client, if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) - return -ENOTSUPP; + return -EOPNOTSUPP; indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); if (!indio_dev) -- cgit v1.2.3 From 7a948c5e05febd23ee8e61db95c3dc96737fe17f Mon Sep 17 00:00:00 2001 From: Grégor Boirie Date: Tue, 1 Mar 2016 11:31:37 +0100 Subject: iio:pressure:ms5611: complete DT support Add device-tree ID tables and document bindings. Signed-off-by: Gregor Boirie Acked-by: Rob Herring Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/pressure/ms5611.txt | 19 +++++++++++++++++++ Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + drivers/iio/pressure/ms5611_i2c.c | 13 +++++++++++++ drivers/iio/pressure/ms5611_spi.c | 13 +++++++++++++ 4 files changed, 46 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/pressure/ms5611.txt (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/iio/pressure/ms5611.txt b/Documentation/devicetree/bindings/iio/pressure/ms5611.txt new file mode 100644 index 000000000000..17bca866c084 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/pressure/ms5611.txt @@ -0,0 +1,19 @@ +MEAS ms5611 family pressure sensors + +Pressure sensors from MEAS Switzerland with SPI and I2C bus interfaces. + +Required properties: +- compatible: "meas,ms5611" or "meas,ms5607" +- reg: the I2C address or SPI chip select the device will respond to + +Optional properties: +- vdd-supply: an optional regulator that needs to be on to provide VDD + power to the sensor. + +Example: + +ms5607@77 { + compatible = "meas,ms5607"; + reg = <0x77>; + vdd-supply = <&ldo_3v3_gnss>; +}; diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 44ddc980b085..7733f8ca5e7b 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -136,6 +136,7 @@ lsi LSI Corp. (LSI Logic) lltc Linear Technology Corporation marvell Marvell Technology Group Ltd. maxim Maxim Integrated Products +meas Measurement Specialties mediatek MediaTek Inc. melexis Melexis N.V. merrii Merrii Technology Co., Ltd. diff --git a/drivers/iio/pressure/ms5611_i2c.c b/drivers/iio/pressure/ms5611_i2c.c index 7f6fc8eee922..57a8f2cfa235 100644 --- a/drivers/iio/pressure/ms5611_i2c.c +++ b/drivers/iio/pressure/ms5611_i2c.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "ms5611.h" @@ -113,6 +114,17 @@ static int ms5611_i2c_remove(struct i2c_client *client) return ms5611_remove(i2c_get_clientdata(client)); } +#if defined(CONFIG_OF) +static const struct of_device_id ms5611_i2c_matches[] = { + { .compatible = "meas,ms5611" }, + { .compatible = "ms5611" }, + { .compatible = "meas,ms5607" }, + { .compatible = "ms5607" }, + { } +}; +MODULE_DEVICE_TABLE(of, ms5611_i2c_matches); +#endif + static const struct i2c_device_id ms5611_id[] = { { "ms5611", MS5611 }, { "ms5607", MS5607 }, @@ -123,6 +135,7 @@ MODULE_DEVICE_TABLE(i2c, ms5611_id); static struct i2c_driver ms5611_driver = { .driver = { .name = "ms5611", + .of_match_table = of_match_ptr(ms5611_i2c_matches) }, .id_table = ms5611_id, .probe = ms5611_i2c_probe, diff --git a/drivers/iio/pressure/ms5611_spi.c b/drivers/iio/pressure/ms5611_spi.c index 5cc009e85f0e..7ec0c6498f93 100644 --- a/drivers/iio/pressure/ms5611_spi.c +++ b/drivers/iio/pressure/ms5611_spi.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "ms5611.h" @@ -114,6 +115,17 @@ static int ms5611_spi_remove(struct spi_device *spi) return ms5611_remove(spi_get_drvdata(spi)); } +#if defined(CONFIG_OF) +static const struct of_device_id ms5611_spi_matches[] = { + { .compatible = "meas,ms5611" }, + { .compatible = "ms5611" }, + { .compatible = "meas,ms5607" }, + { .compatible = "ms5607" }, + { } +}; +MODULE_DEVICE_TABLE(of, ms5611_spi_matches); +#endif + static const struct spi_device_id ms5611_id[] = { { "ms5611", MS5611 }, { "ms5607", MS5607 }, @@ -124,6 +136,7 @@ MODULE_DEVICE_TABLE(spi, ms5611_id); static struct spi_driver ms5611_driver = { .driver = { .name = "ms5611", + .of_match_table = of_match_ptr(ms5611_spi_matches) }, .id_table = ms5611_id, .probe = ms5611_spi_probe, -- cgit v1.2.3 From 033691a9a12f684c68f443f3676806dd64011295 Mon Sep 17 00:00:00 2001 From: Gregor Boirie Date: Tue, 1 Mar 2016 11:31:38 +0100 Subject: iio:pressure:ms5611: oversampling rate support Add support for setting and retrieving OverSampling Rate independently for each of the temperature and pressure channels. This allows userspace to fine tune hardware sampling process according to the following tradeoffs : * the higher the OSR, the finer the resolution ; * the higher the OSR, the lower the noise ; BUT: * the higher the OSR, the larger the drift ; * the higher the OSR, the longer the response time, i.e. less samples per unit of time. Signed-off-by: Gregor Boirie Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/ms5611.h | 20 ++++--- drivers/iio/pressure/ms5611_core.c | 105 ++++++++++++++++++++++++++++++++++++- drivers/iio/pressure/ms5611_i2c.c | 12 ++--- drivers/iio/pressure/ms5611_spi.c | 19 +++---- 4 files changed, 133 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/pressure/ms5611.h b/drivers/iio/pressure/ms5611.h index 8b08e4b7e3a9..d725a3077a17 100644 --- a/drivers/iio/pressure/ms5611.h +++ b/drivers/iio/pressure/ms5611.h @@ -19,12 +19,6 @@ #define MS5611_RESET 0x1e #define MS5611_READ_ADC 0x00 #define MS5611_READ_PROM_WORD 0xA0 -#define MS5611_START_TEMP_CONV 0x58 -#define MS5611_START_PRESSURE_CONV 0x48 - -#define MS5611_CONV_TIME_MIN 9040 -#define MS5611_CONV_TIME_MAX 10000 - #define MS5611_PROM_WORDS_NB 8 enum { @@ -39,10 +33,24 @@ struct ms5611_chip_info { s32 *temp, s32 *pressure); }; +/* + * OverSampling Rate descriptor. + * Warning: cmd MUST be kept aligned on a word boundary (see + * m5611_spi_read_adc_temp_and_pressure in ms5611_spi.c). + */ +struct ms5611_osr { + unsigned long conv_usec; + u8 cmd; + unsigned short rate; +}; + struct ms5611_state { void *client; struct mutex lock; + const struct ms5611_osr *pressure_osr; + const struct ms5611_osr *temp_osr; + int (*reset)(struct device *dev); int (*read_prom_word)(struct device *dev, int index, u16 *word); int (*read_adc_temp_and_pressure)(struct device *dev, diff --git a/drivers/iio/pressure/ms5611_core.c b/drivers/iio/pressure/ms5611_core.c index 992ad8d3b67a..37dbc0401599 100644 --- a/drivers/iio/pressure/ms5611_core.c +++ b/drivers/iio/pressure/ms5611_core.c @@ -18,11 +18,44 @@ #include #include +#include #include #include #include #include "ms5611.h" +#define MS5611_INIT_OSR(_cmd, _conv_usec, _rate) \ + { .cmd = _cmd, .conv_usec = _conv_usec, .rate = _rate } + +static const struct ms5611_osr ms5611_avail_pressure_osr[] = { + MS5611_INIT_OSR(0x40, 600, 256), + MS5611_INIT_OSR(0x42, 1170, 512), + MS5611_INIT_OSR(0x44, 2280, 1024), + MS5611_INIT_OSR(0x46, 4540, 2048), + MS5611_INIT_OSR(0x48, 9040, 4096) +}; + +static const struct ms5611_osr ms5611_avail_temp_osr[] = { + MS5611_INIT_OSR(0x50, 600, 256), + MS5611_INIT_OSR(0x52, 1170, 512), + MS5611_INIT_OSR(0x54, 2280, 1024), + MS5611_INIT_OSR(0x56, 4540, 2048), + MS5611_INIT_OSR(0x58, 9040, 4096) +}; + +static const char ms5611_show_osr[] = "256 512 1024 2048 4096"; + +static IIO_CONST_ATTR(oversampling_ratio_available, ms5611_show_osr); + +static struct attribute *ms5611_attributes[] = { + &iio_const_attr_oversampling_ratio_available.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ms5611_attribute_group = { + .attrs = ms5611_attributes, +}; + static bool ms5611_prom_is_valid(u16 *prom, size_t len) { int i, j; @@ -239,11 +272,70 @@ static int ms5611_read_raw(struct iio_dev *indio_dev, default: return -EINVAL; } + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: + if (chan->type != IIO_TEMP && chan->type != IIO_PRESSURE) + break; + mutex_lock(&st->lock); + if (chan->type == IIO_TEMP) + *val = (int)st->temp_osr->rate; + else + *val = (int)st->pressure_osr->rate; + mutex_unlock(&st->lock); + return IIO_VAL_INT; } return -EINVAL; } +static const struct ms5611_osr *ms5611_find_osr(int rate, + const struct ms5611_osr *osr, + size_t count) +{ + unsigned int r; + + for (r = 0; r < count; r++) + if ((unsigned short)rate == osr[r].rate) + break; + if (r >= count) + return NULL; + return &osr[r]; +} + +static int ms5611_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct ms5611_state *st = iio_priv(indio_dev); + const struct ms5611_osr *osr = NULL; + + if (mask != IIO_CHAN_INFO_OVERSAMPLING_RATIO) + return -EINVAL; + + if (chan->type == IIO_TEMP) + osr = ms5611_find_osr(val, ms5611_avail_temp_osr, + ARRAY_SIZE(ms5611_avail_temp_osr)); + else if (chan->type == IIO_PRESSURE) + osr = ms5611_find_osr(val, ms5611_avail_pressure_osr, + ARRAY_SIZE(ms5611_avail_pressure_osr)); + if (!osr) + return -EINVAL; + + mutex_lock(&st->lock); + + if (iio_buffer_enabled(indio_dev)) { + mutex_unlock(&st->lock); + return -EBUSY; + } + + if (chan->type == IIO_TEMP) + st->temp_osr = osr; + else + st->pressure_osr = osr; + + mutex_unlock(&st->lock); + return 0; +} + static const unsigned long ms5611_scan_masks[] = {0x3, 0}; static struct ms5611_chip_info chip_info_tbl[] = { @@ -259,7 +351,8 @@ static const struct iio_chan_spec ms5611_channels[] = { { .type = IIO_PRESSURE, .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) | - BIT(IIO_CHAN_INFO_SCALE), + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), .scan_index = 0, .scan_type = { .sign = 's', @@ -271,7 +364,8 @@ static const struct iio_chan_spec ms5611_channels[] = { { .type = IIO_TEMP, .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) | - BIT(IIO_CHAN_INFO_SCALE), + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), .scan_index = 1, .scan_type = { .sign = 's', @@ -285,6 +379,8 @@ static const struct iio_chan_spec ms5611_channels[] = { static const struct iio_info ms5611_info = { .read_raw = &ms5611_read_raw, + .write_raw = &ms5611_write_raw, + .attrs = &ms5611_attribute_group, .driver_module = THIS_MODULE, }; @@ -319,6 +415,11 @@ int ms5611_probe(struct iio_dev *indio_dev, struct device *dev, mutex_init(&st->lock); st->chip_info = &chip_info_tbl[type]; + st->temp_osr = + &ms5611_avail_temp_osr[ARRAY_SIZE(ms5611_avail_temp_osr) - 1]; + st->pressure_osr = + &ms5611_avail_pressure_osr[ARRAY_SIZE(ms5611_avail_pressure_osr) + - 1]; indio_dev->dev.parent = dev; indio_dev->name = name; indio_dev->info = &ms5611_info; diff --git a/drivers/iio/pressure/ms5611_i2c.c b/drivers/iio/pressure/ms5611_i2c.c index 57a8f2cfa235..55fb5fc0b6ea 100644 --- a/drivers/iio/pressure/ms5611_i2c.c +++ b/drivers/iio/pressure/ms5611_i2c.c @@ -63,23 +63,23 @@ static int ms5611_i2c_read_adc_temp_and_pressure(struct device *dev, { int ret; struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev)); + const struct ms5611_osr *osr = st->temp_osr; - ret = i2c_smbus_write_byte(st->client, MS5611_START_TEMP_CONV); + ret = i2c_smbus_write_byte(st->client, osr->cmd); if (ret < 0) return ret; - usleep_range(MS5611_CONV_TIME_MIN, MS5611_CONV_TIME_MAX); - + usleep_range(osr->conv_usec, osr->conv_usec + (osr->conv_usec / 10UL)); ret = ms5611_i2c_read_adc(st, temp); if (ret < 0) return ret; - ret = i2c_smbus_write_byte(st->client, MS5611_START_PRESSURE_CONV); + osr = st->pressure_osr; + ret = i2c_smbus_write_byte(st->client, osr->cmd); if (ret < 0) return ret; - usleep_range(MS5611_CONV_TIME_MIN, MS5611_CONV_TIME_MAX); - + usleep_range(osr->conv_usec, osr->conv_usec + (osr->conv_usec / 10UL)); return ms5611_i2c_read_adc(st, pressure); } diff --git a/drivers/iio/pressure/ms5611_spi.c b/drivers/iio/pressure/ms5611_spi.c index 7ec0c6498f93..7600483e8cb4 100644 --- a/drivers/iio/pressure/ms5611_spi.c +++ b/drivers/iio/pressure/ms5611_spi.c @@ -56,28 +56,29 @@ static int ms5611_spi_read_adc(struct device *dev, s32 *val) static int ms5611_spi_read_adc_temp_and_pressure(struct device *dev, s32 *temp, s32 *pressure) { - u8 cmd; int ret; struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev)); + const struct ms5611_osr *osr = st->temp_osr; - cmd = MS5611_START_TEMP_CONV; - ret = spi_write_then_read(st->client, &cmd, 1, NULL, 0); + /* + * Warning: &osr->cmd MUST be aligned on a word boundary since used as + * 2nd argument (void*) of spi_write_then_read. + */ + ret = spi_write_then_read(st->client, &osr->cmd, 1, NULL, 0); if (ret < 0) return ret; - usleep_range(MS5611_CONV_TIME_MIN, MS5611_CONV_TIME_MAX); - + usleep_range(osr->conv_usec, osr->conv_usec + (osr->conv_usec / 10UL)); ret = ms5611_spi_read_adc(dev, temp); if (ret < 0) return ret; - cmd = MS5611_START_PRESSURE_CONV; - ret = spi_write_then_read(st->client, &cmd, 1, NULL, 0); + osr = st->pressure_osr; + ret = spi_write_then_read(st->client, &osr->cmd, 1, NULL, 0); if (ret < 0) return ret; - usleep_range(MS5611_CONV_TIME_MIN, MS5611_CONV_TIME_MAX); - + usleep_range(osr->conv_usec, osr->conv_usec + (osr->conv_usec / 10UL)); return ms5611_spi_read_adc(dev, pressure); } -- cgit v1.2.3 From 43d33f7458383ff6ce9838fca7b78b9b64fb988a Mon Sep 17 00:00:00 2001 From: Ludovic Desroches Date: Thu, 3 Mar 2016 17:09:13 +0100 Subject: iio:adc:at91-sama5d2: fix typo Fix typo in the name of a macro. Signed-off-by: Ludovic Desroches Signed-off-by: Jonathan Cameron --- drivers/iio/adc/at91-sama5d2_adc.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c index dbee13ad33a3..33bacece325c 100644 --- a/drivers/iio/adc/at91-sama5d2_adc.c +++ b/drivers/iio/adc/at91-sama5d2_adc.c @@ -140,7 +140,7 @@ /* Version Register */ #define AT91_SAMA5D2_VERSION 0xfc -#define AT91_AT91_SAMA5D2_CHAN(num, addr) \ +#define AT91_SAMA5D2_CHAN(num, addr) \ { \ .type = IIO_VOLTAGE, \ .channel = num, \ @@ -185,18 +185,18 @@ struct at91_adc_state { }; static const struct iio_chan_spec at91_adc_channels[] = { - AT91_AT91_SAMA5D2_CHAN(0, 0x50), - AT91_AT91_SAMA5D2_CHAN(1, 0x54), - AT91_AT91_SAMA5D2_CHAN(2, 0x58), - AT91_AT91_SAMA5D2_CHAN(3, 0x5c), - AT91_AT91_SAMA5D2_CHAN(4, 0x60), - AT91_AT91_SAMA5D2_CHAN(5, 0x64), - AT91_AT91_SAMA5D2_CHAN(6, 0x68), - AT91_AT91_SAMA5D2_CHAN(7, 0x6c), - AT91_AT91_SAMA5D2_CHAN(8, 0x70), - AT91_AT91_SAMA5D2_CHAN(9, 0x74), - AT91_AT91_SAMA5D2_CHAN(10, 0x78), - AT91_AT91_SAMA5D2_CHAN(11, 0x7c), + AT91_SAMA5D2_CHAN(0, 0x50), + AT91_SAMA5D2_CHAN(1, 0x54), + AT91_SAMA5D2_CHAN(2, 0x58), + AT91_SAMA5D2_CHAN(3, 0x5c), + AT91_SAMA5D2_CHAN(4, 0x60), + AT91_SAMA5D2_CHAN(5, 0x64), + AT91_SAMA5D2_CHAN(6, 0x68), + AT91_SAMA5D2_CHAN(7, 0x6c), + AT91_SAMA5D2_CHAN(8, 0x70), + AT91_SAMA5D2_CHAN(9, 0x74), + AT91_SAMA5D2_CHAN(10, 0x78), + AT91_SAMA5D2_CHAN(11, 0x7c), }; static unsigned at91_adc_startup_time(unsigned startup_time_min, -- cgit v1.2.3 From f0fa15cce13d5987c50907eb98846d13e2b4d9ca Mon Sep 17 00:00:00 2001 From: Ludovic Desroches Date: Thu, 3 Mar 2016 17:09:14 +0100 Subject: iio:adc:at91-sama5d2: fix identation Remove some extra tabs. Signed-off-by: Ludovic Desroches Signed-off-by: Jonathan Cameron --- drivers/iio/adc/at91-sama5d2_adc.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c index 33bacece325c..5bc038f23609 100644 --- a/drivers/iio/adc/at91-sama5d2_adc.c +++ b/drivers/iio/adc/at91-sama5d2_adc.c @@ -92,13 +92,13 @@ /* Last Converted Data Register */ #define AT91_SAMA5D2_LCDR 0x20 /* Interrupt Enable Register */ -#define AT91_SAMA5D2_IER 0x24 +#define AT91_SAMA5D2_IER 0x24 /* Interrupt Disable Register */ -#define AT91_SAMA5D2_IDR 0x28 +#define AT91_SAMA5D2_IDR 0x28 /* Interrupt Mask Register */ -#define AT91_SAMA5D2_IMR 0x2c +#define AT91_SAMA5D2_IMR 0x2c /* Interrupt Status Register */ -#define AT91_SAMA5D2_ISR 0x30 +#define AT91_SAMA5D2_ISR 0x30 /* Last Channel Trigger Mode Register */ #define AT91_SAMA5D2_LCTMR 0x34 /* Last Channel Compare Window Register */ @@ -106,17 +106,17 @@ /* Overrun Status Register */ #define AT91_SAMA5D2_OVER 0x3c /* Extended Mode Register */ -#define AT91_SAMA5D2_EMR 0x40 +#define AT91_SAMA5D2_EMR 0x40 /* Compare Window Register */ -#define AT91_SAMA5D2_CWR 0x44 +#define AT91_SAMA5D2_CWR 0x44 /* Channel Gain Register */ -#define AT91_SAMA5D2_CGR 0x48 +#define AT91_SAMA5D2_CGR 0x48 /* Channel Offset Register */ -#define AT91_SAMA5D2_COR 0x4c +#define AT91_SAMA5D2_COR 0x4c /* Channel Data Register 0 */ #define AT91_SAMA5D2_CDR0 0x50 /* Analog Control Register */ -#define AT91_SAMA5D2_ACR 0x94 +#define AT91_SAMA5D2_ACR 0x94 /* Touchscreen Mode Register */ #define AT91_SAMA5D2_TSMR 0xb0 /* Touchscreen X Position Register */ @@ -130,7 +130,7 @@ /* Correction Select Register */ #define AT91_SAMA5D2_COSR 0xd0 /* Correction Value Register */ -#define AT91_SAMA5D2_CVR 0xd4 +#define AT91_SAMA5D2_CVR 0xd4 /* Channel Error Correction Register */ #define AT91_SAMA5D2_CECR 0xd8 /* Write Protection Mode Register */ -- cgit v1.2.3 From 55c0c530f7113d98cb1a0d42f15b8abe5e4b6928 Mon Sep 17 00:00:00 2001 From: Gregor Boirie Date: Thu, 3 Mar 2016 11:44:03 +0100 Subject: iio:magnetometer:ak8975: fix uninitialized chipset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ak_def_array bounds are not properly checked in case of ACPI matching failure. GCC warns with the following message at line 799: ‘chipset’ may be used uninitialized in this function. Signed-off-by: Gregor Boirie Signed-off-by: Jonathan Cameron --- drivers/iio/magnetometer/ak8975.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c index 9c5c9ef3f1da..11059b2c39a4 100644 --- a/drivers/iio/magnetometer/ak8975.c +++ b/drivers/iio/magnetometer/ak8975.c @@ -774,8 +774,11 @@ static int ak8975_probe(struct i2c_client *client, if (id) { chipset = (enum asahi_compass_chipset)(id->driver_data); name = id->name; - } else if (ACPI_HANDLE(&client->dev)) + } else if (ACPI_HANDLE(&client->dev)) { name = ak8975_match_acpi_device(&client->dev, &chipset); + if (!name) + return -ENODEV; + } else return -ENOSYS; -- cgit v1.2.3 From d3546af67f4937075d0747adb3bf56d3c46b32f0 Mon Sep 17 00:00:00 2001 From: Gregor Boirie Date: Thu, 3 Mar 2016 11:44:04 +0100 Subject: iio:magnetometer:ak8975: remove unused field Remove unused struct ak8975_data attrs field. Signed-off-by: Gregor Boirie Signed-off-by: Jonathan Cameron --- drivers/iio/magnetometer/ak8975.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c index 11059b2c39a4..896b13e39dae 100644 --- a/drivers/iio/magnetometer/ak8975.c +++ b/drivers/iio/magnetometer/ak8975.c @@ -361,7 +361,6 @@ static const struct ak_def ak_def_array[AK_MAX_TYPE] = { struct ak8975_data { struct i2c_client *client; const struct ak_def *def; - struct attribute_group attrs; struct mutex lock; u8 asa[3]; long raw_to_gauss[3]; -- cgit v1.2.3 From 63d5d525cbbc8938d9fa3d6d6fbd4183e784b6e9 Mon Sep 17 00:00:00 2001 From: Gregor Boirie Date: Thu, 3 Mar 2016 11:44:05 +0100 Subject: iio:magnetometer:ak8975: power regulator support Add support for an optional regulator which, if found into device-tree, will power on device at probing time. The regulator is declared into ak8975 DTS entry as a "vdd-supply" property. Signed-off-by: Gregor Boirie Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/magnetometer/ak8975.txt | 2 ++ drivers/iio/magnetometer/ak8975.c | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/iio/magnetometer/ak8975.txt b/Documentation/devicetree/bindings/iio/magnetometer/ak8975.txt index 011679f1a425..34a3206eefdf 100644 --- a/Documentation/devicetree/bindings/iio/magnetometer/ak8975.txt +++ b/Documentation/devicetree/bindings/iio/magnetometer/ak8975.txt @@ -8,6 +8,7 @@ Required properties: Optional properties: - gpios : should be device tree identifier of the magnetometer DRDY pin + - vdd-supply: an optional regulator that needs to be on to provide VDD Example: @@ -15,4 +16,5 @@ ak8975@0c { compatible = "asahi-kasei,ak8975"; reg = <0x0c>; gpios = <&gpj0 7 0>; + vdd-supply = <&ldo_3v3_gnss>; }; diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c index 896b13e39dae..72c03d9fbeb2 100644 --- a/drivers/iio/magnetometer/ak8975.c +++ b/drivers/iio/magnetometer/ak8975.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -379,8 +380,23 @@ static int ak8975_who_i_am(struct i2c_client *client, enum asahi_compass_chipset type) { u8 wia_val[2]; + struct regulator *vdd = devm_regulator_get_optional(&client->dev, + "vdd"); int ret; + /* Enable attached regulator if any. */ + if (!IS_ERR(vdd)) { + ret = regulator_enable(vdd); + if (ret) { + dev_err(&client->dev, "Failed to enable Vdd supply\n"); + return ret; + } + } else { + ret = PTR_ERR(vdd); + if (ret != -ENODEV) + return ret; + } + /* * Signature for each device: * Device | WIA1 | WIA2 -- cgit v1.2.3 From 8b8ff3a6a6e2325662e3af174f54b47487d3ed75 Mon Sep 17 00:00:00 2001 From: Martin Kepplinger Date: Thu, 3 Mar 2016 09:24:01 +0100 Subject: iio: mma8452: coding style fixes fix checkpatch issues like "space before tabs", too long lines or alignment. Signed-off-by: Martin Kepplinger Signed-off-by: Christoph Muellner Signed-off-by: Jonathan Cameron --- drivers/iio/accel/mma8452.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c index 7f4994f32a90..17d72bc2e6fa 100644 --- a/drivers/iio/accel/mma8452.c +++ b/drivers/iio/accel/mma8452.c @@ -357,7 +357,8 @@ static int mma8452_read_raw(struct iio_dev *indio_dev, return IIO_VAL_INT_PLUS_MICRO; case IIO_CHAN_INFO_CALIBBIAS: ret = i2c_smbus_read_byte_data(data->client, - MMA8452_OFF_X + chan->scan_index); + MMA8452_OFF_X + + chan->scan_index); if (ret < 0) return ret; @@ -418,7 +419,7 @@ fail: return ret; } -/* returns >0 if in freefall mode, 0 if not or <0 if an error occured */ +/* returns >0 if in freefall mode, 0 if not or <0 if an error occurred */ static int mma8452_freefall_mode_enabled(struct mma8452_data *data) { int val; @@ -668,7 +669,8 @@ static int mma8452_read_event_config(struct iio_dev *indio_dev, if (ret < 0) return ret; - return !!(ret & BIT(chan->scan_index + chip->ev_cfg_chan_shift)); + return !!(ret & BIT(chan->scan_index + + chip->ev_cfg_chan_shift)); default: return -EINVAL; } @@ -1003,7 +1005,7 @@ static const struct mma_chip_info mma_chip_info_table[] = { * bit. * The userspace interface uses m/s^2 and we declare micro units * So scale factor for 12 bit here is given by: - * g * N * 1000000 / 2048 for N = 2, 4, 8 and g=9.80665 + * g * N * 1000000 / 2048 for N = 2, 4, 8 and g=9.80665 */ .mma_scales = { {0, 2394}, {0, 4788}, {0, 9577} }, .ev_cfg = MMA8452_TRANSIENT_CFG, -- cgit v1.2.3 From e866853d67868ac0f7e0779d19aaad07285c9ff3 Mon Sep 17 00:00:00 2001 From: Martin Kepplinger Date: Thu, 3 Mar 2016 09:24:02 +0100 Subject: iio: mma8452: avoid switching to active because of config change The devices' config registers can only be changed in standby mode. Up until now the driver just held the device *always* active, so for changing a config it was *always* necessary to switch to standby. For upcoming support for runtime pm, the device can as well be in standby mode. Instead of putting runtime pm functions in there, just keep the device in standby if it already is. This section is protected by a lock after all. Signed-off-by: Martin Kepplinger Signed-off-by: Christoph Muellner Signed-off-by: Jonathan Cameron --- drivers/iio/accel/mma8452.c | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c index 17d72bc2e6fa..9c4a84a72ad4 100644 --- a/drivers/iio/accel/mma8452.c +++ b/drivers/iio/accel/mma8452.c @@ -393,24 +393,47 @@ static int mma8452_active(struct mma8452_data *data) data->ctrl_reg1); } +/* returns >0 if active, 0 if in standby and <0 on error */ +static int mma8452_is_active(struct mma8452_data *data) +{ + int reg; + + reg = i2c_smbus_read_byte_data(data->client, MMA8452_CTRL_REG1); + if (reg < 0) + return reg; + + return reg & MMA8452_CTRL_ACTIVE; +} + static int mma8452_change_config(struct mma8452_data *data, u8 reg, u8 val) { int ret; + int is_active; mutex_lock(&data->lock); - /* config can only be changed when in standby */ - ret = mma8452_standby(data); - if (ret < 0) + is_active = mma8452_is_active(data); + if (is_active < 0) { + ret = is_active; goto fail; + } + + /* config can only be changed when in standby */ + if (is_active > 0) { + ret = mma8452_standby(data); + if (ret < 0) + goto fail; + } ret = i2c_smbus_write_byte_data(data->client, reg, val); if (ret < 0) goto fail; - ret = mma8452_active(data); - if (ret < 0) - goto fail; + if (is_active > 0) { + ret = mma8452_active(data); + if (ret < 0) + goto fail; + } ret = 0; fail: -- cgit v1.2.3 From 96c0cb2bbfe0a58bd0c37cf34d50a20f9cd75aa8 Mon Sep 17 00:00:00 2001 From: Martin Kepplinger Date: Thu, 3 Mar 2016 09:24:03 +0100 Subject: iio: mma8452: add support for runtime power management This adds support for runtime power management and, if configured, activates automatic standby after 2 seconds of inactivity. Inactivity means no read of acceleration values and no events triggered or activated. If CONFIG_PM is not set, this doesn't change anything for existing users. Signed-off-by: Martin Kepplinger Signed-off-by: Christoph Muellner Signed-off-by: Jonathan Cameron --- drivers/iio/accel/mma8452.c | 118 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 108 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c index 9c4a84a72ad4..5ca0d169f912 100644 --- a/drivers/iio/accel/mma8452.c +++ b/drivers/iio/accel/mma8452.c @@ -31,6 +31,7 @@ #include #include #include +#include #define MMA8452_STATUS 0x00 #define MMA8452_STATUS_DRDY (BIT(2) | BIT(1) | BIT(0)) @@ -92,6 +93,8 @@ #define MMA8652_DEVICE_ID 0x4a #define MMA8653_DEVICE_ID 0x5a +#define MMA8452_AUTO_SUSPEND_DELAY_MS 2000 + struct mma8452_data { struct i2c_client *client; struct mutex lock; @@ -172,6 +175,31 @@ static int mma8452_drdy(struct mma8452_data *data) return -EIO; } +static int mma8452_set_runtime_pm_state(struct i2c_client *client, bool on) +{ +#ifdef CONFIG_PM + int ret; + + if (on) { + ret = pm_runtime_get_sync(&client->dev); + } else { + pm_runtime_mark_last_busy(&client->dev); + ret = pm_runtime_put_autosuspend(&client->dev); + } + + if (ret < 0) { + dev_err(&client->dev, + "failed to change power state to %d\n", on); + if (on) + pm_runtime_put_noidle(&client->dev); + + return ret; + } +#endif + + return 0; +} + static int mma8452_read(struct mma8452_data *data, __be16 buf[3]) { int ret = mma8452_drdy(data); @@ -179,8 +207,16 @@ static int mma8452_read(struct mma8452_data *data, __be16 buf[3]) if (ret < 0) return ret; - return i2c_smbus_read_i2c_block_data(data->client, MMA8452_OUT_X, - 3 * sizeof(__be16), (u8 *)buf); + ret = mma8452_set_runtime_pm_state(data->client, true); + if (ret) + return ret; + + ret = i2c_smbus_read_i2c_block_data(data->client, MMA8452_OUT_X, + 3 * sizeof(__be16), (u8 *)buf); + + ret = mma8452_set_runtime_pm_state(data->client, false); + + return ret; } static ssize_t mma8452_show_int_plus_micros(char *buf, const int (*vals)[2], @@ -707,7 +743,11 @@ static int mma8452_write_event_config(struct iio_dev *indio_dev, { struct mma8452_data *data = iio_priv(indio_dev); const struct mma_chip_info *chip = data->chip_info; - int val; + int val, ret; + + ret = mma8452_set_runtime_pm_state(data->client, state); + if (ret) + return ret; switch (dir) { case IIO_EV_DIR_FALLING: @@ -1139,7 +1179,11 @@ static int mma8452_data_rdy_trigger_set_state(struct iio_trigger *trig, { struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); struct mma8452_data *data = iio_priv(indio_dev); - int reg; + int reg, ret; + + ret = mma8452_set_runtime_pm_state(data->client, state); + if (ret) + return ret; reg = i2c_smbus_read_byte_data(data->client, MMA8452_CTRL_REG4); if (reg < 0) @@ -1365,6 +1409,15 @@ static int mma8452_probe(struct i2c_client *client, goto buffer_cleanup; } + ret = pm_runtime_set_active(&client->dev); + if (ret < 0) + goto buffer_cleanup; + + pm_runtime_enable(&client->dev); + pm_runtime_set_autosuspend_delay(&client->dev, + MMA8452_AUTO_SUSPEND_DELAY_MS); + pm_runtime_use_autosuspend(&client->dev); + ret = iio_device_register(indio_dev); if (ret < 0) goto buffer_cleanup; @@ -1389,6 +1442,11 @@ static int mma8452_remove(struct i2c_client *client) struct iio_dev *indio_dev = i2c_get_clientdata(client); iio_device_unregister(indio_dev); + + pm_runtime_disable(&client->dev); + pm_runtime_set_suspended(&client->dev); + pm_runtime_put_noidle(&client->dev); + iio_triggered_buffer_cleanup(indio_dev); mma8452_trigger_cleanup(indio_dev); mma8452_standby(iio_priv(indio_dev)); @@ -1396,6 +1454,45 @@ static int mma8452_remove(struct i2c_client *client) return 0; } +#ifdef CONFIG_PM +static int mma8452_runtime_suspend(struct device *dev) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); + struct mma8452_data *data = iio_priv(indio_dev); + int ret; + + mutex_lock(&data->lock); + ret = mma8452_standby(data); + mutex_unlock(&data->lock); + if (ret < 0) { + dev_err(&data->client->dev, "powering off device failed\n"); + return -EAGAIN; + } + + return 0; +} + +static int mma8452_runtime_resume(struct device *dev) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); + struct mma8452_data *data = iio_priv(indio_dev); + int ret, sleep_val; + + ret = mma8452_active(data); + if (ret < 0) + return ret; + + ret = mma8452_get_odr_index(data); + sleep_val = 1000 / mma8452_samp_freq[ret][0]; + if (sleep_val < 20) + usleep_range(sleep_val * 1000, 20000); + else + msleep_interruptible(sleep_val); + + return 0; +} +#endif + #ifdef CONFIG_PM_SLEEP static int mma8452_suspend(struct device *dev) { @@ -1408,13 +1505,14 @@ static int mma8452_resume(struct device *dev) return mma8452_active(iio_priv(i2c_get_clientdata( to_i2c_client(dev)))); } - -static SIMPLE_DEV_PM_OPS(mma8452_pm_ops, mma8452_suspend, mma8452_resume); -#define MMA8452_PM_OPS (&mma8452_pm_ops) -#else -#define MMA8452_PM_OPS NULL #endif +static const struct dev_pm_ops mma8452_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(mma8452_suspend, mma8452_resume) + SET_RUNTIME_PM_OPS(mma8452_runtime_suspend, + mma8452_runtime_resume, NULL) +}; + static const struct i2c_device_id mma8452_id[] = { { "mma8452", mma8452 }, { "mma8453", mma8453 }, @@ -1428,7 +1526,7 @@ static struct i2c_driver mma8452_driver = { .driver = { .name = "mma8452", .of_match_table = of_match_ptr(mma8452_dt_ids), - .pm = MMA8452_PM_OPS, + .pm = &mma8452_pm_ops, }, .probe = mma8452_probe, .remove = mma8452_remove, -- cgit v1.2.3 From c816d9e7a57bd436b2cff8f48b0e8cff128f05db Mon Sep 17 00:00:00 2001 From: Matt Ranostay Date: Wed, 2 Mar 2016 19:18:12 -0800 Subject: iio: imu: mpu6050: fix possible NULL dereferences Fix possible null dereferencing of i2c and spi driver data. Signed-off-by: Matt Ranostay Signed-off-by: Jonathan Cameron --- drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c | 3 ++- drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c index f581256d9d4c..d0c0e20c7122 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c @@ -117,6 +117,7 @@ static int inv_mpu_probe(struct i2c_client *client, struct inv_mpu6050_state *st; int result; const char *name = id ? id->name : NULL; + const int chip_type = id ? id->driver_data : 0; struct regmap *regmap; if (!i2c_check_functionality(client->adapter, @@ -131,7 +132,7 @@ static int inv_mpu_probe(struct i2c_client *client, } result = inv_mpu_core_probe(regmap, client->irq, name, - NULL, id->driver_data); + NULL, chip_type); if (result < 0) return result; diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c index dea6c4361de0..7bcb8d839f05 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c @@ -46,6 +46,7 @@ static int inv_mpu_probe(struct spi_device *spi) struct regmap *regmap; const struct spi_device_id *id = spi_get_device_id(spi); const char *name = id ? id->name : NULL; + const int chip_type = id ? id->driver_data : 0; regmap = devm_regmap_init_spi(spi, &inv_mpu_regmap_config); if (IS_ERR(regmap)) { @@ -55,7 +56,7 @@ static int inv_mpu_probe(struct spi_device *spi) } return inv_mpu_core_probe(regmap, spi->irq, name, - inv_mpu_i2c_disable, id->driver_data); + inv_mpu_i2c_disable, chip_type); } static int inv_mpu_remove(struct spi_device *spi) -- cgit v1.2.3 From e84a41d5db891eab6f1f4a2625bb97f3c6415eee Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 4 Mar 2016 10:05:26 +0900 Subject: iio: adc: Fix build error of missing devm_ioremap_resource on UM The devres.o gets linked if HAS_IOMEM is present so on ARCH=um allyesconfig (COMPILE_TEST) failed with: drivers/built-in.o: In function `at91_adc_probe': at91-sama5d2_adc.c:(.text+0x48f548): undefined reference to `devm_ioremap_resource' Signed-off-by: Krzysztof Kozlowski Signed-off-by: Jonathan Cameron --- drivers/iio/adc/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 932de1f9d1e7..a8819a08a828 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -134,6 +134,7 @@ config AT91_ADC config AT91_SAMA5D2_ADC tristate "Atmel AT91 SAMA5D2 ADC" depends on ARCH_AT91 || COMPILE_TEST + depends on HAS_IOMEM help Say yes here to build support for Atmel SAMA5D2 ADC which is available on SAMA5D2 SoC family. -- cgit v1.2.3 From 2abc525bf5c62fd1f2a2994e5231842221dfdddb Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 4 Mar 2016 21:57:41 +0200 Subject: drm/i915/gen9: Fix DMC firmware initialization In commit 1e657ad7 we moved the last step of firmware initialization to skl_display_core_init(), where it will be run only during system resume, but not during driver loading. Since this init step needs to be done whenever we program the firmware fix this by moving the initialization to the end of intel_csr_load_program(). While at it simplify a bit csr_load_work_fn(). This issue prevented DC5/6 transitions, this change will re-enable those. v2: - remove debugging left-over and redundant comment in csr_load_work_fn() Fixes: 1e657ad7a48f ("drm/i915/gen9: Write dc state debugmask bits only once") CC: Mika Kuoppala CC: Patrik Jakobsson Signed-off-by: Imre Deak Reviewed-by: Mika Kuoppala Link: http://patchwork.freedesktop.org/patch/msgid/1457121461-16729-1-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/intel_csr.c | 40 +++++++++++++++++++++------------ drivers/gpu/drm/i915/intel_drv.h | 2 +- drivers/gpu/drm/i915/intel_runtime_pm.c | 22 ++---------------- 3 files changed, 29 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c index 902054efb902..d417d9ab49b5 100644 --- a/drivers/gpu/drm/i915/intel_csr.c +++ b/drivers/gpu/drm/i915/intel_csr.c @@ -212,6 +212,24 @@ static const struct stepping_info *intel_get_stepping_info(struct drm_device *de return NULL; } +static void gen9_set_dc_state_debugmask(struct drm_i915_private *dev_priv) +{ + uint32_t val, mask; + + mask = DC_STATE_DEBUG_MASK_MEMORY_UP; + + if (IS_BROXTON(dev_priv)) + mask |= DC_STATE_DEBUG_MASK_CORES; + + /* The below bit doesn't need to be cleared ever afterwards */ + val = I915_READ(DC_STATE_DEBUG); + if ((val & mask) != mask) { + val |= mask; + I915_WRITE(DC_STATE_DEBUG, val); + POSTING_READ(DC_STATE_DEBUG); + } +} + /** * intel_csr_load_program() - write the firmware from memory to register. * @dev_priv: i915 drm device. @@ -220,19 +238,19 @@ static const struct stepping_info *intel_get_stepping_info(struct drm_device *de * Everytime display comes back from low power state this function is called to * copy the firmware from internal memory to registers. */ -bool intel_csr_load_program(struct drm_i915_private *dev_priv) +void intel_csr_load_program(struct drm_i915_private *dev_priv) { u32 *payload = dev_priv->csr.dmc_payload; uint32_t i, fw_size; if (!IS_GEN9(dev_priv)) { DRM_ERROR("No CSR support available for this platform\n"); - return false; + return; } if (!dev_priv->csr.dmc_payload) { DRM_ERROR("Tried to program CSR with empty payload\n"); - return false; + return; } fw_size = dev_priv->csr.dmc_fw_size; @@ -246,7 +264,7 @@ bool intel_csr_load_program(struct drm_i915_private *dev_priv) dev_priv->csr.dc_state = 0; - return true; + gen9_set_dc_state_debugmask(dev_priv); } static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, @@ -388,18 +406,12 @@ static void csr_load_work_fn(struct work_struct *work) ret = request_firmware(&fw, dev_priv->csr.fw_path, &dev_priv->dev->pdev->dev); - if (!fw) - goto out; + if (fw) + dev_priv->csr.dmc_payload = parse_csr_fw(dev_priv, fw); - dev_priv->csr.dmc_payload = parse_csr_fw(dev_priv, fw); - if (!dev_priv->csr.dmc_payload) - goto out; - - /* load csr program during system boot, as needed for DC states */ - intel_csr_load_program(dev_priv); - -out: if (dev_priv->csr.dmc_payload) { + intel_csr_load_program(dev_priv); + intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); DRM_INFO("Finished loading %s (v%u.%u)\n", diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index cd0b4eacbddf..3daf1e37af9c 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1279,7 +1279,7 @@ u32 skl_plane_ctl_rotation(unsigned int rotation); /* intel_csr.c */ void intel_csr_ucode_init(struct drm_i915_private *); -bool intel_csr_load_program(struct drm_i915_private *); +void intel_csr_load_program(struct drm_i915_private *); void intel_csr_ucode_fini(struct drm_i915_private *); /* intel_dp.c */ diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 09c52b1a3a54..5adf4b337de3 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -470,24 +470,6 @@ static void assert_can_disable_dc9(struct drm_i915_private *dev_priv) */ } -static void gen9_set_dc_state_debugmask(struct drm_i915_private *dev_priv) -{ - uint32_t val, mask; - - mask = DC_STATE_DEBUG_MASK_MEMORY_UP; - - if (IS_BROXTON(dev_priv)) - mask |= DC_STATE_DEBUG_MASK_CORES; - - /* The below bit doesn't need to be cleared ever afterwards */ - val = I915_READ(DC_STATE_DEBUG); - if ((val & mask) != mask) { - val |= mask; - I915_WRITE(DC_STATE_DEBUG, val); - POSTING_READ(DC_STATE_DEBUG); - } -} - static void gen9_write_dc_state(struct drm_i915_private *dev_priv, u32 state) { @@ -2141,8 +2123,8 @@ static void skl_display_core_init(struct drm_i915_private *dev_priv, skl_init_cdclk(dev_priv); - if (dev_priv->csr.dmc_payload && intel_csr_load_program(dev_priv)) - gen9_set_dc_state_debugmask(dev_priv); + if (dev_priv->csr.dmc_payload) + intel_csr_load_program(dev_priv); } static void skl_display_core_uninit(struct drm_i915_private *dev_priv) -- cgit v1.2.3 From 9dfbffcf4ac0707097af9e6c1372192b9d03a357 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 24 Feb 2016 15:35:22 +0100 Subject: drm/i915: Fix bogus dig_port_map[] assignment for pre-HSW MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The recent commit [0bdf5a05647a: drm/i915: Add reverse mapping between port and intel_encoder] introduced a reverse mapping to retrieve intel_dig_port object from the port number. The code assumed that the port vs intel_dig_port are 1:1 mapping. But in reality, this was a too naive assumption. As Martin reported about the missing HDMI audio on his SNB machine, pre-HSW chips may have multiple intel_dig_port objects corresponding to the same port. Since we assign the mapping statically at the init time and the multiple objects override the map, it may not match with the actually enabled output. This patch tries to address the regression above. The reverse mapping is provided basically only for the audio callbacks, so now we set / clear the mapping dynamically at enabling and disabling HDMI/DP audio, so that we can always track the latest and correct object corresponding to the given port. Fixes: 0bdf5a05647a ('drm/i915: Add reverse mapping between port and intel_encoder') Reported-and-tested-by: Martin Kepplinger Cc: drm-intel-fixes@lists.freedesktop.org Signed-off-by: Takashi Iwai Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1456324522-21591-1-git-send-email-tiwai@suse.de --- drivers/gpu/drm/i915/intel_audio.c | 3 +++ drivers/gpu/drm/i915/intel_ddi.c | 1 - drivers/gpu/drm/i915/intel_dp.c | 1 - drivers/gpu/drm/i915/intel_hdmi.c | 2 -- 4 files changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 31f6d212fb1b..30f921421b0c 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -527,6 +527,8 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder) mutex_lock(&dev_priv->av_mutex); intel_dig_port->audio_connector = connector; + /* referred in audio callbacks */ + dev_priv->dig_port_map[port] = intel_encoder; mutex_unlock(&dev_priv->av_mutex); if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify) @@ -554,6 +556,7 @@ void intel_audio_codec_disable(struct intel_encoder *intel_encoder) mutex_lock(&dev_priv->av_mutex); intel_dig_port->audio_connector = NULL; + dev_priv->dig_port_map[port] = NULL; mutex_unlock(&dev_priv->av_mutex); if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 21a9b83f3bfc..62de9f4bce09 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -3326,7 +3326,6 @@ void intel_ddi_init(struct drm_device *dev, enum port port) intel_encoder->get_config = intel_ddi_get_config; intel_dig_port->port = port; - dev_priv->dig_port_map[port] = intel_encoder; intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) & (DDI_BUF_PORT_REVERSAL | DDI_A_4_LANES); diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 7a0f99db47b0..109ae6166db1 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -6045,7 +6045,6 @@ intel_dp_init(struct drm_device *dev, } intel_dig_port->port = port; - dev_priv->dig_port_map[port] = intel_encoder; intel_dig_port->dp.output_reg = output_reg; intel_dig_port->max_lanes = 4; diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index d8060e6251f8..e2dab4828508 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -2164,7 +2164,6 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, void intel_hdmi_init(struct drm_device *dev, i915_reg_t hdmi_reg, enum port port) { - struct drm_i915_private *dev_priv = dev->dev_private; struct intel_digital_port *intel_dig_port; struct intel_encoder *intel_encoder; struct intel_connector *intel_connector; @@ -2233,7 +2232,6 @@ void intel_hdmi_init(struct drm_device *dev, intel_encoder->cloneable |= 1 << INTEL_OUTPUT_HDMI; intel_dig_port->port = port; - dev_priv->dig_port_map[port] = intel_encoder; intel_dig_port->hdmi.hdmi_reg = hdmi_reg; intel_dig_port->dp.output_reg = INVALID_MMIO_REG; intel_dig_port->max_lanes = 4; -- cgit v1.2.3 From acad889f9eb86ba8830de33cc7a391e9f68ca5ea Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 8 Mar 2016 21:00:56 +0200 Subject: drm/i915/bxt: add missing DSI power domain to power well 1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The DSI power domain was missing from BXT power well 1 definitions, failing to get the power well for DSI transcoders. As pipe A is in the same power well as DSI transcoders, the problem should only occur with pipes B and C. According to Ville, this is basically a nop since pw1 is under dmc control. But given that we still have this stuff defined here, it's clearly correct to include DSI here. Cc: Ramalingam C Cc: Deepak M Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1457463656-29357-1-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_runtime_pm.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 5adf4b337de3..2e88a5e06884 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -421,6 +421,7 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv, BIT(POWER_DOMAIN_TRANSCODER_EDP) | \ BIT(POWER_DOMAIN_PIPE_A_PANEL_FITTER) | \ BIT(POWER_DOMAIN_PORT_DDI_A_LANES) | \ + BIT(POWER_DOMAIN_PORT_DSI) | \ BIT(POWER_DOMAIN_AUX_A) | \ BIT(POWER_DOMAIN_PLLS) | \ BIT(POWER_DOMAIN_INIT)) -- cgit v1.2.3 From 71f0a626143368b8aead361ffaff7e36d043fd8e Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Tue, 8 Mar 2016 10:57:16 +0100 Subject: drm/i915: Only use sanitized values for ILK watermarks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The raw watermark values are needed when planes are not part of the state, but this introduced a regression and possibly an overflow when merging the watermarks because invalid values may end up used. Solve this by calculating raw watermarks for all levels, and only setting non-zero values when the level is valid. Fixes the SNB warning: WARNING: CPU: 1 PID: 25405 at drivers/gpu/drm/i915/intel_pm.c:2580 ilk_program_watermarks+0x7b2/0x9d0 [i915]() WARN_ON(wm_lp != 1) Modules linked in: i915 drm_kms_helper drm bluetooth fuse iTCO_wdt iTCO_vendor_support syscopyarea sysfillrect sysimgblt fb_sys_fops tpm_tis mei_me e1000e snd_hda_codec_hdmi pcspkr tpm mei i2c_i801 lpc_ich snd_hda_codec snd_hda_core CPU: 1 PID: 25405 Comm: kms_universal_p Tainted: G U W 4.5.0-rc6apollolake+ #462 Hardware name: /DH67GD, BIOS BLH6710H.86A.0160.2012.1204.1156 12/04/2012 0000000000000000 ffff88009d42b918 ffffffff8143cfab ffff88009d42b960 ffffffffa0363580 ffff88009d42b950 ffffffff81082746 ffff8800b9a24928 ffff88009d42ba00 ffff88009d4a0000 0000000000000000 ffff88009d42ba6c Call Trace: [] dump_stack+0x4d/0x72 [] warn_slowpath_common+0x86/0xc0 [] warn_slowpath_fmt+0x4c/0x50 [] ilk_program_watermarks+0x7b2/0x9d0 [i915] [] ilk_initial_watermarks+0x107/0x120 [i915] [] intel_pre_plane_update+0x12a/0x190 [i915] [] intel_atomic_commit+0x546/0xd50 [i915] [] drm_atomic_commit+0x37/0x60 [drm] [] drm_atomic_helper_disable_plane+0xb1/0xf0 [drm_kms_helper] [] __setplane_internal+0x184/0x280 [drm] [] ? drm_modeset_lock_all_ctx+0x9a/0xb0 [drm] [] drm_mode_setplane+0x13f/0x1c0 [drm] [] drm_ioctl+0x142/0x590 [drm] [] ? drm_plane_check_pixel_format+0x50/0x50 [drm] [] ? mntput+0x24/0x40 [] ? __fput+0x194/0x200 [] drm_compat_ioctl+0x33/0x40 [drm] [] i915_compat_ioctl+0x32/0x40 [i915] [] compat_SyS_ioctl+0xc2/0x330 [] ? exit_to_usermode_loop+0x95/0xb0 [] do_fast_syscall_32+0x9e/0x210 [] entry_SYSENTER_compat+0x52/0x70 Cc: Matt Roper Cc: Chris Wilson Cc: Paulo Zanoni Cc: Ville Syrjälä Testcase: kms_universal_plane Fixes: d81f04c5ef ("drm/i915: Allow preservation of watermarks, v2.") Signed-off-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/56DEA1FC.8080703@linux.intel.com Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_pm.c | 19 +++++++++++-------- 2 files changed, 12 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 3daf1e37af9c..7b2d66d8dd7f 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -390,6 +390,7 @@ struct intel_crtc_scaler_state { struct intel_pipe_wm { struct intel_wm_level wm[5]; + struct intel_wm_level raw_wm[5]; uint32_t linetime; bool fbc_wm_enabled; bool pipe_enabled; diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index f65e84137060..d7aef17bf0f9 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2335,7 +2335,6 @@ static int ilk_compute_pipe_wm(struct intel_crtc_state *cstate) drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16); } - usable_level = max_level; /* ILK/SNB: LP2+ watermarks only w/o sprites */ @@ -2347,7 +2346,10 @@ static int ilk_compute_pipe_wm(struct intel_crtc_state *cstate) usable_level = 0; ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate, - pristate, sprstate, curstate, &pipe_wm->wm[0]); + pristate, sprstate, curstate, &pipe_wm->raw_wm[0]); + + memset(&pipe_wm->wm, 0, sizeof(pipe_wm->wm)); + pipe_wm->wm[0] = pipe_wm->raw_wm[0]; if (IS_HASWELL(dev) || IS_BROADWELL(dev)) pipe_wm->linetime = hsw_compute_linetime_wm(dev, cstate); @@ -2358,7 +2360,7 @@ static int ilk_compute_pipe_wm(struct intel_crtc_state *cstate) ilk_compute_wm_reg_maximums(dev, 1, &max); for (level = 1; level <= max_level; level++) { - struct intel_wm_level *wm = &pipe_wm->wm[level]; + struct intel_wm_level *wm = &pipe_wm->raw_wm[level]; ilk_compute_wm_level(dev_priv, intel_crtc, level, cstate, pristate, sprstate, curstate, wm); @@ -2368,12 +2370,13 @@ static int ilk_compute_pipe_wm(struct intel_crtc_state *cstate) * register maximums since such watermarks are * always invalid. */ - if (level > usable_level) { - wm->enable = false; - } else if (!ilk_validate_wm_level(level, &max, wm)) { - wm->enable = false; + if (level > usable_level) + continue; + + if (ilk_validate_wm_level(level, &max, wm)) + pipe_wm->wm[level] = *wm; + else usable_level = level; - } } return 0; -- cgit v1.2.3 From 7abd4b35a577d6541bf07493a448eee9dfc8ba2d Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Tue, 8 Mar 2016 17:46:15 +0200 Subject: drm/i915: Move shared dpll code to a new file Create the new file intel_dpll_mgr.c and move the shared dpll code to it. Follow up patches that reorganize pll handling will move more code there and tweak the interface. No functional changes. Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1457451987-17466-2-git-send-email-ander.conselvan.de.oliveira@intel.com --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/intel_display.c | 348 +------------------------------- drivers/gpu/drm/i915/intel_dpll_mgr.c | 368 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_drv.h | 8 + 4 files changed, 379 insertions(+), 346 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_dpll_mgr.c (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 0851de07bd13..5558a0312558 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -56,6 +56,7 @@ i915-y += intel_audio.o \ intel_atomic_plane.o \ intel_bios.o \ intel_display.o \ + intel_dpll_mgr.o \ intel_fbc.o \ intel_fifo_underrun.o \ intel_frontbuffer.o \ diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 62d36a7b3398..1d5695d07abd 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1197,34 +1197,6 @@ static void assert_dsi_pll(struct drm_i915_private *dev_priv, bool state) #define assert_dsi_pll_enabled(d) assert_dsi_pll(d, true) #define assert_dsi_pll_disabled(d) assert_dsi_pll(d, false) -struct intel_shared_dpll * -intel_crtc_to_shared_dpll(struct intel_crtc *crtc) -{ - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; - - if (crtc->config->shared_dpll < 0) - return NULL; - - return &dev_priv->shared_dplls[crtc->config->shared_dpll]; -} - -/* For ILK+ */ -void assert_shared_dpll(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll, - bool state) -{ - bool cur_state; - struct intel_dpll_hw_state hw_state; - - if (WARN(!pll, "asserting DPLL %s with no DPLL\n", onoff(state))) - return; - - cur_state = pll->get_hw_state(dev_priv, pll, &hw_state); - I915_STATE_WARN(cur_state != state, - "%s assertion failure (expected %s, current %s)\n", - pll->name, onoff(state), onoff(cur_state)); -} - static void assert_fdi_tx(struct drm_i915_private *dev_priv, enum pipe pipe, bool state) { @@ -1461,21 +1433,8 @@ static void assert_vblank_disabled(struct drm_crtc *crtc) drm_crtc_vblank_put(crtc); } -static void ibx_assert_pch_refclk_enabled(struct drm_i915_private *dev_priv) -{ - u32 val; - bool enabled; - - I915_STATE_WARN_ON(!(HAS_PCH_IBX(dev_priv->dev) || HAS_PCH_CPT(dev_priv->dev))); - - val = I915_READ(PCH_DREF_CONTROL); - enabled = !!(val & (DREF_SSC_SOURCE_MASK | DREF_NONSPREAD_SOURCE_MASK | - DREF_SUPERSPREAD_SOURCE_MASK)); - I915_STATE_WARN(!enabled, "PCH refclk assertion failure, should be active but is disabled\n"); -} - -static void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv, - enum pipe pipe) +void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv, + enum pipe pipe) { u32 val; bool enabled; @@ -1871,100 +1830,6 @@ void vlv_wait_port_ready(struct drm_i915_private *dev_priv, port_name(dport->port), I915_READ(dpll_reg) & port_mask, expected_mask); } -static void intel_prepare_shared_dpll(struct intel_crtc *crtc) -{ - struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc); - - if (WARN_ON(pll == NULL)) - return; - - WARN_ON(!pll->config.crtc_mask); - if (pll->active == 0) { - DRM_DEBUG_DRIVER("setting up %s\n", pll->name); - WARN_ON(pll->on); - assert_shared_dpll_disabled(dev_priv, pll); - - pll->mode_set(dev_priv, pll); - } -} - -/** - * intel_enable_shared_dpll - enable PCH PLL - * @dev_priv: i915 private structure - * @pipe: pipe PLL to enable - * - * The PCH PLL needs to be enabled before the PCH transcoder, since it - * drives the transcoder clock. - */ -static void intel_enable_shared_dpll(struct intel_crtc *crtc) -{ - struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc); - - if (WARN_ON(pll == NULL)) - return; - - if (WARN_ON(pll->config.crtc_mask == 0)) - return; - - DRM_DEBUG_KMS("enable %s (active %d, on? %d) for crtc %d\n", - pll->name, pll->active, pll->on, - crtc->base.base.id); - - if (pll->active++) { - WARN_ON(!pll->on); - assert_shared_dpll_enabled(dev_priv, pll); - return; - } - WARN_ON(pll->on); - - intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS); - - DRM_DEBUG_KMS("enabling %s\n", pll->name); - pll->enable(dev_priv, pll); - pll->on = true; -} - -static void intel_disable_shared_dpll(struct intel_crtc *crtc) -{ - struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc); - - /* PCH only available on ILK+ */ - if (INTEL_INFO(dev)->gen < 5) - return; - - if (pll == NULL) - return; - - if (WARN_ON(!(pll->config.crtc_mask & (1 << drm_crtc_index(&crtc->base))))) - return; - - DRM_DEBUG_KMS("disable %s (active %d, on? %d) for crtc %d\n", - pll->name, pll->active, pll->on, - crtc->base.base.id); - - if (WARN_ON(pll->active == 0)) { - assert_shared_dpll_disabled(dev_priv, pll); - return; - } - - assert_shared_dpll_enabled(dev_priv, pll); - WARN_ON(!pll->on); - if (--pll->active) - return; - - DRM_DEBUG_KMS("disabling %s\n", pll->name); - pll->disable(dev_priv, pll); - pll->on = false; - - intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); -} - static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv, enum pipe pipe) { @@ -4361,113 +4226,6 @@ static void lpt_pch_enable(struct drm_crtc *crtc) lpt_enable_pch_transcoder(dev_priv, cpu_transcoder); } -struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, - struct intel_crtc_state *crtc_state) -{ - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; - struct intel_shared_dpll *pll; - struct intel_shared_dpll_config *shared_dpll; - enum intel_dpll_id i; - int max = dev_priv->num_shared_dpll; - - shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state->base.state); - - if (HAS_PCH_IBX(dev_priv->dev)) { - /* Ironlake PCH has a fixed PLL->PCH pipe mapping. */ - i = (enum intel_dpll_id) crtc->pipe; - pll = &dev_priv->shared_dplls[i]; - - DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n", - crtc->base.base.id, pll->name); - - WARN_ON(shared_dpll[i].crtc_mask); - - goto found; - } - - if (IS_BROXTON(dev_priv->dev)) { - /* PLL is attached to port in bxt */ - struct intel_encoder *encoder; - struct intel_digital_port *intel_dig_port; - - encoder = intel_ddi_get_crtc_new_encoder(crtc_state); - if (WARN_ON(!encoder)) - return NULL; - - intel_dig_port = enc_to_dig_port(&encoder->base); - /* 1:1 mapping between ports and PLLs */ - i = (enum intel_dpll_id)intel_dig_port->port; - pll = &dev_priv->shared_dplls[i]; - DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n", - crtc->base.base.id, pll->name); - WARN_ON(shared_dpll[i].crtc_mask); - - goto found; - } else if (INTEL_INFO(dev_priv)->gen < 9 && HAS_DDI(dev_priv)) - /* Do not consider SPLL */ - max = 2; - - for (i = 0; i < max; i++) { - pll = &dev_priv->shared_dplls[i]; - - /* Only want to check enabled timings first */ - if (shared_dpll[i].crtc_mask == 0) - continue; - - if (memcmp(&crtc_state->dpll_hw_state, - &shared_dpll[i].hw_state, - sizeof(crtc_state->dpll_hw_state)) == 0) { - DRM_DEBUG_KMS("CRTC:%d sharing existing %s (crtc mask 0x%08x, ative %d)\n", - crtc->base.base.id, pll->name, - shared_dpll[i].crtc_mask, - pll->active); - goto found; - } - } - - /* Ok no matching timings, maybe there's a free one? */ - for (i = 0; i < dev_priv->num_shared_dpll; i++) { - pll = &dev_priv->shared_dplls[i]; - if (shared_dpll[i].crtc_mask == 0) { - DRM_DEBUG_KMS("CRTC:%d allocated %s\n", - crtc->base.base.id, pll->name); - goto found; - } - } - - return NULL; - -found: - if (shared_dpll[i].crtc_mask == 0) - shared_dpll[i].hw_state = - crtc_state->dpll_hw_state; - - crtc_state->shared_dpll = i; - DRM_DEBUG_DRIVER("using %s for pipe %c\n", pll->name, - pipe_name(crtc->pipe)); - - shared_dpll[i].crtc_mask |= 1 << crtc->pipe; - - return pll; -} - -static void intel_shared_dpll_commit(struct drm_atomic_state *state) -{ - struct drm_i915_private *dev_priv = to_i915(state->dev); - struct intel_shared_dpll_config *shared_dpll; - struct intel_shared_dpll *pll; - enum intel_dpll_id i; - - if (!to_intel_atomic_state(state)->dpll_set) - return; - - shared_dpll = to_intel_atomic_state(state)->shared_dpll; - for (i = 0; i < dev_priv->num_shared_dpll; i++) { - pll = &dev_priv->shared_dplls[i]; - pll->config = shared_dpll[i]; - } -} - static void cpt_verify_modeset(struct drm_device *dev, int pipe) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -13887,108 +13645,6 @@ static const struct drm_crtc_funcs intel_crtc_funcs = { .atomic_destroy_state = intel_crtc_destroy_state, }; -static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll, - struct intel_dpll_hw_state *hw_state) -{ - uint32_t val; - - if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS)) - return false; - - val = I915_READ(PCH_DPLL(pll->id)); - hw_state->dpll = val; - hw_state->fp0 = I915_READ(PCH_FP0(pll->id)); - hw_state->fp1 = I915_READ(PCH_FP1(pll->id)); - - intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); - - return val & DPLL_VCO_ENABLE; -} - -static void ibx_pch_dpll_mode_set(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll) -{ - I915_WRITE(PCH_FP0(pll->id), pll->config.hw_state.fp0); - I915_WRITE(PCH_FP1(pll->id), pll->config.hw_state.fp1); -} - -static void ibx_pch_dpll_enable(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll) -{ - /* PCH refclock must be enabled first */ - ibx_assert_pch_refclk_enabled(dev_priv); - - I915_WRITE(PCH_DPLL(pll->id), pll->config.hw_state.dpll); - - /* Wait for the clocks to stabilize. */ - POSTING_READ(PCH_DPLL(pll->id)); - udelay(150); - - /* The pixel multiplier can only be updated once the - * DPLL is enabled and the clocks are stable. - * - * So write it again. - */ - I915_WRITE(PCH_DPLL(pll->id), pll->config.hw_state.dpll); - POSTING_READ(PCH_DPLL(pll->id)); - udelay(200); -} - -static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll) -{ - struct drm_device *dev = dev_priv->dev; - struct intel_crtc *crtc; - - /* Make sure no transcoder isn't still depending on us. */ - for_each_intel_crtc(dev, crtc) { - if (intel_crtc_to_shared_dpll(crtc) == pll) - assert_pch_transcoder_disabled(dev_priv, crtc->pipe); - } - - I915_WRITE(PCH_DPLL(pll->id), 0); - POSTING_READ(PCH_DPLL(pll->id)); - udelay(200); -} - -static char *ibx_pch_dpll_names[] = { - "PCH DPLL A", - "PCH DPLL B", -}; - -static void ibx_pch_dpll_init(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int i; - - dev_priv->num_shared_dpll = 2; - - for (i = 0; i < dev_priv->num_shared_dpll; i++) { - dev_priv->shared_dplls[i].id = i; - dev_priv->shared_dplls[i].name = ibx_pch_dpll_names[i]; - dev_priv->shared_dplls[i].mode_set = ibx_pch_dpll_mode_set; - dev_priv->shared_dplls[i].enable = ibx_pch_dpll_enable; - dev_priv->shared_dplls[i].disable = ibx_pch_dpll_disable; - dev_priv->shared_dplls[i].get_hw_state = - ibx_pch_dpll_get_hw_state; - } -} - -static void intel_shared_dpll_init(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - if (HAS_DDI(dev)) - intel_ddi_pll_init(dev); - else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) - ibx_pch_dpll_init(dev); - else - dev_priv->num_shared_dpll = 0; - - BUG_ON(dev_priv->num_shared_dpll > I915_NUM_PLLS); -} - /** * intel_prepare_plane_fb - Prepare fb for usage on plane * @plane: drm plane to prepare for diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c new file mode 100644 index 000000000000..d7ebac6619a3 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c @@ -0,0 +1,368 @@ +/* + * Copyright © 2006-2016 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "intel_drv.h" + +struct intel_shared_dpll * +intel_crtc_to_shared_dpll(struct intel_crtc *crtc) +{ + struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + + if (crtc->config->shared_dpll < 0) + return NULL; + + return &dev_priv->shared_dplls[crtc->config->shared_dpll]; +} + +/* For ILK+ */ +void assert_shared_dpll(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll, + bool state) +{ + bool cur_state; + struct intel_dpll_hw_state hw_state; + + if (WARN(!pll, "asserting DPLL %s with no DPLL\n", onoff(state))) + return; + + cur_state = pll->get_hw_state(dev_priv, pll, &hw_state); + I915_STATE_WARN(cur_state != state, + "%s assertion failure (expected %s, current %s)\n", + pll->name, onoff(state), onoff(cur_state)); +} + +void intel_prepare_shared_dpll(struct intel_crtc *crtc) +{ + struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc); + + if (WARN_ON(pll == NULL)) + return; + + WARN_ON(!pll->config.crtc_mask); + if (pll->active == 0) { + DRM_DEBUG_DRIVER("setting up %s\n", pll->name); + WARN_ON(pll->on); + assert_shared_dpll_disabled(dev_priv, pll); + + pll->mode_set(dev_priv, pll); + } +} + +/** + * intel_enable_shared_dpll - enable PCH PLL + * @dev_priv: i915 private structure + * @pipe: pipe PLL to enable + * + * The PCH PLL needs to be enabled before the PCH transcoder, since it + * drives the transcoder clock. + */ +void intel_enable_shared_dpll(struct intel_crtc *crtc) +{ + struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc); + + if (WARN_ON(pll == NULL)) + return; + + if (WARN_ON(pll->config.crtc_mask == 0)) + return; + + DRM_DEBUG_KMS("enable %s (active %d, on? %d) for crtc %d\n", + pll->name, pll->active, pll->on, + crtc->base.base.id); + + if (pll->active++) { + WARN_ON(!pll->on); + assert_shared_dpll_enabled(dev_priv, pll); + return; + } + WARN_ON(pll->on); + + intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS); + + DRM_DEBUG_KMS("enabling %s\n", pll->name); + pll->enable(dev_priv, pll); + pll->on = true; +} + +void intel_disable_shared_dpll(struct intel_crtc *crtc) +{ + struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc); + + /* PCH only available on ILK+ */ + if (INTEL_INFO(dev)->gen < 5) + return; + + if (pll == NULL) + return; + + if (WARN_ON(!(pll->config.crtc_mask & (1 << drm_crtc_index(&crtc->base))))) + return; + + DRM_DEBUG_KMS("disable %s (active %d, on? %d) for crtc %d\n", + pll->name, pll->active, pll->on, + crtc->base.base.id); + + if (WARN_ON(pll->active == 0)) { + assert_shared_dpll_disabled(dev_priv, pll); + return; + } + + assert_shared_dpll_enabled(dev_priv, pll); + WARN_ON(!pll->on); + if (--pll->active) + return; + + DRM_DEBUG_KMS("disabling %s\n", pll->name); + pll->disable(dev_priv, pll); + pll->on = false; + + intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); +} + +struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, + struct intel_crtc_state *crtc_state) +{ + struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct intel_shared_dpll *pll; + struct intel_shared_dpll_config *shared_dpll; + enum intel_dpll_id i; + int max = dev_priv->num_shared_dpll; + + shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state->base.state); + + if (HAS_PCH_IBX(dev_priv->dev)) { + /* Ironlake PCH has a fixed PLL->PCH pipe mapping. */ + i = (enum intel_dpll_id) crtc->pipe; + pll = &dev_priv->shared_dplls[i]; + + DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n", + crtc->base.base.id, pll->name); + + WARN_ON(shared_dpll[i].crtc_mask); + + goto found; + } + + if (IS_BROXTON(dev_priv->dev)) { + /* PLL is attached to port in bxt */ + struct intel_encoder *encoder; + struct intel_digital_port *intel_dig_port; + + encoder = intel_ddi_get_crtc_new_encoder(crtc_state); + if (WARN_ON(!encoder)) + return NULL; + + intel_dig_port = enc_to_dig_port(&encoder->base); + /* 1:1 mapping between ports and PLLs */ + i = (enum intel_dpll_id)intel_dig_port->port; + pll = &dev_priv->shared_dplls[i]; + DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n", + crtc->base.base.id, pll->name); + WARN_ON(shared_dpll[i].crtc_mask); + + goto found; + } else if (INTEL_INFO(dev_priv)->gen < 9 && HAS_DDI(dev_priv)) + /* Do not consider SPLL */ + max = 2; + + for (i = 0; i < max; i++) { + pll = &dev_priv->shared_dplls[i]; + + /* Only want to check enabled timings first */ + if (shared_dpll[i].crtc_mask == 0) + continue; + + if (memcmp(&crtc_state->dpll_hw_state, + &shared_dpll[i].hw_state, + sizeof(crtc_state->dpll_hw_state)) == 0) { + DRM_DEBUG_KMS("CRTC:%d sharing existing %s (crtc mask 0x%08x, ative %d)\n", + crtc->base.base.id, pll->name, + shared_dpll[i].crtc_mask, + pll->active); + goto found; + } + } + + /* Ok no matching timings, maybe there's a free one? */ + for (i = 0; i < dev_priv->num_shared_dpll; i++) { + pll = &dev_priv->shared_dplls[i]; + if (shared_dpll[i].crtc_mask == 0) { + DRM_DEBUG_KMS("CRTC:%d allocated %s\n", + crtc->base.base.id, pll->name); + goto found; + } + } + + return NULL; + +found: + if (shared_dpll[i].crtc_mask == 0) + shared_dpll[i].hw_state = + crtc_state->dpll_hw_state; + + crtc_state->shared_dpll = i; + DRM_DEBUG_DRIVER("using %s for pipe %c\n", pll->name, + pipe_name(crtc->pipe)); + + shared_dpll[i].crtc_mask |= 1 << crtc->pipe; + + return pll; +} + +void intel_shared_dpll_commit(struct drm_atomic_state *state) +{ + struct drm_i915_private *dev_priv = to_i915(state->dev); + struct intel_shared_dpll_config *shared_dpll; + struct intel_shared_dpll *pll; + enum intel_dpll_id i; + + if (!to_intel_atomic_state(state)->dpll_set) + return; + + shared_dpll = to_intel_atomic_state(state)->shared_dpll; + for (i = 0; i < dev_priv->num_shared_dpll; i++) { + pll = &dev_priv->shared_dplls[i]; + pll->config = shared_dpll[i]; + } +} + +static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll, + struct intel_dpll_hw_state *hw_state) +{ + uint32_t val; + + if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS)) + return false; + + val = I915_READ(PCH_DPLL(pll->id)); + hw_state->dpll = val; + hw_state->fp0 = I915_READ(PCH_FP0(pll->id)); + hw_state->fp1 = I915_READ(PCH_FP1(pll->id)); + + intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); + + return val & DPLL_VCO_ENABLE; +} + +static void ibx_pch_dpll_mode_set(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll) +{ + I915_WRITE(PCH_FP0(pll->id), pll->config.hw_state.fp0); + I915_WRITE(PCH_FP1(pll->id), pll->config.hw_state.fp1); +} + +static void ibx_assert_pch_refclk_enabled(struct drm_i915_private *dev_priv) +{ + u32 val; + bool enabled; + + I915_STATE_WARN_ON(!(HAS_PCH_IBX(dev_priv->dev) || HAS_PCH_CPT(dev_priv->dev))); + + val = I915_READ(PCH_DREF_CONTROL); + enabled = !!(val & (DREF_SSC_SOURCE_MASK | DREF_NONSPREAD_SOURCE_MASK | + DREF_SUPERSPREAD_SOURCE_MASK)); + I915_STATE_WARN(!enabled, "PCH refclk assertion failure, should be active but is disabled\n"); +} + +static void ibx_pch_dpll_enable(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll) +{ + /* PCH refclock must be enabled first */ + ibx_assert_pch_refclk_enabled(dev_priv); + + I915_WRITE(PCH_DPLL(pll->id), pll->config.hw_state.dpll); + + /* Wait for the clocks to stabilize. */ + POSTING_READ(PCH_DPLL(pll->id)); + udelay(150); + + /* The pixel multiplier can only be updated once the + * DPLL is enabled and the clocks are stable. + * + * So write it again. + */ + I915_WRITE(PCH_DPLL(pll->id), pll->config.hw_state.dpll); + POSTING_READ(PCH_DPLL(pll->id)); + udelay(200); +} + +static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll) +{ + struct drm_device *dev = dev_priv->dev; + struct intel_crtc *crtc; + + /* Make sure no transcoder isn't still depending on us. */ + for_each_intel_crtc(dev, crtc) { + if (intel_crtc_to_shared_dpll(crtc) == pll) + assert_pch_transcoder_disabled(dev_priv, crtc->pipe); + } + + I915_WRITE(PCH_DPLL(pll->id), 0); + POSTING_READ(PCH_DPLL(pll->id)); + udelay(200); +} + +static char *ibx_pch_dpll_names[] = { + "PCH DPLL A", + "PCH DPLL B", +}; + +static void ibx_pch_dpll_init(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + int i; + + dev_priv->num_shared_dpll = 2; + + for (i = 0; i < dev_priv->num_shared_dpll; i++) { + dev_priv->shared_dplls[i].id = i; + dev_priv->shared_dplls[i].name = ibx_pch_dpll_names[i]; + dev_priv->shared_dplls[i].mode_set = ibx_pch_dpll_mode_set; + dev_priv->shared_dplls[i].enable = ibx_pch_dpll_enable; + dev_priv->shared_dplls[i].disable = ibx_pch_dpll_disable; + dev_priv->shared_dplls[i].get_hw_state = + ibx_pch_dpll_get_hw_state; + } +} + +void intel_shared_dpll_init(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + if (HAS_DDI(dev)) + intel_ddi_pll_init(dev); + else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) + ibx_pch_dpll_init(dev); + else + dev_priv->num_shared_dpll = 0; + + BUG_ON(dev_priv->num_shared_dpll > I915_NUM_PLLS); +} diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 7b2d66d8dd7f..63b36b56c913 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1201,6 +1201,9 @@ intel_rotation_90_or_270(unsigned int rotation) void intel_create_rotation_property(struct drm_device *dev, struct intel_plane *plane); +void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv, + enum pipe pipe); + /* shared dpll functions */ struct intel_shared_dpll *intel_crtc_to_shared_dpll(struct intel_crtc *crtc); void assert_shared_dpll(struct drm_i915_private *dev_priv, @@ -1210,6 +1213,11 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv, #define assert_shared_dpll_disabled(d, p) assert_shared_dpll(d, p, false) struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, struct intel_crtc_state *state); +void intel_prepare_shared_dpll(struct intel_crtc *crtc); +void intel_enable_shared_dpll(struct intel_crtc *crtc); +void intel_disable_shared_dpll(struct intel_crtc *crtc); +void intel_shared_dpll_commit(struct drm_atomic_state *state); +void intel_shared_dpll_init(struct drm_device *dev); int vlv_force_pll_on(struct drm_device *dev, enum pipe pipe, const struct dpll *dpll); -- cgit v1.2.3 From 55be2f0854613b97aa606122bbe8b12a4b068bd9 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Tue, 8 Mar 2016 17:46:16 +0200 Subject: drm/i915: Move ddi shared dpll code to intel_dpll_mgr.c No functional changes. Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1457451987-17466-3-git-send-email-ander.conselvan.de.oliveira@intel.com --- drivers/gpu/drm/i915/intel_ddi.c | 472 ---------------------------------- drivers/gpu/drm/i915/intel_dpll_mgr.c | 472 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_drv.h | 1 - 3 files changed, 472 insertions(+), 473 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 62de9f4bce09..54880662f597 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -2430,235 +2430,6 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder) } } -static void hsw_ddi_wrpll_enable(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll) -{ - I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll); - POSTING_READ(WRPLL_CTL(pll->id)); - udelay(20); -} - -static void hsw_ddi_spll_enable(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll) -{ - I915_WRITE(SPLL_CTL, pll->config.hw_state.spll); - POSTING_READ(SPLL_CTL); - udelay(20); -} - -static void hsw_ddi_wrpll_disable(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll) -{ - uint32_t val; - - val = I915_READ(WRPLL_CTL(pll->id)); - I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE); - POSTING_READ(WRPLL_CTL(pll->id)); -} - -static void hsw_ddi_spll_disable(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll) -{ - uint32_t val; - - val = I915_READ(SPLL_CTL); - I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE); - POSTING_READ(SPLL_CTL); -} - -static bool hsw_ddi_wrpll_get_hw_state(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll, - struct intel_dpll_hw_state *hw_state) -{ - uint32_t val; - - if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS)) - return false; - - val = I915_READ(WRPLL_CTL(pll->id)); - hw_state->wrpll = val; - - intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); - - return val & WRPLL_PLL_ENABLE; -} - -static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll, - struct intel_dpll_hw_state *hw_state) -{ - uint32_t val; - - if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS)) - return false; - - val = I915_READ(SPLL_CTL); - hw_state->spll = val; - - intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); - - return val & SPLL_PLL_ENABLE; -} - - -static const char * const hsw_ddi_pll_names[] = { - "WRPLL 1", - "WRPLL 2", - "SPLL" -}; - -static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv) -{ - int i; - - dev_priv->num_shared_dpll = 3; - - for (i = 0; i < 2; i++) { - dev_priv->shared_dplls[i].id = i; - dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i]; - dev_priv->shared_dplls[i].disable = hsw_ddi_wrpll_disable; - dev_priv->shared_dplls[i].enable = hsw_ddi_wrpll_enable; - dev_priv->shared_dplls[i].get_hw_state = - hsw_ddi_wrpll_get_hw_state; - } - - /* SPLL is special, but needs to be initialized anyway.. */ - dev_priv->shared_dplls[i].id = i; - dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i]; - dev_priv->shared_dplls[i].disable = hsw_ddi_spll_disable; - dev_priv->shared_dplls[i].enable = hsw_ddi_spll_enable; - dev_priv->shared_dplls[i].get_hw_state = hsw_ddi_spll_get_hw_state; - -} - -static const char * const skl_ddi_pll_names[] = { - "DPLL 1", - "DPLL 2", - "DPLL 3", -}; - -struct skl_dpll_regs { - i915_reg_t ctl, cfgcr1, cfgcr2; -}; - -/* this array is indexed by the *shared* pll id */ -static const struct skl_dpll_regs skl_dpll_regs[3] = { - { - /* DPLL 1 */ - .ctl = LCPLL2_CTL, - .cfgcr1 = DPLL_CFGCR1(SKL_DPLL1), - .cfgcr2 = DPLL_CFGCR2(SKL_DPLL1), - }, - { - /* DPLL 2 */ - .ctl = WRPLL_CTL(0), - .cfgcr1 = DPLL_CFGCR1(SKL_DPLL2), - .cfgcr2 = DPLL_CFGCR2(SKL_DPLL2), - }, - { - /* DPLL 3 */ - .ctl = WRPLL_CTL(1), - .cfgcr1 = DPLL_CFGCR1(SKL_DPLL3), - .cfgcr2 = DPLL_CFGCR2(SKL_DPLL3), - }, -}; - -static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll) -{ - uint32_t val; - unsigned int dpll; - const struct skl_dpll_regs *regs = skl_dpll_regs; - - /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */ - dpll = pll->id + 1; - - val = I915_READ(DPLL_CTRL1); - - val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) | - DPLL_CTRL1_LINK_RATE_MASK(dpll)); - val |= pll->config.hw_state.ctrl1 << (dpll * 6); - - I915_WRITE(DPLL_CTRL1, val); - POSTING_READ(DPLL_CTRL1); - - I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1); - I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2); - POSTING_READ(regs[pll->id].cfgcr1); - POSTING_READ(regs[pll->id].cfgcr2); - - /* the enable bit is always bit 31 */ - I915_WRITE(regs[pll->id].ctl, - I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE); - - if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5)) - DRM_ERROR("DPLL %d not locked\n", dpll); -} - -static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll) -{ - const struct skl_dpll_regs *regs = skl_dpll_regs; - - /* the enable bit is always bit 31 */ - I915_WRITE(regs[pll->id].ctl, - I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE); - POSTING_READ(regs[pll->id].ctl); -} - -static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll, - struct intel_dpll_hw_state *hw_state) -{ - uint32_t val; - unsigned int dpll; - const struct skl_dpll_regs *regs = skl_dpll_regs; - bool ret; - - if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS)) - return false; - - ret = false; - - /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */ - dpll = pll->id + 1; - - val = I915_READ(regs[pll->id].ctl); - if (!(val & LCPLL_PLL_ENABLE)) - goto out; - - val = I915_READ(DPLL_CTRL1); - hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f; - - /* avoid reading back stale values if HDMI mode is not enabled */ - if (val & DPLL_CTRL1_HDMI_MODE(dpll)) { - hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1); - hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2); - } - ret = true; - -out: - intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); - - return ret; -} - -static void skl_shared_dplls_init(struct drm_i915_private *dev_priv) -{ - int i; - - dev_priv->num_shared_dpll = 3; - - for (i = 0; i < dev_priv->num_shared_dpll; i++) { - dev_priv->shared_dplls[i].id = i; - dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i]; - dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable; - dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable; - dev_priv->shared_dplls[i].get_hw_state = - skl_ddi_pll_get_hw_state; - } -} - static void broxton_phy_init(struct drm_i915_private *dev_priv, enum dpio_phy phy) { @@ -2783,249 +2554,6 @@ void broxton_ddi_phy_uninit(struct drm_device *dev) I915_WRITE(BXT_P_CR_GT_DISP_PWRON, 0); } -static const char * const bxt_ddi_pll_names[] = { - "PORT PLL A", - "PORT PLL B", - "PORT PLL C", -}; - -static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll) -{ - uint32_t temp; - enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */ - - temp = I915_READ(BXT_PORT_PLL_ENABLE(port)); - temp &= ~PORT_PLL_REF_SEL; - /* Non-SSC reference */ - I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp); - - /* Disable 10 bit clock */ - temp = I915_READ(BXT_PORT_PLL_EBB_4(port)); - temp &= ~PORT_PLL_10BIT_CLK_ENABLE; - I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp); - - /* Write P1 & P2 */ - temp = I915_READ(BXT_PORT_PLL_EBB_0(port)); - temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK); - temp |= pll->config.hw_state.ebb0; - I915_WRITE(BXT_PORT_PLL_EBB_0(port), temp); - - /* Write M2 integer */ - temp = I915_READ(BXT_PORT_PLL(port, 0)); - temp &= ~PORT_PLL_M2_MASK; - temp |= pll->config.hw_state.pll0; - I915_WRITE(BXT_PORT_PLL(port, 0), temp); - - /* Write N */ - temp = I915_READ(BXT_PORT_PLL(port, 1)); - temp &= ~PORT_PLL_N_MASK; - temp |= pll->config.hw_state.pll1; - I915_WRITE(BXT_PORT_PLL(port, 1), temp); - - /* Write M2 fraction */ - temp = I915_READ(BXT_PORT_PLL(port, 2)); - temp &= ~PORT_PLL_M2_FRAC_MASK; - temp |= pll->config.hw_state.pll2; - I915_WRITE(BXT_PORT_PLL(port, 2), temp); - - /* Write M2 fraction enable */ - temp = I915_READ(BXT_PORT_PLL(port, 3)); - temp &= ~PORT_PLL_M2_FRAC_ENABLE; - temp |= pll->config.hw_state.pll3; - I915_WRITE(BXT_PORT_PLL(port, 3), temp); - - /* Write coeff */ - temp = I915_READ(BXT_PORT_PLL(port, 6)); - temp &= ~PORT_PLL_PROP_COEFF_MASK; - temp &= ~PORT_PLL_INT_COEFF_MASK; - temp &= ~PORT_PLL_GAIN_CTL_MASK; - temp |= pll->config.hw_state.pll6; - I915_WRITE(BXT_PORT_PLL(port, 6), temp); - - /* Write calibration val */ - temp = I915_READ(BXT_PORT_PLL(port, 8)); - temp &= ~PORT_PLL_TARGET_CNT_MASK; - temp |= pll->config.hw_state.pll8; - I915_WRITE(BXT_PORT_PLL(port, 8), temp); - - temp = I915_READ(BXT_PORT_PLL(port, 9)); - temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK; - temp |= pll->config.hw_state.pll9; - I915_WRITE(BXT_PORT_PLL(port, 9), temp); - - temp = I915_READ(BXT_PORT_PLL(port, 10)); - temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H; - temp &= ~PORT_PLL_DCO_AMP_MASK; - temp |= pll->config.hw_state.pll10; - I915_WRITE(BXT_PORT_PLL(port, 10), temp); - - /* Recalibrate with new settings */ - temp = I915_READ(BXT_PORT_PLL_EBB_4(port)); - temp |= PORT_PLL_RECALIBRATE; - I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp); - temp &= ~PORT_PLL_10BIT_CLK_ENABLE; - temp |= pll->config.hw_state.ebb4; - I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp); - - /* Enable PLL */ - temp = I915_READ(BXT_PORT_PLL_ENABLE(port)); - temp |= PORT_PLL_ENABLE; - I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp); - POSTING_READ(BXT_PORT_PLL_ENABLE(port)); - - if (wait_for_atomic_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) & - PORT_PLL_LOCK), 200)) - DRM_ERROR("PLL %d not locked\n", port); - - /* - * While we write to the group register to program all lanes at once we - * can read only lane registers and we pick lanes 0/1 for that. - */ - temp = I915_READ(BXT_PORT_PCS_DW12_LN01(port)); - temp &= ~LANE_STAGGER_MASK; - temp &= ~LANESTAGGER_STRAP_OVRD; - temp |= pll->config.hw_state.pcsdw12; - I915_WRITE(BXT_PORT_PCS_DW12_GRP(port), temp); -} - -static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll) -{ - enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */ - uint32_t temp; - - temp = I915_READ(BXT_PORT_PLL_ENABLE(port)); - temp &= ~PORT_PLL_ENABLE; - I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp); - POSTING_READ(BXT_PORT_PLL_ENABLE(port)); -} - -static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll, - struct intel_dpll_hw_state *hw_state) -{ - enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */ - uint32_t val; - bool ret; - - if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS)) - return false; - - ret = false; - - val = I915_READ(BXT_PORT_PLL_ENABLE(port)); - if (!(val & PORT_PLL_ENABLE)) - goto out; - - hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port)); - hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK; - - hw_state->ebb4 = I915_READ(BXT_PORT_PLL_EBB_4(port)); - hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE; - - hw_state->pll0 = I915_READ(BXT_PORT_PLL(port, 0)); - hw_state->pll0 &= PORT_PLL_M2_MASK; - - hw_state->pll1 = I915_READ(BXT_PORT_PLL(port, 1)); - hw_state->pll1 &= PORT_PLL_N_MASK; - - hw_state->pll2 = I915_READ(BXT_PORT_PLL(port, 2)); - hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK; - - hw_state->pll3 = I915_READ(BXT_PORT_PLL(port, 3)); - hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE; - - hw_state->pll6 = I915_READ(BXT_PORT_PLL(port, 6)); - hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK | - PORT_PLL_INT_COEFF_MASK | - PORT_PLL_GAIN_CTL_MASK; - - hw_state->pll8 = I915_READ(BXT_PORT_PLL(port, 8)); - hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK; - - hw_state->pll9 = I915_READ(BXT_PORT_PLL(port, 9)); - hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK; - - hw_state->pll10 = I915_READ(BXT_PORT_PLL(port, 10)); - hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H | - PORT_PLL_DCO_AMP_MASK; - - /* - * While we write to the group register to program all lanes at once we - * can read only lane registers. We configure all lanes the same way, so - * here just read out lanes 0/1 and output a note if lanes 2/3 differ. - */ - hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(port)); - if (I915_READ(BXT_PORT_PCS_DW12_LN23(port)) != hw_state->pcsdw12) - DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n", - hw_state->pcsdw12, - I915_READ(BXT_PORT_PCS_DW12_LN23(port))); - hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD; - - ret = true; - -out: - intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); - - return ret; -} - -static void bxt_shared_dplls_init(struct drm_i915_private *dev_priv) -{ - int i; - - dev_priv->num_shared_dpll = 3; - - for (i = 0; i < dev_priv->num_shared_dpll; i++) { - dev_priv->shared_dplls[i].id = i; - dev_priv->shared_dplls[i].name = bxt_ddi_pll_names[i]; - dev_priv->shared_dplls[i].disable = bxt_ddi_pll_disable; - dev_priv->shared_dplls[i].enable = bxt_ddi_pll_enable; - dev_priv->shared_dplls[i].get_hw_state = - bxt_ddi_pll_get_hw_state; - } -} - -void intel_ddi_pll_init(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t val = I915_READ(LCPLL_CTL); - - if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) - skl_shared_dplls_init(dev_priv); - else if (IS_BROXTON(dev)) - bxt_shared_dplls_init(dev_priv); - else - hsw_shared_dplls_init(dev_priv); - - if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) { - int cdclk_freq; - - cdclk_freq = dev_priv->display.get_display_clock_speed(dev); - dev_priv->skl_boot_cdclk = cdclk_freq; - if (skl_sanitize_cdclk(dev_priv)) - DRM_DEBUG_KMS("Sanitized cdclk programmed by pre-os\n"); - if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE)) - DRM_ERROR("LCPLL1 is disabled\n"); - } else if (IS_BROXTON(dev)) { - broxton_init_cdclk(dev); - broxton_ddi_phy_init(dev); - } else { - /* - * The LCPLL register should be turned on by the BIOS. For now - * let's just check its state and print errors in case - * something is wrong. Don't even try to turn it on. - */ - - if (val & LCPLL_CD_SOURCE_FCLK) - DRM_ERROR("CDCLK source is not LCPLL\n"); - - if (val & LCPLL_PLL_DISABLE) - DRM_ERROR("LCPLL is disabled\n"); - } -} - void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c index d7ebac6619a3..6be0cd09ea88 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c @@ -353,6 +353,478 @@ static void ibx_pch_dpll_init(struct drm_device *dev) } } +static void hsw_ddi_wrpll_enable(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll) +{ + I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll); + POSTING_READ(WRPLL_CTL(pll->id)); + udelay(20); +} + +static void hsw_ddi_spll_enable(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll) +{ + I915_WRITE(SPLL_CTL, pll->config.hw_state.spll); + POSTING_READ(SPLL_CTL); + udelay(20); +} + +static void hsw_ddi_wrpll_disable(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll) +{ + uint32_t val; + + val = I915_READ(WRPLL_CTL(pll->id)); + I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE); + POSTING_READ(WRPLL_CTL(pll->id)); +} + +static void hsw_ddi_spll_disable(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll) +{ + uint32_t val; + + val = I915_READ(SPLL_CTL); + I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE); + POSTING_READ(SPLL_CTL); +} + +static bool hsw_ddi_wrpll_get_hw_state(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll, + struct intel_dpll_hw_state *hw_state) +{ + uint32_t val; + + if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS)) + return false; + + val = I915_READ(WRPLL_CTL(pll->id)); + hw_state->wrpll = val; + + intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); + + return val & WRPLL_PLL_ENABLE; +} + +static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll, + struct intel_dpll_hw_state *hw_state) +{ + uint32_t val; + + if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS)) + return false; + + val = I915_READ(SPLL_CTL); + hw_state->spll = val; + + intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); + + return val & SPLL_PLL_ENABLE; +} + + +static const char * const hsw_ddi_pll_names[] = { + "WRPLL 1", + "WRPLL 2", + "SPLL" +}; + +static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv) +{ + int i; + + dev_priv->num_shared_dpll = 3; + + for (i = 0; i < 2; i++) { + dev_priv->shared_dplls[i].id = i; + dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i]; + dev_priv->shared_dplls[i].disable = hsw_ddi_wrpll_disable; + dev_priv->shared_dplls[i].enable = hsw_ddi_wrpll_enable; + dev_priv->shared_dplls[i].get_hw_state = + hsw_ddi_wrpll_get_hw_state; + } + + /* SPLL is special, but needs to be initialized anyway.. */ + dev_priv->shared_dplls[i].id = i; + dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i]; + dev_priv->shared_dplls[i].disable = hsw_ddi_spll_disable; + dev_priv->shared_dplls[i].enable = hsw_ddi_spll_enable; + dev_priv->shared_dplls[i].get_hw_state = hsw_ddi_spll_get_hw_state; + +} + +static const char * const skl_ddi_pll_names[] = { + "DPLL 1", + "DPLL 2", + "DPLL 3", +}; + +struct skl_dpll_regs { + i915_reg_t ctl, cfgcr1, cfgcr2; +}; + +/* this array is indexed by the *shared* pll id */ +static const struct skl_dpll_regs skl_dpll_regs[3] = { + { + /* DPLL 1 */ + .ctl = LCPLL2_CTL, + .cfgcr1 = DPLL_CFGCR1(SKL_DPLL1), + .cfgcr2 = DPLL_CFGCR2(SKL_DPLL1), + }, + { + /* DPLL 2 */ + .ctl = WRPLL_CTL(0), + .cfgcr1 = DPLL_CFGCR1(SKL_DPLL2), + .cfgcr2 = DPLL_CFGCR2(SKL_DPLL2), + }, + { + /* DPLL 3 */ + .ctl = WRPLL_CTL(1), + .cfgcr1 = DPLL_CFGCR1(SKL_DPLL3), + .cfgcr2 = DPLL_CFGCR2(SKL_DPLL3), + }, +}; + +static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll) +{ + uint32_t val; + unsigned int dpll; + const struct skl_dpll_regs *regs = skl_dpll_regs; + + /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */ + dpll = pll->id + 1; + + val = I915_READ(DPLL_CTRL1); + + val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) | + DPLL_CTRL1_LINK_RATE_MASK(dpll)); + val |= pll->config.hw_state.ctrl1 << (dpll * 6); + + I915_WRITE(DPLL_CTRL1, val); + POSTING_READ(DPLL_CTRL1); + + I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1); + I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2); + POSTING_READ(regs[pll->id].cfgcr1); + POSTING_READ(regs[pll->id].cfgcr2); + + /* the enable bit is always bit 31 */ + I915_WRITE(regs[pll->id].ctl, + I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE); + + if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5)) + DRM_ERROR("DPLL %d not locked\n", dpll); +} + +static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll) +{ + const struct skl_dpll_regs *regs = skl_dpll_regs; + + /* the enable bit is always bit 31 */ + I915_WRITE(regs[pll->id].ctl, + I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE); + POSTING_READ(regs[pll->id].ctl); +} + +static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll, + struct intel_dpll_hw_state *hw_state) +{ + uint32_t val; + unsigned int dpll; + const struct skl_dpll_regs *regs = skl_dpll_regs; + bool ret; + + if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS)) + return false; + + ret = false; + + /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */ + dpll = pll->id + 1; + + val = I915_READ(regs[pll->id].ctl); + if (!(val & LCPLL_PLL_ENABLE)) + goto out; + + val = I915_READ(DPLL_CTRL1); + hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f; + + /* avoid reading back stale values if HDMI mode is not enabled */ + if (val & DPLL_CTRL1_HDMI_MODE(dpll)) { + hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1); + hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2); + } + ret = true; + +out: + intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); + + return ret; +} + +static void skl_shared_dplls_init(struct drm_i915_private *dev_priv) +{ + int i; + + dev_priv->num_shared_dpll = 3; + + for (i = 0; i < dev_priv->num_shared_dpll; i++) { + dev_priv->shared_dplls[i].id = i; + dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i]; + dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable; + dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable; + dev_priv->shared_dplls[i].get_hw_state = + skl_ddi_pll_get_hw_state; + } +} + +static const char * const bxt_ddi_pll_names[] = { + "PORT PLL A", + "PORT PLL B", + "PORT PLL C", +}; + +static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll) +{ + uint32_t temp; + enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */ + + temp = I915_READ(BXT_PORT_PLL_ENABLE(port)); + temp &= ~PORT_PLL_REF_SEL; + /* Non-SSC reference */ + I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp); + + /* Disable 10 bit clock */ + temp = I915_READ(BXT_PORT_PLL_EBB_4(port)); + temp &= ~PORT_PLL_10BIT_CLK_ENABLE; + I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp); + + /* Write P1 & P2 */ + temp = I915_READ(BXT_PORT_PLL_EBB_0(port)); + temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK); + temp |= pll->config.hw_state.ebb0; + I915_WRITE(BXT_PORT_PLL_EBB_0(port), temp); + + /* Write M2 integer */ + temp = I915_READ(BXT_PORT_PLL(port, 0)); + temp &= ~PORT_PLL_M2_MASK; + temp |= pll->config.hw_state.pll0; + I915_WRITE(BXT_PORT_PLL(port, 0), temp); + + /* Write N */ + temp = I915_READ(BXT_PORT_PLL(port, 1)); + temp &= ~PORT_PLL_N_MASK; + temp |= pll->config.hw_state.pll1; + I915_WRITE(BXT_PORT_PLL(port, 1), temp); + + /* Write M2 fraction */ + temp = I915_READ(BXT_PORT_PLL(port, 2)); + temp &= ~PORT_PLL_M2_FRAC_MASK; + temp |= pll->config.hw_state.pll2; + I915_WRITE(BXT_PORT_PLL(port, 2), temp); + + /* Write M2 fraction enable */ + temp = I915_READ(BXT_PORT_PLL(port, 3)); + temp &= ~PORT_PLL_M2_FRAC_ENABLE; + temp |= pll->config.hw_state.pll3; + I915_WRITE(BXT_PORT_PLL(port, 3), temp); + + /* Write coeff */ + temp = I915_READ(BXT_PORT_PLL(port, 6)); + temp &= ~PORT_PLL_PROP_COEFF_MASK; + temp &= ~PORT_PLL_INT_COEFF_MASK; + temp &= ~PORT_PLL_GAIN_CTL_MASK; + temp |= pll->config.hw_state.pll6; + I915_WRITE(BXT_PORT_PLL(port, 6), temp); + + /* Write calibration val */ + temp = I915_READ(BXT_PORT_PLL(port, 8)); + temp &= ~PORT_PLL_TARGET_CNT_MASK; + temp |= pll->config.hw_state.pll8; + I915_WRITE(BXT_PORT_PLL(port, 8), temp); + + temp = I915_READ(BXT_PORT_PLL(port, 9)); + temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK; + temp |= pll->config.hw_state.pll9; + I915_WRITE(BXT_PORT_PLL(port, 9), temp); + + temp = I915_READ(BXT_PORT_PLL(port, 10)); + temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H; + temp &= ~PORT_PLL_DCO_AMP_MASK; + temp |= pll->config.hw_state.pll10; + I915_WRITE(BXT_PORT_PLL(port, 10), temp); + + /* Recalibrate with new settings */ + temp = I915_READ(BXT_PORT_PLL_EBB_4(port)); + temp |= PORT_PLL_RECALIBRATE; + I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp); + temp &= ~PORT_PLL_10BIT_CLK_ENABLE; + temp |= pll->config.hw_state.ebb4; + I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp); + + /* Enable PLL */ + temp = I915_READ(BXT_PORT_PLL_ENABLE(port)); + temp |= PORT_PLL_ENABLE; + I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp); + POSTING_READ(BXT_PORT_PLL_ENABLE(port)); + + if (wait_for_atomic_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) & + PORT_PLL_LOCK), 200)) + DRM_ERROR("PLL %d not locked\n", port); + + /* + * While we write to the group register to program all lanes at once we + * can read only lane registers and we pick lanes 0/1 for that. + */ + temp = I915_READ(BXT_PORT_PCS_DW12_LN01(port)); + temp &= ~LANE_STAGGER_MASK; + temp &= ~LANESTAGGER_STRAP_OVRD; + temp |= pll->config.hw_state.pcsdw12; + I915_WRITE(BXT_PORT_PCS_DW12_GRP(port), temp); +} + +static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll) +{ + enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */ + uint32_t temp; + + temp = I915_READ(BXT_PORT_PLL_ENABLE(port)); + temp &= ~PORT_PLL_ENABLE; + I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp); + POSTING_READ(BXT_PORT_PLL_ENABLE(port)); +} + +static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll, + struct intel_dpll_hw_state *hw_state) +{ + enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */ + uint32_t val; + bool ret; + + if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS)) + return false; + + ret = false; + + val = I915_READ(BXT_PORT_PLL_ENABLE(port)); + if (!(val & PORT_PLL_ENABLE)) + goto out; + + hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port)); + hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK; + + hw_state->ebb4 = I915_READ(BXT_PORT_PLL_EBB_4(port)); + hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE; + + hw_state->pll0 = I915_READ(BXT_PORT_PLL(port, 0)); + hw_state->pll0 &= PORT_PLL_M2_MASK; + + hw_state->pll1 = I915_READ(BXT_PORT_PLL(port, 1)); + hw_state->pll1 &= PORT_PLL_N_MASK; + + hw_state->pll2 = I915_READ(BXT_PORT_PLL(port, 2)); + hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK; + + hw_state->pll3 = I915_READ(BXT_PORT_PLL(port, 3)); + hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE; + + hw_state->pll6 = I915_READ(BXT_PORT_PLL(port, 6)); + hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK | + PORT_PLL_INT_COEFF_MASK | + PORT_PLL_GAIN_CTL_MASK; + + hw_state->pll8 = I915_READ(BXT_PORT_PLL(port, 8)); + hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK; + + hw_state->pll9 = I915_READ(BXT_PORT_PLL(port, 9)); + hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK; + + hw_state->pll10 = I915_READ(BXT_PORT_PLL(port, 10)); + hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H | + PORT_PLL_DCO_AMP_MASK; + + /* + * While we write to the group register to program all lanes at once we + * can read only lane registers. We configure all lanes the same way, so + * here just read out lanes 0/1 and output a note if lanes 2/3 differ. + */ + hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(port)); + if (I915_READ(BXT_PORT_PCS_DW12_LN23(port)) != hw_state->pcsdw12) + DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n", + hw_state->pcsdw12, + I915_READ(BXT_PORT_PCS_DW12_LN23(port))); + hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD; + + ret = true; + +out: + intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); + + return ret; +} + +static void bxt_shared_dplls_init(struct drm_i915_private *dev_priv) +{ + int i; + + dev_priv->num_shared_dpll = 3; + + for (i = 0; i < dev_priv->num_shared_dpll; i++) { + dev_priv->shared_dplls[i].id = i; + dev_priv->shared_dplls[i].name = bxt_ddi_pll_names[i]; + dev_priv->shared_dplls[i].disable = bxt_ddi_pll_disable; + dev_priv->shared_dplls[i].enable = bxt_ddi_pll_enable; + dev_priv->shared_dplls[i].get_hw_state = + bxt_ddi_pll_get_hw_state; + } +} + +static void intel_ddi_pll_init(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t val = I915_READ(LCPLL_CTL); + + if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) + skl_shared_dplls_init(dev_priv); + else if (IS_BROXTON(dev)) + bxt_shared_dplls_init(dev_priv); + else + hsw_shared_dplls_init(dev_priv); + + if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) { + int cdclk_freq; + + cdclk_freq = dev_priv->display.get_display_clock_speed(dev); + dev_priv->skl_boot_cdclk = cdclk_freq; + if (skl_sanitize_cdclk(dev_priv)) + DRM_DEBUG_KMS("Sanitized cdclk programmed by pre-os\n"); + if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE)) + DRM_ERROR("LCPLL1 is disabled\n"); + } else if (IS_BROXTON(dev)) { + broxton_init_cdclk(dev); + broxton_ddi_phy_init(dev); + } else { + /* + * The LCPLL register should be turned on by the BIOS. For now + * let's just check its state and print errors in case + * something is wrong. Don't even try to turn it on. + */ + + if (val & LCPLL_CD_SOURCE_FCLK) + DRM_ERROR("CDCLK source is not LCPLL\n"); + + if (val & LCPLL_PLL_DISABLE) + DRM_ERROR("LCPLL is disabled\n"); + } +} + void intel_shared_dpll_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 63b36b56c913..94aaad92bf73 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1066,7 +1066,6 @@ void hsw_fdi_link_train(struct drm_crtc *crtc); void intel_ddi_init(struct drm_device *dev, enum port port); enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder); bool intel_ddi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe); -void intel_ddi_pll_init(struct drm_device *dev); void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc); void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv, enum transcoder cpu_transcoder); -- cgit v1.2.3 From a4780b7744c2833ba762d64576f661a9dae045f1 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Tue, 8 Mar 2016 17:46:17 +0200 Subject: drm/i915: Split intel_get_shared_dpll() into smaller functions Make the code neater by splitting the code for platforms with fixed PLL to their own functions and splitting the logic for finding a shareable or unused pll from the logic for setting it up. Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1457451987-17466-4-git-send-email-ander.conselvan.de.oliveira@intel.com --- drivers/gpu/drm/i915/intel_dpll_mgr.c | 109 +++++++++++++++++++++++----------- 1 file changed, 74 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c index 6be0cd09ea88..11effe3652c6 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c @@ -145,52 +145,65 @@ void intel_disable_shared_dpll(struct intel_crtc *crtc) intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); } -struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, - struct intel_crtc_state *crtc_state) +static enum intel_dpll_id +ibx_get_fixed_dpll(struct intel_crtc *crtc, + struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct intel_shared_dpll *pll; - struct intel_shared_dpll_config *shared_dpll; enum intel_dpll_id i; - int max = dev_priv->num_shared_dpll; - shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state->base.state); + /* Ironlake PCH has a fixed PLL->PCH pipe mapping. */ + i = (enum intel_dpll_id) crtc->pipe; + pll = &dev_priv->shared_dplls[i]; - if (HAS_PCH_IBX(dev_priv->dev)) { - /* Ironlake PCH has a fixed PLL->PCH pipe mapping. */ - i = (enum intel_dpll_id) crtc->pipe; - pll = &dev_priv->shared_dplls[i]; + DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n", + crtc->base.base.id, pll->name); - DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n", - crtc->base.base.id, pll->name); + return i; +} - WARN_ON(shared_dpll[i].crtc_mask); +static enum intel_dpll_id +bxt_get_fixed_dpll(struct intel_crtc *crtc, + struct intel_crtc_state *crtc_state) +{ + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_encoder *encoder; + struct intel_digital_port *intel_dig_port; + struct intel_shared_dpll *pll; + enum intel_dpll_id i; - goto found; - } + /* PLL is attached to port in bxt */ + encoder = intel_ddi_get_crtc_new_encoder(crtc_state); + if (WARN_ON(!encoder)) + return DPLL_ID_PRIVATE; - if (IS_BROXTON(dev_priv->dev)) { - /* PLL is attached to port in bxt */ - struct intel_encoder *encoder; - struct intel_digital_port *intel_dig_port; + intel_dig_port = enc_to_dig_port(&encoder->base); + /* 1:1 mapping between ports and PLLs */ + i = (enum intel_dpll_id)intel_dig_port->port; + pll = &dev_priv->shared_dplls[i]; + DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n", + crtc->base.base.id, pll->name); - encoder = intel_ddi_get_crtc_new_encoder(crtc_state); - if (WARN_ON(!encoder)) - return NULL; + return i; +} - intel_dig_port = enc_to_dig_port(&encoder->base); - /* 1:1 mapping between ports and PLLs */ - i = (enum intel_dpll_id)intel_dig_port->port; - pll = &dev_priv->shared_dplls[i]; - DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n", - crtc->base.base.id, pll->name); - WARN_ON(shared_dpll[i].crtc_mask); +static enum intel_dpll_id +intel_find_shared_dpll(struct intel_crtc *crtc, + struct intel_crtc_state *crtc_state) +{ + struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct intel_shared_dpll *pll; + struct intel_shared_dpll_config *shared_dpll; + enum intel_dpll_id i; + int max = dev_priv->num_shared_dpll; - goto found; - } else if (INTEL_INFO(dev_priv)->gen < 9 && HAS_DDI(dev_priv)) + if (INTEL_INFO(dev_priv)->gen < 9 && HAS_DDI(dev_priv)) /* Do not consider SPLL */ max = 2; + shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state->base.state); + for (i = 0; i < max; i++) { pll = &dev_priv->shared_dplls[i]; @@ -205,7 +218,7 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, crtc->base.base.id, pll->name, shared_dpll[i].crtc_mask, pll->active); - goto found; + return i; } } @@ -215,13 +228,39 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, if (shared_dpll[i].crtc_mask == 0) { DRM_DEBUG_KMS("CRTC:%d allocated %s\n", crtc->base.base.id, pll->name); - goto found; + return i; } } - return NULL; + return DPLL_ID_PRIVATE; +} + +struct intel_shared_dpll * +intel_get_shared_dpll(struct intel_crtc *crtc, + struct intel_crtc_state *crtc_state) +{ + struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct intel_shared_dpll *pll; + struct intel_shared_dpll_config *shared_dpll; + enum intel_dpll_id i; + + shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state->base.state); + + if (HAS_PCH_IBX(dev_priv->dev)) { + i = ibx_get_fixed_dpll(crtc, crtc_state); + WARN_ON(shared_dpll[i].crtc_mask); + } else if (IS_BROXTON(dev_priv->dev)) { + i = bxt_get_fixed_dpll(crtc, crtc_state); + WARN_ON(shared_dpll[i].crtc_mask); + } else { + i = intel_find_shared_dpll(crtc, crtc_state); + } + + if (i < 0) + return NULL; + + pll = &dev_priv->shared_dplls[i]; -found: if (shared_dpll[i].crtc_mask == 0) shared_dpll[i].hw_state = crtc_state->dpll_hw_state; -- cgit v1.2.3 From 8106ddbd7733f31205007f97be0866b408772907 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Tue, 8 Mar 2016 17:46:18 +0200 Subject: drm/i915: Store a direct pointer to shared dpll in intel_crtc_state Change the type of intel_crtc_state->shared_dpll to be a pointer to a shared dpll. With this there is no need to first convert the id stored in the crtc state to a pointer in order to use it. It does introduce a bit of hassle on doing the opposite. The long term objective is to hide details about dpll ids behind the shared dpll interface. Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1457451987-17466-5-git-send-email-ander.conselvan.de.oliveira@intel.com --- drivers/gpu/drm/i915/intel_ddi.c | 4 +- drivers/gpu/drm/i915/intel_display.c | 108 ++++++++++++++++++++++------------ drivers/gpu/drm/i915/intel_dpll_mgr.c | 51 ++++++++++++---- drivers/gpu/drm/i915/intel_drv.h | 19 +++++- drivers/gpu/drm/i915/intel_lvds.c | 2 +- 5 files changed, 132 insertions(+), 52 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 54880662f597..b6af5c0a6ae6 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1209,6 +1209,7 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state, struct intel_encoder *intel_encoder) { + struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev); int clock = crtc_state->port_clock; if (intel_encoder->type == INTEL_OUTPUT_HDMI) { @@ -1244,7 +1245,8 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc, WARN_ON(spll->hw_state.spll != crtc_state->dpll_hw_state.spll)) return false; - crtc_state->shared_dpll = DPLL_ID_SPLL; + crtc_state->shared_dpll = + intel_get_shared_dpll_by_id(dev_priv, DPLL_ID_SPLL); spll->hw_state.spll = crtc_state->dpll_hw_state.spll; spll->crtc_mask |= 1 << intel_crtc->pipe; } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 1d5695d07abd..579da412a200 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1843,8 +1843,7 @@ static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv, BUG_ON(!HAS_PCH_SPLIT(dev)); /* Make sure PCH DPLL is enabled */ - assert_shared_dpll_enabled(dev_priv, - intel_crtc_to_shared_dpll(intel_crtc)); + assert_shared_dpll_enabled(dev_priv, intel_crtc->config->shared_dpll); /* FDI must be feeding us bits for PCH ports */ assert_fdi_tx_enabled(dev_priv, pipe); @@ -4147,7 +4146,8 @@ static void ironlake_pch_enable(struct drm_crtc *crtc) temp = I915_READ(PCH_DPLL_SEL); temp |= TRANS_DPLL_ENABLE(pipe); sel = TRANS_DPLLB_SEL(pipe); - if (intel_crtc->config->shared_dpll == DPLL_ID_PCH_PLL_B) + if (intel_crtc->config->shared_dpll == + intel_get_shared_dpll_by_id(dev_priv, DPLL_ID_PCH_PLL_B)) temp |= sel; else temp &= ~sel; @@ -4883,7 +4883,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A, false); - if (intel_crtc_to_shared_dpll(intel_crtc)) + if (intel_crtc->config->shared_dpll) intel_enable_shared_dpll(intel_crtc); if (intel_crtc->config->has_dp_encoder) @@ -8052,7 +8052,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, return false; pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe; - pipe_config->shared_dpll = DPLL_ID_PRIVATE; + pipe_config->shared_dpll = NULL; ret = false; @@ -9256,7 +9256,7 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, return false; pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe; - pipe_config->shared_dpll = DPLL_ID_PRIVATE; + pipe_config->shared_dpll = NULL; ret = false; tmp = I915_READ(PIPECONF(crtc->pipe)); @@ -9285,6 +9285,7 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, if (I915_READ(PCH_TRANSCONF(crtc->pipe)) & TRANS_ENABLE) { struct intel_shared_dpll *pll; + enum intel_dpll_id pll_id; pipe_config->has_pch_encoder = true; @@ -9295,17 +9296,18 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, ironlake_get_fdi_m_n_config(crtc, pipe_config); if (HAS_PCH_IBX(dev_priv->dev)) { - pipe_config->shared_dpll = - (enum intel_dpll_id) crtc->pipe; + pll_id = (enum intel_dpll_id) crtc->pipe; } else { tmp = I915_READ(PCH_DPLL_SEL); if (tmp & TRANS_DPLLB_SEL(crtc->pipe)) - pipe_config->shared_dpll = DPLL_ID_PCH_PLL_B; + pll_id = DPLL_ID_PCH_PLL_B; else - pipe_config->shared_dpll = DPLL_ID_PCH_PLL_A; + pll_id= DPLL_ID_PCH_PLL_A; } - pll = &dev_priv->shared_dplls[pipe_config->shared_dpll]; + pipe_config->shared_dpll = + intel_get_shared_dpll_by_id(dev_priv, pll_id); + pll = pipe_config->shared_dpll; WARN_ON(!pll->get_hw_state(dev_priv, pll, &pipe_config->dpll_hw_state)); @@ -9741,28 +9743,34 @@ static void bxt_get_ddi_pll(struct drm_i915_private *dev_priv, enum port port, struct intel_crtc_state *pipe_config) { + enum intel_dpll_id id; + switch (port) { case PORT_A: pipe_config->ddi_pll_sel = SKL_DPLL0; - pipe_config->shared_dpll = DPLL_ID_SKL_DPLL1; + id = DPLL_ID_SKL_DPLL1; break; case PORT_B: pipe_config->ddi_pll_sel = SKL_DPLL1; - pipe_config->shared_dpll = DPLL_ID_SKL_DPLL2; + id = DPLL_ID_SKL_DPLL2; break; case PORT_C: pipe_config->ddi_pll_sel = SKL_DPLL2; - pipe_config->shared_dpll = DPLL_ID_SKL_DPLL3; + id = DPLL_ID_SKL_DPLL3; break; default: DRM_ERROR("Incorrect port type\n"); + return; } + + pipe_config->shared_dpll = intel_get_shared_dpll_by_id(dev_priv, id); } static void skylake_get_ddi_pll(struct drm_i915_private *dev_priv, enum port port, struct intel_crtc_state *pipe_config) { + enum intel_dpll_id id; u32 temp, dpll_ctl1; temp = I915_READ(DPLL_CTRL2) & DPLL_CTRL2_DDI_CLK_SEL_MASK(port); @@ -9777,36 +9785,53 @@ static void skylake_get_ddi_pll(struct drm_i915_private *dev_priv, */ dpll_ctl1 = I915_READ(DPLL_CTRL1); pipe_config->dpll_hw_state.ctrl1 = dpll_ctl1 & 0x3f; - break; + return; case SKL_DPLL1: - pipe_config->shared_dpll = DPLL_ID_SKL_DPLL1; + id = DPLL_ID_SKL_DPLL1; break; case SKL_DPLL2: - pipe_config->shared_dpll = DPLL_ID_SKL_DPLL2; + id = DPLL_ID_SKL_DPLL2; break; case SKL_DPLL3: - pipe_config->shared_dpll = DPLL_ID_SKL_DPLL3; + id = DPLL_ID_SKL_DPLL3; break; + default: + MISSING_CASE(pipe_config->ddi_pll_sel); + return; } + + pipe_config->shared_dpll = intel_get_shared_dpll_by_id(dev_priv, id); } static void haswell_get_ddi_pll(struct drm_i915_private *dev_priv, enum port port, struct intel_crtc_state *pipe_config) { + enum intel_dpll_id id; + pipe_config->ddi_pll_sel = I915_READ(PORT_CLK_SEL(port)); switch (pipe_config->ddi_pll_sel) { case PORT_CLK_SEL_WRPLL1: - pipe_config->shared_dpll = DPLL_ID_WRPLL1; + id = DPLL_ID_WRPLL1; break; case PORT_CLK_SEL_WRPLL2: - pipe_config->shared_dpll = DPLL_ID_WRPLL2; + id = DPLL_ID_WRPLL2; break; case PORT_CLK_SEL_SPLL: - pipe_config->shared_dpll = DPLL_ID_SPLL; + id = DPLL_ID_SPLL; break; + default: + MISSING_CASE(pipe_config->ddi_pll_sel); + /* fall through */ + case PORT_CLK_SEL_NONE: + case PORT_CLK_SEL_LCPLL_810: + case PORT_CLK_SEL_LCPLL_1350: + case PORT_CLK_SEL_LCPLL_2700: + return; } + + pipe_config->shared_dpll = intel_get_shared_dpll_by_id(dev_priv, id); } static void haswell_get_ddi_port_state(struct intel_crtc *crtc, @@ -9829,9 +9854,8 @@ static void haswell_get_ddi_port_state(struct intel_crtc *crtc, else haswell_get_ddi_pll(dev_priv, port, pipe_config); - if (pipe_config->shared_dpll >= 0) { - pll = &dev_priv->shared_dplls[pipe_config->shared_dpll]; - + pll = pipe_config->shared_dpll; + if (pll) { WARN_ON(!pll->get_hw_state(dev_priv, pll, &pipe_config->dpll_hw_state)); } @@ -9871,7 +9895,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, ret = false; pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe; - pipe_config->shared_dpll = DPLL_ID_PRIVATE; + pipe_config->shared_dpll = NULL; tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)); if (tmp & TRANS_DDI_FUNC_ENABLE) { @@ -11868,7 +11892,7 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc, if (mode_changed && crtc_state->enable && dev_priv->display.crtc_compute_clock && - !WARN_ON(pipe_config->shared_dpll != DPLL_ID_PRIVATE)) { + !WARN_ON(pipe_config->shared_dpll)) { ret = dev_priv->display.crtc_compute_clock(intel_crtc, pipe_config); if (ret) @@ -12213,7 +12237,7 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state) struct drm_crtc_state tmp_state; struct intel_crtc_scaler_state scaler_state; struct intel_dpll_hw_state dpll_hw_state; - enum intel_dpll_id shared_dpll; + struct intel_shared_dpll *shared_dpll; uint32_t ddi_pll_sel; bool force_thru; @@ -12483,6 +12507,15 @@ intel_pipe_config_compare(struct drm_device *dev, ret = false; \ } +#define PIPE_CONF_CHECK_P(name) \ + if (current_config->name != pipe_config->name) { \ + INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \ + "(expected %p, found %p)\n", \ + current_config->name, \ + pipe_config->name); \ + ret = false; \ + } + #define PIPE_CONF_CHECK_M_N(name) \ if (!intel_compare_link_m_n(¤t_config->name, \ &pipe_config->name,\ @@ -12650,7 +12683,7 @@ intel_pipe_config_compare(struct drm_device *dev, PIPE_CONF_CHECK_X(ddi_pll_sel); - PIPE_CONF_CHECK_I(shared_dpll); + PIPE_CONF_CHECK_P(shared_dpll); PIPE_CONF_CHECK_X(dpll_hw_state.dpll); PIPE_CONF_CHECK_X(dpll_hw_state.dpll_md); PIPE_CONF_CHECK_X(dpll_hw_state.fp0); @@ -12669,6 +12702,7 @@ intel_pipe_config_compare(struct drm_device *dev, #undef PIPE_CONF_CHECK_X #undef PIPE_CONF_CHECK_I +#undef PIPE_CONF_CHECK_P #undef PIPE_CONF_CHECK_I_ALT #undef PIPE_CONF_CHECK_FLAGS #undef PIPE_CONF_CHECK_CLOCK_FUZZY @@ -12892,7 +12926,8 @@ check_shared_dpll_state(struct drm_device *dev) int i; for (i = 0; i < dev_priv->num_shared_dpll; i++) { - struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i]; + struct intel_shared_dpll *pll = + intel_get_shared_dpll_by_id(dev_priv, i); int enabled_crtcs = 0, active_crtcs = 0; bool active; @@ -12914,9 +12949,9 @@ check_shared_dpll_state(struct drm_device *dev) pll->on, active); for_each_intel_crtc(dev, crtc) { - if (crtc->base.state->enable && intel_crtc_to_shared_dpll(crtc) == pll) + if (crtc->base.state->enable && crtc->config->shared_dpll == pll) enabled_crtcs++; - if (crtc->active && intel_crtc_to_shared_dpll(crtc) == pll) + if (crtc->active && crtc->config->shared_dpll == pll) active_crtcs++; } I915_STATE_WARN(pll->active != active_crtcs, @@ -12995,20 +13030,21 @@ static void intel_modeset_clear_plls(struct drm_atomic_state *state) for_each_crtc_in_state(state, crtc, crtc_state, i) { struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int old_dpll = to_intel_crtc_state(crtc->state)->shared_dpll; + struct intel_shared_dpll *old_dpll = + to_intel_crtc_state(crtc->state)->shared_dpll; if (!needs_modeset(crtc_state)) continue; - to_intel_crtc_state(crtc_state)->shared_dpll = DPLL_ID_PRIVATE; + to_intel_crtc_state(crtc_state)->shared_dpll = NULL; - if (old_dpll == DPLL_ID_PRIVATE) + if (!old_dpll) continue; if (!shared_dpll) shared_dpll = intel_atomic_get_shared_dpll_state(state); - shared_dpll[old_dpll].crtc_mask &= ~(1 << intel_crtc->pipe); + intel_shared_dpll_config_put(shared_dpll, old_dpll, intel_crtc); } } @@ -15655,7 +15691,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) pll->active = 0; pll->config.crtc_mask = 0; for_each_intel_crtc(dev, crtc) { - if (crtc->active && intel_crtc_to_shared_dpll(crtc) == pll) { + if (crtc->active && crtc->config->shared_dpll == pll) { pll->active++; pll->config.crtc_mask |= 1 << crtc->pipe; } diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c index 11effe3652c6..889ceedcaab8 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c @@ -24,14 +24,43 @@ #include "intel_drv.h" struct intel_shared_dpll * -intel_crtc_to_shared_dpll(struct intel_crtc *crtc) +intel_get_shared_dpll_by_id(struct drm_i915_private *dev_priv, + enum intel_dpll_id id) { - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + return &dev_priv->shared_dplls[id]; +} - if (crtc->config->shared_dpll < 0) - return NULL; +enum intel_dpll_id +intel_get_shared_dpll_id(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll) +{ + if (WARN_ON(pll < dev_priv->shared_dplls|| + pll > &dev_priv->shared_dplls[dev_priv->num_shared_dpll])) + return -1; + + return (enum intel_dpll_id) (pll - dev_priv->shared_dplls); +} + +void +intel_shared_dpll_config_get(struct intel_shared_dpll_config *config, + struct intel_shared_dpll *pll, + struct intel_crtc *crtc) +{ + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + enum intel_dpll_id id = intel_get_shared_dpll_id(dev_priv, pll); + + config[id].crtc_mask |= 1 << crtc->pipe; +} + +void +intel_shared_dpll_config_put(struct intel_shared_dpll_config *config, + struct intel_shared_dpll *pll, + struct intel_crtc *crtc) +{ + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + enum intel_dpll_id id = intel_get_shared_dpll_id(dev_priv, pll); - return &dev_priv->shared_dplls[crtc->config->shared_dpll]; + config[id].crtc_mask &= ~(1 << crtc->pipe); } /* For ILK+ */ @@ -55,7 +84,7 @@ void intel_prepare_shared_dpll(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc); + struct intel_shared_dpll *pll = crtc->config->shared_dpll; if (WARN_ON(pll == NULL)) return; @@ -82,7 +111,7 @@ void intel_enable_shared_dpll(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc); + struct intel_shared_dpll *pll = crtc->config->shared_dpll; if (WARN_ON(pll == NULL)) return; @@ -112,7 +141,7 @@ void intel_disable_shared_dpll(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc); + struct intel_shared_dpll *pll = crtc->config->shared_dpll; /* PCH only available on ILK+ */ if (INTEL_INFO(dev)->gen < 5) @@ -265,11 +294,11 @@ intel_get_shared_dpll(struct intel_crtc *crtc, shared_dpll[i].hw_state = crtc_state->dpll_hw_state; - crtc_state->shared_dpll = i; + crtc_state->shared_dpll = pll; DRM_DEBUG_DRIVER("using %s for pipe %c\n", pll->name, pipe_name(crtc->pipe)); - shared_dpll[i].crtc_mask |= 1 << crtc->pipe; + intel_shared_dpll_config_get(shared_dpll, pll, crtc); return pll; } @@ -360,7 +389,7 @@ static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv, /* Make sure no transcoder isn't still depending on us. */ for_each_intel_crtc(dev, crtc) { - if (intel_crtc_to_shared_dpll(crtc) == pll) + if (crtc->config->shared_dpll == pll) assert_pch_transcoder_disabled(dev_priv, crtc->pipe); } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 94aaad92bf73..1fbf069d9671 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -483,8 +483,8 @@ struct intel_crtc_state { * haswell. */ struct dpll dpll; - /* Selected dpll when shared or DPLL_ID_PRIVATE. */ - enum intel_dpll_id shared_dpll; + /* Selected dpll when shared or NULL. */ + struct intel_shared_dpll *shared_dpll; /* * - PORT_CLK_SEL for DDI ports on HSW/BDW. @@ -1204,7 +1204,20 @@ void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv, enum pipe pipe); /* shared dpll functions */ -struct intel_shared_dpll *intel_crtc_to_shared_dpll(struct intel_crtc *crtc); +struct intel_shared_dpll * +intel_get_shared_dpll_by_id(struct drm_i915_private *dev_priv, + enum intel_dpll_id id); +enum intel_dpll_id +intel_get_shared_dpll_id(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll); +void +intel_shared_dpll_config_get(struct intel_shared_dpll_config *config, + struct intel_shared_dpll *pll, + struct intel_crtc *crtc); +void +intel_shared_dpll_config_put(struct intel_shared_dpll_config *config, + struct intel_shared_dpll *pll, + struct intel_crtc *crtc); void assert_shared_dpll(struct drm_i915_private *dev_priv, struct intel_shared_dpll *pll, bool state); diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index b35342f7b969..cbd1b0d547ee 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -145,7 +145,7 @@ static void intel_pre_enable_lvds(struct intel_encoder *encoder) if (HAS_PCH_SPLIT(dev)) { assert_fdi_rx_pll_disabled(dev_priv, pipe); assert_shared_dpll_disabled(dev_priv, - intel_crtc_to_shared_dpll(crtc)); + crtc->config->shared_dpll); } else { assert_pll_disabled(dev_priv, pipe); } -- cgit v1.2.3 From ac7f11c6106507f1e09a970a03904c323ae741b8 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Tue, 8 Mar 2016 17:46:19 +0200 Subject: drm/i915: Move shared dpll struct definitions to separate header file Move the declarations related to shared dplls from i915_drv.h to their own header file. The code that became the shared dpll infrastructre was first introcude in commit ee7b9f93fd96 ("drm/i915: manage PCH PLLs separately from pipes"), hence the 2012-2016 copyright years in the new header file. Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1457451987-17466-6-git-send-email-ander.conselvan.de.oliveira@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 76 +----------------------- drivers/gpu/drm/i915/intel_dpll_mgr.h | 106 ++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 75 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_dpll_mgr.h (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f37ac120a29d..e74a61bf7a11 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -53,6 +53,7 @@ #include #include #include "intel_guc.h" +#include "intel_dpll_mgr.h" /* General customization: */ @@ -340,81 +341,6 @@ struct drm_i915_file_private { unsigned int bsd_ring; }; -enum intel_dpll_id { - DPLL_ID_PRIVATE = -1, /* non-shared dpll in use */ - /* real shared dpll ids must be >= 0 */ - DPLL_ID_PCH_PLL_A = 0, - DPLL_ID_PCH_PLL_B = 1, - /* hsw/bdw */ - DPLL_ID_WRPLL1 = 0, - DPLL_ID_WRPLL2 = 1, - DPLL_ID_SPLL = 2, - - /* skl */ - DPLL_ID_SKL_DPLL1 = 0, - DPLL_ID_SKL_DPLL2 = 1, - DPLL_ID_SKL_DPLL3 = 2, -}; -#define I915_NUM_PLLS 3 - -struct intel_dpll_hw_state { - /* i9xx, pch plls */ - uint32_t dpll; - uint32_t dpll_md; - uint32_t fp0; - uint32_t fp1; - - /* hsw, bdw */ - uint32_t wrpll; - uint32_t spll; - - /* skl */ - /* - * DPLL_CTRL1 has 6 bits for each each this DPLL. We store those in - * lower part of ctrl1 and they get shifted into position when writing - * the register. This allows us to easily compare the state to share - * the DPLL. - */ - uint32_t ctrl1; - /* HDMI only, 0 when used for DP */ - uint32_t cfgcr1, cfgcr2; - - /* bxt */ - uint32_t ebb0, ebb4, pll0, pll1, pll2, pll3, pll6, pll8, pll9, pll10, - pcsdw12; -}; - -struct intel_shared_dpll_config { - unsigned crtc_mask; /* mask of CRTCs sharing this PLL */ - struct intel_dpll_hw_state hw_state; -}; - -struct intel_shared_dpll { - struct intel_shared_dpll_config config; - - int active; /* count of number of active CRTCs (i.e. DPMS on) */ - bool on; /* is the PLL actually active? Disabled during modeset */ - const char *name; - /* should match the index in the dev_priv->shared_dplls array */ - enum intel_dpll_id id; - /* The mode_set hook is optional and should be used together with the - * intel_prepare_shared_dpll function. */ - void (*mode_set)(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll); - void (*enable)(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll); - void (*disable)(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll); - bool (*get_hw_state)(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll, - struct intel_dpll_hw_state *hw_state); -}; - -#define SKL_DPLL0 0 -#define SKL_DPLL1 1 -#define SKL_DPLL2 2 -#define SKL_DPLL3 3 - /* Used by dp and fdi links */ struct intel_link_m_n { uint32_t tu; diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h new file mode 100644 index 000000000000..a62d1baff76f --- /dev/null +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h @@ -0,0 +1,106 @@ +/* + * Copyright © 2012-2016 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + */ + +#ifndef _INTEL_DPLL_MGR_H_ +#define _INTEL_DPLL_MGR_H_ + +struct drm_i915_private; + +enum intel_dpll_id { + DPLL_ID_PRIVATE = -1, /* non-shared dpll in use */ + /* real shared dpll ids must be >= 0 */ + DPLL_ID_PCH_PLL_A = 0, + DPLL_ID_PCH_PLL_B = 1, + /* hsw/bdw */ + DPLL_ID_WRPLL1 = 0, + DPLL_ID_WRPLL2 = 1, + DPLL_ID_SPLL = 2, + + /* skl */ + DPLL_ID_SKL_DPLL1 = 0, + DPLL_ID_SKL_DPLL2 = 1, + DPLL_ID_SKL_DPLL3 = 2, +}; +#define I915_NUM_PLLS 3 + +struct intel_dpll_hw_state { + /* i9xx, pch plls */ + uint32_t dpll; + uint32_t dpll_md; + uint32_t fp0; + uint32_t fp1; + + /* hsw, bdw */ + uint32_t wrpll; + uint32_t spll; + + /* skl */ + /* + * DPLL_CTRL1 has 6 bits for each each this DPLL. We store those in + * lower part of ctrl1 and they get shifted into position when writing + * the register. This allows us to easily compare the state to share + * the DPLL. + */ + uint32_t ctrl1; + /* HDMI only, 0 when used for DP */ + uint32_t cfgcr1, cfgcr2; + + /* bxt */ + uint32_t ebb0, ebb4, pll0, pll1, pll2, pll3, pll6, pll8, pll9, pll10, + pcsdw12; +}; + +struct intel_shared_dpll_config { + unsigned crtc_mask; /* mask of CRTCs sharing this PLL */ + struct intel_dpll_hw_state hw_state; +}; + +struct intel_shared_dpll { + struct intel_shared_dpll_config config; + + int active; /* count of number of active CRTCs (i.e. DPMS on) */ + bool on; /* is the PLL actually active? Disabled during modeset */ + const char *name; + /* should match the index in the dev_priv->shared_dplls array */ + enum intel_dpll_id id; + /* The mode_set hook is optional and should be used together with the + * intel_prepare_shared_dpll function. */ + void (*mode_set)(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll); + void (*enable)(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll); + void (*disable)(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll); + bool (*get_hw_state)(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll, + struct intel_dpll_hw_state *hw_state); +}; + +#define SKL_DPLL0 0 +#define SKL_DPLL1 1 +#define SKL_DPLL2 2 +#define SKL_DPLL3 3 + + +#endif /* _INTEL_DPLL_MGR_H_ */ -- cgit v1.2.3 From c2a9fcd6831aee2944f5e6d3858f56f35a2ed70a Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Tue, 8 Mar 2016 17:46:20 +0200 Subject: drm/i915: Move shared dpll function prototypes to intel_dpll_mgr.h Move shared dpll function prototype together with other shared dpll definitions. Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1457451987-17466-7-git-send-email-ander.conselvan.de.oliveira@intel.com --- drivers/gpu/drm/i915/intel_dpll_mgr.h | 30 ++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_drv.h | 28 ---------------------------- 2 files changed, 30 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h index a62d1baff76f..a2ecf80239f3 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.h +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h @@ -26,6 +26,8 @@ #define _INTEL_DPLL_MGR_H_ struct drm_i915_private; +struct intel_crtc; +struct intel_crtc_state; enum intel_dpll_id { DPLL_ID_PRIVATE = -1, /* non-shared dpll in use */ @@ -102,5 +104,33 @@ struct intel_shared_dpll { #define SKL_DPLL2 2 #define SKL_DPLL3 3 +/* shared dpll functions */ +struct intel_shared_dpll * +intel_get_shared_dpll_by_id(struct drm_i915_private *dev_priv, + enum intel_dpll_id id); +enum intel_dpll_id +intel_get_shared_dpll_id(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll); +void +intel_shared_dpll_config_get(struct intel_shared_dpll_config *config, + struct intel_shared_dpll *pll, + struct intel_crtc *crtc); +void +intel_shared_dpll_config_put(struct intel_shared_dpll_config *config, + struct intel_shared_dpll *pll, + struct intel_crtc *crtc); +void assert_shared_dpll(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll, + bool state); +#define assert_shared_dpll_enabled(d, p) assert_shared_dpll(d, p, true) +#define assert_shared_dpll_disabled(d, p) assert_shared_dpll(d, p, false) +struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, + struct intel_crtc_state *state); +void intel_prepare_shared_dpll(struct intel_crtc *crtc); +void intel_enable_shared_dpll(struct intel_crtc *crtc); +void intel_disable_shared_dpll(struct intel_crtc *crtc); +void intel_shared_dpll_commit(struct drm_atomic_state *state); +void intel_shared_dpll_init(struct drm_device *dev); + #endif /* _INTEL_DPLL_MGR_H_ */ diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 1fbf069d9671..1f62fba3ae3a 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1203,34 +1203,6 @@ void intel_create_rotation_property(struct drm_device *dev, void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv, enum pipe pipe); -/* shared dpll functions */ -struct intel_shared_dpll * -intel_get_shared_dpll_by_id(struct drm_i915_private *dev_priv, - enum intel_dpll_id id); -enum intel_dpll_id -intel_get_shared_dpll_id(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll); -void -intel_shared_dpll_config_get(struct intel_shared_dpll_config *config, - struct intel_shared_dpll *pll, - struct intel_crtc *crtc); -void -intel_shared_dpll_config_put(struct intel_shared_dpll_config *config, - struct intel_shared_dpll *pll, - struct intel_crtc *crtc); -void assert_shared_dpll(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll, - bool state); -#define assert_shared_dpll_enabled(d, p) assert_shared_dpll(d, p, true) -#define assert_shared_dpll_disabled(d, p) assert_shared_dpll(d, p, false) -struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, - struct intel_crtc_state *state); -void intel_prepare_shared_dpll(struct intel_crtc *crtc); -void intel_enable_shared_dpll(struct intel_crtc *crtc); -void intel_disable_shared_dpll(struct intel_crtc *crtc); -void intel_shared_dpll_commit(struct drm_atomic_state *state); -void intel_shared_dpll_init(struct drm_device *dev); - int vlv_force_pll_on(struct drm_device *dev, enum pipe pipe, const struct dpll *dpll); void vlv_force_pll_off(struct drm_device *dev, enum pipe pipe); -- cgit v1.2.3 From 2edd6443e3d03267bfc63071a86332a1711dc1bc Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Tue, 8 Mar 2016 17:46:21 +0200 Subject: drm/i915: Use a table to initilize shared dplls Use a table to store the per-platform shared dpll information in one place. This way, there is no need for platform specific init funtions. Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1457451987-17466-8-git-send-email-ander.conselvan.de.oliveira@intel.com --- drivers/gpu/drm/i915/intel_display.c | 16 +-- drivers/gpu/drm/i915/intel_dpll_mgr.c | 189 ++++++++++++++++------------------ drivers/gpu/drm/i915/intel_dpll_mgr.h | 22 ++-- 3 files changed, 108 insertions(+), 119 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 579da412a200..5852a1a307f1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9309,8 +9309,8 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, intel_get_shared_dpll_by_id(dev_priv, pll_id); pll = pipe_config->shared_dpll; - WARN_ON(!pll->get_hw_state(dev_priv, pll, - &pipe_config->dpll_hw_state)); + WARN_ON(!pll->funcs.get_hw_state(dev_priv, pll, + &pipe_config->dpll_hw_state)); tmp = pipe_config->dpll_hw_state.dpll; pipe_config->pixel_multiplier = @@ -9856,8 +9856,8 @@ static void haswell_get_ddi_port_state(struct intel_crtc *crtc, pll = pipe_config->shared_dpll; if (pll) { - WARN_ON(!pll->get_hw_state(dev_priv, pll, - &pipe_config->dpll_hw_state)); + WARN_ON(!pll->funcs.get_hw_state(dev_priv, pll, + &pipe_config->dpll_hw_state)); } /* @@ -12935,7 +12935,7 @@ check_shared_dpll_state(struct drm_device *dev) DRM_DEBUG_KMS("%s\n", pll->name); - active = pll->get_hw_state(dev_priv, pll, &dpll_hw_state); + active = pll->funcs.get_hw_state(dev_priv, pll, &dpll_hw_state); I915_STATE_WARN(pll->active > hweight32(pll->config.crtc_mask), "more active pll users than references: %i vs %i\n", @@ -15686,8 +15686,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) for (i = 0; i < dev_priv->num_shared_dpll; i++) { struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i]; - pll->on = pll->get_hw_state(dev_priv, pll, - &pll->config.hw_state); + pll->on = pll->funcs.get_hw_state(dev_priv, pll, + &pll->config.hw_state); pll->active = 0; pll->config.crtc_mask = 0; for_each_intel_crtc(dev, crtc) { @@ -15824,7 +15824,7 @@ intel_modeset_setup_hw_state(struct drm_device *dev) DRM_DEBUG_KMS("%s enabled but not in use, disabling\n", pll->name); - pll->disable(dev_priv, pll); + pll->funcs.disable(dev_priv, pll); pll->on = false; } diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c index 889ceedcaab8..e88dc46afe85 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c @@ -74,7 +74,7 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv, if (WARN(!pll, "asserting DPLL %s with no DPLL\n", onoff(state))) return; - cur_state = pll->get_hw_state(dev_priv, pll, &hw_state); + cur_state = pll->funcs.get_hw_state(dev_priv, pll, &hw_state); I915_STATE_WARN(cur_state != state, "%s assertion failure (expected %s, current %s)\n", pll->name, onoff(state), onoff(cur_state)); @@ -95,7 +95,7 @@ void intel_prepare_shared_dpll(struct intel_crtc *crtc) WARN_ON(pll->on); assert_shared_dpll_disabled(dev_priv, pll); - pll->mode_set(dev_priv, pll); + pll->funcs.mode_set(dev_priv, pll); } } @@ -133,7 +133,7 @@ void intel_enable_shared_dpll(struct intel_crtc *crtc) intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS); DRM_DEBUG_KMS("enabling %s\n", pll->name); - pll->enable(dev_priv, pll); + pll->funcs.enable(dev_priv, pll); pll->on = true; } @@ -168,7 +168,7 @@ void intel_disable_shared_dpll(struct intel_crtc *crtc) return; DRM_DEBUG_KMS("disabling %s\n", pll->name); - pll->disable(dev_priv, pll); + pll->funcs.disable(dev_priv, pll); pll->on = false; intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); @@ -398,29 +398,13 @@ static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv, udelay(200); } -static char *ibx_pch_dpll_names[] = { - "PCH DPLL A", - "PCH DPLL B", +static const struct intel_shared_dpll_funcs ibx_pch_dpll_funcs = { + .mode_set = ibx_pch_dpll_mode_set, + .enable = ibx_pch_dpll_enable, + .disable = ibx_pch_dpll_disable, + .get_hw_state = ibx_pch_dpll_get_hw_state, }; -static void ibx_pch_dpll_init(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int i; - - dev_priv->num_shared_dpll = 2; - - for (i = 0; i < dev_priv->num_shared_dpll; i++) { - dev_priv->shared_dplls[i].id = i; - dev_priv->shared_dplls[i].name = ibx_pch_dpll_names[i]; - dev_priv->shared_dplls[i].mode_set = ibx_pch_dpll_mode_set; - dev_priv->shared_dplls[i].enable = ibx_pch_dpll_enable; - dev_priv->shared_dplls[i].disable = ibx_pch_dpll_disable; - dev_priv->shared_dplls[i].get_hw_state = - ibx_pch_dpll_get_hw_state; - } -} - static void hsw_ddi_wrpll_enable(struct drm_i915_private *dev_priv, struct intel_shared_dpll *pll) { @@ -492,40 +476,16 @@ static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv, } -static const char * const hsw_ddi_pll_names[] = { - "WRPLL 1", - "WRPLL 2", - "SPLL" +static const struct intel_shared_dpll_funcs hsw_ddi_wrpll_funcs = { + .enable = hsw_ddi_wrpll_enable, + .disable = hsw_ddi_wrpll_disable, + .get_hw_state = hsw_ddi_wrpll_get_hw_state, }; -static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv) -{ - int i; - - dev_priv->num_shared_dpll = 3; - - for (i = 0; i < 2; i++) { - dev_priv->shared_dplls[i].id = i; - dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i]; - dev_priv->shared_dplls[i].disable = hsw_ddi_wrpll_disable; - dev_priv->shared_dplls[i].enable = hsw_ddi_wrpll_enable; - dev_priv->shared_dplls[i].get_hw_state = - hsw_ddi_wrpll_get_hw_state; - } - - /* SPLL is special, but needs to be initialized anyway.. */ - dev_priv->shared_dplls[i].id = i; - dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i]; - dev_priv->shared_dplls[i].disable = hsw_ddi_spll_disable; - dev_priv->shared_dplls[i].enable = hsw_ddi_spll_enable; - dev_priv->shared_dplls[i].get_hw_state = hsw_ddi_spll_get_hw_state; - -} - -static const char * const skl_ddi_pll_names[] = { - "DPLL 1", - "DPLL 2", - "DPLL 3", +static const struct intel_shared_dpll_funcs hsw_ddi_spll_funcs = { + .enable = hsw_ddi_spll_enable, + .disable = hsw_ddi_spll_disable, + .get_hw_state = hsw_ddi_spll_get_hw_state, }; struct skl_dpll_regs { @@ -634,26 +594,10 @@ out: return ret; } -static void skl_shared_dplls_init(struct drm_i915_private *dev_priv) -{ - int i; - - dev_priv->num_shared_dpll = 3; - - for (i = 0; i < dev_priv->num_shared_dpll; i++) { - dev_priv->shared_dplls[i].id = i; - dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i]; - dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable; - dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable; - dev_priv->shared_dplls[i].get_hw_state = - skl_ddi_pll_get_hw_state; - } -} - -static const char * const bxt_ddi_pll_names[] = { - "PORT PLL A", - "PORT PLL B", - "PORT PLL C", +static const struct intel_shared_dpll_funcs skl_ddi_pll_funcs = { + .enable = skl_ddi_pll_enable, + .disable = skl_ddi_pll_disable, + .get_hw_state = skl_ddi_pll_get_hw_state, }; static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv, @@ -838,34 +782,17 @@ out: return ret; } -static void bxt_shared_dplls_init(struct drm_i915_private *dev_priv) -{ - int i; - - dev_priv->num_shared_dpll = 3; - - for (i = 0; i < dev_priv->num_shared_dpll; i++) { - dev_priv->shared_dplls[i].id = i; - dev_priv->shared_dplls[i].name = bxt_ddi_pll_names[i]; - dev_priv->shared_dplls[i].disable = bxt_ddi_pll_disable; - dev_priv->shared_dplls[i].enable = bxt_ddi_pll_enable; - dev_priv->shared_dplls[i].get_hw_state = - bxt_ddi_pll_get_hw_state; - } -} +static const struct intel_shared_dpll_funcs bxt_ddi_pll_funcs = { + .enable = bxt_ddi_pll_enable, + .disable = bxt_ddi_pll_disable, + .get_hw_state = bxt_ddi_pll_get_hw_state, +}; static void intel_ddi_pll_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; uint32_t val = I915_READ(LCPLL_CTL); - if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) - skl_shared_dplls_init(dev_priv); - else if (IS_BROXTON(dev)) - bxt_shared_dplls_init(dev_priv); - else - hsw_shared_dplls_init(dev_priv); - if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) { int cdclk_freq; @@ -893,16 +820,72 @@ static void intel_ddi_pll_init(struct drm_device *dev) } } +struct dpll_info { + const char *name; + const int id; + const struct intel_shared_dpll_funcs *funcs; +}; + +static const struct dpll_info pch_plls[] = { + { "PCH DPLL A", DPLL_ID_PCH_PLL_A, &ibx_pch_dpll_funcs }, + { "PCH DPLL B", DPLL_ID_PCH_PLL_B, &ibx_pch_dpll_funcs }, + { NULL, -1, NULL }, +}; + +static const struct dpll_info hsw_plls[] = { + { "WRPLL 1", DPLL_ID_WRPLL1, &hsw_ddi_wrpll_funcs }, + { "WRPLL 2", DPLL_ID_WRPLL2, &hsw_ddi_wrpll_funcs }, + { "SPLL", DPLL_ID_SPLL, &hsw_ddi_spll_funcs }, + { NULL, -1, NULL, }, +}; + +static const struct dpll_info skl_plls[] = { + { "DPPL 1", DPLL_ID_SKL_DPLL1, &skl_ddi_pll_funcs }, + { "DPPL 2", DPLL_ID_SKL_DPLL2, &skl_ddi_pll_funcs }, + { "DPPL 3", DPLL_ID_SKL_DPLL3, &skl_ddi_pll_funcs }, + { NULL, -1, NULL, }, +}; + +static const struct dpll_info bxt_plls[] = { + { "PORT PLL A", 0, &bxt_ddi_pll_funcs }, + { "PORT PLL B", 1, &bxt_ddi_pll_funcs }, + { "PORT PLL C", 2, &bxt_ddi_pll_funcs }, + { NULL, -1, NULL, }, +}; + void intel_shared_dpll_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + const struct dpll_info *dpll_info = NULL; + int i; - if (HAS_DDI(dev)) - intel_ddi_pll_init(dev); + if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) + dpll_info = skl_plls; + else if IS_BROXTON(dev) + dpll_info = bxt_plls; + else if (HAS_DDI(dev)) + dpll_info = hsw_plls; else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) - ibx_pch_dpll_init(dev); - else + dpll_info = pch_plls; + + if (!dpll_info) { dev_priv->num_shared_dpll = 0; + return; + } + + for (i = 0; dpll_info[i].id >= 0; i++) { + WARN_ON(i != dpll_info[i].id); + + dev_priv->shared_dplls[i].id = dpll_info[i].id; + dev_priv->shared_dplls[i].name = dpll_info[i].name; + dev_priv->shared_dplls[i].funcs = *dpll_info[i].funcs; + } + + dev_priv->num_shared_dpll = i; BUG_ON(dev_priv->num_shared_dpll > I915_NUM_PLLS); + + /* FIXME: Move this to a more suitable place */ + if (HAS_DDI(dev)) + intel_ddi_pll_init(dev); } diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h index a2ecf80239f3..8be2478af78f 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.h +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h @@ -28,6 +28,7 @@ struct drm_i915_private; struct intel_crtc; struct intel_crtc_state; +struct intel_shared_dpll; enum intel_dpll_id { DPLL_ID_PRIVATE = -1, /* non-shared dpll in use */ @@ -78,14 +79,7 @@ struct intel_shared_dpll_config { struct intel_dpll_hw_state hw_state; }; -struct intel_shared_dpll { - struct intel_shared_dpll_config config; - - int active; /* count of number of active CRTCs (i.e. DPMS on) */ - bool on; /* is the PLL actually active? Disabled during modeset */ - const char *name; - /* should match the index in the dev_priv->shared_dplls array */ - enum intel_dpll_id id; +struct intel_shared_dpll_funcs { /* The mode_set hook is optional and should be used together with the * intel_prepare_shared_dpll function. */ void (*mode_set)(struct drm_i915_private *dev_priv, @@ -99,6 +93,18 @@ struct intel_shared_dpll { struct intel_dpll_hw_state *hw_state); }; +struct intel_shared_dpll { + struct intel_shared_dpll_config config; + + int active; /* count of number of active CRTCs (i.e. DPMS on) */ + bool on; /* is the PLL actually active? Disabled during modeset */ + const char *name; + /* should match the index in the dev_priv->shared_dplls array */ + enum intel_dpll_id id; + + struct intel_shared_dpll_funcs funcs; +}; + #define SKL_DPLL0 0 #define SKL_DPLL1 1 #define SKL_DPLL2 2 -- cgit v1.2.3 From f9476a6c6d0c33cbce271ea08a3fbef131c73dc0 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Tue, 8 Mar 2016 17:46:22 +0200 Subject: drm/i915: Refactor platform specifics out of intel_get_shared_dpll() The function intel_get_shared_dpll() had a more or less generic implementation with some platform specific checks to handle smaller differences between platforms. However, the minimalist approach forces bigger differences between platforms to be implemented outside of the shared dpll code (see the *_ddi_pll_select() functions in intel_ddi.c, for instance). This patch changes the implementation of intel_get_share_dpll() so that a completely platform specific version can be used, providing helpers to reduce code duplication. This should allow the code from the ddi pll select functions to be moved, and also make room for making more dplls managed by the shared dpll infrastructure. v2: WARN_ON(!dpll_mgr) in intel_get_shared_dpll(). (Maarten) Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1457451987-17466-9-git-send-email-ander.conselvan.de.oliveira@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_dpll_mgr.c | 226 +++++++++++++++++++++------------- drivers/gpu/drm/i915/intel_dpll_mgr.h | 2 + 3 files changed, 145 insertions(+), 84 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index e74a61bf7a11..1557d65485b0 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1810,6 +1810,7 @@ struct drm_i915_private { /* dpll and cdclk state is protected by connection_mutex */ int num_shared_dpll; struct intel_shared_dpll shared_dplls[I915_NUM_PLLS]; + const struct intel_dpll_mgr *dpll_mgr; unsigned int active_crtcs; unsigned int min_pixclk[I915_MAX_PIPES]; diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c index e88dc46afe85..b711407014d2 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c @@ -174,66 +174,20 @@ void intel_disable_shared_dpll(struct intel_crtc *crtc) intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); } -static enum intel_dpll_id -ibx_get_fixed_dpll(struct intel_crtc *crtc, - struct intel_crtc_state *crtc_state) -{ - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - struct intel_shared_dpll *pll; - enum intel_dpll_id i; - - /* Ironlake PCH has a fixed PLL->PCH pipe mapping. */ - i = (enum intel_dpll_id) crtc->pipe; - pll = &dev_priv->shared_dplls[i]; - - DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n", - crtc->base.base.id, pll->name); - - return i; -} - -static enum intel_dpll_id -bxt_get_fixed_dpll(struct intel_crtc *crtc, - struct intel_crtc_state *crtc_state) -{ - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - struct intel_encoder *encoder; - struct intel_digital_port *intel_dig_port; - struct intel_shared_dpll *pll; - enum intel_dpll_id i; - - /* PLL is attached to port in bxt */ - encoder = intel_ddi_get_crtc_new_encoder(crtc_state); - if (WARN_ON(!encoder)) - return DPLL_ID_PRIVATE; - - intel_dig_port = enc_to_dig_port(&encoder->base); - /* 1:1 mapping between ports and PLLs */ - i = (enum intel_dpll_id)intel_dig_port->port; - pll = &dev_priv->shared_dplls[i]; - DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n", - crtc->base.base.id, pll->name); - - return i; -} - -static enum intel_dpll_id +static struct intel_shared_dpll * intel_find_shared_dpll(struct intel_crtc *crtc, - struct intel_crtc_state *crtc_state) + struct intel_crtc_state *crtc_state, + enum intel_dpll_id range_min, + enum intel_dpll_id range_max) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; struct intel_shared_dpll *pll; struct intel_shared_dpll_config *shared_dpll; enum intel_dpll_id i; - int max = dev_priv->num_shared_dpll; - - if (INTEL_INFO(dev_priv)->gen < 9 && HAS_DDI(dev_priv)) - /* Do not consider SPLL */ - max = 2; shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state->base.state); - for (i = 0; i < max; i++) { + for (i = range_min; i <= range_max; i++) { pll = &dev_priv->shared_dplls[i]; /* Only want to check enabled timings first */ @@ -247,49 +201,33 @@ intel_find_shared_dpll(struct intel_crtc *crtc, crtc->base.base.id, pll->name, shared_dpll[i].crtc_mask, pll->active); - return i; + return pll; } } /* Ok no matching timings, maybe there's a free one? */ - for (i = 0; i < dev_priv->num_shared_dpll; i++) { + for (i = range_min; i <= range_max; i++) { pll = &dev_priv->shared_dplls[i]; if (shared_dpll[i].crtc_mask == 0) { DRM_DEBUG_KMS("CRTC:%d allocated %s\n", crtc->base.base.id, pll->name); - return i; + return pll; } } - return DPLL_ID_PRIVATE; + return NULL; } -struct intel_shared_dpll * -intel_get_shared_dpll(struct intel_crtc *crtc, - struct intel_crtc_state *crtc_state) +static void +intel_reference_shared_dpll(struct intel_shared_dpll *pll, + struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; - struct intel_shared_dpll *pll; struct intel_shared_dpll_config *shared_dpll; - enum intel_dpll_id i; + struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); + enum intel_dpll_id i = pll->id; shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state->base.state); - if (HAS_PCH_IBX(dev_priv->dev)) { - i = ibx_get_fixed_dpll(crtc, crtc_state); - WARN_ON(shared_dpll[i].crtc_mask); - } else if (IS_BROXTON(dev_priv->dev)) { - i = bxt_get_fixed_dpll(crtc, crtc_state); - WARN_ON(shared_dpll[i].crtc_mask); - } else { - i = intel_find_shared_dpll(crtc, crtc_state); - } - - if (i < 0) - return NULL; - - pll = &dev_priv->shared_dplls[i]; - if (shared_dpll[i].crtc_mask == 0) shared_dpll[i].hw_state = crtc_state->dpll_hw_state; @@ -299,8 +237,6 @@ intel_get_shared_dpll(struct intel_crtc *crtc, pipe_name(crtc->pipe)); intel_shared_dpll_config_get(shared_dpll, pll, crtc); - - return pll; } void intel_shared_dpll_commit(struct drm_atomic_state *state) @@ -398,6 +334,32 @@ static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv, udelay(200); } +static struct intel_shared_dpll * +ibx_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state) +{ + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_shared_dpll *pll; + enum intel_dpll_id i; + + if (HAS_PCH_IBX(dev_priv)) { + /* Ironlake PCH has a fixed PLL->PCH pipe mapping. */ + i = (enum intel_dpll_id) crtc->pipe; + pll = &dev_priv->shared_dplls[i]; + + DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n", + crtc->base.base.id, pll->name); + } else { + pll = intel_find_shared_dpll(crtc, crtc_state, + DPLL_ID_PCH_PLL_A, + DPLL_ID_PCH_PLL_B); + } + + /* reference the pll */ + intel_reference_shared_dpll(pll, crtc_state); + + return pll; +} + static const struct intel_shared_dpll_funcs ibx_pch_dpll_funcs = { .mode_set = ibx_pch_dpll_mode_set, .enable = ibx_pch_dpll_enable, @@ -475,6 +437,19 @@ static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv, return val & SPLL_PLL_ENABLE; } +static struct intel_shared_dpll * +hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state) +{ + struct intel_shared_dpll *pll; + + pll = intel_find_shared_dpll(crtc, crtc_state, + DPLL_ID_WRPLL1, DPLL_ID_WRPLL2); + if (pll) + intel_reference_shared_dpll(pll, crtc_state); + + return pll; +} + static const struct intel_shared_dpll_funcs hsw_ddi_wrpll_funcs = { .enable = hsw_ddi_wrpll_enable, @@ -594,6 +569,19 @@ out: return ret; } +static struct intel_shared_dpll * +skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state) +{ + struct intel_shared_dpll *pll; + + pll = intel_find_shared_dpll(crtc, crtc_state, + DPLL_ID_SKL_DPLL1, DPLL_ID_SKL_DPLL3); + if (pll) + intel_reference_shared_dpll(pll, crtc_state); + + return pll; +} + static const struct intel_shared_dpll_funcs skl_ddi_pll_funcs = { .enable = skl_ddi_pll_enable, .disable = skl_ddi_pll_disable, @@ -782,6 +770,32 @@ out: return ret; } +static struct intel_shared_dpll * +bxt_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state) +{ + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_encoder *encoder; + struct intel_digital_port *intel_dig_port; + struct intel_shared_dpll *pll; + enum intel_dpll_id i; + + /* PLL is attached to port in bxt */ + encoder = intel_ddi_get_crtc_new_encoder(crtc_state); + if (WARN_ON(!encoder)) + return NULL; + + intel_dig_port = enc_to_dig_port(&encoder->base); + /* 1:1 mapping between ports and PLLs */ + i = (enum intel_dpll_id)intel_dig_port->port; + pll = &dev_priv->shared_dplls[i]; + DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n", + crtc->base.base.id, pll->name); + + intel_reference_shared_dpll(pll, crtc_state); + + return pll; +} + static const struct intel_shared_dpll_funcs bxt_ddi_pll_funcs = { .enable = bxt_ddi_pll_enable, .disable = bxt_ddi_pll_disable, @@ -826,12 +840,24 @@ struct dpll_info { const struct intel_shared_dpll_funcs *funcs; }; +struct intel_dpll_mgr { + const struct dpll_info *dpll_info; + + struct intel_shared_dpll *(*get_dpll)(struct intel_crtc *crtc, + struct intel_crtc_state *crtc_state); +}; + static const struct dpll_info pch_plls[] = { { "PCH DPLL A", DPLL_ID_PCH_PLL_A, &ibx_pch_dpll_funcs }, { "PCH DPLL B", DPLL_ID_PCH_PLL_B, &ibx_pch_dpll_funcs }, { NULL, -1, NULL }, }; +static const struct intel_dpll_mgr pch_pll_mgr = { + .dpll_info = pch_plls, + .get_dpll = ibx_get_dpll, +}; + static const struct dpll_info hsw_plls[] = { { "WRPLL 1", DPLL_ID_WRPLL1, &hsw_ddi_wrpll_funcs }, { "WRPLL 2", DPLL_ID_WRPLL2, &hsw_ddi_wrpll_funcs }, @@ -839,6 +865,11 @@ static const struct dpll_info hsw_plls[] = { { NULL, -1, NULL, }, }; +static const struct intel_dpll_mgr hsw_pll_mgr = { + .dpll_info = hsw_plls, + .get_dpll = hsw_get_dpll, +}; + static const struct dpll_info skl_plls[] = { { "DPPL 1", DPLL_ID_SKL_DPLL1, &skl_ddi_pll_funcs }, { "DPPL 2", DPLL_ID_SKL_DPLL2, &skl_ddi_pll_funcs }, @@ -846,6 +877,11 @@ static const struct dpll_info skl_plls[] = { { NULL, -1, NULL, }, }; +static const struct intel_dpll_mgr skl_pll_mgr = { + .dpll_info = skl_plls, + .get_dpll = skl_get_dpll, +}; + static const struct dpll_info bxt_plls[] = { { "PORT PLL A", 0, &bxt_ddi_pll_funcs }, { "PORT PLL B", 1, &bxt_ddi_pll_funcs }, @@ -853,26 +889,34 @@ static const struct dpll_info bxt_plls[] = { { NULL, -1, NULL, }, }; +static const struct intel_dpll_mgr bxt_pll_mgr = { + .dpll_info = bxt_plls, + .get_dpll = bxt_get_dpll, +}; + void intel_shared_dpll_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - const struct dpll_info *dpll_info = NULL; + const struct intel_dpll_mgr *dpll_mgr = NULL; + const struct dpll_info *dpll_info; int i; if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) - dpll_info = skl_plls; + dpll_mgr = &skl_pll_mgr; else if IS_BROXTON(dev) - dpll_info = bxt_plls; + dpll_mgr = &bxt_pll_mgr; else if (HAS_DDI(dev)) - dpll_info = hsw_plls; + dpll_mgr = &hsw_pll_mgr; else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) - dpll_info = pch_plls; + dpll_mgr = &pch_pll_mgr; - if (!dpll_info) { + if (!dpll_mgr) { dev_priv->num_shared_dpll = 0; return; } + dpll_info = dpll_mgr->dpll_info; + for (i = 0; dpll_info[i].id >= 0; i++) { WARN_ON(i != dpll_info[i].id); @@ -881,6 +925,7 @@ void intel_shared_dpll_init(struct drm_device *dev) dev_priv->shared_dplls[i].funcs = *dpll_info[i].funcs; } + dev_priv->dpll_mgr = dpll_mgr; dev_priv->num_shared_dpll = i; BUG_ON(dev_priv->num_shared_dpll > I915_NUM_PLLS); @@ -889,3 +934,16 @@ void intel_shared_dpll_init(struct drm_device *dev) if (HAS_DDI(dev)) intel_ddi_pll_init(dev); } + +struct intel_shared_dpll * +intel_get_shared_dpll(struct intel_crtc *crtc, + struct intel_crtc_state *crtc_state) +{ + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + const struct intel_dpll_mgr *dpll_mgr = dev_priv->dpll_mgr; + + if (WARN_ON(!dpll_mgr)) + return NULL; + + return dpll_mgr->get_dpll(crtc, crtc_state); +} diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h index 8be2478af78f..7794c7ac87e6 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.h +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h @@ -30,6 +30,8 @@ struct intel_crtc; struct intel_crtc_state; struct intel_shared_dpll; +struct intel_dpll_mgr; + enum intel_dpll_id { DPLL_ID_PRIVATE = -1, /* non-shared dpll in use */ /* real shared dpll ids must be >= 0 */ -- cgit v1.2.3 From daedf20a4f69685a636c9104cf6f1f5d8835345b Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Tue, 8 Mar 2016 17:46:23 +0200 Subject: drm/i915: Move HSW/BDW pll selection logic to intel_dpll_mgr.c Move the code for selecting and configuring HSW/BDW DDI PLLs into the shared dpll infrastructure. With this most of the PLL selection logic for those platforms is in one place. DisplayPort is handled separately, but that should be fixed on a follow up patch. It also allows a small clean up of the SPLL logic. v2: Rebase. Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1457451987-17466-10-git-send-email-ander.conselvan.de.oliveira@intel.com --- drivers/gpu/drm/i915/intel_crt.c | 8 +- drivers/gpu/drm/i915/intel_ddi.c | 271 ++----------------------------- drivers/gpu/drm/i915/intel_display.c | 2 +- drivers/gpu/drm/i915/intel_dpll_mgr.c | 295 ++++++++++++++++++++++++++++++++-- drivers/gpu/drm/i915/intel_dpll_mgr.h | 13 +- 5 files changed, 307 insertions(+), 282 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 5f12a195d55c..a2a31fd01d1d 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -265,15 +265,9 @@ static bool intel_crt_compute_config(struct intel_encoder *encoder, pipe_config->pipe_bpp = 24; /* FDI must always be 2.7 GHz */ - if (HAS_DDI(dev)) { - pipe_config->ddi_pll_sel = PORT_CLK_SEL_SPLL; + if (HAS_DDI(dev)) pipe_config->port_clock = 135000 * 2; - pipe_config->dpll_hw_state.wrpll = 0; - pipe_config->dpll_hw_state.spll = - SPLL_PLL_ENABLE | SPLL_PLL_FREQ_1350MHz | SPLL_PLL_SSC; - } - return true; } diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index b6af5c0a6ae6..eae3ce2e0f62 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -724,160 +724,6 @@ intel_ddi_get_crtc_new_encoder(struct intel_crtc_state *crtc_state) } #define LC_FREQ 2700 -#define LC_FREQ_2K U64_C(LC_FREQ * 2000) - -#define P_MIN 2 -#define P_MAX 64 -#define P_INC 2 - -/* Constraints for PLL good behavior */ -#define REF_MIN 48 -#define REF_MAX 400 -#define VCO_MIN 2400 -#define VCO_MAX 4800 - -#define abs_diff(a, b) ({ \ - typeof(a) __a = (a); \ - typeof(b) __b = (b); \ - (void) (&__a == &__b); \ - __a > __b ? (__a - __b) : (__b - __a); }) - -struct hsw_wrpll_rnp { - unsigned p, n2, r2; -}; - -static unsigned hsw_wrpll_get_budget_for_freq(int clock) -{ - unsigned budget; - - switch (clock) { - case 25175000: - case 25200000: - case 27000000: - case 27027000: - case 37762500: - case 37800000: - case 40500000: - case 40541000: - case 54000000: - case 54054000: - case 59341000: - case 59400000: - case 72000000: - case 74176000: - case 74250000: - case 81000000: - case 81081000: - case 89012000: - case 89100000: - case 108000000: - case 108108000: - case 111264000: - case 111375000: - case 148352000: - case 148500000: - case 162000000: - case 162162000: - case 222525000: - case 222750000: - case 296703000: - case 297000000: - budget = 0; - break; - case 233500000: - case 245250000: - case 247750000: - case 253250000: - case 298000000: - budget = 1500; - break; - case 169128000: - case 169500000: - case 179500000: - case 202000000: - budget = 2000; - break; - case 256250000: - case 262500000: - case 270000000: - case 272500000: - case 273750000: - case 280750000: - case 281250000: - case 286000000: - case 291750000: - budget = 4000; - break; - case 267250000: - case 268500000: - budget = 5000; - break; - default: - budget = 1000; - break; - } - - return budget; -} - -static void hsw_wrpll_update_rnp(uint64_t freq2k, unsigned budget, - unsigned r2, unsigned n2, unsigned p, - struct hsw_wrpll_rnp *best) -{ - uint64_t a, b, c, d, diff, diff_best; - - /* No best (r,n,p) yet */ - if (best->p == 0) { - best->p = p; - best->n2 = n2; - best->r2 = r2; - return; - } - - /* - * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to - * freq2k. - * - * delta = 1e6 * - * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) / - * freq2k; - * - * and we would like delta <= budget. - * - * If the discrepancy is above the PPM-based budget, always prefer to - * improve upon the previous solution. However, if you're within the - * budget, try to maximize Ref * VCO, that is N / (P * R^2). - */ - a = freq2k * budget * p * r2; - b = freq2k * budget * best->p * best->r2; - diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2); - diff_best = abs_diff(freq2k * best->p * best->r2, - LC_FREQ_2K * best->n2); - c = 1000000 * diff; - d = 1000000 * diff_best; - - if (a < c && b < d) { - /* If both are above the budget, pick the closer */ - if (best->p * best->r2 * diff < p * r2 * diff_best) { - best->p = p; - best->n2 = n2; - best->r2 = r2; - } - } else if (a >= c && b < d) { - /* If A is below the threshold but B is above it? Update. */ - best->p = p; - best->n2 = n2; - best->r2 = r2; - } else if (a >= c && b >= d) { - /* Both are below the limit, so pick the higher n2/(r2*r2) */ - if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) { - best->p = p; - best->n2 = n2; - best->r2 = r2; - } - } - /* Otherwise a < c && b >= d, do nothing */ -} static int hsw_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv, i915_reg_t reg) @@ -1139,119 +985,24 @@ void intel_ddi_clock_get(struct intel_encoder *encoder, bxt_ddi_clock_get(encoder, pipe_config); } -static void -hsw_ddi_calculate_wrpll(int clock /* in Hz */, - unsigned *r2_out, unsigned *n2_out, unsigned *p_out) -{ - uint64_t freq2k; - unsigned p, n2, r2; - struct hsw_wrpll_rnp best = { 0, 0, 0 }; - unsigned budget; - - freq2k = clock / 100; - - budget = hsw_wrpll_get_budget_for_freq(clock); - - /* Special case handling for 540 pixel clock: bypass WR PLL entirely - * and directly pass the LC PLL to it. */ - if (freq2k == 5400000) { - *n2_out = 2; - *p_out = 1; - *r2_out = 2; - return; - } - - /* - * Ref = LC_FREQ / R, where Ref is the actual reference input seen by - * the WR PLL. - * - * We want R so that REF_MIN <= Ref <= REF_MAX. - * Injecting R2 = 2 * R gives: - * REF_MAX * r2 > LC_FREQ * 2 and - * REF_MIN * r2 < LC_FREQ * 2 - * - * Which means the desired boundaries for r2 are: - * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN - * - */ - for (r2 = LC_FREQ * 2 / REF_MAX + 1; - r2 <= LC_FREQ * 2 / REF_MIN; - r2++) { - - /* - * VCO = N * Ref, that is: VCO = N * LC_FREQ / R - * - * Once again we want VCO_MIN <= VCO <= VCO_MAX. - * Injecting R2 = 2 * R and N2 = 2 * N, we get: - * VCO_MAX * r2 > n2 * LC_FREQ and - * VCO_MIN * r2 < n2 * LC_FREQ) - * - * Which means the desired boundaries for n2 are: - * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ - */ - for (n2 = VCO_MIN * r2 / LC_FREQ + 1; - n2 <= VCO_MAX * r2 / LC_FREQ; - n2++) { - - for (p = P_MIN; p <= P_MAX; p += P_INC) - hsw_wrpll_update_rnp(freq2k, budget, - r2, n2, p, &best); - } - } - - *n2_out = best.n2; - *p_out = best.p; - *r2_out = best.r2; -} - static bool hsw_ddi_pll_select(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state, struct intel_encoder *intel_encoder) { - struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev); - int clock = crtc_state->port_clock; - - if (intel_encoder->type == INTEL_OUTPUT_HDMI) { - struct intel_shared_dpll *pll; - uint32_t val; - unsigned p, n2, r2; - - hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p); - - val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL | - WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) | - WRPLL_DIVIDER_POST(p); - - memset(&crtc_state->dpll_hw_state, 0, - sizeof(crtc_state->dpll_hw_state)); - - crtc_state->dpll_hw_state.wrpll = val; + struct intel_shared_dpll *pll; - pll = intel_get_shared_dpll(intel_crtc, crtc_state); - if (pll == NULL) { + if (intel_encoder->type == INTEL_OUTPUT_HDMI || + intel_encoder->type == INTEL_OUTPUT_ANALOG) { + pll = intel_get_shared_dpll(intel_crtc, crtc_state, + intel_encoder); + if (!pll) DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n", pipe_name(intel_crtc->pipe)); - return false; - } - - crtc_state->ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id); - } else if (crtc_state->ddi_pll_sel == PORT_CLK_SEL_SPLL) { - struct drm_atomic_state *state = crtc_state->base.state; - struct intel_shared_dpll_config *spll = - &intel_atomic_get_shared_dpll_state(state)[DPLL_ID_SPLL]; - - if (spll->crtc_mask && - WARN_ON(spll->hw_state.spll != crtc_state->dpll_hw_state.spll)) - return false; - - crtc_state->shared_dpll = - intel_get_shared_dpll_by_id(dev_priv, DPLL_ID_SPLL); - spll->hw_state.spll = crtc_state->dpll_hw_state.spll; - spll->crtc_mask |= 1 << intel_crtc->pipe; + return pll; + } else { + return true; } - - return true; } struct skl_wrpll_context { @@ -1560,7 +1311,7 @@ skl_ddi_pll_select(struct intel_crtc *intel_crtc, crtc_state->dpll_hw_state.cfgcr1 = cfgcr1; crtc_state->dpll_hw_state.cfgcr2 = cfgcr2; - pll = intel_get_shared_dpll(intel_crtc, crtc_state); + pll = intel_get_shared_dpll(intel_crtc, crtc_state, intel_encoder); if (pll == NULL) { DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n", pipe_name(intel_crtc->pipe)); @@ -1707,7 +1458,7 @@ bxt_ddi_pll_select(struct intel_crtc *intel_crtc, crtc_state->dpll_hw_state.pcsdw12 = LANESTAGGER_STRAP_OVRD | lanestagger; - pll = intel_get_shared_dpll(intel_crtc, crtc_state); + pll = intel_get_shared_dpll(intel_crtc, crtc_state, intel_encoder); if (pll == NULL) { DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n", pipe_name(intel_crtc->pipe)); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5852a1a307f1..9d2f494c0e65 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8943,7 +8943,7 @@ static int ironlake_crtc_compute_clock(struct intel_crtc *crtc, else crtc_state->dpll_hw_state.fp1 = fp; - pll = intel_get_shared_dpll(crtc, crtc_state); + pll = intel_get_shared_dpll(crtc, crtc_state, NULL); if (pll == NULL) { DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n", pipe_name(crtc->pipe)); diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c index b711407014d2..224c8965ec95 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c @@ -335,7 +335,8 @@ static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv, } static struct intel_shared_dpll * -ibx_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state) +ibx_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, + struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct intel_shared_dpll *pll; @@ -437,15 +438,282 @@ static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv, return val & SPLL_PLL_ENABLE; } +static uint32_t hsw_pll_to_ddi_pll_sel(struct intel_shared_dpll *pll) +{ + switch (pll->id) { + case DPLL_ID_WRPLL1: + return PORT_CLK_SEL_WRPLL1; + case DPLL_ID_WRPLL2: + return PORT_CLK_SEL_WRPLL2; + case DPLL_ID_SPLL: + return PORT_CLK_SEL_SPLL; + default: + return PORT_CLK_SEL_NONE; + } +} + +#define LC_FREQ 2700 +#define LC_FREQ_2K U64_C(LC_FREQ * 2000) + +#define P_MIN 2 +#define P_MAX 64 +#define P_INC 2 + +/* Constraints for PLL good behavior */ +#define REF_MIN 48 +#define REF_MAX 400 +#define VCO_MIN 2400 +#define VCO_MAX 4800 + +struct hsw_wrpll_rnp { + unsigned p, n2, r2; +}; + +static unsigned hsw_wrpll_get_budget_for_freq(int clock) +{ + unsigned budget; + + switch (clock) { + case 25175000: + case 25200000: + case 27000000: + case 27027000: + case 37762500: + case 37800000: + case 40500000: + case 40541000: + case 54000000: + case 54054000: + case 59341000: + case 59400000: + case 72000000: + case 74176000: + case 74250000: + case 81000000: + case 81081000: + case 89012000: + case 89100000: + case 108000000: + case 108108000: + case 111264000: + case 111375000: + case 148352000: + case 148500000: + case 162000000: + case 162162000: + case 222525000: + case 222750000: + case 296703000: + case 297000000: + budget = 0; + break; + case 233500000: + case 245250000: + case 247750000: + case 253250000: + case 298000000: + budget = 1500; + break; + case 169128000: + case 169500000: + case 179500000: + case 202000000: + budget = 2000; + break; + case 256250000: + case 262500000: + case 270000000: + case 272500000: + case 273750000: + case 280750000: + case 281250000: + case 286000000: + case 291750000: + budget = 4000; + break; + case 267250000: + case 268500000: + budget = 5000; + break; + default: + budget = 1000; + break; + } + + return budget; +} + +static void hsw_wrpll_update_rnp(uint64_t freq2k, unsigned budget, + unsigned r2, unsigned n2, unsigned p, + struct hsw_wrpll_rnp *best) +{ + uint64_t a, b, c, d, diff, diff_best; + + /* No best (r,n,p) yet */ + if (best->p == 0) { + best->p = p; + best->n2 = n2; + best->r2 = r2; + return; + } + + /* + * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to + * freq2k. + * + * delta = 1e6 * + * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) / + * freq2k; + * + * and we would like delta <= budget. + * + * If the discrepancy is above the PPM-based budget, always prefer to + * improve upon the previous solution. However, if you're within the + * budget, try to maximize Ref * VCO, that is N / (P * R^2). + */ + a = freq2k * budget * p * r2; + b = freq2k * budget * best->p * best->r2; + diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2); + diff_best = abs_diff(freq2k * best->p * best->r2, + LC_FREQ_2K * best->n2); + c = 1000000 * diff; + d = 1000000 * diff_best; + + if (a < c && b < d) { + /* If both are above the budget, pick the closer */ + if (best->p * best->r2 * diff < p * r2 * diff_best) { + best->p = p; + best->n2 = n2; + best->r2 = r2; + } + } else if (a >= c && b < d) { + /* If A is below the threshold but B is above it? Update. */ + best->p = p; + best->n2 = n2; + best->r2 = r2; + } else if (a >= c && b >= d) { + /* Both are below the limit, so pick the higher n2/(r2*r2) */ + if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) { + best->p = p; + best->n2 = n2; + best->r2 = r2; + } + } + /* Otherwise a < c && b >= d, do nothing */ +} + +static void +hsw_ddi_calculate_wrpll(int clock /* in Hz */, + unsigned *r2_out, unsigned *n2_out, unsigned *p_out) +{ + uint64_t freq2k; + unsigned p, n2, r2; + struct hsw_wrpll_rnp best = { 0, 0, 0 }; + unsigned budget; + + freq2k = clock / 100; + + budget = hsw_wrpll_get_budget_for_freq(clock); + + /* Special case handling for 540 pixel clock: bypass WR PLL entirely + * and directly pass the LC PLL to it. */ + if (freq2k == 5400000) { + *n2_out = 2; + *p_out = 1; + *r2_out = 2; + return; + } + + /* + * Ref = LC_FREQ / R, where Ref is the actual reference input seen by + * the WR PLL. + * + * We want R so that REF_MIN <= Ref <= REF_MAX. + * Injecting R2 = 2 * R gives: + * REF_MAX * r2 > LC_FREQ * 2 and + * REF_MIN * r2 < LC_FREQ * 2 + * + * Which means the desired boundaries for r2 are: + * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN + * + */ + for (r2 = LC_FREQ * 2 / REF_MAX + 1; + r2 <= LC_FREQ * 2 / REF_MIN; + r2++) { + + /* + * VCO = N * Ref, that is: VCO = N * LC_FREQ / R + * + * Once again we want VCO_MIN <= VCO <= VCO_MAX. + * Injecting R2 = 2 * R and N2 = 2 * N, we get: + * VCO_MAX * r2 > n2 * LC_FREQ and + * VCO_MIN * r2 < n2 * LC_FREQ) + * + * Which means the desired boundaries for n2 are: + * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ + */ + for (n2 = VCO_MIN * r2 / LC_FREQ + 1; + n2 <= VCO_MAX * r2 / LC_FREQ; + n2++) { + + for (p = P_MIN; p <= P_MAX; p += P_INC) + hsw_wrpll_update_rnp(freq2k, budget, + r2, n2, p, &best); + } + } + + *n2_out = best.n2; + *p_out = best.p; + *r2_out = best.r2; +} + static struct intel_shared_dpll * -hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state) +hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, + struct intel_encoder *encoder) { struct intel_shared_dpll *pll; + int clock = crtc_state->port_clock; - pll = intel_find_shared_dpll(crtc, crtc_state, - DPLL_ID_WRPLL1, DPLL_ID_WRPLL2); - if (pll) - intel_reference_shared_dpll(pll, crtc_state); + if (encoder->type == INTEL_OUTPUT_HDMI) { + uint32_t val; + unsigned p, n2, r2; + + hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p); + + val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL | + WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) | + WRPLL_DIVIDER_POST(p); + + memset(&crtc_state->dpll_hw_state, 0, + sizeof(crtc_state->dpll_hw_state)); + + crtc_state->dpll_hw_state.wrpll = val; + + pll = intel_find_shared_dpll(crtc, crtc_state, + DPLL_ID_WRPLL1, DPLL_ID_WRPLL2); + + } else if (encoder->type == INTEL_OUTPUT_ANALOG) { + if (WARN_ON(crtc_state->port_clock / 2 != 135000)) + return NULL; + + memset(&crtc_state->dpll_hw_state, 0, + sizeof(crtc_state->dpll_hw_state)); + + crtc_state->dpll_hw_state.spll = + SPLL_PLL_ENABLE | SPLL_PLL_FREQ_1350MHz | SPLL_PLL_SSC; + + pll = intel_find_shared_dpll(crtc, crtc_state, + DPLL_ID_SPLL, DPLL_ID_SPLL); + } else { + return NULL; + } + + if (!pll) + return NULL; + + crtc_state->ddi_pll_sel = hsw_pll_to_ddi_pll_sel(pll); + + intel_reference_shared_dpll(pll, crtc_state); return pll; } @@ -570,7 +838,8 @@ out: } static struct intel_shared_dpll * -skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state) +skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, + struct intel_encoder *encoder) { struct intel_shared_dpll *pll; @@ -771,10 +1040,10 @@ out: } static struct intel_shared_dpll * -bxt_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state) +bxt_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, + struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - struct intel_encoder *encoder; struct intel_digital_port *intel_dig_port; struct intel_shared_dpll *pll; enum intel_dpll_id i; @@ -844,7 +1113,8 @@ struct intel_dpll_mgr { const struct dpll_info *dpll_info; struct intel_shared_dpll *(*get_dpll)(struct intel_crtc *crtc, - struct intel_crtc_state *crtc_state); + struct intel_crtc_state *crtc_state, + struct intel_encoder *encoder); }; static const struct dpll_info pch_plls[] = { @@ -937,7 +1207,8 @@ void intel_shared_dpll_init(struct drm_device *dev) struct intel_shared_dpll * intel_get_shared_dpll(struct intel_crtc *crtc, - struct intel_crtc_state *crtc_state) + struct intel_crtc_state *crtc_state, + struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); const struct intel_dpll_mgr *dpll_mgr = dev_priv->dpll_mgr; @@ -945,5 +1216,5 @@ intel_get_shared_dpll(struct intel_crtc *crtc, if (WARN_ON(!dpll_mgr)) return NULL; - return dpll_mgr->get_dpll(crtc, crtc_state); + return dpll_mgr->get_dpll(crtc, crtc_state, encoder); } diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h index 7794c7ac87e6..82e53f5b5c63 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.h +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h @@ -25,11 +25,19 @@ #ifndef _INTEL_DPLL_MGR_H_ #define _INTEL_DPLL_MGR_H_ +/*FIXME: Move this to a more appropriate place. */ +#define abs_diff(a, b) ({ \ + typeof(a) __a = (a); \ + typeof(b) __b = (b); \ + (void) (&__a == &__b); \ + __a > __b ? (__a - __b) : (__b - __a); }) + struct drm_i915_private; struct intel_crtc; struct intel_crtc_state; -struct intel_shared_dpll; +struct intel_encoder; +struct intel_shared_dpll; struct intel_dpll_mgr; enum intel_dpll_id { @@ -133,7 +141,8 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv, #define assert_shared_dpll_enabled(d, p) assert_shared_dpll(d, p, true) #define assert_shared_dpll_disabled(d, p) assert_shared_dpll(d, p, false) struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, - struct intel_crtc_state *state); + struct intel_crtc_state *state, + struct intel_encoder *encoder); void intel_prepare_shared_dpll(struct intel_crtc *crtc); void intel_enable_shared_dpll(struct intel_crtc *crtc); void intel_disable_shared_dpll(struct intel_crtc *crtc); -- cgit v1.2.3 From 304b65cbdc8d6d73b12ea798099b7ca64f491795 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Tue, 8 Mar 2016 17:46:24 +0200 Subject: drm/i915: Move SKL/KLB pll selection logic to intel_dpll_mgr.c Move the code for selecting plls for SKL/KLB into the shared dpll code, so that the platform specific details are hidden behind that interface. Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1457451987-17466-11-git-send-email-ander.conselvan.de.oliveira@intel.com --- drivers/gpu/drm/i915/intel_ddi.c | 301 +-------------------------------- drivers/gpu/drm/i915/intel_dpll_mgr.c | 307 +++++++++++++++++++++++++++++++++- 2 files changed, 306 insertions(+), 302 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index eae3ce2e0f62..2890675b5f9e 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1005,311 +1005,15 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc, } } -struct skl_wrpll_context { - uint64_t min_deviation; /* current minimal deviation */ - uint64_t central_freq; /* chosen central freq */ - uint64_t dco_freq; /* chosen dco freq */ - unsigned int p; /* chosen divider */ -}; - -static void skl_wrpll_context_init(struct skl_wrpll_context *ctx) -{ - memset(ctx, 0, sizeof(*ctx)); - - ctx->min_deviation = U64_MAX; -} - -/* DCO freq must be within +1%/-6% of the DCO central freq */ -#define SKL_DCO_MAX_PDEVIATION 100 -#define SKL_DCO_MAX_NDEVIATION 600 - -static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx, - uint64_t central_freq, - uint64_t dco_freq, - unsigned int divider) -{ - uint64_t deviation; - - deviation = div64_u64(10000 * abs_diff(dco_freq, central_freq), - central_freq); - - /* positive deviation */ - if (dco_freq >= central_freq) { - if (deviation < SKL_DCO_MAX_PDEVIATION && - deviation < ctx->min_deviation) { - ctx->min_deviation = deviation; - ctx->central_freq = central_freq; - ctx->dco_freq = dco_freq; - ctx->p = divider; - } - /* negative deviation */ - } else if (deviation < SKL_DCO_MAX_NDEVIATION && - deviation < ctx->min_deviation) { - ctx->min_deviation = deviation; - ctx->central_freq = central_freq; - ctx->dco_freq = dco_freq; - ctx->p = divider; - } -} - -static void skl_wrpll_get_multipliers(unsigned int p, - unsigned int *p0 /* out */, - unsigned int *p1 /* out */, - unsigned int *p2 /* out */) -{ - /* even dividers */ - if (p % 2 == 0) { - unsigned int half = p / 2; - - if (half == 1 || half == 2 || half == 3 || half == 5) { - *p0 = 2; - *p1 = 1; - *p2 = half; - } else if (half % 2 == 0) { - *p0 = 2; - *p1 = half / 2; - *p2 = 2; - } else if (half % 3 == 0) { - *p0 = 3; - *p1 = half / 3; - *p2 = 2; - } else if (half % 7 == 0) { - *p0 = 7; - *p1 = half / 7; - *p2 = 2; - } - } else if (p == 3 || p == 9) { /* 3, 5, 7, 9, 15, 21, 35 */ - *p0 = 3; - *p1 = 1; - *p2 = p / 3; - } else if (p == 5 || p == 7) { - *p0 = p; - *p1 = 1; - *p2 = 1; - } else if (p == 15) { - *p0 = 3; - *p1 = 1; - *p2 = 5; - } else if (p == 21) { - *p0 = 7; - *p1 = 1; - *p2 = 3; - } else if (p == 35) { - *p0 = 7; - *p1 = 1; - *p2 = 5; - } -} - -struct skl_wrpll_params { - uint32_t dco_fraction; - uint32_t dco_integer; - uint32_t qdiv_ratio; - uint32_t qdiv_mode; - uint32_t kdiv; - uint32_t pdiv; - uint32_t central_freq; -}; - -static void skl_wrpll_params_populate(struct skl_wrpll_params *params, - uint64_t afe_clock, - uint64_t central_freq, - uint32_t p0, uint32_t p1, uint32_t p2) -{ - uint64_t dco_freq; - - switch (central_freq) { - case 9600000000ULL: - params->central_freq = 0; - break; - case 9000000000ULL: - params->central_freq = 1; - break; - case 8400000000ULL: - params->central_freq = 3; - } - - switch (p0) { - case 1: - params->pdiv = 0; - break; - case 2: - params->pdiv = 1; - break; - case 3: - params->pdiv = 2; - break; - case 7: - params->pdiv = 4; - break; - default: - WARN(1, "Incorrect PDiv\n"); - } - - switch (p2) { - case 5: - params->kdiv = 0; - break; - case 2: - params->kdiv = 1; - break; - case 3: - params->kdiv = 2; - break; - case 1: - params->kdiv = 3; - break; - default: - WARN(1, "Incorrect KDiv\n"); - } - - params->qdiv_ratio = p1; - params->qdiv_mode = (params->qdiv_ratio == 1) ? 0 : 1; - - dco_freq = p0 * p1 * p2 * afe_clock; - - /* - * Intermediate values are in Hz. - * Divide by MHz to match bsepc - */ - params->dco_integer = div_u64(dco_freq, 24 * MHz(1)); - params->dco_fraction = - div_u64((div_u64(dco_freq, 24) - - params->dco_integer * MHz(1)) * 0x8000, MHz(1)); -} - -static bool -skl_ddi_calculate_wrpll(int clock /* in Hz */, - struct skl_wrpll_params *wrpll_params) -{ - uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */ - uint64_t dco_central_freq[3] = {8400000000ULL, - 9000000000ULL, - 9600000000ULL}; - static const int even_dividers[] = { 4, 6, 8, 10, 12, 14, 16, 18, 20, - 24, 28, 30, 32, 36, 40, 42, 44, - 48, 52, 54, 56, 60, 64, 66, 68, - 70, 72, 76, 78, 80, 84, 88, 90, - 92, 96, 98 }; - static const int odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 }; - static const struct { - const int *list; - int n_dividers; - } dividers[] = { - { even_dividers, ARRAY_SIZE(even_dividers) }, - { odd_dividers, ARRAY_SIZE(odd_dividers) }, - }; - struct skl_wrpll_context ctx; - unsigned int dco, d, i; - unsigned int p0, p1, p2; - - skl_wrpll_context_init(&ctx); - - for (d = 0; d < ARRAY_SIZE(dividers); d++) { - for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) { - for (i = 0; i < dividers[d].n_dividers; i++) { - unsigned int p = dividers[d].list[i]; - uint64_t dco_freq = p * afe_clock; - - skl_wrpll_try_divider(&ctx, - dco_central_freq[dco], - dco_freq, - p); - /* - * Skip the remaining dividers if we're sure to - * have found the definitive divider, we can't - * improve a 0 deviation. - */ - if (ctx.min_deviation == 0) - goto skip_remaining_dividers; - } - } - -skip_remaining_dividers: - /* - * If a solution is found with an even divider, prefer - * this one. - */ - if (d == 0 && ctx.p) - break; - } - - if (!ctx.p) { - DRM_DEBUG_DRIVER("No valid divider found for %dHz\n", clock); - return false; - } - - /* - * gcc incorrectly analyses that these can be used without being - * initialized. To be fair, it's hard to guess. - */ - p0 = p1 = p2 = 0; - skl_wrpll_get_multipliers(ctx.p, &p0, &p1, &p2); - skl_wrpll_params_populate(wrpll_params, afe_clock, ctx.central_freq, - p0, p1, p2); - - return true; -} - static bool skl_ddi_pll_select(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state, struct intel_encoder *intel_encoder) { struct intel_shared_dpll *pll; - uint32_t ctrl1, cfgcr1, cfgcr2; - int clock = crtc_state->port_clock; - /* - * See comment in intel_dpll_hw_state to understand why we always use 0 - * as the DPLL id in this function. - */ - - ctrl1 = DPLL_CTRL1_OVERRIDE(0); - - if (intel_encoder->type == INTEL_OUTPUT_HDMI) { - struct skl_wrpll_params wrpll_params = { 0, }; - - ctrl1 |= DPLL_CTRL1_HDMI_MODE(0); - - if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params)) - return false; - - cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE | - DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) | - wrpll_params.dco_integer; - - cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) | - DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) | - DPLL_CFGCR2_KDIV(wrpll_params.kdiv) | - DPLL_CFGCR2_PDIV(wrpll_params.pdiv) | - wrpll_params.central_freq; - } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT || - intel_encoder->type == INTEL_OUTPUT_DP_MST) { - switch (crtc_state->port_clock / 2) { - case 81000: - ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0); - break; - case 135000: - ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0); - break; - case 270000: - ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0); - break; - } - - cfgcr1 = cfgcr2 = 0; - } else if (intel_encoder->type == INTEL_OUTPUT_EDP) { + if (intel_encoder->type == INTEL_OUTPUT_EDP) return true; - } else - return false; - - memset(&crtc_state->dpll_hw_state, 0, - sizeof(crtc_state->dpll_hw_state)); - - crtc_state->dpll_hw_state.ctrl1 = ctrl1; - crtc_state->dpll_hw_state.cfgcr1 = cfgcr1; - crtc_state->dpll_hw_state.cfgcr2 = cfgcr2; pll = intel_get_shared_dpll(intel_crtc, crtc_state, intel_encoder); if (pll == NULL) { @@ -1318,9 +1022,6 @@ skl_ddi_pll_select(struct intel_crtc *intel_crtc, return false; } - /* shared DPLL id 0 is DPLL 1 */ - crtc_state->ddi_pll_sel = pll->id + 1; - return true; } diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c index 224c8965ec95..61887ae82b31 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c @@ -837,16 +837,319 @@ out: return ret; } +struct skl_wrpll_context { + uint64_t min_deviation; /* current minimal deviation */ + uint64_t central_freq; /* chosen central freq */ + uint64_t dco_freq; /* chosen dco freq */ + unsigned int p; /* chosen divider */ +}; + +static void skl_wrpll_context_init(struct skl_wrpll_context *ctx) +{ + memset(ctx, 0, sizeof(*ctx)); + + ctx->min_deviation = U64_MAX; +} + +/* DCO freq must be within +1%/-6% of the DCO central freq */ +#define SKL_DCO_MAX_PDEVIATION 100 +#define SKL_DCO_MAX_NDEVIATION 600 + +static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx, + uint64_t central_freq, + uint64_t dco_freq, + unsigned int divider) +{ + uint64_t deviation; + + deviation = div64_u64(10000 * abs_diff(dco_freq, central_freq), + central_freq); + + /* positive deviation */ + if (dco_freq >= central_freq) { + if (deviation < SKL_DCO_MAX_PDEVIATION && + deviation < ctx->min_deviation) { + ctx->min_deviation = deviation; + ctx->central_freq = central_freq; + ctx->dco_freq = dco_freq; + ctx->p = divider; + } + /* negative deviation */ + } else if (deviation < SKL_DCO_MAX_NDEVIATION && + deviation < ctx->min_deviation) { + ctx->min_deviation = deviation; + ctx->central_freq = central_freq; + ctx->dco_freq = dco_freq; + ctx->p = divider; + } +} + +static void skl_wrpll_get_multipliers(unsigned int p, + unsigned int *p0 /* out */, + unsigned int *p1 /* out */, + unsigned int *p2 /* out */) +{ + /* even dividers */ + if (p % 2 == 0) { + unsigned int half = p / 2; + + if (half == 1 || half == 2 || half == 3 || half == 5) { + *p0 = 2; + *p1 = 1; + *p2 = half; + } else if (half % 2 == 0) { + *p0 = 2; + *p1 = half / 2; + *p2 = 2; + } else if (half % 3 == 0) { + *p0 = 3; + *p1 = half / 3; + *p2 = 2; + } else if (half % 7 == 0) { + *p0 = 7; + *p1 = half / 7; + *p2 = 2; + } + } else if (p == 3 || p == 9) { /* 3, 5, 7, 9, 15, 21, 35 */ + *p0 = 3; + *p1 = 1; + *p2 = p / 3; + } else if (p == 5 || p == 7) { + *p0 = p; + *p1 = 1; + *p2 = 1; + } else if (p == 15) { + *p0 = 3; + *p1 = 1; + *p2 = 5; + } else if (p == 21) { + *p0 = 7; + *p1 = 1; + *p2 = 3; + } else if (p == 35) { + *p0 = 7; + *p1 = 1; + *p2 = 5; + } +} + +struct skl_wrpll_params { + uint32_t dco_fraction; + uint32_t dco_integer; + uint32_t qdiv_ratio; + uint32_t qdiv_mode; + uint32_t kdiv; + uint32_t pdiv; + uint32_t central_freq; +}; + +static void skl_wrpll_params_populate(struct skl_wrpll_params *params, + uint64_t afe_clock, + uint64_t central_freq, + uint32_t p0, uint32_t p1, uint32_t p2) +{ + uint64_t dco_freq; + + switch (central_freq) { + case 9600000000ULL: + params->central_freq = 0; + break; + case 9000000000ULL: + params->central_freq = 1; + break; + case 8400000000ULL: + params->central_freq = 3; + } + + switch (p0) { + case 1: + params->pdiv = 0; + break; + case 2: + params->pdiv = 1; + break; + case 3: + params->pdiv = 2; + break; + case 7: + params->pdiv = 4; + break; + default: + WARN(1, "Incorrect PDiv\n"); + } + + switch (p2) { + case 5: + params->kdiv = 0; + break; + case 2: + params->kdiv = 1; + break; + case 3: + params->kdiv = 2; + break; + case 1: + params->kdiv = 3; + break; + default: + WARN(1, "Incorrect KDiv\n"); + } + + params->qdiv_ratio = p1; + params->qdiv_mode = (params->qdiv_ratio == 1) ? 0 : 1; + + dco_freq = p0 * p1 * p2 * afe_clock; + + /* + * Intermediate values are in Hz. + * Divide by MHz to match bsepc + */ + params->dco_integer = div_u64(dco_freq, 24 * MHz(1)); + params->dco_fraction = + div_u64((div_u64(dco_freq, 24) - + params->dco_integer * MHz(1)) * 0x8000, MHz(1)); +} + +static bool +skl_ddi_calculate_wrpll(int clock /* in Hz */, + struct skl_wrpll_params *wrpll_params) +{ + uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */ + uint64_t dco_central_freq[3] = {8400000000ULL, + 9000000000ULL, + 9600000000ULL}; + static const int even_dividers[] = { 4, 6, 8, 10, 12, 14, 16, 18, 20, + 24, 28, 30, 32, 36, 40, 42, 44, + 48, 52, 54, 56, 60, 64, 66, 68, + 70, 72, 76, 78, 80, 84, 88, 90, + 92, 96, 98 }; + static const int odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 }; + static const struct { + const int *list; + int n_dividers; + } dividers[] = { + { even_dividers, ARRAY_SIZE(even_dividers) }, + { odd_dividers, ARRAY_SIZE(odd_dividers) }, + }; + struct skl_wrpll_context ctx; + unsigned int dco, d, i; + unsigned int p0, p1, p2; + + skl_wrpll_context_init(&ctx); + + for (d = 0; d < ARRAY_SIZE(dividers); d++) { + for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) { + for (i = 0; i < dividers[d].n_dividers; i++) { + unsigned int p = dividers[d].list[i]; + uint64_t dco_freq = p * afe_clock; + + skl_wrpll_try_divider(&ctx, + dco_central_freq[dco], + dco_freq, + p); + /* + * Skip the remaining dividers if we're sure to + * have found the definitive divider, we can't + * improve a 0 deviation. + */ + if (ctx.min_deviation == 0) + goto skip_remaining_dividers; + } + } + +skip_remaining_dividers: + /* + * If a solution is found with an even divider, prefer + * this one. + */ + if (d == 0 && ctx.p) + break; + } + + if (!ctx.p) { + DRM_DEBUG_DRIVER("No valid divider found for %dHz\n", clock); + return false; + } + + /* + * gcc incorrectly analyses that these can be used without being + * initialized. To be fair, it's hard to guess. + */ + p0 = p1 = p2 = 0; + skl_wrpll_get_multipliers(ctx.p, &p0, &p1, &p2); + skl_wrpll_params_populate(wrpll_params, afe_clock, ctx.central_freq, + p0, p1, p2); + + return true; +} + static struct intel_shared_dpll * skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, struct intel_encoder *encoder) { struct intel_shared_dpll *pll; + uint32_t ctrl1, cfgcr1, cfgcr2; + int clock = crtc_state->port_clock; + + /* + * See comment in intel_dpll_hw_state to understand why we always use 0 + * as the DPLL id in this function. + */ + + ctrl1 = DPLL_CTRL1_OVERRIDE(0); + + if (encoder->type == INTEL_OUTPUT_HDMI) { + struct skl_wrpll_params wrpll_params = { 0, }; + + ctrl1 |= DPLL_CTRL1_HDMI_MODE(0); + + if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params)) + return false; + + cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE | + DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) | + wrpll_params.dco_integer; + + cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) | + DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) | + DPLL_CFGCR2_KDIV(wrpll_params.kdiv) | + DPLL_CFGCR2_PDIV(wrpll_params.pdiv) | + wrpll_params.central_freq; + } else if (encoder->type == INTEL_OUTPUT_DISPLAYPORT || + encoder->type == INTEL_OUTPUT_DP_MST) { + switch (crtc_state->port_clock / 2) { + case 81000: + ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0); + break; + case 135000: + ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0); + break; + case 270000: + ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0); + break; + } + + cfgcr1 = cfgcr2 = 0; + } else { + return NULL; + } + + memset(&crtc_state->dpll_hw_state, 0, + sizeof(crtc_state->dpll_hw_state)); + + crtc_state->dpll_hw_state.ctrl1 = ctrl1; + crtc_state->dpll_hw_state.cfgcr1 = cfgcr1; + crtc_state->dpll_hw_state.cfgcr2 = cfgcr2; pll = intel_find_shared_dpll(crtc, crtc_state, DPLL_ID_SKL_DPLL1, DPLL_ID_SKL_DPLL3); - if (pll) - intel_reference_shared_dpll(pll, crtc_state); + if (!pll) + return NULL; + + /* shared DPLL id 0 is DPLL 1 */ + crtc_state->ddi_pll_sel = pll->id + 1; + + intel_reference_shared_dpll(pll, crtc_state); return pll; } -- cgit v1.2.3 From 34177c249af743ceccaf583bf750e8bc17c4f18a Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Tue, 8 Mar 2016 17:46:25 +0200 Subject: drm/i915: Move BXT pll configuration logic to intel_dpll_mgr.c Move the code for configurating BXT plls into the shared dpll code, so that the platform specific details are hidden behind that interface. Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1457451987-17466-12-git-send-email-ander.conselvan.de.oliveira@intel.com --- drivers/gpu/drm/i915/intel_ddi.c | 141 +--------------------------------- drivers/gpu/drm/i915/intel_dpll_mgr.c | 139 +++++++++++++++++++++++++++++++-- 2 files changed, 134 insertions(+), 146 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 2890675b5f9e..50cc26435595 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1025,151 +1025,12 @@ skl_ddi_pll_select(struct intel_crtc *intel_crtc, return true; } -/* bxt clock parameters */ -struct bxt_clk_div { - int clock; - uint32_t p1; - uint32_t p2; - uint32_t m2_int; - uint32_t m2_frac; - bool m2_frac_en; - uint32_t n; -}; - -/* pre-calculated values for DP linkrates */ -static const struct bxt_clk_div bxt_dp_clk_val[] = { - {162000, 4, 2, 32, 1677722, 1, 1}, - {270000, 4, 1, 27, 0, 0, 1}, - {540000, 2, 1, 27, 0, 0, 1}, - {216000, 3, 2, 32, 1677722, 1, 1}, - {243000, 4, 1, 24, 1258291, 1, 1}, - {324000, 4, 1, 32, 1677722, 1, 1}, - {432000, 3, 1, 32, 1677722, 1, 1} -}; - static bool bxt_ddi_pll_select(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state, struct intel_encoder *intel_encoder) { - struct intel_shared_dpll *pll; - struct bxt_clk_div clk_div = {0}; - int vco = 0; - uint32_t prop_coef, int_coef, gain_ctl, targ_cnt; - uint32_t lanestagger; - int clock = crtc_state->port_clock; - - if (intel_encoder->type == INTEL_OUTPUT_HDMI) { - intel_clock_t best_clock; - - /* Calculate HDMI div */ - /* - * FIXME: tie the following calculation into - * i9xx_crtc_compute_clock - */ - if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) { - DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n", - clock, pipe_name(intel_crtc->pipe)); - return false; - } - - clk_div.p1 = best_clock.p1; - clk_div.p2 = best_clock.p2; - WARN_ON(best_clock.m1 != 2); - clk_div.n = best_clock.n; - clk_div.m2_int = best_clock.m2 >> 22; - clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1); - clk_div.m2_frac_en = clk_div.m2_frac != 0; - - vco = best_clock.vco; - } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT || - intel_encoder->type == INTEL_OUTPUT_EDP) { - int i; - - clk_div = bxt_dp_clk_val[0]; - for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) { - if (bxt_dp_clk_val[i].clock == clock) { - clk_div = bxt_dp_clk_val[i]; - break; - } - } - vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2; - } - - if (vco >= 6200000 && vco <= 6700000) { - prop_coef = 4; - int_coef = 9; - gain_ctl = 3; - targ_cnt = 8; - } else if ((vco > 5400000 && vco < 6200000) || - (vco >= 4800000 && vco < 5400000)) { - prop_coef = 5; - int_coef = 11; - gain_ctl = 3; - targ_cnt = 9; - } else if (vco == 5400000) { - prop_coef = 3; - int_coef = 8; - gain_ctl = 1; - targ_cnt = 9; - } else { - DRM_ERROR("Invalid VCO\n"); - return false; - } - - memset(&crtc_state->dpll_hw_state, 0, - sizeof(crtc_state->dpll_hw_state)); - - if (clock > 270000) - lanestagger = 0x18; - else if (clock > 135000) - lanestagger = 0x0d; - else if (clock > 67000) - lanestagger = 0x07; - else if (clock > 33000) - lanestagger = 0x04; - else - lanestagger = 0x02; - - crtc_state->dpll_hw_state.ebb0 = - PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2); - crtc_state->dpll_hw_state.pll0 = clk_div.m2_int; - crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n); - crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac; - - if (clk_div.m2_frac_en) - crtc_state->dpll_hw_state.pll3 = - PORT_PLL_M2_FRAC_ENABLE; - - crtc_state->dpll_hw_state.pll6 = - prop_coef | PORT_PLL_INT_COEFF(int_coef); - crtc_state->dpll_hw_state.pll6 |= - PORT_PLL_GAIN_CTL(gain_ctl); - - crtc_state->dpll_hw_state.pll8 = targ_cnt; - - crtc_state->dpll_hw_state.pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT; - - crtc_state->dpll_hw_state.pll10 = - PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT) - | PORT_PLL_DCO_AMP_OVR_EN_H; - - crtc_state->dpll_hw_state.ebb4 = PORT_PLL_10BIT_CLK_ENABLE; - - crtc_state->dpll_hw_state.pcsdw12 = - LANESTAGGER_STRAP_OVRD | lanestagger; - - pll = intel_get_shared_dpll(intel_crtc, crtc_state, intel_encoder); - if (pll == NULL) { - DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n", - pipe_name(intel_crtc->pipe)); - return false; - } - - /* shared DPLL id 0 is DPLL A */ - crtc_state->ddi_pll_sel = pll->id; - - return true; + return !!intel_get_shared_dpll(intel_crtc, crtc_state, intel_encoder); } /* diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c index 61887ae82b31..a90ef34a7785 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c @@ -1342,29 +1342,156 @@ out: return ret; } +/* bxt clock parameters */ +struct bxt_clk_div { + int clock; + uint32_t p1; + uint32_t p2; + uint32_t m2_int; + uint32_t m2_frac; + bool m2_frac_en; + uint32_t n; +}; + +/* pre-calculated values for DP linkrates */ +static const struct bxt_clk_div bxt_dp_clk_val[] = { + {162000, 4, 2, 32, 1677722, 1, 1}, + {270000, 4, 1, 27, 0, 0, 1}, + {540000, 2, 1, 27, 0, 0, 1}, + {216000, 3, 2, 32, 1677722, 1, 1}, + {243000, 4, 1, 24, 1258291, 1, 1}, + {324000, 4, 1, 32, 1677722, 1, 1}, + {432000, 3, 1, 32, 1677722, 1, 1} +}; + static struct intel_shared_dpll * bxt_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - struct intel_digital_port *intel_dig_port; struct intel_shared_dpll *pll; enum intel_dpll_id i; + struct intel_digital_port *intel_dig_port; + struct bxt_clk_div clk_div = {0}; + int vco = 0; + uint32_t prop_coef, int_coef, gain_ctl, targ_cnt; + uint32_t lanestagger; + int clock = crtc_state->port_clock; - /* PLL is attached to port in bxt */ - encoder = intel_ddi_get_crtc_new_encoder(crtc_state); - if (WARN_ON(!encoder)) + if (encoder->type == INTEL_OUTPUT_HDMI) { + intel_clock_t best_clock; + + /* Calculate HDMI div */ + /* + * FIXME: tie the following calculation into + * i9xx_crtc_compute_clock + */ + if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) { + DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n", + clock, pipe_name(crtc->pipe)); + return NULL; + } + + clk_div.p1 = best_clock.p1; + clk_div.p2 = best_clock.p2; + WARN_ON(best_clock.m1 != 2); + clk_div.n = best_clock.n; + clk_div.m2_int = best_clock.m2 >> 22; + clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1); + clk_div.m2_frac_en = clk_div.m2_frac != 0; + + vco = best_clock.vco; + } else if (encoder->type == INTEL_OUTPUT_DISPLAYPORT || + encoder->type == INTEL_OUTPUT_EDP) { + int i; + + clk_div = bxt_dp_clk_val[0]; + for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) { + if (bxt_dp_clk_val[i].clock == clock) { + clk_div = bxt_dp_clk_val[i]; + break; + } + } + vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2; + } + + if (vco >= 6200000 && vco <= 6700000) { + prop_coef = 4; + int_coef = 9; + gain_ctl = 3; + targ_cnt = 8; + } else if ((vco > 5400000 && vco < 6200000) || + (vco >= 4800000 && vco < 5400000)) { + prop_coef = 5; + int_coef = 11; + gain_ctl = 3; + targ_cnt = 9; + } else if (vco == 5400000) { + prop_coef = 3; + int_coef = 8; + gain_ctl = 1; + targ_cnt = 9; + } else { + DRM_ERROR("Invalid VCO\n"); return NULL; + } + + memset(&crtc_state->dpll_hw_state, 0, + sizeof(crtc_state->dpll_hw_state)); + + if (clock > 270000) + lanestagger = 0x18; + else if (clock > 135000) + lanestagger = 0x0d; + else if (clock > 67000) + lanestagger = 0x07; + else if (clock > 33000) + lanestagger = 0x04; + else + lanestagger = 0x02; + + crtc_state->dpll_hw_state.ebb0 = + PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2); + crtc_state->dpll_hw_state.pll0 = clk_div.m2_int; + crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n); + crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac; + + if (clk_div.m2_frac_en) + crtc_state->dpll_hw_state.pll3 = + PORT_PLL_M2_FRAC_ENABLE; + + crtc_state->dpll_hw_state.pll6 = + prop_coef | PORT_PLL_INT_COEFF(int_coef); + crtc_state->dpll_hw_state.pll6 |= + PORT_PLL_GAIN_CTL(gain_ctl); + + crtc_state->dpll_hw_state.pll8 = targ_cnt; + + crtc_state->dpll_hw_state.pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT; + + crtc_state->dpll_hw_state.pll10 = + PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT) + | PORT_PLL_DCO_AMP_OVR_EN_H; + + crtc_state->dpll_hw_state.ebb4 = PORT_PLL_10BIT_CLK_ENABLE; + + crtc_state->dpll_hw_state.pcsdw12 = + LANESTAGGER_STRAP_OVRD | lanestagger; intel_dig_port = enc_to_dig_port(&encoder->base); + /* 1:1 mapping between ports and PLLs */ - i = (enum intel_dpll_id)intel_dig_port->port; - pll = &dev_priv->shared_dplls[i]; + i = (enum intel_dpll_id) intel_dig_port->port; + pll = intel_get_shared_dpll_by_id(dev_priv, i); + DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n", crtc->base.base.id, pll->name); intel_reference_shared_dpll(pll, crtc_state); + /* shared DPLL id 0 is DPLL A */ + crtc_state->ddi_pll_sel = pll->id; + return pll; } -- cgit v1.2.3 From 9d16da65bfda54dea0b9b10ec49a0e1d23b631eb Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Tue, 8 Mar 2016 17:46:26 +0200 Subject: drm/i915: Manage HSW/BDW LCPLLs with the shared dpll interface Manage the LCPLLs used with DisplayPort, so that all the HSW/BDW DPLLs are managed by the shared dpll code. v2: Introduce INTEL_DPLL_ALWAYS_ON flag to please state checker. (Ander) v3: Initialize pll->flags in intel_shared_dpll_init(). (Ander) Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1457451987-17466-13-git-send-email-ander.conselvan.de.oliveira@intel.com --- drivers/gpu/drm/i915/intel_ddi.c | 18 +++---- drivers/gpu/drm/i915/intel_display.c | 25 ++++++---- drivers/gpu/drm/i915/intel_dp.c | 23 +-------- drivers/gpu/drm/i915/intel_dp_mst.c | 4 -- drivers/gpu/drm/i915/intel_dpll_mgr.c | 90 ++++++++++++++++++++++++++++------- drivers/gpu/drm/i915/intel_dpll_mgr.h | 12 ++++- drivers/gpu/drm/i915/intel_drv.h | 1 - 7 files changed, 108 insertions(+), 65 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 50cc26435595..31f9aa0c2b51 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -992,17 +992,13 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc, { struct intel_shared_dpll *pll; - if (intel_encoder->type == INTEL_OUTPUT_HDMI || - intel_encoder->type == INTEL_OUTPUT_ANALOG) { - pll = intel_get_shared_dpll(intel_crtc, crtc_state, - intel_encoder); - if (!pll) - DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n", - pipe_name(intel_crtc->pipe)); - return pll; - } else { - return true; - } + pll = intel_get_shared_dpll(intel_crtc, crtc_state, + intel_encoder); + if (!pll) + DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n", + pipe_name(intel_crtc->pipe)); + + return pll; } static bool diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9d2f494c0e65..7e00ee51b2c9 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9821,13 +9821,19 @@ static void haswell_get_ddi_pll(struct drm_i915_private *dev_priv, case PORT_CLK_SEL_SPLL: id = DPLL_ID_SPLL; break; + case PORT_CLK_SEL_LCPLL_810: + id = DPLL_ID_LCPLL_810; + break; + case PORT_CLK_SEL_LCPLL_1350: + id = DPLL_ID_LCPLL_1350; + break; + case PORT_CLK_SEL_LCPLL_2700: + id = DPLL_ID_LCPLL_2700; + break; default: MISSING_CASE(pipe_config->ddi_pll_sel); /* fall through */ case PORT_CLK_SEL_NONE: - case PORT_CLK_SEL_LCPLL_810: - case PORT_CLK_SEL_LCPLL_1350: - case PORT_CLK_SEL_LCPLL_2700: return; } @@ -12942,11 +12948,14 @@ check_shared_dpll_state(struct drm_device *dev) pll->active, hweight32(pll->config.crtc_mask)); I915_STATE_WARN(pll->active && !pll->on, "pll in active use but not on in sw tracking\n"); - I915_STATE_WARN(pll->on && !pll->active, - "pll in on but not on in use in sw tracking\n"); - I915_STATE_WARN(pll->on != active, - "pll on state mismatch (expected %i, found %i)\n", - pll->on, active); + + if (!(pll->flags & INTEL_DPLL_ALWAYS_ON)) { + I915_STATE_WARN(pll->on && !pll->active, + "pll in on but not on in use in sw tracking\n"); + I915_STATE_WARN(pll->on != active, + "pll on state mismatch (expected %i, found %i)\n", + pll->on, active); + } for_each_intel_crtc(dev, crtc) { if (crtc->base.state->enable && crtc->config->shared_dpll == pll) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 109ae6166db1..4f0fad3cf138 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1283,25 +1283,6 @@ skl_edp_set_pll_config(struct intel_crtc_state *pipe_config) pipe_config->dpll_hw_state.ctrl1 = ctrl1; } -void -hsw_dp_set_ddi_pll_sel(struct intel_crtc_state *pipe_config) -{ - memset(&pipe_config->dpll_hw_state, 0, - sizeof(pipe_config->dpll_hw_state)); - - switch (pipe_config->port_clock / 2) { - case 81000: - pipe_config->ddi_pll_sel = PORT_CLK_SEL_LCPLL_810; - break; - case 135000: - pipe_config->ddi_pll_sel = PORT_CLK_SEL_LCPLL_1350; - break; - case 270000: - pipe_config->ddi_pll_sel = PORT_CLK_SEL_LCPLL_2700; - break; - } -} - static int intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates) { @@ -1661,10 +1642,8 @@ found: if ((IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) && is_edp(intel_dp)) skl_edp_set_pll_config(pipe_config); - else if (IS_BROXTON(dev)) + else if (IS_BROXTON(dev) || IS_HASWELL(dev) || IS_BROADWELL(dev)) /* handled in ddi */; - else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) - hsw_dp_set_ddi_pll_sel(pipe_config); else intel_dp_set_clock(encoder, pipe_config); diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index a2bd698fe2f7..8d1b7033aaba 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -33,7 +33,6 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { - struct drm_device *dev = encoder->base.dev; struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base); struct intel_digital_port *intel_dig_port = intel_mst->primary; struct intel_dp *intel_dp = &intel_dig_port->dp; @@ -92,9 +91,6 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, pipe_config->dp_m_n.tu = slots; - if (IS_HASWELL(dev) || IS_BROADWELL(dev)) - hsw_dp_set_ddi_pll_sel(pipe_config); - return true; } diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c index a90ef34a7785..a83af07e3570 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c @@ -447,6 +447,12 @@ static uint32_t hsw_pll_to_ddi_pll_sel(struct intel_shared_dpll *pll) return PORT_CLK_SEL_WRPLL2; case DPLL_ID_SPLL: return PORT_CLK_SEL_SPLL; + case DPLL_ID_LCPLL_810: + return PORT_CLK_SEL_LCPLL_810; + case DPLL_ID_LCPLL_1350: + return PORT_CLK_SEL_LCPLL_1350; + case DPLL_ID_LCPLL_2700: + return PORT_CLK_SEL_LCPLL_2700; default: return PORT_CLK_SEL_NONE; } @@ -671,9 +677,13 @@ static struct intel_shared_dpll * hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, struct intel_encoder *encoder) { + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct intel_shared_dpll *pll; int clock = crtc_state->port_clock; + memset(&crtc_state->dpll_hw_state, 0, + sizeof(crtc_state->dpll_hw_state)); + if (encoder->type == INTEL_OUTPUT_HDMI) { uint32_t val; unsigned p, n2, r2; @@ -684,21 +694,37 @@ hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) | WRPLL_DIVIDER_POST(p); - memset(&crtc_state->dpll_hw_state, 0, - sizeof(crtc_state->dpll_hw_state)); - crtc_state->dpll_hw_state.wrpll = val; pll = intel_find_shared_dpll(crtc, crtc_state, DPLL_ID_WRPLL1, DPLL_ID_WRPLL2); + } else if (encoder->type == INTEL_OUTPUT_DISPLAYPORT || + encoder->type == INTEL_OUTPUT_DP_MST || + encoder->type == INTEL_OUTPUT_EDP) { + enum intel_dpll_id pll_id; + + switch (clock / 2) { + case 81000: + pll_id = DPLL_ID_LCPLL_810; + break; + case 135000: + pll_id = DPLL_ID_LCPLL_1350; + break; + case 270000: + pll_id = DPLL_ID_LCPLL_2700; + break; + default: + DRM_DEBUG_KMS("Invalid clock for DP: %d\n", clock); + return NULL; + } + + pll = intel_get_shared_dpll_by_id(dev_priv, pll_id); + } else if (encoder->type == INTEL_OUTPUT_ANALOG) { if (WARN_ON(crtc_state->port_clock / 2 != 135000)) return NULL; - memset(&crtc_state->dpll_hw_state, 0, - sizeof(crtc_state->dpll_hw_state)); - crtc_state->dpll_hw_state.spll = SPLL_PLL_ENABLE | SPLL_PLL_FREQ_1350MHz | SPLL_PLL_SSC; @@ -731,6 +757,29 @@ static const struct intel_shared_dpll_funcs hsw_ddi_spll_funcs = { .get_hw_state = hsw_ddi_spll_get_hw_state, }; +static void hsw_ddi_lcpll_enable(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll) +{ +} + +static void hsw_ddi_lcpll_disable(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll) +{ +} + +static bool hsw_ddi_lcpll_get_hw_state(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll, + struct intel_dpll_hw_state *hw_state) +{ + return true; +} + +static const struct intel_shared_dpll_funcs hsw_ddi_lcpll_funcs = { + .enable = hsw_ddi_lcpll_enable, + .disable = hsw_ddi_lcpll_disable, + .get_hw_state = hsw_ddi_lcpll_get_hw_state, +}; + struct skl_dpll_regs { i915_reg_t ctl, cfgcr1, cfgcr2; }; @@ -1537,6 +1586,7 @@ struct dpll_info { const char *name; const int id; const struct intel_shared_dpll_funcs *funcs; + uint32_t flags; }; struct intel_dpll_mgr { @@ -1548,9 +1598,9 @@ struct intel_dpll_mgr { }; static const struct dpll_info pch_plls[] = { - { "PCH DPLL A", DPLL_ID_PCH_PLL_A, &ibx_pch_dpll_funcs }, - { "PCH DPLL B", DPLL_ID_PCH_PLL_B, &ibx_pch_dpll_funcs }, - { NULL, -1, NULL }, + { "PCH DPLL A", DPLL_ID_PCH_PLL_A, &ibx_pch_dpll_funcs, 0 }, + { "PCH DPLL B", DPLL_ID_PCH_PLL_B, &ibx_pch_dpll_funcs, 0 }, + { NULL, -1, NULL, 0 }, }; static const struct intel_dpll_mgr pch_pll_mgr = { @@ -1559,9 +1609,12 @@ static const struct intel_dpll_mgr pch_pll_mgr = { }; static const struct dpll_info hsw_plls[] = { - { "WRPLL 1", DPLL_ID_WRPLL1, &hsw_ddi_wrpll_funcs }, - { "WRPLL 2", DPLL_ID_WRPLL2, &hsw_ddi_wrpll_funcs }, - { "SPLL", DPLL_ID_SPLL, &hsw_ddi_spll_funcs }, + { "WRPLL 1", DPLL_ID_WRPLL1, &hsw_ddi_wrpll_funcs, 0 }, + { "WRPLL 2", DPLL_ID_WRPLL2, &hsw_ddi_wrpll_funcs, 0 }, + { "SPLL", DPLL_ID_SPLL, &hsw_ddi_spll_funcs, 0 }, + { "LCPLL 810", DPLL_ID_LCPLL_810, &hsw_ddi_lcpll_funcs, INTEL_DPLL_ALWAYS_ON }, + { "LCPLL 1350", DPLL_ID_LCPLL_1350, &hsw_ddi_lcpll_funcs, INTEL_DPLL_ALWAYS_ON }, + { "LCPLL 2700", DPLL_ID_LCPLL_2700, &hsw_ddi_lcpll_funcs, INTEL_DPLL_ALWAYS_ON }, { NULL, -1, NULL, }, }; @@ -1571,9 +1624,9 @@ static const struct intel_dpll_mgr hsw_pll_mgr = { }; static const struct dpll_info skl_plls[] = { - { "DPPL 1", DPLL_ID_SKL_DPLL1, &skl_ddi_pll_funcs }, - { "DPPL 2", DPLL_ID_SKL_DPLL2, &skl_ddi_pll_funcs }, - { "DPPL 3", DPLL_ID_SKL_DPLL3, &skl_ddi_pll_funcs }, + { "DPPL 1", DPLL_ID_SKL_DPLL1, &skl_ddi_pll_funcs, 0 }, + { "DPPL 2", DPLL_ID_SKL_DPLL2, &skl_ddi_pll_funcs, 0 }, + { "DPPL 3", DPLL_ID_SKL_DPLL3, &skl_ddi_pll_funcs, 0 }, { NULL, -1, NULL, }, }; @@ -1583,9 +1636,9 @@ static const struct intel_dpll_mgr skl_pll_mgr = { }; static const struct dpll_info bxt_plls[] = { - { "PORT PLL A", 0, &bxt_ddi_pll_funcs }, - { "PORT PLL B", 1, &bxt_ddi_pll_funcs }, - { "PORT PLL C", 2, &bxt_ddi_pll_funcs }, + { "PORT PLL A", 0, &bxt_ddi_pll_funcs, 0 }, + { "PORT PLL B", 1, &bxt_ddi_pll_funcs, 0 }, + { "PORT PLL C", 2, &bxt_ddi_pll_funcs, 0 }, { NULL, -1, NULL, }, }; @@ -1623,6 +1676,7 @@ void intel_shared_dpll_init(struct drm_device *dev) dev_priv->shared_dplls[i].id = dpll_info[i].id; dev_priv->shared_dplls[i].name = dpll_info[i].name; dev_priv->shared_dplls[i].funcs = *dpll_info[i].funcs; + dev_priv->shared_dplls[i].flags = dpll_info[i].flags; } dev_priv->dpll_mgr = dpll_mgr; diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h index 82e53f5b5c63..adf4706b8e58 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.h +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h @@ -49,13 +49,21 @@ enum intel_dpll_id { DPLL_ID_WRPLL1 = 0, DPLL_ID_WRPLL2 = 1, DPLL_ID_SPLL = 2, + DPLL_ID_LCPLL_810 = 3, + DPLL_ID_LCPLL_1350 = 4, + DPLL_ID_LCPLL_2700 = 5, /* skl */ DPLL_ID_SKL_DPLL1 = 0, DPLL_ID_SKL_DPLL2 = 1, DPLL_ID_SKL_DPLL3 = 2, }; -#define I915_NUM_PLLS 3 +#define I915_NUM_PLLS 6 + +/** Inform the state checker that the DPLL is kept enabled even if not + * in use by any crtc. + */ +#define INTEL_DPLL_ALWAYS_ON (1 << 0) struct intel_dpll_hw_state { /* i9xx, pch plls */ @@ -113,6 +121,8 @@ struct intel_shared_dpll { enum intel_dpll_id id; struct intel_shared_dpll_funcs funcs; + + uint32_t flags; }; #define SKL_DPLL0 0 diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 1f62fba3ae3a..1e3992889647 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1312,7 +1312,6 @@ void intel_edp_drrs_invalidate(struct drm_device *dev, void intel_edp_drrs_flush(struct drm_device *dev, unsigned frontbuffer_bits); bool intel_digital_port_connected(struct drm_i915_private *dev_priv, struct intel_digital_port *port); -void hsw_dp_set_ddi_pll_sel(struct intel_crtc_state *pipe_config); void intel_dp_program_link_training_pattern(struct intel_dp *intel_dp, -- cgit v1.2.3 From a3c988ea068c94f39a2e6bd37e0faf1c2606a55d Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Tue, 8 Mar 2016 17:46:27 +0200 Subject: drm/i915: Make SKL/KBL DPLL0 managed by the shared dpll code Include DPLL0 in the managed dplls for SKL/KBL. While it has to be kept enabled because of it driving CDCLK, it is better to special case that inside the DPLL code than in the higher level. v2: Use INTEL_DPLL_ALWAYS_ON flag. (Ander) v3: Remove extremely paranoid WARN_ONs. (Maarten) Handle DPLL0 in skylake_get_ddi_pll() properly. (Ander) Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1457451987-17466-14-git-send-email-ander.conselvan.de.oliveira@intel.com --- drivers/gpu/drm/i915/intel_ddi.c | 21 ------ drivers/gpu/drm/i915/intel_display.c | 12 +--- drivers/gpu/drm/i915/intel_dp.c | 52 +------------- drivers/gpu/drm/i915/intel_dpll_mgr.c | 124 ++++++++++++++++++++++++++-------- drivers/gpu/drm/i915/intel_dpll_mgr.h | 7 +- 5 files changed, 105 insertions(+), 111 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 31f9aa0c2b51..91654ffc3a42 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1008,9 +1008,6 @@ skl_ddi_pll_select(struct intel_crtc *intel_crtc, { struct intel_shared_dpll *pll; - if (intel_encoder->type == INTEL_OUTPUT_EDP) - return true; - pll = intel_get_shared_dpll(intel_crtc, crtc_state, intel_encoder); if (pll == NULL) { DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n", @@ -1570,24 +1567,6 @@ void intel_ddi_clk_select(struct intel_encoder *encoder, uint32_t dpll = pipe_config->ddi_pll_sel; uint32_t val; - /* - * DPLL0 is used for eDP and is the only "private" DPLL (as - * opposed to shared) on SKL - */ - if (encoder->type == INTEL_OUTPUT_EDP) { - WARN_ON(dpll != SKL_DPLL0); - - val = I915_READ(DPLL_CTRL1); - - val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | - DPLL_CTRL1_SSC(dpll) | - DPLL_CTRL1_LINK_RATE_MASK(dpll)); - val |= pipe_config->dpll_hw_state.ctrl1 << (dpll * 6); - - I915_WRITE(DPLL_CTRL1, val); - POSTING_READ(DPLL_CTRL1); - } - /* DDI -> PLL mapping */ val = I915_READ(DPLL_CTRL2); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 7e00ee51b2c9..28556a800804 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9771,21 +9771,15 @@ static void skylake_get_ddi_pll(struct drm_i915_private *dev_priv, struct intel_crtc_state *pipe_config) { enum intel_dpll_id id; - u32 temp, dpll_ctl1; + u32 temp; temp = I915_READ(DPLL_CTRL2) & DPLL_CTRL2_DDI_CLK_SEL_MASK(port); pipe_config->ddi_pll_sel = temp >> (port * 3 + 1); switch (pipe_config->ddi_pll_sel) { case SKL_DPLL0: - /* - * On SKL the eDP DPLL (DPLL0 as we don't use SSC) is not part - * of the shared DPLL framework and thus needs to be read out - * separately - */ - dpll_ctl1 = I915_READ(DPLL_CTRL1); - pipe_config->dpll_hw_state.ctrl1 = dpll_ctl1 & 0x3f; - return; + id = DPLL_ID_SKL_DPLL0; + break; case SKL_DPLL1: id = DPLL_ID_SKL_DPLL1; break; diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 4f0fad3cf138..13e1cc8936d8 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1237,52 +1237,6 @@ intel_dp_connector_unregister(struct intel_connector *intel_connector) intel_connector_unregister(intel_connector); } -static void -skl_edp_set_pll_config(struct intel_crtc_state *pipe_config) -{ - u32 ctrl1; - - memset(&pipe_config->dpll_hw_state, 0, - sizeof(pipe_config->dpll_hw_state)); - - pipe_config->ddi_pll_sel = SKL_DPLL0; - pipe_config->dpll_hw_state.cfgcr1 = 0; - pipe_config->dpll_hw_state.cfgcr2 = 0; - - ctrl1 = DPLL_CTRL1_OVERRIDE(SKL_DPLL0); - switch (pipe_config->port_clock / 2) { - case 81000: - ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, - SKL_DPLL0); - break; - case 135000: - ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, - SKL_DPLL0); - break; - case 270000: - ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, - SKL_DPLL0); - break; - case 162000: - ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620, - SKL_DPLL0); - break; - /* TBD: For DP link rates 2.16 GHz and 4.32 GHz, VCO is 8640 which - results in CDCLK change. Need to handle the change of CDCLK by - disabling pipes and re-enabling them */ - case 108000: - ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080, - SKL_DPLL0); - break; - case 216000: - ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2160, - SKL_DPLL0); - break; - - } - pipe_config->dpll_hw_state.ctrl1 = ctrl1; -} - static int intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates) { @@ -1640,11 +1594,7 @@ found: &pipe_config->dp_m2_n2); } - if ((IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) && is_edp(intel_dp)) - skl_edp_set_pll_config(pipe_config); - else if (IS_BROXTON(dev) || IS_HASWELL(dev) || IS_BROADWELL(dev)) - /* handled in ddi */; - else + if (!HAS_DDI(dev)) intel_dp_set_clock(encoder, pipe_config); return true; diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c index a83af07e3570..4b636c47e8e3 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c @@ -785,7 +785,12 @@ struct skl_dpll_regs { }; /* this array is indexed by the *shared* pll id */ -static const struct skl_dpll_regs skl_dpll_regs[3] = { +static const struct skl_dpll_regs skl_dpll_regs[4] = { + { + /* DPLL 0 */ + .ctl = LCPLL1_CTL, + /* DPLL 0 doesn't support HDMI mode */ + }, { /* DPLL 1 */ .ctl = LCPLL2_CTL, @@ -806,24 +811,27 @@ static const struct skl_dpll_regs skl_dpll_regs[3] = { }, }; -static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll) +static void skl_ddi_pll_write_ctrl1(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll) { uint32_t val; - unsigned int dpll; - const struct skl_dpll_regs *regs = skl_dpll_regs; - - /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */ - dpll = pll->id + 1; val = I915_READ(DPLL_CTRL1); - val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) | - DPLL_CTRL1_LINK_RATE_MASK(dpll)); - val |= pll->config.hw_state.ctrl1 << (dpll * 6); + val &= ~(DPLL_CTRL1_HDMI_MODE(pll->id) | DPLL_CTRL1_SSC(pll->id) | + DPLL_CTRL1_LINK_RATE_MASK(pll->id)); + val |= pll->config.hw_state.ctrl1 << (pll->id * 6); I915_WRITE(DPLL_CTRL1, val); POSTING_READ(DPLL_CTRL1); +} + +static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll) +{ + const struct skl_dpll_regs *regs = skl_dpll_regs; + + skl_ddi_pll_write_ctrl1(dev_priv, pll); I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1); I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2); @@ -834,8 +842,14 @@ static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv, I915_WRITE(regs[pll->id].ctl, I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE); - if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5)) - DRM_ERROR("DPLL %d not locked\n", dpll); + if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(pll->id), 5)) + DRM_ERROR("DPLL %d not locked\n", pll->id); +} + +static void skl_ddi_dpll0_enable(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll) +{ + skl_ddi_pll_write_ctrl1(dev_priv, pll); } static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv, @@ -849,12 +863,16 @@ static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv, POSTING_READ(regs[pll->id].ctl); } +static void skl_ddi_dpll0_disable(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll) +{ +} + static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv, struct intel_shared_dpll *pll, struct intel_dpll_hw_state *hw_state) { uint32_t val; - unsigned int dpll; const struct skl_dpll_regs *regs = skl_dpll_regs; bool ret; @@ -863,18 +881,15 @@ static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv, ret = false; - /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */ - dpll = pll->id + 1; - val = I915_READ(regs[pll->id].ctl); if (!(val & LCPLL_PLL_ENABLE)) goto out; val = I915_READ(DPLL_CTRL1); - hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f; + hw_state->ctrl1 = (val >> (pll->id * 6)) & 0x3f; /* avoid reading back stale values if HDMI mode is not enabled */ - if (val & DPLL_CTRL1_HDMI_MODE(dpll)) { + if (val & DPLL_CTRL1_HDMI_MODE(pll->id)) { hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1); hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2); } @@ -886,6 +901,35 @@ out: return ret; } +static bool skl_ddi_dpll0_get_hw_state(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll, + struct intel_dpll_hw_state *hw_state) +{ + uint32_t val; + const struct skl_dpll_regs *regs = skl_dpll_regs; + bool ret; + + if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS)) + return false; + + ret = false; + + /* DPLL0 is always enabled since it drives CDCLK */ + val = I915_READ(regs[pll->id].ctl); + if (WARN_ON(!(val & LCPLL_PLL_ENABLE))) + goto out; + + val = I915_READ(DPLL_CTRL1); + hw_state->ctrl1 = (val >> (pll->id * 6)) & 0x3f; + + ret = true; + +out: + intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); + + return ret; +} + struct skl_wrpll_context { uint64_t min_deviation; /* current minimal deviation */ uint64_t central_freq; /* chosen central freq */ @@ -1165,7 +1209,8 @@ skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, DPLL_CFGCR2_PDIV(wrpll_params.pdiv) | wrpll_params.central_freq; } else if (encoder->type == INTEL_OUTPUT_DISPLAYPORT || - encoder->type == INTEL_OUTPUT_DP_MST) { + encoder->type == INTEL_OUTPUT_DP_MST || + encoder->type == INTEL_OUTPUT_EDP) { switch (crtc_state->port_clock / 2) { case 81000: ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0); @@ -1176,6 +1221,19 @@ skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, case 270000: ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0); break; + /* eDP 1.4 rates */ + case 162000: + ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620, 0); + break; + /* TBD: For DP link rates 2.16 GHz and 4.32 GHz, VCO is 8640 which + results in CDCLK change. Need to handle the change of CDCLK by + disabling pipes and re-enabling them */ + case 108000: + ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080, 0); + break; + case 216000: + ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2160, 0); + break; } cfgcr1 = cfgcr2 = 0; @@ -1190,13 +1248,18 @@ skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, crtc_state->dpll_hw_state.cfgcr1 = cfgcr1; crtc_state->dpll_hw_state.cfgcr2 = cfgcr2; - pll = intel_find_shared_dpll(crtc, crtc_state, - DPLL_ID_SKL_DPLL1, DPLL_ID_SKL_DPLL3); + if (encoder->type == INTEL_OUTPUT_EDP) + pll = intel_find_shared_dpll(crtc, crtc_state, + DPLL_ID_SKL_DPLL0, + DPLL_ID_SKL_DPLL0); + else + pll = intel_find_shared_dpll(crtc, crtc_state, + DPLL_ID_SKL_DPLL1, + DPLL_ID_SKL_DPLL3); if (!pll) return NULL; - /* shared DPLL id 0 is DPLL 1 */ - crtc_state->ddi_pll_sel = pll->id + 1; + crtc_state->ddi_pll_sel = pll->id; intel_reference_shared_dpll(pll, crtc_state); @@ -1209,6 +1272,12 @@ static const struct intel_shared_dpll_funcs skl_ddi_pll_funcs = { .get_hw_state = skl_ddi_pll_get_hw_state, }; +static const struct intel_shared_dpll_funcs skl_ddi_dpll0_funcs = { + .enable = skl_ddi_dpll0_enable, + .disable = skl_ddi_dpll0_disable, + .get_hw_state = skl_ddi_dpll0_get_hw_state, +}; + static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv, struct intel_shared_dpll *pll) { @@ -1624,9 +1693,10 @@ static const struct intel_dpll_mgr hsw_pll_mgr = { }; static const struct dpll_info skl_plls[] = { - { "DPPL 1", DPLL_ID_SKL_DPLL1, &skl_ddi_pll_funcs, 0 }, - { "DPPL 2", DPLL_ID_SKL_DPLL2, &skl_ddi_pll_funcs, 0 }, - { "DPPL 3", DPLL_ID_SKL_DPLL3, &skl_ddi_pll_funcs, 0 }, + { "DPLL 0", DPLL_ID_SKL_DPLL0, &skl_ddi_dpll0_funcs, INTEL_DPLL_ALWAYS_ON }, + { "DPPL 1", DPLL_ID_SKL_DPLL1, &skl_ddi_pll_funcs, 0 }, + { "DPPL 2", DPLL_ID_SKL_DPLL2, &skl_ddi_pll_funcs, 0 }, + { "DPPL 3", DPLL_ID_SKL_DPLL3, &skl_ddi_pll_funcs, 0 }, { NULL, -1, NULL, }, }; diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h index adf4706b8e58..1d341472f8b0 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.h +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h @@ -54,9 +54,10 @@ enum intel_dpll_id { DPLL_ID_LCPLL_2700 = 5, /* skl */ - DPLL_ID_SKL_DPLL1 = 0, - DPLL_ID_SKL_DPLL2 = 1, - DPLL_ID_SKL_DPLL3 = 2, + DPLL_ID_SKL_DPLL0 = 0, + DPLL_ID_SKL_DPLL1 = 1, + DPLL_ID_SKL_DPLL2 = 2, + DPLL_ID_SKL_DPLL3 = 3, }; #define I915_NUM_PLLS 6 -- cgit v1.2.3 From 8b1f165a4a8f64c28cf42d10e1f4d3b451dedc51 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 7 Mar 2016 17:56:57 +0200 Subject: drm/i915: Actually retry with bit-banging after GMBUS timeout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After the GMBUS transfer times out, we set force_bit=1 and return -EAGAIN expecting the i2c core to call the .master_xfer hook again so that we will retry the same transfer via bit-banging. This is in case the gmbus hardware is somehow faulty. Unfortunately we left adapter->retries to 0, meaning the i2c core didn't actually do the retry. Let's tell the core we want one retry when we return -EAGAIN. Note that i2c-algo-bit also uses this retry count for some internal retries, so we'll end up increasing those a bit as well. Cc: Jani Nikula Cc: drm-intel-fixes@lists.freedesktop.org Fixes: bffce907d640 ("drm/i915: abstract i2c bit banging fallback in gmbus xfer") Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1457366220-29409-2-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/intel_i2c.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index deb8282c26d8..52fbe530fc9e 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c @@ -664,6 +664,12 @@ int intel_setup_gmbus(struct drm_device *dev) bus->adapter.algo = &gmbus_algorithm; + /* + * We wish to retry with bit banging + * after a timed out GMBUS attempt. + */ + bus->adapter.retries = 1; + /* By default use a conservative clock rate */ bus->reg0 = pin | GMBUS_RATE_100KHZ; -- cgit v1.2.3 From 88ae3aedb8ec20a6b6ea8f7bd1990c0eb7c6f5d5 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 7 Mar 2016 15:22:31 +0100 Subject: staging:iio:adis16204: Remove adis16204 driver The ADIS16204 part has been obsoleted, which makes it hard to get the hardware to even test the driver. Considering this there is no expectation that the driver will be cleaned up and be able to move out of staging, so remove the driver. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/accel/Kconfig | 12 -- drivers/staging/iio/accel/Makefile | 3 - drivers/staging/iio/accel/adis16204.h | 68 -------- drivers/staging/iio/accel/adis16204_core.c | 253 ----------------------------- 4 files changed, 336 deletions(-) delete mode 100644 drivers/staging/iio/accel/adis16204.h delete mode 100644 drivers/staging/iio/accel/adis16204_core.c (limited to 'drivers') diff --git a/drivers/staging/iio/accel/Kconfig b/drivers/staging/iio/accel/Kconfig index fa67da9408b6..5bc98031a34d 100644 --- a/drivers/staging/iio/accel/Kconfig +++ b/drivers/staging/iio/accel/Kconfig @@ -27,18 +27,6 @@ config ADIS16203 To compile this driver as a module, say M here: the module will be called adis16203. -config ADIS16204 - tristate "Analog Devices ADIS16204 Programmable High-g Digital Impact Sensor and Recorder" - depends on SPI - select IIO_ADIS_LIB - select IIO_ADIS_LIB_BUFFER if IIO_BUFFER - help - Say Y here to build support for Analog Devices adis16204 Programmable - High-g Digital Impact Sensor and Recorder. - - To compile this driver as a module, say M here: the module will be - called adis16204. - config ADIS16209 tristate "Analog Devices ADIS16209 Dual-Axis Digital Inclinometer and Accelerometer" depends on SPI diff --git a/drivers/staging/iio/accel/Makefile b/drivers/staging/iio/accel/Makefile index 1ed137f1a506..8ad9732e3dbb 100644 --- a/drivers/staging/iio/accel/Makefile +++ b/drivers/staging/iio/accel/Makefile @@ -8,9 +8,6 @@ obj-$(CONFIG_ADIS16201) += adis16201.o adis16203-y := adis16203_core.o obj-$(CONFIG_ADIS16203) += adis16203.o -adis16204-y := adis16204_core.o -obj-$(CONFIG_ADIS16204) += adis16204.o - adis16209-y := adis16209_core.o obj-$(CONFIG_ADIS16209) += adis16209.o diff --git a/drivers/staging/iio/accel/adis16204.h b/drivers/staging/iio/accel/adis16204.h deleted file mode 100644 index 0b23f0b5c52f..000000000000 --- a/drivers/staging/iio/accel/adis16204.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef SPI_ADIS16204_H_ -#define SPI_ADIS16204_H_ - -#define ADIS16204_STARTUP_DELAY 220 /* ms */ - -#define ADIS16204_FLASH_CNT 0x00 /* Flash memory write count */ -#define ADIS16204_SUPPLY_OUT 0x02 /* Output, power supply */ -#define ADIS16204_XACCL_OUT 0x04 /* Output, x-axis accelerometer */ -#define ADIS16204_YACCL_OUT 0x06 /* Output, y-axis accelerometer */ -#define ADIS16204_AUX_ADC 0x08 /* Output, auxiliary ADC input */ -#define ADIS16204_TEMP_OUT 0x0A /* Output, temperature */ -#define ADIS16204_X_PEAK_OUT 0x0C /* Twos complement */ -#define ADIS16204_Y_PEAK_OUT 0x0E /* Twos complement */ -#define ADIS16204_XACCL_NULL 0x10 /* Calibration, x-axis acceleration offset null */ -#define ADIS16204_YACCL_NULL 0x12 /* Calibration, y-axis acceleration offset null */ -#define ADIS16204_XACCL_SCALE 0x14 /* X-axis scale factor calibration register */ -#define ADIS16204_YACCL_SCALE 0x16 /* Y-axis scale factor calibration register */ -#define ADIS16204_XY_RSS_OUT 0x18 /* XY combined acceleration (RSS) */ -#define ADIS16204_XY_PEAK_OUT 0x1A /* Peak, XY combined output (RSS) */ -#define ADIS16204_CAP_BUF_1 0x1C /* Capture buffer output register 1 */ -#define ADIS16204_CAP_BUF_2 0x1E /* Capture buffer output register 2 */ -#define ADIS16204_ALM_MAG1 0x20 /* Alarm 1 amplitude threshold */ -#define ADIS16204_ALM_MAG2 0x22 /* Alarm 2 amplitude threshold */ -#define ADIS16204_ALM_CTRL 0x28 /* Alarm control */ -#define ADIS16204_CAPT_PNTR 0x2A /* Capture register address pointer */ -#define ADIS16204_AUX_DAC 0x30 /* Auxiliary DAC data */ -#define ADIS16204_GPIO_CTRL 0x32 /* General-purpose digital input/output control */ -#define ADIS16204_MSC_CTRL 0x34 /* Miscellaneous control */ -#define ADIS16204_SMPL_PRD 0x36 /* Internal sample period (rate) control */ -#define ADIS16204_AVG_CNT 0x38 /* Operation, filter configuration */ -#define ADIS16204_SLP_CNT 0x3A /* Operation, sleep mode control */ -#define ADIS16204_DIAG_STAT 0x3C /* Diagnostics, system status register */ -#define ADIS16204_GLOB_CMD 0x3E /* Operation, system command register */ - -/* MSC_CTRL */ -#define ADIS16204_MSC_CTRL_PWRUP_SELF_TEST BIT(10) /* Self-test at power-on: 1 = disabled, 0 = enabled */ -#define ADIS16204_MSC_CTRL_SELF_TEST_EN BIT(8) /* Self-test enable */ -#define ADIS16204_MSC_CTRL_DATA_RDY_EN BIT(2) /* Data-ready enable: 1 = enabled, 0 = disabled */ -#define ADIS16204_MSC_CTRL_ACTIVE_HIGH BIT(1) /* Data-ready polarity: 1 = active high, 0 = active low */ -#define ADIS16204_MSC_CTRL_DATA_RDY_DIO2 BIT(0) /* Data-ready line selection: 1 = DIO2, 0 = DIO1 */ - -/* DIAG_STAT */ -#define ADIS16204_DIAG_STAT_ALARM2 BIT(9) /* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */ -#define ADIS16204_DIAG_STAT_ALARM1 BIT(8) /* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */ -#define ADIS16204_DIAG_STAT_SELFTEST_FAIL_BIT 5 /* Self-test diagnostic error flag: 1 = error condition, - 0 = normal operation */ -#define ADIS16204_DIAG_STAT_SPI_FAIL_BIT 3 /* SPI communications failure */ -#define ADIS16204_DIAG_STAT_FLASH_UPT_BIT 2 /* Flash update failure */ -#define ADIS16204_DIAG_STAT_POWER_HIGH_BIT 1 /* Power supply above 3.625 V */ -#define ADIS16204_DIAG_STAT_POWER_LOW_BIT 0 /* Power supply below 2.975 V */ - -/* GLOB_CMD */ -#define ADIS16204_GLOB_CMD_SW_RESET BIT(7) -#define ADIS16204_GLOB_CMD_CLEAR_STAT BIT(4) -#define ADIS16204_GLOB_CMD_FACTORY_CAL BIT(1) - -#define ADIS16204_ERROR_ACTIVE BIT(14) - -enum adis16204_scan { - ADIS16204_SCAN_ACC_X, - ADIS16204_SCAN_ACC_Y, - ADIS16204_SCAN_ACC_XY, - ADIS16204_SCAN_SUPPLY, - ADIS16204_SCAN_AUX_ADC, - ADIS16204_SCAN_TEMP, -}; - -#endif /* SPI_ADIS16204_H_ */ diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c deleted file mode 100644 index 20a9df64f1ed..000000000000 --- a/drivers/staging/iio/accel/adis16204_core.c +++ /dev/null @@ -1,253 +0,0 @@ -/* - * ADIS16204 Programmable High-g Digital Impact Sensor and Recorder - * - * Copyright 2010 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "adis16204.h" - -/* Unique to this driver currently */ - -static const u8 adis16204_addresses[][2] = { - [ADIS16204_SCAN_ACC_X] = { ADIS16204_XACCL_NULL, ADIS16204_X_PEAK_OUT }, - [ADIS16204_SCAN_ACC_Y] = { ADIS16204_YACCL_NULL, ADIS16204_Y_PEAK_OUT }, - [ADIS16204_SCAN_ACC_XY] = { 0, ADIS16204_XY_PEAK_OUT }, -}; - -static int adis16204_read_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int *val, int *val2, - long mask) -{ - struct adis *st = iio_priv(indio_dev); - int ret; - int bits; - u8 addr; - s16 val16; - int addrind; - - switch (mask) { - case IIO_CHAN_INFO_RAW: - return adis_single_conversion(indio_dev, chan, - ADIS16204_ERROR_ACTIVE, val); - case IIO_CHAN_INFO_SCALE: - switch (chan->type) { - case IIO_VOLTAGE: - if (chan->channel == 0) { - *val = 1; - *val2 = 220000; /* 1.22 mV */ - } else { - *val = 0; - *val2 = 610000; /* 0.61 mV */ - } - return IIO_VAL_INT_PLUS_MICRO; - case IIO_TEMP: - *val = -470; /* 0.47 C */ - *val2 = 0; - return IIO_VAL_INT_PLUS_MICRO; - case IIO_ACCEL: - *val = 0; - switch (chan->channel2) { - case IIO_MOD_X: - case IIO_MOD_ROOT_SUM_SQUARED_X_Y: - *val2 = IIO_G_TO_M_S_2(17125); /* 17.125 mg */ - break; - case IIO_MOD_Y: - case IIO_MOD_Z: - *val2 = IIO_G_TO_M_S_2(8407); /* 8.407 mg */ - break; - } - return IIO_VAL_INT_PLUS_MICRO; - default: - return -EINVAL; - } - break; - case IIO_CHAN_INFO_OFFSET: - *val = 25000 / -470 - 1278; /* 25 C = 1278 */ - return IIO_VAL_INT; - case IIO_CHAN_INFO_CALIBBIAS: - case IIO_CHAN_INFO_PEAK: - if (mask == IIO_CHAN_INFO_CALIBBIAS) { - bits = 12; - addrind = 0; - } else { /* PEAK_SEPARATE */ - bits = 14; - addrind = 1; - } - mutex_lock(&indio_dev->mlock); - addr = adis16204_addresses[chan->scan_index][addrind]; - ret = adis_read_reg_16(st, addr, &val16); - if (ret) { - mutex_unlock(&indio_dev->mlock); - return ret; - } - val16 &= (1 << bits) - 1; - val16 = (s16)(val16 << (16 - bits)) >> (16 - bits); - *val = val16; - mutex_unlock(&indio_dev->mlock); - return IIO_VAL_INT; - } - return -EINVAL; -} - -static int adis16204_write_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int val, - int val2, - long mask) -{ - struct adis *st = iio_priv(indio_dev); - int bits; - s16 val16; - u8 addr; - - switch (mask) { - case IIO_CHAN_INFO_CALIBBIAS: - switch (chan->type) { - case IIO_ACCEL: - bits = 12; - break; - default: - return -EINVAL; - } - val16 = val & ((1 << bits) - 1); - addr = adis16204_addresses[chan->scan_index][1]; - return adis_write_reg_16(st, addr, val16); - } - return -EINVAL; -} - -static const struct iio_chan_spec adis16204_channels[] = { - ADIS_SUPPLY_CHAN(ADIS16204_SUPPLY_OUT, ADIS16204_SCAN_SUPPLY, 0, 12), - ADIS_AUX_ADC_CHAN(ADIS16204_AUX_ADC, ADIS16204_SCAN_AUX_ADC, 0, 12), - ADIS_TEMP_CHAN(ADIS16204_TEMP_OUT, ADIS16204_SCAN_TEMP, 0, 12), - ADIS_ACCEL_CHAN(X, ADIS16204_XACCL_OUT, ADIS16204_SCAN_ACC_X, - BIT(IIO_CHAN_INFO_CALIBBIAS) | BIT(IIO_CHAN_INFO_PEAK), - 0, 14), - ADIS_ACCEL_CHAN(Y, ADIS16204_YACCL_OUT, ADIS16204_SCAN_ACC_Y, - BIT(IIO_CHAN_INFO_CALIBBIAS) | BIT(IIO_CHAN_INFO_PEAK), - 0, 14), - ADIS_ACCEL_CHAN(ROOT_SUM_SQUARED_X_Y, ADIS16204_XY_RSS_OUT, - ADIS16204_SCAN_ACC_XY, BIT(IIO_CHAN_INFO_PEAK), 0, 14), - IIO_CHAN_SOFT_TIMESTAMP(5), -}; - -static const struct iio_info adis16204_info = { - .read_raw = &adis16204_read_raw, - .write_raw = &adis16204_write_raw, - .update_scan_mode = adis_update_scan_mode, - .driver_module = THIS_MODULE, -}; - -static const char * const adis16204_status_error_msgs[] = { - [ADIS16204_DIAG_STAT_SELFTEST_FAIL_BIT] = "Self test failure", - [ADIS16204_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure", - [ADIS16204_DIAG_STAT_FLASH_UPT_BIT] = "Flash update failed", - [ADIS16204_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V", - [ADIS16204_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 2.975V", -}; - -static const struct adis_data adis16204_data = { - .read_delay = 20, - .msc_ctrl_reg = ADIS16204_MSC_CTRL, - .glob_cmd_reg = ADIS16204_GLOB_CMD, - .diag_stat_reg = ADIS16204_DIAG_STAT, - - .self_test_mask = ADIS16204_MSC_CTRL_SELF_TEST_EN, - .startup_delay = ADIS16204_STARTUP_DELAY, - - .status_error_msgs = adis16204_status_error_msgs, - .status_error_mask = BIT(ADIS16204_DIAG_STAT_SELFTEST_FAIL_BIT) | - BIT(ADIS16204_DIAG_STAT_SPI_FAIL_BIT) | - BIT(ADIS16204_DIAG_STAT_FLASH_UPT_BIT) | - BIT(ADIS16204_DIAG_STAT_POWER_HIGH_BIT) | - BIT(ADIS16204_DIAG_STAT_POWER_LOW_BIT), -}; - -static int adis16204_probe(struct spi_device *spi) -{ - int ret; - struct adis *st; - struct iio_dev *indio_dev; - - /* setup the industrialio driver allocated elements */ - indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); - if (!indio_dev) - return -ENOMEM; - st = iio_priv(indio_dev); - /* this is only used for removal purposes */ - spi_set_drvdata(spi, indio_dev); - - indio_dev->name = spi->dev.driver->name; - indio_dev->dev.parent = &spi->dev; - indio_dev->info = &adis16204_info; - indio_dev->channels = adis16204_channels; - indio_dev->num_channels = ARRAY_SIZE(adis16204_channels); - indio_dev->modes = INDIO_DIRECT_MODE; - - ret = adis_init(st, indio_dev, spi, &adis16204_data); - if (ret) - return ret; - - ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL); - if (ret) - return ret; - - /* Get the device into a sane initial state */ - ret = adis_initial_startup(st); - if (ret) - goto error_cleanup_buffer_trigger; - ret = iio_device_register(indio_dev); - if (ret) - goto error_cleanup_buffer_trigger; - - return 0; - -error_cleanup_buffer_trigger: - adis_cleanup_buffer_and_trigger(st, indio_dev); - return ret; -} - -static int adis16204_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct adis *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - adis_cleanup_buffer_and_trigger(st, indio_dev); - - return 0; -} - -static struct spi_driver adis16204_driver = { - .driver = { - .name = "adis16204", - }, - .probe = adis16204_probe, - .remove = adis16204_remove, -}; -module_spi_driver(adis16204_driver); - -MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); -MODULE_DESCRIPTION("ADIS16204 High-g Digital Impact Sensor and Recorder"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("spi:adis16204"); -- cgit v1.2.3 From 2bcdb3f2e05f011b7456d363a6fc5a0177196587 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 7 Mar 2016 15:22:32 +0100 Subject: staging:iio:adis16220: Remove adis16220 driver The ADIS16220 part has been obsoleted, which makes it hard to get the hardware to even test the driver. Considering this there is no expectation that the driver will be cleaned up and be able to move out of staging, so remove the driver. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/accel/Kconfig | 11 - drivers/staging/iio/accel/Makefile | 3 - drivers/staging/iio/accel/adis16220.h | 140 -------- drivers/staging/iio/accel/adis16220_core.c | 494 ----------------------------- 4 files changed, 648 deletions(-) delete mode 100644 drivers/staging/iio/accel/adis16220.h delete mode 100644 drivers/staging/iio/accel/adis16220_core.c (limited to 'drivers') diff --git a/drivers/staging/iio/accel/Kconfig b/drivers/staging/iio/accel/Kconfig index 5bc98031a34d..f066aa30f0ac 100644 --- a/drivers/staging/iio/accel/Kconfig +++ b/drivers/staging/iio/accel/Kconfig @@ -39,17 +39,6 @@ config ADIS16209 To compile this driver as a module, say M here: the module will be called adis16209. -config ADIS16220 - tristate "Analog Devices ADIS16220 Programmable Digital Vibration Sensor" - depends on SPI - select IIO_ADIS_LIB - help - Say Y here to build support for Analog Devices adis16220 programmable - digital vibration sensor. - - To compile this driver as a module, say M here: the module will be - called adis16220. - config ADIS16240 tristate "Analog Devices ADIS16240 Programmable Impact Sensor and Recorder" depends on SPI diff --git a/drivers/staging/iio/accel/Makefile b/drivers/staging/iio/accel/Makefile index 8ad9732e3dbb..415329c96f0c 100644 --- a/drivers/staging/iio/accel/Makefile +++ b/drivers/staging/iio/accel/Makefile @@ -11,9 +11,6 @@ obj-$(CONFIG_ADIS16203) += adis16203.o adis16209-y := adis16209_core.o obj-$(CONFIG_ADIS16209) += adis16209.o -adis16220-y := adis16220_core.o -obj-$(CONFIG_ADIS16220) += adis16220.o - adis16240-y := adis16240_core.o obj-$(CONFIG_ADIS16240) += adis16240.o diff --git a/drivers/staging/iio/accel/adis16220.h b/drivers/staging/iio/accel/adis16220.h deleted file mode 100644 index eab86331124f..000000000000 --- a/drivers/staging/iio/accel/adis16220.h +++ /dev/null @@ -1,140 +0,0 @@ -#ifndef SPI_ADIS16220_H_ -#define SPI_ADIS16220_H_ - -#include - -#define ADIS16220_STARTUP_DELAY 220 /* ms */ - -/* Flash memory write count */ -#define ADIS16220_FLASH_CNT 0x00 -/* Control, acceleration offset adjustment control */ -#define ADIS16220_ACCL_NULL 0x02 -/* Control, AIN1 offset adjustment control */ -#define ADIS16220_AIN1_NULL 0x04 -/* Control, AIN2 offset adjustment control */ -#define ADIS16220_AIN2_NULL 0x06 -/* Output, power supply during capture */ -#define ADIS16220_CAPT_SUPPLY 0x0A -/* Output, temperature during capture */ -#define ADIS16220_CAPT_TEMP 0x0C -/* Output, peak acceleration during capture */ -#define ADIS16220_CAPT_PEAKA 0x0E -/* Output, peak AIN1 level during capture */ -#define ADIS16220_CAPT_PEAK1 0x10 -/* Output, peak AIN2 level during capture */ -#define ADIS16220_CAPT_PEAK2 0x12 -/* Output, capture buffer for acceleration */ -#define ADIS16220_CAPT_BUFA 0x14 -/* Output, capture buffer for AIN1 */ -#define ADIS16220_CAPT_BUF1 0x16 -/* Output, capture buffer for AIN2 */ -#define ADIS16220_CAPT_BUF2 0x18 -/* Control, capture buffer address pointer */ -#define ADIS16220_CAPT_PNTR 0x1A -/* Control, capture control register */ -#define ADIS16220_CAPT_CTRL 0x1C -/* Control, capture period (automatic mode) */ -#define ADIS16220_CAPT_PRD 0x1E -/* Control, Alarm A, acceleration peak threshold */ -#define ADIS16220_ALM_MAGA 0x20 -/* Control, Alarm 1, AIN1 peak threshold */ -#define ADIS16220_ALM_MAG1 0x22 -/* Control, Alarm 2, AIN2 peak threshold */ -#define ADIS16220_ALM_MAG2 0x24 -/* Control, Alarm S, peak threshold */ -#define ADIS16220_ALM_MAGS 0x26 -/* Control, alarm configuration register */ -#define ADIS16220_ALM_CTRL 0x28 -/* Control, general I/O configuration */ -#define ADIS16220_GPIO_CTRL 0x32 -/* Control, self-test control, AIN configuration */ -#define ADIS16220_MSC_CTRL 0x34 -/* Control, digital I/O configuration */ -#define ADIS16220_DIO_CTRL 0x36 -/* Control, filter configuration */ -#define ADIS16220_AVG_CNT 0x38 -/* Status, system status */ -#define ADIS16220_DIAG_STAT 0x3C -/* Control, system commands */ -#define ADIS16220_GLOB_CMD 0x3E -/* Status, self-test response */ -#define ADIS16220_ST_DELTA 0x40 -/* Lot Identification Code 1 */ -#define ADIS16220_LOT_ID1 0x52 -/* Lot Identification Code 2 */ -#define ADIS16220_LOT_ID2 0x54 -/* Product identifier; convert to decimal = 16220 */ -#define ADIS16220_PROD_ID 0x56 -/* Serial number */ -#define ADIS16220_SERIAL_NUM 0x58 - -#define ADIS16220_CAPTURE_SIZE 2048 - -/* MSC_CTRL */ -#define ADIS16220_MSC_CTRL_SELF_TEST_EN BIT(8) -#define ADIS16220_MSC_CTRL_POWER_SUP_COM_AIN1 BIT(1) -#define ADIS16220_MSC_CTRL_POWER_SUP_COM_AIN2 BIT(0) - -/* DIO_CTRL */ -#define ADIS16220_MSC_CTRL_DIO2_BUSY_IND (BIT(5) | BIT(4)) -#define ADIS16220_MSC_CTRL_DIO1_BUSY_IND (BIT(3) | BIT(2)) -#define ADIS16220_MSC_CTRL_DIO2_ACT_HIGH BIT(1) -#define ADIS16220_MSC_CTRL_DIO1_ACT_HIGH BIT(0) - -/* DIAG_STAT */ -/* AIN2 sample > ALM_MAG2 */ -#define ADIS16220_DIAG_STAT_ALM_MAG2 BIT(14) -/* AIN1 sample > ALM_MAG1 */ -#define ADIS16220_DIAG_STAT_ALM_MAG1 BIT(13) -/* Acceleration sample > ALM_MAGA */ -#define ADIS16220_DIAG_STAT_ALM_MAGA BIT(12) -/* Error condition programmed into ALM_MAGS[11:0] and ALM_CTRL[5:4] is true */ -#define ADIS16220_DIAG_STAT_ALM_MAGS BIT(11) -/* |Peak value in AIN2 data capture| > ALM_MAG2 */ -#define ADIS16220_DIAG_STAT_PEAK_AIN2 BIT(10) -/* |Peak value in AIN1 data capture| > ALM_MAG1 */ -#define ADIS16220_DIAG_STAT_PEAK_AIN1 BIT(9) -/* |Peak value in acceleration data capture| > ALM_MAGA */ -#define ADIS16220_DIAG_STAT_PEAK_ACCEL BIT(8) -/* Data ready, capture complete */ -#define ADIS16220_DIAG_STAT_DATA_RDY BIT(7) -#define ADIS16220_DIAG_STAT_FLASH_CHK BIT(6) -#define ADIS16220_DIAG_STAT_SELF_TEST BIT(5) -/* Capture period violation/interruption */ -#define ADIS16220_DIAG_STAT_VIOLATION_BIT 4 -/* SPI communications failure */ -#define ADIS16220_DIAG_STAT_SPI_FAIL_BIT 3 -/* Flash update failure */ -#define ADIS16220_DIAG_STAT_FLASH_UPT_BIT 2 -/* Power supply above 3.625 V */ -#define ADIS16220_DIAG_STAT_POWER_HIGH_BIT 1 -/* Power supply below 3.15 V */ -#define ADIS16220_DIAG_STAT_POWER_LOW_BIT 0 - -/* GLOB_CMD */ -#define ADIS16220_GLOB_CMD_SW_RESET BIT(7) -#define ADIS16220_GLOB_CMD_SELF_TEST BIT(2) -#define ADIS16220_GLOB_CMD_PWR_DOWN BIT(1) - -#define ADIS16220_MAX_TX 2048 -#define ADIS16220_MAX_RX 2048 - -#define ADIS16220_SPI_BURST (u32)(1000 * 1000) -#define ADIS16220_SPI_FAST (u32)(2000 * 1000) - -/** - * struct adis16220_state - device instance specific data - * @adis: adis device - * @tx: transmit buffer - * @rx: receive buffer - * @buf_lock: mutex to protect tx and rx - **/ -struct adis16220_state { - struct adis adis; - - struct mutex buf_lock; - u8 tx[ADIS16220_MAX_TX] ____cacheline_aligned; - u8 rx[ADIS16220_MAX_RX]; -}; - -#endif /* SPI_ADIS16220_H_ */ diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c deleted file mode 100644 index d0165218b60c..000000000000 --- a/drivers/staging/iio/accel/adis16220_core.c +++ /dev/null @@ -1,494 +0,0 @@ -/* - * ADIS16220 Programmable Digital Vibration Sensor driver - * - * Copyright 2010 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "adis16220.h" - -static ssize_t adis16220_read_16bit(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct adis16220_state *st = iio_priv(indio_dev); - ssize_t ret; - u16 val; - - /* Take the iio_dev status lock */ - mutex_lock(&indio_dev->mlock); - ret = adis_read_reg_16(&st->adis, this_attr->address, &val); - mutex_unlock(&indio_dev->mlock); - if (ret) - return ret; - return sprintf(buf, "%u\n", val); -} - -static ssize_t adis16220_write_16bit(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - struct adis16220_state *st = iio_priv(indio_dev); - int ret; - u16 val; - - ret = kstrtou16(buf, 10, &val); - if (ret) - goto error_ret; - ret = adis_write_reg_16(&st->adis, this_attr->address, val); - -error_ret: - return ret ? ret : len; -} - -static int adis16220_capture(struct iio_dev *indio_dev) -{ - struct adis16220_state *st = iio_priv(indio_dev); - int ret; - - /* initiates a manual data capture */ - ret = adis_write_reg_16(&st->adis, ADIS16220_GLOB_CMD, 0xBF08); - if (ret) - dev_err(&indio_dev->dev, "problem beginning capture"); - - usleep_range(10000, 11000); /* delay for capture to finish */ - - return ret; -} - -static ssize_t adis16220_write_capture(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - bool val; - int ret; - - ret = strtobool(buf, &val); - if (ret) - return ret; - if (!val) - return -EINVAL; - ret = adis16220_capture(indio_dev); - if (ret) - return ret; - - return len; -} - -static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev, - char *buf, - loff_t off, - size_t count, - int addr) -{ - struct adis16220_state *st = iio_priv(indio_dev); - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .delay_usecs = 25, - }, { - .tx_buf = st->tx, - .rx_buf = st->rx, - .bits_per_word = 8, - .cs_change = 1, - .delay_usecs = 25, - }, - }; - int ret; - int i; - - if (unlikely(!count)) - return count; - - if ((off >= ADIS16220_CAPTURE_SIZE) || (count & 1) || (off & 1)) - return -EINVAL; - - if (off + count > ADIS16220_CAPTURE_SIZE) - count = ADIS16220_CAPTURE_SIZE - off; - - /* write the begin position of capture buffer */ - ret = adis_write_reg_16(&st->adis, - ADIS16220_CAPT_PNTR, - off > 1); - if (ret) - return -EIO; - - /* read count/2 values from capture buffer */ - mutex_lock(&st->buf_lock); - - for (i = 0; i < count; i += 2) { - st->tx[i] = ADIS_READ_REG(addr); - st->tx[i + 1] = 0; - } - xfers[1].len = count; - - ret = spi_sync_transfer(st->adis.spi, xfers, ARRAY_SIZE(xfers)); - if (ret) { - mutex_unlock(&st->buf_lock); - return -EIO; - } - - memcpy(buf, st->rx, count); - - mutex_unlock(&st->buf_lock); - return count; -} - -static ssize_t adis16220_accel_bin_read(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, - char *buf, - loff_t off, - size_t count) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(kobj_to_dev(kobj)); - - return adis16220_capture_buffer_read(indio_dev, buf, - off, count, - ADIS16220_CAPT_BUFA); -} - -static struct bin_attribute accel_bin = { - .attr = { - .name = "accel_bin", - .mode = S_IRUGO, - }, - .read = adis16220_accel_bin_read, - .size = ADIS16220_CAPTURE_SIZE, -}; - -static ssize_t adis16220_adc1_bin_read(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, - char *buf, loff_t off, - size_t count) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(kobj_to_dev(kobj)); - - return adis16220_capture_buffer_read(indio_dev, buf, - off, count, - ADIS16220_CAPT_BUF1); -} - -static struct bin_attribute adc1_bin = { - .attr = { - .name = "in0_bin", - .mode = S_IRUGO, - }, - .read = adis16220_adc1_bin_read, - .size = ADIS16220_CAPTURE_SIZE, -}; - -static ssize_t adis16220_adc2_bin_read(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, - char *buf, loff_t off, - size_t count) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(kobj_to_dev(kobj)); - - return adis16220_capture_buffer_read(indio_dev, buf, - off, count, - ADIS16220_CAPT_BUF2); -} - -static struct bin_attribute adc2_bin = { - .attr = { - .name = "in1_bin", - .mode = S_IRUGO, - }, - .read = adis16220_adc2_bin_read, - .size = ADIS16220_CAPTURE_SIZE, -}; - -#define IIO_DEV_ATTR_CAPTURE(_store) \ - IIO_DEVICE_ATTR(capture, S_IWUSR, NULL, _store, 0) - -static IIO_DEV_ATTR_CAPTURE(adis16220_write_capture); - -#define IIO_DEV_ATTR_CAPTURE_COUNT(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(capture_count, _mode, _show, _store, _addr) - -static IIO_DEV_ATTR_CAPTURE_COUNT(S_IWUSR | S_IRUGO, - adis16220_read_16bit, - adis16220_write_16bit, - ADIS16220_CAPT_PNTR); - -enum adis16220_channel { - in_supply, in_1, in_2, accel, temp -}; - -struct adis16220_address_spec { - u8 addr; - u8 bits; - bool sign; -}; - -/* Address / bits / signed */ -static const struct adis16220_address_spec adis16220_addresses[][3] = { - [in_supply] = { { ADIS16220_CAPT_SUPPLY, 12, 0 }, }, - [in_1] = { { ADIS16220_CAPT_BUF1, 16, 1 }, - { ADIS16220_AIN1_NULL, 16, 1 }, - { ADIS16220_CAPT_PEAK1, 16, 1 }, }, - [in_2] = { { ADIS16220_CAPT_BUF2, 16, 1 }, - { ADIS16220_AIN2_NULL, 16, 1 }, - { ADIS16220_CAPT_PEAK2, 16, 1 }, }, - [accel] = { { ADIS16220_CAPT_BUFA, 16, 1 }, - { ADIS16220_ACCL_NULL, 16, 1 }, - { ADIS16220_CAPT_PEAKA, 16, 1 }, }, - [temp] = { { ADIS16220_CAPT_TEMP, 12, 0 }, } -}; - -static int adis16220_read_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int *val, int *val2, - long mask) -{ - struct adis16220_state *st = iio_priv(indio_dev); - const struct adis16220_address_spec *addr; - int ret = -EINVAL; - int addrind = 0; - u16 uval; - s16 sval; - u8 bits; - - switch (mask) { - case IIO_CHAN_INFO_RAW: - addrind = 0; - break; - case IIO_CHAN_INFO_OFFSET: - if (chan->type == IIO_TEMP) { - *val = 25000 / -470 - 1278; /* 25 C = 1278 */ - return IIO_VAL_INT; - } - addrind = 1; - break; - case IIO_CHAN_INFO_PEAK: - addrind = 2; - break; - case IIO_CHAN_INFO_SCALE: - switch (chan->type) { - case IIO_TEMP: - *val = -470; /* -0.47 C */ - *val2 = 0; - return IIO_VAL_INT_PLUS_MICRO; - case IIO_ACCEL: - *val2 = IIO_G_TO_M_S_2(19073); /* 19.073 g */ - return IIO_VAL_INT_PLUS_MICRO; - case IIO_VOLTAGE: - if (chan->channel == 0) { - *val = 1; - *val2 = 220700; /* 1.2207 mV */ - } else { - /* Should really be dependent on VDD */ - *val2 = 305180; /* 305.18 uV */ - } - return IIO_VAL_INT_PLUS_MICRO; - default: - return -EINVAL; - } - default: - return -EINVAL; - } - addr = &adis16220_addresses[chan->address][addrind]; - if (addr->sign) { - ret = adis_read_reg_16(&st->adis, addr->addr, &sval); - if (ret) - return ret; - bits = addr->bits; - sval &= (1 << bits) - 1; - sval = (s16)(sval << (16 - bits)) >> (16 - bits); - *val = sval; - return IIO_VAL_INT; - } - ret = adis_read_reg_16(&st->adis, addr->addr, &uval); - if (ret) - return ret; - bits = addr->bits; - uval &= (1 << bits) - 1; - *val = uval; - return IIO_VAL_INT; -} - -static const struct iio_chan_spec adis16220_channels[] = { - { - .type = IIO_VOLTAGE, - .indexed = 1, - .channel = 0, - .extend_name = "supply", - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | - BIT(IIO_CHAN_INFO_SCALE), - .address = in_supply, - }, { - .type = IIO_ACCEL, - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | - BIT(IIO_CHAN_INFO_OFFSET) | - BIT(IIO_CHAN_INFO_SCALE) | - BIT(IIO_CHAN_INFO_PEAK), - .address = accel, - }, { - .type = IIO_TEMP, - .indexed = 1, - .channel = 0, - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | - BIT(IIO_CHAN_INFO_OFFSET) | - BIT(IIO_CHAN_INFO_SCALE), - .address = temp, - }, { - .type = IIO_VOLTAGE, - .indexed = 1, - .channel = 1, - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | - BIT(IIO_CHAN_INFO_OFFSET) | - BIT(IIO_CHAN_INFO_SCALE), - .address = in_1, - }, { - .type = IIO_VOLTAGE, - .indexed = 1, - .channel = 2, - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), - .address = in_2, - } -}; - -static struct attribute *adis16220_attributes[] = { - &iio_dev_attr_capture.dev_attr.attr, - &iio_dev_attr_capture_count.dev_attr.attr, - NULL -}; - -static const struct attribute_group adis16220_attribute_group = { - .attrs = adis16220_attributes, -}; - -static const struct iio_info adis16220_info = { - .attrs = &adis16220_attribute_group, - .driver_module = THIS_MODULE, - .read_raw = &adis16220_read_raw, -}; - -static const char * const adis16220_status_error_msgs[] = { - [ADIS16220_DIAG_STAT_VIOLATION_BIT] = "Capture period violation/interruption", - [ADIS16220_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure", - [ADIS16220_DIAG_STAT_FLASH_UPT_BIT] = "Flash update failed", - [ADIS16220_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V", - [ADIS16220_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 3.15V", -}; - -static const struct adis_data adis16220_data = { - .read_delay = 35, - .write_delay = 35, - .msc_ctrl_reg = ADIS16220_MSC_CTRL, - .glob_cmd_reg = ADIS16220_GLOB_CMD, - .diag_stat_reg = ADIS16220_DIAG_STAT, - - .self_test_mask = ADIS16220_MSC_CTRL_SELF_TEST_EN, - .startup_delay = ADIS16220_STARTUP_DELAY, - - .status_error_msgs = adis16220_status_error_msgs, - .status_error_mask = BIT(ADIS16220_DIAG_STAT_VIOLATION_BIT) | - BIT(ADIS16220_DIAG_STAT_SPI_FAIL_BIT) | - BIT(ADIS16220_DIAG_STAT_FLASH_UPT_BIT) | - BIT(ADIS16220_DIAG_STAT_POWER_HIGH_BIT) | - BIT(ADIS16220_DIAG_STAT_POWER_LOW_BIT), -}; - -static int adis16220_probe(struct spi_device *spi) -{ - int ret; - struct adis16220_state *st; - struct iio_dev *indio_dev; - - /* setup the industrialio driver allocated elements */ - indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); - if (!indio_dev) - return -ENOMEM; - - st = iio_priv(indio_dev); - /* this is only used for removal purposes */ - spi_set_drvdata(spi, indio_dev); - - indio_dev->name = spi->dev.driver->name; - indio_dev->dev.parent = &spi->dev; - indio_dev->info = &adis16220_info; - indio_dev->modes = INDIO_DIRECT_MODE; - indio_dev->channels = adis16220_channels; - indio_dev->num_channels = ARRAY_SIZE(adis16220_channels); - - ret = devm_iio_device_register(&spi->dev, indio_dev); - if (ret) - return ret; - - ret = sysfs_create_bin_file(&indio_dev->dev.kobj, &accel_bin); - if (ret) - return ret; - - ret = sysfs_create_bin_file(&indio_dev->dev.kobj, &adc1_bin); - if (ret) - goto error_rm_accel_bin; - - ret = sysfs_create_bin_file(&indio_dev->dev.kobj, &adc2_bin); - if (ret) - goto error_rm_adc1_bin; - - ret = adis_init(&st->adis, indio_dev, spi, &adis16220_data); - if (ret) - goto error_rm_adc2_bin; - /* Get the device into a sane initial state */ - ret = adis_initial_startup(&st->adis); - if (ret) - goto error_rm_adc2_bin; - return 0; - -error_rm_adc2_bin: - sysfs_remove_bin_file(&indio_dev->dev.kobj, &adc2_bin); -error_rm_adc1_bin: - sysfs_remove_bin_file(&indio_dev->dev.kobj, &adc1_bin); -error_rm_accel_bin: - sysfs_remove_bin_file(&indio_dev->dev.kobj, &accel_bin); - return ret; -} - -static int adis16220_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - - sysfs_remove_bin_file(&indio_dev->dev.kobj, &adc2_bin); - sysfs_remove_bin_file(&indio_dev->dev.kobj, &adc1_bin); - sysfs_remove_bin_file(&indio_dev->dev.kobj, &accel_bin); - - return 0; -} - -static struct spi_driver adis16220_driver = { - .driver = { - .name = "adis16220", - }, - .probe = adis16220_probe, - .remove = adis16220_remove, -}; -module_spi_driver(adis16220_driver); - -MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); -MODULE_DESCRIPTION("Analog Devices ADIS16220 Digital Vibration Sensor"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("spi:adis16220"); -- cgit v1.2.3 From dcb2e993f3c0cecc6c0d905cbf2e428640a957c1 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 9 Mar 2016 19:07:23 +0200 Subject: Revert "drm/i915: Enable PSR by default on Valleyview and Cherryview." MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit a38c274faad0ec6aba692e294ec751d04dbba803. PSR causes all sorts of vblank wait timeouts and whanot on CHV. Disable it again. Cc: Rodrigo Vivi Fixes: a38c274faad0 ("drm/i915: Enable PSR by default on Valleyview and Cherryview.") Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1457543247-13987-2-git-send-email-ville.syrjala@linux.intel.com Link: http://patchwork.freedesktop.org/patch/msgid/1457543247-13987-2-git-send-email-ville.syrjala@linux.intel.com Acked-by: Rodrigo Vivi Reviewed-by: Maarten Lankhorst --- drivers/gpu/drm/i915/intel_psr.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index b1413beb00d1..38e95185d9c6 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -781,8 +781,7 @@ void intel_psr_init(struct drm_device *dev) /* Per platform default */ if (i915.enable_psr == -1) { - if (IS_HASWELL(dev) || IS_BROADWELL(dev) || - IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) + if (IS_HASWELL(dev) || IS_BROADWELL(dev)) i915.enable_psr = 1; else i915.enable_psr = 0; -- cgit v1.2.3 From 9f6151c9039084e18c118831779a99ac8f29e39c Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 9 Mar 2016 19:07:24 +0200 Subject: drm/i915: Pass the correct crtc state to .update_plane() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pass the current crtc state, not the old crtc state, to the .update_plane() hook. Noticed on BSW when PRIMSIZE was getting programmed to a stale value which produced utter garbage on screen eg. wwhen going from 1920x1080 to 1024x768. Cc: Maarten Lankhorst Fixes: a758e6845825 ("drm/i915: Do not use commit_plane for sprite planes.") Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1457543247-13987-3-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Maarten Lankhorst --- drivers/gpu/drm/i915/intel_atomic_plane.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c index e0b851a0004a..7de7721f65bc 100644 --- a/drivers/gpu/drm/i915/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c @@ -195,12 +195,10 @@ static void intel_plane_atomic_update(struct drm_plane *plane, struct intel_plane_state *intel_state = to_intel_plane_state(plane->state); struct drm_crtc *crtc = plane->state->crtc ?: old_state->crtc; - struct drm_crtc_state *crtc_state = - drm_atomic_get_existing_crtc_state(old_state->state, crtc); if (intel_state->visible) intel_plane->update_plane(plane, - to_intel_crtc_state(crtc_state), + to_intel_crtc_state(crtc->state), intel_state); else intel_plane->disable_plane(plane, crtc); -- cgit v1.2.3 From caed361d83b204b7766924b80463bf7502ee7986 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 9 Mar 2016 19:07:25 +0200 Subject: drm/i915: Fix watermarks for VLV/CHV MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 92826fcdfc14 ("drm/i915: Calculate watermark related members in the crtc_state, v4.") broke thigns by removing the pre vs. post wm update distinction. We also lost the pre plane wm update entirely for VLV/CHV from the crtc enable path. This caused underruns on modeset and plane enable/disable on CHV, and often those can lead to a dead pipe. So let's bring back the pre vs. post thing, and let's toss in an explicit wm update to valleyview_crtc_enable() to avoid having to put it into the common code. This is more or less a partial revert of the offending commit. Cc: Maarten Lankhorst Cc: drm-intel-fixes@lists.freedesktop.org Fixes: 92826fcdfc14 ("drm/i915: Calculate watermark related members in the crtc_state, v4.") Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1457543247-13987-4-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Maarten Lankhorst --- drivers/gpu/drm/i915/intel_atomic.c | 3 ++- drivers/gpu/drm/i915/intel_display.c | 29 +++++++++++++++++++---------- drivers/gpu/drm/i915/intel_drv.h | 2 +- 3 files changed, 22 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c index 6a661e796328..79448f1c8b8d 100644 --- a/drivers/gpu/drm/i915/intel_atomic.c +++ b/drivers/gpu/drm/i915/intel_atomic.c @@ -96,7 +96,8 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc) crtc_state->update_pipe = false; crtc_state->disable_lp_wm = false; crtc_state->disable_cxsr = false; - crtc_state->wm_changed = false; + crtc_state->update_wm_pre = false; + crtc_state->update_wm_post = false; crtc_state->fb_changed = false; crtc_state->wm.need_postvbl_update = false; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 28556a800804..860c53063c9b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4677,7 +4677,7 @@ static void intel_post_plane_update(struct intel_crtc *crtc) crtc->wm.cxsr_allowed = true; - if (pipe_config->wm_changed && pipe_config->base.active) + if (pipe_config->update_wm_post && pipe_config->base.active) intel_update_watermarks(&crtc->base); if (atomic->update_fbc) @@ -4759,7 +4759,7 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state) */ if (dev_priv->display.initial_watermarks != NULL) dev_priv->display.initial_watermarks(pipe_config); - else if (pipe_config->wm_changed) + else if (pipe_config->update_wm_pre) intel_update_watermarks(&crtc->base); } @@ -6130,6 +6130,7 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) intel_crtc_load_lut(crtc); + intel_update_watermarks(crtc); intel_enable_pipe(intel_crtc); assert_vblank_disabled(crtc); @@ -11776,19 +11777,27 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state, plane->base.id, was_visible, visible, turn_off, turn_on, mode_changed); - if (turn_on || turn_off) { - pipe_config->wm_changed = true; + if (turn_on) { + pipe_config->update_wm_pre = true; + + /* must disable cxsr around plane enable/disable */ + if (plane->type != DRM_PLANE_TYPE_CURSOR) + pipe_config->disable_cxsr = true; + } else if (turn_off) { + pipe_config->update_wm_post = true; /* must disable cxsr around plane enable/disable */ if (plane->type != DRM_PLANE_TYPE_CURSOR) pipe_config->disable_cxsr = true; } else if (intel_wm_need_update(plane, plane_state)) { - pipe_config->wm_changed = true; + /* FIXME bollocks */ + pipe_config->update_wm_pre = true; + pipe_config->update_wm_post = true; } /* Pre-gen9 platforms need two-step watermark updates */ - if (pipe_config->wm_changed && INTEL_INFO(dev)->gen < 9 && - dev_priv->display.optimize_watermarks) + if ((pipe_config->update_wm_pre || pipe_config->update_wm_post) && + INTEL_INFO(dev)->gen < 9 && dev_priv->display.optimize_watermarks) to_intel_crtc_state(crtc_state)->wm.need_postvbl_update = true; if (visible || was_visible) @@ -11888,7 +11897,7 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc, } if (mode_changed && !crtc_state->active) - pipe_config->wm_changed = true; + pipe_config->update_wm_post = true; if (mode_changed && crtc_state->enable && dev_priv->display.crtc_compute_clock && @@ -13442,12 +13451,12 @@ static bool needs_vblank_wait(struct intel_crtc_state *crtc_state) return true; /* wm changes, need vblank before final wm's */ - if (crtc_state->wm_changed) + if (crtc_state->update_wm_post) return true; /* * cxsr is re-enabled after vblank. - * This is already handled by crtc_state->wm_changed, + * This is already handled by crtc_state->update_wm_post, * but added for clarity. */ if (crtc_state->disable_cxsr) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 1e3992889647..02b3d22862a1 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -420,7 +420,7 @@ struct intel_crtc_state { bool update_pipe; /* can a fast modeset be performed? */ bool disable_cxsr; - bool wm_changed; /* watermarks are updated */ + bool update_wm_pre, update_wm_post; /* watermarks are updated */ bool fb_changed; /* fb on any of the planes is changed */ /* Pipe source size (ie. panel fitter input size) -- cgit v1.2.3 From 2622a08108b07fdb6ad74c46fc05e445e8be94bf Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 9 Mar 2016 19:07:26 +0200 Subject: drm/i915: Wait for vblank after cxsr disable in pre_plane_update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We must wait for the hardware to exit cxsr before doing the plane update, so add the missing vblank wait to pre_plane_update after disabling cxsr. We have the wait for vblank in the pre_disable_primary hook, but not in the pre_plane_update hook. Just move the code from (and comment) from pre_disable_primary into pre_plane_update. Well, we still have to keep it in pre_disable_primary for these strange _noatomic codepaths, so let's do another version of pre_disable_primary for those. Also toss in some FIXMEs in the hope that someone will eventually clean up this pre_disable_primary mess. Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1457543247-13987-5-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Maarten Lankhorst --- drivers/gpu/drm/i915/intel_display.c | 59 ++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 860c53063c9b..6f8d7dd545b9 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -116,7 +116,7 @@ static void skylake_pfit_enable(struct intel_crtc *crtc); static void ironlake_pfit_disable(struct intel_crtc *crtc, bool force); static void ironlake_pfit_enable(struct intel_crtc *crtc); static void intel_modeset_setup_hw_state(struct drm_device *dev); -static void intel_pre_disable_primary(struct drm_crtc *crtc); +static void intel_pre_disable_primary_noatomic(struct drm_crtc *crtc); typedef struct { int min, max; @@ -2619,7 +2619,7 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc, */ to_intel_plane_state(plane_state)->visible = false; crtc_state->plane_mask &= ~(1 << drm_plane_index(primary)); - intel_pre_disable_primary(&intel_crtc->base); + intel_pre_disable_primary_noatomic(&intel_crtc->base); intel_plane->disable_plane(primary, &intel_crtc->base); return; @@ -4615,16 +4615,7 @@ intel_post_enable_primary(struct drm_crtc *crtc) intel_check_pch_fifo_underruns(dev_priv); } -/** - * intel_pre_disable_primary - Perform operations before disabling primary plane - * @crtc: the CRTC whose primary plane is to be disabled - * - * Performs potentially sleeping operations that must be done before the - * primary plane is disabled, such as updating FBC and IPS. Note that this may - * be called due to an explicit primary plane update, or due to an implicit - * disable that is caused when a sprite plane completely hides the primary - * plane. - */ +/* FIXME move all this to pre_plane_update() with proper state tracking */ static void intel_pre_disable_primary(struct drm_crtc *crtc) { @@ -4642,6 +4633,26 @@ intel_pre_disable_primary(struct drm_crtc *crtc) if (IS_GEN2(dev)) intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false); + /* + * FIXME IPS should be fine as long as one plane is + * enabled, but in practice it seems to have problems + * when going from primary only to sprite only and vice + * versa. + */ + hsw_disable_ips(intel_crtc); +} + +/* FIXME get rid of this and use pre_plane_update */ +static void +intel_pre_disable_primary_noatomic(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int pipe = intel_crtc->pipe; + + intel_pre_disable_primary(crtc); + /* * Vblank time updates from the shadow to live plane control register * are blocked if the memory self-refresh mode is active at that @@ -4656,14 +4667,6 @@ intel_pre_disable_primary(struct drm_crtc *crtc) dev_priv->wm.vlv.cxsr = false; intel_wait_for_vblank(dev, pipe); } - - /* - * FIXME IPS should be fine as long as one plane is - * enabled, but in practice it seems to have problems - * when going from primary only to sprite only and vice - * versa. - */ - hsw_disable_ips(intel_crtc); } static void intel_post_plane_update(struct intel_crtc *crtc) @@ -4720,8 +4723,20 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state) if (pipe_config->disable_cxsr) { crtc->wm.cxsr_allowed = false; - if (old_crtc_state->base.active) + /* + * Vblank time updates from the shadow to live plane control register + * are blocked if the memory self-refresh mode is active at that + * moment. So to make sure the plane gets truly disabled, disable + * first the self-refresh mode. The self-refresh enable bit in turn + * will be checked/applied by the HW only at the next frame start + * event which is after the vblank start event, so we need to have a + * wait-for-vblank between disabling the plane and the pipe. + */ + if (old_crtc_state->base.active) { intel_set_memory_cxsr(dev_priv, false); + dev_priv->wm.vlv.cxsr = false; + intel_wait_for_vblank(dev, crtc->pipe); + } } /* @@ -6269,7 +6284,7 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc) if (to_intel_plane_state(crtc->primary->state)->visible) { WARN_ON(intel_crtc->unpin_work); - intel_pre_disable_primary(crtc); + intel_pre_disable_primary_noatomic(crtc); intel_crtc_disable_planes(crtc, 1 << drm_plane_index(crtc->primary)); to_intel_plane_state(crtc->primary->state)->visible = false; -- cgit v1.2.3 From 29ceb0e6c896f9476c681bb15dd0763f2137c0f4 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 9 Mar 2016 19:07:27 +0200 Subject: drm/i915: s/crtc_state/old_crtc_state/ in intel_atomic_commit() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoid some head spinning by renaming the crtc_state variable to old_crtc_state. Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1457543247-13987-6-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Maarten Lankhorst --- drivers/gpu/drm/i915/intel_display.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 6f8d7dd545b9..46a697cd567e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13502,7 +13502,7 @@ static int intel_atomic_commit(struct drm_device *dev, { struct intel_atomic_state *intel_state = to_intel_atomic_state(state); struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_crtc_state *crtc_state; + struct drm_crtc_state *old_crtc_state; struct drm_crtc *crtc; struct intel_crtc_state *intel_cstate; int ret = 0, i; @@ -13528,7 +13528,7 @@ static int intel_atomic_commit(struct drm_device *dev, intel_display_power_get(dev_priv, POWER_DOMAIN_MODESET); } - for_each_crtc_in_state(state, crtc, crtc_state, i) { + for_each_crtc_in_state(state, crtc, old_crtc_state, i) { struct intel_crtc *intel_crtc = to_intel_crtc(crtc); if (needs_modeset(crtc->state) || @@ -13543,10 +13543,10 @@ static int intel_atomic_commit(struct drm_device *dev, if (!needs_modeset(crtc->state)) continue; - intel_pre_plane_update(to_intel_crtc_state(crtc_state)); + intel_pre_plane_update(to_intel_crtc_state(old_crtc_state)); - if (crtc_state->active) { - intel_crtc_disable_planes(crtc, crtc_state->plane_mask); + if (old_crtc_state->active) { + intel_crtc_disable_planes(crtc, old_crtc_state->plane_mask); dev_priv->display.crtc_disable(crtc); intel_crtc->active = false; intel_fbc_disable(intel_crtc); @@ -13579,7 +13579,7 @@ static int intel_atomic_commit(struct drm_device *dev, } /* Now enable the clocks, plane, pipe, and connectors that we set up. */ - for_each_crtc_in_state(state, crtc, crtc_state, i) { + for_each_crtc_in_state(state, crtc, old_crtc_state, i) { struct intel_crtc *intel_crtc = to_intel_crtc(crtc); bool modeset = needs_modeset(crtc->state); struct intel_crtc_state *pipe_config = @@ -13592,14 +13592,14 @@ static int intel_atomic_commit(struct drm_device *dev, } if (!modeset) - intel_pre_plane_update(to_intel_crtc_state(crtc_state)); + intel_pre_plane_update(to_intel_crtc_state(old_crtc_state)); if (crtc->state->active && intel_crtc->atomic.update_fbc) intel_fbc_enable(intel_crtc); if (crtc->state->active && (crtc->state->planes_changed || update_pipe)) - drm_atomic_helper_commit_planes_on_crtc(crtc_state); + drm_atomic_helper_commit_planes_on_crtc(old_crtc_state); if (pipe_config->base.active && needs_vblank_wait(pipe_config)) crtc_vblank_mask |= 1 << i; @@ -13610,7 +13610,7 @@ static int intel_atomic_commit(struct drm_device *dev, if (!state->legacy_cursor_update) intel_atomic_wait_for_vblanks(dev, dev_priv, crtc_vblank_mask); - for_each_crtc_in_state(state, crtc, crtc_state, i) { + for_each_crtc_in_state(state, crtc, old_crtc_state, i) { intel_post_plane_update(to_intel_crtc(crtc)); if (put_domains[i]) @@ -13627,7 +13627,7 @@ static int intel_atomic_commit(struct drm_device *dev, * * TODO: Move this (and other cleanup) to an async worker eventually. */ - for_each_crtc_in_state(state, crtc, crtc_state, i) { + for_each_crtc_in_state(state, crtc, old_crtc_state, i) { intel_cstate = to_intel_crtc_state(crtc->state); if (dev_priv->display.optimize_watermarks) -- cgit v1.2.3 From 842e03076ffb655e35c72f6c95fe216cc856f42b Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Wed, 2 Mar 2016 15:48:01 +0100 Subject: drm/i915: Update state before setting watermarks, v2. When intel_update_watermarks is called on skylake from the hw state readout disable function it calls intel_update_watermarks. intel_update_watermarks inspects crtc->state, which should be set to disabled. This wasn't the case, and this resulted in a divide-by-zero in skl_update_wm when intel_update_watermarks got called. ------------[ cut here ]------------ WARNING: CPU: 1 PID: 295 at drivers/gpu/drm/i915/intel_pm.c:2834 skl_update_pipe_wm+0x102/0x8c0 [i915]() WARN_ON(!config->num_pipes_active) Modules linked in: coretemp i915(+) xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx CPU: 1 PID: 295 Comm: systemd-udevd Tainted: G U W 4.5.0-rc4 -xxxxxx #25 Hardware name: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 0000000000000000 ffff88003777f5a8 ffffffff813485c2 ffff88003777f5f0 ffffffffa0236240 ffff88003777f5e0 ffffffff81050fce ffff8800aa420000 ffff8800aba18000 ffff8800aba18000 ffff880037304c00 ffff8800aa420000 Call Trace: [] dump_stack+0x67/0x95 [] warn_slowpath_common+0x9e/0xc0 [] warn_slowpath_fmt+0x4c/0x50 [] ? flush_work+0x8e/0x280 [] ? flush_work+0x5/0x280 [] skl_update_pipe_wm+0x102/0x8c0 [i915] [] skl_update_wm+0xff/0x5f0 [i915] [] ? trace_hardirqs_on_caller+0x15e/0x1d0 [] ? trace_hardirqs_on+0xd/0x10 [] intel_update_watermarks+0x1e/0x30 [i915] [] intel_crtc_disable_noatomic+0xd2/0x150 [i915] [] intel_modeset_setup_hw_state+0xdd2/0xde0 [i915] [] intel_modeset_init+0x15a3/0x1950 [i915] [] i915_driver_load+0x13c6/0x1720 [i915] [] ? add_sysfs_fw_map_entry+0x9b/0x9b [] drm_dev_register+0x6f/0xb0 [drm] [] drm_get_pci_dev+0x10a/0x1d0 [drm] [] i915_pci_probe+0x49/0x50 [i915] [] pci_device_probe+0x80/0xf0 [] driver_probe_device+0x1bc/0x3d0 [] __driver_attach+0x66/0x90 [] ? driver_probe_device+0x3d0/0x3d0 [] bus_for_each_dev+0x5b/0xa0 [] driver_attach+0x1e/0x20 [] bus_add_driver+0x151/0x270 [] driver_register+0x8c/0xd0 [] __pci_register_driver+0x5d/0x60 [] drm_pci_init+0x58/0xf0 [drm] [] ? trace_hardirqs_on+0xd/0x10 [] ? 0xffffffffa02aa000 [] i915_init+0x94/0x9b [i915] [] do_one_initcall+0x113/0x1f0 [] ? rcu_read_lock_sched_held+0x61/0x90 [] ? kmem_cache_alloc_trace+0x1cc/0x280 [] do_init_module+0x60/0x1c8 [] load_module+0x1ceb/0x2410 [] ? store_uevent+0x40/0x40 [] ? kernel_read+0x41/0x60 [] SYSC_finit_module+0x8d/0xa0 [] SyS_finit_module+0xe/0x10 [] entry_SYSCALL_64_fastpath+0x12/0x6f ---[ end trace 1149e9ab3695a423 ]--- ------------[ cut here ]------------ Changes since v1: - Clear state before calling any function after .crtc_disable. Reported-by: Tvrtko Ursulin Signed-off-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/56D6FD21.7020907@linux.intel.com Tested-by: Tvrtko Ursulin Reviewed-by: Ander Conselvan de Oliveira --- drivers/gpu/drm/i915/intel_display.c | 45 ++++++++++++------------------------ 1 file changed, 15 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 46a697cd567e..ce55f0b683c6 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6273,6 +6273,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) static void intel_crtc_disable_noatomic(struct drm_crtc *crtc) { + struct intel_encoder *encoder; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct drm_i915_private *dev_priv = to_i915(crtc->dev); enum intel_display_power_domain domain; @@ -6291,7 +6292,20 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc) } dev_priv->display.crtc_disable(crtc); + + DRM_DEBUG_KMS("[CRTC:%d] hw state adjusted, was enabled, now disabled\n", + crtc->base.id); + + WARN_ON(drm_atomic_set_mode_for_crtc(crtc->state, NULL) < 0); + crtc->state->active = false; intel_crtc->active = false; + crtc->enabled = false; + crtc->state->connector_mask = 0; + crtc->state->encoder_mask = 0; + + for_each_encoder_on_crtc(crtc->dev, crtc, encoder) + encoder->base.crtc = NULL; + intel_fbc_disable(intel_crtc); intel_update_watermarks(crtc); intel_disable_shared_dpll(intel_crtc); @@ -15513,38 +15527,9 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc) /* Adjust the state of the output pipe according to whether we * have active connectors/encoders. */ - if (!intel_crtc_has_encoders(crtc)) + if (crtc->active && !intel_crtc_has_encoders(crtc)) intel_crtc_disable_noatomic(&crtc->base); - if (crtc->active != crtc->base.state->active) { - struct intel_encoder *encoder; - - /* This can happen either due to bugs in the get_hw_state - * functions or because of calls to intel_crtc_disable_noatomic, - * or because the pipe is force-enabled due to the - * pipe A quirk. */ - DRM_DEBUG_KMS("[CRTC:%d] hw state adjusted, was %s, now %s\n", - crtc->base.base.id, - crtc->base.state->enable ? "enabled" : "disabled", - crtc->active ? "enabled" : "disabled"); - - WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, NULL) < 0); - crtc->base.state->active = crtc->active; - crtc->base.enabled = crtc->active; - crtc->base.state->connector_mask = 0; - crtc->base.state->encoder_mask = 0; - - /* Because we only establish the connector -> encoder -> - * crtc links if something is active, this means the - * crtc is now deactivated. Break the links. connector - * -> encoder links are only establish when things are - * actually up, hence no need to break them. */ - WARN_ON(crtc->active); - - for_each_encoder_on_crtc(dev, &crtc->base, encoder) - encoder->base.crtc = NULL; - } - if (crtc->active || HAS_GMCH_DISPLAY(dev)) { /* * We start out with underrun reporting disabled to avoid races. -- cgit v1.2.3 From 1e52fefc9b0c481f8ca860e19781720fb5404383 Mon Sep 17 00:00:00 2001 From: Tiberiu Breana Date: Wed, 9 Mar 2016 14:06:14 +0200 Subject: iio: accel: Add support for the h3lis331dl accelerometer This commit adds support for STMicroelectronics h3lis331dl high-g accelerometer. The datasheet for this device can be found here: http://www.st.com/web/en/resource/technical/document/ datasheet/DM00053090.pdf Signed-off-by: Tiberiu Breana Reviewed-by: Denis Ciocca Acked-by: Denis Ciocca Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/st-sensors.txt | 1 + drivers/iio/accel/Kconfig | 2 +- drivers/iio/accel/st_accel.h | 1 + drivers/iio/accel/st_accel_core.c | 92 ++++++++++++++++++++++ drivers/iio/accel/st_accel_i2c.c | 4 + 5 files changed, 99 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/iio/st-sensors.txt b/Documentation/devicetree/bindings/iio/st-sensors.txt index d4b87cc1e446..71b7bdff21cd 100644 --- a/Documentation/devicetree/bindings/iio/st-sensors.txt +++ b/Documentation/devicetree/bindings/iio/st-sensors.txt @@ -37,6 +37,7 @@ Accelerometers: - st,lsm330-accel - st,lsm303agr-accel - st,lis2dh12-accel +- st,h3lis331dl-accel Gyroscopes: - st,l3g4200d-gyro diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig index b0d3ecf3318b..7636eec63ea5 100644 --- a/drivers/iio/accel/Kconfig +++ b/drivers/iio/accel/Kconfig @@ -64,7 +64,7 @@ config IIO_ST_ACCEL_3AXIS help Say yes here to build support for STMicroelectronics accelerometers: LSM303DLH, LSM303DLHC, LIS3DH, LSM330D, LSM330DL, LSM330DLC, - LIS331DLH, LSM303DL, LSM303DLM, LSM330, LIS2DH12. + LIS331DLH, LSM303DL, LSM303DLM, LSM330, LIS2DH12, H3LIS331DL. This driver can also be built as a module. If so, these modules will be created: diff --git a/drivers/iio/accel/st_accel.h b/drivers/iio/accel/st_accel.h index 5d4a1897b293..57f83a67948c 100644 --- a/drivers/iio/accel/st_accel.h +++ b/drivers/iio/accel/st_accel.h @@ -14,6 +14,7 @@ #include #include +#define H3LIS331DL_DRIVER_NAME "h3lis331dl_accel" #define LIS3LV02DL_ACCEL_DEV_NAME "lis3lv02dl_accel" #define LSM303DLHC_ACCEL_DEV_NAME "lsm303dlhc_accel" #define LIS3DH_ACCEL_DEV_NAME "lis3dh" diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c index a03a1417dd63..fee32e3d7a05 100644 --- a/drivers/iio/accel/st_accel_core.c +++ b/drivers/iio/accel/st_accel_core.c @@ -39,6 +39,9 @@ #define ST_ACCEL_FS_AVL_6G 6 #define ST_ACCEL_FS_AVL_8G 8 #define ST_ACCEL_FS_AVL_16G 16 +#define ST_ACCEL_FS_AVL_100G 100 +#define ST_ACCEL_FS_AVL_200G 200 +#define ST_ACCEL_FS_AVL_400G 400 /* CUSTOM VALUES FOR SENSOR 1 */ #define ST_ACCEL_1_WAI_EXP 0x33 @@ -181,6 +184,33 @@ #define ST_ACCEL_5_IG1_EN_MASK 0x08 #define ST_ACCEL_5_MULTIREAD_BIT false +/* CUSTOM VALUES FOR SENSOR 6 */ +#define ST_ACCEL_6_WAI_EXP 0x32 +#define ST_ACCEL_6_ODR_ADDR 0x20 +#define ST_ACCEL_6_ODR_MASK 0x18 +#define ST_ACCEL_6_ODR_AVL_50HZ_VAL 0x00 +#define ST_ACCEL_6_ODR_AVL_100HZ_VAL 0x01 +#define ST_ACCEL_6_ODR_AVL_400HZ_VAL 0x02 +#define ST_ACCEL_6_ODR_AVL_1000HZ_VAL 0x03 +#define ST_ACCEL_6_PW_ADDR 0x20 +#define ST_ACCEL_6_PW_MASK 0x20 +#define ST_ACCEL_6_FS_ADDR 0x23 +#define ST_ACCEL_6_FS_MASK 0x30 +#define ST_ACCEL_6_FS_AVL_100_VAL 0x00 +#define ST_ACCEL_6_FS_AVL_200_VAL 0x01 +#define ST_ACCEL_6_FS_AVL_400_VAL 0x03 +#define ST_ACCEL_6_FS_AVL_100_GAIN IIO_G_TO_M_S_2(49000) +#define ST_ACCEL_6_FS_AVL_200_GAIN IIO_G_TO_M_S_2(98000) +#define ST_ACCEL_6_FS_AVL_400_GAIN IIO_G_TO_M_S_2(195000) +#define ST_ACCEL_6_BDU_ADDR 0x23 +#define ST_ACCEL_6_BDU_MASK 0x80 +#define ST_ACCEL_6_DRDY_IRQ_ADDR 0x22 +#define ST_ACCEL_6_DRDY_IRQ_INT1_MASK 0x02 +#define ST_ACCEL_6_DRDY_IRQ_INT2_MASK 0x10 +#define ST_ACCEL_6_IHL_IRQ_ADDR 0x22 +#define ST_ACCEL_6_IHL_IRQ_MASK 0x80 +#define ST_ACCEL_6_MULTIREAD_BIT true + static const struct iio_chan_spec st_accel_8bit_channels[] = { ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), @@ -557,6 +587,68 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = { .multi_read_bit = ST_ACCEL_5_MULTIREAD_BIT, .bootime = 2, /* guess */ }, + { + .wai = ST_ACCEL_6_WAI_EXP, + .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS, + .sensors_supported = { + [0] = H3LIS331DL_DRIVER_NAME, + }, + .ch = (struct iio_chan_spec *)st_accel_12bit_channels, + .odr = { + .addr = ST_ACCEL_6_ODR_ADDR, + .mask = ST_ACCEL_6_ODR_MASK, + .odr_avl = { + { 50, ST_ACCEL_6_ODR_AVL_50HZ_VAL }, + { 100, ST_ACCEL_6_ODR_AVL_100HZ_VAL, }, + { 400, ST_ACCEL_6_ODR_AVL_400HZ_VAL, }, + { 1000, ST_ACCEL_6_ODR_AVL_1000HZ_VAL, }, + }, + }, + .pw = { + .addr = ST_ACCEL_6_PW_ADDR, + .mask = ST_ACCEL_6_PW_MASK, + .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE, + .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE, + }, + .enable_axis = { + .addr = ST_SENSORS_DEFAULT_AXIS_ADDR, + .mask = ST_SENSORS_DEFAULT_AXIS_MASK, + }, + .fs = { + .addr = ST_ACCEL_6_FS_ADDR, + .mask = ST_ACCEL_6_FS_MASK, + .fs_avl = { + [0] = { + .num = ST_ACCEL_FS_AVL_100G, + .value = ST_ACCEL_6_FS_AVL_100_VAL, + .gain = ST_ACCEL_6_FS_AVL_100_GAIN, + }, + [1] = { + .num = ST_ACCEL_FS_AVL_200G, + .value = ST_ACCEL_6_FS_AVL_200_VAL, + .gain = ST_ACCEL_6_FS_AVL_200_GAIN, + }, + [2] = { + .num = ST_ACCEL_FS_AVL_400G, + .value = ST_ACCEL_6_FS_AVL_400_VAL, + .gain = ST_ACCEL_6_FS_AVL_400_GAIN, + }, + }, + }, + .bdu = { + .addr = ST_ACCEL_6_BDU_ADDR, + .mask = ST_ACCEL_6_BDU_MASK, + }, + .drdy_irq = { + .addr = ST_ACCEL_6_DRDY_IRQ_ADDR, + .mask_int1 = ST_ACCEL_6_DRDY_IRQ_INT1_MASK, + .mask_int2 = ST_ACCEL_6_DRDY_IRQ_INT2_MASK, + .addr_ihl = ST_ACCEL_6_IHL_IRQ_ADDR, + .mask_ihl = ST_ACCEL_6_IHL_IRQ_MASK, + }, + .multi_read_bit = ST_ACCEL_6_MULTIREAD_BIT, + .bootime = 2, + }, }; static int st_accel_read_raw(struct iio_dev *indio_dev, diff --git a/drivers/iio/accel/st_accel_i2c.c b/drivers/iio/accel/st_accel_i2c.c index 294a32f89367..7333ee9fb11b 100644 --- a/drivers/iio/accel/st_accel_i2c.c +++ b/drivers/iio/accel/st_accel_i2c.c @@ -76,6 +76,10 @@ static const struct of_device_id st_accel_of_match[] = { .compatible = "st,lis2dh12-accel", .data = LIS2DH12_ACCEL_DEV_NAME, }, + { + .compatible = "st,h3lis331dl-accel", + .data = H3LIS331DL_DRIVER_NAME, + }, {}, }; MODULE_DEVICE_TABLE(of, st_accel_of_match); -- cgit v1.2.3 From e8731180fbf6fd45351b587d67cdc0685ce99a7a Mon Sep 17 00:00:00 2001 From: Martin Kepplinger Date: Wed, 9 Mar 2016 12:01:29 +0100 Subject: iio: mma8452: add support for FXLS8471Q This adds support for Freescale's (now NXP's) FXLS8471Q accelerometer. We use MMA8451Q's configuration because for what the driver supports, FXLS8471Q is the same. Support for FXLS8471Q's features (fast SPI interface and a larger FIFO, among others) can be added to this driver anytime. See it's datasheet for the details: http://cache.nxp.com/files/sensors/doc/data_sheet/FXLS8471Q.pdf Signed-off-by: Martin Kepplinger Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/accel/mma8452.txt | 3 ++- drivers/iio/accel/Kconfig | 3 ++- drivers/iio/accel/mma8452.c | 22 ++++++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/iio/accel/mma8452.txt b/Documentation/devicetree/bindings/iio/accel/mma8452.txt index 165937e1ac1c..45f5c5c5929c 100644 --- a/Documentation/devicetree/bindings/iio/accel/mma8452.txt +++ b/Documentation/devicetree/bindings/iio/accel/mma8452.txt @@ -1,4 +1,4 @@ -Freescale MMA8451Q, MMA8452Q, MMA8453Q, MMA8652FC or MMA8653FC +Freescale MMA8451Q, MMA8452Q, MMA8453Q, MMA8652FC, MMA8653FC or FXLS8471Q triaxial accelerometer Required properties: @@ -9,6 +9,7 @@ Required properties: * "fsl,mma8453" * "fsl,mma8652" * "fsl,mma8653" + * "fsl,fxls8471" - reg: the I2C address of the chip diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig index 7636eec63ea5..e4a758cd7d35 100644 --- a/drivers/iio/accel/Kconfig +++ b/drivers/iio/accel/Kconfig @@ -143,7 +143,8 @@ config MMA8452 select IIO_TRIGGERED_BUFFER help Say yes here to build support for the following Freescale 3-axis - accelerometers: MMA8451Q, MMA8452Q, MMA8453Q, MMA8652FC, MMA8653FC. + accelerometers: MMA8451Q, MMA8452Q, MMA8453Q, MMA8652FC, MMA8653FC, + FXLS8471Q. To compile this driver as a module, choose M here: the module will be called mma8452. diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c index 5ca0d169f912..305ed0e37dfb 100644 --- a/drivers/iio/accel/mma8452.c +++ b/drivers/iio/accel/mma8452.c @@ -6,6 +6,7 @@ * MMA8453Q (10 bit) * MMA8652FC (12 bit) * MMA8653FC (10 bit) + * FXLS8471Q (14 bit) * * Copyright 2015 Martin Kepplinger * Copyright 2014 Peter Meerwald @@ -92,6 +93,7 @@ #define MMA8453_DEVICE_ID 0x3a #define MMA8652_DEVICE_ID 0x4a #define MMA8653_DEVICE_ID 0x5a +#define FXLS8471_DEVICE_ID 0x6a #define MMA8452_AUTO_SUSPEND_DELAY_MS 2000 @@ -1055,6 +1057,7 @@ enum { mma8453, mma8652, mma8653, + fxls8471, }; static const struct mma_chip_info mma_chip_info_table[] = { @@ -1146,6 +1149,22 @@ static const struct mma_chip_info mma_chip_info_table[] = { .ev_ths_mask = MMA8452_FF_MT_THS_MASK, .ev_count = MMA8452_FF_MT_COUNT, }, + [fxls8471] = { + .chip_id = FXLS8471_DEVICE_ID, + .channels = mma8451_channels, + .num_channels = ARRAY_SIZE(mma8451_channels), + .mma_scales = { {0, 2394}, {0, 4788}, {0, 9577} }, + .ev_cfg = MMA8452_TRANSIENT_CFG, + .ev_cfg_ele = MMA8452_TRANSIENT_CFG_ELE, + .ev_cfg_chan_shift = 1, + .ev_src = MMA8452_TRANSIENT_SRC, + .ev_src_xe = MMA8452_TRANSIENT_SRC_XTRANSE, + .ev_src_ye = MMA8452_TRANSIENT_SRC_YTRANSE, + .ev_src_ze = MMA8452_TRANSIENT_SRC_ZTRANSE, + .ev_ths = MMA8452_TRANSIENT_THS, + .ev_ths_mask = MMA8452_TRANSIENT_THS_MASK, + .ev_count = MMA8452_TRANSIENT_COUNT, + }, }; static struct attribute *mma8452_attributes[] = { @@ -1275,6 +1294,7 @@ static const struct of_device_id mma8452_dt_ids[] = { { .compatible = "fsl,mma8453", .data = &mma_chip_info_table[mma8453] }, { .compatible = "fsl,mma8652", .data = &mma_chip_info_table[mma8652] }, { .compatible = "fsl,mma8653", .data = &mma_chip_info_table[mma8653] }, + { .compatible = "fsl,fxls8471", .data = &mma_chip_info_table[fxls8471] }, { } }; MODULE_DEVICE_TABLE(of, mma8452_dt_ids); @@ -1312,6 +1332,7 @@ static int mma8452_probe(struct i2c_client *client, case MMA8453_DEVICE_ID: case MMA8652_DEVICE_ID: case MMA8653_DEVICE_ID: + case FXLS8471_DEVICE_ID: if (ret == data->chip_info->chip_id) break; default: @@ -1518,6 +1539,7 @@ static const struct i2c_device_id mma8452_id[] = { { "mma8453", mma8453 }, { "mma8652", mma8652 }, { "mma8653", mma8653 }, + { "fxls8471", fxls8471 }, { } }; MODULE_DEVICE_TABLE(i2c, mma8452_id); -- cgit v1.2.3 From 08a33805518e7845486f88287e8aace6f8439391 Mon Sep 17 00:00:00 2001 From: Alison Schofield Date: Wed, 9 Mar 2016 11:30:12 -0800 Subject: iio: core: implement iio_device_{claim|release}_direct_mode() It is often the case that the driver wants to be sure a device stays in direct mode while it is executing a task or series of tasks. To accomplish this today, the driver performs this sequence: 1) take the device state lock, 2) verify it is not in a buffered mode, 3) execute some tasks, and 4) release that lock. This patch introduces a pair of helper functions that simplify these steps and make it more semantically expressive. iio_device_claim_direct_mode() If the device is not in any buffered mode it is guaranteed to stay that way until iio_release_direct_mode() is called. iio_device_release_direct_mode() Release the claim. Device is no longer guaranteed to stay in direct mode. Signed-off-by: Alison Schofield Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-core.c | 39 +++++++++++++++++++++++++++++++++++++++ include/linux/iio/iio.h | 2 ++ 2 files changed, 41 insertions(+) (limited to 'drivers') diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 70cb7eb0a75c..2e768bc99f05 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include "iio_core.h" #include "iio_core_trigger.h" @@ -1375,6 +1376,44 @@ void devm_iio_device_unregister(struct device *dev, struct iio_dev *indio_dev) } EXPORT_SYMBOL_GPL(devm_iio_device_unregister); +/** + * iio_device_claim_direct_mode - Keep device in direct mode + * @indio_dev: the iio_dev associated with the device + * + * If the device is in direct mode it is guaranteed to stay + * that way until iio_device_release_direct_mode() is called. + * + * Use with iio_device_release_direct_mode() + * + * Returns: 0 on success, -EBUSY on failure + */ +int iio_device_claim_direct_mode(struct iio_dev *indio_dev) +{ + mutex_lock(&indio_dev->mlock); + + if (iio_buffer_enabled(indio_dev)) { + mutex_unlock(&indio_dev->mlock); + return -EBUSY; + } + return 0; +} +EXPORT_SYMBOL_GPL(iio_device_claim_direct_mode); + +/** + * iio_device_release_direct_mode - releases claim on direct mode + * @indio_dev: the iio_dev associated with the device + * + * Release the claim. Device is no longer guaranteed to stay + * in direct mode. + * + * Use with iio_device_claim_direct_mode() + */ +void iio_device_release_direct_mode(struct iio_dev *indio_dev) +{ + mutex_unlock(&indio_dev->mlock); +} +EXPORT_SYMBOL_GPL(iio_device_release_direct_mode); + subsys_initcall(iio_init); module_exit(iio_exit); diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index b2b16772c651..0b2773ada0ba 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -527,6 +527,8 @@ void iio_device_unregister(struct iio_dev *indio_dev); int devm_iio_device_register(struct device *dev, struct iio_dev *indio_dev); void devm_iio_device_unregister(struct device *dev, struct iio_dev *indio_dev); int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp); +int iio_device_claim_direct_mode(struct iio_dev *indio_dev); +void iio_device_release_direct_mode(struct iio_dev *indio_dev); extern struct bus_type iio_bus_type; -- cgit v1.2.3 From 1c118b7230a16cb627061de9bd548ed7fdbdad24 Mon Sep 17 00:00:00 2001 From: Alison Schofield Date: Wed, 9 Mar 2016 11:30:43 -0800 Subject: staging: iio: ad7192: use iio_device_{claim|release}_direct_mode() Replace the code that guarantees the device stays in direct mode with iio_device_{claim|release}_direct_mode() which does same. Signed-off-by: Alison Schofield Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/ad7192.c | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index f843f19cf675..15d965c089ff 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c @@ -349,11 +349,9 @@ static ssize_t ad7192_write_frequency(struct device *dev, if (lval == 0) return -EINVAL; - mutex_lock(&indio_dev->mlock); - if (iio_buffer_enabled(indio_dev)) { - mutex_unlock(&indio_dev->mlock); - return -EBUSY; - } + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; div = st->mclk / (lval * st->f_order * 1024); if (div < 1 || div > 1023) { @@ -366,7 +364,7 @@ static ssize_t ad7192_write_frequency(struct device *dev, ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode); out: - mutex_unlock(&indio_dev->mlock); + iio_device_release_direct_mode(indio_dev); return ret ? ret : len; } @@ -434,11 +432,9 @@ static ssize_t ad7192_set(struct device *dev, if (ret < 0) return ret; - mutex_lock(&indio_dev->mlock); - if (iio_buffer_enabled(indio_dev)) { - mutex_unlock(&indio_dev->mlock); - return -EBUSY; - } + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; switch ((u32)this_attr->address) { case AD7192_REG_GPOCON: @@ -461,7 +457,7 @@ static ssize_t ad7192_set(struct device *dev, ret = -EINVAL; } - mutex_unlock(&indio_dev->mlock); + iio_device_release_direct_mode(indio_dev); return ret ? ret : len; } @@ -555,11 +551,9 @@ static int ad7192_write_raw(struct iio_dev *indio_dev, int ret, i; unsigned int tmp; - mutex_lock(&indio_dev->mlock); - if (iio_buffer_enabled(indio_dev)) { - mutex_unlock(&indio_dev->mlock); - return -EBUSY; - } + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; switch (mask) { case IIO_CHAN_INFO_SCALE: @@ -582,7 +576,7 @@ static int ad7192_write_raw(struct iio_dev *indio_dev, ret = -EINVAL; } - mutex_unlock(&indio_dev->mlock); + iio_device_release_direct_mode(indio_dev); return ret; } -- cgit v1.2.3 From a583c24deefdaaaf5bd96a1117b850904a294804 Mon Sep 17 00:00:00 2001 From: Joachim Eastwood Date: Sat, 12 Mar 2016 13:30:14 +0100 Subject: iio: adc: add NXP LPC18xx ADC driver Add base support for the 10-bit SAR ADC peripheral found on NXP LPC18xx/43xx SoCs. This is a minimal driver that does not support burst mode, interrupts, DMA or hardware triggers. User manual with register description can be found on: LPC18xx: www.nxp.com/documents/user_manual/UM10430.pdf LPC43xx: www.nxp.com/documents/user_manual/UM10503.pdf Signed-off-by: Joachim Eastwood Signed-off-by: Jonathan Cameron --- drivers/iio/adc/Kconfig | 10 ++ drivers/iio/adc/Makefile | 1 + drivers/iio/adc/lpc18xx_adc.c | 231 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 242 insertions(+) create mode 100644 drivers/iio/adc/lpc18xx_adc.c (limited to 'drivers') diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index a8819a08a828..9ddcd5db039b 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -235,6 +235,16 @@ config LP8788_ADC To compile this driver as a module, choose M here: the module will be called lp8788_adc. +config LPC18XX_ADC + tristate "NXP LPC18xx ADC driver" + depends on ARCH_LPC18XX || COMPILE_TEST + depends on OF && HAS_IOMEM + help + Say yes here to build support for NXP LPC18XX ADC. + + To compile this driver as a module, choose M here: the module will be + called lpc18xx_adc. + config MAX1027 tristate "Maxim max1027 ADC driver" depends on SPI diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index b1aa456e6af3..1a4ac4590857 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_HI8435) += hi8435.o obj-$(CONFIG_IMX7D_ADC) += imx7d_adc.o obj-$(CONFIG_INA2XX_ADC) += ina2xx-adc.o obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o +obj-$(CONFIG_LPC18XX_ADC) += lpc18xx_adc.o obj-$(CONFIG_MAX1027) += max1027.o obj-$(CONFIG_MAX1363) += max1363.o obj-$(CONFIG_MCP320X) += mcp320x.o diff --git a/drivers/iio/adc/lpc18xx_adc.c b/drivers/iio/adc/lpc18xx_adc.c new file mode 100644 index 000000000000..3ef18f4b27f0 --- /dev/null +++ b/drivers/iio/adc/lpc18xx_adc.c @@ -0,0 +1,231 @@ +/* + * IIO ADC driver for NXP LPC18xx ADC + * + * Copyright (C) 2016 Joachim Eastwood + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * UNSUPPORTED hardware features: + * - Hardware triggers + * - Burst mode + * - Interrupts + * - DMA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* LPC18XX ADC registers and bits */ +#define LPC18XX_ADC_CR 0x000 +#define LPC18XX_ADC_CR_CLKDIV_SHIFT 8 +#define LPC18XX_ADC_CR_PDN BIT(21) +#define LPC18XX_ADC_CR_START_NOW (0x1 << 24) +#define LPC18XX_ADC_GDR 0x004 + +/* Data register bits */ +#define LPC18XX_ADC_SAMPLE_SHIFT 6 +#define LPC18XX_ADC_SAMPLE_MASK 0x3ff +#define LPC18XX_ADC_CONV_DONE BIT(31) + +/* Clock should be 4.5 MHz or less */ +#define LPC18XX_ADC_CLK_TARGET 4500000 + +struct lpc18xx_adc { + struct regulator *vref; + void __iomem *base; + struct device *dev; + struct mutex lock; + struct clk *clk; + u32 cr_reg; +}; + +#define LPC18XX_ADC_CHAN(_idx) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = _idx, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ +} + +static const struct iio_chan_spec lpc18xx_adc_iio_channels[] = { + LPC18XX_ADC_CHAN(0), + LPC18XX_ADC_CHAN(1), + LPC18XX_ADC_CHAN(2), + LPC18XX_ADC_CHAN(3), + LPC18XX_ADC_CHAN(4), + LPC18XX_ADC_CHAN(5), + LPC18XX_ADC_CHAN(6), + LPC18XX_ADC_CHAN(7), +}; + +static int lpc18xx_adc_read_chan(struct lpc18xx_adc *adc, unsigned int ch) +{ + int ret; + u32 reg; + + reg = adc->cr_reg | BIT(ch) | LPC18XX_ADC_CR_START_NOW; + writel(reg, adc->base + LPC18XX_ADC_CR); + + ret = readl_poll_timeout(adc->base + LPC18XX_ADC_GDR, reg, + reg & LPC18XX_ADC_CONV_DONE, 3, 9); + if (ret) { + dev_warn(adc->dev, "adc read timed out\n"); + return ret; + } + + return (reg >> LPC18XX_ADC_SAMPLE_SHIFT) & LPC18XX_ADC_SAMPLE_MASK; +} + +static int lpc18xx_adc_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct lpc18xx_adc *adc = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_RAW: + mutex_lock(&adc->lock); + *val = lpc18xx_adc_read_chan(adc, chan->channel); + mutex_unlock(&adc->lock); + if (*val < 0) + return *val; + + return IIO_VAL_INT; + + case IIO_CHAN_INFO_SCALE: + *val = regulator_get_voltage(adc->vref) / 1000; + *val2 = 10; + + return IIO_VAL_FRACTIONAL_LOG2; + } + + return -EINVAL; +} + +static const struct iio_info lpc18xx_adc_info = { + .read_raw = lpc18xx_adc_read_raw, + .driver_module = THIS_MODULE, +}; + +static int lpc18xx_adc_probe(struct platform_device *pdev) +{ + struct iio_dev *indio_dev; + struct lpc18xx_adc *adc; + struct resource *res; + unsigned int clkdiv; + unsigned long rate; + int ret; + + indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc)); + if (!indio_dev) + return -ENOMEM; + + platform_set_drvdata(pdev, indio_dev); + adc = iio_priv(indio_dev); + adc->dev = &pdev->dev; + mutex_init(&adc->lock); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + adc->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(adc->base)) + return PTR_ERR(adc->base); + + adc->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(adc->clk)) { + dev_err(&pdev->dev, "error getting clock\n"); + return PTR_ERR(adc->clk); + } + + rate = clk_get_rate(adc->clk); + clkdiv = DIV_ROUND_UP(rate, LPC18XX_ADC_CLK_TARGET); + + adc->vref = devm_regulator_get(&pdev->dev, "vref"); + if (IS_ERR(adc->vref)) { + dev_err(&pdev->dev, "error getting regulator\n"); + return PTR_ERR(adc->vref); + } + + indio_dev->name = dev_name(&pdev->dev); + indio_dev->dev.parent = &pdev->dev; + indio_dev->info = &lpc18xx_adc_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = lpc18xx_adc_iio_channels; + indio_dev->num_channels = ARRAY_SIZE(lpc18xx_adc_iio_channels); + + ret = regulator_enable(adc->vref); + if (ret) { + dev_err(&pdev->dev, "unable to enable regulator\n"); + return ret; + } + + ret = clk_prepare_enable(adc->clk); + if (ret) { + dev_err(&pdev->dev, "unable to enable clock\n"); + goto dis_reg; + } + + adc->cr_reg = (clkdiv << LPC18XX_ADC_CR_CLKDIV_SHIFT) | + LPC18XX_ADC_CR_PDN; + writel(adc->cr_reg, adc->base + LPC18XX_ADC_CR); + + ret = iio_device_register(indio_dev); + if (ret) { + dev_err(&pdev->dev, "unable to register device\n"); + goto dis_clk; + } + + return 0; + +dis_clk: + writel(0, adc->base + LPC18XX_ADC_CR); + clk_disable_unprepare(adc->clk); +dis_reg: + regulator_disable(adc->vref); + return ret; +} + +static int lpc18xx_adc_remove(struct platform_device *pdev) +{ + struct iio_dev *indio_dev = platform_get_drvdata(pdev); + struct lpc18xx_adc *adc = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + + writel(0, adc->base + LPC18XX_ADC_CR); + clk_disable_unprepare(adc->clk); + regulator_disable(adc->vref); + + return 0; +} + +static const struct of_device_id lpc18xx_adc_match[] = { + { .compatible = "nxp,lpc1850-adc" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, lpc18xx_adc_match); + +static struct platform_driver lpc18xx_adc_driver = { + .probe = lpc18xx_adc_probe, + .remove = lpc18xx_adc_remove, + .driver = { + .name = "lpc18xx-adc", + .of_match_table = lpc18xx_adc_match, + }, +}; +module_platform_driver(lpc18xx_adc_driver); + +MODULE_DESCRIPTION("LPC18xx ADC driver"); +MODULE_AUTHOR("Joachim Eastwood "); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 9bbccbe11ab78c74bed9a2bc99943929f49ca565 Mon Sep 17 00:00:00 2001 From: Joachim Eastwood Date: Sat, 12 Mar 2016 13:30:16 +0100 Subject: iio: dac: add NXP LPC18xx DAC driver Add base support for the 10-bit DAC peripheral found on NXP LPC18xx/43xx SoCs. This is a minimal driver that does not support DMA or interrupts. User manual with register description can be found on: LPC18xx: www.nxp.com/documents/user_manual/UM10430.pdf LPC43xx: www.nxp.com/documents/user_manual/UM10503.pdf Signed-off-by: Joachim Eastwood Signed-off-by: Jonathan Cameron --- drivers/iio/dac/Kconfig | 10 ++ drivers/iio/dac/Makefile | 1 + drivers/iio/dac/lpc18xx_dac.c | 210 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 221 insertions(+) create mode 100644 drivers/iio/dac/lpc18xx_dac.c (limited to 'drivers') diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig index a995139f907c..210db81ca144 100644 --- a/drivers/iio/dac/Kconfig +++ b/drivers/iio/dac/Kconfig @@ -154,6 +154,16 @@ config AD7303 To compile this driver as module choose M here: the module will be called ad7303. +config LPC18XX_DAC + tristate "NXP LPC18xx DAC driver" + depends on ARCH_LPC18XX || COMPILE_TEST + depends on OF && HAS_IOMEM + help + Say yes here to build support for NXP LPC18XX DAC. + + To compile this driver as a module, choose M here: the module will be + called lpc18xx_dac. + config M62332 tristate "Mitsubishi M62332 DAC driver" depends on I2C diff --git a/drivers/iio/dac/Makefile b/drivers/iio/dac/Makefile index 67b48429686d..420a15cdaa53 100644 --- a/drivers/iio/dac/Makefile +++ b/drivers/iio/dac/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_AD5764) += ad5764.o obj-$(CONFIG_AD5791) += ad5791.o obj-$(CONFIG_AD5686) += ad5686.o obj-$(CONFIG_AD7303) += ad7303.o +obj-$(CONFIG_LPC18XX_DAC) += lpc18xx_dac.o obj-$(CONFIG_M62332) += m62332.o obj-$(CONFIG_MAX517) += max517.o obj-$(CONFIG_MAX5821) += max5821.o diff --git a/drivers/iio/dac/lpc18xx_dac.c b/drivers/iio/dac/lpc18xx_dac.c new file mode 100644 index 000000000000..55d1456a059d --- /dev/null +++ b/drivers/iio/dac/lpc18xx_dac.c @@ -0,0 +1,210 @@ +/* + * IIO DAC driver for NXP LPC18xx DAC + * + * Copyright (C) 2016 Joachim Eastwood + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * UNSUPPORTED hardware features: + * - Interrupts + * - DMA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* LPC18XX DAC registers and bits */ +#define LPC18XX_DAC_CR 0x000 +#define LPC18XX_DAC_CR_VALUE_SHIFT 6 +#define LPC18XX_DAC_CR_VALUE_MASK 0x3ff +#define LPC18XX_DAC_CR_BIAS BIT(16) +#define LPC18XX_DAC_CTRL 0x004 +#define LPC18XX_DAC_CTRL_DMA_ENA BIT(3) + +struct lpc18xx_dac { + struct regulator *vref; + void __iomem *base; + struct mutex lock; + struct clk *clk; +}; + +static const struct iio_chan_spec lpc18xx_dac_iio_channels[] = { + { + .type = IIO_VOLTAGE, + .output = 1, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE), + }, +}; + +static int lpc18xx_dac_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct lpc18xx_dac *dac = iio_priv(indio_dev); + u32 reg; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + reg = readl(dac->base + LPC18XX_DAC_CR); + *val = reg >> LPC18XX_DAC_CR_VALUE_SHIFT; + *val &= LPC18XX_DAC_CR_VALUE_MASK; + + return IIO_VAL_INT; + + case IIO_CHAN_INFO_SCALE: + *val = regulator_get_voltage(dac->vref) / 1000; + *val2 = 10; + + return IIO_VAL_FRACTIONAL_LOG2; + } + + return -EINVAL; +} + +static int lpc18xx_dac_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct lpc18xx_dac *dac = iio_priv(indio_dev); + u32 reg; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + if (val < 0 || val > LPC18XX_DAC_CR_VALUE_MASK) + return -EINVAL; + + reg = LPC18XX_DAC_CR_BIAS; + reg |= val << LPC18XX_DAC_CR_VALUE_SHIFT; + + mutex_lock(&dac->lock); + writel(reg, dac->base + LPC18XX_DAC_CR); + writel(LPC18XX_DAC_CTRL_DMA_ENA, dac->base + LPC18XX_DAC_CTRL); + mutex_unlock(&dac->lock); + + return 0; + } + + return -EINVAL; +} + +static const struct iio_info lpc18xx_dac_info = { + .read_raw = lpc18xx_dac_read_raw, + .write_raw = lpc18xx_dac_write_raw, + .driver_module = THIS_MODULE, +}; + +static int lpc18xx_dac_probe(struct platform_device *pdev) +{ + struct iio_dev *indio_dev; + struct lpc18xx_dac *dac; + struct resource *res; + int ret; + + indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*dac)); + if (!indio_dev) + return -ENOMEM; + + platform_set_drvdata(pdev, indio_dev); + dac = iio_priv(indio_dev); + mutex_init(&dac->lock); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + dac->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(dac->base)) + return PTR_ERR(dac->base); + + dac->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(dac->clk)) { + dev_err(&pdev->dev, "error getting clock\n"); + return PTR_ERR(dac->clk); + } + + dac->vref = devm_regulator_get(&pdev->dev, "vref"); + if (IS_ERR(dac->vref)) { + dev_err(&pdev->dev, "error getting regulator\n"); + return PTR_ERR(dac->vref); + } + + indio_dev->name = dev_name(&pdev->dev); + indio_dev->dev.parent = &pdev->dev; + indio_dev->info = &lpc18xx_dac_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = lpc18xx_dac_iio_channels; + indio_dev->num_channels = ARRAY_SIZE(lpc18xx_dac_iio_channels); + + ret = regulator_enable(dac->vref); + if (ret) { + dev_err(&pdev->dev, "unable to enable regulator\n"); + return ret; + } + + ret = clk_prepare_enable(dac->clk); + if (ret) { + dev_err(&pdev->dev, "unable to enable clock\n"); + goto dis_reg; + } + + writel(0, dac->base + LPC18XX_DAC_CTRL); + writel(0, dac->base + LPC18XX_DAC_CR); + + ret = iio_device_register(indio_dev); + if (ret) { + dev_err(&pdev->dev, "unable to register device\n"); + goto dis_clk; + } + + return 0; + +dis_clk: + clk_disable_unprepare(dac->clk); +dis_reg: + regulator_disable(dac->vref); + return ret; +} + +static int lpc18xx_dac_remove(struct platform_device *pdev) +{ + struct iio_dev *indio_dev = platform_get_drvdata(pdev); + struct lpc18xx_dac *dac = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + + writel(0, dac->base + LPC18XX_DAC_CTRL); + clk_disable_unprepare(dac->clk); + regulator_disable(dac->vref); + + return 0; +} + +static const struct of_device_id lpc18xx_dac_match[] = { + { .compatible = "nxp,lpc1850-dac" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, lpc18xx_dac_match); + +static struct platform_driver lpc18xx_dac_driver = { + .probe = lpc18xx_dac_probe, + .remove = lpc18xx_dac_remove, + .driver = { + .name = "lpc18xx-dac", + .of_match_table = lpc18xx_dac_match, + }, +}; +module_platform_driver(lpc18xx_dac_driver); + +MODULE_DESCRIPTION("LPC18xx DAC driver"); +MODULE_AUTHOR("Joachim Eastwood "); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 359d2243117a79599435141fda0047d01ef324e8 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 14 Mar 2016 08:16:51 +0100 Subject: drm/i915: Update DRIVER_DATE to 20160314 Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 1557d65485b0..80b14f1ba302 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -60,7 +60,7 @@ #define DRIVER_NAME "i915" #define DRIVER_DESC "Intel Graphics" -#define DRIVER_DATE "20160229" +#define DRIVER_DATE "20160314" #undef WARN_ON /* Many gcc seem to no see through this and fall over :( */ -- cgit v1.2.3 From cd202f69d89c48a935d4763ff96c50e762ed2e0a Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Wed, 9 Mar 2016 10:35:44 +0100 Subject: drm/i915: Remove some post-commit members from intel_crtc->atomic, v3. fb_bits is useful to have in the crtc_state for cs flips when the code is updated to use intel_frontbuffer_flip_prepare/complete. So calculate it in advance and move it to crtc_state. The other stuff can be calculated in post_plane_update, and aren't useful elsewhere. Changes since v1: - Changing wording, remove comment about loop. Changes since v2: - Rebase. Signed-off-by: Maarten Lankhorst Reviewed-by: Ander Conselvan de Oliveira Link: http://patchwork.freedesktop.org/patch/msgid/1457516145-32117-1-git-send-email-maarten.lankhorst@linux.intel.com --- drivers/gpu/drm/i915/intel_atomic.c | 1 + drivers/gpu/drm/i915/intel_display.c | 29 +++++++++++++++++++++-------- drivers/gpu/drm/i915/intel_drv.h | 5 +---- 3 files changed, 23 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c index 79448f1c8b8d..50ff90aea721 100644 --- a/drivers/gpu/drm/i915/intel_atomic.c +++ b/drivers/gpu/drm/i915/intel_atomic.c @@ -100,6 +100,7 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc) crtc_state->update_wm_post = false; crtc_state->fb_changed = false; crtc_state->wm.need_postvbl_update = false; + crtc_state->fb_bits = 0; return &crtc_state->base; } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ce55f0b683c6..8a834261155b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4669,14 +4669,20 @@ intel_pre_disable_primary_noatomic(struct drm_crtc *crtc) } } -static void intel_post_plane_update(struct intel_crtc *crtc) +static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state) { + struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc); + struct drm_atomic_state *old_state = old_crtc_state->base.state; struct intel_crtc_atomic_commit *atomic = &crtc->atomic; struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc->base.state); struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_plane *primary = crtc->base.primary; + struct drm_plane_state *old_pri_state = + drm_atomic_get_existing_plane_state(old_state, primary); - intel_frontbuffer_flip(dev, atomic->fb_bits); + intel_frontbuffer_flip(dev, pipe_config->fb_bits); crtc->wm.cxsr_allowed = true; @@ -4686,8 +4692,17 @@ static void intel_post_plane_update(struct intel_crtc *crtc) if (atomic->update_fbc) intel_fbc_post_update(crtc); - if (atomic->post_enable_primary) - intel_post_enable_primary(&crtc->base); + if (old_pri_state) { + struct intel_plane_state *primary_state = + to_intel_plane_state(primary->state); + struct intel_plane_state *old_primary_state = + to_intel_plane_state(old_pri_state); + + if (primary_state->visible && + (needs_modeset(&pipe_config->base) || + !old_primary_state->visible)) + intel_post_enable_primary(&crtc->base); + } memset(atomic, 0, sizeof(*atomic)); } @@ -11830,12 +11845,10 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state, to_intel_crtc_state(crtc_state)->wm.need_postvbl_update = true; if (visible || was_visible) - intel_crtc->atomic.fb_bits |= - to_intel_plane(plane)->frontbuffer_bit; + pipe_config->fb_bits |= to_intel_plane(plane)->frontbuffer_bit; switch (plane->type) { case DRM_PLANE_TYPE_PRIMARY: - intel_crtc->atomic.post_enable_primary = turn_on; intel_crtc->atomic.update_fbc = true; break; @@ -13625,7 +13638,7 @@ static int intel_atomic_commit(struct drm_device *dev, intel_atomic_wait_for_vblanks(dev, dev_priv, crtc_vblank_mask); for_each_crtc_in_state(state, crtc, old_crtc_state, i) { - intel_post_plane_update(to_intel_crtc(crtc)); + intel_post_plane_update(to_intel_crtc_state(old_crtc_state)); if (put_domains[i]) modeset_put_power_domains(dev_priv, put_domains[i]); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 02b3d22862a1..09ab436bafef 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -418,6 +418,7 @@ struct intel_crtc_state { #define PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS (1<<0) /* unreliable sync mode.flags */ unsigned long quirks; + unsigned fb_bits; /* framebuffers to flip */ bool update_pipe; /* can a fast modeset be performed? */ bool disable_cxsr; bool update_wm_pre, update_wm_post; /* watermarks are updated */ @@ -605,10 +606,6 @@ struct intel_crtc_atomic_commit { /* Sleepable operations to perform before commit */ /* Sleepable operations to perform after commit */ - unsigned fb_bits; - bool post_enable_primary; - - /* Sleepable operations to perform before and after commit */ bool update_fbc; }; -- cgit v1.2.3 From 31ae71fca7f91101613fac9deb8e858e1319b4f5 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Wed, 9 Mar 2016 10:35:45 +0100 Subject: drm/i915: Nuke fbc members from intel_crtc->atomic, v4. Whenever there's an update to the primary plane, fbc_pre_update and fbc_post_update are called. Kill off intel_crtc->atomic.update_fbc and now that intel_crtc->atomic is empty, kill it off too. Changes since v1: - Add a intel_fbc_supports_rotation helper. Changes since v2: - Remove intel_fbc_supports_rotation_helper. - Remove unrelated changes. Changes since v3: - Rebase Signed-off-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1457516145-32117-2-git-send-email-maarten.lankhorst@linux.intel.com Reviewed-by: Paulo Zanoni --- drivers/gpu/drm/i915/intel_display.c | 51 +++++++++++------------------------- drivers/gpu/drm/i915/intel_drv.h | 15 ----------- 2 files changed, 16 insertions(+), 50 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8a834261155b..ed650a4f67b6 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4673,11 +4673,9 @@ static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state) { struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc); struct drm_atomic_state *old_state = old_crtc_state->base.state; - struct intel_crtc_atomic_commit *atomic = &crtc->atomic; struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc->base.state); struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; struct drm_plane *primary = crtc->base.primary; struct drm_plane_state *old_pri_state = drm_atomic_get_existing_plane_state(old_state, primary); @@ -4689,22 +4687,19 @@ static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state) if (pipe_config->update_wm_post && pipe_config->base.active) intel_update_watermarks(&crtc->base); - if (atomic->update_fbc) - intel_fbc_post_update(crtc); - if (old_pri_state) { struct intel_plane_state *primary_state = to_intel_plane_state(primary->state); struct intel_plane_state *old_primary_state = to_intel_plane_state(old_pri_state); + intel_fbc_post_update(crtc); + if (primary_state->visible && (needs_modeset(&pipe_config->base) || !old_primary_state->visible)) intel_post_enable_primary(&crtc->base); } - - memset(atomic, 0, sizeof(*atomic)); } static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state) @@ -4712,7 +4707,6 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state) struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc); struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc_atomic_commit *atomic = &crtc->atomic; struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc->base.state); struct drm_atomic_state *old_state = old_crtc_state->base.state; @@ -4721,15 +4715,14 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state) drm_atomic_get_existing_plane_state(old_state, primary); bool modeset = needs_modeset(&pipe_config->base); - if (atomic->update_fbc) - intel_fbc_pre_update(crtc); - if (old_pri_state) { struct intel_plane_state *primary_state = to_intel_plane_state(primary->state); struct intel_plane_state *old_primary_state = to_intel_plane_state(old_pri_state); + intel_fbc_pre_update(crtc); + if (old_primary_state->visible && (modeset || !primary_state->visible)) intel_pre_disable_primary(&crtc->base); @@ -11847,27 +11840,17 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state, if (visible || was_visible) pipe_config->fb_bits |= to_intel_plane(plane)->frontbuffer_bit; - switch (plane->type) { - case DRM_PLANE_TYPE_PRIMARY: - intel_crtc->atomic.update_fbc = true; - - break; - case DRM_PLANE_TYPE_CURSOR: - break; - case DRM_PLANE_TYPE_OVERLAY: - /* - * WaCxSRDisabledForSpriteScaling:ivb - * - * cstate->update_wm was already set above, so this flag will - * take effect when we commit and program watermarks. - */ - if (IS_IVYBRIDGE(dev) && - needs_scaling(to_intel_plane_state(plane_state)) && - !needs_scaling(old_plane_state)) - pipe_config->disable_lp_wm = true; + /* + * WaCxSRDisabledForSpriteScaling:ivb + * + * cstate->update_wm was already set above, so this flag will + * take effect when we commit and program watermarks. + */ + if (plane->type == DRM_PLANE_TYPE_OVERLAY && IS_IVYBRIDGE(dev) && + needs_scaling(to_intel_plane_state(plane_state)) && + !needs_scaling(old_plane_state)) + pipe_config->disable_lp_wm = true; - break; - } return 0; } @@ -13310,9 +13293,6 @@ static int intel_atomic_check(struct drm_device *dev, struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc_state); - memset(&to_intel_crtc(crtc)->atomic, 0, - sizeof(struct intel_crtc_atomic_commit)); - /* Catch I915_MODE_FLAG_INHERITED */ if (crtc_state->mode.private_flags != crtc->state->mode.private_flags) crtc_state->mode_changed = true; @@ -13621,7 +13601,8 @@ static int intel_atomic_commit(struct drm_device *dev, if (!modeset) intel_pre_plane_update(to_intel_crtc_state(old_crtc_state)); - if (crtc->state->active && intel_crtc->atomic.update_fbc) + if (crtc->state->active && + drm_atomic_get_existing_plane_state(state, crtc->primary)) intel_fbc_enable(intel_crtc); if (crtc->state->active && diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 09ab436bafef..0786246b8a88 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -596,19 +596,6 @@ struct intel_mmio_flip { unsigned int rotation; }; -/* - * Tracking of operations that need to be performed at the beginning/end of an - * atomic commit, outside the atomic section where interrupts are disabled. - * These are generally operations that grab mutexes or might otherwise sleep - * and thus can't be run with interrupts disabled. - */ -struct intel_crtc_atomic_commit { - /* Sleepable operations to perform before commit */ - - /* Sleepable operations to perform after commit */ - bool update_fbc; -}; - struct intel_crtc { struct drm_crtc base; enum pipe pipe; @@ -669,8 +656,6 @@ struct intel_crtc { int scanline_start; } debug; - struct intel_crtc_atomic_commit atomic; - /* scalers available on this crtc */ int num_scalers; -- cgit v1.2.3 From 08250c4ba650a9d8453166b4c05962766798fe9b Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 14 Mar 2016 19:55:34 +0200 Subject: drm/i915/bxt: Fix off-by-one error in Broxton PLL IDs After the commit below the Broxton PLL IDs had an off-by-one error, so fix this up. Also add a missing brace at intel_shared_dpll_init(), it happened to compile only due to the way the IS_BROXTON macro is defined. v2: - remove debugging left-over Fixes: a3c988ea068c ("drm/i915: Make SKL/KBL DPLL0 managed by the shared dpll code") CC: Ander Conselvan de Oliveira CC: Maarten Lankhorst Signed-off-by: Imre Deak Reviewed-by: Ander Conselvan de Oliveira Link: http://patchwork.freedesktop.org/patch/msgid/1457978134-12362-1-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/intel_display.c | 6 +++--- drivers/gpu/drm/i915/intel_dpll_mgr.c | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ed650a4f67b6..4c04dab36305 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9786,15 +9786,15 @@ static void bxt_get_ddi_pll(struct drm_i915_private *dev_priv, switch (port) { case PORT_A: pipe_config->ddi_pll_sel = SKL_DPLL0; - id = DPLL_ID_SKL_DPLL1; + id = DPLL_ID_SKL_DPLL0; break; case PORT_B: pipe_config->ddi_pll_sel = SKL_DPLL1; - id = DPLL_ID_SKL_DPLL2; + id = DPLL_ID_SKL_DPLL1; break; case PORT_C: pipe_config->ddi_pll_sel = SKL_DPLL2; - id = DPLL_ID_SKL_DPLL3; + id = DPLL_ID_SKL_DPLL2; break; default: DRM_ERROR("Incorrect port type\n"); diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c index 4b636c47e8e3..74d5aecc0be5 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c @@ -1706,9 +1706,9 @@ static const struct intel_dpll_mgr skl_pll_mgr = { }; static const struct dpll_info bxt_plls[] = { - { "PORT PLL A", 0, &bxt_ddi_pll_funcs, 0 }, - { "PORT PLL B", 1, &bxt_ddi_pll_funcs, 0 }, - { "PORT PLL C", 2, &bxt_ddi_pll_funcs, 0 }, + { "PORT PLL A", DPLL_ID_SKL_DPLL0, &bxt_ddi_pll_funcs, 0 }, + { "PORT PLL B", DPLL_ID_SKL_DPLL1, &bxt_ddi_pll_funcs, 0 }, + { "PORT PLL C", DPLL_ID_SKL_DPLL2, &bxt_ddi_pll_funcs, 0 }, { NULL, -1, NULL, }, }; @@ -1726,7 +1726,7 @@ void intel_shared_dpll_init(struct drm_device *dev) if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) dpll_mgr = &skl_pll_mgr; - else if IS_BROXTON(dev) + else if (IS_BROXTON(dev)) dpll_mgr = &bxt_pll_mgr; else if (HAS_DDI(dev)) dpll_mgr = &hsw_pll_mgr; -- cgit v1.2.3 From e2f80391478af71bbbc91686fe0efc580b907caa Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Wed, 16 Mar 2016 11:00:36 +0000 Subject: drm/i915: Rename local struct intel_engine_cs variables Done by the Coccinelle script below plus a manual intervention to GEN8_RING_SEMAPHORE_INIT. @@ expression E; @@ - struct intel_engine_cs *ring = E; + struct intel_engine_cs *engine = E; <+... - ring + engine ...+> @@ @@ - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; <+... - ring + engine ...+> Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 203 ++++---- drivers/gpu/drm/i915/i915_gem.c | 136 ++--- drivers/gpu/drm/i915/i915_gem_context.c | 140 ++--- drivers/gpu/drm/i915/i915_gem_debug.c | 15 +- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 74 +-- drivers/gpu/drm/i915/i915_gem_gtt.c | 90 ++-- drivers/gpu/drm/i915/i915_gpu_error.c | 35 +- drivers/gpu/drm/i915/i915_guc_submission.c | 30 +- drivers/gpu/drm/i915/i915_irq.c | 84 +-- drivers/gpu/drm/i915/intel_display.c | 106 ++-- drivers/gpu/drm/i915/intel_guc_loader.c | 12 +- drivers/gpu/drm/i915/intel_lrc.c | 216 ++++---- drivers/gpu/drm/i915/intel_mocs.c | 4 +- drivers/gpu/drm/i915/intel_overlay.c | 60 +-- drivers/gpu/drm/i915/intel_pm.c | 36 +- drivers/gpu/drm/i915/intel_ringbuffer.c | 785 +++++++++++++++-------------- drivers/gpu/drm/i915/intel_ringbuffer.h | 14 +- 17 files changed, 1035 insertions(+), 1005 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 15aacd0ee66f..5037ccb18e77 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -129,7 +129,7 @@ static void describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) { struct drm_i915_private *dev_priv = to_i915(obj->base.dev); - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; struct i915_vma *vma; int pin_count = 0; int i; @@ -143,7 +143,7 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) obj->base.size / 1024, obj->base.read_domains, obj->base.write_domain); - for_each_ring(ring, dev_priv, i) + for_each_ring(engine, dev_priv, i) seq_printf(m, "%x ", i915_gem_request_get_seqno(obj->last_read_req[i])); seq_printf(m, "] %x %x%s%s%s", @@ -397,15 +397,15 @@ static void print_batch_pool_stats(struct seq_file *m, { struct drm_i915_gem_object *obj; struct file_stats stats; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; int i, j; memset(&stats, 0, sizeof(stats)); - for_each_ring(ring, dev_priv, i) { - for (j = 0; j < ARRAY_SIZE(ring->batch_pool.cache_list); j++) { + for_each_ring(engine, dev_priv, i) { + for (j = 0; j < ARRAY_SIZE(engine->batch_pool.cache_list); j++) { list_for_each_entry(obj, - &ring->batch_pool.cache_list[j], + &engine->batch_pool.cache_list[j], batch_pool_link) per_file_stats(0, obj, &stats); } @@ -591,14 +591,13 @@ static int i915_gem_pageflip_info(struct seq_file *m, void *data) pipe, plane); } if (work->flip_queued_req) { - struct intel_engine_cs *ring = - i915_gem_request_get_ring(work->flip_queued_req); + struct intel_engine_cs *engine = i915_gem_request_get_ring(work->flip_queued_req); seq_printf(m, "Flip queued on %s at seqno %x, next seqno %x [current breadcrumb %x], completed? %d\n", - ring->name, + engine->name, i915_gem_request_get_seqno(work->flip_queued_req), dev_priv->next_seqno, - ring->get_seqno(ring, true), + engine->get_seqno(engine, true), i915_gem_request_completed(work->flip_queued_req, true)); } else seq_printf(m, "Flip not associated with any ring\n"); @@ -637,7 +636,7 @@ static int i915_gem_batch_pool_info(struct seq_file *m, void *data) struct drm_device *dev = node->minor->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; int total = 0; int ret, i, j; @@ -645,20 +644,20 @@ static int i915_gem_batch_pool_info(struct seq_file *m, void *data) if (ret) return ret; - for_each_ring(ring, dev_priv, i) { - for (j = 0; j < ARRAY_SIZE(ring->batch_pool.cache_list); j++) { + for_each_ring(engine, dev_priv, i) { + for (j = 0; j < ARRAY_SIZE(engine->batch_pool.cache_list); j++) { int count; count = 0; list_for_each_entry(obj, - &ring->batch_pool.cache_list[j], + &engine->batch_pool.cache_list[j], batch_pool_link) count++; seq_printf(m, "%s cache[%d]: %d objects\n", - ring->name, j, count); + engine->name, j, count); list_for_each_entry(obj, - &ring->batch_pool.cache_list[j], + &engine->batch_pool.cache_list[j], batch_pool_link) { seq_puts(m, " "); describe_obj(m, obj); @@ -681,7 +680,7 @@ static int i915_gem_request_info(struct seq_file *m, void *data) struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; struct drm_i915_gem_request *req; int ret, any, i; @@ -690,17 +689,17 @@ static int i915_gem_request_info(struct seq_file *m, void *data) return ret; any = 0; - for_each_ring(ring, dev_priv, i) { + for_each_ring(engine, dev_priv, i) { int count; count = 0; - list_for_each_entry(req, &ring->request_list, list) + list_for_each_entry(req, &engine->request_list, list) count++; if (count == 0) continue; - seq_printf(m, "%s requests: %d\n", ring->name, count); - list_for_each_entry(req, &ring->request_list, list) { + seq_printf(m, "%s requests: %d\n", engine->name, count); + list_for_each_entry(req, &engine->request_list, list) { struct task_struct *task; rcu_read_lock(); @@ -739,7 +738,7 @@ static int i915_gem_seqno_info(struct seq_file *m, void *data) struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; int ret, i; ret = mutex_lock_interruptible(&dev->struct_mutex); @@ -747,8 +746,8 @@ static int i915_gem_seqno_info(struct seq_file *m, void *data) return ret; intel_runtime_pm_get(dev_priv); - for_each_ring(ring, dev_priv, i) - i915_ring_seqno_info(m, ring); + for_each_ring(engine, dev_priv, i) + i915_ring_seqno_info(m, engine); intel_runtime_pm_put(dev_priv); mutex_unlock(&dev->struct_mutex); @@ -762,7 +761,7 @@ static int i915_interrupt_info(struct seq_file *m, void *data) struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; int ret, i, pipe; ret = mutex_lock_interruptible(&dev->struct_mutex); @@ -934,13 +933,13 @@ static int i915_interrupt_info(struct seq_file *m, void *data) seq_printf(m, "Graphics Interrupt mask: %08x\n", I915_READ(GTIMR)); } - for_each_ring(ring, dev_priv, i) { + for_each_ring(engine, dev_priv, i) { if (INTEL_INFO(dev)->gen >= 6) { seq_printf(m, "Graphics Interrupt mask (%s): %08x\n", - ring->name, I915_READ_IMR(ring)); + engine->name, I915_READ_IMR(engine)); } - i915_ring_seqno_info(m, ring); + i915_ring_seqno_info(m, engine); } intel_runtime_pm_put(dev_priv); mutex_unlock(&dev->struct_mutex); @@ -981,12 +980,12 @@ static int i915_hws_info(struct seq_file *m, void *data) struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; const u32 *hws; int i; - ring = &dev_priv->ring[(uintptr_t)node->info_ent->data]; - hws = ring->status_page.page_addr; + engine = &dev_priv->ring[(uintptr_t)node->info_ent->data]; + hws = engine->status_page.page_addr; if (hws == NULL) return 0; @@ -1331,7 +1330,7 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused) struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; u64 acthd[I915_NUM_RINGS]; u32 seqno[I915_NUM_RINGS]; u32 instdone[I915_NUM_INSTDONE_REG]; @@ -1344,9 +1343,9 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused) intel_runtime_pm_get(dev_priv); - for_each_ring(ring, dev_priv, i) { - seqno[i] = ring->get_seqno(ring, false); - acthd[i] = intel_ring_get_active_head(ring); + for_each_ring(engine, dev_priv, i) { + seqno[i] = engine->get_seqno(engine, false); + acthd[i] = intel_ring_get_active_head(engine); } i915_get_extra_instdone(dev, instdone); @@ -1360,17 +1359,17 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused) } else seq_printf(m, "Hangcheck inactive\n"); - for_each_ring(ring, dev_priv, i) { - seq_printf(m, "%s:\n", ring->name); + for_each_ring(engine, dev_priv, i) { + seq_printf(m, "%s:\n", engine->name); seq_printf(m, "\tseqno = %x [current %x]\n", - ring->hangcheck.seqno, seqno[i]); + engine->hangcheck.seqno, seqno[i]); seq_printf(m, "\tACTHD = 0x%08llx [current 0x%08llx]\n", - (long long)ring->hangcheck.acthd, + (long long)engine->hangcheck.acthd, (long long)acthd[i]); - seq_printf(m, "\tscore = %d\n", ring->hangcheck.score); - seq_printf(m, "\taction = %d\n", ring->hangcheck.action); + seq_printf(m, "\tscore = %d\n", engine->hangcheck.score); + seq_printf(m, "\taction = %d\n", engine->hangcheck.action); - if (ring->id == RCS) { + if (engine->id == RCS) { seq_puts(m, "\tinstdone read ="); for (j = 0; j < I915_NUM_INSTDONE_REG; j++) @@ -1380,7 +1379,7 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused) for (j = 0; j < I915_NUM_INSTDONE_REG; j++) seq_printf(m, " 0x%08x", - ring->hangcheck.instdone[j]); + engine->hangcheck.instdone[j]); seq_puts(m, "\n"); } @@ -1946,7 +1945,7 @@ static int i915_context_status(struct seq_file *m, void *unused) struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; struct intel_context *ctx; int ret, i; @@ -1966,13 +1965,13 @@ static int i915_context_status(struct seq_file *m, void *unused) if (i915.enable_execlists) { seq_putc(m, '\n'); - for_each_ring(ring, dev_priv, i) { + for_each_ring(engine, dev_priv, i) { struct drm_i915_gem_object *ctx_obj = ctx->engine[i].state; struct intel_ringbuffer *ringbuf = ctx->engine[i].ringbuf; - seq_printf(m, "%s: ", ring->name); + seq_printf(m, "%s: ", engine->name); if (ctx_obj) describe_obj(m, ctx_obj); if (ringbuf) @@ -2041,7 +2040,7 @@ static int i915_dump_lrc(struct seq_file *m, void *unused) struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; struct intel_context *ctx; int ret, i; @@ -2056,8 +2055,8 @@ static int i915_dump_lrc(struct seq_file *m, void *unused) list_for_each_entry(ctx, &dev_priv->context_list, link) if (ctx != dev_priv->kernel_context) - for_each_ring(ring, dev_priv, i) - i915_dump_lrc_obj(m, ctx, ring); + for_each_ring(engine, dev_priv, i) + i915_dump_lrc_obj(m, ctx, engine); mutex_unlock(&dev->struct_mutex); @@ -2069,7 +2068,7 @@ static int i915_execlists(struct seq_file *m, void *data) struct drm_info_node *node = (struct drm_info_node *)m->private; struct drm_device *dev = node->minor->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; u32 status_pointer; u8 read_pointer; u8 write_pointer; @@ -2090,22 +2089,22 @@ static int i915_execlists(struct seq_file *m, void *data) intel_runtime_pm_get(dev_priv); - for_each_ring(ring, dev_priv, ring_id) { + for_each_ring(engine, dev_priv, ring_id) { struct drm_i915_gem_request *head_req = NULL; int count = 0; unsigned long flags; - seq_printf(m, "%s\n", ring->name); + seq_printf(m, "%s\n", engine->name); - status = I915_READ(RING_EXECLIST_STATUS_LO(ring)); - ctx_id = I915_READ(RING_EXECLIST_STATUS_HI(ring)); + status = I915_READ(RING_EXECLIST_STATUS_LO(engine)); + ctx_id = I915_READ(RING_EXECLIST_STATUS_HI(engine)); seq_printf(m, "\tExeclist status: 0x%08X, context: %u\n", status, ctx_id); - status_pointer = I915_READ(RING_CONTEXT_STATUS_PTR(ring)); + status_pointer = I915_READ(RING_CONTEXT_STATUS_PTR(engine)); seq_printf(m, "\tStatus pointer: 0x%08X\n", status_pointer); - read_pointer = ring->next_context_status_buffer; + read_pointer = engine->next_context_status_buffer; write_pointer = GEN8_CSB_WRITE_PTR(status_pointer); if (read_pointer > write_pointer) write_pointer += GEN8_CSB_ENTRIES; @@ -2113,24 +2112,25 @@ static int i915_execlists(struct seq_file *m, void *data) read_pointer, write_pointer); for (i = 0; i < GEN8_CSB_ENTRIES; i++) { - status = I915_READ(RING_CONTEXT_STATUS_BUF_LO(ring, i)); - ctx_id = I915_READ(RING_CONTEXT_STATUS_BUF_HI(ring, i)); + status = I915_READ(RING_CONTEXT_STATUS_BUF_LO(engine, i)); + ctx_id = I915_READ(RING_CONTEXT_STATUS_BUF_HI(engine, i)); seq_printf(m, "\tStatus buffer %d: 0x%08X, context: %u\n", i, status, ctx_id); } - spin_lock_irqsave(&ring->execlist_lock, flags); - list_for_each(cursor, &ring->execlist_queue) + spin_lock_irqsave(&engine->execlist_lock, flags); + list_for_each(cursor, &engine->execlist_queue) count++; - head_req = list_first_entry_or_null(&ring->execlist_queue, - struct drm_i915_gem_request, execlist_link); - spin_unlock_irqrestore(&ring->execlist_lock, flags); + head_req = list_first_entry_or_null(&engine->execlist_queue, + struct drm_i915_gem_request, + execlist_link); + spin_unlock_irqrestore(&engine->execlist_lock, flags); seq_printf(m, "\t%d requests in queue\n", count); if (head_req) { seq_printf(m, "\tHead request id: %u\n", - intel_execlists_ctx_id(head_req->ctx, ring)); + intel_execlists_ctx_id(head_req->ctx, engine)); seq_printf(m, "\tHead request tail: %u\n", head_req->tail); } @@ -2246,19 +2246,19 @@ static int per_file_ctx(int id, void *ptr, void *data) static void gen8_ppgtt_info(struct seq_file *m, struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; int unused, i; if (!ppgtt) return; - for_each_ring(ring, dev_priv, unused) { - seq_printf(m, "%s\n", ring->name); + for_each_ring(engine, dev_priv, unused) { + seq_printf(m, "%s\n", engine->name); for (i = 0; i < 4; i++) { - u64 pdp = I915_READ(GEN8_RING_PDP_UDW(ring, i)); + u64 pdp = I915_READ(GEN8_RING_PDP_UDW(engine, i)); pdp <<= 32; - pdp |= I915_READ(GEN8_RING_PDP_LDW(ring, i)); + pdp |= I915_READ(GEN8_RING_PDP_LDW(engine, i)); seq_printf(m, "\tPDP%d 0x%016llx\n", i, pdp); } } @@ -2267,19 +2267,23 @@ static void gen8_ppgtt_info(struct seq_file *m, struct drm_device *dev) static void gen6_ppgtt_info(struct seq_file *m, struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; int i; if (INTEL_INFO(dev)->gen == 6) seq_printf(m, "GFX_MODE: 0x%08x\n", I915_READ(GFX_MODE)); - for_each_ring(ring, dev_priv, i) { - seq_printf(m, "%s\n", ring->name); + for_each_ring(engine, dev_priv, i) { + seq_printf(m, "%s\n", engine->name); if (INTEL_INFO(dev)->gen == 7) - seq_printf(m, "GFX_MODE: 0x%08x\n", I915_READ(RING_MODE_GEN7(ring))); - seq_printf(m, "PP_DIR_BASE: 0x%08x\n", I915_READ(RING_PP_DIR_BASE(ring))); - seq_printf(m, "PP_DIR_BASE_READ: 0x%08x\n", I915_READ(RING_PP_DIR_BASE_READ(ring))); - seq_printf(m, "PP_DIR_DCLV: 0x%08x\n", I915_READ(RING_PP_DIR_DCLV(ring))); + seq_printf(m, "GFX_MODE: 0x%08x\n", + I915_READ(RING_MODE_GEN7(engine))); + seq_printf(m, "PP_DIR_BASE: 0x%08x\n", + I915_READ(RING_PP_DIR_BASE(engine))); + seq_printf(m, "PP_DIR_BASE_READ: 0x%08x\n", + I915_READ(RING_PP_DIR_BASE_READ(engine))); + seq_printf(m, "PP_DIR_DCLV: 0x%08x\n", + I915_READ(RING_PP_DIR_DCLV(engine))); } if (dev_priv->mm.aliasing_ppgtt) { struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; @@ -2334,12 +2338,12 @@ out_put: static int count_irq_waiters(struct drm_i915_private *i915) { - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; int count = 0; int i; - for_each_ring(ring, i915, i) - count += ring->irq_refcount; + for_each_ring(engine, i915, i) + count += engine->irq_refcount; return count; } @@ -2447,7 +2451,7 @@ static void i915_guc_client_info(struct seq_file *m, struct drm_i915_private *dev_priv, struct i915_guc_client *client) { - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; uint64_t tot = 0; uint32_t i; @@ -2462,11 +2466,11 @@ static void i915_guc_client_info(struct seq_file *m, seq_printf(m, "\tFailed doorbell: %u\n", client->b_fail); seq_printf(m, "\tLast submission result: %d\n", client->retcode); - for_each_ring(ring, dev_priv, i) { + for_each_ring(engine, dev_priv, i) { seq_printf(m, "\tSubmissions: %llu %s\n", - client->submissions[ring->guc_id], - ring->name); - tot += client->submissions[ring->guc_id]; + client->submissions[engine->guc_id], + engine->name); + tot += client->submissions[engine->guc_id]; } seq_printf(m, "\tTotal: %llu\n", tot); } @@ -2478,7 +2482,7 @@ static int i915_guc_info(struct seq_file *m, void *data) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_guc guc; struct i915_guc_client client = {}; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; enum intel_ring_id i; u64 total = 0; @@ -2502,11 +2506,11 @@ static int i915_guc_info(struct seq_file *m, void *data) seq_printf(m, "GuC last action error code: %d\n", guc.action_err); seq_printf(m, "\nGuC submissions:\n"); - for_each_ring(ring, dev_priv, i) { + for_each_ring(engine, dev_priv, i) { seq_printf(m, "\t%-24s: %10llu, last seqno 0x%08x\n", - ring->name, guc.submissions[ring->guc_id], - guc.last_seqno[ring->guc_id]); - total += guc.submissions[ring->guc_id]; + engine->name, guc.submissions[engine->guc_id], + guc.last_seqno[engine->guc_id]); + total += guc.submissions[engine->guc_id]; } seq_printf(m, "\t%s: %llu\n", "Total", total); @@ -3128,7 +3132,7 @@ static int i915_semaphore_status(struct seq_file *m, void *unused) struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; int num_rings = hweight32(INTEL_INFO(dev)->ring_mask); int i, j, ret; @@ -3149,10 +3153,10 @@ static int i915_semaphore_status(struct seq_file *m, void *unused) page = i915_gem_object_get_page(dev_priv->semaphore_obj, 0); seqno = (uint64_t *)kmap_atomic(page); - for_each_ring(ring, dev_priv, i) { + for_each_ring(engine, dev_priv, i) { uint64_t offset; - seq_printf(m, "%s\n", ring->name); + seq_printf(m, "%s\n", engine->name); seq_puts(m, " Last signal:"); for (j = 0; j < num_rings; j++) { @@ -3174,17 +3178,18 @@ static int i915_semaphore_status(struct seq_file *m, void *unused) kunmap_atomic(seqno); } else { seq_puts(m, " Last signal:"); - for_each_ring(ring, dev_priv, i) + for_each_ring(engine, dev_priv, i) for (j = 0; j < num_rings; j++) seq_printf(m, "0x%08x\n", - I915_READ(ring->semaphore.mbox.signal[j])); + I915_READ(engine->semaphore.mbox.signal[j])); seq_putc(m, '\n'); } seq_puts(m, "\nSync seqno:\n"); - for_each_ring(ring, dev_priv, i) { + for_each_ring(engine, dev_priv, i) { for (j = 0; j < num_rings; j++) { - seq_printf(m, " 0x%08x ", ring->semaphore.sync_seqno[j]); + seq_printf(m, " 0x%08x ", + engine->semaphore.sync_seqno[j]); } seq_putc(m, '\n'); } @@ -3226,7 +3231,7 @@ static int i915_wa_registers(struct seq_file *m, void *unused) { int i; int ret; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -3239,9 +3244,9 @@ static int i915_wa_registers(struct seq_file *m, void *unused) intel_runtime_pm_get(dev_priv); seq_printf(m, "Workarounds applied: %d\n", workarounds->count); - for_each_ring(ring, dev_priv, i) + for_each_ring(engine, dev_priv, i) seq_printf(m, "HW whitelist count for %s: %d\n", - ring->name, workarounds->hw_whitelist_count[i]); + engine->name, workarounds->hw_whitelist_count[i]); for (i = 0; i < workarounds->count; ++i) { i915_reg_t addr; u32 mask, value, read; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index b854af2c4141..5a7f6032f066 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1243,11 +1243,11 @@ int __i915_wait_request(struct drm_i915_gem_request *req, s64 *timeout, struct intel_rps_client *rps) { - struct intel_engine_cs *ring = i915_gem_request_get_ring(req); - struct drm_device *dev = ring->dev; + struct intel_engine_cs *engine = i915_gem_request_get_ring(req); + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; const bool irq_test_in_progress = - ACCESS_ONCE(dev_priv->gpu_error.test_irq_rings) & intel_ring_flag(ring); + ACCESS_ONCE(dev_priv->gpu_error.test_irq_rings) & intel_ring_flag(engine); int state = interruptible ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE; DEFINE_WAIT(wait); unsigned long timeout_expire; @@ -1288,7 +1288,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req, if (ret == 0) goto out; - if (!irq_test_in_progress && WARN_ON(!ring->irq_get(ring))) { + if (!irq_test_in_progress && WARN_ON(!engine->irq_get(engine))) { ret = -ENODEV; goto out; } @@ -1296,7 +1296,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req, for (;;) { struct timer_list timer; - prepare_to_wait(&ring->irq_queue, &wait, state); + prepare_to_wait(&engine->irq_queue, &wait, state); /* We need to check whether any gpu reset happened in between * the caller grabbing the seqno and now ... */ @@ -1325,11 +1325,11 @@ int __i915_wait_request(struct drm_i915_gem_request *req, } timer.function = NULL; - if (timeout || missed_irq(dev_priv, ring)) { + if (timeout || missed_irq(dev_priv, engine)) { unsigned long expire; setup_timer_on_stack(&timer, fake_irq, (unsigned long)current); - expire = missed_irq(dev_priv, ring) ? jiffies + 1 : timeout_expire; + expire = missed_irq(dev_priv, engine) ? jiffies + 1 : timeout_expire; mod_timer(&timer, expire); } @@ -1341,9 +1341,9 @@ int __i915_wait_request(struct drm_i915_gem_request *req, } } if (!irq_test_in_progress) - ring->irq_put(ring); + engine->irq_put(engine); - finish_wait(&ring->irq_queue, &wait); + finish_wait(&engine->irq_queue, &wait); out: trace_i915_gem_request_wait_end(req); @@ -2404,17 +2404,17 @@ void i915_vma_move_to_active(struct i915_vma *vma, struct drm_i915_gem_request *req) { struct drm_i915_gem_object *obj = vma->obj; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; - ring = i915_gem_request_get_ring(req); + engine = i915_gem_request_get_ring(req); /* Add a reference if we're newly entering the active list. */ if (obj->active == 0) drm_gem_object_reference(&obj->base); - obj->active |= intel_ring_flag(ring); + obj->active |= intel_ring_flag(engine); - list_move_tail(&obj->ring_list[ring->id], &ring->active_list); - i915_gem_request_assign(&obj->last_read_req[ring->id], req); + list_move_tail(&obj->ring_list[engine->id], &engine->active_list); + i915_gem_request_assign(&obj->last_read_req[engine->id], req); list_move_tail(&vma->vm_link, &vma->vm->active_list); } @@ -2467,23 +2467,23 @@ static int i915_gem_init_seqno(struct drm_device *dev, u32 seqno) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; int ret, i, j; /* Carefully retire all requests without writing to the rings */ - for_each_ring(ring, dev_priv, i) { - ret = intel_ring_idle(ring); + for_each_ring(engine, dev_priv, i) { + ret = intel_ring_idle(engine); if (ret) return ret; } i915_gem_retire_requests(dev); /* Finally reset hw state */ - for_each_ring(ring, dev_priv, i) { - intel_ring_init_seqno(ring, seqno); + for_each_ring(engine, dev_priv, i) { + intel_ring_init_seqno(engine, seqno); - for (j = 0; j < ARRAY_SIZE(ring->semaphore.sync_seqno); j++) - ring->semaphore.sync_seqno[j] = 0; + for (j = 0; j < ARRAY_SIZE(engine->semaphore.sync_seqno); j++) + engine->semaphore.sync_seqno[j] = 0; } return 0; @@ -2542,7 +2542,7 @@ void __i915_add_request(struct drm_i915_gem_request *request, struct drm_i915_gem_object *obj, bool flush_caches) { - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; struct drm_i915_private *dev_priv; struct intel_ringbuffer *ringbuf; u32 request_start; @@ -2551,8 +2551,8 @@ void __i915_add_request(struct drm_i915_gem_request *request, if (WARN_ON(request == NULL)) return; - ring = request->ring; - dev_priv = ring->dev->dev_private; + engine = request->ring; + dev_priv = engine->dev->dev_private; ringbuf = request->ringbuf; /* @@ -2587,9 +2587,9 @@ void __i915_add_request(struct drm_i915_gem_request *request, request->postfix = intel_ring_get_tail(ringbuf); if (i915.enable_execlists) - ret = ring->emit_request(request); + ret = engine->emit_request(request); else { - ret = ring->add_request(request); + ret = engine->add_request(request); request->tail = intel_ring_get_tail(ringbuf); } @@ -2607,13 +2607,13 @@ void __i915_add_request(struct drm_i915_gem_request *request, request->batch_obj = obj; request->emitted_jiffies = jiffies; - request->previous_seqno = ring->last_submitted_seqno; - ring->last_submitted_seqno = request->seqno; - list_add_tail(&request->list, &ring->request_list); + request->previous_seqno = engine->last_submitted_seqno; + engine->last_submitted_seqno = request->seqno; + list_add_tail(&request->list, &engine->request_list); trace_i915_gem_request_add(request); - i915_queue_hangcheck(ring->dev); + i915_queue_hangcheck(engine->dev); queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, @@ -2885,7 +2885,7 @@ static void i915_gem_reset_ring_cleanup(struct drm_i915_private *dev_priv, void i915_gem_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; int i; /* @@ -2893,11 +2893,11 @@ void i915_gem_reset(struct drm_device *dev) * them for finding the guilty party. As the requests only borrow * their reference to the objects, the inspection must be done first. */ - for_each_ring(ring, dev_priv, i) - i915_gem_reset_ring_status(dev_priv, ring); + for_each_ring(engine, dev_priv, i) + i915_gem_reset_ring_status(dev_priv, engine); - for_each_ring(ring, dev_priv, i) - i915_gem_reset_ring_cleanup(dev_priv, ring); + for_each_ring(engine, dev_priv, i) + i915_gem_reset_ring_cleanup(dev_priv, engine); i915_gem_context_reset(dev); @@ -2962,19 +2962,19 @@ bool i915_gem_retire_requests(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; bool idle = true; int i; - for_each_ring(ring, dev_priv, i) { - i915_gem_retire_requests_ring(ring); - idle &= list_empty(&ring->request_list); + for_each_ring(engine, dev_priv, i) { + i915_gem_retire_requests_ring(engine); + idle &= list_empty(&engine->request_list); if (i915.enable_execlists) { - spin_lock_irq(&ring->execlist_lock); - idle &= list_empty(&ring->execlist_queue); - spin_unlock_irq(&ring->execlist_lock); + spin_lock_irq(&engine->execlist_lock); + idle &= list_empty(&engine->execlist_queue); + spin_unlock_irq(&engine->execlist_lock); - intel_execlists_retire_requests(ring); + intel_execlists_retire_requests(engine); } } @@ -3025,11 +3025,11 @@ i915_gem_idle_work_handler(struct work_struct *work) intel_mark_idle(dev); if (mutex_trylock(&dev->struct_mutex)) { - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; int i; - for_each_ring(ring, dev_priv, i) - i915_gem_batch_pool_fini(&ring->batch_pool); + for_each_ring(engine, dev_priv, i) + i915_gem_batch_pool_fini(&engine->batch_pool); mutex_unlock(&dev->struct_mutex); } @@ -3391,15 +3391,15 @@ int __i915_vma_unbind_no_wait(struct i915_vma *vma) int i915_gpu_idle(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; int ret, i; /* Flush everything onto the inactive list. */ - for_each_ring(ring, dev_priv, i) { + for_each_ring(engine, dev_priv, i) { if (!i915.enable_execlists) { struct drm_i915_gem_request *req; - req = i915_gem_request_alloc(ring, NULL); + req = i915_gem_request_alloc(engine, NULL); if (IS_ERR(req)) return PTR_ERR(req); @@ -3412,7 +3412,7 @@ int i915_gpu_idle(struct drm_device *dev) i915_add_request_no_flush(req); } - ret = intel_ring_idle(ring); + ret = intel_ring_idle(engine); if (ret) return ret; } @@ -4656,11 +4656,11 @@ static void i915_gem_stop_ringbuffers(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; int i; - for_each_ring(ring, dev_priv, i) - dev_priv->gt.stop_ring(ring); + for_each_ring(engine, dev_priv, i) + dev_priv->gt.stop_ring(engine); } int @@ -4697,8 +4697,8 @@ err: int i915_gem_l3_remap(struct drm_i915_gem_request *req, int slice) { - struct intel_engine_cs *ring = req->ring; - struct drm_device *dev = ring->dev; + struct intel_engine_cs *engine = req->ring; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; u32 *remap_info = dev_priv->l3_parity.remap_info[slice]; int i, ret; @@ -4716,12 +4716,12 @@ int i915_gem_l3_remap(struct drm_i915_gem_request *req, int slice) * at initialization time. */ for (i = 0; i < GEN7_L3LOG_SIZE / 4; i++) { - intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); - intel_ring_emit_reg(ring, GEN7_L3LOG(slice, i)); - intel_ring_emit(ring, remap_info[i]); + intel_ring_emit(engine, MI_LOAD_REGISTER_IMM(1)); + intel_ring_emit_reg(engine, GEN7_L3LOG(slice, i)); + intel_ring_emit(engine, remap_info[i]); } - intel_ring_advance(ring); + intel_ring_advance(engine); return ret; } @@ -4829,7 +4829,7 @@ int i915_gem_init_hw(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; int ret, i, j; if (INTEL_INFO(dev)->gen < 6 && !intel_enable_gtt()) @@ -4876,8 +4876,8 @@ i915_gem_init_hw(struct drm_device *dev) } /* Need to do basic initialisation of all rings first: */ - for_each_ring(ring, dev_priv, i) { - ret = ring->init_hw(ring); + for_each_ring(engine, dev_priv, i) { + ret = engine->init_hw(engine); if (ret) goto out; } @@ -4901,17 +4901,17 @@ i915_gem_init_hw(struct drm_device *dev) goto out; /* Now it is safe to go back round and do everything else: */ - for_each_ring(ring, dev_priv, i) { + for_each_ring(engine, dev_priv, i) { struct drm_i915_gem_request *req; - req = i915_gem_request_alloc(ring, NULL); + req = i915_gem_request_alloc(engine, NULL); if (IS_ERR(req)) { ret = PTR_ERR(req); i915_gem_cleanup_ringbuffer(dev); goto out; } - if (ring->id == RCS) { + if (engine->id == RCS) { for (j = 0; j < NUM_L3_SLICES(dev); j++) i915_gem_l3_remap(req, j); } @@ -5006,11 +5006,11 @@ void i915_gem_cleanup_ringbuffer(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; int i; - for_each_ring(ring, dev_priv, i) - dev_priv->gt.cleanup_ring(ring); + for_each_ring(engine, dev_priv, i) + dev_priv->gt.cleanup_ring(engine); if (i915.enable_execlists) /* diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 5dd84e148bba..cc07666c2d91 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -346,11 +346,11 @@ void i915_gem_context_reset(struct drm_device *dev) } for (i = 0; i < I915_NUM_RINGS; i++) { - struct intel_engine_cs *ring = &dev_priv->ring[i]; + struct intel_engine_cs *engine = &dev_priv->ring[i]; - if (ring->last_context) { - i915_gem_context_unpin(ring->last_context, ring); - ring->last_context = NULL; + if (engine->last_context) { + i915_gem_context_unpin(engine->last_context, engine); + engine->last_context = NULL; } } @@ -427,11 +427,11 @@ void i915_gem_context_fini(struct drm_device *dev) } for (i = I915_NUM_RINGS; --i >= 0;) { - struct intel_engine_cs *ring = &dev_priv->ring[i]; + struct intel_engine_cs *engine = &dev_priv->ring[i]; - if (ring->last_context) { - i915_gem_context_unpin(ring->last_context, ring); - ring->last_context = NULL; + if (engine->last_context) { + i915_gem_context_unpin(engine->last_context, engine); + engine->last_context = NULL; } } @@ -441,14 +441,14 @@ void i915_gem_context_fini(struct drm_device *dev) int i915_gem_context_enable(struct drm_i915_gem_request *req) { - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; int ret; if (i915.enable_execlists) { - if (ring->init_context == NULL) + if (engine->init_context == NULL) return 0; - ret = ring->init_context(req); + ret = engine->init_context(req); } else ret = i915_switch_context(req); @@ -510,12 +510,12 @@ i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id) static inline int mi_set_context(struct drm_i915_gem_request *req, u32 hw_flags) { - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; u32 flags = hw_flags | MI_MM_SPACE_GTT; const int num_rings = /* Use an extended w/a on ivb+ if signalling from other rings */ - i915_semaphore_is_enabled(ring->dev) ? - hweight32(INTEL_INFO(ring->dev)->ring_mask) - 1 : + i915_semaphore_is_enabled(engine->dev) ? + hweight32(INTEL_INFO(engine->dev)->ring_mask) - 1 : 0; int len, i, ret; @@ -524,21 +524,21 @@ mi_set_context(struct drm_i915_gem_request *req, u32 hw_flags) * explicitly, so we rely on the value at ring init, stored in * itlb_before_ctx_switch. */ - if (IS_GEN6(ring->dev)) { - ret = ring->flush(req, I915_GEM_GPU_DOMAINS, 0); + if (IS_GEN6(engine->dev)) { + ret = engine->flush(req, I915_GEM_GPU_DOMAINS, 0); if (ret) return ret; } /* These flags are for resource streamer on HSW+ */ - if (IS_HASWELL(ring->dev) || INTEL_INFO(ring->dev)->gen >= 8) + if (IS_HASWELL(engine->dev) || INTEL_INFO(engine->dev)->gen >= 8) flags |= (HSW_MI_RS_SAVE_STATE_EN | HSW_MI_RS_RESTORE_STATE_EN); - else if (INTEL_INFO(ring->dev)->gen < 8) + else if (INTEL_INFO(engine->dev)->gen < 8) flags |= (MI_SAVE_EXT_STATE_EN | MI_RESTORE_EXT_STATE_EN); len = 4; - if (INTEL_INFO(ring->dev)->gen >= 7) + if (INTEL_INFO(engine->dev)->gen >= 7) len += 2 + (num_rings ? 4*num_rings + 2 : 0); ret = intel_ring_begin(req, len); @@ -546,49 +546,56 @@ mi_set_context(struct drm_i915_gem_request *req, u32 hw_flags) return ret; /* WaProgramMiArbOnOffAroundMiSetContext:ivb,vlv,hsw,bdw,chv */ - if (INTEL_INFO(ring->dev)->gen >= 7) { - intel_ring_emit(ring, MI_ARB_ON_OFF | MI_ARB_DISABLE); + if (INTEL_INFO(engine->dev)->gen >= 7) { + intel_ring_emit(engine, MI_ARB_ON_OFF | MI_ARB_DISABLE); if (num_rings) { struct intel_engine_cs *signaller; - intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(num_rings)); - for_each_ring(signaller, to_i915(ring->dev), i) { - if (signaller == ring) + intel_ring_emit(engine, + MI_LOAD_REGISTER_IMM(num_rings)); + for_each_ring(signaller, to_i915(engine->dev), i) { + if (signaller == engine) continue; - intel_ring_emit_reg(ring, RING_PSMI_CTL(signaller->mmio_base)); - intel_ring_emit(ring, _MASKED_BIT_ENABLE(GEN6_PSMI_SLEEP_MSG_DISABLE)); + intel_ring_emit_reg(engine, + RING_PSMI_CTL(signaller->mmio_base)); + intel_ring_emit(engine, + _MASKED_BIT_ENABLE(GEN6_PSMI_SLEEP_MSG_DISABLE)); } } } - intel_ring_emit(ring, MI_NOOP); - intel_ring_emit(ring, MI_SET_CONTEXT); - intel_ring_emit(ring, i915_gem_obj_ggtt_offset(req->ctx->legacy_hw_ctx.rcs_state) | + intel_ring_emit(engine, MI_NOOP); + intel_ring_emit(engine, MI_SET_CONTEXT); + intel_ring_emit(engine, + i915_gem_obj_ggtt_offset(req->ctx->legacy_hw_ctx.rcs_state) | flags); /* * w/a: MI_SET_CONTEXT must always be followed by MI_NOOP * WaMiSetContext_Hang:snb,ivb,vlv */ - intel_ring_emit(ring, MI_NOOP); + intel_ring_emit(engine, MI_NOOP); - if (INTEL_INFO(ring->dev)->gen >= 7) { + if (INTEL_INFO(engine->dev)->gen >= 7) { if (num_rings) { struct intel_engine_cs *signaller; - intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(num_rings)); - for_each_ring(signaller, to_i915(ring->dev), i) { - if (signaller == ring) + intel_ring_emit(engine, + MI_LOAD_REGISTER_IMM(num_rings)); + for_each_ring(signaller, to_i915(engine->dev), i) { + if (signaller == engine) continue; - intel_ring_emit_reg(ring, RING_PSMI_CTL(signaller->mmio_base)); - intel_ring_emit(ring, _MASKED_BIT_DISABLE(GEN6_PSMI_SLEEP_MSG_DISABLE)); + intel_ring_emit_reg(engine, + RING_PSMI_CTL(signaller->mmio_base)); + intel_ring_emit(engine, + _MASKED_BIT_DISABLE(GEN6_PSMI_SLEEP_MSG_DISABLE)); } } - intel_ring_emit(ring, MI_ARB_ON_OFF | MI_ARB_ENABLE); + intel_ring_emit(engine, MI_ARB_ON_OFF | MI_ARB_ENABLE); } - intel_ring_advance(ring); + intel_ring_advance(engine); return ret; } @@ -648,25 +655,26 @@ needs_pd_load_post(struct intel_engine_cs *ring, struct intel_context *to, static int do_switch(struct drm_i915_gem_request *req) { struct intel_context *to = req->ctx; - struct intel_engine_cs *ring = req->ring; - struct drm_i915_private *dev_priv = ring->dev->dev_private; - struct intel_context *from = ring->last_context; + struct intel_engine_cs *engine = req->ring; + struct drm_i915_private *dev_priv = engine->dev->dev_private; + struct intel_context *from = engine->last_context; u32 hw_flags = 0; bool uninitialized = false; int ret, i; - if (from != NULL && ring == &dev_priv->ring[RCS]) { + if (from != NULL && engine == &dev_priv->ring[RCS]) { BUG_ON(from->legacy_hw_ctx.rcs_state == NULL); BUG_ON(!i915_gem_obj_is_pinned(from->legacy_hw_ctx.rcs_state)); } - if (should_skip_switch(ring, from, to)) + if (should_skip_switch(engine, from, to)) return 0; /* Trying to pin first makes error handling easier. */ - if (ring == &dev_priv->ring[RCS]) { + if (engine == &dev_priv->ring[RCS]) { ret = i915_gem_obj_ggtt_pin(to->legacy_hw_ctx.rcs_state, - get_context_alignment(ring->dev), 0); + get_context_alignment(engine->dev), + 0); if (ret) return ret; } @@ -676,23 +684,23 @@ static int do_switch(struct drm_i915_gem_request *req) * evict_everything - as a last ditch gtt defrag effort that also * switches to the default context. Hence we need to reload from here. */ - from = ring->last_context; + from = engine->last_context; - if (needs_pd_load_pre(ring, to)) { + if (needs_pd_load_pre(engine, to)) { /* Older GENs and non render rings still want the load first, * "PP_DCLV followed by PP_DIR_BASE register through Load * Register Immediate commands in Ring Buffer before submitting * a context."*/ - trace_switch_mm(ring, to); + trace_switch_mm(engine, to); ret = to->ppgtt->switch_mm(to->ppgtt, req); if (ret) goto unpin_out; /* Doing a PD load always reloads the page dirs */ - to->ppgtt->pd_dirty_rings &= ~intel_ring_flag(ring); + to->ppgtt->pd_dirty_rings &= ~intel_ring_flag(engine); } - if (ring != &dev_priv->ring[RCS]) { + if (engine != &dev_priv->ring[RCS]) { if (from) i915_gem_context_unreference(from); goto done; @@ -717,14 +725,14 @@ static int do_switch(struct drm_i915_gem_request *req) * space. This means we must enforce that a page table load * occur when this occurs. */ } else if (to->ppgtt && - (intel_ring_flag(ring) & to->ppgtt->pd_dirty_rings)) { + (intel_ring_flag(engine) & to->ppgtt->pd_dirty_rings)) { hw_flags |= MI_FORCE_RESTORE; - to->ppgtt->pd_dirty_rings &= ~intel_ring_flag(ring); + to->ppgtt->pd_dirty_rings &= ~intel_ring_flag(engine); } /* We should never emit switch_mm more than once */ - WARN_ON(needs_pd_load_pre(ring, to) && - needs_pd_load_post(ring, to, hw_flags)); + WARN_ON(needs_pd_load_pre(engine, to) && + needs_pd_load_post(engine, to, hw_flags)); ret = mi_set_context(req, hw_flags); if (ret) @@ -733,8 +741,8 @@ static int do_switch(struct drm_i915_gem_request *req) /* GEN8 does *not* require an explicit reload if the PDPs have been * setup, and we do not wish to move them. */ - if (needs_pd_load_post(ring, to, hw_flags)) { - trace_switch_mm(ring, to); + if (needs_pd_load_post(engine, to, hw_flags)) { + trace_switch_mm(engine, to); ret = to->ppgtt->switch_mm(to->ppgtt, req); /* The hardware context switch is emitted, but we haven't * actually changed the state - so it's probably safe to bail @@ -787,11 +795,11 @@ static int do_switch(struct drm_i915_gem_request *req) done: i915_gem_context_reference(to); - ring->last_context = to; + engine->last_context = to; if (uninitialized) { - if (ring->init_context) { - ret = ring->init_context(req); + if (engine->init_context) { + ret = engine->init_context(req); if (ret) DRM_ERROR("ring init context: %d\n", ret); } @@ -800,7 +808,7 @@ done: return 0; unpin_out: - if (ring->id == RCS) + if (engine->id == RCS) i915_gem_object_ggtt_unpin(to->legacy_hw_ctx.rcs_state); return ret; } @@ -820,18 +828,18 @@ unpin_out: */ int i915_switch_context(struct drm_i915_gem_request *req) { - struct intel_engine_cs *ring = req->ring; - struct drm_i915_private *dev_priv = ring->dev->dev_private; + struct intel_engine_cs *engine = req->ring; + struct drm_i915_private *dev_priv = engine->dev->dev_private; WARN_ON(i915.enable_execlists); WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); if (req->ctx->legacy_hw_ctx.rcs_state == NULL) { /* We have the fake context */ - if (req->ctx != ring->last_context) { + if (req->ctx != engine->last_context) { i915_gem_context_reference(req->ctx); - if (ring->last_context) - i915_gem_context_unreference(ring->last_context); - ring->last_context = req->ctx; + if (engine->last_context) + i915_gem_context_unreference(engine->last_context); + engine->last_context = req->ctx; } return 0; } diff --git a/drivers/gpu/drm/i915/i915_gem_debug.c b/drivers/gpu/drm/i915/i915_gem_debug.c index 17299d04189f..202a7e6ae295 100644 --- a/drivers/gpu/drm/i915/i915_gem_debug.c +++ b/drivers/gpu/drm/i915/i915_gem_debug.c @@ -36,29 +36,30 @@ i915_verify_lists(struct drm_device *dev) static int warned; struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_gem_object *obj; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; int err = 0; int i; if (warned) return 0; - for_each_ring(ring, dev_priv, i) { - list_for_each_entry(obj, &ring->active_list, ring_list[ring->id]) { + for_each_ring(engine, dev_priv, i) { + list_for_each_entry(obj, &engine->active_list, + ring_list[engine->id]) { if (obj->base.dev != dev || !atomic_read(&obj->base.refcount.refcount)) { DRM_ERROR("%s: freed active obj %p\n", - ring->name, obj); + engine->name, obj); err++; break; } else if (!obj->active || - obj->last_read_req[ring->id] == NULL) { + obj->last_read_req[engine->id] == NULL) { DRM_ERROR("%s: invalid active obj %p\n", - ring->name, obj); + engine->name, obj); err++; } else if (obj->base.write_domain) { DRM_ERROR("%s: invalid write obj %p (w %x)\n", - ring->name, + engine->name, obj, obj->base.write_domain); err++; } diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 1328bc5021b4..b73496ea5583 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -1095,7 +1095,7 @@ void i915_gem_execbuffer_move_to_active(struct list_head *vmas, struct drm_i915_gem_request *req) { - struct intel_engine_cs *ring = i915_gem_request_get_ring(req); + struct intel_engine_cs *engine = i915_gem_request_get_ring(req); struct i915_vma *vma; list_for_each_entry(vma, vmas, exec_list) { @@ -1122,7 +1122,7 @@ i915_gem_execbuffer_move_to_active(struct list_head *vmas, if (entry->flags & EXEC_OBJECT_NEEDS_FENCE) { i915_gem_request_assign(&obj->last_fenced_req, req); if (entry->flags & __EXEC_OBJECT_HAS_FENCE) { - struct drm_i915_private *dev_priv = to_i915(ring->dev); + struct drm_i915_private *dev_priv = to_i915(engine->dev); list_move_tail(&dev_priv->fence_regs[obj->fence_reg].lru_list, &dev_priv->mm.fence_list); } @@ -1146,11 +1146,11 @@ static int i915_reset_gen7_sol_offsets(struct drm_device *dev, struct drm_i915_gem_request *req) { - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; struct drm_i915_private *dev_priv = dev->dev_private; int ret, i; - if (!IS_GEN7(dev) || ring != &dev_priv->ring[RCS]) { + if (!IS_GEN7(dev) || engine != &dev_priv->ring[RCS]) { DRM_DEBUG("sol reset is gen7/rcs only\n"); return -EINVAL; } @@ -1160,12 +1160,12 @@ i915_reset_gen7_sol_offsets(struct drm_device *dev, return ret; for (i = 0; i < 4; i++) { - intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); - intel_ring_emit_reg(ring, GEN7_SO_WRITE_OFFSET(i)); - intel_ring_emit(ring, 0); + intel_ring_emit(engine, MI_LOAD_REGISTER_IMM(1)); + intel_ring_emit_reg(engine, GEN7_SO_WRITE_OFFSET(i)); + intel_ring_emit(engine, 0); } - intel_ring_advance(ring); + intel_ring_advance(engine); return 0; } @@ -1229,7 +1229,7 @@ i915_gem_ringbuffer_submission(struct i915_execbuffer_params *params, struct list_head *vmas) { struct drm_device *dev = params->dev; - struct intel_engine_cs *ring = params->ring; + struct intel_engine_cs *engine = params->ring; struct drm_i915_private *dev_priv = dev->dev_private; u64 exec_start, exec_len; int instp_mode; @@ -1244,8 +1244,8 @@ i915_gem_ringbuffer_submission(struct i915_execbuffer_params *params, if (ret) return ret; - WARN(params->ctx->ppgtt && params->ctx->ppgtt->pd_dirty_rings & (1<id), - "%s didn't clear reload\n", ring->name); + WARN(params->ctx->ppgtt && params->ctx->ppgtt->pd_dirty_rings & (1<id), + "%s didn't clear reload\n", engine->name); instp_mode = args->flags & I915_EXEC_CONSTANTS_MASK; instp_mask = I915_EXEC_CONSTANTS_MASK; @@ -1253,7 +1253,7 @@ i915_gem_ringbuffer_submission(struct i915_execbuffer_params *params, case I915_EXEC_CONSTANTS_REL_GENERAL: case I915_EXEC_CONSTANTS_ABSOLUTE: case I915_EXEC_CONSTANTS_REL_SURFACE: - if (instp_mode != 0 && ring != &dev_priv->ring[RCS]) { + if (instp_mode != 0 && engine != &dev_priv->ring[RCS]) { DRM_DEBUG("non-0 rel constants mode on non-RCS\n"); return -EINVAL; } @@ -1280,17 +1280,17 @@ i915_gem_ringbuffer_submission(struct i915_execbuffer_params *params, return -EINVAL; } - if (ring == &dev_priv->ring[RCS] && + if (engine == &dev_priv->ring[RCS] && instp_mode != dev_priv->relative_constants_mode) { ret = intel_ring_begin(params->request, 4); if (ret) return ret; - intel_ring_emit(ring, MI_NOOP); - intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); - intel_ring_emit_reg(ring, INSTPM); - intel_ring_emit(ring, instp_mask << 16 | instp_mode); - intel_ring_advance(ring); + intel_ring_emit(engine, MI_NOOP); + intel_ring_emit(engine, MI_LOAD_REGISTER_IMM(1)); + intel_ring_emit_reg(engine, INSTPM); + intel_ring_emit(engine, instp_mask << 16 | instp_mode); + intel_ring_advance(engine); dev_priv->relative_constants_mode = instp_mode; } @@ -1308,7 +1308,7 @@ i915_gem_ringbuffer_submission(struct i915_execbuffer_params *params, if (exec_len == 0) exec_len = params->batch_obj->base.size; - ret = ring->dispatch_execbuffer(params->request, + ret = engine->dispatch_execbuffer(params->request, exec_start, exec_len, params->dispatch_flags); if (ret) @@ -1432,7 +1432,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, struct eb_vmas *eb; struct drm_i915_gem_object *batch_obj; struct drm_i915_gem_exec_object2 shadow_exec_entry; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; struct intel_context *ctx; struct i915_address_space *vm; struct i915_execbuffer_params params_master; /* XXX: will be removed later */ @@ -1459,7 +1459,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, if (args->flags & I915_EXEC_IS_PINNED) dispatch_flags |= I915_DISPATCH_PINNED; - ret = eb_select_ring(dev_priv, file, args, &ring); + ret = eb_select_ring(dev_priv, file, args, &engine); if (ret) return ret; @@ -1473,9 +1473,9 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, DRM_DEBUG("RS is only allowed for Haswell, Gen8 and above\n"); return -EINVAL; } - if (ring->id != RCS) { + if (engine->id != RCS) { DRM_DEBUG("RS is not available on %s\n", - ring->name); + engine->name); return -EINVAL; } @@ -1488,7 +1488,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, if (ret) goto pre_mutex_err; - ctx = i915_gem_validate_context(dev, file, ring, ctx_id); + ctx = i915_gem_validate_context(dev, file, engine, ctx_id); if (IS_ERR(ctx)) { mutex_unlock(&dev->struct_mutex); ret = PTR_ERR(ctx); @@ -1522,7 +1522,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, /* Move the objects en-masse into the GTT, evicting if necessary. */ need_relocs = (args->flags & I915_EXEC_NO_RELOC) == 0; - ret = i915_gem_execbuffer_reserve(ring, &eb->vmas, ctx, &need_relocs); + ret = i915_gem_execbuffer_reserve(engine, &eb->vmas, ctx, + &need_relocs); if (ret) goto err; @@ -1531,7 +1532,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, ret = i915_gem_execbuffer_relocate(eb); if (ret) { if (ret == -EFAULT) { - ret = i915_gem_execbuffer_relocate_slow(dev, args, file, ring, + ret = i915_gem_execbuffer_relocate_slow(dev, args, file, + engine, eb, exec, ctx); BUG_ON(!mutex_is_locked(&dev->struct_mutex)); } @@ -1547,16 +1549,16 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, } params->args_batch_start_offset = args->batch_start_offset; - if (i915_needs_cmd_parser(ring) && args->batch_len) { + if (i915_needs_cmd_parser(engine) && args->batch_len) { struct drm_i915_gem_object *parsed_batch_obj; - parsed_batch_obj = i915_gem_execbuffer_parse(ring, - &shadow_exec_entry, - eb, - batch_obj, - args->batch_start_offset, - args->batch_len, - file->is_master); + parsed_batch_obj = i915_gem_execbuffer_parse(engine, + &shadow_exec_entry, + eb, + batch_obj, + args->batch_start_offset, + args->batch_len, + file->is_master); if (IS_ERR(parsed_batch_obj)) { ret = PTR_ERR(parsed_batch_obj); goto err; @@ -1608,7 +1610,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, params->batch_obj_vm_offset = i915_gem_obj_offset(batch_obj, vm); /* Allocate a request for this batch buffer nice and early. */ - req = i915_gem_request_alloc(ring, ctx); + req = i915_gem_request_alloc(engine, ctx); if (IS_ERR(req)) { ret = PTR_ERR(req); goto err_batch_unpin; @@ -1626,7 +1628,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, */ params->dev = dev; params->file = file; - params->ring = ring; + params->ring = engine; params->dispatch_flags = dispatch_flags; params->batch_obj = batch_obj; params->ctx = ctx; diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 7b8de85c5f76..1bc77791bc96 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -658,7 +658,7 @@ static int gen8_write_pdp(struct drm_i915_gem_request *req, unsigned entry, dma_addr_t addr) { - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; int ret; BUG_ON(entry >= 4); @@ -667,13 +667,13 @@ static int gen8_write_pdp(struct drm_i915_gem_request *req, if (ret) return ret; - intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); - intel_ring_emit_reg(ring, GEN8_RING_PDP_UDW(ring, entry)); - intel_ring_emit(ring, upper_32_bits(addr)); - intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); - intel_ring_emit_reg(ring, GEN8_RING_PDP_LDW(ring, entry)); - intel_ring_emit(ring, lower_32_bits(addr)); - intel_ring_advance(ring); + intel_ring_emit(engine, MI_LOAD_REGISTER_IMM(1)); + intel_ring_emit_reg(engine, GEN8_RING_PDP_UDW(engine, entry)); + intel_ring_emit(engine, upper_32_bits(addr)); + intel_ring_emit(engine, MI_LOAD_REGISTER_IMM(1)); + intel_ring_emit_reg(engine, GEN8_RING_PDP_LDW(engine, entry)); + intel_ring_emit(engine, lower_32_bits(addr)); + intel_ring_advance(engine); return 0; } @@ -1650,11 +1650,11 @@ static uint32_t get_pd_offset(struct i915_hw_ppgtt *ppgtt) static int hsw_mm_switch(struct i915_hw_ppgtt *ppgtt, struct drm_i915_gem_request *req) { - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; int ret; /* NB: TLBs must be flushed and invalidated before a switch */ - ret = ring->flush(req, I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); + ret = engine->flush(req, I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); if (ret) return ret; @@ -1662,13 +1662,13 @@ static int hsw_mm_switch(struct i915_hw_ppgtt *ppgtt, if (ret) return ret; - intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(2)); - intel_ring_emit_reg(ring, RING_PP_DIR_DCLV(ring)); - intel_ring_emit(ring, PP_DIR_DCLV_2G); - intel_ring_emit_reg(ring, RING_PP_DIR_BASE(ring)); - intel_ring_emit(ring, get_pd_offset(ppgtt)); - intel_ring_emit(ring, MI_NOOP); - intel_ring_advance(ring); + intel_ring_emit(engine, MI_LOAD_REGISTER_IMM(2)); + intel_ring_emit_reg(engine, RING_PP_DIR_DCLV(engine)); + intel_ring_emit(engine, PP_DIR_DCLV_2G); + intel_ring_emit_reg(engine, RING_PP_DIR_BASE(engine)); + intel_ring_emit(engine, get_pd_offset(ppgtt)); + intel_ring_emit(engine, MI_NOOP); + intel_ring_advance(engine); return 0; } @@ -1676,22 +1676,22 @@ static int hsw_mm_switch(struct i915_hw_ppgtt *ppgtt, static int vgpu_mm_switch(struct i915_hw_ppgtt *ppgtt, struct drm_i915_gem_request *req) { - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; struct drm_i915_private *dev_priv = to_i915(ppgtt->base.dev); - I915_WRITE(RING_PP_DIR_DCLV(ring), PP_DIR_DCLV_2G); - I915_WRITE(RING_PP_DIR_BASE(ring), get_pd_offset(ppgtt)); + I915_WRITE(RING_PP_DIR_DCLV(engine), PP_DIR_DCLV_2G); + I915_WRITE(RING_PP_DIR_BASE(engine), get_pd_offset(ppgtt)); return 0; } static int gen7_mm_switch(struct i915_hw_ppgtt *ppgtt, struct drm_i915_gem_request *req) { - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; int ret; /* NB: TLBs must be flushed and invalidated before a switch */ - ret = ring->flush(req, I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); + ret = engine->flush(req, I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); if (ret) return ret; @@ -1699,17 +1699,17 @@ static int gen7_mm_switch(struct i915_hw_ppgtt *ppgtt, if (ret) return ret; - intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(2)); - intel_ring_emit_reg(ring, RING_PP_DIR_DCLV(ring)); - intel_ring_emit(ring, PP_DIR_DCLV_2G); - intel_ring_emit_reg(ring, RING_PP_DIR_BASE(ring)); - intel_ring_emit(ring, get_pd_offset(ppgtt)); - intel_ring_emit(ring, MI_NOOP); - intel_ring_advance(ring); + intel_ring_emit(engine, MI_LOAD_REGISTER_IMM(2)); + intel_ring_emit_reg(engine, RING_PP_DIR_DCLV(engine)); + intel_ring_emit(engine, PP_DIR_DCLV_2G); + intel_ring_emit_reg(engine, RING_PP_DIR_BASE(engine)); + intel_ring_emit(engine, get_pd_offset(ppgtt)); + intel_ring_emit(engine, MI_NOOP); + intel_ring_advance(engine); /* XXX: RCS is the only one to auto invalidate the TLBs? */ - if (ring->id != RCS) { - ret = ring->flush(req, I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); + if (engine->id != RCS) { + ret = engine->flush(req, I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); if (ret) return ret; } @@ -1720,15 +1720,15 @@ static int gen7_mm_switch(struct i915_hw_ppgtt *ppgtt, static int gen6_mm_switch(struct i915_hw_ppgtt *ppgtt, struct drm_i915_gem_request *req) { - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; struct drm_device *dev = ppgtt->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - I915_WRITE(RING_PP_DIR_DCLV(ring), PP_DIR_DCLV_2G); - I915_WRITE(RING_PP_DIR_BASE(ring), get_pd_offset(ppgtt)); + I915_WRITE(RING_PP_DIR_DCLV(engine), PP_DIR_DCLV_2G); + I915_WRITE(RING_PP_DIR_BASE(engine), get_pd_offset(ppgtt)); - POSTING_READ(RING_PP_DIR_DCLV(ring)); + POSTING_READ(RING_PP_DIR_DCLV(engine)); return 0; } @@ -1736,12 +1736,12 @@ static int gen6_mm_switch(struct i915_hw_ppgtt *ppgtt, static void gen8_ppgtt_enable(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; int j; - for_each_ring(ring, dev_priv, j) { + for_each_ring(engine, dev_priv, j) { u32 four_level = USES_FULL_48BIT_PPGTT(dev) ? GEN8_GFX_PPGTT_48B : 0; - I915_WRITE(RING_MODE_GEN7(ring), + I915_WRITE(RING_MODE_GEN7(engine), _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE | four_level)); } } @@ -1749,7 +1749,7 @@ static void gen8_ppgtt_enable(struct drm_device *dev) static void gen7_ppgtt_enable(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; uint32_t ecochk, ecobits; int i; @@ -1765,9 +1765,9 @@ static void gen7_ppgtt_enable(struct drm_device *dev) } I915_WRITE(GAM_ECOCHK, ecochk); - for_each_ring(ring, dev_priv, i) { + for_each_ring(engine, dev_priv, i) { /* GFX_MODE is per-ring on gen7+ */ - I915_WRITE(RING_MODE_GEN7(ring), + I915_WRITE(RING_MODE_GEN7(engine), _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE)); } } @@ -2286,15 +2286,15 @@ static void undo_idling(struct drm_i915_private *dev_priv, bool interruptible) void i915_check_and_clear_faults(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; int i; if (INTEL_INFO(dev)->gen < 6) return; - for_each_ring(ring, dev_priv, i) { + for_each_ring(engine, dev_priv, i) { u32 fault_reg; - fault_reg = I915_READ(RING_FAULT_REG(ring)); + fault_reg = I915_READ(RING_FAULT_REG(engine)); if (fault_reg & RING_FAULT_VALID) { DRM_DEBUG_DRIVER("Unexpected fault\n" "\tAddr: 0x%08lx\n" @@ -2305,7 +2305,7 @@ void i915_check_and_clear_faults(struct drm_device *dev) fault_reg & RING_FAULT_GTTSEL_MASK ? "GGTT" : "PPGTT", RING_FAULT_SRCID(fault_reg), RING_FAULT_FAULT_TYPE(fault_reg)); - I915_WRITE(RING_FAULT_REG(ring), + I915_WRITE(RING_FAULT_REG(engine), fault_reg & ~RING_FAULT_VALID); } } diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 13b5f3aed01c..d97cadcfccb1 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -495,9 +495,9 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, if (obj) { u64 wa_ctx_offset = obj->gtt_offset; u32 *wa_ctx_page = &obj->pages[0][0]; - struct intel_engine_cs *ring = &dev_priv->ring[RCS]; - u32 wa_ctx_size = (ring->wa_ctx.indirect_ctx.size + - ring->wa_ctx.per_ctx.size); + struct intel_engine_cs *engine = &dev_priv->ring[RCS]; + u32 wa_ctx_size = (engine->wa_ctx.indirect_ctx.size + + engine->wa_ctx.per_ctx.size); err_printf(m, "%s --- WA ctx batch buffer = 0x%08llx\n", dev_priv->ring[i].name, wa_ctx_offset); @@ -1019,19 +1019,19 @@ static void i915_gem_record_rings(struct drm_device *dev, int i, count; for (i = 0; i < I915_NUM_RINGS; i++) { - struct intel_engine_cs *ring = &dev_priv->ring[i]; + struct intel_engine_cs *engine = &dev_priv->ring[i]; struct intel_ringbuffer *rbuf; error->ring[i].pid = -1; - if (ring->dev == NULL) + if (engine->dev == NULL) continue; error->ring[i].valid = true; - i915_record_ring_state(dev, error, ring, &error->ring[i]); + i915_record_ring_state(dev, error, engine, &error->ring[i]); - request = i915_gem_find_active_request(ring); + request = i915_gem_find_active_request(engine); if (request) { struct i915_address_space *vm; @@ -1051,7 +1051,7 @@ static void i915_gem_record_rings(struct drm_device *dev, if (HAS_BROKEN_CS_TLB(dev_priv->dev)) error->ring[i].wa_batchbuffer = i915_error_ggtt_object_create(dev_priv, - ring->scratch.obj); + engine->scratch.obj); if (request->pid) { struct task_struct *task; @@ -1073,11 +1073,11 @@ static void i915_gem_record_rings(struct drm_device *dev, * executed). */ if (request) - rbuf = request->ctx->engine[ring->id].ringbuf; + rbuf = request->ctx->engine[engine->id].ringbuf; else - rbuf = dev_priv->kernel_context->engine[ring->id].ringbuf; + rbuf = dev_priv->kernel_context->engine[engine->id].ringbuf; } else - rbuf = ring->buffer; + rbuf = engine->buffer; error->ring[i].cpu_ring_head = rbuf->head; error->ring[i].cpu_ring_tail = rbuf->tail; @@ -1086,18 +1086,19 @@ static void i915_gem_record_rings(struct drm_device *dev, i915_error_ggtt_object_create(dev_priv, rbuf->obj); error->ring[i].hws_page = - i915_error_ggtt_object_create(dev_priv, ring->status_page.obj); + i915_error_ggtt_object_create(dev_priv, + engine->status_page.obj); - if (ring->wa_ctx.obj) { + if (engine->wa_ctx.obj) { error->ring[i].wa_ctx = i915_error_ggtt_object_create(dev_priv, - ring->wa_ctx.obj); + engine->wa_ctx.obj); } - i915_gem_record_active_context(ring, error, &error->ring[i]); + i915_gem_record_active_context(engine, error, &error->ring[i]); count = 0; - list_for_each_entry(request, &ring->request_list, list) + list_for_each_entry(request, &engine->request_list, list) count++; error->ring[i].num_requests = count; @@ -1110,7 +1111,7 @@ static void i915_gem_record_rings(struct drm_device *dev, } count = 0; - list_for_each_entry(request, &ring->request_list, list) { + list_for_each_entry(request, &engine->request_list, list) { struct drm_i915_error_request *erq; if (count >= error->ring[i].num_requests) { diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index d7543efc8a5e..15a4beb387d4 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -377,7 +377,7 @@ static void guc_init_ctx_desc(struct intel_guc *guc, struct i915_guc_client *client) { struct drm_i915_private *dev_priv = guc_to_i915(guc); - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; struct intel_context *ctx = client->owner; struct guc_context_desc desc; struct sg_table *sg; @@ -390,8 +390,8 @@ static void guc_init_ctx_desc(struct intel_guc *guc, desc.priority = client->priority; desc.db_id = client->doorbell_id; - for_each_ring(ring, dev_priv, i) { - struct guc_execlist_context *lrc = &desc.lrc[ring->guc_id]; + for_each_ring(engine, dev_priv, i) { + struct guc_execlist_context *lrc = &desc.lrc[engine->guc_id]; struct drm_i915_gem_object *obj; uint64_t ctx_desc; @@ -406,14 +406,14 @@ static void guc_init_ctx_desc(struct intel_guc *guc, if (!obj) break; /* XXX: continue? */ - ctx_desc = intel_lr_context_descriptor(ctx, ring); + ctx_desc = intel_lr_context_descriptor(ctx, engine); lrc->context_desc = (u32)ctx_desc; /* The state page is after PPHWSP */ lrc->ring_lcra = i915_gem_obj_ggtt_offset(obj) + LRC_STATE_PN * PAGE_SIZE; lrc->context_id = (client->ctx_index << GUC_ELC_CTXID_OFFSET) | - (ring->guc_id << GUC_ELC_ENGINE_OFFSET); + (engine->guc_id << GUC_ELC_ENGINE_OFFSET); obj = ctx->engine[i].ringbuf->obj; @@ -422,7 +422,7 @@ static void guc_init_ctx_desc(struct intel_guc *guc, lrc->ring_next_free_location = lrc->ring_begin; lrc->ring_current_tail_pointer_value = 0; - desc.engines_used |= (1 << ring->guc_id); + desc.engines_used |= (1 << engine->guc_id); } WARN_ON(desc.engines_used == 0); @@ -839,7 +839,7 @@ static void guc_create_ads(struct intel_guc *guc) struct guc_ads *ads; struct guc_policies *policies; struct guc_mmio_reg_state *reg_state; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; struct page *page; u32 size, i; @@ -867,11 +867,11 @@ static void guc_create_ads(struct intel_guc *guc) * so its address won't change after we've told the GuC where * to find it. */ - ring = &dev_priv->ring[RCS]; - ads->golden_context_lrca = ring->status_page.gfx_addr; + engine = &dev_priv->ring[RCS]; + ads->golden_context_lrca = engine->status_page.gfx_addr; - for_each_ring(ring, dev_priv, i) - ads->eng_state_size[ring->guc_id] = intel_lr_context_size(ring); + for_each_ring(engine, dev_priv, i) + ads->eng_state_size[engine->guc_id] = intel_lr_context_size(engine); /* GuC scheduling policies */ policies = (void *)ads + sizeof(struct guc_ads); @@ -883,12 +883,12 @@ static void guc_create_ads(struct intel_guc *guc) /* MMIO reg state */ reg_state = (void *)policies + sizeof(struct guc_policies); - for_each_ring(ring, dev_priv, i) { - reg_state->mmio_white_list[ring->guc_id].mmio_start = - ring->mmio_base + GUC_MMIO_WHITE_LIST_START; + for_each_ring(engine, dev_priv, i) { + reg_state->mmio_white_list[engine->guc_id].mmio_start = + engine->mmio_base + GUC_MMIO_WHITE_LIST_START; /* Nothing to be saved or restored for now. */ - reg_state->mmio_white_list[ring->guc_id].count = 0; + reg_state->mmio_white_list[engine->guc_id].count = 0; } ads->reg_state_addr = ads->scheduler_policies + diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 53e5104964b3..f172de0a61bf 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1079,11 +1079,11 @@ static u32 vlv_wa_c0_ei(struct drm_i915_private *dev_priv, u32 pm_iir) static bool any_waiters(struct drm_i915_private *dev_priv) { - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; int i; - for_each_ring(ring, dev_priv, i) - if (ring->irq_refcount) + for_each_ring(engine, dev_priv, i) + if (engine->irq_refcount) return true; return false; @@ -2449,7 +2449,7 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) static void i915_error_wake_up(struct drm_i915_private *dev_priv, bool reset_completed) { - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; int i; /* @@ -2460,8 +2460,8 @@ static void i915_error_wake_up(struct drm_i915_private *dev_priv, */ /* Wake up __wait_seqno, potentially holding dev->struct_mutex. */ - for_each_ring(ring, dev_priv, i) - wake_up_all(&ring->irq_queue); + for_each_ring(engine, dev_priv, i) + wake_up_all(&engine->irq_queue); /* Wake up intel_crtc_wait_for_pending_flips, holding crtc->mutex. */ wake_up_all(&dev_priv->pending_flip_queue); @@ -2956,11 +2956,11 @@ static int semaphore_passed(struct intel_engine_cs *ring) static void semaphore_clear_deadlocks(struct drm_i915_private *dev_priv) { - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; int i; - for_each_ring(ring, dev_priv, i) - ring->hangcheck.deadlock = 0; + for_each_ring(engine, dev_priv, i) + engine->hangcheck.deadlock = 0; } static bool subunits_stuck(struct intel_engine_cs *ring) @@ -3071,7 +3071,7 @@ static void i915_hangcheck_elapsed(struct work_struct *work) container_of(work, typeof(*dev_priv), gpu_error.hangcheck_work.work); struct drm_device *dev = dev_priv->dev; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; int i; int busy_count = 0, rings_hung = 0; bool stuck[I915_NUM_RINGS] = { 0 }; @@ -3096,33 +3096,33 @@ static void i915_hangcheck_elapsed(struct work_struct *work) */ intel_uncore_arm_unclaimed_mmio_detection(dev_priv); - for_each_ring(ring, dev_priv, i) { + for_each_ring(engine, dev_priv, i) { u64 acthd; u32 seqno; bool busy = true; semaphore_clear_deadlocks(dev_priv); - seqno = ring->get_seqno(ring, false); - acthd = intel_ring_get_active_head(ring); + seqno = engine->get_seqno(engine, false); + acthd = intel_ring_get_active_head(engine); - if (ring->hangcheck.seqno == seqno) { - if (ring_idle(ring, seqno)) { - ring->hangcheck.action = HANGCHECK_IDLE; + if (engine->hangcheck.seqno == seqno) { + if (ring_idle(engine, seqno)) { + engine->hangcheck.action = HANGCHECK_IDLE; - if (waitqueue_active(&ring->irq_queue)) { + if (waitqueue_active(&engine->irq_queue)) { /* Issue a wake-up to catch stuck h/w. */ - if (!test_and_set_bit(ring->id, &dev_priv->gpu_error.missed_irq_rings)) { - if (!(dev_priv->gpu_error.test_irq_rings & intel_ring_flag(ring))) + if (!test_and_set_bit(engine->id, &dev_priv->gpu_error.missed_irq_rings)) { + if (!(dev_priv->gpu_error.test_irq_rings & intel_ring_flag(engine))) DRM_ERROR("Hangcheck timer elapsed... %s idle\n", - ring->name); + engine->name); else DRM_INFO("Fake missed irq on %s\n", - ring->name); - wake_up_all(&ring->irq_queue); + engine->name); + wake_up_all(&engine->irq_queue); } /* Safeguard against driver failure */ - ring->hangcheck.score += BUSY; + engine->hangcheck.score += BUSY; } else busy = false; } else { @@ -3141,53 +3141,53 @@ static void i915_hangcheck_elapsed(struct work_struct *work) * being repeatedly kicked and so responsible * for stalling the machine. */ - ring->hangcheck.action = ring_stuck(ring, - acthd); + engine->hangcheck.action = ring_stuck(engine, + acthd); - switch (ring->hangcheck.action) { + switch (engine->hangcheck.action) { case HANGCHECK_IDLE: case HANGCHECK_WAIT: break; case HANGCHECK_ACTIVE: - ring->hangcheck.score += BUSY; + engine->hangcheck.score += BUSY; break; case HANGCHECK_KICK: - ring->hangcheck.score += KICK; + engine->hangcheck.score += KICK; break; case HANGCHECK_HUNG: - ring->hangcheck.score += HUNG; + engine->hangcheck.score += HUNG; stuck[i] = true; break; } } } else { - ring->hangcheck.action = HANGCHECK_ACTIVE; + engine->hangcheck.action = HANGCHECK_ACTIVE; /* Gradually reduce the count so that we catch DoS * attempts across multiple batches. */ - if (ring->hangcheck.score > 0) - ring->hangcheck.score -= ACTIVE_DECAY; - if (ring->hangcheck.score < 0) - ring->hangcheck.score = 0; + if (engine->hangcheck.score > 0) + engine->hangcheck.score -= ACTIVE_DECAY; + if (engine->hangcheck.score < 0) + engine->hangcheck.score = 0; /* Clear head and subunit states on seqno movement */ - ring->hangcheck.acthd = 0; + engine->hangcheck.acthd = 0; - memset(ring->hangcheck.instdone, 0, - sizeof(ring->hangcheck.instdone)); + memset(engine->hangcheck.instdone, 0, + sizeof(engine->hangcheck.instdone)); } - ring->hangcheck.seqno = seqno; - ring->hangcheck.acthd = acthd; + engine->hangcheck.seqno = seqno; + engine->hangcheck.acthd = acthd; busy_count += busy; } - for_each_ring(ring, dev_priv, i) { - if (ring->hangcheck.score >= HANGCHECK_SCORE_RING_HUNG) { + for_each_ring(engine, dev_priv, i) { + if (engine->hangcheck.score >= HANGCHECK_SCORE_RING_HUNG) { DRM_INFO("%s on %s\n", stuck[i] ? "stuck" : "no progress", - ring->name); + engine->name); rings_hung++; } } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 4c04dab36305..e95f2b7ed962 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10984,7 +10984,7 @@ static int intel_gen2_queue_flip(struct drm_device *dev, struct drm_i915_gem_request *req, uint32_t flags) { - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); u32 flip_mask; int ret; @@ -11000,13 +11000,13 @@ static int intel_gen2_queue_flip(struct drm_device *dev, flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; else flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; - intel_ring_emit(ring, MI_WAIT_FOR_EVENT | flip_mask); - intel_ring_emit(ring, MI_NOOP); - intel_ring_emit(ring, MI_DISPLAY_FLIP | + intel_ring_emit(engine, MI_WAIT_FOR_EVENT | flip_mask); + intel_ring_emit(engine, MI_NOOP); + intel_ring_emit(engine, MI_DISPLAY_FLIP | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); - intel_ring_emit(ring, fb->pitches[0]); - intel_ring_emit(ring, intel_crtc->unpin_work->gtt_offset); - intel_ring_emit(ring, 0); /* aux display base address, unused */ + intel_ring_emit(engine, fb->pitches[0]); + intel_ring_emit(engine, intel_crtc->unpin_work->gtt_offset); + intel_ring_emit(engine, 0); /* aux display base address, unused */ intel_mark_page_flip_active(intel_crtc->unpin_work); return 0; @@ -11019,7 +11019,7 @@ static int intel_gen3_queue_flip(struct drm_device *dev, struct drm_i915_gem_request *req, uint32_t flags) { - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); u32 flip_mask; int ret; @@ -11032,13 +11032,13 @@ static int intel_gen3_queue_flip(struct drm_device *dev, flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; else flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; - intel_ring_emit(ring, MI_WAIT_FOR_EVENT | flip_mask); - intel_ring_emit(ring, MI_NOOP); - intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | + intel_ring_emit(engine, MI_WAIT_FOR_EVENT | flip_mask); + intel_ring_emit(engine, MI_NOOP); + intel_ring_emit(engine, MI_DISPLAY_FLIP_I915 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); - intel_ring_emit(ring, fb->pitches[0]); - intel_ring_emit(ring, intel_crtc->unpin_work->gtt_offset); - intel_ring_emit(ring, MI_NOOP); + intel_ring_emit(engine, fb->pitches[0]); + intel_ring_emit(engine, intel_crtc->unpin_work->gtt_offset); + intel_ring_emit(engine, MI_NOOP); intel_mark_page_flip_active(intel_crtc->unpin_work); return 0; @@ -11051,7 +11051,7 @@ static int intel_gen4_queue_flip(struct drm_device *dev, struct drm_i915_gem_request *req, uint32_t flags) { - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); uint32_t pf, pipesrc; @@ -11065,10 +11065,10 @@ static int intel_gen4_queue_flip(struct drm_device *dev, * Display Registers (which do not change across a page-flip) * so we need only reprogram the base address. */ - intel_ring_emit(ring, MI_DISPLAY_FLIP | + intel_ring_emit(engine, MI_DISPLAY_FLIP | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); - intel_ring_emit(ring, fb->pitches[0]); - intel_ring_emit(ring, intel_crtc->unpin_work->gtt_offset | + intel_ring_emit(engine, fb->pitches[0]); + intel_ring_emit(engine, intel_crtc->unpin_work->gtt_offset | obj->tiling_mode); /* XXX Enabling the panel-fitter across page-flip is so far @@ -11077,7 +11077,7 @@ static int intel_gen4_queue_flip(struct drm_device *dev, */ pf = 0; pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff; - intel_ring_emit(ring, pf | pipesrc); + intel_ring_emit(engine, pf | pipesrc); intel_mark_page_flip_active(intel_crtc->unpin_work); return 0; @@ -11090,7 +11090,7 @@ static int intel_gen6_queue_flip(struct drm_device *dev, struct drm_i915_gem_request *req, uint32_t flags) { - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); uint32_t pf, pipesrc; @@ -11100,10 +11100,10 @@ static int intel_gen6_queue_flip(struct drm_device *dev, if (ret) return ret; - intel_ring_emit(ring, MI_DISPLAY_FLIP | + intel_ring_emit(engine, MI_DISPLAY_FLIP | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); - intel_ring_emit(ring, fb->pitches[0] | obj->tiling_mode); - intel_ring_emit(ring, intel_crtc->unpin_work->gtt_offset); + intel_ring_emit(engine, fb->pitches[0] | obj->tiling_mode); + intel_ring_emit(engine, intel_crtc->unpin_work->gtt_offset); /* Contrary to the suggestions in the documentation, * "Enable Panel Fitter" does not seem to be required when page @@ -11113,7 +11113,7 @@ static int intel_gen6_queue_flip(struct drm_device *dev, */ pf = 0; pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff; - intel_ring_emit(ring, pf | pipesrc); + intel_ring_emit(engine, pf | pipesrc); intel_mark_page_flip_active(intel_crtc->unpin_work); return 0; @@ -11126,7 +11126,7 @@ static int intel_gen7_queue_flip(struct drm_device *dev, struct drm_i915_gem_request *req, uint32_t flags) { - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); uint32_t plane_bit = 0; int len, ret; @@ -11147,7 +11147,7 @@ static int intel_gen7_queue_flip(struct drm_device *dev, } len = 4; - if (ring->id == RCS) { + if (engine->id == RCS) { len += 6; /* * On Gen 8, SRM is now taking an extra dword to accommodate @@ -11185,30 +11185,30 @@ static int intel_gen7_queue_flip(struct drm_device *dev, * for the RCS also doesn't appear to drop events. Setting the DERRMR * to zero does lead to lockups within MI_DISPLAY_FLIP. */ - if (ring->id == RCS) { - intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); - intel_ring_emit_reg(ring, DERRMR); - intel_ring_emit(ring, ~(DERRMR_PIPEA_PRI_FLIP_DONE | - DERRMR_PIPEB_PRI_FLIP_DONE | - DERRMR_PIPEC_PRI_FLIP_DONE)); + if (engine->id == RCS) { + intel_ring_emit(engine, MI_LOAD_REGISTER_IMM(1)); + intel_ring_emit_reg(engine, DERRMR); + intel_ring_emit(engine, ~(DERRMR_PIPEA_PRI_FLIP_DONE | + DERRMR_PIPEB_PRI_FLIP_DONE | + DERRMR_PIPEC_PRI_FLIP_DONE)); if (IS_GEN8(dev)) - intel_ring_emit(ring, MI_STORE_REGISTER_MEM_GEN8 | + intel_ring_emit(engine, MI_STORE_REGISTER_MEM_GEN8 | MI_SRM_LRM_GLOBAL_GTT); else - intel_ring_emit(ring, MI_STORE_REGISTER_MEM | + intel_ring_emit(engine, MI_STORE_REGISTER_MEM | MI_SRM_LRM_GLOBAL_GTT); - intel_ring_emit_reg(ring, DERRMR); - intel_ring_emit(ring, ring->scratch.gtt_offset + 256); + intel_ring_emit_reg(engine, DERRMR); + intel_ring_emit(engine, engine->scratch.gtt_offset + 256); if (IS_GEN8(dev)) { - intel_ring_emit(ring, 0); - intel_ring_emit(ring, MI_NOOP); + intel_ring_emit(engine, 0); + intel_ring_emit(engine, MI_NOOP); } } - intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane_bit); - intel_ring_emit(ring, (fb->pitches[0] | obj->tiling_mode)); - intel_ring_emit(ring, intel_crtc->unpin_work->gtt_offset); - intel_ring_emit(ring, (MI_NOOP)); + intel_ring_emit(engine, MI_DISPLAY_FLIP_I915 | plane_bit); + intel_ring_emit(engine, (fb->pitches[0] | obj->tiling_mode)); + intel_ring_emit(engine, intel_crtc->unpin_work->gtt_offset); + intel_ring_emit(engine, (MI_NOOP)); intel_mark_page_flip_active(intel_crtc->unpin_work); return 0; @@ -11488,7 +11488,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, struct drm_plane *primary = crtc->primary; enum pipe pipe = intel_crtc->pipe; struct intel_unpin_work *work; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; bool mmio_flip; struct drm_i915_gem_request *request = NULL; int ret; @@ -11575,21 +11575,21 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, work->flip_count = I915_READ(PIPE_FLIPCOUNT_G4X(pipe)) + 1; if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) { - ring = &dev_priv->ring[BCS]; + engine = &dev_priv->ring[BCS]; if (obj->tiling_mode != intel_fb_obj(work->old_fb)->tiling_mode) /* vlv: DISPLAY_FLIP fails to change tiling */ - ring = NULL; + engine = NULL; } else if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) { - ring = &dev_priv->ring[BCS]; + engine = &dev_priv->ring[BCS]; } else if (INTEL_INFO(dev)->gen >= 7) { - ring = i915_gem_request_get_ring(obj->last_write_req); - if (ring == NULL || ring->id != RCS) - ring = &dev_priv->ring[BCS]; + engine = i915_gem_request_get_ring(obj->last_write_req); + if (engine == NULL || engine->id != RCS) + engine = &dev_priv->ring[BCS]; } else { - ring = &dev_priv->ring[RCS]; + engine = &dev_priv->ring[RCS]; } - mmio_flip = use_mmio_flip(ring, obj); + mmio_flip = use_mmio_flip(engine, obj); /* When using CS flips, we want to emit semaphores between rings. * However, when using mmio flips we will create a task to do the @@ -11597,7 +11597,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, * into the display plane and skip any waits. */ if (!mmio_flip) { - ret = i915_gem_object_sync(obj, ring, &request); + ret = i915_gem_object_sync(obj, engine, &request); if (ret) goto cleanup_pending; } @@ -11619,7 +11619,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, obj->last_write_req); } else { if (!request) { - request = i915_gem_request_alloc(ring, NULL); + request = i915_gem_request_alloc(engine, NULL); if (IS_ERR(request)) { ret = PTR_ERR(request); goto cleanup_unpin; diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c index 82a3c03fbc0e..fc2c5188b095 100644 --- a/drivers/gpu/drm/i915/intel_guc_loader.c +++ b/drivers/gpu/drm/i915/intel_guc_loader.c @@ -81,14 +81,14 @@ const char *intel_guc_fw_status_repr(enum intel_guc_fw_status status) static void direct_interrupts_to_host(struct drm_i915_private *dev_priv) { - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; int i, irqs; /* tell all command streamers NOT to forward interrupts and vblank to GuC */ irqs = _MASKED_FIELD(GFX_FORWARD_VBLANK_MASK, GFX_FORWARD_VBLANK_NEVER); irqs |= _MASKED_BIT_DISABLE(GFX_INTERRUPT_STEERING); - for_each_ring(ring, dev_priv, i) - I915_WRITE(RING_MODE_GEN7(ring), irqs); + for_each_ring(engine, dev_priv, i) + I915_WRITE(RING_MODE_GEN7(engine), irqs); /* route all GT interrupts to the host */ I915_WRITE(GUC_BCS_RCS_IER, 0); @@ -98,14 +98,14 @@ static void direct_interrupts_to_host(struct drm_i915_private *dev_priv) static void direct_interrupts_to_guc(struct drm_i915_private *dev_priv) { - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; int i, irqs; /* tell all command streamers to forward interrupts and vblank to GuC */ irqs = _MASKED_FIELD(GFX_FORWARD_VBLANK_MASK, GFX_FORWARD_VBLANK_ALWAYS); irqs |= _MASKED_BIT_ENABLE(GFX_INTERRUPT_STEERING); - for_each_ring(ring, dev_priv, i) - I915_WRITE(RING_MODE_GEN7(ring), irqs); + for_each_ring(engine, dev_priv, i) + I915_WRITE(RING_MODE_GEN7(engine), irqs); /* route USER_INTERRUPT to Host, all others are sent to GuC. */ irqs = GT_RENDER_USER_INTERRUPT << GEN8_RCS_IRQ_SHIFT | diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 6fcbf6bb0479..448c68e69194 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -360,8 +360,8 @@ static void execlists_elsp_write(struct drm_i915_gem_request *rq0, struct drm_i915_gem_request *rq1) { - struct intel_engine_cs *ring = rq0->ring; - struct drm_device *dev = ring->dev; + struct intel_engine_cs *engine = rq0->ring; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; uint64_t desc[2]; @@ -376,15 +376,15 @@ static void execlists_elsp_write(struct drm_i915_gem_request *rq0, rq0->elsp_submitted++; /* You must always write both descriptors in the order below. */ - I915_WRITE_FW(RING_ELSP(ring), upper_32_bits(desc[1])); - I915_WRITE_FW(RING_ELSP(ring), lower_32_bits(desc[1])); + I915_WRITE_FW(RING_ELSP(engine), upper_32_bits(desc[1])); + I915_WRITE_FW(RING_ELSP(engine), lower_32_bits(desc[1])); - I915_WRITE_FW(RING_ELSP(ring), upper_32_bits(desc[0])); + I915_WRITE_FW(RING_ELSP(engine), upper_32_bits(desc[0])); /* The context is automatically loaded after the following */ - I915_WRITE_FW(RING_ELSP(ring), lower_32_bits(desc[0])); + I915_WRITE_FW(RING_ELSP(engine), lower_32_bits(desc[0])); /* ELSP is a wo register, use another nearby reg for posting */ - POSTING_READ_FW(RING_EXECLIST_STATUS_LO(ring)); + POSTING_READ_FW(RING_EXECLIST_STATUS_LO(engine)); } static void @@ -398,9 +398,9 @@ execlists_update_context_pdps(struct i915_hw_ppgtt *ppgtt, u32 *reg_state) static void execlists_update_context(struct drm_i915_gem_request *rq) { - struct intel_engine_cs *ring = rq->ring; + struct intel_engine_cs *engine = rq->ring; struct i915_hw_ppgtt *ppgtt = rq->ctx->ppgtt; - uint32_t *reg_state = rq->ctx->engine[ring->id].lrc_reg_state; + uint32_t *reg_state = rq->ctx->engine[engine->id].lrc_reg_state; reg_state[CTX_RING_TAIL+1] = rq->tail; @@ -609,25 +609,25 @@ void intel_lrc_irq_handler(struct intel_engine_cs *ring) static void execlists_context_queue(struct drm_i915_gem_request *request) { - struct intel_engine_cs *ring = request->ring; + struct intel_engine_cs *engine = request->ring; struct drm_i915_gem_request *cursor; int num_elements = 0; if (request->ctx != request->i915->kernel_context) - intel_lr_context_pin(request->ctx, ring); + intel_lr_context_pin(request->ctx, engine); i915_gem_request_reference(request); - spin_lock_irq(&ring->execlist_lock); + spin_lock_irq(&engine->execlist_lock); - list_for_each_entry(cursor, &ring->execlist_queue, execlist_link) + list_for_each_entry(cursor, &engine->execlist_queue, execlist_link) if (++num_elements > 2) break; if (num_elements > 2) { struct drm_i915_gem_request *tail_req; - tail_req = list_last_entry(&ring->execlist_queue, + tail_req = list_last_entry(&engine->execlist_queue, struct drm_i915_gem_request, execlist_link); @@ -635,32 +635,32 @@ static void execlists_context_queue(struct drm_i915_gem_request *request) WARN(tail_req->elsp_submitted != 0, "More than 2 already-submitted reqs queued\n"); list_move_tail(&tail_req->execlist_link, - &ring->execlist_retired_req_list); + &engine->execlist_retired_req_list); } } - list_add_tail(&request->execlist_link, &ring->execlist_queue); + list_add_tail(&request->execlist_link, &engine->execlist_queue); if (num_elements == 0) - execlists_context_unqueue(ring); + execlists_context_unqueue(engine); - spin_unlock_irq(&ring->execlist_lock); + spin_unlock_irq(&engine->execlist_lock); } static int logical_ring_invalidate_all_caches(struct drm_i915_gem_request *req) { - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; uint32_t flush_domains; int ret; flush_domains = 0; - if (ring->gpu_caches_dirty) + if (engine->gpu_caches_dirty) flush_domains = I915_GEM_GPU_DOMAINS; - ret = ring->emit_flush(req, I915_GEM_GPU_DOMAINS, flush_domains); + ret = engine->emit_flush(req, I915_GEM_GPU_DOMAINS, flush_domains); if (ret) return ret; - ring->gpu_caches_dirty = false; + engine->gpu_caches_dirty = false; return 0; } @@ -726,7 +726,7 @@ static int logical_ring_wait_for_space(struct drm_i915_gem_request *req, int bytes) { struct intel_ringbuffer *ringbuf = req->ringbuf; - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; struct drm_i915_gem_request *target; unsigned space; int ret; @@ -737,7 +737,7 @@ static int logical_ring_wait_for_space(struct drm_i915_gem_request *req, /* The whole point of reserving space is to not wait! */ WARN_ON(ringbuf->reserved_in_use); - list_for_each_entry(target, &ring->request_list, list) { + list_for_each_entry(target, &engine->request_list, list) { /* * The request queue is per-engine, so can contain requests * from multiple ringbuffers. Here, we must ignore any that @@ -753,7 +753,7 @@ static int logical_ring_wait_for_space(struct drm_i915_gem_request *req, break; } - if (WARN_ON(&target->list == &ring->request_list)) + if (WARN_ON(&target->list == &engine->request_list)) return -ENOSPC; ret = i915_wait_request(target); @@ -947,9 +947,9 @@ int intel_execlists_submission(struct i915_execbuffer_params *params, struct list_head *vmas) { struct drm_device *dev = params->dev; - struct intel_engine_cs *ring = params->ring; + struct intel_engine_cs *engine = params->ring; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_ringbuffer *ringbuf = params->ctx->engine[ring->id].ringbuf; + struct intel_ringbuffer *ringbuf = params->ctx->engine[engine->id].ringbuf; u64 exec_start; int instp_mode; u32 instp_mask; @@ -961,7 +961,7 @@ int intel_execlists_submission(struct i915_execbuffer_params *params, case I915_EXEC_CONSTANTS_REL_GENERAL: case I915_EXEC_CONSTANTS_ABSOLUTE: case I915_EXEC_CONSTANTS_REL_SURFACE: - if (instp_mode != 0 && ring != &dev_priv->ring[RCS]) { + if (instp_mode != 0 && engine != &dev_priv->ring[RCS]) { DRM_DEBUG("non-0 rel constants mode on non-RCS\n"); return -EINVAL; } @@ -990,7 +990,7 @@ int intel_execlists_submission(struct i915_execbuffer_params *params, if (ret) return ret; - if (ring == &dev_priv->ring[RCS] && + if (engine == &dev_priv->ring[RCS] && instp_mode != dev_priv->relative_constants_mode) { ret = intel_logical_ring_begin(params->request, 4); if (ret) @@ -1008,7 +1008,7 @@ int intel_execlists_submission(struct i915_execbuffer_params *params, exec_start = params->batch_obj_vm_offset + args->batch_start_offset; - ret = ring->emit_bb_start(params->request, exec_start, params->dispatch_flags); + ret = engine->emit_bb_start(params->request, exec_start, params->dispatch_flags); if (ret) return ret; @@ -1071,17 +1071,17 @@ void intel_logical_ring_stop(struct intel_engine_cs *ring) int logical_ring_flush_all_caches(struct drm_i915_gem_request *req) { - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; int ret; - if (!ring->gpu_caches_dirty) + if (!engine->gpu_caches_dirty) return 0; - ret = ring->emit_flush(req, 0, I915_GEM_GPU_DOMAINS); + ret = engine->emit_flush(req, 0, I915_GEM_GPU_DOMAINS); if (ret) return ret; - ring->gpu_caches_dirty = false; + engine->gpu_caches_dirty = false; return 0; } @@ -1172,16 +1172,16 @@ void intel_lr_context_unpin(struct intel_context *ctx, static int intel_logical_ring_workarounds_emit(struct drm_i915_gem_request *req) { int ret, i; - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; struct intel_ringbuffer *ringbuf = req->ringbuf; - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct i915_workarounds *w = &dev_priv->workarounds; if (w->count == 0) return 0; - ring->gpu_caches_dirty = true; + engine->gpu_caches_dirty = true; ret = logical_ring_flush_all_caches(req); if (ret) return ret; @@ -1199,7 +1199,7 @@ static int intel_logical_ring_workarounds_emit(struct drm_i915_gem_request *req) intel_logical_ring_advance(ringbuf); - ring->gpu_caches_dirty = true; + engine->gpu_caches_dirty = true; ret = logical_ring_flush_all_caches(req); if (ret) return ret; @@ -1643,7 +1643,7 @@ static int gen9_init_render_ring(struct intel_engine_cs *ring) static int intel_logical_ring_emit_pdps(struct drm_i915_gem_request *req) { struct i915_hw_ppgtt *ppgtt = req->ctx->ppgtt; - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; struct intel_ringbuffer *ringbuf = req->ringbuf; const int num_lri_cmds = GEN8_LEGACY_PDPES * 2; int i, ret; @@ -1656,9 +1656,11 @@ static int intel_logical_ring_emit_pdps(struct drm_i915_gem_request *req) for (i = GEN8_LEGACY_PDPES - 1; i >= 0; i--) { const dma_addr_t pd_daddr = i915_page_dir_dma_addr(ppgtt, i); - intel_logical_ring_emit_reg(ringbuf, GEN8_RING_PDP_UDW(ring, i)); + intel_logical_ring_emit_reg(ringbuf, + GEN8_RING_PDP_UDW(engine, i)); intel_logical_ring_emit(ringbuf, upper_32_bits(pd_daddr)); - intel_logical_ring_emit_reg(ringbuf, GEN8_RING_PDP_LDW(ring, i)); + intel_logical_ring_emit_reg(ringbuf, + GEN8_RING_PDP_LDW(engine, i)); intel_logical_ring_emit(ringbuf, lower_32_bits(pd_daddr)); } @@ -1748,8 +1750,8 @@ static int gen8_emit_flush(struct drm_i915_gem_request *request, u32 unused) { struct intel_ringbuffer *ringbuf = request->ringbuf; - struct intel_engine_cs *ring = ringbuf->ring; - struct drm_device *dev = ring->dev; + struct intel_engine_cs *engine = ringbuf->ring; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; uint32_t cmd; int ret; @@ -1769,7 +1771,7 @@ static int gen8_emit_flush(struct drm_i915_gem_request *request, if (invalidate_domains & I915_GEM_GPU_DOMAINS) { cmd |= MI_INVALIDATE_TLB; - if (ring == &dev_priv->ring[VCS]) + if (engine == &dev_priv->ring[VCS]) cmd |= MI_INVALIDATE_BSD; } @@ -1789,8 +1791,8 @@ static int gen8_emit_flush_render(struct drm_i915_gem_request *request, u32 flush_domains) { struct intel_ringbuffer *ringbuf = request->ringbuf; - struct intel_engine_cs *ring = ringbuf->ring; - u32 scratch_addr = ring->scratch.gtt_offset + 2 * CACHELINE_BYTES; + struct intel_engine_cs *engine = ringbuf->ring; + u32 scratch_addr = engine->scratch.gtt_offset + 2 * CACHELINE_BYTES; bool vf_flush_wa = false; u32 flags = 0; int ret; @@ -1818,7 +1820,7 @@ static int gen8_emit_flush_render(struct drm_i915_gem_request *request, * On GEN9: before VF_CACHE_INVALIDATE we need to emit a NULL * pipe control. */ - if (IS_GEN9(ring->dev)) + if (IS_GEN9(engine->dev)) vf_flush_wa = true; } @@ -2109,38 +2111,38 @@ error: static int logical_render_ring_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring = &dev_priv->ring[RCS]; + struct intel_engine_cs *engine = &dev_priv->ring[RCS]; int ret; - ring->name = "render ring"; - ring->id = RCS; - ring->exec_id = I915_EXEC_RENDER; - ring->guc_id = GUC_RENDER_ENGINE; - ring->mmio_base = RENDER_RING_BASE; + engine->name = "render ring"; + engine->id = RCS; + engine->exec_id = I915_EXEC_RENDER; + engine->guc_id = GUC_RENDER_ENGINE; + engine->mmio_base = RENDER_RING_BASE; - logical_ring_default_irqs(ring, GEN8_RCS_IRQ_SHIFT); + logical_ring_default_irqs(engine, GEN8_RCS_IRQ_SHIFT); if (HAS_L3_DPF(dev)) - ring->irq_keep_mask |= GT_RENDER_L3_PARITY_ERROR_INTERRUPT; + engine->irq_keep_mask |= GT_RENDER_L3_PARITY_ERROR_INTERRUPT; - logical_ring_default_vfuncs(dev, ring); + logical_ring_default_vfuncs(dev, engine); /* Override some for render ring. */ if (INTEL_INFO(dev)->gen >= 9) - ring->init_hw = gen9_init_render_ring; + engine->init_hw = gen9_init_render_ring; else - ring->init_hw = gen8_init_render_ring; - ring->init_context = gen8_init_rcs_context; - ring->cleanup = intel_fini_pipe_control; - ring->emit_flush = gen8_emit_flush_render; - ring->emit_request = gen8_emit_request_render; + engine->init_hw = gen8_init_render_ring; + engine->init_context = gen8_init_rcs_context; + engine->cleanup = intel_fini_pipe_control; + engine->emit_flush = gen8_emit_flush_render; + engine->emit_request = gen8_emit_request_render; - ring->dev = dev; + engine->dev = dev; - ret = intel_init_pipe_control(ring); + ret = intel_init_pipe_control(engine); if (ret) return ret; - ret = intel_init_workaround_bb(ring); + ret = intel_init_workaround_bb(engine); if (ret) { /* * We continue even if we fail to initialize WA batch @@ -2151,9 +2153,9 @@ static int logical_render_ring_init(struct drm_device *dev) ret); } - ret = logical_ring_init(dev, ring); + ret = logical_ring_init(dev, engine); if (ret) { - lrc_destroy_wa_ctx_obj(ring); + lrc_destroy_wa_ctx_obj(engine); } return ret; @@ -2162,69 +2164,69 @@ static int logical_render_ring_init(struct drm_device *dev) static int logical_bsd_ring_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring = &dev_priv->ring[VCS]; + struct intel_engine_cs *engine = &dev_priv->ring[VCS]; - ring->name = "bsd ring"; - ring->id = VCS; - ring->exec_id = I915_EXEC_BSD; - ring->guc_id = GUC_VIDEO_ENGINE; - ring->mmio_base = GEN6_BSD_RING_BASE; + engine->name = "bsd ring"; + engine->id = VCS; + engine->exec_id = I915_EXEC_BSD; + engine->guc_id = GUC_VIDEO_ENGINE; + engine->mmio_base = GEN6_BSD_RING_BASE; - logical_ring_default_irqs(ring, GEN8_VCS1_IRQ_SHIFT); - logical_ring_default_vfuncs(dev, ring); + logical_ring_default_irqs(engine, GEN8_VCS1_IRQ_SHIFT); + logical_ring_default_vfuncs(dev, engine); - return logical_ring_init(dev, ring); + return logical_ring_init(dev, engine); } static int logical_bsd2_ring_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring = &dev_priv->ring[VCS2]; + struct intel_engine_cs *engine = &dev_priv->ring[VCS2]; - ring->name = "bsd2 ring"; - ring->id = VCS2; - ring->exec_id = I915_EXEC_BSD; - ring->guc_id = GUC_VIDEO_ENGINE2; - ring->mmio_base = GEN8_BSD2_RING_BASE; + engine->name = "bsd2 ring"; + engine->id = VCS2; + engine->exec_id = I915_EXEC_BSD; + engine->guc_id = GUC_VIDEO_ENGINE2; + engine->mmio_base = GEN8_BSD2_RING_BASE; - logical_ring_default_irqs(ring, GEN8_VCS2_IRQ_SHIFT); - logical_ring_default_vfuncs(dev, ring); + logical_ring_default_irqs(engine, GEN8_VCS2_IRQ_SHIFT); + logical_ring_default_vfuncs(dev, engine); - return logical_ring_init(dev, ring); + return logical_ring_init(dev, engine); } static int logical_blt_ring_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring = &dev_priv->ring[BCS]; + struct intel_engine_cs *engine = &dev_priv->ring[BCS]; - ring->name = "blitter ring"; - ring->id = BCS; - ring->exec_id = I915_EXEC_BLT; - ring->guc_id = GUC_BLITTER_ENGINE; - ring->mmio_base = BLT_RING_BASE; + engine->name = "blitter ring"; + engine->id = BCS; + engine->exec_id = I915_EXEC_BLT; + engine->guc_id = GUC_BLITTER_ENGINE; + engine->mmio_base = BLT_RING_BASE; - logical_ring_default_irqs(ring, GEN8_BCS_IRQ_SHIFT); - logical_ring_default_vfuncs(dev, ring); + logical_ring_default_irqs(engine, GEN8_BCS_IRQ_SHIFT); + logical_ring_default_vfuncs(dev, engine); - return logical_ring_init(dev, ring); + return logical_ring_init(dev, engine); } static int logical_vebox_ring_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring = &dev_priv->ring[VECS]; + struct intel_engine_cs *engine = &dev_priv->ring[VECS]; - ring->name = "video enhancement ring"; - ring->id = VECS; - ring->exec_id = I915_EXEC_VEBOX; - ring->guc_id = GUC_VIDEOENHANCE_ENGINE; - ring->mmio_base = VEBOX_RING_BASE; + engine->name = "video enhancement ring"; + engine->id = VECS; + engine->exec_id = I915_EXEC_VEBOX; + engine->guc_id = GUC_VIDEOENHANCE_ENGINE; + engine->mmio_base = VEBOX_RING_BASE; - logical_ring_default_irqs(ring, GEN8_VECS_IRQ_SHIFT); - logical_ring_default_vfuncs(dev, ring); + logical_ring_default_irqs(engine, GEN8_VECS_IRQ_SHIFT); + logical_ring_default_vfuncs(dev, engine); - return logical_ring_init(dev, ring); + return logical_ring_init(dev, engine); } /** @@ -2639,14 +2641,14 @@ void intel_lr_context_reset(struct drm_device *dev, struct intel_context *ctx) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; int i; - for_each_ring(ring, dev_priv, i) { + for_each_ring(engine, dev_priv, i) { struct drm_i915_gem_object *ctx_obj = - ctx->engine[ring->id].state; + ctx->engine[engine->id].state; struct intel_ringbuffer *ringbuf = - ctx->engine[ring->id].ringbuf; + ctx->engine[engine->id].ringbuf; uint32_t *reg_state; struct page *page; diff --git a/drivers/gpu/drm/i915/intel_mocs.c b/drivers/gpu/drm/i915/intel_mocs.c index fed7bea19cc9..d55925987ebf 100644 --- a/drivers/gpu/drm/i915/intel_mocs.c +++ b/drivers/gpu/drm/i915/intel_mocs.c @@ -324,11 +324,11 @@ int intel_rcs_context_init_mocs(struct drm_i915_gem_request *req) if (get_mocs_settings(req->ring->dev, &t)) { struct drm_i915_private *dev_priv = req->i915; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; enum intel_ring_id ring_id; /* Program the control registers */ - for_each_ring(ring, dev_priv, ring_id) { + for_each_ring(engine, dev_priv, ring_id) { ret = emit_mocs_control_table(req, &t, ring_id); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 9168413fe204..13b27632636e 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -233,14 +233,14 @@ static int intel_overlay_on(struct intel_overlay *overlay) { struct drm_device *dev = overlay->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring = &dev_priv->ring[RCS]; + struct intel_engine_cs *engine = &dev_priv->ring[RCS]; struct drm_i915_gem_request *req; int ret; WARN_ON(overlay->active); WARN_ON(IS_I830(dev) && !(dev_priv->quirks & QUIRK_PIPEA_FORCE)); - req = i915_gem_request_alloc(ring, NULL); + req = i915_gem_request_alloc(engine, NULL); if (IS_ERR(req)) return PTR_ERR(req); @@ -252,11 +252,11 @@ static int intel_overlay_on(struct intel_overlay *overlay) overlay->active = true; - intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_ON); - intel_ring_emit(ring, overlay->flip_addr | OFC_UPDATE); - intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); - intel_ring_emit(ring, MI_NOOP); - intel_ring_advance(ring); + intel_ring_emit(engine, MI_OVERLAY_FLIP | MI_OVERLAY_ON); + intel_ring_emit(engine, overlay->flip_addr | OFC_UPDATE); + intel_ring_emit(engine, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); + intel_ring_emit(engine, MI_NOOP); + intel_ring_advance(engine); return intel_overlay_do_wait_request(overlay, req, NULL); } @@ -267,7 +267,7 @@ static int intel_overlay_continue(struct intel_overlay *overlay, { struct drm_device *dev = overlay->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring = &dev_priv->ring[RCS]; + struct intel_engine_cs *engine = &dev_priv->ring[RCS]; struct drm_i915_gem_request *req; u32 flip_addr = overlay->flip_addr; u32 tmp; @@ -283,7 +283,7 @@ static int intel_overlay_continue(struct intel_overlay *overlay, if (tmp & (1 << 17)) DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp); - req = i915_gem_request_alloc(ring, NULL); + req = i915_gem_request_alloc(engine, NULL); if (IS_ERR(req)) return PTR_ERR(req); @@ -293,9 +293,9 @@ static int intel_overlay_continue(struct intel_overlay *overlay, return ret; } - intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); - intel_ring_emit(ring, flip_addr); - intel_ring_advance(ring); + intel_ring_emit(engine, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); + intel_ring_emit(engine, flip_addr); + intel_ring_advance(engine); WARN_ON(overlay->last_flip_req); i915_gem_request_assign(&overlay->last_flip_req, req); @@ -336,7 +336,7 @@ static int intel_overlay_off(struct intel_overlay *overlay) { struct drm_device *dev = overlay->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring = &dev_priv->ring[RCS]; + struct intel_engine_cs *engine = &dev_priv->ring[RCS]; struct drm_i915_gem_request *req; u32 flip_addr = overlay->flip_addr; int ret; @@ -349,7 +349,7 @@ static int intel_overlay_off(struct intel_overlay *overlay) * of the hw. Do it in both cases */ flip_addr |= OFC_UPDATE; - req = i915_gem_request_alloc(ring, NULL); + req = i915_gem_request_alloc(engine, NULL); if (IS_ERR(req)) return PTR_ERR(req); @@ -360,22 +360,23 @@ static int intel_overlay_off(struct intel_overlay *overlay) } /* wait for overlay to go idle */ - intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); - intel_ring_emit(ring, flip_addr); - intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); + intel_ring_emit(engine, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); + intel_ring_emit(engine, flip_addr); + intel_ring_emit(engine, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); /* turn overlay off */ if (IS_I830(dev)) { /* Workaround: Don't disable the overlay fully, since otherwise * it dies on the next OVERLAY_ON cmd. */ - intel_ring_emit(ring, MI_NOOP); - intel_ring_emit(ring, MI_NOOP); - intel_ring_emit(ring, MI_NOOP); + intel_ring_emit(engine, MI_NOOP); + intel_ring_emit(engine, MI_NOOP); + intel_ring_emit(engine, MI_NOOP); } else { - intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF); - intel_ring_emit(ring, flip_addr); - intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); + intel_ring_emit(engine, MI_OVERLAY_FLIP | MI_OVERLAY_OFF); + intel_ring_emit(engine, flip_addr); + intel_ring_emit(engine, + MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); } - intel_ring_advance(ring); + intel_ring_advance(engine); return intel_overlay_do_wait_request(overlay, req, intel_overlay_off_tail); } @@ -408,7 +409,7 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay) { struct drm_device *dev = overlay->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring = &dev_priv->ring[RCS]; + struct intel_engine_cs *engine = &dev_priv->ring[RCS]; int ret; WARN_ON(!mutex_is_locked(&dev->struct_mutex)); @@ -423,7 +424,7 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay) /* synchronous slowpath */ struct drm_i915_gem_request *req; - req = i915_gem_request_alloc(ring, NULL); + req = i915_gem_request_alloc(engine, NULL); if (IS_ERR(req)) return PTR_ERR(req); @@ -433,9 +434,10 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay) return ret; } - intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); - intel_ring_emit(ring, MI_NOOP); - intel_ring_advance(ring); + intel_ring_emit(engine, + MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); + intel_ring_emit(engine, MI_NOOP); + intel_ring_advance(engine); ret = intel_overlay_do_wait_request(overlay, req, intel_overlay_release_old_vid_tail); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index d7aef17bf0f9..c54a7df7c2c9 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4815,7 +4815,7 @@ static void gen9_enable_rps(struct drm_device *dev) static void gen9_enable_rc6(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; uint32_t rc6_mask = 0; int unused; @@ -4838,8 +4838,8 @@ static void gen9_enable_rc6(struct drm_device *dev) I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16); I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */ I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */ - for_each_ring(ring, dev_priv, unused) - I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10); + for_each_ring(engine, dev_priv, unused) + I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10); if (HAS_GUC_UCODE(dev)) I915_WRITE(GUC_MAX_IDLE_COUNT, 0xA); @@ -4885,7 +4885,7 @@ static void gen9_enable_rc6(struct drm_device *dev) static void gen8_enable_rps(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; uint32_t rc6_mask = 0; int unused; @@ -4906,8 +4906,8 @@ static void gen8_enable_rps(struct drm_device *dev) I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16); I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */ I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */ - for_each_ring(ring, dev_priv, unused) - I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10); + for_each_ring(engine, dev_priv, unused) + I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10); I915_WRITE(GEN6_RC_SLEEP, 0); if (IS_BROADWELL(dev)) I915_WRITE(GEN6_RC6_THRESHOLD, 625); /* 800us/1.28 for TO */ @@ -4967,7 +4967,7 @@ static void gen8_enable_rps(struct drm_device *dev) static void gen6_enable_rps(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; u32 rc6vids, pcu_mbox = 0, rc6_mask = 0; u32 gtfifodbg; int rc6_mode; @@ -5003,8 +5003,8 @@ static void gen6_enable_rps(struct drm_device *dev) I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); - for_each_ring(ring, dev_priv, i) - I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10); + for_each_ring(engine, dev_priv, i) + I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10); I915_WRITE(GEN6_RC_SLEEP, 0); I915_WRITE(GEN6_RC1e_THRESHOLD, 1000); @@ -5495,7 +5495,7 @@ static void valleyview_cleanup_gt_powersave(struct drm_device *dev) static void cherryview_enable_rps(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; u32 gtfifodbg, val, rc6_mode = 0, pcbr; int i; @@ -5522,8 +5522,8 @@ static void cherryview_enable_rps(struct drm_device *dev) I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */ I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */ - for_each_ring(ring, dev_priv, i) - I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10); + for_each_ring(engine, dev_priv, i) + I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10); I915_WRITE(GEN6_RC_SLEEP, 0); /* TO threshold set to 500 us ( 0x186 * 1.28 us) */ @@ -5593,7 +5593,7 @@ static void cherryview_enable_rps(struct drm_device *dev) static void valleyview_enable_rps(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; u32 gtfifodbg, val, rc6_mode = 0; int i; @@ -5633,8 +5633,8 @@ static void valleyview_enable_rps(struct drm_device *dev) I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); - for_each_ring(ring, dev_priv, i) - I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10); + for_each_ring(engine, dev_priv, i) + I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10); I915_WRITE(GEN6_RC6_THRESHOLD, 0x557); @@ -6010,7 +6010,7 @@ EXPORT_SYMBOL_GPL(i915_gpu_lower); bool i915_gpu_busy(void) { struct drm_i915_private *dev_priv; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; bool ret = false; int i; @@ -6019,8 +6019,8 @@ bool i915_gpu_busy(void) goto out_unlock; dev_priv = i915_mch_dev; - for_each_ring(ring, dev_priv, i) - ret |= !list_empty(&ring->request_list); + for_each_ring(engine, dev_priv, i) + ret |= !list_empty(&engine->request_list); out_unlock: spin_unlock_irq(&mchdev_lock); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 45ce45a5e122..688773aaa5e5 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -79,7 +79,7 @@ gen2_render_ring_flush(struct drm_i915_gem_request *req, u32 invalidate_domains, u32 flush_domains) { - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; u32 cmd; int ret; @@ -94,9 +94,9 @@ gen2_render_ring_flush(struct drm_i915_gem_request *req, if (ret) return ret; - intel_ring_emit(ring, cmd); - intel_ring_emit(ring, MI_NOOP); - intel_ring_advance(ring); + intel_ring_emit(engine, cmd); + intel_ring_emit(engine, MI_NOOP); + intel_ring_advance(engine); return 0; } @@ -106,8 +106,8 @@ gen4_render_ring_flush(struct drm_i915_gem_request *req, u32 invalidate_domains, u32 flush_domains) { - struct intel_engine_cs *ring = req->ring; - struct drm_device *dev = ring->dev; + struct intel_engine_cs *engine = req->ring; + struct drm_device *dev = engine->dev; u32 cmd; int ret; @@ -153,9 +153,9 @@ gen4_render_ring_flush(struct drm_i915_gem_request *req, if (ret) return ret; - intel_ring_emit(ring, cmd); - intel_ring_emit(ring, MI_NOOP); - intel_ring_advance(ring); + intel_ring_emit(engine, cmd); + intel_ring_emit(engine, MI_NOOP); + intel_ring_advance(engine); return 0; } @@ -200,34 +200,34 @@ gen4_render_ring_flush(struct drm_i915_gem_request *req, static int intel_emit_post_sync_nonzero_flush(struct drm_i915_gem_request *req) { - struct intel_engine_cs *ring = req->ring; - u32 scratch_addr = ring->scratch.gtt_offset + 2 * CACHELINE_BYTES; + struct intel_engine_cs *engine = req->ring; + u32 scratch_addr = engine->scratch.gtt_offset + 2 * CACHELINE_BYTES; int ret; ret = intel_ring_begin(req, 6); if (ret) return ret; - intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(5)); - intel_ring_emit(ring, PIPE_CONTROL_CS_STALL | + intel_ring_emit(engine, GFX_OP_PIPE_CONTROL(5)); + intel_ring_emit(engine, PIPE_CONTROL_CS_STALL | PIPE_CONTROL_STALL_AT_SCOREBOARD); - intel_ring_emit(ring, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); /* address */ - intel_ring_emit(ring, 0); /* low dword */ - intel_ring_emit(ring, 0); /* high dword */ - intel_ring_emit(ring, MI_NOOP); - intel_ring_advance(ring); + intel_ring_emit(engine, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); /* address */ + intel_ring_emit(engine, 0); /* low dword */ + intel_ring_emit(engine, 0); /* high dword */ + intel_ring_emit(engine, MI_NOOP); + intel_ring_advance(engine); ret = intel_ring_begin(req, 6); if (ret) return ret; - intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(5)); - intel_ring_emit(ring, PIPE_CONTROL_QW_WRITE); - intel_ring_emit(ring, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); /* address */ - intel_ring_emit(ring, 0); - intel_ring_emit(ring, 0); - intel_ring_emit(ring, MI_NOOP); - intel_ring_advance(ring); + intel_ring_emit(engine, GFX_OP_PIPE_CONTROL(5)); + intel_ring_emit(engine, PIPE_CONTROL_QW_WRITE); + intel_ring_emit(engine, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); /* address */ + intel_ring_emit(engine, 0); + intel_ring_emit(engine, 0); + intel_ring_emit(engine, MI_NOOP); + intel_ring_advance(engine); return 0; } @@ -236,9 +236,9 @@ static int gen6_render_ring_flush(struct drm_i915_gem_request *req, u32 invalidate_domains, u32 flush_domains) { - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; u32 flags = 0; - u32 scratch_addr = ring->scratch.gtt_offset + 2 * CACHELINE_BYTES; + u32 scratch_addr = engine->scratch.gtt_offset + 2 * CACHELINE_BYTES; int ret; /* Force SNB workarounds for PIPE_CONTROL flushes */ @@ -276,11 +276,11 @@ gen6_render_ring_flush(struct drm_i915_gem_request *req, if (ret) return ret; - intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(4)); - intel_ring_emit(ring, flags); - intel_ring_emit(ring, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); - intel_ring_emit(ring, 0); - intel_ring_advance(ring); + intel_ring_emit(engine, GFX_OP_PIPE_CONTROL(4)); + intel_ring_emit(engine, flags); + intel_ring_emit(engine, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); + intel_ring_emit(engine, 0); + intel_ring_advance(engine); return 0; } @@ -288,19 +288,19 @@ gen6_render_ring_flush(struct drm_i915_gem_request *req, static int gen7_render_ring_cs_stall_wa(struct drm_i915_gem_request *req) { - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; int ret; ret = intel_ring_begin(req, 4); if (ret) return ret; - intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(4)); - intel_ring_emit(ring, PIPE_CONTROL_CS_STALL | + intel_ring_emit(engine, GFX_OP_PIPE_CONTROL(4)); + intel_ring_emit(engine, PIPE_CONTROL_CS_STALL | PIPE_CONTROL_STALL_AT_SCOREBOARD); - intel_ring_emit(ring, 0); - intel_ring_emit(ring, 0); - intel_ring_advance(ring); + intel_ring_emit(engine, 0); + intel_ring_emit(engine, 0); + intel_ring_advance(engine); return 0; } @@ -309,9 +309,9 @@ static int gen7_render_ring_flush(struct drm_i915_gem_request *req, u32 invalidate_domains, u32 flush_domains) { - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; u32 flags = 0; - u32 scratch_addr = ring->scratch.gtt_offset + 2 * CACHELINE_BYTES; + u32 scratch_addr = engine->scratch.gtt_offset + 2 * CACHELINE_BYTES; int ret; /* @@ -360,11 +360,11 @@ gen7_render_ring_flush(struct drm_i915_gem_request *req, if (ret) return ret; - intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(4)); - intel_ring_emit(ring, flags); - intel_ring_emit(ring, scratch_addr); - intel_ring_emit(ring, 0); - intel_ring_advance(ring); + intel_ring_emit(engine, GFX_OP_PIPE_CONTROL(4)); + intel_ring_emit(engine, flags); + intel_ring_emit(engine, scratch_addr); + intel_ring_emit(engine, 0); + intel_ring_advance(engine); return 0; } @@ -373,20 +373,20 @@ static int gen8_emit_pipe_control(struct drm_i915_gem_request *req, u32 flags, u32 scratch_addr) { - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; int ret; ret = intel_ring_begin(req, 6); if (ret) return ret; - intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(6)); - intel_ring_emit(ring, flags); - intel_ring_emit(ring, scratch_addr); - intel_ring_emit(ring, 0); - intel_ring_emit(ring, 0); - intel_ring_emit(ring, 0); - intel_ring_advance(ring); + intel_ring_emit(engine, GFX_OP_PIPE_CONTROL(6)); + intel_ring_emit(engine, flags); + intel_ring_emit(engine, scratch_addr); + intel_ring_emit(engine, 0); + intel_ring_emit(engine, 0); + intel_ring_emit(engine, 0); + intel_ring_advance(engine); return 0; } @@ -700,15 +700,15 @@ err: static int intel_ring_workarounds_emit(struct drm_i915_gem_request *req) { int ret, i; - struct intel_engine_cs *ring = req->ring; - struct drm_device *dev = ring->dev; + struct intel_engine_cs *engine = req->ring; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct i915_workarounds *w = &dev_priv->workarounds; if (w->count == 0) return 0; - ring->gpu_caches_dirty = true; + engine->gpu_caches_dirty = true; ret = intel_ring_flush_all_caches(req); if (ret) return ret; @@ -717,16 +717,16 @@ static int intel_ring_workarounds_emit(struct drm_i915_gem_request *req) if (ret) return ret; - intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(w->count)); + intel_ring_emit(engine, MI_LOAD_REGISTER_IMM(w->count)); for (i = 0; i < w->count; i++) { - intel_ring_emit_reg(ring, w->reg[i].addr); - intel_ring_emit(ring, w->reg[i].value); + intel_ring_emit_reg(engine, w->reg[i].addr); + intel_ring_emit(engine, w->reg[i].value); } - intel_ring_emit(ring, MI_NOOP); + intel_ring_emit(engine, MI_NOOP); - intel_ring_advance(ring); + intel_ring_advance(engine); - ring->gpu_caches_dirty = true; + engine->gpu_caches_dirty = true; ret = intel_ring_flush_all_caches(req); if (ret) return ret; @@ -1388,22 +1388,23 @@ static int gen6_signal(struct drm_i915_gem_request *signaller_req, static int gen6_add_request(struct drm_i915_gem_request *req) { - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; int ret; - if (ring->semaphore.signal) - ret = ring->semaphore.signal(req, 4); + if (engine->semaphore.signal) + ret = engine->semaphore.signal(req, 4); else ret = intel_ring_begin(req, 4); if (ret) return ret; - intel_ring_emit(ring, MI_STORE_DWORD_INDEX); - intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); - intel_ring_emit(ring, i915_gem_request_get_seqno(req)); - intel_ring_emit(ring, MI_USER_INTERRUPT); - __intel_ring_advance(ring); + intel_ring_emit(engine, MI_STORE_DWORD_INDEX); + intel_ring_emit(engine, + I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); + intel_ring_emit(engine, i915_gem_request_get_seqno(req)); + intel_ring_emit(engine, MI_USER_INTERRUPT); + __intel_ring_advance(engine); return 0; } @@ -1502,8 +1503,8 @@ do { \ static int pc_render_add_request(struct drm_i915_gem_request *req) { - struct intel_engine_cs *ring = req->ring; - u32 scratch_addr = ring->scratch.gtt_offset + 2 * CACHELINE_BYTES; + struct intel_engine_cs *engine = req->ring; + u32 scratch_addr = engine->scratch.gtt_offset + 2 * CACHELINE_BYTES; int ret; /* For Ironlake, MI_USER_INTERRUPT was deprecated and apparently @@ -1518,32 +1519,36 @@ pc_render_add_request(struct drm_i915_gem_request *req) if (ret) return ret; - intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE | + intel_ring_emit(engine, + GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE | PIPE_CONTROL_WRITE_FLUSH | PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE); - intel_ring_emit(ring, ring->scratch.gtt_offset | PIPE_CONTROL_GLOBAL_GTT); - intel_ring_emit(ring, i915_gem_request_get_seqno(req)); - intel_ring_emit(ring, 0); - PIPE_CONTROL_FLUSH(ring, scratch_addr); + intel_ring_emit(engine, + engine->scratch.gtt_offset | PIPE_CONTROL_GLOBAL_GTT); + intel_ring_emit(engine, i915_gem_request_get_seqno(req)); + intel_ring_emit(engine, 0); + PIPE_CONTROL_FLUSH(engine, scratch_addr); scratch_addr += 2 * CACHELINE_BYTES; /* write to separate cachelines */ - PIPE_CONTROL_FLUSH(ring, scratch_addr); + PIPE_CONTROL_FLUSH(engine, scratch_addr); scratch_addr += 2 * CACHELINE_BYTES; - PIPE_CONTROL_FLUSH(ring, scratch_addr); + PIPE_CONTROL_FLUSH(engine, scratch_addr); scratch_addr += 2 * CACHELINE_BYTES; - PIPE_CONTROL_FLUSH(ring, scratch_addr); + PIPE_CONTROL_FLUSH(engine, scratch_addr); scratch_addr += 2 * CACHELINE_BYTES; - PIPE_CONTROL_FLUSH(ring, scratch_addr); + PIPE_CONTROL_FLUSH(engine, scratch_addr); scratch_addr += 2 * CACHELINE_BYTES; - PIPE_CONTROL_FLUSH(ring, scratch_addr); + PIPE_CONTROL_FLUSH(engine, scratch_addr); - intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE | + intel_ring_emit(engine, + GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE | PIPE_CONTROL_WRITE_FLUSH | PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE | PIPE_CONTROL_NOTIFY); - intel_ring_emit(ring, ring->scratch.gtt_offset | PIPE_CONTROL_GLOBAL_GTT); - intel_ring_emit(ring, i915_gem_request_get_seqno(req)); - intel_ring_emit(ring, 0); - __intel_ring_advance(ring); + intel_ring_emit(engine, + engine->scratch.gtt_offset | PIPE_CONTROL_GLOBAL_GTT); + intel_ring_emit(engine, i915_gem_request_get_seqno(req)); + intel_ring_emit(engine, 0); + __intel_ring_advance(engine); return 0; } @@ -1696,34 +1701,35 @@ bsd_ring_flush(struct drm_i915_gem_request *req, u32 invalidate_domains, u32 flush_domains) { - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; int ret; ret = intel_ring_begin(req, 2); if (ret) return ret; - intel_ring_emit(ring, MI_FLUSH); - intel_ring_emit(ring, MI_NOOP); - intel_ring_advance(ring); + intel_ring_emit(engine, MI_FLUSH); + intel_ring_emit(engine, MI_NOOP); + intel_ring_advance(engine); return 0; } static int i9xx_add_request(struct drm_i915_gem_request *req) { - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; int ret; ret = intel_ring_begin(req, 4); if (ret) return ret; - intel_ring_emit(ring, MI_STORE_DWORD_INDEX); - intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); - intel_ring_emit(ring, i915_gem_request_get_seqno(req)); - intel_ring_emit(ring, MI_USER_INTERRUPT); - __intel_ring_advance(ring); + intel_ring_emit(engine, MI_STORE_DWORD_INDEX); + intel_ring_emit(engine, + I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); + intel_ring_emit(engine, i915_gem_request_get_seqno(req)); + intel_ring_emit(engine, MI_USER_INTERRUPT); + __intel_ring_advance(engine); return 0; } @@ -1857,20 +1863,20 @@ i965_dispatch_execbuffer(struct drm_i915_gem_request *req, u64 offset, u32 length, unsigned dispatch_flags) { - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; int ret; ret = intel_ring_begin(req, 2); if (ret) return ret; - intel_ring_emit(ring, + intel_ring_emit(engine, MI_BATCH_BUFFER_START | MI_BATCH_GTT | (dispatch_flags & I915_DISPATCH_SECURE ? 0 : MI_BATCH_NON_SECURE_I965)); - intel_ring_emit(ring, offset); - intel_ring_advance(ring); + intel_ring_emit(engine, offset); + intel_ring_advance(engine); return 0; } @@ -1884,8 +1890,8 @@ i830_dispatch_execbuffer(struct drm_i915_gem_request *req, u64 offset, u32 len, unsigned dispatch_flags) { - struct intel_engine_cs *ring = req->ring; - u32 cs_offset = ring->scratch.gtt_offset; + struct intel_engine_cs *engine = req->ring; + u32 cs_offset = engine->scratch.gtt_offset; int ret; ret = intel_ring_begin(req, 6); @@ -1893,13 +1899,13 @@ i830_dispatch_execbuffer(struct drm_i915_gem_request *req, return ret; /* Evict the invalid PTE TLBs */ - intel_ring_emit(ring, COLOR_BLT_CMD | BLT_WRITE_RGBA); - intel_ring_emit(ring, BLT_DEPTH_32 | BLT_ROP_COLOR_COPY | 4096); - intel_ring_emit(ring, I830_TLB_ENTRIES << 16 | 4); /* load each page */ - intel_ring_emit(ring, cs_offset); - intel_ring_emit(ring, 0xdeadbeef); - intel_ring_emit(ring, MI_NOOP); - intel_ring_advance(ring); + intel_ring_emit(engine, COLOR_BLT_CMD | BLT_WRITE_RGBA); + intel_ring_emit(engine, BLT_DEPTH_32 | BLT_ROP_COLOR_COPY | 4096); + intel_ring_emit(engine, I830_TLB_ENTRIES << 16 | 4); /* load each page */ + intel_ring_emit(engine, cs_offset); + intel_ring_emit(engine, 0xdeadbeef); + intel_ring_emit(engine, MI_NOOP); + intel_ring_advance(engine); if ((dispatch_flags & I915_DISPATCH_PINNED) == 0) { if (len > I830_BATCH_LIMIT) @@ -1913,16 +1919,17 @@ i830_dispatch_execbuffer(struct drm_i915_gem_request *req, * stable batch scratch bo area (so that the CS never * stumbles over its tlb invalidation bug) ... */ - intel_ring_emit(ring, SRC_COPY_BLT_CMD | BLT_WRITE_RGBA); - intel_ring_emit(ring, BLT_DEPTH_32 | BLT_ROP_SRC_COPY | 4096); - intel_ring_emit(ring, DIV_ROUND_UP(len, 4096) << 16 | 4096); - intel_ring_emit(ring, cs_offset); - intel_ring_emit(ring, 4096); - intel_ring_emit(ring, offset); - - intel_ring_emit(ring, MI_FLUSH); - intel_ring_emit(ring, MI_NOOP); - intel_ring_advance(ring); + intel_ring_emit(engine, SRC_COPY_BLT_CMD | BLT_WRITE_RGBA); + intel_ring_emit(engine, + BLT_DEPTH_32 | BLT_ROP_SRC_COPY | 4096); + intel_ring_emit(engine, DIV_ROUND_UP(len, 4096) << 16 | 4096); + intel_ring_emit(engine, cs_offset); + intel_ring_emit(engine, 4096); + intel_ring_emit(engine, offset); + + intel_ring_emit(engine, MI_FLUSH); + intel_ring_emit(engine, MI_NOOP); + intel_ring_advance(engine); /* ... and execute it. */ offset = cs_offset; @@ -1932,10 +1939,10 @@ i830_dispatch_execbuffer(struct drm_i915_gem_request *req, if (ret) return ret; - intel_ring_emit(ring, MI_BATCH_BUFFER_START | MI_BATCH_GTT); - intel_ring_emit(ring, offset | (dispatch_flags & I915_DISPATCH_SECURE ? - 0 : MI_BATCH_NON_SECURE)); - intel_ring_advance(ring); + intel_ring_emit(engine, MI_BATCH_BUFFER_START | MI_BATCH_GTT); + intel_ring_emit(engine, offset | (dispatch_flags & I915_DISPATCH_SECURE ? + 0 : MI_BATCH_NON_SECURE)); + intel_ring_advance(engine); return 0; } @@ -1945,17 +1952,17 @@ i915_dispatch_execbuffer(struct drm_i915_gem_request *req, u64 offset, u32 len, unsigned dispatch_flags) { - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; int ret; ret = intel_ring_begin(req, 2); if (ret) return ret; - intel_ring_emit(ring, MI_BATCH_BUFFER_START | MI_BATCH_GTT); - intel_ring_emit(ring, offset | (dispatch_flags & I915_DISPATCH_SECURE ? - 0 : MI_BATCH_NON_SECURE)); - intel_ring_advance(ring); + intel_ring_emit(engine, MI_BATCH_BUFFER_START | MI_BATCH_GTT); + intel_ring_emit(engine, offset | (dispatch_flags & I915_DISPATCH_SECURE ? + 0 : MI_BATCH_NON_SECURE)); + intel_ring_advance(engine); return 0; } @@ -2480,32 +2487,32 @@ static int __intel_ring_prepare(struct intel_engine_cs *ring, int bytes) int intel_ring_begin(struct drm_i915_gem_request *req, int num_dwords) { - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; struct drm_i915_private *dev_priv; int ret; WARN_ON(req == NULL); - ring = req->ring; - dev_priv = ring->dev->dev_private; + engine = req->ring; + dev_priv = engine->dev->dev_private; ret = i915_gem_check_wedge(&dev_priv->gpu_error, dev_priv->mm.interruptible); if (ret) return ret; - ret = __intel_ring_prepare(ring, num_dwords * sizeof(uint32_t)); + ret = __intel_ring_prepare(engine, num_dwords * sizeof(uint32_t)); if (ret) return ret; - ring->buffer->space -= num_dwords * sizeof(uint32_t); + engine->buffer->space -= num_dwords * sizeof(uint32_t); return 0; } /* Align the ring tail to a cacheline boundary */ int intel_ring_cacheline_align(struct drm_i915_gem_request *req) { - struct intel_engine_cs *ring = req->ring; - int num_dwords = (ring->buffer->tail & (CACHELINE_BYTES - 1)) / sizeof(uint32_t); + struct intel_engine_cs *engine = req->ring; + int num_dwords = (engine->buffer->tail & (CACHELINE_BYTES - 1)) / sizeof(uint32_t); int ret; if (num_dwords == 0) @@ -2517,9 +2524,9 @@ int intel_ring_cacheline_align(struct drm_i915_gem_request *req) return ret; while (num_dwords--) - intel_ring_emit(ring, MI_NOOP); + intel_ring_emit(engine, MI_NOOP); - intel_ring_advance(ring); + intel_ring_advance(engine); return 0; } @@ -2576,7 +2583,7 @@ static void gen6_bsd_ring_write_tail(struct intel_engine_cs *ring, static int gen6_bsd_ring_flush(struct drm_i915_gem_request *req, u32 invalidate, u32 flush) { - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; uint32_t cmd; int ret; @@ -2585,7 +2592,7 @@ static int gen6_bsd_ring_flush(struct drm_i915_gem_request *req, return ret; cmd = MI_FLUSH_DW; - if (INTEL_INFO(ring->dev)->gen >= 8) + if (INTEL_INFO(engine->dev)->gen >= 8) cmd += 1; /* We always require a command barrier so that subsequent @@ -2604,16 +2611,17 @@ static int gen6_bsd_ring_flush(struct drm_i915_gem_request *req, if (invalidate & I915_GEM_GPU_DOMAINS) cmd |= MI_INVALIDATE_TLB | MI_INVALIDATE_BSD; - intel_ring_emit(ring, cmd); - intel_ring_emit(ring, I915_GEM_HWS_SCRATCH_ADDR | MI_FLUSH_DW_USE_GTT); - if (INTEL_INFO(ring->dev)->gen >= 8) { - intel_ring_emit(ring, 0); /* upper addr */ - intel_ring_emit(ring, 0); /* value */ + intel_ring_emit(engine, cmd); + intel_ring_emit(engine, + I915_GEM_HWS_SCRATCH_ADDR | MI_FLUSH_DW_USE_GTT); + if (INTEL_INFO(engine->dev)->gen >= 8) { + intel_ring_emit(engine, 0); /* upper addr */ + intel_ring_emit(engine, 0); /* value */ } else { - intel_ring_emit(ring, 0); - intel_ring_emit(ring, MI_NOOP); + intel_ring_emit(engine, 0); + intel_ring_emit(engine, MI_NOOP); } - intel_ring_advance(ring); + intel_ring_advance(engine); return 0; } @@ -2622,8 +2630,8 @@ gen8_ring_dispatch_execbuffer(struct drm_i915_gem_request *req, u64 offset, u32 len, unsigned dispatch_flags) { - struct intel_engine_cs *ring = req->ring; - bool ppgtt = USES_PPGTT(ring->dev) && + struct intel_engine_cs *engine = req->ring; + bool ppgtt = USES_PPGTT(engine->dev) && !(dispatch_flags & I915_DISPATCH_SECURE); int ret; @@ -2632,13 +2640,13 @@ gen8_ring_dispatch_execbuffer(struct drm_i915_gem_request *req, return ret; /* FIXME(BDW): Address space and security selectors. */ - intel_ring_emit(ring, MI_BATCH_BUFFER_START_GEN8 | (ppgtt<<8) | + intel_ring_emit(engine, MI_BATCH_BUFFER_START_GEN8 | (ppgtt<<8) | (dispatch_flags & I915_DISPATCH_RS ? MI_BATCH_RESOURCE_STREAMER : 0)); - intel_ring_emit(ring, lower_32_bits(offset)); - intel_ring_emit(ring, upper_32_bits(offset)); - intel_ring_emit(ring, MI_NOOP); - intel_ring_advance(ring); + intel_ring_emit(engine, lower_32_bits(offset)); + intel_ring_emit(engine, upper_32_bits(offset)); + intel_ring_emit(engine, MI_NOOP); + intel_ring_advance(engine); return 0; } @@ -2648,22 +2656,22 @@ hsw_ring_dispatch_execbuffer(struct drm_i915_gem_request *req, u64 offset, u32 len, unsigned dispatch_flags) { - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; int ret; ret = intel_ring_begin(req, 2); if (ret) return ret; - intel_ring_emit(ring, + intel_ring_emit(engine, MI_BATCH_BUFFER_START | (dispatch_flags & I915_DISPATCH_SECURE ? 0 : MI_BATCH_PPGTT_HSW | MI_BATCH_NON_SECURE_HSW) | (dispatch_flags & I915_DISPATCH_RS ? MI_BATCH_RESOURCE_STREAMER : 0)); /* bit0-7 is the length on GEN6+ */ - intel_ring_emit(ring, offset); - intel_ring_advance(ring); + intel_ring_emit(engine, offset); + intel_ring_advance(engine); return 0; } @@ -2673,20 +2681,20 @@ gen6_ring_dispatch_execbuffer(struct drm_i915_gem_request *req, u64 offset, u32 len, unsigned dispatch_flags) { - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; int ret; ret = intel_ring_begin(req, 2); if (ret) return ret; - intel_ring_emit(ring, + intel_ring_emit(engine, MI_BATCH_BUFFER_START | (dispatch_flags & I915_DISPATCH_SECURE ? 0 : MI_BATCH_NON_SECURE_I965)); /* bit0-7 is the length on GEN6+ */ - intel_ring_emit(ring, offset); - intel_ring_advance(ring); + intel_ring_emit(engine, offset); + intel_ring_advance(engine); return 0; } @@ -2696,8 +2704,8 @@ gen6_ring_dispatch_execbuffer(struct drm_i915_gem_request *req, static int gen6_ring_flush(struct drm_i915_gem_request *req, u32 invalidate, u32 flush) { - struct intel_engine_cs *ring = req->ring; - struct drm_device *dev = ring->dev; + struct intel_engine_cs *engine = req->ring; + struct drm_device *dev = engine->dev; uint32_t cmd; int ret; @@ -2724,16 +2732,17 @@ static int gen6_ring_flush(struct drm_i915_gem_request *req, */ if (invalidate & I915_GEM_DOMAIN_RENDER) cmd |= MI_INVALIDATE_TLB; - intel_ring_emit(ring, cmd); - intel_ring_emit(ring, I915_GEM_HWS_SCRATCH_ADDR | MI_FLUSH_DW_USE_GTT); + intel_ring_emit(engine, cmd); + intel_ring_emit(engine, + I915_GEM_HWS_SCRATCH_ADDR | MI_FLUSH_DW_USE_GTT); if (INTEL_INFO(dev)->gen >= 8) { - intel_ring_emit(ring, 0); /* upper addr */ - intel_ring_emit(ring, 0); /* value */ + intel_ring_emit(engine, 0); /* upper addr */ + intel_ring_emit(engine, 0); /* value */ } else { - intel_ring_emit(ring, 0); - intel_ring_emit(ring, MI_NOOP); + intel_ring_emit(engine, 0); + intel_ring_emit(engine, MI_NOOP); } - intel_ring_advance(ring); + intel_ring_advance(engine); return 0; } @@ -2741,14 +2750,14 @@ static int gen6_ring_flush(struct drm_i915_gem_request *req, int intel_init_render_ring_buffer(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring = &dev_priv->ring[RCS]; + struct intel_engine_cs *engine = &dev_priv->ring[RCS]; struct drm_i915_gem_object *obj; int ret; - ring->name = "render ring"; - ring->id = RCS; - ring->exec_id = I915_EXEC_RENDER; - ring->mmio_base = RENDER_RING_BASE; + engine->name = "render ring"; + engine->id = RCS; + engine->exec_id = I915_EXEC_RENDER; + engine->mmio_base = RENDER_RING_BASE; if (INTEL_INFO(dev)->gen >= 8) { if (i915_semaphore_is_enabled(dev)) { @@ -2768,34 +2777,34 @@ int intel_init_render_ring_buffer(struct drm_device *dev) } } - ring->init_context = intel_rcs_ctx_init; - ring->add_request = gen6_add_request; - ring->flush = gen8_render_ring_flush; - ring->irq_get = gen8_ring_get_irq; - ring->irq_put = gen8_ring_put_irq; - ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT; - ring->get_seqno = gen6_ring_get_seqno; - ring->set_seqno = ring_set_seqno; + engine->init_context = intel_rcs_ctx_init; + engine->add_request = gen6_add_request; + engine->flush = gen8_render_ring_flush; + engine->irq_get = gen8_ring_get_irq; + engine->irq_put = gen8_ring_put_irq; + engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT; + engine->get_seqno = gen6_ring_get_seqno; + engine->set_seqno = ring_set_seqno; if (i915_semaphore_is_enabled(dev)) { WARN_ON(!dev_priv->semaphore_obj); - ring->semaphore.sync_to = gen8_ring_sync; - ring->semaphore.signal = gen8_rcs_signal; - GEN8_RING_SEMAPHORE_INIT; + engine->semaphore.sync_to = gen8_ring_sync; + engine->semaphore.signal = gen8_rcs_signal; + GEN8_RING_SEMAPHORE_INIT(engine); } } else if (INTEL_INFO(dev)->gen >= 6) { - ring->init_context = intel_rcs_ctx_init; - ring->add_request = gen6_add_request; - ring->flush = gen7_render_ring_flush; + engine->init_context = intel_rcs_ctx_init; + engine->add_request = gen6_add_request; + engine->flush = gen7_render_ring_flush; if (INTEL_INFO(dev)->gen == 6) - ring->flush = gen6_render_ring_flush; - ring->irq_get = gen6_ring_get_irq; - ring->irq_put = gen6_ring_put_irq; - ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT; - ring->get_seqno = gen6_ring_get_seqno; - ring->set_seqno = ring_set_seqno; + engine->flush = gen6_render_ring_flush; + engine->irq_get = gen6_ring_get_irq; + engine->irq_put = gen6_ring_put_irq; + engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT; + engine->get_seqno = gen6_ring_get_seqno; + engine->set_seqno = ring_set_seqno; if (i915_semaphore_is_enabled(dev)) { - ring->semaphore.sync_to = gen6_ring_sync; - ring->semaphore.signal = gen6_signal; + engine->semaphore.sync_to = gen6_ring_sync; + engine->semaphore.signal = gen6_signal; /* * The current semaphore is only applied on pre-gen8 * platform. And there is no VCS2 ring on the pre-gen8 @@ -2803,59 +2812,59 @@ int intel_init_render_ring_buffer(struct drm_device *dev) * initialized as INVALID. Gen8 will initialize the * sema between VCS2 and RCS later. */ - ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_INVALID; - ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_RV; - ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_RB; - ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_RVE; - ring->semaphore.mbox.wait[VCS2] = MI_SEMAPHORE_SYNC_INVALID; - ring->semaphore.mbox.signal[RCS] = GEN6_NOSYNC; - ring->semaphore.mbox.signal[VCS] = GEN6_VRSYNC; - ring->semaphore.mbox.signal[BCS] = GEN6_BRSYNC; - ring->semaphore.mbox.signal[VECS] = GEN6_VERSYNC; - ring->semaphore.mbox.signal[VCS2] = GEN6_NOSYNC; + engine->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_INVALID; + engine->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_RV; + engine->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_RB; + engine->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_RVE; + engine->semaphore.mbox.wait[VCS2] = MI_SEMAPHORE_SYNC_INVALID; + engine->semaphore.mbox.signal[RCS] = GEN6_NOSYNC; + engine->semaphore.mbox.signal[VCS] = GEN6_VRSYNC; + engine->semaphore.mbox.signal[BCS] = GEN6_BRSYNC; + engine->semaphore.mbox.signal[VECS] = GEN6_VERSYNC; + engine->semaphore.mbox.signal[VCS2] = GEN6_NOSYNC; } } else if (IS_GEN5(dev)) { - ring->add_request = pc_render_add_request; - ring->flush = gen4_render_ring_flush; - ring->get_seqno = pc_render_get_seqno; - ring->set_seqno = pc_render_set_seqno; - ring->irq_get = gen5_ring_get_irq; - ring->irq_put = gen5_ring_put_irq; - ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT | + engine->add_request = pc_render_add_request; + engine->flush = gen4_render_ring_flush; + engine->get_seqno = pc_render_get_seqno; + engine->set_seqno = pc_render_set_seqno; + engine->irq_get = gen5_ring_get_irq; + engine->irq_put = gen5_ring_put_irq; + engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT | GT_RENDER_PIPECTL_NOTIFY_INTERRUPT; } else { - ring->add_request = i9xx_add_request; + engine->add_request = i9xx_add_request; if (INTEL_INFO(dev)->gen < 4) - ring->flush = gen2_render_ring_flush; + engine->flush = gen2_render_ring_flush; else - ring->flush = gen4_render_ring_flush; - ring->get_seqno = ring_get_seqno; - ring->set_seqno = ring_set_seqno; + engine->flush = gen4_render_ring_flush; + engine->get_seqno = ring_get_seqno; + engine->set_seqno = ring_set_seqno; if (IS_GEN2(dev)) { - ring->irq_get = i8xx_ring_get_irq; - ring->irq_put = i8xx_ring_put_irq; + engine->irq_get = i8xx_ring_get_irq; + engine->irq_put = i8xx_ring_put_irq; } else { - ring->irq_get = i9xx_ring_get_irq; - ring->irq_put = i9xx_ring_put_irq; + engine->irq_get = i9xx_ring_get_irq; + engine->irq_put = i9xx_ring_put_irq; } - ring->irq_enable_mask = I915_USER_INTERRUPT; + engine->irq_enable_mask = I915_USER_INTERRUPT; } - ring->write_tail = ring_write_tail; + engine->write_tail = ring_write_tail; if (IS_HASWELL(dev)) - ring->dispatch_execbuffer = hsw_ring_dispatch_execbuffer; + engine->dispatch_execbuffer = hsw_ring_dispatch_execbuffer; else if (IS_GEN8(dev)) - ring->dispatch_execbuffer = gen8_ring_dispatch_execbuffer; + engine->dispatch_execbuffer = gen8_ring_dispatch_execbuffer; else if (INTEL_INFO(dev)->gen >= 6) - ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; + engine->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; else if (INTEL_INFO(dev)->gen >= 4) - ring->dispatch_execbuffer = i965_dispatch_execbuffer; + engine->dispatch_execbuffer = i965_dispatch_execbuffer; else if (IS_I830(dev) || IS_845G(dev)) - ring->dispatch_execbuffer = i830_dispatch_execbuffer; + engine->dispatch_execbuffer = i830_dispatch_execbuffer; else - ring->dispatch_execbuffer = i915_dispatch_execbuffer; - ring->init_hw = init_render_ring; - ring->cleanup = render_ring_cleanup; + engine->dispatch_execbuffer = i915_dispatch_execbuffer; + engine->init_hw = init_render_ring; + engine->cleanup = render_ring_cleanup; /* Workaround batchbuffer to combat CS tlb bug. */ if (HAS_BROKEN_CS_TLB(dev)) { @@ -2872,16 +2881,16 @@ int intel_init_render_ring_buffer(struct drm_device *dev) return ret; } - ring->scratch.obj = obj; - ring->scratch.gtt_offset = i915_gem_obj_ggtt_offset(obj); + engine->scratch.obj = obj; + engine->scratch.gtt_offset = i915_gem_obj_ggtt_offset(obj); } - ret = intel_init_ring_buffer(dev, ring); + ret = intel_init_ring_buffer(dev, engine); if (ret) return ret; if (INTEL_INFO(dev)->gen >= 5) { - ret = intel_init_pipe_control(ring); + ret = intel_init_pipe_control(engine); if (ret) return ret; } @@ -2892,75 +2901,75 @@ int intel_init_render_ring_buffer(struct drm_device *dev) int intel_init_bsd_ring_buffer(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring = &dev_priv->ring[VCS]; + struct intel_engine_cs *engine = &dev_priv->ring[VCS]; - ring->name = "bsd ring"; - ring->id = VCS; - ring->exec_id = I915_EXEC_BSD; + engine->name = "bsd ring"; + engine->id = VCS; + engine->exec_id = I915_EXEC_BSD; - ring->write_tail = ring_write_tail; + engine->write_tail = ring_write_tail; if (INTEL_INFO(dev)->gen >= 6) { - ring->mmio_base = GEN6_BSD_RING_BASE; + engine->mmio_base = GEN6_BSD_RING_BASE; /* gen6 bsd needs a special wa for tail updates */ if (IS_GEN6(dev)) - ring->write_tail = gen6_bsd_ring_write_tail; - ring->flush = gen6_bsd_ring_flush; - ring->add_request = gen6_add_request; - ring->get_seqno = gen6_ring_get_seqno; - ring->set_seqno = ring_set_seqno; + engine->write_tail = gen6_bsd_ring_write_tail; + engine->flush = gen6_bsd_ring_flush; + engine->add_request = gen6_add_request; + engine->get_seqno = gen6_ring_get_seqno; + engine->set_seqno = ring_set_seqno; if (INTEL_INFO(dev)->gen >= 8) { - ring->irq_enable_mask = + engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT << GEN8_VCS1_IRQ_SHIFT; - ring->irq_get = gen8_ring_get_irq; - ring->irq_put = gen8_ring_put_irq; - ring->dispatch_execbuffer = + engine->irq_get = gen8_ring_get_irq; + engine->irq_put = gen8_ring_put_irq; + engine->dispatch_execbuffer = gen8_ring_dispatch_execbuffer; if (i915_semaphore_is_enabled(dev)) { - ring->semaphore.sync_to = gen8_ring_sync; - ring->semaphore.signal = gen8_xcs_signal; - GEN8_RING_SEMAPHORE_INIT; + engine->semaphore.sync_to = gen8_ring_sync; + engine->semaphore.signal = gen8_xcs_signal; + GEN8_RING_SEMAPHORE_INIT(engine); } } else { - ring->irq_enable_mask = GT_BSD_USER_INTERRUPT; - ring->irq_get = gen6_ring_get_irq; - ring->irq_put = gen6_ring_put_irq; - ring->dispatch_execbuffer = + engine->irq_enable_mask = GT_BSD_USER_INTERRUPT; + engine->irq_get = gen6_ring_get_irq; + engine->irq_put = gen6_ring_put_irq; + engine->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; if (i915_semaphore_is_enabled(dev)) { - ring->semaphore.sync_to = gen6_ring_sync; - ring->semaphore.signal = gen6_signal; - ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_VR; - ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_INVALID; - ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_VB; - ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_VVE; - ring->semaphore.mbox.wait[VCS2] = MI_SEMAPHORE_SYNC_INVALID; - ring->semaphore.mbox.signal[RCS] = GEN6_RVSYNC; - ring->semaphore.mbox.signal[VCS] = GEN6_NOSYNC; - ring->semaphore.mbox.signal[BCS] = GEN6_BVSYNC; - ring->semaphore.mbox.signal[VECS] = GEN6_VEVSYNC; - ring->semaphore.mbox.signal[VCS2] = GEN6_NOSYNC; + engine->semaphore.sync_to = gen6_ring_sync; + engine->semaphore.signal = gen6_signal; + engine->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_VR; + engine->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_INVALID; + engine->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_VB; + engine->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_VVE; + engine->semaphore.mbox.wait[VCS2] = MI_SEMAPHORE_SYNC_INVALID; + engine->semaphore.mbox.signal[RCS] = GEN6_RVSYNC; + engine->semaphore.mbox.signal[VCS] = GEN6_NOSYNC; + engine->semaphore.mbox.signal[BCS] = GEN6_BVSYNC; + engine->semaphore.mbox.signal[VECS] = GEN6_VEVSYNC; + engine->semaphore.mbox.signal[VCS2] = GEN6_NOSYNC; } } } else { - ring->mmio_base = BSD_RING_BASE; - ring->flush = bsd_ring_flush; - ring->add_request = i9xx_add_request; - ring->get_seqno = ring_get_seqno; - ring->set_seqno = ring_set_seqno; + engine->mmio_base = BSD_RING_BASE; + engine->flush = bsd_ring_flush; + engine->add_request = i9xx_add_request; + engine->get_seqno = ring_get_seqno; + engine->set_seqno = ring_set_seqno; if (IS_GEN5(dev)) { - ring->irq_enable_mask = ILK_BSD_USER_INTERRUPT; - ring->irq_get = gen5_ring_get_irq; - ring->irq_put = gen5_ring_put_irq; + engine->irq_enable_mask = ILK_BSD_USER_INTERRUPT; + engine->irq_get = gen5_ring_get_irq; + engine->irq_put = gen5_ring_put_irq; } else { - ring->irq_enable_mask = I915_BSD_USER_INTERRUPT; - ring->irq_get = i9xx_ring_get_irq; - ring->irq_put = i9xx_ring_put_irq; + engine->irq_enable_mask = I915_BSD_USER_INTERRUPT; + engine->irq_get = i9xx_ring_get_irq; + engine->irq_put = i9xx_ring_put_irq; } - ring->dispatch_execbuffer = i965_dispatch_execbuffer; + engine->dispatch_execbuffer = i965_dispatch_execbuffer; } - ring->init_hw = init_ring_common; + engine->init_hw = init_ring_common; - return intel_init_ring_buffer(dev, ring); + return intel_init_ring_buffer(dev, engine); } /** @@ -2969,68 +2978,68 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) int intel_init_bsd2_ring_buffer(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring = &dev_priv->ring[VCS2]; - - ring->name = "bsd2 ring"; - ring->id = VCS2; - ring->exec_id = I915_EXEC_BSD; - - ring->write_tail = ring_write_tail; - ring->mmio_base = GEN8_BSD2_RING_BASE; - ring->flush = gen6_bsd_ring_flush; - ring->add_request = gen6_add_request; - ring->get_seqno = gen6_ring_get_seqno; - ring->set_seqno = ring_set_seqno; - ring->irq_enable_mask = + struct intel_engine_cs *engine = &dev_priv->ring[VCS2]; + + engine->name = "bsd2 ring"; + engine->id = VCS2; + engine->exec_id = I915_EXEC_BSD; + + engine->write_tail = ring_write_tail; + engine->mmio_base = GEN8_BSD2_RING_BASE; + engine->flush = gen6_bsd_ring_flush; + engine->add_request = gen6_add_request; + engine->get_seqno = gen6_ring_get_seqno; + engine->set_seqno = ring_set_seqno; + engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT << GEN8_VCS2_IRQ_SHIFT; - ring->irq_get = gen8_ring_get_irq; - ring->irq_put = gen8_ring_put_irq; - ring->dispatch_execbuffer = + engine->irq_get = gen8_ring_get_irq; + engine->irq_put = gen8_ring_put_irq; + engine->dispatch_execbuffer = gen8_ring_dispatch_execbuffer; if (i915_semaphore_is_enabled(dev)) { - ring->semaphore.sync_to = gen8_ring_sync; - ring->semaphore.signal = gen8_xcs_signal; - GEN8_RING_SEMAPHORE_INIT; + engine->semaphore.sync_to = gen8_ring_sync; + engine->semaphore.signal = gen8_xcs_signal; + GEN8_RING_SEMAPHORE_INIT(engine); } - ring->init_hw = init_ring_common; + engine->init_hw = init_ring_common; - return intel_init_ring_buffer(dev, ring); + return intel_init_ring_buffer(dev, engine); } int intel_init_blt_ring_buffer(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring = &dev_priv->ring[BCS]; - - ring->name = "blitter ring"; - ring->id = BCS; - ring->exec_id = I915_EXEC_BLT; - - ring->mmio_base = BLT_RING_BASE; - ring->write_tail = ring_write_tail; - ring->flush = gen6_ring_flush; - ring->add_request = gen6_add_request; - ring->get_seqno = gen6_ring_get_seqno; - ring->set_seqno = ring_set_seqno; + struct intel_engine_cs *engine = &dev_priv->ring[BCS]; + + engine->name = "blitter ring"; + engine->id = BCS; + engine->exec_id = I915_EXEC_BLT; + + engine->mmio_base = BLT_RING_BASE; + engine->write_tail = ring_write_tail; + engine->flush = gen6_ring_flush; + engine->add_request = gen6_add_request; + engine->get_seqno = gen6_ring_get_seqno; + engine->set_seqno = ring_set_seqno; if (INTEL_INFO(dev)->gen >= 8) { - ring->irq_enable_mask = + engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT; - ring->irq_get = gen8_ring_get_irq; - ring->irq_put = gen8_ring_put_irq; - ring->dispatch_execbuffer = gen8_ring_dispatch_execbuffer; + engine->irq_get = gen8_ring_get_irq; + engine->irq_put = gen8_ring_put_irq; + engine->dispatch_execbuffer = gen8_ring_dispatch_execbuffer; if (i915_semaphore_is_enabled(dev)) { - ring->semaphore.sync_to = gen8_ring_sync; - ring->semaphore.signal = gen8_xcs_signal; - GEN8_RING_SEMAPHORE_INIT; + engine->semaphore.sync_to = gen8_ring_sync; + engine->semaphore.signal = gen8_xcs_signal; + GEN8_RING_SEMAPHORE_INIT(engine); } } else { - ring->irq_enable_mask = GT_BLT_USER_INTERRUPT; - ring->irq_get = gen6_ring_get_irq; - ring->irq_put = gen6_ring_put_irq; - ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; + engine->irq_enable_mask = GT_BLT_USER_INTERRUPT; + engine->irq_get = gen6_ring_get_irq; + engine->irq_put = gen6_ring_put_irq; + engine->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; if (i915_semaphore_is_enabled(dev)) { - ring->semaphore.signal = gen6_signal; - ring->semaphore.sync_to = gen6_ring_sync; + engine->semaphore.signal = gen6_signal; + engine->semaphore.sync_to = gen6_ring_sync; /* * The current semaphore is only applied on pre-gen8 * platform. And there is no VCS2 ring on the pre-gen8 @@ -3038,112 +3047,112 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) * initialized as INVALID. Gen8 will initialize the * sema between BCS and VCS2 later. */ - ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_BR; - ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_BV; - ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_INVALID; - ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_BVE; - ring->semaphore.mbox.wait[VCS2] = MI_SEMAPHORE_SYNC_INVALID; - ring->semaphore.mbox.signal[RCS] = GEN6_RBSYNC; - ring->semaphore.mbox.signal[VCS] = GEN6_VBSYNC; - ring->semaphore.mbox.signal[BCS] = GEN6_NOSYNC; - ring->semaphore.mbox.signal[VECS] = GEN6_VEBSYNC; - ring->semaphore.mbox.signal[VCS2] = GEN6_NOSYNC; + engine->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_BR; + engine->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_BV; + engine->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_INVALID; + engine->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_BVE; + engine->semaphore.mbox.wait[VCS2] = MI_SEMAPHORE_SYNC_INVALID; + engine->semaphore.mbox.signal[RCS] = GEN6_RBSYNC; + engine->semaphore.mbox.signal[VCS] = GEN6_VBSYNC; + engine->semaphore.mbox.signal[BCS] = GEN6_NOSYNC; + engine->semaphore.mbox.signal[VECS] = GEN6_VEBSYNC; + engine->semaphore.mbox.signal[VCS2] = GEN6_NOSYNC; } } - ring->init_hw = init_ring_common; + engine->init_hw = init_ring_common; - return intel_init_ring_buffer(dev, ring); + return intel_init_ring_buffer(dev, engine); } int intel_init_vebox_ring_buffer(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring = &dev_priv->ring[VECS]; + struct intel_engine_cs *engine = &dev_priv->ring[VECS]; - ring->name = "video enhancement ring"; - ring->id = VECS; - ring->exec_id = I915_EXEC_VEBOX; + engine->name = "video enhancement ring"; + engine->id = VECS; + engine->exec_id = I915_EXEC_VEBOX; - ring->mmio_base = VEBOX_RING_BASE; - ring->write_tail = ring_write_tail; - ring->flush = gen6_ring_flush; - ring->add_request = gen6_add_request; - ring->get_seqno = gen6_ring_get_seqno; - ring->set_seqno = ring_set_seqno; + engine->mmio_base = VEBOX_RING_BASE; + engine->write_tail = ring_write_tail; + engine->flush = gen6_ring_flush; + engine->add_request = gen6_add_request; + engine->get_seqno = gen6_ring_get_seqno; + engine->set_seqno = ring_set_seqno; if (INTEL_INFO(dev)->gen >= 8) { - ring->irq_enable_mask = + engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT << GEN8_VECS_IRQ_SHIFT; - ring->irq_get = gen8_ring_get_irq; - ring->irq_put = gen8_ring_put_irq; - ring->dispatch_execbuffer = gen8_ring_dispatch_execbuffer; + engine->irq_get = gen8_ring_get_irq; + engine->irq_put = gen8_ring_put_irq; + engine->dispatch_execbuffer = gen8_ring_dispatch_execbuffer; if (i915_semaphore_is_enabled(dev)) { - ring->semaphore.sync_to = gen8_ring_sync; - ring->semaphore.signal = gen8_xcs_signal; - GEN8_RING_SEMAPHORE_INIT; + engine->semaphore.sync_to = gen8_ring_sync; + engine->semaphore.signal = gen8_xcs_signal; + GEN8_RING_SEMAPHORE_INIT(engine); } } else { - ring->irq_enable_mask = PM_VEBOX_USER_INTERRUPT; - ring->irq_get = hsw_vebox_get_irq; - ring->irq_put = hsw_vebox_put_irq; - ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; + engine->irq_enable_mask = PM_VEBOX_USER_INTERRUPT; + engine->irq_get = hsw_vebox_get_irq; + engine->irq_put = hsw_vebox_put_irq; + engine->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; if (i915_semaphore_is_enabled(dev)) { - ring->semaphore.sync_to = gen6_ring_sync; - ring->semaphore.signal = gen6_signal; - ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_VER; - ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_VEV; - ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_VEB; - ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_INVALID; - ring->semaphore.mbox.wait[VCS2] = MI_SEMAPHORE_SYNC_INVALID; - ring->semaphore.mbox.signal[RCS] = GEN6_RVESYNC; - ring->semaphore.mbox.signal[VCS] = GEN6_VVESYNC; - ring->semaphore.mbox.signal[BCS] = GEN6_BVESYNC; - ring->semaphore.mbox.signal[VECS] = GEN6_NOSYNC; - ring->semaphore.mbox.signal[VCS2] = GEN6_NOSYNC; + engine->semaphore.sync_to = gen6_ring_sync; + engine->semaphore.signal = gen6_signal; + engine->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_VER; + engine->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_VEV; + engine->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_VEB; + engine->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_INVALID; + engine->semaphore.mbox.wait[VCS2] = MI_SEMAPHORE_SYNC_INVALID; + engine->semaphore.mbox.signal[RCS] = GEN6_RVESYNC; + engine->semaphore.mbox.signal[VCS] = GEN6_VVESYNC; + engine->semaphore.mbox.signal[BCS] = GEN6_BVESYNC; + engine->semaphore.mbox.signal[VECS] = GEN6_NOSYNC; + engine->semaphore.mbox.signal[VCS2] = GEN6_NOSYNC; } } - ring->init_hw = init_ring_common; + engine->init_hw = init_ring_common; - return intel_init_ring_buffer(dev, ring); + return intel_init_ring_buffer(dev, engine); } int intel_ring_flush_all_caches(struct drm_i915_gem_request *req) { - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; int ret; - if (!ring->gpu_caches_dirty) + if (!engine->gpu_caches_dirty) return 0; - ret = ring->flush(req, 0, I915_GEM_GPU_DOMAINS); + ret = engine->flush(req, 0, I915_GEM_GPU_DOMAINS); if (ret) return ret; trace_i915_gem_ring_flush(req, 0, I915_GEM_GPU_DOMAINS); - ring->gpu_caches_dirty = false; + engine->gpu_caches_dirty = false; return 0; } int intel_ring_invalidate_all_caches(struct drm_i915_gem_request *req) { - struct intel_engine_cs *ring = req->ring; + struct intel_engine_cs *engine = req->ring; uint32_t flush_domains; int ret; flush_domains = 0; - if (ring->gpu_caches_dirty) + if (engine->gpu_caches_dirty) flush_domains = I915_GEM_GPU_DOMAINS; - ret = ring->flush(req, I915_GEM_GPU_DOMAINS, flush_domains); + ret = engine->flush(req, I915_GEM_GPU_DOMAINS, flush_domains); if (ret) return ret; trace_i915_gem_ring_flush(req, I915_GEM_GPU_DOMAINS, flush_domains); - ring->gpu_caches_dirty = false; + engine->gpu_caches_dirty = false; return 0; } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 4b1439deb7fe..24efb57dcd7d 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -63,16 +63,16 @@ struct intel_hw_status_page { ((from) * I915_NUM_RINGS * i915_semaphore_seqno_size) + \ (i915_semaphore_seqno_size * (__ring)->id)) -#define GEN8_RING_SEMAPHORE_INIT do { \ +#define GEN8_RING_SEMAPHORE_INIT(e) do { \ if (!dev_priv->semaphore_obj) { \ break; \ } \ - ring->semaphore.signal_ggtt[RCS] = GEN8_SIGNAL_OFFSET(ring, RCS); \ - ring->semaphore.signal_ggtt[VCS] = GEN8_SIGNAL_OFFSET(ring, VCS); \ - ring->semaphore.signal_ggtt[BCS] = GEN8_SIGNAL_OFFSET(ring, BCS); \ - ring->semaphore.signal_ggtt[VECS] = GEN8_SIGNAL_OFFSET(ring, VECS); \ - ring->semaphore.signal_ggtt[VCS2] = GEN8_SIGNAL_OFFSET(ring, VCS2); \ - ring->semaphore.signal_ggtt[ring->id] = MI_SEMAPHORE_SYNC_INVALID; \ + (e)->semaphore.signal_ggtt[RCS] = GEN8_SIGNAL_OFFSET((e), RCS); \ + (e)->semaphore.signal_ggtt[VCS] = GEN8_SIGNAL_OFFSET((e), VCS); \ + (e)->semaphore.signal_ggtt[BCS] = GEN8_SIGNAL_OFFSET((e), BCS); \ + (e)->semaphore.signal_ggtt[VECS] = GEN8_SIGNAL_OFFSET((e), VECS); \ + (e)->semaphore.signal_ggtt[VCS2] = GEN8_SIGNAL_OFFSET((e), VCS2); \ + (e)->semaphore.signal_ggtt[(e)->id] = MI_SEMAPHORE_SYNC_INVALID; \ } while(0) enum intel_ring_hangcheck_action { -- cgit v1.2.3 From 0bc40be85f33ca1795253a5f8674efb430f83cce Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Wed, 16 Mar 2016 11:00:37 +0000 Subject: drm/i915: Rename intel_engine_cs function parameters @@ identifier func; @@ func(..., struct intel_engine_cs * - ring + engine , ...) { <... - ring + engine ...> } @@ identifier func; type T; @@ T func(..., struct intel_engine_cs * - ring + engine , ...); Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/i915_cmd_parser.c | 122 +++--- drivers/gpu/drm/i915/i915_debugfs.c | 16 +- drivers/gpu/drm/i915/i915_drv.h | 18 +- drivers/gpu/drm/i915/i915_gem.c | 86 ++-- drivers/gpu/drm/i915/i915_gem_context.c | 22 +- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 34 +- drivers/gpu/drm/i915/i915_gem_render_state.c | 6 +- drivers/gpu/drm/i915/i915_gem_render_state.h | 2 +- drivers/gpu/drm/i915/i915_gpu_error.c | 97 ++--- drivers/gpu/drm/i915/i915_irq.c | 111 ++--- drivers/gpu/drm/i915/intel_display.c | 8 +- drivers/gpu/drm/i915/intel_lrc.c | 566 ++++++++++++------------ drivers/gpu/drm/i915/intel_lrc.h | 16 +- drivers/gpu/drm/i915/intel_ringbuffer.c | 618 ++++++++++++++------------- drivers/gpu/drm/i915/intel_ringbuffer.h | 54 +-- 15 files changed, 909 insertions(+), 867 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index 814d894ed925..2c50142be559 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c @@ -555,7 +555,7 @@ static u32 gen7_blt_get_cmd_length_mask(u32 cmd_header) return 0; } -static bool validate_cmds_sorted(struct intel_engine_cs *ring, +static bool validate_cmds_sorted(struct intel_engine_cs *engine, const struct drm_i915_cmd_table *cmd_tables, int cmd_table_count) { @@ -577,7 +577,7 @@ static bool validate_cmds_sorted(struct intel_engine_cs *ring, if (curr < previous) { DRM_ERROR("CMD: table not sorted ring=%d table=%d entry=%d cmd=0x%08X prev=0x%08X\n", - ring->id, i, j, curr, previous); + engine->id, i, j, curr, previous); ret = false; } @@ -611,11 +611,11 @@ static bool check_sorted(int ring_id, return ret; } -static bool validate_regs_sorted(struct intel_engine_cs *ring) +static bool validate_regs_sorted(struct intel_engine_cs *engine) { - return check_sorted(ring->id, ring->reg_table, ring->reg_count) && - check_sorted(ring->id, ring->master_reg_table, - ring->master_reg_count); + return check_sorted(engine->id, engine->reg_table, engine->reg_count) && + check_sorted(engine->id, engine->master_reg_table, + engine->master_reg_count); } struct cmd_node { @@ -639,13 +639,13 @@ struct cmd_node { */ #define CMD_HASH_MASK STD_MI_OPCODE_MASK -static int init_hash_table(struct intel_engine_cs *ring, +static int init_hash_table(struct intel_engine_cs *engine, const struct drm_i915_cmd_table *cmd_tables, int cmd_table_count) { int i, j; - hash_init(ring->cmd_hash); + hash_init(engine->cmd_hash); for (i = 0; i < cmd_table_count; i++) { const struct drm_i915_cmd_table *table = &cmd_tables[i]; @@ -660,7 +660,7 @@ static int init_hash_table(struct intel_engine_cs *ring, return -ENOMEM; desc_node->desc = desc; - hash_add(ring->cmd_hash, &desc_node->node, + hash_add(engine->cmd_hash, &desc_node->node, desc->cmd.value & CMD_HASH_MASK); } } @@ -668,13 +668,13 @@ static int init_hash_table(struct intel_engine_cs *ring, return 0; } -static void fini_hash_table(struct intel_engine_cs *ring) +static void fini_hash_table(struct intel_engine_cs *engine) { struct hlist_node *tmp; struct cmd_node *desc_node; int i; - hash_for_each_safe(ring->cmd_hash, i, tmp, desc_node, node) { + hash_for_each_safe(engine->cmd_hash, i, tmp, desc_node, node) { hash_del(&desc_node->node); kfree(desc_node); } @@ -690,18 +690,18 @@ static void fini_hash_table(struct intel_engine_cs *ring) * * Return: non-zero if initialization fails */ -int i915_cmd_parser_init_ring(struct intel_engine_cs *ring) +int i915_cmd_parser_init_ring(struct intel_engine_cs *engine) { const struct drm_i915_cmd_table *cmd_tables; int cmd_table_count; int ret; - if (!IS_GEN7(ring->dev)) + if (!IS_GEN7(engine->dev)) return 0; - switch (ring->id) { + switch (engine->id) { case RCS: - if (IS_HASWELL(ring->dev)) { + if (IS_HASWELL(engine->dev)) { cmd_tables = hsw_render_ring_cmds; cmd_table_count = ARRAY_SIZE(hsw_render_ring_cmds); @@ -710,26 +710,26 @@ int i915_cmd_parser_init_ring(struct intel_engine_cs *ring) cmd_table_count = ARRAY_SIZE(gen7_render_cmds); } - ring->reg_table = gen7_render_regs; - ring->reg_count = ARRAY_SIZE(gen7_render_regs); + engine->reg_table = gen7_render_regs; + engine->reg_count = ARRAY_SIZE(gen7_render_regs); - if (IS_HASWELL(ring->dev)) { - ring->master_reg_table = hsw_master_regs; - ring->master_reg_count = ARRAY_SIZE(hsw_master_regs); + if (IS_HASWELL(engine->dev)) { + engine->master_reg_table = hsw_master_regs; + engine->master_reg_count = ARRAY_SIZE(hsw_master_regs); } else { - ring->master_reg_table = ivb_master_regs; - ring->master_reg_count = ARRAY_SIZE(ivb_master_regs); + engine->master_reg_table = ivb_master_regs; + engine->master_reg_count = ARRAY_SIZE(ivb_master_regs); } - ring->get_cmd_length_mask = gen7_render_get_cmd_length_mask; + engine->get_cmd_length_mask = gen7_render_get_cmd_length_mask; break; case VCS: cmd_tables = gen7_video_cmds; cmd_table_count = ARRAY_SIZE(gen7_video_cmds); - ring->get_cmd_length_mask = gen7_bsd_get_cmd_length_mask; + engine->get_cmd_length_mask = gen7_bsd_get_cmd_length_mask; break; case BCS: - if (IS_HASWELL(ring->dev)) { + if (IS_HASWELL(engine->dev)) { cmd_tables = hsw_blt_ring_cmds; cmd_table_count = ARRAY_SIZE(hsw_blt_ring_cmds); } else { @@ -737,44 +737,44 @@ int i915_cmd_parser_init_ring(struct intel_engine_cs *ring) cmd_table_count = ARRAY_SIZE(gen7_blt_cmds); } - ring->reg_table = gen7_blt_regs; - ring->reg_count = ARRAY_SIZE(gen7_blt_regs); + engine->reg_table = gen7_blt_regs; + engine->reg_count = ARRAY_SIZE(gen7_blt_regs); - if (IS_HASWELL(ring->dev)) { - ring->master_reg_table = hsw_master_regs; - ring->master_reg_count = ARRAY_SIZE(hsw_master_regs); + if (IS_HASWELL(engine->dev)) { + engine->master_reg_table = hsw_master_regs; + engine->master_reg_count = ARRAY_SIZE(hsw_master_regs); } else { - ring->master_reg_table = ivb_master_regs; - ring->master_reg_count = ARRAY_SIZE(ivb_master_regs); + engine->master_reg_table = ivb_master_regs; + engine->master_reg_count = ARRAY_SIZE(ivb_master_regs); } - ring->get_cmd_length_mask = gen7_blt_get_cmd_length_mask; + engine->get_cmd_length_mask = gen7_blt_get_cmd_length_mask; break; case VECS: cmd_tables = hsw_vebox_cmds; cmd_table_count = ARRAY_SIZE(hsw_vebox_cmds); /* VECS can use the same length_mask function as VCS */ - ring->get_cmd_length_mask = gen7_bsd_get_cmd_length_mask; + engine->get_cmd_length_mask = gen7_bsd_get_cmd_length_mask; break; default: DRM_ERROR("CMD: cmd_parser_init with unknown ring: %d\n", - ring->id); + engine->id); BUG(); } - BUG_ON(!validate_cmds_sorted(ring, cmd_tables, cmd_table_count)); - BUG_ON(!validate_regs_sorted(ring)); + BUG_ON(!validate_cmds_sorted(engine, cmd_tables, cmd_table_count)); + BUG_ON(!validate_regs_sorted(engine)); - WARN_ON(!hash_empty(ring->cmd_hash)); + WARN_ON(!hash_empty(engine->cmd_hash)); - ret = init_hash_table(ring, cmd_tables, cmd_table_count); + ret = init_hash_table(engine, cmd_tables, cmd_table_count); if (ret) { DRM_ERROR("CMD: cmd_parser_init failed!\n"); - fini_hash_table(ring); + fini_hash_table(engine); return ret; } - ring->needs_cmd_parser = true; + engine->needs_cmd_parser = true; return 0; } @@ -786,21 +786,21 @@ int i915_cmd_parser_init_ring(struct intel_engine_cs *ring) * Releases any resources related to command parsing that may have been * initialized for the specified ring. */ -void i915_cmd_parser_fini_ring(struct intel_engine_cs *ring) +void i915_cmd_parser_fini_ring(struct intel_engine_cs *engine) { - if (!ring->needs_cmd_parser) + if (!engine->needs_cmd_parser) return; - fini_hash_table(ring); + fini_hash_table(engine); } static const struct drm_i915_cmd_descriptor* -find_cmd_in_table(struct intel_engine_cs *ring, +find_cmd_in_table(struct intel_engine_cs *engine, u32 cmd_header) { struct cmd_node *desc_node; - hash_for_each_possible(ring->cmd_hash, desc_node, node, + hash_for_each_possible(engine->cmd_hash, desc_node, node, cmd_header & CMD_HASH_MASK) { const struct drm_i915_cmd_descriptor *desc = desc_node->desc; u32 masked_cmd = desc->cmd.mask & cmd_header; @@ -822,18 +822,18 @@ find_cmd_in_table(struct intel_engine_cs *ring, * ring's default length encoding and returns default_desc. */ static const struct drm_i915_cmd_descriptor* -find_cmd(struct intel_engine_cs *ring, +find_cmd(struct intel_engine_cs *engine, u32 cmd_header, struct drm_i915_cmd_descriptor *default_desc) { const struct drm_i915_cmd_descriptor *desc; u32 mask; - desc = find_cmd_in_table(ring, cmd_header); + desc = find_cmd_in_table(engine, cmd_header); if (desc) return desc; - mask = ring->get_cmd_length_mask(cmd_header); + mask = engine->get_cmd_length_mask(cmd_header); if (!mask) return NULL; @@ -963,18 +963,18 @@ unpin_src: * * Return: true if the ring requires software command parsing */ -bool i915_needs_cmd_parser(struct intel_engine_cs *ring) +bool i915_needs_cmd_parser(struct intel_engine_cs *engine) { - if (!ring->needs_cmd_parser) + if (!engine->needs_cmd_parser) return false; - if (!USES_PPGTT(ring->dev)) + if (!USES_PPGTT(engine->dev)) return false; return (i915.enable_cmd_parser == 1); } -static bool check_cmd(const struct intel_engine_cs *ring, +static bool check_cmd(const struct intel_engine_cs *engine, const struct drm_i915_cmd_descriptor *desc, const u32 *cmd, u32 length, const bool is_master, @@ -1004,17 +1004,17 @@ static bool check_cmd(const struct intel_engine_cs *ring, offset += step) { const u32 reg_addr = cmd[offset] & desc->reg.mask; const struct drm_i915_reg_descriptor *reg = - find_reg(ring->reg_table, ring->reg_count, + find_reg(engine->reg_table, engine->reg_count, reg_addr); if (!reg && is_master) - reg = find_reg(ring->master_reg_table, - ring->master_reg_count, + reg = find_reg(engine->master_reg_table, + engine->master_reg_count, reg_addr); if (!reg) { DRM_DEBUG_DRIVER("CMD: Rejected register 0x%08X in command: 0x%08X (ring=%d)\n", - reg_addr, *cmd, ring->id); + reg_addr, *cmd, engine->id); return false; } @@ -1087,7 +1087,7 @@ static bool check_cmd(const struct intel_engine_cs *ring, *cmd, desc->bits[i].mask, desc->bits[i].expected, - dword, ring->id); + dword, engine->id); return false; } } @@ -1113,7 +1113,7 @@ static bool check_cmd(const struct intel_engine_cs *ring, * Return: non-zero if the parser finds violations or otherwise fails; -EACCES * if the batch appears legal but should use hardware parsing */ -int i915_parse_cmds(struct intel_engine_cs *ring, +int i915_parse_cmds(struct intel_engine_cs *engine, struct drm_i915_gem_object *batch_obj, struct drm_i915_gem_object *shadow_batch_obj, u32 batch_start_offset, @@ -1147,7 +1147,7 @@ int i915_parse_cmds(struct intel_engine_cs *ring, if (*cmd == MI_BATCH_BUFFER_END) break; - desc = find_cmd(ring, *cmd, &default_desc); + desc = find_cmd(engine, *cmd, &default_desc); if (!desc) { DRM_DEBUG_DRIVER("CMD: Unrecognized command: 0x%08X\n", *cmd); @@ -1179,7 +1179,7 @@ int i915_parse_cmds(struct intel_engine_cs *ring, break; } - if (!check_cmd(ring, desc, cmd, length, is_master, + if (!check_cmd(engine, desc, cmd, length, is_master, &oacontrol_set)) { ret = -EINVAL; break; diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 5037ccb18e77..164e1432d41f 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -725,11 +725,11 @@ static int i915_gem_request_info(struct seq_file *m, void *data) } static void i915_ring_seqno_info(struct seq_file *m, - struct intel_engine_cs *ring) + struct intel_engine_cs *engine) { - if (ring->get_seqno) { + if (engine->get_seqno) { seq_printf(m, "Current sequence (%s): %x\n", - ring->name, ring->get_seqno(ring, false)); + engine->name, engine->get_seqno(engine, false)); } } @@ -1992,22 +1992,22 @@ static int i915_context_status(struct seq_file *m, void *unused) static void i915_dump_lrc_obj(struct seq_file *m, struct intel_context *ctx, - struct intel_engine_cs *ring) + struct intel_engine_cs *engine) { struct page *page; uint32_t *reg_state; int j; - struct drm_i915_gem_object *ctx_obj = ctx->engine[ring->id].state; + struct drm_i915_gem_object *ctx_obj = ctx->engine[engine->id].state; unsigned long ggtt_offset = 0; if (ctx_obj == NULL) { seq_printf(m, "Context on %s with no gem object\n", - ring->name); + engine->name); return; } - seq_printf(m, "CONTEXT: %s %u\n", ring->name, - intel_execlists_ctx_id(ctx, ring)); + seq_printf(m, "CONTEXT: %s %u\n", engine->name, + intel_execlists_ctx_id(ctx, engine)); if (!i915_gem_obj_ggtt_bound(ctx_obj)) seq_puts(m, "\tNot bound in GGTT\n"); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 80b14f1ba302..8d87242ce601 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2964,10 +2964,10 @@ int __must_check i915_gem_get_seqno(struct drm_device *dev, u32 *seqno); int __must_check i915_gem_set_seqno(struct drm_device *dev, u32 seqno); struct drm_i915_gem_request * -i915_gem_find_active_request(struct intel_engine_cs *ring); +i915_gem_find_active_request(struct intel_engine_cs *engine); bool i915_gem_retire_requests(struct drm_device *dev); -void i915_gem_retire_requests_ring(struct intel_engine_cs *ring); +void i915_gem_retire_requests_ring(struct intel_engine_cs *engine); int __must_check i915_gem_check_wedge(struct i915_gpu_error *error, bool interruptible); @@ -3297,10 +3297,10 @@ const char *i915_cache_level_str(struct drm_i915_private *i915, int type); /* i915_cmd_parser.c */ int i915_cmd_parser_get_version(void); -int i915_cmd_parser_init_ring(struct intel_engine_cs *ring); -void i915_cmd_parser_fini_ring(struct intel_engine_cs *ring); -bool i915_needs_cmd_parser(struct intel_engine_cs *ring); -int i915_parse_cmds(struct intel_engine_cs *ring, +int i915_cmd_parser_init_ring(struct intel_engine_cs *engine); +void i915_cmd_parser_fini_ring(struct intel_engine_cs *engine); +bool i915_needs_cmd_parser(struct intel_engine_cs *engine); +int i915_parse_cmds(struct intel_engine_cs *engine, struct drm_i915_gem_object *batch_obj, struct drm_i915_gem_object *shadow_batch_obj, u32 batch_start_offset, @@ -3571,11 +3571,11 @@ wait_remaining_ms_from_jiffies(unsigned long timestamp_jiffies, int to_wait_ms) } } -static inline void i915_trace_irq_get(struct intel_engine_cs *ring, +static inline void i915_trace_irq_get(struct intel_engine_cs *engine, struct drm_i915_gem_request *req) { - if (ring->trace_irq_req == NULL && ring->irq_get(ring)) - i915_gem_request_assign(&ring->trace_irq_req, req); + if (engine->trace_irq_req == NULL && engine->irq_get(engine)) + i915_gem_request_assign(&engine->trace_irq_req, req); } #endif diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 5a7f6032f066..1119b8f46f09 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1141,9 +1141,9 @@ static void fake_irq(unsigned long data) } static bool missed_irq(struct drm_i915_private *dev_priv, - struct intel_engine_cs *ring) + struct intel_engine_cs *engine) { - return test_bit(ring->id, &dev_priv->gpu_error.missed_irq_rings); + return test_bit(engine->id, &dev_priv->gpu_error.missed_irq_rings); } static unsigned long local_clock_us(unsigned *cpu) @@ -2689,11 +2689,11 @@ void i915_gem_request_free(struct kref *req_ref) } static inline int -__i915_gem_request_alloc(struct intel_engine_cs *ring, +__i915_gem_request_alloc(struct intel_engine_cs *engine, struct intel_context *ctx, struct drm_i915_gem_request **req_out) { - struct drm_i915_private *dev_priv = to_i915(ring->dev); + struct drm_i915_private *dev_priv = to_i915(engine->dev); struct drm_i915_gem_request *req; int ret; @@ -2706,13 +2706,13 @@ __i915_gem_request_alloc(struct intel_engine_cs *ring, if (req == NULL) return -ENOMEM; - ret = i915_gem_get_seqno(ring->dev, &req->seqno); + ret = i915_gem_get_seqno(engine->dev, &req->seqno); if (ret) goto err; kref_init(&req->ref); req->i915 = dev_priv; - req->ring = ring; + req->ring = engine; req->ctx = ctx; i915_gem_context_reference(req->ctx); @@ -2787,11 +2787,11 @@ void i915_gem_request_cancel(struct drm_i915_gem_request *req) } struct drm_i915_gem_request * -i915_gem_find_active_request(struct intel_engine_cs *ring) +i915_gem_find_active_request(struct intel_engine_cs *engine) { struct drm_i915_gem_request *request; - list_for_each_entry(request, &ring->request_list, list) { + list_for_each_entry(request, &engine->request_list, list) { if (i915_gem_request_completed(request, false)) continue; @@ -2802,37 +2802,37 @@ i915_gem_find_active_request(struct intel_engine_cs *ring) } static void i915_gem_reset_ring_status(struct drm_i915_private *dev_priv, - struct intel_engine_cs *ring) + struct intel_engine_cs *engine) { struct drm_i915_gem_request *request; bool ring_hung; - request = i915_gem_find_active_request(ring); + request = i915_gem_find_active_request(engine); if (request == NULL) return; - ring_hung = ring->hangcheck.score >= HANGCHECK_SCORE_RING_HUNG; + ring_hung = engine->hangcheck.score >= HANGCHECK_SCORE_RING_HUNG; i915_set_reset_status(dev_priv, request->ctx, ring_hung); - list_for_each_entry_continue(request, &ring->request_list, list) + list_for_each_entry_continue(request, &engine->request_list, list) i915_set_reset_status(dev_priv, request->ctx, false); } static void i915_gem_reset_ring_cleanup(struct drm_i915_private *dev_priv, - struct intel_engine_cs *ring) + struct intel_engine_cs *engine) { struct intel_ringbuffer *buffer; - while (!list_empty(&ring->active_list)) { + while (!list_empty(&engine->active_list)) { struct drm_i915_gem_object *obj; - obj = list_first_entry(&ring->active_list, + obj = list_first_entry(&engine->active_list, struct drm_i915_gem_object, - ring_list[ring->id]); + ring_list[engine->id]); - i915_gem_object_retire__read(obj, ring->id); + i915_gem_object_retire__read(obj, engine->id); } /* @@ -2842,14 +2842,14 @@ static void i915_gem_reset_ring_cleanup(struct drm_i915_private *dev_priv, */ if (i915.enable_execlists) { - spin_lock_irq(&ring->execlist_lock); + spin_lock_irq(&engine->execlist_lock); /* list_splice_tail_init checks for empty lists */ - list_splice_tail_init(&ring->execlist_queue, - &ring->execlist_retired_req_list); + list_splice_tail_init(&engine->execlist_queue, + &engine->execlist_retired_req_list); - spin_unlock_irq(&ring->execlist_lock); - intel_execlists_retire_requests(ring); + spin_unlock_irq(&engine->execlist_lock); + intel_execlists_retire_requests(engine); } /* @@ -2859,10 +2859,10 @@ static void i915_gem_reset_ring_cleanup(struct drm_i915_private *dev_priv, * implicit references on things like e.g. ppgtt address spaces through * the request. */ - while (!list_empty(&ring->request_list)) { + while (!list_empty(&engine->request_list)) { struct drm_i915_gem_request *request; - request = list_first_entry(&ring->request_list, + request = list_first_entry(&engine->request_list, struct drm_i915_gem_request, list); @@ -2876,7 +2876,7 @@ static void i915_gem_reset_ring_cleanup(struct drm_i915_private *dev_priv, * upon reset is less than when we start. Do one more pass over * all the ringbuffers to reset last_retired_head. */ - list_for_each_entry(buffer, &ring->buffers, link) { + list_for_each_entry(buffer, &engine->buffers, link) { buffer->last_retired_head = buffer->tail; intel_ring_update_space(buffer); } @@ -2910,19 +2910,19 @@ void i915_gem_reset(struct drm_device *dev) * This function clears the request list as sequence numbers are passed. */ void -i915_gem_retire_requests_ring(struct intel_engine_cs *ring) +i915_gem_retire_requests_ring(struct intel_engine_cs *engine) { - WARN_ON(i915_verify_lists(ring->dev)); + WARN_ON(i915_verify_lists(engine->dev)); /* Retire requests first as we use it above for the early return. * If we retire requests last, we may use a later seqno and so clear * the requests lists without clearing the active list, leading to * confusion. */ - while (!list_empty(&ring->request_list)) { + while (!list_empty(&engine->request_list)) { struct drm_i915_gem_request *request; - request = list_first_entry(&ring->request_list, + request = list_first_entry(&engine->request_list, struct drm_i915_gem_request, list); @@ -2936,26 +2936,26 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring) * by the ringbuffer to the flushing/inactive lists as appropriate, * before we free the context associated with the requests. */ - while (!list_empty(&ring->active_list)) { + while (!list_empty(&engine->active_list)) { struct drm_i915_gem_object *obj; - obj = list_first_entry(&ring->active_list, - struct drm_i915_gem_object, - ring_list[ring->id]); + obj = list_first_entry(&engine->active_list, + struct drm_i915_gem_object, + ring_list[engine->id]); - if (!list_empty(&obj->last_read_req[ring->id]->list)) + if (!list_empty(&obj->last_read_req[engine->id]->list)) break; - i915_gem_object_retire__read(obj, ring->id); + i915_gem_object_retire__read(obj, engine->id); } - if (unlikely(ring->trace_irq_req && - i915_gem_request_completed(ring->trace_irq_req, true))) { - ring->irq_put(ring); - i915_gem_request_assign(&ring->trace_irq_req, NULL); + if (unlikely(engine->trace_irq_req && + i915_gem_request_completed(engine->trace_irq_req, true))) { + engine->irq_put(engine); + i915_gem_request_assign(&engine->trace_irq_req, NULL); } - WARN_ON(i915_verify_lists(ring->dev)); + WARN_ON(i915_verify_lists(engine->dev)); } bool @@ -5022,10 +5022,10 @@ i915_gem_cleanup_ringbuffer(struct drm_device *dev) } static void -init_ring_lists(struct intel_engine_cs *ring) +init_ring_lists(struct intel_engine_cs *engine) { - INIT_LIST_HEAD(&ring->active_list); - INIT_LIST_HEAD(&ring->request_list); + INIT_LIST_HEAD(&engine->active_list); + INIT_LIST_HEAD(&engine->request_list); } void diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index cc07666c2d91..44f582988094 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -600,7 +600,7 @@ mi_set_context(struct drm_i915_gem_request *req, u32 hw_flags) return ret; } -static inline bool should_skip_switch(struct intel_engine_cs *ring, +static inline bool should_skip_switch(struct intel_engine_cs *engine, struct intel_context *from, struct intel_context *to) { @@ -608,42 +608,42 @@ static inline bool should_skip_switch(struct intel_engine_cs *ring, return false; if (to->ppgtt && from == to && - !(intel_ring_flag(ring) & to->ppgtt->pd_dirty_rings)) + !(intel_ring_flag(engine) & to->ppgtt->pd_dirty_rings)) return true; return false; } static bool -needs_pd_load_pre(struct intel_engine_cs *ring, struct intel_context *to) +needs_pd_load_pre(struct intel_engine_cs *engine, struct intel_context *to) { - struct drm_i915_private *dev_priv = ring->dev->dev_private; + struct drm_i915_private *dev_priv = engine->dev->dev_private; if (!to->ppgtt) return false; - if (INTEL_INFO(ring->dev)->gen < 8) + if (INTEL_INFO(engine->dev)->gen < 8) return true; - if (ring != &dev_priv->ring[RCS]) + if (engine != &dev_priv->ring[RCS]) return true; return false; } static bool -needs_pd_load_post(struct intel_engine_cs *ring, struct intel_context *to, - u32 hw_flags) +needs_pd_load_post(struct intel_engine_cs *engine, struct intel_context *to, + u32 hw_flags) { - struct drm_i915_private *dev_priv = ring->dev->dev_private; + struct drm_i915_private *dev_priv = engine->dev->dev_private; if (!to->ppgtt) return false; - if (!IS_GEN8(ring->dev)) + if (!IS_GEN8(engine->dev)) return false; - if (ring != &dev_priv->ring[RCS]) + if (engine != &dev_priv->ring[RCS]) return false; if (hw_flags & MI_RESTORE_INHIBIT) diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index b73496ea5583..f94d756828e8 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -599,7 +599,7 @@ static bool only_mappable_for_reloc(unsigned int flags) static int i915_gem_execbuffer_reserve_vma(struct i915_vma *vma, - struct intel_engine_cs *ring, + struct intel_engine_cs *engine, bool *need_reloc) { struct drm_i915_gem_object *obj = vma->obj; @@ -713,7 +713,7 @@ eb_vma_misplaced(struct i915_vma *vma) } static int -i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, +i915_gem_execbuffer_reserve(struct intel_engine_cs *engine, struct list_head *vmas, struct intel_context *ctx, bool *need_relocs) @@ -723,10 +723,10 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, struct i915_address_space *vm; struct list_head ordered_vmas; struct list_head pinned_vmas; - bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4; + bool has_fenced_gpu_access = INTEL_INFO(engine->dev)->gen < 4; int retry; - i915_gem_retire_requests_ring(ring); + i915_gem_retire_requests_ring(engine); vm = list_first_entry(vmas, struct i915_vma, exec_list)->vm; @@ -788,7 +788,9 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, if (eb_vma_misplaced(vma)) ret = i915_vma_unbind(vma); else - ret = i915_gem_execbuffer_reserve_vma(vma, ring, need_relocs); + ret = i915_gem_execbuffer_reserve_vma(vma, + engine, + need_relocs); if (ret) goto err; } @@ -798,7 +800,8 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, if (drm_mm_node_allocated(&vma->node)) continue; - ret = i915_gem_execbuffer_reserve_vma(vma, ring, need_relocs); + ret = i915_gem_execbuffer_reserve_vma(vma, engine, + need_relocs); if (ret) goto err; } @@ -821,7 +824,7 @@ static int i915_gem_execbuffer_relocate_slow(struct drm_device *dev, struct drm_i915_gem_execbuffer2 *args, struct drm_file *file, - struct intel_engine_cs *ring, + struct intel_engine_cs *engine, struct eb_vmas *eb, struct drm_i915_gem_exec_object2 *exec, struct intel_context *ctx) @@ -910,7 +913,8 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, goto err; need_relocs = (args->flags & I915_EXEC_NO_RELOC) == 0; - ret = i915_gem_execbuffer_reserve(ring, &eb->vmas, ctx, &need_relocs); + ret = i915_gem_execbuffer_reserve(engine, &eb->vmas, ctx, + &need_relocs); if (ret) goto err; @@ -1062,12 +1066,12 @@ validate_exec_list(struct drm_device *dev, static struct intel_context * i915_gem_validate_context(struct drm_device *dev, struct drm_file *file, - struct intel_engine_cs *ring, const u32 ctx_id) + struct intel_engine_cs *engine, const u32 ctx_id) { struct intel_context *ctx = NULL; struct i915_ctx_hang_stats *hs; - if (ring->id != RCS && ctx_id != DEFAULT_CONTEXT_HANDLE) + if (engine->id != RCS && ctx_id != DEFAULT_CONTEXT_HANDLE) return ERR_PTR(-EINVAL); ctx = i915_gem_context_get(file->driver_priv, ctx_id); @@ -1080,8 +1084,8 @@ i915_gem_validate_context(struct drm_device *dev, struct drm_file *file, return ERR_PTR(-EIO); } - if (i915.enable_execlists && !ctx->engine[ring->id].state) { - int ret = intel_lr_context_deferred_alloc(ctx, ring); + if (i915.enable_execlists && !ctx->engine[engine->id].state) { + int ret = intel_lr_context_deferred_alloc(ctx, engine); if (ret) { DRM_DEBUG("Could not create LRC %u: %d\n", ctx_id, ret); return ERR_PTR(ret); @@ -1171,7 +1175,7 @@ i915_reset_gen7_sol_offsets(struct drm_device *dev, } static struct drm_i915_gem_object* -i915_gem_execbuffer_parse(struct intel_engine_cs *ring, +i915_gem_execbuffer_parse(struct intel_engine_cs *engine, struct drm_i915_gem_exec_object2 *shadow_exec_entry, struct eb_vmas *eb, struct drm_i915_gem_object *batch_obj, @@ -1183,12 +1187,12 @@ i915_gem_execbuffer_parse(struct intel_engine_cs *ring, struct i915_vma *vma; int ret; - shadow_batch_obj = i915_gem_batch_pool_get(&ring->batch_pool, + shadow_batch_obj = i915_gem_batch_pool_get(&engine->batch_pool, PAGE_ALIGN(batch_len)); if (IS_ERR(shadow_batch_obj)) return shadow_batch_obj; - ret = i915_parse_cmds(ring, + ret = i915_parse_cmds(engine, batch_obj, shadow_batch_obj, batch_start_offset, diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/i915/i915_gem_render_state.c index fc7e6d5c6251..b21f72ec895c 100644 --- a/drivers/gpu/drm/i915/i915_gem_render_state.c +++ b/drivers/gpu/drm/i915/i915_gem_render_state.c @@ -169,15 +169,15 @@ void i915_gem_render_state_fini(struct render_state *so) drm_gem_object_unreference(&so->obj->base); } -int i915_gem_render_state_prepare(struct intel_engine_cs *ring, +int i915_gem_render_state_prepare(struct intel_engine_cs *engine, struct render_state *so) { int ret; - if (WARN_ON(ring->id != RCS)) + if (WARN_ON(engine->id != RCS)) return -ENOENT; - ret = render_state_init(so, ring->dev); + ret = render_state_init(so, engine->dev); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.h b/drivers/gpu/drm/i915/i915_gem_render_state.h index e641bb093a90..6aaa3a10a630 100644 --- a/drivers/gpu/drm/i915/i915_gem_render_state.h +++ b/drivers/gpu/drm/i915/i915_gem_render_state.h @@ -43,7 +43,7 @@ struct render_state { int i915_gem_render_state_init(struct drm_i915_gem_request *req); void i915_gem_render_state_fini(struct render_state *so); -int i915_gem_render_state_prepare(struct intel_engine_cs *ring, +int i915_gem_render_state_prepare(struct intel_engine_cs *engine, struct render_state *so); #endif /* _I915_GEM_RENDER_STATE_H_ */ diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index d97cadcfccb1..029ed4031edf 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -842,7 +842,7 @@ static void i915_gem_record_fences(struct drm_device *dev, static void gen8_record_semaphore_state(struct drm_i915_private *dev_priv, struct drm_i915_error_state *error, - struct intel_engine_cs *ring, + struct intel_engine_cs *engine, struct drm_i915_error_ring *ering) { struct intel_engine_cs *to; @@ -861,63 +861,64 @@ static void gen8_record_semaphore_state(struct drm_i915_private *dev_priv, u16 signal_offset; u32 *tmp; - if (ring == to) + if (engine == to) continue; - signal_offset = (GEN8_SIGNAL_OFFSET(ring, i) & (PAGE_SIZE - 1)) + signal_offset = (GEN8_SIGNAL_OFFSET(engine, i) & (PAGE_SIZE - 1)) / 4; tmp = error->semaphore_obj->pages[0]; - idx = intel_ring_sync_index(ring, to); + idx = intel_ring_sync_index(engine, to); ering->semaphore_mboxes[idx] = tmp[signal_offset]; - ering->semaphore_seqno[idx] = ring->semaphore.sync_seqno[idx]; + ering->semaphore_seqno[idx] = engine->semaphore.sync_seqno[idx]; } } static void gen6_record_semaphore_state(struct drm_i915_private *dev_priv, - struct intel_engine_cs *ring, + struct intel_engine_cs *engine, struct drm_i915_error_ring *ering) { - ering->semaphore_mboxes[0] = I915_READ(RING_SYNC_0(ring->mmio_base)); - ering->semaphore_mboxes[1] = I915_READ(RING_SYNC_1(ring->mmio_base)); - ering->semaphore_seqno[0] = ring->semaphore.sync_seqno[0]; - ering->semaphore_seqno[1] = ring->semaphore.sync_seqno[1]; + ering->semaphore_mboxes[0] = I915_READ(RING_SYNC_0(engine->mmio_base)); + ering->semaphore_mboxes[1] = I915_READ(RING_SYNC_1(engine->mmio_base)); + ering->semaphore_seqno[0] = engine->semaphore.sync_seqno[0]; + ering->semaphore_seqno[1] = engine->semaphore.sync_seqno[1]; if (HAS_VEBOX(dev_priv->dev)) { ering->semaphore_mboxes[2] = - I915_READ(RING_SYNC_2(ring->mmio_base)); - ering->semaphore_seqno[2] = ring->semaphore.sync_seqno[2]; + I915_READ(RING_SYNC_2(engine->mmio_base)); + ering->semaphore_seqno[2] = engine->semaphore.sync_seqno[2]; } } static void i915_record_ring_state(struct drm_device *dev, struct drm_i915_error_state *error, - struct intel_engine_cs *ring, + struct intel_engine_cs *engine, struct drm_i915_error_ring *ering) { struct drm_i915_private *dev_priv = dev->dev_private; if (INTEL_INFO(dev)->gen >= 6) { - ering->rc_psmi = I915_READ(RING_PSMI_CTL(ring->mmio_base)); - ering->fault_reg = I915_READ(RING_FAULT_REG(ring)); + ering->rc_psmi = I915_READ(RING_PSMI_CTL(engine->mmio_base)); + ering->fault_reg = I915_READ(RING_FAULT_REG(engine)); if (INTEL_INFO(dev)->gen >= 8) - gen8_record_semaphore_state(dev_priv, error, ring, ering); + gen8_record_semaphore_state(dev_priv, error, engine, + ering); else - gen6_record_semaphore_state(dev_priv, ring, ering); + gen6_record_semaphore_state(dev_priv, engine, ering); } if (INTEL_INFO(dev)->gen >= 4) { - ering->faddr = I915_READ(RING_DMA_FADD(ring->mmio_base)); - ering->ipeir = I915_READ(RING_IPEIR(ring->mmio_base)); - ering->ipehr = I915_READ(RING_IPEHR(ring->mmio_base)); - ering->instdone = I915_READ(RING_INSTDONE(ring->mmio_base)); - ering->instps = I915_READ(RING_INSTPS(ring->mmio_base)); - ering->bbaddr = I915_READ(RING_BBADDR(ring->mmio_base)); + ering->faddr = I915_READ(RING_DMA_FADD(engine->mmio_base)); + ering->ipeir = I915_READ(RING_IPEIR(engine->mmio_base)); + ering->ipehr = I915_READ(RING_IPEHR(engine->mmio_base)); + ering->instdone = I915_READ(RING_INSTDONE(engine->mmio_base)); + ering->instps = I915_READ(RING_INSTPS(engine->mmio_base)); + ering->bbaddr = I915_READ(RING_BBADDR(engine->mmio_base)); if (INTEL_INFO(dev)->gen >= 8) { - ering->faddr |= (u64) I915_READ(RING_DMA_FADD_UDW(ring->mmio_base)) << 32; - ering->bbaddr |= (u64) I915_READ(RING_BBADDR_UDW(ring->mmio_base)) << 32; + ering->faddr |= (u64) I915_READ(RING_DMA_FADD_UDW(engine->mmio_base)) << 32; + ering->bbaddr |= (u64) I915_READ(RING_BBADDR_UDW(engine->mmio_base)) << 32; } - ering->bbstate = I915_READ(RING_BBSTATE(ring->mmio_base)); + ering->bbstate = I915_READ(RING_BBSTATE(engine->mmio_base)); } else { ering->faddr = I915_READ(DMA_FADD_I8XX); ering->ipeir = I915_READ(IPEIR); @@ -925,20 +926,20 @@ static void i915_record_ring_state(struct drm_device *dev, ering->instdone = I915_READ(GEN2_INSTDONE); } - ering->waiting = waitqueue_active(&ring->irq_queue); - ering->instpm = I915_READ(RING_INSTPM(ring->mmio_base)); - ering->seqno = ring->get_seqno(ring, false); - ering->acthd = intel_ring_get_active_head(ring); - ering->start = I915_READ_START(ring); - ering->head = I915_READ_HEAD(ring); - ering->tail = I915_READ_TAIL(ring); - ering->ctl = I915_READ_CTL(ring); + ering->waiting = waitqueue_active(&engine->irq_queue); + ering->instpm = I915_READ(RING_INSTPM(engine->mmio_base)); + ering->seqno = engine->get_seqno(engine, false); + ering->acthd = intel_ring_get_active_head(engine); + ering->start = I915_READ_START(engine); + ering->head = I915_READ_HEAD(engine); + ering->tail = I915_READ_TAIL(engine); + ering->ctl = I915_READ_CTL(engine); if (I915_NEED_GFX_HWS(dev)) { i915_reg_t mmio; if (IS_GEN7(dev)) { - switch (ring->id) { + switch (engine->id) { default: case RCS: mmio = RENDER_HWS_PGA_GEN7; @@ -953,51 +954,51 @@ static void i915_record_ring_state(struct drm_device *dev, mmio = VEBOX_HWS_PGA_GEN7; break; } - } else if (IS_GEN6(ring->dev)) { - mmio = RING_HWS_PGA_GEN6(ring->mmio_base); + } else if (IS_GEN6(engine->dev)) { + mmio = RING_HWS_PGA_GEN6(engine->mmio_base); } else { /* XXX: gen8 returns to sanity */ - mmio = RING_HWS_PGA(ring->mmio_base); + mmio = RING_HWS_PGA(engine->mmio_base); } ering->hws = I915_READ(mmio); } - ering->hangcheck_score = ring->hangcheck.score; - ering->hangcheck_action = ring->hangcheck.action; + ering->hangcheck_score = engine->hangcheck.score; + ering->hangcheck_action = engine->hangcheck.action; if (USES_PPGTT(dev)) { int i; - ering->vm_info.gfx_mode = I915_READ(RING_MODE_GEN7(ring)); + ering->vm_info.gfx_mode = I915_READ(RING_MODE_GEN7(engine)); if (IS_GEN6(dev)) ering->vm_info.pp_dir_base = - I915_READ(RING_PP_DIR_BASE_READ(ring)); + I915_READ(RING_PP_DIR_BASE_READ(engine)); else if (IS_GEN7(dev)) ering->vm_info.pp_dir_base = - I915_READ(RING_PP_DIR_BASE(ring)); + I915_READ(RING_PP_DIR_BASE(engine)); else if (INTEL_INFO(dev)->gen >= 8) for (i = 0; i < 4; i++) { ering->vm_info.pdp[i] = - I915_READ(GEN8_RING_PDP_UDW(ring, i)); + I915_READ(GEN8_RING_PDP_UDW(engine, i)); ering->vm_info.pdp[i] <<= 32; ering->vm_info.pdp[i] |= - I915_READ(GEN8_RING_PDP_LDW(ring, i)); + I915_READ(GEN8_RING_PDP_LDW(engine, i)); } } } -static void i915_gem_record_active_context(struct intel_engine_cs *ring, +static void i915_gem_record_active_context(struct intel_engine_cs *engine, struct drm_i915_error_state *error, struct drm_i915_error_ring *ering) { - struct drm_i915_private *dev_priv = ring->dev->dev_private; + struct drm_i915_private *dev_priv = engine->dev->dev_private; struct drm_i915_gem_object *obj; /* Currently render ring is the only HW context user */ - if (ring->id != RCS || !error->ccid) + if (engine->id != RCS || !error->ccid) return; list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index f172de0a61bf..64658961a7e5 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -994,14 +994,14 @@ static void ironlake_rps_change_irq_handler(struct drm_device *dev) return; } -static void notify_ring(struct intel_engine_cs *ring) +static void notify_ring(struct intel_engine_cs *engine) { - if (!intel_ring_initialized(ring)) + if (!intel_ring_initialized(engine)) return; - trace_i915_gem_request_notify(ring); + trace_i915_gem_request_notify(engine); - wake_up_all(&ring->irq_queue); + wake_up_all(&engine->irq_queue); } static void vlv_c0_read(struct drm_i915_private *dev_priv, @@ -1319,12 +1319,12 @@ static void snb_gt_irq_handler(struct drm_device *dev, } static __always_inline void -gen8_cs_irq_handler(struct intel_engine_cs *ring, u32 iir, int test_shift) +gen8_cs_irq_handler(struct intel_engine_cs *engine, u32 iir, int test_shift) { if (iir & (GT_RENDER_USER_INTERRUPT << test_shift)) - notify_ring(ring); + notify_ring(engine); if (iir & (GT_CONTEXT_SWITCH_INTERRUPT << test_shift)) - intel_lrc_irq_handler(ring); + intel_lrc_irq_handler(engine); } static irqreturn_t gen8_gt_irq_handler(struct drm_i915_private *dev_priv, @@ -2805,10 +2805,10 @@ static void gen8_disable_vblank(struct drm_device *dev, unsigned int pipe) } static bool -ring_idle(struct intel_engine_cs *ring, u32 seqno) +ring_idle(struct intel_engine_cs *engine, u32 seqno) { - return (list_empty(&ring->request_list) || - i915_seqno_passed(seqno, ring->last_submitted_seqno)); + return (list_empty(&engine->request_list) || + i915_seqno_passed(seqno, engine->last_submitted_seqno)); } static bool @@ -2824,42 +2824,43 @@ ipehr_is_semaphore_wait(struct drm_device *dev, u32 ipehr) } static struct intel_engine_cs * -semaphore_wait_to_signaller_ring(struct intel_engine_cs *ring, u32 ipehr, u64 offset) +semaphore_wait_to_signaller_ring(struct intel_engine_cs *engine, u32 ipehr, + u64 offset) { - struct drm_i915_private *dev_priv = ring->dev->dev_private; + struct drm_i915_private *dev_priv = engine->dev->dev_private; struct intel_engine_cs *signaller; int i; if (INTEL_INFO(dev_priv->dev)->gen >= 8) { for_each_ring(signaller, dev_priv, i) { - if (ring == signaller) + if (engine == signaller) continue; - if (offset == signaller->semaphore.signal_ggtt[ring->id]) + if (offset == signaller->semaphore.signal_ggtt[engine->id]) return signaller; } } else { u32 sync_bits = ipehr & MI_SEMAPHORE_SYNC_MASK; for_each_ring(signaller, dev_priv, i) { - if(ring == signaller) + if(engine == signaller) continue; - if (sync_bits == signaller->semaphore.mbox.wait[ring->id]) + if (sync_bits == signaller->semaphore.mbox.wait[engine->id]) return signaller; } } DRM_ERROR("No signaller ring found for ring %i, ipehr 0x%08x, offset 0x%016llx\n", - ring->id, ipehr, offset); + engine->id, ipehr, offset); return NULL; } static struct intel_engine_cs * -semaphore_waits_for(struct intel_engine_cs *ring, u32 *seqno) +semaphore_waits_for(struct intel_engine_cs *engine, u32 *seqno) { - struct drm_i915_private *dev_priv = ring->dev->dev_private; + struct drm_i915_private *dev_priv = engine->dev->dev_private; u32 cmd, ipehr, head; u64 offset = 0; int i, backwards; @@ -2881,11 +2882,11 @@ semaphore_waits_for(struct intel_engine_cs *ring, u32 *seqno) * Therefore, this function does not support execlist mode in its * current form. Just return NULL and move on. */ - if (ring->buffer == NULL) + if (engine->buffer == NULL) return NULL; - ipehr = I915_READ(RING_IPEHR(ring->mmio_base)); - if (!ipehr_is_semaphore_wait(ring->dev, ipehr)) + ipehr = I915_READ(RING_IPEHR(engine->mmio_base)); + if (!ipehr_is_semaphore_wait(engine->dev, ipehr)) return NULL; /* @@ -2896,8 +2897,8 @@ semaphore_waits_for(struct intel_engine_cs *ring, u32 *seqno) * point at at batch, and semaphores are always emitted into the * ringbuffer itself. */ - head = I915_READ_HEAD(ring) & HEAD_ADDR; - backwards = (INTEL_INFO(ring->dev)->gen >= 8) ? 5 : 4; + head = I915_READ_HEAD(engine) & HEAD_ADDR; + backwards = (INTEL_INFO(engine->dev)->gen >= 8) ? 5 : 4; for (i = backwards; i; --i) { /* @@ -2905,10 +2906,10 @@ semaphore_waits_for(struct intel_engine_cs *ring, u32 *seqno) * our ring is smaller than what the hardware (and hence * HEAD_ADDR) allows. Also handles wrap-around. */ - head &= ring->buffer->size - 1; + head &= engine->buffer->size - 1; /* This here seems to blow up */ - cmd = ioread32(ring->buffer->virtual_start + head); + cmd = ioread32(engine->buffer->virtual_start + head); if (cmd == ipehr) break; @@ -2918,24 +2919,24 @@ semaphore_waits_for(struct intel_engine_cs *ring, u32 *seqno) if (!i) return NULL; - *seqno = ioread32(ring->buffer->virtual_start + head + 4) + 1; - if (INTEL_INFO(ring->dev)->gen >= 8) { - offset = ioread32(ring->buffer->virtual_start + head + 12); + *seqno = ioread32(engine->buffer->virtual_start + head + 4) + 1; + if (INTEL_INFO(engine->dev)->gen >= 8) { + offset = ioread32(engine->buffer->virtual_start + head + 12); offset <<= 32; - offset = ioread32(ring->buffer->virtual_start + head + 8); + offset = ioread32(engine->buffer->virtual_start + head + 8); } - return semaphore_wait_to_signaller_ring(ring, ipehr, offset); + return semaphore_wait_to_signaller_ring(engine, ipehr, offset); } -static int semaphore_passed(struct intel_engine_cs *ring) +static int semaphore_passed(struct intel_engine_cs *engine) { - struct drm_i915_private *dev_priv = ring->dev->dev_private; + struct drm_i915_private *dev_priv = engine->dev->dev_private; struct intel_engine_cs *signaller; u32 seqno; - ring->hangcheck.deadlock++; + engine->hangcheck.deadlock++; - signaller = semaphore_waits_for(ring, &seqno); + signaller = semaphore_waits_for(engine, &seqno); if (signaller == NULL) return -1; @@ -2963,16 +2964,16 @@ static void semaphore_clear_deadlocks(struct drm_i915_private *dev_priv) engine->hangcheck.deadlock = 0; } -static bool subunits_stuck(struct intel_engine_cs *ring) +static bool subunits_stuck(struct intel_engine_cs *engine) { u32 instdone[I915_NUM_INSTDONE_REG]; bool stuck; int i; - if (ring->id != RCS) + if (engine->id != RCS) return true; - i915_get_extra_instdone(ring->dev, instdone); + i915_get_extra_instdone(engine->dev, instdone); /* There might be unstable subunit states even when * actual head is not moving. Filter out the unstable ones by @@ -2981,44 +2982,44 @@ static bool subunits_stuck(struct intel_engine_cs *ring) */ stuck = true; for (i = 0; i < I915_NUM_INSTDONE_REG; i++) { - const u32 tmp = instdone[i] | ring->hangcheck.instdone[i]; + const u32 tmp = instdone[i] | engine->hangcheck.instdone[i]; - if (tmp != ring->hangcheck.instdone[i]) + if (tmp != engine->hangcheck.instdone[i]) stuck = false; - ring->hangcheck.instdone[i] |= tmp; + engine->hangcheck.instdone[i] |= tmp; } return stuck; } static enum intel_ring_hangcheck_action -head_stuck(struct intel_engine_cs *ring, u64 acthd) +head_stuck(struct intel_engine_cs *engine, u64 acthd) { - if (acthd != ring->hangcheck.acthd) { + if (acthd != engine->hangcheck.acthd) { /* Clear subunit states on head movement */ - memset(ring->hangcheck.instdone, 0, - sizeof(ring->hangcheck.instdone)); + memset(engine->hangcheck.instdone, 0, + sizeof(engine->hangcheck.instdone)); return HANGCHECK_ACTIVE; } - if (!subunits_stuck(ring)) + if (!subunits_stuck(engine)) return HANGCHECK_ACTIVE; return HANGCHECK_HUNG; } static enum intel_ring_hangcheck_action -ring_stuck(struct intel_engine_cs *ring, u64 acthd) +ring_stuck(struct intel_engine_cs *engine, u64 acthd) { - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; enum intel_ring_hangcheck_action ha; u32 tmp; - ha = head_stuck(ring, acthd); + ha = head_stuck(engine, acthd); if (ha != HANGCHECK_HUNG) return ha; @@ -3030,24 +3031,24 @@ ring_stuck(struct intel_engine_cs *ring, u64 acthd) * and break the hang. This should work on * all but the second generation chipsets. */ - tmp = I915_READ_CTL(ring); + tmp = I915_READ_CTL(engine); if (tmp & RING_WAIT) { i915_handle_error(dev, false, "Kicking stuck wait on %s", - ring->name); - I915_WRITE_CTL(ring, tmp); + engine->name); + I915_WRITE_CTL(engine, tmp); return HANGCHECK_KICK; } if (INTEL_INFO(dev)->gen >= 6 && tmp & RING_WAIT_SEMAPHORE) { - switch (semaphore_passed(ring)) { + switch (semaphore_passed(engine)) { default: return HANGCHECK_HUNG; case 1: i915_handle_error(dev, false, "Kicking stuck semaphore on %s", - ring->name); - I915_WRITE_CTL(ring, tmp); + engine->name); + I915_WRITE_CTL(engine, tmp); return HANGCHECK_KICK; case 0: return HANGCHECK_WAIT; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e95f2b7ed962..317b55b0b596 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11214,7 +11214,7 @@ static int intel_gen7_queue_flip(struct drm_device *dev, return 0; } -static bool use_mmio_flip(struct intel_engine_cs *ring, +static bool use_mmio_flip(struct intel_engine_cs *engine, struct drm_i915_gem_object *obj) { /* @@ -11225,10 +11225,10 @@ static bool use_mmio_flip(struct intel_engine_cs *ring, * So using MMIO flips there would disrupt this mechanism. */ - if (ring == NULL) + if (engine == NULL) return true; - if (INTEL_INFO(ring->dev)->gen < 5) + if (INTEL_INFO(engine->dev)->gen < 5) return false; if (i915.use_mmio_flip < 0) @@ -11242,7 +11242,7 @@ static bool use_mmio_flip(struct intel_engine_cs *ring, false)) return true; else - return ring != i915_gem_request_get_ring(obj->last_write_req); + return engine != i915_gem_request_get_ring(obj->last_write_req); } static void skl_do_mmio_flip(struct intel_crtc *intel_crtc, diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 448c68e69194..25514e91479a 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -228,8 +228,8 @@ enum { static int intel_lr_context_pin(struct intel_context *ctx, struct intel_engine_cs *engine); -static void lrc_setup_hardware_status_page(struct intel_engine_cs *ring, - struct drm_i915_gem_object *default_ctx_obj); +static void lrc_setup_hardware_status_page(struct intel_engine_cs *engine, + struct drm_i915_gem_object *default_ctx_obj); /** @@ -266,23 +266,23 @@ int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists } static void -logical_ring_init_platform_invariants(struct intel_engine_cs *ring) +logical_ring_init_platform_invariants(struct intel_engine_cs *engine) { - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; if (IS_GEN8(dev) || IS_GEN9(dev)) - ring->idle_lite_restore_wa = ~0; + engine->idle_lite_restore_wa = ~0; - ring->disable_lite_restore_wa = (IS_SKL_REVID(dev, 0, SKL_REVID_B0) || + engine->disable_lite_restore_wa = (IS_SKL_REVID(dev, 0, SKL_REVID_B0) || IS_BXT_REVID(dev, 0, BXT_REVID_A1)) && - (ring->id == VCS || ring->id == VCS2); + (engine->id == VCS || engine->id == VCS2); - ring->ctx_desc_template = GEN8_CTX_VALID; - ring->ctx_desc_template |= GEN8_CTX_ADDRESSING_MODE(dev) << + engine->ctx_desc_template = GEN8_CTX_VALID; + engine->ctx_desc_template |= GEN8_CTX_ADDRESSING_MODE(dev) << GEN8_CTX_ADDRESSING_MODE_SHIFT; if (IS_GEN8(dev)) - ring->ctx_desc_template |= GEN8_CTX_L3LLC_COHERENT; - ring->ctx_desc_template |= GEN8_CTX_PRIVILEGE; + engine->ctx_desc_template |= GEN8_CTX_L3LLC_COHERENT; + engine->ctx_desc_template |= GEN8_CTX_PRIVILEGE; /* TODO: WaDisableLiteRestore when we start using semaphore * signalling between Command Streamers */ @@ -290,8 +290,8 @@ logical_ring_init_platform_invariants(struct intel_engine_cs *ring) /* WaEnableForceRestoreInCtxtDescForVCS:skl */ /* WaEnableForceRestoreInCtxtDescForVCS:bxt */ - if (ring->disable_lite_restore_wa) - ring->ctx_desc_template |= GEN8_CTX_FORCE_RESTORE; + if (engine->disable_lite_restore_wa) + engine->ctx_desc_template |= GEN8_CTX_FORCE_RESTORE; } /** @@ -314,24 +314,24 @@ logical_ring_init_platform_invariants(struct intel_engine_cs *ring) */ static void intel_lr_context_descriptor_update(struct intel_context *ctx, - struct intel_engine_cs *ring) + struct intel_engine_cs *engine) { uint64_t lrca, desc; - lrca = ctx->engine[ring->id].lrc_vma->node.start + + lrca = ctx->engine[engine->id].lrc_vma->node.start + LRC_PPHWSP_PN * PAGE_SIZE; - desc = ring->ctx_desc_template; /* bits 0-11 */ + desc = engine->ctx_desc_template; /* bits 0-11 */ desc |= lrca; /* bits 12-31 */ desc |= (lrca >> PAGE_SHIFT) << GEN8_CTX_ID_SHIFT; /* bits 32-51 */ - ctx->engine[ring->id].lrc_desc = desc; + ctx->engine[engine->id].lrc_desc = desc; } uint64_t intel_lr_context_descriptor(struct intel_context *ctx, - struct intel_engine_cs *ring) + struct intel_engine_cs *engine) { - return ctx->engine[ring->id].lrc_desc; + return ctx->engine[engine->id].lrc_desc; } /** @@ -351,9 +351,9 @@ uint64_t intel_lr_context_descriptor(struct intel_context *ctx, * Return: 20-bits globally unique context ID. */ u32 intel_execlists_ctx_id(struct intel_context *ctx, - struct intel_engine_cs *ring) + struct intel_engine_cs *engine) { - return intel_lr_context_descriptor(ctx, ring) >> GEN8_CTX_ID_SHIFT; + return intel_lr_context_descriptor(ctx, engine) >> GEN8_CTX_ID_SHIFT; } static void execlists_elsp_write(struct drm_i915_gem_request *rq0, @@ -424,21 +424,21 @@ static void execlists_submit_requests(struct drm_i915_gem_request *rq0, execlists_elsp_write(rq0, rq1); } -static void execlists_context_unqueue__locked(struct intel_engine_cs *ring) +static void execlists_context_unqueue__locked(struct intel_engine_cs *engine) { struct drm_i915_gem_request *req0 = NULL, *req1 = NULL; struct drm_i915_gem_request *cursor, *tmp; - assert_spin_locked(&ring->execlist_lock); + assert_spin_locked(&engine->execlist_lock); /* * If irqs are not active generate a warning as batches that finish * without the irqs may get lost and a GPU Hang may occur. */ - WARN_ON(!intel_irqs_enabled(ring->dev->dev_private)); + WARN_ON(!intel_irqs_enabled(engine->dev->dev_private)); /* Try to read in pairs */ - list_for_each_entry_safe(cursor, tmp, &ring->execlist_queue, + list_for_each_entry_safe(cursor, tmp, &engine->execlist_queue, execlist_link) { if (!req0) { req0 = cursor; @@ -447,7 +447,7 @@ static void execlists_context_unqueue__locked(struct intel_engine_cs *ring) * will update tail past first request's workload */ cursor->elsp_submitted = req0->elsp_submitted; list_move_tail(&req0->execlist_link, - &ring->execlist_retired_req_list); + &engine->execlist_retired_req_list); req0 = cursor; } else { req1 = cursor; @@ -459,7 +459,7 @@ static void execlists_context_unqueue__locked(struct intel_engine_cs *ring) if (unlikely(!req0)) return; - if (req0->elsp_submitted & ring->idle_lite_restore_wa) { + if (req0->elsp_submitted & engine->idle_lite_restore_wa) { /* * WaIdleLiteRestore: make sure we never cause a lite restore * with HEAD==TAIL. @@ -470,7 +470,7 @@ static void execlists_context_unqueue__locked(struct intel_engine_cs *ring) */ struct intel_ringbuffer *ringbuf; - ringbuf = req0->ctx->engine[ring->id].ringbuf; + ringbuf = req0->ctx->engine[engine->id].ringbuf; req0->tail += 8; req0->tail &= ringbuf->size - 1; } @@ -478,34 +478,34 @@ static void execlists_context_unqueue__locked(struct intel_engine_cs *ring) execlists_submit_requests(req0, req1); } -static void execlists_context_unqueue(struct intel_engine_cs *ring) +static void execlists_context_unqueue(struct intel_engine_cs *engine) { - struct drm_i915_private *dev_priv = ring->dev->dev_private; + struct drm_i915_private *dev_priv = engine->dev->dev_private; spin_lock(&dev_priv->uncore.lock); intel_uncore_forcewake_get__locked(dev_priv, FORCEWAKE_ALL); - execlists_context_unqueue__locked(ring); + execlists_context_unqueue__locked(engine); intel_uncore_forcewake_put__locked(dev_priv, FORCEWAKE_ALL); spin_unlock(&dev_priv->uncore.lock); } static unsigned int -execlists_check_remove_request(struct intel_engine_cs *ring, u32 request_id) +execlists_check_remove_request(struct intel_engine_cs *engine, u32 request_id) { struct drm_i915_gem_request *head_req; - assert_spin_locked(&ring->execlist_lock); + assert_spin_locked(&engine->execlist_lock); - head_req = list_first_entry_or_null(&ring->execlist_queue, + head_req = list_first_entry_or_null(&engine->execlist_queue, struct drm_i915_gem_request, execlist_link); if (!head_req) return 0; - if (unlikely(intel_execlists_ctx_id(head_req->ctx, ring) != request_id)) + if (unlikely(intel_execlists_ctx_id(head_req->ctx, engine) != request_id)) return 0; WARN(head_req->elsp_submitted == 0, "Never submitted head request\n"); @@ -514,26 +514,26 @@ execlists_check_remove_request(struct intel_engine_cs *ring, u32 request_id) return 0; list_move_tail(&head_req->execlist_link, - &ring->execlist_retired_req_list); + &engine->execlist_retired_req_list); return 1; } static u32 -get_context_status(struct intel_engine_cs *ring, unsigned int read_pointer, +get_context_status(struct intel_engine_cs *engine, unsigned int read_pointer, u32 *context_id) { - struct drm_i915_private *dev_priv = ring->dev->dev_private; + struct drm_i915_private *dev_priv = engine->dev->dev_private; u32 status; read_pointer %= GEN8_CSB_ENTRIES; - status = I915_READ_FW(RING_CONTEXT_STATUS_BUF_LO(ring, read_pointer)); + status = I915_READ_FW(RING_CONTEXT_STATUS_BUF_LO(engine, read_pointer)); if (status & GEN8_CTX_STATUS_IDLE_ACTIVE) return 0; - *context_id = I915_READ_FW(RING_CONTEXT_STATUS_BUF_HI(ring, + *context_id = I915_READ_FW(RING_CONTEXT_STATUS_BUF_HI(engine, read_pointer)); return status; @@ -546,33 +546,34 @@ get_context_status(struct intel_engine_cs *ring, unsigned int read_pointer, * Check the unread Context Status Buffers and manage the submission of new * contexts to the ELSP accordingly. */ -void intel_lrc_irq_handler(struct intel_engine_cs *ring) +void intel_lrc_irq_handler(struct intel_engine_cs *engine) { - struct drm_i915_private *dev_priv = ring->dev->dev_private; + struct drm_i915_private *dev_priv = engine->dev->dev_private; u32 status_pointer; unsigned int read_pointer, write_pointer; u32 status = 0; u32 status_id; unsigned int submit_contexts = 0; - spin_lock(&ring->execlist_lock); + spin_lock(&engine->execlist_lock); spin_lock(&dev_priv->uncore.lock); intel_uncore_forcewake_get__locked(dev_priv, FORCEWAKE_ALL); - status_pointer = I915_READ_FW(RING_CONTEXT_STATUS_PTR(ring)); + status_pointer = I915_READ_FW(RING_CONTEXT_STATUS_PTR(engine)); - read_pointer = ring->next_context_status_buffer; + read_pointer = engine->next_context_status_buffer; write_pointer = GEN8_CSB_WRITE_PTR(status_pointer); if (read_pointer > write_pointer) write_pointer += GEN8_CSB_ENTRIES; while (read_pointer < write_pointer) { - status = get_context_status(ring, ++read_pointer, &status_id); + status = get_context_status(engine, ++read_pointer, + &status_id); if (unlikely(status & GEN8_CTX_STATUS_PREEMPTED)) { if (status & GEN8_CTX_STATUS_LITE_RESTORE) { - if (execlists_check_remove_request(ring, status_id)) + if (execlists_check_remove_request(engine, status_id)) WARN(1, "Lite Restored request removed from queue\n"); } else WARN(1, "Preemption without Lite Restore\n"); @@ -581,27 +582,28 @@ void intel_lrc_irq_handler(struct intel_engine_cs *ring) if (status & (GEN8_CTX_STATUS_ACTIVE_IDLE | GEN8_CTX_STATUS_ELEMENT_SWITCH)) submit_contexts += - execlists_check_remove_request(ring, status_id); + execlists_check_remove_request(engine, + status_id); } if (submit_contexts) { - if (!ring->disable_lite_restore_wa || + if (!engine->disable_lite_restore_wa || (status & GEN8_CTX_STATUS_ACTIVE_IDLE)) - execlists_context_unqueue__locked(ring); + execlists_context_unqueue__locked(engine); } - ring->next_context_status_buffer = write_pointer % GEN8_CSB_ENTRIES; + engine->next_context_status_buffer = write_pointer % GEN8_CSB_ENTRIES; /* Update the read pointer to the old write pointer. Manual ringbuffer * management ftw */ - I915_WRITE_FW(RING_CONTEXT_STATUS_PTR(ring), + I915_WRITE_FW(RING_CONTEXT_STATUS_PTR(engine), _MASKED_FIELD(GEN8_CSB_READ_PTR_MASK, - ring->next_context_status_buffer << 8)); + engine->next_context_status_buffer << 8)); intel_uncore_forcewake_put__locked(dev_priv, FORCEWAKE_ALL); spin_unlock(&dev_priv->uncore.lock); - spin_unlock(&ring->execlist_lock); + spin_unlock(&engine->execlist_lock); if (unlikely(submit_contexts > 2)) DRM_ERROR("More than two context complete events?\n"); @@ -1020,53 +1022,53 @@ int intel_execlists_submission(struct i915_execbuffer_params *params, return 0; } -void intel_execlists_retire_requests(struct intel_engine_cs *ring) +void intel_execlists_retire_requests(struct intel_engine_cs *engine) { struct drm_i915_gem_request *req, *tmp; struct list_head retired_list; - WARN_ON(!mutex_is_locked(&ring->dev->struct_mutex)); - if (list_empty(&ring->execlist_retired_req_list)) + WARN_ON(!mutex_is_locked(&engine->dev->struct_mutex)); + if (list_empty(&engine->execlist_retired_req_list)) return; INIT_LIST_HEAD(&retired_list); - spin_lock_irq(&ring->execlist_lock); - list_replace_init(&ring->execlist_retired_req_list, &retired_list); - spin_unlock_irq(&ring->execlist_lock); + spin_lock_irq(&engine->execlist_lock); + list_replace_init(&engine->execlist_retired_req_list, &retired_list); + spin_unlock_irq(&engine->execlist_lock); list_for_each_entry_safe(req, tmp, &retired_list, execlist_link) { struct intel_context *ctx = req->ctx; struct drm_i915_gem_object *ctx_obj = - ctx->engine[ring->id].state; + ctx->engine[engine->id].state; if (ctx_obj && (ctx != req->i915->kernel_context)) - intel_lr_context_unpin(ctx, ring); + intel_lr_context_unpin(ctx, engine); list_del(&req->execlist_link); i915_gem_request_unreference(req); } } -void intel_logical_ring_stop(struct intel_engine_cs *ring) +void intel_logical_ring_stop(struct intel_engine_cs *engine) { - struct drm_i915_private *dev_priv = ring->dev->dev_private; + struct drm_i915_private *dev_priv = engine->dev->dev_private; int ret; - if (!intel_ring_initialized(ring)) + if (!intel_ring_initialized(engine)) return; - ret = intel_ring_idle(ring); - if (ret && !i915_reset_in_progress(&to_i915(ring->dev)->gpu_error)) + ret = intel_ring_idle(engine); + if (ret && !i915_reset_in_progress(&to_i915(engine->dev)->gpu_error)) DRM_ERROR("failed to quiesce %s whilst cleaning up: %d\n", - ring->name, ret); + engine->name, ret); /* TODO: Is this correct with Execlists enabled? */ - I915_WRITE_MODE(ring, _MASKED_BIT_ENABLE(STOP_RING)); - if (wait_for((I915_READ_MODE(ring) & MODE_IDLE) != 0, 1000)) { - DRM_ERROR("%s :timed out trying to stop ring\n", ring->name); + I915_WRITE_MODE(engine, _MASKED_BIT_ENABLE(STOP_RING)); + if (wait_for((I915_READ_MODE(engine) & MODE_IDLE) != 0, 1000)) { + DRM_ERROR("%s :timed out trying to stop ring\n", engine->name); return; } - I915_WRITE_MODE(ring, _MASKED_BIT_DISABLE(STOP_RING)); + I915_WRITE_MODE(engine, _MASKED_BIT_DISABLE(STOP_RING)); } int logical_ring_flush_all_caches(struct drm_i915_gem_request *req) @@ -1086,17 +1088,17 @@ int logical_ring_flush_all_caches(struct drm_i915_gem_request *req) } static int intel_lr_context_do_pin(struct intel_context *ctx, - struct intel_engine_cs *ring) + struct intel_engine_cs *engine) { - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_object *ctx_obj = ctx->engine[ring->id].state; - struct intel_ringbuffer *ringbuf = ctx->engine[ring->id].ringbuf; + struct drm_i915_gem_object *ctx_obj = ctx->engine[engine->id].state; + struct intel_ringbuffer *ringbuf = ctx->engine[engine->id].ringbuf; struct page *lrc_state_page; uint32_t *lrc_reg_state; int ret; - WARN_ON(!mutex_is_locked(&ring->dev->struct_mutex)); + WARN_ON(!mutex_is_locked(&engine->dev->struct_mutex)); ret = i915_gem_obj_ggtt_pin(ctx_obj, GEN8_LR_CONTEXT_ALIGN, PIN_OFFSET_BIAS | GUC_WOPCM_TOP); @@ -1109,15 +1111,15 @@ static int intel_lr_context_do_pin(struct intel_context *ctx, goto unpin_ctx_obj; } - ret = intel_pin_and_map_ringbuffer_obj(ring->dev, ringbuf); + ret = intel_pin_and_map_ringbuffer_obj(engine->dev, ringbuf); if (ret) goto unpin_ctx_obj; - ctx->engine[ring->id].lrc_vma = i915_gem_obj_to_ggtt(ctx_obj); - intel_lr_context_descriptor_update(ctx, ring); + ctx->engine[engine->id].lrc_vma = i915_gem_obj_to_ggtt(ctx_obj); + intel_lr_context_descriptor_update(ctx, engine); lrc_reg_state = kmap(lrc_state_page); lrc_reg_state[CTX_RING_BUFFER_START+1] = ringbuf->vma->node.start; - ctx->engine[ring->id].lrc_reg_state = lrc_reg_state; + ctx->engine[engine->id].lrc_reg_state = lrc_reg_state; ctx_obj->dirty = true; /* Invalidate GuC TLB. */ @@ -1235,7 +1237,7 @@ static int intel_logical_ring_workarounds_emit(struct drm_i915_gem_request *req) * This WA is also required for Gen9 so extracting as a function avoids * code duplication. */ -static inline int gen8_emit_flush_coherentl3_wa(struct intel_engine_cs *ring, +static inline int gen8_emit_flush_coherentl3_wa(struct intel_engine_cs *engine, uint32_t *const batch, uint32_t index) { @@ -1247,13 +1249,13 @@ static inline int gen8_emit_flush_coherentl3_wa(struct intel_engine_cs *ring, * this batch updates GEN8_L3SQCREG4 with default value we need to * set this bit here to retain the WA during flush. */ - if (IS_SKL_REVID(ring->dev, 0, SKL_REVID_E0)) + if (IS_SKL_REVID(engine->dev, 0, SKL_REVID_E0)) l3sqc4_flush |= GEN8_LQSC_RO_PERF_DIS; wa_ctx_emit(batch, index, (MI_STORE_REGISTER_MEM_GEN8 | MI_SRM_LRM_GLOBAL_GTT)); wa_ctx_emit_reg(batch, index, GEN8_L3SQCREG4); - wa_ctx_emit(batch, index, ring->scratch.gtt_offset + 256); + wa_ctx_emit(batch, index, engine->scratch.gtt_offset + 256); wa_ctx_emit(batch, index, 0); wa_ctx_emit(batch, index, MI_LOAD_REGISTER_IMM(1)); @@ -1271,7 +1273,7 @@ static inline int gen8_emit_flush_coherentl3_wa(struct intel_engine_cs *ring, wa_ctx_emit(batch, index, (MI_LOAD_REGISTER_MEM_GEN8 | MI_SRM_LRM_GLOBAL_GTT)); wa_ctx_emit_reg(batch, index, GEN8_L3SQCREG4); - wa_ctx_emit(batch, index, ring->scratch.gtt_offset + 256); + wa_ctx_emit(batch, index, engine->scratch.gtt_offset + 256); wa_ctx_emit(batch, index, 0); return index; @@ -1324,7 +1326,7 @@ static inline int wa_ctx_end(struct i915_wa_ctx_bb *wa_ctx, * Return: non-zero if we exceed the PAGE_SIZE limit. */ -static int gen8_init_indirectctx_bb(struct intel_engine_cs *ring, +static int gen8_init_indirectctx_bb(struct intel_engine_cs *engine, struct i915_wa_ctx_bb *wa_ctx, uint32_t *const batch, uint32_t *offset) @@ -1336,8 +1338,8 @@ static int gen8_init_indirectctx_bb(struct intel_engine_cs *ring, wa_ctx_emit(batch, index, MI_ARB_ON_OFF | MI_ARB_DISABLE); /* WaFlushCoherentL3CacheLinesAtContextSwitch:bdw */ - if (IS_BROADWELL(ring->dev)) { - int rc = gen8_emit_flush_coherentl3_wa(ring, batch, index); + if (IS_BROADWELL(engine->dev)) { + int rc = gen8_emit_flush_coherentl3_wa(engine, batch, index); if (rc < 0) return rc; index = rc; @@ -1345,7 +1347,7 @@ static int gen8_init_indirectctx_bb(struct intel_engine_cs *ring, /* WaClearSlmSpaceAtContextSwitch:bdw,chv */ /* Actual scratch location is at 128 bytes offset */ - scratch_addr = ring->scratch.gtt_offset + 2*CACHELINE_BYTES; + scratch_addr = engine->scratch.gtt_offset + 2*CACHELINE_BYTES; wa_ctx_emit(batch, index, GFX_OP_PIPE_CONTROL(6)); wa_ctx_emit(batch, index, (PIPE_CONTROL_FLUSH_L3 | @@ -1387,7 +1389,7 @@ static int gen8_init_indirectctx_bb(struct intel_engine_cs *ring, * This batch is terminated with MI_BATCH_BUFFER_END and so we need not add padding * to align it with cacheline as padding after MI_BATCH_BUFFER_END is redundant. */ -static int gen8_init_perctx_bb(struct intel_engine_cs *ring, +static int gen8_init_perctx_bb(struct intel_engine_cs *engine, struct i915_wa_ctx_bb *wa_ctx, uint32_t *const batch, uint32_t *offset) @@ -1402,13 +1404,13 @@ static int gen8_init_perctx_bb(struct intel_engine_cs *ring, return wa_ctx_end(wa_ctx, *offset = index, 1); } -static int gen9_init_indirectctx_bb(struct intel_engine_cs *ring, +static int gen9_init_indirectctx_bb(struct intel_engine_cs *engine, struct i915_wa_ctx_bb *wa_ctx, uint32_t *const batch, uint32_t *offset) { int ret; - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; uint32_t index = wa_ctx_start(wa_ctx, *offset, CACHELINE_DWORDS); /* WaDisableCtxRestoreArbitration:skl,bxt */ @@ -1417,7 +1419,7 @@ static int gen9_init_indirectctx_bb(struct intel_engine_cs *ring, wa_ctx_emit(batch, index, MI_ARB_ON_OFF | MI_ARB_DISABLE); /* WaFlushCoherentL3CacheLinesAtContextSwitch:skl,bxt */ - ret = gen8_emit_flush_coherentl3_wa(ring, batch, index); + ret = gen8_emit_flush_coherentl3_wa(engine, batch, index); if (ret < 0) return ret; index = ret; @@ -1429,12 +1431,12 @@ static int gen9_init_indirectctx_bb(struct intel_engine_cs *ring, return wa_ctx_end(wa_ctx, *offset = index, CACHELINE_DWORDS); } -static int gen9_init_perctx_bb(struct intel_engine_cs *ring, +static int gen9_init_perctx_bb(struct intel_engine_cs *engine, struct i915_wa_ctx_bb *wa_ctx, uint32_t *const batch, uint32_t *offset) { - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; uint32_t index = wa_ctx_start(wa_ctx, *offset, CACHELINE_DWORDS); /* WaSetDisablePixMaskCammingAndRhwoInCommonSliceChicken:skl,bxt */ @@ -1457,60 +1459,61 @@ static int gen9_init_perctx_bb(struct intel_engine_cs *ring, return wa_ctx_end(wa_ctx, *offset = index, 1); } -static int lrc_setup_wa_ctx_obj(struct intel_engine_cs *ring, u32 size) +static int lrc_setup_wa_ctx_obj(struct intel_engine_cs *engine, u32 size) { int ret; - ring->wa_ctx.obj = i915_gem_alloc_object(ring->dev, PAGE_ALIGN(size)); - if (!ring->wa_ctx.obj) { + engine->wa_ctx.obj = i915_gem_alloc_object(engine->dev, + PAGE_ALIGN(size)); + if (!engine->wa_ctx.obj) { DRM_DEBUG_DRIVER("alloc LRC WA ctx backing obj failed.\n"); return -ENOMEM; } - ret = i915_gem_obj_ggtt_pin(ring->wa_ctx.obj, PAGE_SIZE, 0); + ret = i915_gem_obj_ggtt_pin(engine->wa_ctx.obj, PAGE_SIZE, 0); if (ret) { DRM_DEBUG_DRIVER("pin LRC WA ctx backing obj failed: %d\n", ret); - drm_gem_object_unreference(&ring->wa_ctx.obj->base); + drm_gem_object_unreference(&engine->wa_ctx.obj->base); return ret; } return 0; } -static void lrc_destroy_wa_ctx_obj(struct intel_engine_cs *ring) +static void lrc_destroy_wa_ctx_obj(struct intel_engine_cs *engine) { - if (ring->wa_ctx.obj) { - i915_gem_object_ggtt_unpin(ring->wa_ctx.obj); - drm_gem_object_unreference(&ring->wa_ctx.obj->base); - ring->wa_ctx.obj = NULL; + if (engine->wa_ctx.obj) { + i915_gem_object_ggtt_unpin(engine->wa_ctx.obj); + drm_gem_object_unreference(&engine->wa_ctx.obj->base); + engine->wa_ctx.obj = NULL; } } -static int intel_init_workaround_bb(struct intel_engine_cs *ring) +static int intel_init_workaround_bb(struct intel_engine_cs *engine) { int ret; uint32_t *batch; uint32_t offset; struct page *page; - struct i915_ctx_workarounds *wa_ctx = &ring->wa_ctx; + struct i915_ctx_workarounds *wa_ctx = &engine->wa_ctx; - WARN_ON(ring->id != RCS); + WARN_ON(engine->id != RCS); /* update this when WA for higher Gen are added */ - if (INTEL_INFO(ring->dev)->gen > 9) { + if (INTEL_INFO(engine->dev)->gen > 9) { DRM_ERROR("WA batch buffer is not initialized for Gen%d\n", - INTEL_INFO(ring->dev)->gen); + INTEL_INFO(engine->dev)->gen); return 0; } /* some WA perform writes to scratch page, ensure it is valid */ - if (ring->scratch.obj == NULL) { - DRM_ERROR("scratch page not allocated for %s\n", ring->name); + if (engine->scratch.obj == NULL) { + DRM_ERROR("scratch page not allocated for %s\n", engine->name); return -EINVAL; } - ret = lrc_setup_wa_ctx_obj(ring, PAGE_SIZE); + ret = lrc_setup_wa_ctx_obj(engine, PAGE_SIZE); if (ret) { DRM_DEBUG_DRIVER("Failed to setup context WA page: %d\n", ret); return ret; @@ -1520,29 +1523,29 @@ static int intel_init_workaround_bb(struct intel_engine_cs *ring) batch = kmap_atomic(page); offset = 0; - if (INTEL_INFO(ring->dev)->gen == 8) { - ret = gen8_init_indirectctx_bb(ring, + if (INTEL_INFO(engine->dev)->gen == 8) { + ret = gen8_init_indirectctx_bb(engine, &wa_ctx->indirect_ctx, batch, &offset); if (ret) goto out; - ret = gen8_init_perctx_bb(ring, + ret = gen8_init_perctx_bb(engine, &wa_ctx->per_ctx, batch, &offset); if (ret) goto out; - } else if (INTEL_INFO(ring->dev)->gen == 9) { - ret = gen9_init_indirectctx_bb(ring, + } else if (INTEL_INFO(engine->dev)->gen == 9) { + ret = gen9_init_indirectctx_bb(engine, &wa_ctx->indirect_ctx, batch, &offset); if (ret) goto out; - ret = gen9_init_perctx_bb(ring, + ret = gen9_init_perctx_bb(engine, &wa_ctx->per_ctx, batch, &offset); @@ -1553,27 +1556,28 @@ static int intel_init_workaround_bb(struct intel_engine_cs *ring) out: kunmap_atomic(batch); if (ret) - lrc_destroy_wa_ctx_obj(ring); + lrc_destroy_wa_ctx_obj(engine); return ret; } -static int gen8_init_common_ring(struct intel_engine_cs *ring) +static int gen8_init_common_ring(struct intel_engine_cs *engine) { - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; unsigned int next_context_status_buffer_hw; - lrc_setup_hardware_status_page(ring, - dev_priv->kernel_context->engine[ring->id].state); + lrc_setup_hardware_status_page(engine, + dev_priv->kernel_context->engine[engine->id].state); - I915_WRITE_IMR(ring, ~(ring->irq_enable_mask | ring->irq_keep_mask)); - I915_WRITE(RING_HWSTAM(ring->mmio_base), 0xffffffff); + I915_WRITE_IMR(engine, + ~(engine->irq_enable_mask | engine->irq_keep_mask)); + I915_WRITE(RING_HWSTAM(engine->mmio_base), 0xffffffff); - I915_WRITE(RING_MODE_GEN7(ring), + I915_WRITE(RING_MODE_GEN7(engine), _MASKED_BIT_DISABLE(GFX_REPLAY_MODE) | _MASKED_BIT_ENABLE(GFX_RUN_LIST_ENABLE)); - POSTING_READ(RING_MODE_GEN7(ring)); + POSTING_READ(RING_MODE_GEN7(engine)); /* * Instead of resetting the Context Status Buffer (CSB) read pointer to @@ -1588,7 +1592,7 @@ static int gen8_init_common_ring(struct intel_engine_cs *ring) * BXT | ? | ? | */ next_context_status_buffer_hw = - GEN8_CSB_WRITE_PTR(I915_READ(RING_CONTEXT_STATUS_PTR(ring))); + GEN8_CSB_WRITE_PTR(I915_READ(RING_CONTEXT_STATUS_PTR(engine))); /* * When the CSB registers are reset (also after power-up / gpu reset), @@ -1598,21 +1602,21 @@ static int gen8_init_common_ring(struct intel_engine_cs *ring) if (next_context_status_buffer_hw == GEN8_CSB_PTR_MASK) next_context_status_buffer_hw = (GEN8_CSB_ENTRIES - 1); - ring->next_context_status_buffer = next_context_status_buffer_hw; - DRM_DEBUG_DRIVER("Execlists enabled for %s\n", ring->name); + engine->next_context_status_buffer = next_context_status_buffer_hw; + DRM_DEBUG_DRIVER("Execlists enabled for %s\n", engine->name); - memset(&ring->hangcheck, 0, sizeof(ring->hangcheck)); + memset(&engine->hangcheck, 0, sizeof(engine->hangcheck)); return 0; } -static int gen8_init_render_ring(struct intel_engine_cs *ring) +static int gen8_init_render_ring(struct intel_engine_cs *engine) { - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; int ret; - ret = gen8_init_common_ring(ring); + ret = gen8_init_common_ring(engine); if (ret) return ret; @@ -1626,18 +1630,18 @@ static int gen8_init_render_ring(struct intel_engine_cs *ring) I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_FORCE_ORDERING)); - return init_workarounds_ring(ring); + return init_workarounds_ring(engine); } -static int gen9_init_render_ring(struct intel_engine_cs *ring) +static int gen9_init_render_ring(struct intel_engine_cs *engine) { int ret; - ret = gen8_init_common_ring(ring); + ret = gen8_init_common_ring(engine); if (ret) return ret; - return init_workarounds_ring(ring); + return init_workarounds_ring(engine); } static int intel_logical_ring_emit_pdps(struct drm_i915_gem_request *req) @@ -1712,9 +1716,9 @@ static int gen8_emit_bb_start(struct drm_i915_gem_request *req, return 0; } -static bool gen8_logical_ring_get_irq(struct intel_engine_cs *ring) +static bool gen8_logical_ring_get_irq(struct intel_engine_cs *engine) { - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; unsigned long flags; @@ -1722,25 +1726,26 @@ static bool gen8_logical_ring_get_irq(struct intel_engine_cs *ring) return false; spin_lock_irqsave(&dev_priv->irq_lock, flags); - if (ring->irq_refcount++ == 0) { - I915_WRITE_IMR(ring, ~(ring->irq_enable_mask | ring->irq_keep_mask)); - POSTING_READ(RING_IMR(ring->mmio_base)); + if (engine->irq_refcount++ == 0) { + I915_WRITE_IMR(engine, + ~(engine->irq_enable_mask | engine->irq_keep_mask)); + POSTING_READ(RING_IMR(engine->mmio_base)); } spin_unlock_irqrestore(&dev_priv->irq_lock, flags); return true; } -static void gen8_logical_ring_put_irq(struct intel_engine_cs *ring) +static void gen8_logical_ring_put_irq(struct intel_engine_cs *engine) { - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; unsigned long flags; spin_lock_irqsave(&dev_priv->irq_lock, flags); - if (--ring->irq_refcount == 0) { - I915_WRITE_IMR(ring, ~ring->irq_keep_mask); - POSTING_READ(RING_IMR(ring->mmio_base)); + if (--engine->irq_refcount == 0) { + I915_WRITE_IMR(engine, ~engine->irq_keep_mask); + POSTING_READ(RING_IMR(engine->mmio_base)); } spin_unlock_irqrestore(&dev_priv->irq_lock, flags); } @@ -1848,17 +1853,18 @@ static int gen8_emit_flush_render(struct drm_i915_gem_request *request, return 0; } -static u32 gen8_get_seqno(struct intel_engine_cs *ring, bool lazy_coherency) +static u32 gen8_get_seqno(struct intel_engine_cs *engine, bool lazy_coherency) { - return intel_read_status_page(ring, I915_GEM_HWS_INDEX); + return intel_read_status_page(engine, I915_GEM_HWS_INDEX); } -static void gen8_set_seqno(struct intel_engine_cs *ring, u32 seqno) +static void gen8_set_seqno(struct intel_engine_cs *engine, u32 seqno) { - intel_write_status_page(ring, I915_GEM_HWS_INDEX, seqno); + intel_write_status_page(engine, I915_GEM_HWS_INDEX, seqno); } -static u32 bxt_a_get_seqno(struct intel_engine_cs *ring, bool lazy_coherency) +static u32 bxt_a_get_seqno(struct intel_engine_cs *engine, + bool lazy_coherency) { /* @@ -1873,17 +1879,17 @@ static u32 bxt_a_get_seqno(struct intel_engine_cs *ring, bool lazy_coherency) */ if (!lazy_coherency) - intel_flush_status_page(ring, I915_GEM_HWS_INDEX); + intel_flush_status_page(engine, I915_GEM_HWS_INDEX); - return intel_read_status_page(ring, I915_GEM_HWS_INDEX); + return intel_read_status_page(engine, I915_GEM_HWS_INDEX); } -static void bxt_a_set_seqno(struct intel_engine_cs *ring, u32 seqno) +static void bxt_a_set_seqno(struct intel_engine_cs *engine, u32 seqno) { - intel_write_status_page(ring, I915_GEM_HWS_INDEX, seqno); + intel_write_status_page(engine, I915_GEM_HWS_INDEX, seqno); /* See bxt_a_get_seqno() explaining the reason for the clflush. */ - intel_flush_status_page(ring, I915_GEM_HWS_INDEX); + intel_flush_status_page(engine, I915_GEM_HWS_INDEX); } /* @@ -2002,109 +2008,109 @@ static int gen8_init_rcs_context(struct drm_i915_gem_request *req) * @ring: Engine Command Streamer. * */ -void intel_logical_ring_cleanup(struct intel_engine_cs *ring) +void intel_logical_ring_cleanup(struct intel_engine_cs *engine) { struct drm_i915_private *dev_priv; - if (!intel_ring_initialized(ring)) + if (!intel_ring_initialized(engine)) return; - dev_priv = ring->dev->dev_private; + dev_priv = engine->dev->dev_private; - if (ring->buffer) { - intel_logical_ring_stop(ring); - WARN_ON((I915_READ_MODE(ring) & MODE_IDLE) == 0); + if (engine->buffer) { + intel_logical_ring_stop(engine); + WARN_ON((I915_READ_MODE(engine) & MODE_IDLE) == 0); } - if (ring->cleanup) - ring->cleanup(ring); + if (engine->cleanup) + engine->cleanup(engine); - i915_cmd_parser_fini_ring(ring); - i915_gem_batch_pool_fini(&ring->batch_pool); + i915_cmd_parser_fini_ring(engine); + i915_gem_batch_pool_fini(&engine->batch_pool); - if (ring->status_page.obj) { - kunmap(sg_page(ring->status_page.obj->pages->sgl)); - ring->status_page.obj = NULL; + if (engine->status_page.obj) { + kunmap(sg_page(engine->status_page.obj->pages->sgl)); + engine->status_page.obj = NULL; } - ring->idle_lite_restore_wa = 0; - ring->disable_lite_restore_wa = false; - ring->ctx_desc_template = 0; + engine->idle_lite_restore_wa = 0; + engine->disable_lite_restore_wa = false; + engine->ctx_desc_template = 0; - lrc_destroy_wa_ctx_obj(ring); - ring->dev = NULL; + lrc_destroy_wa_ctx_obj(engine); + engine->dev = NULL; } static void logical_ring_default_vfuncs(struct drm_device *dev, - struct intel_engine_cs *ring) + struct intel_engine_cs *engine) { /* Default vfuncs which can be overriden by each engine. */ - ring->init_hw = gen8_init_common_ring; - ring->emit_request = gen8_emit_request; - ring->emit_flush = gen8_emit_flush; - ring->irq_get = gen8_logical_ring_get_irq; - ring->irq_put = gen8_logical_ring_put_irq; - ring->emit_bb_start = gen8_emit_bb_start; + engine->init_hw = gen8_init_common_ring; + engine->emit_request = gen8_emit_request; + engine->emit_flush = gen8_emit_flush; + engine->irq_get = gen8_logical_ring_get_irq; + engine->irq_put = gen8_logical_ring_put_irq; + engine->emit_bb_start = gen8_emit_bb_start; if (IS_BXT_REVID(dev, 0, BXT_REVID_A1)) { - ring->get_seqno = bxt_a_get_seqno; - ring->set_seqno = bxt_a_set_seqno; + engine->get_seqno = bxt_a_get_seqno; + engine->set_seqno = bxt_a_set_seqno; } else { - ring->get_seqno = gen8_get_seqno; - ring->set_seqno = gen8_set_seqno; + engine->get_seqno = gen8_get_seqno; + engine->set_seqno = gen8_set_seqno; } } static inline void -logical_ring_default_irqs(struct intel_engine_cs *ring, unsigned shift) +logical_ring_default_irqs(struct intel_engine_cs *engine, unsigned shift) { - ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT << shift; - ring->irq_keep_mask = GT_CONTEXT_SWITCH_INTERRUPT << shift; + engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT << shift; + engine->irq_keep_mask = GT_CONTEXT_SWITCH_INTERRUPT << shift; } static int -logical_ring_init(struct drm_device *dev, struct intel_engine_cs *ring) +logical_ring_init(struct drm_device *dev, struct intel_engine_cs *engine) { struct intel_context *dctx = to_i915(dev)->kernel_context; int ret; /* Intentionally left blank. */ - ring->buffer = NULL; + engine->buffer = NULL; - ring->dev = dev; - INIT_LIST_HEAD(&ring->active_list); - INIT_LIST_HEAD(&ring->request_list); - i915_gem_batch_pool_init(dev, &ring->batch_pool); - init_waitqueue_head(&ring->irq_queue); + engine->dev = dev; + INIT_LIST_HEAD(&engine->active_list); + INIT_LIST_HEAD(&engine->request_list); + i915_gem_batch_pool_init(dev, &engine->batch_pool); + init_waitqueue_head(&engine->irq_queue); - INIT_LIST_HEAD(&ring->buffers); - INIT_LIST_HEAD(&ring->execlist_queue); - INIT_LIST_HEAD(&ring->execlist_retired_req_list); - spin_lock_init(&ring->execlist_lock); + INIT_LIST_HEAD(&engine->buffers); + INIT_LIST_HEAD(&engine->execlist_queue); + INIT_LIST_HEAD(&engine->execlist_retired_req_list); + spin_lock_init(&engine->execlist_lock); - logical_ring_init_platform_invariants(ring); + logical_ring_init_platform_invariants(engine); - ret = i915_cmd_parser_init_ring(ring); + ret = i915_cmd_parser_init_ring(engine); if (ret) goto error; - ret = intel_lr_context_deferred_alloc(dctx, ring); + ret = intel_lr_context_deferred_alloc(dctx, engine); if (ret) goto error; /* As this is the default context, always pin it */ - ret = intel_lr_context_do_pin(dctx, ring); + ret = intel_lr_context_do_pin(dctx, engine); if (ret) { DRM_ERROR( "Failed to pin and map ringbuffer %s: %d\n", - ring->name, ret); + engine->name, ret); goto error; } return 0; error: - intel_logical_ring_cleanup(ring); + intel_logical_ring_cleanup(engine); return ret; } @@ -2329,13 +2335,13 @@ make_rpcs(struct drm_device *dev) return rpcs; } -static u32 intel_lr_indirect_ctx_offset(struct intel_engine_cs *ring) +static u32 intel_lr_indirect_ctx_offset(struct intel_engine_cs *engine) { u32 indirect_ctx_offset; - switch (INTEL_INFO(ring->dev)->gen) { + switch (INTEL_INFO(engine->dev)->gen) { default: - MISSING_CASE(INTEL_INFO(ring->dev)->gen); + MISSING_CASE(INTEL_INFO(engine->dev)->gen); /* fall through */ case 9: indirect_ctx_offset = @@ -2352,9 +2358,10 @@ static u32 intel_lr_indirect_ctx_offset(struct intel_engine_cs *ring) static int populate_lr_context(struct intel_context *ctx, struct drm_i915_gem_object *ctx_obj, - struct intel_engine_cs *ring, struct intel_ringbuffer *ringbuf) + struct intel_engine_cs *engine, + struct intel_ringbuffer *ringbuf) { - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct i915_hw_ppgtt *ppgtt = ctx->ppgtt; struct page *page; @@ -2389,33 +2396,47 @@ populate_lr_context(struct intel_context *ctx, struct drm_i915_gem_object *ctx_o * recreate this batchbuffer with new values (including all the missing * MI_LOAD_REGISTER_IMM commands that we are not initializing here). */ reg_state[CTX_LRI_HEADER_0] = - MI_LOAD_REGISTER_IMM(ring->id == RCS ? 14 : 11) | MI_LRI_FORCE_POSTED; - ASSIGN_CTX_REG(reg_state, CTX_CONTEXT_CONTROL, RING_CONTEXT_CONTROL(ring), + MI_LOAD_REGISTER_IMM(engine->id == RCS ? 14 : 11) | MI_LRI_FORCE_POSTED; + ASSIGN_CTX_REG(reg_state, CTX_CONTEXT_CONTROL, + RING_CONTEXT_CONTROL(engine), _MASKED_BIT_ENABLE(CTX_CTRL_INHIBIT_SYN_CTX_SWITCH | CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT | (HAS_RESOURCE_STREAMER(dev) ? CTX_CTRL_RS_CTX_ENABLE : 0))); - ASSIGN_CTX_REG(reg_state, CTX_RING_HEAD, RING_HEAD(ring->mmio_base), 0); - ASSIGN_CTX_REG(reg_state, CTX_RING_TAIL, RING_TAIL(ring->mmio_base), 0); + ASSIGN_CTX_REG(reg_state, CTX_RING_HEAD, RING_HEAD(engine->mmio_base), + 0); + ASSIGN_CTX_REG(reg_state, CTX_RING_TAIL, RING_TAIL(engine->mmio_base), + 0); /* Ring buffer start address is not known until the buffer is pinned. * It is written to the context image in execlists_update_context() */ - ASSIGN_CTX_REG(reg_state, CTX_RING_BUFFER_START, RING_START(ring->mmio_base), 0); - ASSIGN_CTX_REG(reg_state, CTX_RING_BUFFER_CONTROL, RING_CTL(ring->mmio_base), + ASSIGN_CTX_REG(reg_state, CTX_RING_BUFFER_START, + RING_START(engine->mmio_base), 0); + ASSIGN_CTX_REG(reg_state, CTX_RING_BUFFER_CONTROL, + RING_CTL(engine->mmio_base), ((ringbuf->size - PAGE_SIZE) & RING_NR_PAGES) | RING_VALID); - ASSIGN_CTX_REG(reg_state, CTX_BB_HEAD_U, RING_BBADDR_UDW(ring->mmio_base), 0); - ASSIGN_CTX_REG(reg_state, CTX_BB_HEAD_L, RING_BBADDR(ring->mmio_base), 0); - ASSIGN_CTX_REG(reg_state, CTX_BB_STATE, RING_BBSTATE(ring->mmio_base), + ASSIGN_CTX_REG(reg_state, CTX_BB_HEAD_U, + RING_BBADDR_UDW(engine->mmio_base), 0); + ASSIGN_CTX_REG(reg_state, CTX_BB_HEAD_L, + RING_BBADDR(engine->mmio_base), 0); + ASSIGN_CTX_REG(reg_state, CTX_BB_STATE, + RING_BBSTATE(engine->mmio_base), RING_BB_PPGTT); - ASSIGN_CTX_REG(reg_state, CTX_SECOND_BB_HEAD_U, RING_SBBADDR_UDW(ring->mmio_base), 0); - ASSIGN_CTX_REG(reg_state, CTX_SECOND_BB_HEAD_L, RING_SBBADDR(ring->mmio_base), 0); - ASSIGN_CTX_REG(reg_state, CTX_SECOND_BB_STATE, RING_SBBSTATE(ring->mmio_base), 0); - if (ring->id == RCS) { - ASSIGN_CTX_REG(reg_state, CTX_BB_PER_CTX_PTR, RING_BB_PER_CTX_PTR(ring->mmio_base), 0); - ASSIGN_CTX_REG(reg_state, CTX_RCS_INDIRECT_CTX, RING_INDIRECT_CTX(ring->mmio_base), 0); - ASSIGN_CTX_REG(reg_state, CTX_RCS_INDIRECT_CTX_OFFSET, RING_INDIRECT_CTX_OFFSET(ring->mmio_base), 0); - if (ring->wa_ctx.obj) { - struct i915_ctx_workarounds *wa_ctx = &ring->wa_ctx; + ASSIGN_CTX_REG(reg_state, CTX_SECOND_BB_HEAD_U, + RING_SBBADDR_UDW(engine->mmio_base), 0); + ASSIGN_CTX_REG(reg_state, CTX_SECOND_BB_HEAD_L, + RING_SBBADDR(engine->mmio_base), 0); + ASSIGN_CTX_REG(reg_state, CTX_SECOND_BB_STATE, + RING_SBBSTATE(engine->mmio_base), 0); + if (engine->id == RCS) { + ASSIGN_CTX_REG(reg_state, CTX_BB_PER_CTX_PTR, + RING_BB_PER_CTX_PTR(engine->mmio_base), 0); + ASSIGN_CTX_REG(reg_state, CTX_RCS_INDIRECT_CTX, + RING_INDIRECT_CTX(engine->mmio_base), 0); + ASSIGN_CTX_REG(reg_state, CTX_RCS_INDIRECT_CTX_OFFSET, + RING_INDIRECT_CTX_OFFSET(engine->mmio_base), 0); + if (engine->wa_ctx.obj) { + struct i915_ctx_workarounds *wa_ctx = &engine->wa_ctx; uint32_t ggtt_offset = i915_gem_obj_ggtt_offset(wa_ctx->obj); reg_state[CTX_RCS_INDIRECT_CTX+1] = @@ -2423,7 +2444,7 @@ populate_lr_context(struct intel_context *ctx, struct drm_i915_gem_object *ctx_o (wa_ctx->indirect_ctx.size / CACHELINE_DWORDS); reg_state[CTX_RCS_INDIRECT_CTX_OFFSET+1] = - intel_lr_indirect_ctx_offset(ring) << 6; + intel_lr_indirect_ctx_offset(engine) << 6; reg_state[CTX_BB_PER_CTX_PTR+1] = (ggtt_offset + wa_ctx->per_ctx.offset * sizeof(uint32_t)) | @@ -2431,16 +2452,25 @@ populate_lr_context(struct intel_context *ctx, struct drm_i915_gem_object *ctx_o } } reg_state[CTX_LRI_HEADER_1] = MI_LOAD_REGISTER_IMM(9) | MI_LRI_FORCE_POSTED; - ASSIGN_CTX_REG(reg_state, CTX_CTX_TIMESTAMP, RING_CTX_TIMESTAMP(ring->mmio_base), 0); + ASSIGN_CTX_REG(reg_state, CTX_CTX_TIMESTAMP, + RING_CTX_TIMESTAMP(engine->mmio_base), 0); /* PDP values well be assigned later if needed */ - ASSIGN_CTX_REG(reg_state, CTX_PDP3_UDW, GEN8_RING_PDP_UDW(ring, 3), 0); - ASSIGN_CTX_REG(reg_state, CTX_PDP3_LDW, GEN8_RING_PDP_LDW(ring, 3), 0); - ASSIGN_CTX_REG(reg_state, CTX_PDP2_UDW, GEN8_RING_PDP_UDW(ring, 2), 0); - ASSIGN_CTX_REG(reg_state, CTX_PDP2_LDW, GEN8_RING_PDP_LDW(ring, 2), 0); - ASSIGN_CTX_REG(reg_state, CTX_PDP1_UDW, GEN8_RING_PDP_UDW(ring, 1), 0); - ASSIGN_CTX_REG(reg_state, CTX_PDP1_LDW, GEN8_RING_PDP_LDW(ring, 1), 0); - ASSIGN_CTX_REG(reg_state, CTX_PDP0_UDW, GEN8_RING_PDP_UDW(ring, 0), 0); - ASSIGN_CTX_REG(reg_state, CTX_PDP0_LDW, GEN8_RING_PDP_LDW(ring, 0), 0); + ASSIGN_CTX_REG(reg_state, CTX_PDP3_UDW, GEN8_RING_PDP_UDW(engine, 3), + 0); + ASSIGN_CTX_REG(reg_state, CTX_PDP3_LDW, GEN8_RING_PDP_LDW(engine, 3), + 0); + ASSIGN_CTX_REG(reg_state, CTX_PDP2_UDW, GEN8_RING_PDP_UDW(engine, 2), + 0); + ASSIGN_CTX_REG(reg_state, CTX_PDP2_LDW, GEN8_RING_PDP_LDW(engine, 2), + 0); + ASSIGN_CTX_REG(reg_state, CTX_PDP1_UDW, GEN8_RING_PDP_UDW(engine, 1), + 0); + ASSIGN_CTX_REG(reg_state, CTX_PDP1_LDW, GEN8_RING_PDP_LDW(engine, 1), + 0); + ASSIGN_CTX_REG(reg_state, CTX_PDP0_UDW, GEN8_RING_PDP_UDW(engine, 0), + 0); + ASSIGN_CTX_REG(reg_state, CTX_PDP0_LDW, GEN8_RING_PDP_LDW(engine, 0), + 0); if (USES_FULL_48BIT_PPGTT(ppgtt->base.dev)) { /* 64b PPGTT (48bit canonical) @@ -2457,7 +2487,7 @@ populate_lr_context(struct intel_context *ctx, struct drm_i915_gem_object *ctx_o execlists_update_context_pdps(ppgtt, reg_state); } - if (ring->id == RCS) { + if (engine->id == RCS) { reg_state[CTX_LRI_HEADER_2] = MI_LOAD_REGISTER_IMM(1); ASSIGN_CTX_REG(reg_state, CTX_R_PWR_CLK_STATE, GEN8_R_PWR_CLK_STATE, make_rpcs(dev)); @@ -2513,15 +2543,15 @@ void intel_lr_context_free(struct intel_context *ctx) * in LRC mode, but does not include the "shared data page" used with * GuC submission. The caller should account for this if using the GuC. */ -uint32_t intel_lr_context_size(struct intel_engine_cs *ring) +uint32_t intel_lr_context_size(struct intel_engine_cs *engine) { int ret = 0; - WARN_ON(INTEL_INFO(ring->dev)->gen < 8); + WARN_ON(INTEL_INFO(engine->dev)->gen < 8); - switch (ring->id) { + switch (engine->id) { case RCS: - if (INTEL_INFO(ring->dev)->gen >= 9) + if (INTEL_INFO(engine->dev)->gen >= 9) ret = GEN9_LR_CONTEXT_RENDER_SIZE; else ret = GEN8_LR_CONTEXT_RENDER_SIZE; @@ -2537,22 +2567,22 @@ uint32_t intel_lr_context_size(struct intel_engine_cs *ring) return ret; } -static void lrc_setup_hardware_status_page(struct intel_engine_cs *ring, - struct drm_i915_gem_object *default_ctx_obj) +static void lrc_setup_hardware_status_page(struct intel_engine_cs *engine, + struct drm_i915_gem_object *default_ctx_obj) { - struct drm_i915_private *dev_priv = ring->dev->dev_private; + struct drm_i915_private *dev_priv = engine->dev->dev_private; struct page *page; /* The HWSP is part of the default context object in LRC mode. */ - ring->status_page.gfx_addr = i915_gem_obj_ggtt_offset(default_ctx_obj) + engine->status_page.gfx_addr = i915_gem_obj_ggtt_offset(default_ctx_obj) + LRC_PPHWSP_PN * PAGE_SIZE; page = i915_gem_object_get_page(default_ctx_obj, LRC_PPHWSP_PN); - ring->status_page.page_addr = kmap(page); - ring->status_page.obj = default_ctx_obj; + engine->status_page.page_addr = kmap(page); + engine->status_page.obj = default_ctx_obj; - I915_WRITE(RING_HWS_PGA(ring->mmio_base), - (u32)ring->status_page.gfx_addr); - POSTING_READ(RING_HWS_PGA(ring->mmio_base)); + I915_WRITE(RING_HWS_PGA(engine->mmio_base), + (u32)engine->status_page.gfx_addr); + POSTING_READ(RING_HWS_PGA(engine->mmio_base)); } /** @@ -2570,18 +2600,18 @@ static void lrc_setup_hardware_status_page(struct intel_engine_cs *ring, */ int intel_lr_context_deferred_alloc(struct intel_context *ctx, - struct intel_engine_cs *ring) + struct intel_engine_cs *engine) { - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_gem_object *ctx_obj; uint32_t context_size; struct intel_ringbuffer *ringbuf; int ret; WARN_ON(ctx->legacy_hw_ctx.rcs_state != NULL); - WARN_ON(ctx->engine[ring->id].state); + WARN_ON(ctx->engine[engine->id].state); - context_size = round_up(intel_lr_context_size(ring), 4096); + context_size = round_up(intel_lr_context_size(engine), 4096); /* One extra page as the sharing data between driver and GuC */ context_size += PAGE_SIZE * LRC_PPHWSP_PN; @@ -2592,32 +2622,32 @@ int intel_lr_context_deferred_alloc(struct intel_context *ctx, return -ENOMEM; } - ringbuf = intel_engine_create_ringbuffer(ring, 4 * PAGE_SIZE); + ringbuf = intel_engine_create_ringbuffer(engine, 4 * PAGE_SIZE); if (IS_ERR(ringbuf)) { ret = PTR_ERR(ringbuf); goto error_deref_obj; } - ret = populate_lr_context(ctx, ctx_obj, ring, ringbuf); + ret = populate_lr_context(ctx, ctx_obj, engine, ringbuf); if (ret) { DRM_DEBUG_DRIVER("Failed to populate LRC: %d\n", ret); goto error_ringbuf; } - ctx->engine[ring->id].ringbuf = ringbuf; - ctx->engine[ring->id].state = ctx_obj; + ctx->engine[engine->id].ringbuf = ringbuf; + ctx->engine[engine->id].state = ctx_obj; - if (ctx != ctx->i915->kernel_context && ring->init_context) { + if (ctx != ctx->i915->kernel_context && engine->init_context) { struct drm_i915_gem_request *req; - req = i915_gem_request_alloc(ring, ctx); + req = i915_gem_request_alloc(engine, ctx); if (IS_ERR(req)) { ret = PTR_ERR(req); DRM_ERROR("ring create req: %d\n", ret); goto error_ringbuf; } - ret = ring->init_context(req); + ret = engine->init_context(req); if (ret) { DRM_ERROR("ring init context: %d\n", ret); @@ -2632,8 +2662,8 @@ error_ringbuf: intel_ringbuffer_free(ringbuf); error_deref_obj: drm_gem_object_unreference(&ctx_obj->base); - ctx->engine[ring->id].ringbuf = NULL; - ctx->engine[ring->id].state = NULL; + ctx->engine[engine->id].ringbuf = NULL; + ctx->engine[engine->id].state = NULL; return ret; } diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index e6cda3e225d0..a17cb12221ba 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -57,8 +57,8 @@ /* Logical Rings */ int intel_logical_ring_alloc_request_extras(struct drm_i915_gem_request *request); int intel_logical_ring_reserve_space(struct drm_i915_gem_request *request); -void intel_logical_ring_stop(struct intel_engine_cs *ring); -void intel_logical_ring_cleanup(struct intel_engine_cs *ring); +void intel_logical_ring_stop(struct intel_engine_cs *engine); +void intel_logical_ring_cleanup(struct intel_engine_cs *engine); int intel_logical_rings_init(struct drm_device *dev); int intel_logical_ring_begin(struct drm_i915_gem_request *req, int num_dwords); @@ -98,18 +98,18 @@ static inline void intel_logical_ring_emit_reg(struct intel_ringbuffer *ringbuf, #define LRC_STATE_PN (LRC_PPHWSP_PN + 1) void intel_lr_context_free(struct intel_context *ctx); -uint32_t intel_lr_context_size(struct intel_engine_cs *ring); +uint32_t intel_lr_context_size(struct intel_engine_cs *engine); int intel_lr_context_deferred_alloc(struct intel_context *ctx, - struct intel_engine_cs *ring); + struct intel_engine_cs *engine); void intel_lr_context_unpin(struct intel_context *ctx, struct intel_engine_cs *engine); void intel_lr_context_reset(struct drm_device *dev, struct intel_context *ctx); uint64_t intel_lr_context_descriptor(struct intel_context *ctx, - struct intel_engine_cs *ring); + struct intel_engine_cs *engine); u32 intel_execlists_ctx_id(struct intel_context *ctx, - struct intel_engine_cs *ring); + struct intel_engine_cs *engine); /* Execlists */ int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists); @@ -118,7 +118,7 @@ int intel_execlists_submission(struct i915_execbuffer_params *params, struct drm_i915_gem_execbuffer2 *args, struct list_head *vmas); -void intel_lrc_irq_handler(struct intel_engine_cs *ring); -void intel_execlists_retire_requests(struct intel_engine_cs *ring); +void intel_lrc_irq_handler(struct intel_engine_cs *engine); +void intel_execlists_retire_requests(struct intel_engine_cs *engine); #endif /* _INTEL_LRC_H_ */ diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 688773aaa5e5..53237616ce19 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -59,19 +59,19 @@ int intel_ring_space(struct intel_ringbuffer *ringbuf) return ringbuf->space; } -bool intel_ring_stopped(struct intel_engine_cs *ring) +bool intel_ring_stopped(struct intel_engine_cs *engine) { - struct drm_i915_private *dev_priv = ring->dev->dev_private; - return dev_priv->gpu_error.stop_rings & intel_ring_flag(ring); + struct drm_i915_private *dev_priv = engine->dev->dev_private; + return dev_priv->gpu_error.stop_rings & intel_ring_flag(engine); } -static void __intel_ring_advance(struct intel_engine_cs *ring) +static void __intel_ring_advance(struct intel_engine_cs *engine) { - struct intel_ringbuffer *ringbuf = ring->buffer; + struct intel_ringbuffer *ringbuf = engine->buffer; ringbuf->tail &= ringbuf->size - 1; - if (intel_ring_stopped(ring)) + if (intel_ring_stopped(engine)) return; - ring->write_tail(ring, ringbuf->tail); + engine->write_tail(engine, ringbuf->tail); } static int @@ -429,51 +429,51 @@ gen8_render_ring_flush(struct drm_i915_gem_request *req, return gen8_emit_pipe_control(req, flags, scratch_addr); } -static void ring_write_tail(struct intel_engine_cs *ring, +static void ring_write_tail(struct intel_engine_cs *engine, u32 value) { - struct drm_i915_private *dev_priv = ring->dev->dev_private; - I915_WRITE_TAIL(ring, value); + struct drm_i915_private *dev_priv = engine->dev->dev_private; + I915_WRITE_TAIL(engine, value); } -u64 intel_ring_get_active_head(struct intel_engine_cs *ring) +u64 intel_ring_get_active_head(struct intel_engine_cs *engine) { - struct drm_i915_private *dev_priv = ring->dev->dev_private; + struct drm_i915_private *dev_priv = engine->dev->dev_private; u64 acthd; - if (INTEL_INFO(ring->dev)->gen >= 8) - acthd = I915_READ64_2x32(RING_ACTHD(ring->mmio_base), - RING_ACTHD_UDW(ring->mmio_base)); - else if (INTEL_INFO(ring->dev)->gen >= 4) - acthd = I915_READ(RING_ACTHD(ring->mmio_base)); + if (INTEL_INFO(engine->dev)->gen >= 8) + acthd = I915_READ64_2x32(RING_ACTHD(engine->mmio_base), + RING_ACTHD_UDW(engine->mmio_base)); + else if (INTEL_INFO(engine->dev)->gen >= 4) + acthd = I915_READ(RING_ACTHD(engine->mmio_base)); else acthd = I915_READ(ACTHD); return acthd; } -static void ring_setup_phys_status_page(struct intel_engine_cs *ring) +static void ring_setup_phys_status_page(struct intel_engine_cs *engine) { - struct drm_i915_private *dev_priv = ring->dev->dev_private; + struct drm_i915_private *dev_priv = engine->dev->dev_private; u32 addr; addr = dev_priv->status_page_dmah->busaddr; - if (INTEL_INFO(ring->dev)->gen >= 4) + if (INTEL_INFO(engine->dev)->gen >= 4) addr |= (dev_priv->status_page_dmah->busaddr >> 28) & 0xf0; I915_WRITE(HWS_PGA, addr); } -static void intel_ring_setup_status_page(struct intel_engine_cs *ring) +static void intel_ring_setup_status_page(struct intel_engine_cs *engine) { - struct drm_device *dev = ring->dev; - struct drm_i915_private *dev_priv = ring->dev->dev_private; + struct drm_device *dev = engine->dev; + struct drm_i915_private *dev_priv = engine->dev->dev_private; i915_reg_t mmio; /* The ring status page addresses are no longer next to the rest of * the ring registers as of gen7. */ if (IS_GEN7(dev)) { - switch (ring->id) { + switch (engine->id) { case RCS: mmio = RENDER_HWS_PGA_GEN7; break; @@ -492,14 +492,14 @@ static void intel_ring_setup_status_page(struct intel_engine_cs *ring) mmio = VEBOX_HWS_PGA_GEN7; break; } - } else if (IS_GEN6(ring->dev)) { - mmio = RING_HWS_PGA_GEN6(ring->mmio_base); + } else if (IS_GEN6(engine->dev)) { + mmio = RING_HWS_PGA_GEN6(engine->mmio_base); } else { /* XXX: gen8 returns to sanity */ - mmio = RING_HWS_PGA(ring->mmio_base); + mmio = RING_HWS_PGA(engine->mmio_base); } - I915_WRITE(mmio, (u32)ring->status_page.gfx_addr); + I915_WRITE(mmio, (u32)engine->status_page.gfx_addr); POSTING_READ(mmio); /* @@ -510,10 +510,10 @@ static void intel_ring_setup_status_page(struct intel_engine_cs *ring) * invalidating the TLB? */ if (INTEL_INFO(dev)->gen >= 6 && INTEL_INFO(dev)->gen < 8) { - i915_reg_t reg = RING_INSTPM(ring->mmio_base); + i915_reg_t reg = RING_INSTPM(engine->mmio_base); /* ring should be idle before issuing a sync flush*/ - WARN_ON((I915_READ_MODE(ring) & MODE_IDLE) == 0); + WARN_ON((I915_READ_MODE(engine) & MODE_IDLE) == 0); I915_WRITE(reg, _MASKED_BIT_ENABLE(INSTPM_TLB_INVALIDATE | @@ -521,117 +521,120 @@ static void intel_ring_setup_status_page(struct intel_engine_cs *ring) if (wait_for((I915_READ(reg) & INSTPM_SYNC_FLUSH) == 0, 1000)) DRM_ERROR("%s: wait for SyncFlush to complete for TLB invalidation timed out\n", - ring->name); + engine->name); } } -static bool stop_ring(struct intel_engine_cs *ring) +static bool stop_ring(struct intel_engine_cs *engine) { - struct drm_i915_private *dev_priv = to_i915(ring->dev); + struct drm_i915_private *dev_priv = to_i915(engine->dev); - if (!IS_GEN2(ring->dev)) { - I915_WRITE_MODE(ring, _MASKED_BIT_ENABLE(STOP_RING)); - if (wait_for((I915_READ_MODE(ring) & MODE_IDLE) != 0, 1000)) { - DRM_ERROR("%s : timed out trying to stop ring\n", ring->name); + if (!IS_GEN2(engine->dev)) { + I915_WRITE_MODE(engine, _MASKED_BIT_ENABLE(STOP_RING)); + if (wait_for((I915_READ_MODE(engine) & MODE_IDLE) != 0, 1000)) { + DRM_ERROR("%s : timed out trying to stop ring\n", + engine->name); /* Sometimes we observe that the idle flag is not * set even though the ring is empty. So double * check before giving up. */ - if (I915_READ_HEAD(ring) != I915_READ_TAIL(ring)) + if (I915_READ_HEAD(engine) != I915_READ_TAIL(engine)) return false; } } - I915_WRITE_CTL(ring, 0); - I915_WRITE_HEAD(ring, 0); - ring->write_tail(ring, 0); + I915_WRITE_CTL(engine, 0); + I915_WRITE_HEAD(engine, 0); + engine->write_tail(engine, 0); - if (!IS_GEN2(ring->dev)) { - (void)I915_READ_CTL(ring); - I915_WRITE_MODE(ring, _MASKED_BIT_DISABLE(STOP_RING)); + if (!IS_GEN2(engine->dev)) { + (void)I915_READ_CTL(engine); + I915_WRITE_MODE(engine, _MASKED_BIT_DISABLE(STOP_RING)); } - return (I915_READ_HEAD(ring) & HEAD_ADDR) == 0; + return (I915_READ_HEAD(engine) & HEAD_ADDR) == 0; } -static int init_ring_common(struct intel_engine_cs *ring) +static int init_ring_common(struct intel_engine_cs *engine) { - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_ringbuffer *ringbuf = ring->buffer; + struct intel_ringbuffer *ringbuf = engine->buffer; struct drm_i915_gem_object *obj = ringbuf->obj; int ret = 0; intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); - if (!stop_ring(ring)) { + if (!stop_ring(engine)) { /* G45 ring initialization often fails to reset head to zero */ DRM_DEBUG_KMS("%s head not reset to zero " "ctl %08x head %08x tail %08x start %08x\n", - ring->name, - I915_READ_CTL(ring), - I915_READ_HEAD(ring), - I915_READ_TAIL(ring), - I915_READ_START(ring)); + engine->name, + I915_READ_CTL(engine), + I915_READ_HEAD(engine), + I915_READ_TAIL(engine), + I915_READ_START(engine)); - if (!stop_ring(ring)) { + if (!stop_ring(engine)) { DRM_ERROR("failed to set %s head to zero " "ctl %08x head %08x tail %08x start %08x\n", - ring->name, - I915_READ_CTL(ring), - I915_READ_HEAD(ring), - I915_READ_TAIL(ring), - I915_READ_START(ring)); + engine->name, + I915_READ_CTL(engine), + I915_READ_HEAD(engine), + I915_READ_TAIL(engine), + I915_READ_START(engine)); ret = -EIO; goto out; } } if (I915_NEED_GFX_HWS(dev)) - intel_ring_setup_status_page(ring); + intel_ring_setup_status_page(engine); else - ring_setup_phys_status_page(ring); + ring_setup_phys_status_page(engine); /* Enforce ordering by reading HEAD register back */ - I915_READ_HEAD(ring); + I915_READ_HEAD(engine); /* Initialize the ring. This must happen _after_ we've cleared the ring * registers with the above sequence (the readback of the HEAD registers * also enforces ordering), otherwise the hw might lose the new ring * register values. */ - I915_WRITE_START(ring, i915_gem_obj_ggtt_offset(obj)); + I915_WRITE_START(engine, i915_gem_obj_ggtt_offset(obj)); /* WaClearRingBufHeadRegAtInit:ctg,elk */ - if (I915_READ_HEAD(ring)) + if (I915_READ_HEAD(engine)) DRM_DEBUG("%s initialization failed [head=%08x], fudging\n", - ring->name, I915_READ_HEAD(ring)); - I915_WRITE_HEAD(ring, 0); - (void)I915_READ_HEAD(ring); + engine->name, I915_READ_HEAD(engine)); + I915_WRITE_HEAD(engine, 0); + (void)I915_READ_HEAD(engine); - I915_WRITE_CTL(ring, + I915_WRITE_CTL(engine, ((ringbuf->size - PAGE_SIZE) & RING_NR_PAGES) | RING_VALID); /* If the head is still not zero, the ring is dead */ - if (wait_for((I915_READ_CTL(ring) & RING_VALID) != 0 && - I915_READ_START(ring) == i915_gem_obj_ggtt_offset(obj) && - (I915_READ_HEAD(ring) & HEAD_ADDR) == 0, 50)) { + if (wait_for((I915_READ_CTL(engine) & RING_VALID) != 0 && + I915_READ_START(engine) == i915_gem_obj_ggtt_offset(obj) && + (I915_READ_HEAD(engine) & HEAD_ADDR) == 0, 50)) { DRM_ERROR("%s initialization failed " "ctl %08x (valid? %d) head %08x tail %08x start %08x [expected %08lx]\n", - ring->name, - I915_READ_CTL(ring), I915_READ_CTL(ring) & RING_VALID, - I915_READ_HEAD(ring), I915_READ_TAIL(ring), - I915_READ_START(ring), (unsigned long)i915_gem_obj_ggtt_offset(obj)); + engine->name, + I915_READ_CTL(engine), + I915_READ_CTL(engine) & RING_VALID, + I915_READ_HEAD(engine), I915_READ_TAIL(engine), + I915_READ_START(engine), + (unsigned long)i915_gem_obj_ggtt_offset(obj)); ret = -EIO; goto out; } ringbuf->last_retired_head = -1; - ringbuf->head = I915_READ_HEAD(ring); - ringbuf->tail = I915_READ_TAIL(ring) & TAIL_ADDR; + ringbuf->head = I915_READ_HEAD(engine); + ringbuf->tail = I915_READ_TAIL(engine) & TAIL_ADDR; intel_ring_update_space(ringbuf); - memset(&ring->hangcheck, 0, sizeof(ring->hangcheck)); + memset(&engine->hangcheck, 0, sizeof(engine->hangcheck)); out: intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); @@ -640,59 +643,60 @@ out: } void -intel_fini_pipe_control(struct intel_engine_cs *ring) +intel_fini_pipe_control(struct intel_engine_cs *engine) { - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; - if (ring->scratch.obj == NULL) + if (engine->scratch.obj == NULL) return; if (INTEL_INFO(dev)->gen >= 5) { - kunmap(sg_page(ring->scratch.obj->pages->sgl)); - i915_gem_object_ggtt_unpin(ring->scratch.obj); + kunmap(sg_page(engine->scratch.obj->pages->sgl)); + i915_gem_object_ggtt_unpin(engine->scratch.obj); } - drm_gem_object_unreference(&ring->scratch.obj->base); - ring->scratch.obj = NULL; + drm_gem_object_unreference(&engine->scratch.obj->base); + engine->scratch.obj = NULL; } int -intel_init_pipe_control(struct intel_engine_cs *ring) +intel_init_pipe_control(struct intel_engine_cs *engine) { int ret; - WARN_ON(ring->scratch.obj); + WARN_ON(engine->scratch.obj); - ring->scratch.obj = i915_gem_alloc_object(ring->dev, 4096); - if (ring->scratch.obj == NULL) { + engine->scratch.obj = i915_gem_alloc_object(engine->dev, 4096); + if (engine->scratch.obj == NULL) { DRM_ERROR("Failed to allocate seqno page\n"); ret = -ENOMEM; goto err; } - ret = i915_gem_object_set_cache_level(ring->scratch.obj, I915_CACHE_LLC); + ret = i915_gem_object_set_cache_level(engine->scratch.obj, + I915_CACHE_LLC); if (ret) goto err_unref; - ret = i915_gem_obj_ggtt_pin(ring->scratch.obj, 4096, 0); + ret = i915_gem_obj_ggtt_pin(engine->scratch.obj, 4096, 0); if (ret) goto err_unref; - ring->scratch.gtt_offset = i915_gem_obj_ggtt_offset(ring->scratch.obj); - ring->scratch.cpu_page = kmap(sg_page(ring->scratch.obj->pages->sgl)); - if (ring->scratch.cpu_page == NULL) { + engine->scratch.gtt_offset = i915_gem_obj_ggtt_offset(engine->scratch.obj); + engine->scratch.cpu_page = kmap(sg_page(engine->scratch.obj->pages->sgl)); + if (engine->scratch.cpu_page == NULL) { ret = -ENOMEM; goto err_unpin; } DRM_DEBUG_DRIVER("%s pipe control offset: 0x%08x\n", - ring->name, ring->scratch.gtt_offset); + engine->name, engine->scratch.gtt_offset); return 0; err_unpin: - i915_gem_object_ggtt_unpin(ring->scratch.obj); + i915_gem_object_ggtt_unpin(engine->scratch.obj); err_unref: - drm_gem_object_unreference(&ring->scratch.obj->base); + drm_gem_object_unreference(&engine->scratch.obj->base); err: return ret; } @@ -789,25 +793,26 @@ static int wa_add(struct drm_i915_private *dev_priv, #define WA_WRITE(addr, val) WA_REG(addr, 0xffffffff, val) -static int wa_ring_whitelist_reg(struct intel_engine_cs *ring, i915_reg_t reg) +static int wa_ring_whitelist_reg(struct intel_engine_cs *engine, + i915_reg_t reg) { - struct drm_i915_private *dev_priv = ring->dev->dev_private; + struct drm_i915_private *dev_priv = engine->dev->dev_private; struct i915_workarounds *wa = &dev_priv->workarounds; - const uint32_t index = wa->hw_whitelist_count[ring->id]; + const uint32_t index = wa->hw_whitelist_count[engine->id]; if (WARN_ON(index >= RING_MAX_NONPRIV_SLOTS)) return -EINVAL; - WA_WRITE(RING_FORCE_TO_NONPRIV(ring->mmio_base, index), + WA_WRITE(RING_FORCE_TO_NONPRIV(engine->mmio_base, index), i915_mmio_reg_offset(reg)); - wa->hw_whitelist_count[ring->id]++; + wa->hw_whitelist_count[engine->id]++; return 0; } -static int gen8_init_workarounds(struct intel_engine_cs *ring) +static int gen8_init_workarounds(struct intel_engine_cs *engine) { - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; WA_SET_BIT_MASKED(INSTPM, INSTPM_FORCE_ORDERING); @@ -857,13 +862,13 @@ static int gen8_init_workarounds(struct intel_engine_cs *ring) return 0; } -static int bdw_init_workarounds(struct intel_engine_cs *ring) +static int bdw_init_workarounds(struct intel_engine_cs *engine) { int ret; - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; - ret = gen8_init_workarounds(ring); + ret = gen8_init_workarounds(engine); if (ret) return ret; @@ -886,13 +891,13 @@ static int bdw_init_workarounds(struct intel_engine_cs *ring) return 0; } -static int chv_init_workarounds(struct intel_engine_cs *ring) +static int chv_init_workarounds(struct intel_engine_cs *engine) { int ret; - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; - ret = gen8_init_workarounds(ring); + ret = gen8_init_workarounds(engine); if (ret) return ret; @@ -905,9 +910,9 @@ static int chv_init_workarounds(struct intel_engine_cs *ring) return 0; } -static int gen9_init_workarounds(struct intel_engine_cs *ring) +static int gen9_init_workarounds(struct intel_engine_cs *engine) { - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; uint32_t tmp; int ret; @@ -986,21 +991,21 @@ static int gen9_init_workarounds(struct intel_engine_cs *ring) GEN8_LQSC_FLUSH_COHERENT_LINES)); /* WaEnablePreemptionGranularityControlByUMD:skl,bxt */ - ret= wa_ring_whitelist_reg(ring, GEN8_CS_CHICKEN1); + ret= wa_ring_whitelist_reg(engine, GEN8_CS_CHICKEN1); if (ret) return ret; /* WaAllowUMDToModifyHDCChicken1:skl,bxt */ - ret = wa_ring_whitelist_reg(ring, GEN8_HDC_CHICKEN1); + ret = wa_ring_whitelist_reg(engine, GEN8_HDC_CHICKEN1); if (ret) return ret; return 0; } -static int skl_tune_iz_hashing(struct intel_engine_cs *ring) +static int skl_tune_iz_hashing(struct intel_engine_cs *engine) { - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; u8 vals[3] = { 0, 0, 0 }; unsigned int i; @@ -1040,13 +1045,13 @@ static int skl_tune_iz_hashing(struct intel_engine_cs *ring) return 0; } -static int skl_init_workarounds(struct intel_engine_cs *ring) +static int skl_init_workarounds(struct intel_engine_cs *engine) { int ret; - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; - ret = gen9_init_workarounds(ring); + ret = gen9_init_workarounds(engine); if (ret) return ret; @@ -1113,20 +1118,20 @@ static int skl_init_workarounds(struct intel_engine_cs *ring) GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE); /* WaDisableLSQCROPERFforOCL:skl */ - ret = wa_ring_whitelist_reg(ring, GEN8_L3SQCREG4); + ret = wa_ring_whitelist_reg(engine, GEN8_L3SQCREG4); if (ret) return ret; - return skl_tune_iz_hashing(ring); + return skl_tune_iz_hashing(engine); } -static int bxt_init_workarounds(struct intel_engine_cs *ring) +static int bxt_init_workarounds(struct intel_engine_cs *engine) { int ret; - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; - ret = gen9_init_workarounds(ring); + ret = gen9_init_workarounds(engine); if (ret) return ret; @@ -1157,11 +1162,11 @@ static int bxt_init_workarounds(struct intel_engine_cs *ring) /* WaDisableObjectLevelPreemtionForInstanceId:bxt */ /* WaDisableLSQCROPERFforOCL:bxt */ if (IS_BXT_REVID(dev, 0, BXT_REVID_A1)) { - ret = wa_ring_whitelist_reg(ring, GEN9_CS_DEBUG_MODE1); + ret = wa_ring_whitelist_reg(engine, GEN9_CS_DEBUG_MODE1); if (ret) return ret; - ret = wa_ring_whitelist_reg(ring, GEN8_L3SQCREG4); + ret = wa_ring_whitelist_reg(engine, GEN8_L3SQCREG4); if (ret) return ret; } @@ -1169,36 +1174,36 @@ static int bxt_init_workarounds(struct intel_engine_cs *ring) return 0; } -int init_workarounds_ring(struct intel_engine_cs *ring) +int init_workarounds_ring(struct intel_engine_cs *engine) { - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; - WARN_ON(ring->id != RCS); + WARN_ON(engine->id != RCS); dev_priv->workarounds.count = 0; dev_priv->workarounds.hw_whitelist_count[RCS] = 0; if (IS_BROADWELL(dev)) - return bdw_init_workarounds(ring); + return bdw_init_workarounds(engine); if (IS_CHERRYVIEW(dev)) - return chv_init_workarounds(ring); + return chv_init_workarounds(engine); if (IS_SKYLAKE(dev)) - return skl_init_workarounds(ring); + return skl_init_workarounds(engine); if (IS_BROXTON(dev)) - return bxt_init_workarounds(ring); + return bxt_init_workarounds(engine); return 0; } -static int init_render_ring(struct intel_engine_cs *ring) +static int init_render_ring(struct intel_engine_cs *engine) { - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; - int ret = init_ring_common(ring); + int ret = init_ring_common(engine); if (ret) return ret; @@ -1241,14 +1246,14 @@ static int init_render_ring(struct intel_engine_cs *ring) I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_FORCE_ORDERING)); if (HAS_L3_DPF(dev)) - I915_WRITE_IMR(ring, ~GT_PARITY_ERROR(dev)); + I915_WRITE_IMR(engine, ~GT_PARITY_ERROR(dev)); - return init_workarounds_ring(ring); + return init_workarounds_ring(engine); } -static void render_ring_cleanup(struct intel_engine_cs *ring) +static void render_ring_cleanup(struct intel_engine_cs *engine) { - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; if (dev_priv->semaphore_obj) { @@ -1257,7 +1262,7 @@ static void render_ring_cleanup(struct intel_engine_cs *ring) dev_priv->semaphore_obj = NULL; } - intel_fini_pipe_control(ring); + intel_fini_pipe_control(engine); } static int gen8_rcs_signal(struct drm_i915_gem_request *signaller_req, @@ -1554,47 +1559,47 @@ pc_render_add_request(struct drm_i915_gem_request *req) } static u32 -gen6_ring_get_seqno(struct intel_engine_cs *ring, bool lazy_coherency) +gen6_ring_get_seqno(struct intel_engine_cs *engine, bool lazy_coherency) { /* Workaround to force correct ordering between irq and seqno writes on * ivb (and maybe also on snb) by reading from a CS register (like * ACTHD) before reading the status page. */ if (!lazy_coherency) { - struct drm_i915_private *dev_priv = ring->dev->dev_private; - POSTING_READ(RING_ACTHD(ring->mmio_base)); + struct drm_i915_private *dev_priv = engine->dev->dev_private; + POSTING_READ(RING_ACTHD(engine->mmio_base)); } - return intel_read_status_page(ring, I915_GEM_HWS_INDEX); + return intel_read_status_page(engine, I915_GEM_HWS_INDEX); } static u32 -ring_get_seqno(struct intel_engine_cs *ring, bool lazy_coherency) +ring_get_seqno(struct intel_engine_cs *engine, bool lazy_coherency) { - return intel_read_status_page(ring, I915_GEM_HWS_INDEX); + return intel_read_status_page(engine, I915_GEM_HWS_INDEX); } static void -ring_set_seqno(struct intel_engine_cs *ring, u32 seqno) +ring_set_seqno(struct intel_engine_cs *engine, u32 seqno) { - intel_write_status_page(ring, I915_GEM_HWS_INDEX, seqno); + intel_write_status_page(engine, I915_GEM_HWS_INDEX, seqno); } static u32 -pc_render_get_seqno(struct intel_engine_cs *ring, bool lazy_coherency) +pc_render_get_seqno(struct intel_engine_cs *engine, bool lazy_coherency) { - return ring->scratch.cpu_page[0]; + return engine->scratch.cpu_page[0]; } static void -pc_render_set_seqno(struct intel_engine_cs *ring, u32 seqno) +pc_render_set_seqno(struct intel_engine_cs *engine, u32 seqno) { - ring->scratch.cpu_page[0] = seqno; + engine->scratch.cpu_page[0] = seqno; } static bool -gen5_ring_get_irq(struct intel_engine_cs *ring) +gen5_ring_get_irq(struct intel_engine_cs *engine) { - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; unsigned long flags; @@ -1602,30 +1607,30 @@ gen5_ring_get_irq(struct intel_engine_cs *ring) return false; spin_lock_irqsave(&dev_priv->irq_lock, flags); - if (ring->irq_refcount++ == 0) - gen5_enable_gt_irq(dev_priv, ring->irq_enable_mask); + if (engine->irq_refcount++ == 0) + gen5_enable_gt_irq(dev_priv, engine->irq_enable_mask); spin_unlock_irqrestore(&dev_priv->irq_lock, flags); return true; } static void -gen5_ring_put_irq(struct intel_engine_cs *ring) +gen5_ring_put_irq(struct intel_engine_cs *engine) { - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; unsigned long flags; spin_lock_irqsave(&dev_priv->irq_lock, flags); - if (--ring->irq_refcount == 0) - gen5_disable_gt_irq(dev_priv, ring->irq_enable_mask); + if (--engine->irq_refcount == 0) + gen5_disable_gt_irq(dev_priv, engine->irq_enable_mask); spin_unlock_irqrestore(&dev_priv->irq_lock, flags); } static bool -i9xx_ring_get_irq(struct intel_engine_cs *ring) +i9xx_ring_get_irq(struct intel_engine_cs *engine) { - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; unsigned long flags; @@ -1633,8 +1638,8 @@ i9xx_ring_get_irq(struct intel_engine_cs *ring) return false; spin_lock_irqsave(&dev_priv->irq_lock, flags); - if (ring->irq_refcount++ == 0) { - dev_priv->irq_mask &= ~ring->irq_enable_mask; + if (engine->irq_refcount++ == 0) { + dev_priv->irq_mask &= ~engine->irq_enable_mask; I915_WRITE(IMR, dev_priv->irq_mask); POSTING_READ(IMR); } @@ -1644,15 +1649,15 @@ i9xx_ring_get_irq(struct intel_engine_cs *ring) } static void -i9xx_ring_put_irq(struct intel_engine_cs *ring) +i9xx_ring_put_irq(struct intel_engine_cs *engine) { - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; unsigned long flags; spin_lock_irqsave(&dev_priv->irq_lock, flags); - if (--ring->irq_refcount == 0) { - dev_priv->irq_mask |= ring->irq_enable_mask; + if (--engine->irq_refcount == 0) { + dev_priv->irq_mask |= engine->irq_enable_mask; I915_WRITE(IMR, dev_priv->irq_mask); POSTING_READ(IMR); } @@ -1660,9 +1665,9 @@ i9xx_ring_put_irq(struct intel_engine_cs *ring) } static bool -i8xx_ring_get_irq(struct intel_engine_cs *ring) +i8xx_ring_get_irq(struct intel_engine_cs *engine) { - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; unsigned long flags; @@ -1670,8 +1675,8 @@ i8xx_ring_get_irq(struct intel_engine_cs *ring) return false; spin_lock_irqsave(&dev_priv->irq_lock, flags); - if (ring->irq_refcount++ == 0) { - dev_priv->irq_mask &= ~ring->irq_enable_mask; + if (engine->irq_refcount++ == 0) { + dev_priv->irq_mask &= ~engine->irq_enable_mask; I915_WRITE16(IMR, dev_priv->irq_mask); POSTING_READ16(IMR); } @@ -1681,15 +1686,15 @@ i8xx_ring_get_irq(struct intel_engine_cs *ring) } static void -i8xx_ring_put_irq(struct intel_engine_cs *ring) +i8xx_ring_put_irq(struct intel_engine_cs *engine) { - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; unsigned long flags; spin_lock_irqsave(&dev_priv->irq_lock, flags); - if (--ring->irq_refcount == 0) { - dev_priv->irq_mask |= ring->irq_enable_mask; + if (--engine->irq_refcount == 0) { + dev_priv->irq_mask |= engine->irq_enable_mask; I915_WRITE16(IMR, dev_priv->irq_mask); POSTING_READ16(IMR); } @@ -1735,9 +1740,9 @@ i9xx_add_request(struct drm_i915_gem_request *req) } static bool -gen6_ring_get_irq(struct intel_engine_cs *ring) +gen6_ring_get_irq(struct intel_engine_cs *engine) { - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; unsigned long flags; @@ -1745,14 +1750,14 @@ gen6_ring_get_irq(struct intel_engine_cs *ring) return false; spin_lock_irqsave(&dev_priv->irq_lock, flags); - if (ring->irq_refcount++ == 0) { - if (HAS_L3_DPF(dev) && ring->id == RCS) - I915_WRITE_IMR(ring, - ~(ring->irq_enable_mask | + if (engine->irq_refcount++ == 0) { + if (HAS_L3_DPF(dev) && engine->id == RCS) + I915_WRITE_IMR(engine, + ~(engine->irq_enable_mask | GT_PARITY_ERROR(dev))); else - I915_WRITE_IMR(ring, ~ring->irq_enable_mask); - gen5_enable_gt_irq(dev_priv, ring->irq_enable_mask); + I915_WRITE_IMR(engine, ~engine->irq_enable_mask); + gen5_enable_gt_irq(dev_priv, engine->irq_enable_mask); } spin_unlock_irqrestore(&dev_priv->irq_lock, flags); @@ -1760,27 +1765,27 @@ gen6_ring_get_irq(struct intel_engine_cs *ring) } static void -gen6_ring_put_irq(struct intel_engine_cs *ring) +gen6_ring_put_irq(struct intel_engine_cs *engine) { - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; unsigned long flags; spin_lock_irqsave(&dev_priv->irq_lock, flags); - if (--ring->irq_refcount == 0) { - if (HAS_L3_DPF(dev) && ring->id == RCS) - I915_WRITE_IMR(ring, ~GT_PARITY_ERROR(dev)); + if (--engine->irq_refcount == 0) { + if (HAS_L3_DPF(dev) && engine->id == RCS) + I915_WRITE_IMR(engine, ~GT_PARITY_ERROR(dev)); else - I915_WRITE_IMR(ring, ~0); - gen5_disable_gt_irq(dev_priv, ring->irq_enable_mask); + I915_WRITE_IMR(engine, ~0); + gen5_disable_gt_irq(dev_priv, engine->irq_enable_mask); } spin_unlock_irqrestore(&dev_priv->irq_lock, flags); } static bool -hsw_vebox_get_irq(struct intel_engine_cs *ring) +hsw_vebox_get_irq(struct intel_engine_cs *engine) { - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; unsigned long flags; @@ -1788,9 +1793,9 @@ hsw_vebox_get_irq(struct intel_engine_cs *ring) return false; spin_lock_irqsave(&dev_priv->irq_lock, flags); - if (ring->irq_refcount++ == 0) { - I915_WRITE_IMR(ring, ~ring->irq_enable_mask); - gen6_enable_pm_irq(dev_priv, ring->irq_enable_mask); + if (engine->irq_refcount++ == 0) { + I915_WRITE_IMR(engine, ~engine->irq_enable_mask); + gen6_enable_pm_irq(dev_priv, engine->irq_enable_mask); } spin_unlock_irqrestore(&dev_priv->irq_lock, flags); @@ -1798,24 +1803,24 @@ hsw_vebox_get_irq(struct intel_engine_cs *ring) } static void -hsw_vebox_put_irq(struct intel_engine_cs *ring) +hsw_vebox_put_irq(struct intel_engine_cs *engine) { - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; unsigned long flags; spin_lock_irqsave(&dev_priv->irq_lock, flags); - if (--ring->irq_refcount == 0) { - I915_WRITE_IMR(ring, ~0); - gen6_disable_pm_irq(dev_priv, ring->irq_enable_mask); + if (--engine->irq_refcount == 0) { + I915_WRITE_IMR(engine, ~0); + gen6_disable_pm_irq(dev_priv, engine->irq_enable_mask); } spin_unlock_irqrestore(&dev_priv->irq_lock, flags); } static bool -gen8_ring_get_irq(struct intel_engine_cs *ring) +gen8_ring_get_irq(struct intel_engine_cs *engine) { - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; unsigned long flags; @@ -1823,15 +1828,15 @@ gen8_ring_get_irq(struct intel_engine_cs *ring) return false; spin_lock_irqsave(&dev_priv->irq_lock, flags); - if (ring->irq_refcount++ == 0) { - if (HAS_L3_DPF(dev) && ring->id == RCS) { - I915_WRITE_IMR(ring, - ~(ring->irq_enable_mask | + if (engine->irq_refcount++ == 0) { + if (HAS_L3_DPF(dev) && engine->id == RCS) { + I915_WRITE_IMR(engine, + ~(engine->irq_enable_mask | GT_RENDER_L3_PARITY_ERROR_INTERRUPT)); } else { - I915_WRITE_IMR(ring, ~ring->irq_enable_mask); + I915_WRITE_IMR(engine, ~engine->irq_enable_mask); } - POSTING_READ(RING_IMR(ring->mmio_base)); + POSTING_READ(RING_IMR(engine->mmio_base)); } spin_unlock_irqrestore(&dev_priv->irq_lock, flags); @@ -1839,21 +1844,21 @@ gen8_ring_get_irq(struct intel_engine_cs *ring) } static void -gen8_ring_put_irq(struct intel_engine_cs *ring) +gen8_ring_put_irq(struct intel_engine_cs *engine) { - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; unsigned long flags; spin_lock_irqsave(&dev_priv->irq_lock, flags); - if (--ring->irq_refcount == 0) { - if (HAS_L3_DPF(dev) && ring->id == RCS) { - I915_WRITE_IMR(ring, + if (--engine->irq_refcount == 0) { + if (HAS_L3_DPF(dev) && engine->id == RCS) { + I915_WRITE_IMR(engine, ~GT_RENDER_L3_PARITY_ERROR_INTERRUPT); } else { - I915_WRITE_IMR(ring, ~0); + I915_WRITE_IMR(engine, ~0); } - POSTING_READ(RING_IMR(ring->mmio_base)); + POSTING_READ(RING_IMR(engine->mmio_base)); } spin_unlock_irqrestore(&dev_priv->irq_lock, flags); } @@ -1967,40 +1972,40 @@ i915_dispatch_execbuffer(struct drm_i915_gem_request *req, return 0; } -static void cleanup_phys_status_page(struct intel_engine_cs *ring) +static void cleanup_phys_status_page(struct intel_engine_cs *engine) { - struct drm_i915_private *dev_priv = to_i915(ring->dev); + struct drm_i915_private *dev_priv = to_i915(engine->dev); if (!dev_priv->status_page_dmah) return; - drm_pci_free(ring->dev, dev_priv->status_page_dmah); - ring->status_page.page_addr = NULL; + drm_pci_free(engine->dev, dev_priv->status_page_dmah); + engine->status_page.page_addr = NULL; } -static void cleanup_status_page(struct intel_engine_cs *ring) +static void cleanup_status_page(struct intel_engine_cs *engine) { struct drm_i915_gem_object *obj; - obj = ring->status_page.obj; + obj = engine->status_page.obj; if (obj == NULL) return; kunmap(sg_page(obj->pages->sgl)); i915_gem_object_ggtt_unpin(obj); drm_gem_object_unreference(&obj->base); - ring->status_page.obj = NULL; + engine->status_page.obj = NULL; } -static int init_status_page(struct intel_engine_cs *ring) +static int init_status_page(struct intel_engine_cs *engine) { - struct drm_i915_gem_object *obj = ring->status_page.obj; + struct drm_i915_gem_object *obj = engine->status_page.obj; if (obj == NULL) { unsigned flags; int ret; - obj = i915_gem_alloc_object(ring->dev, 4096); + obj = i915_gem_alloc_object(engine->dev, 4096); if (obj == NULL) { DRM_ERROR("Failed to allocate status page\n"); return -ENOMEM; @@ -2011,7 +2016,7 @@ static int init_status_page(struct intel_engine_cs *ring) goto err_unref; flags = 0; - if (!HAS_LLC(ring->dev)) + if (!HAS_LLC(engine->dev)) /* On g33, we cannot place HWS above 256MiB, so * restrict its pinning to the low mappable arena. * Though this restriction is not documented for @@ -2030,32 +2035,32 @@ err_unref: return ret; } - ring->status_page.obj = obj; + engine->status_page.obj = obj; } - ring->status_page.gfx_addr = i915_gem_obj_ggtt_offset(obj); - ring->status_page.page_addr = kmap(sg_page(obj->pages->sgl)); - memset(ring->status_page.page_addr, 0, PAGE_SIZE); + engine->status_page.gfx_addr = i915_gem_obj_ggtt_offset(obj); + engine->status_page.page_addr = kmap(sg_page(obj->pages->sgl)); + memset(engine->status_page.page_addr, 0, PAGE_SIZE); DRM_DEBUG_DRIVER("%s hws offset: 0x%08x\n", - ring->name, ring->status_page.gfx_addr); + engine->name, engine->status_page.gfx_addr); return 0; } -static int init_phys_status_page(struct intel_engine_cs *ring) +static int init_phys_status_page(struct intel_engine_cs *engine) { - struct drm_i915_private *dev_priv = ring->dev->dev_private; + struct drm_i915_private *dev_priv = engine->dev->dev_private; if (!dev_priv->status_page_dmah) { dev_priv->status_page_dmah = - drm_pci_alloc(ring->dev, PAGE_SIZE, PAGE_SIZE); + drm_pci_alloc(engine->dev, PAGE_SIZE, PAGE_SIZE); if (!dev_priv->status_page_dmah) return -ENOMEM; } - ring->status_page.page_addr = dev_priv->status_page_dmah->vaddr; - memset(ring->status_page.page_addr, 0, PAGE_SIZE); + engine->status_page.page_addr = dev_priv->status_page_dmah->vaddr; + memset(engine->status_page.page_addr, 0, PAGE_SIZE); return 0; } @@ -2218,37 +2223,38 @@ intel_ringbuffer_free(struct intel_ringbuffer *ring) } static int intel_init_ring_buffer(struct drm_device *dev, - struct intel_engine_cs *ring) + struct intel_engine_cs *engine) { struct intel_ringbuffer *ringbuf; int ret; - WARN_ON(ring->buffer); + WARN_ON(engine->buffer); - ring->dev = dev; - INIT_LIST_HEAD(&ring->active_list); - INIT_LIST_HEAD(&ring->request_list); - INIT_LIST_HEAD(&ring->execlist_queue); - INIT_LIST_HEAD(&ring->buffers); - i915_gem_batch_pool_init(dev, &ring->batch_pool); - memset(ring->semaphore.sync_seqno, 0, sizeof(ring->semaphore.sync_seqno)); + engine->dev = dev; + INIT_LIST_HEAD(&engine->active_list); + INIT_LIST_HEAD(&engine->request_list); + INIT_LIST_HEAD(&engine->execlist_queue); + INIT_LIST_HEAD(&engine->buffers); + i915_gem_batch_pool_init(dev, &engine->batch_pool); + memset(engine->semaphore.sync_seqno, 0, + sizeof(engine->semaphore.sync_seqno)); - init_waitqueue_head(&ring->irq_queue); + init_waitqueue_head(&engine->irq_queue); - ringbuf = intel_engine_create_ringbuffer(ring, 32 * PAGE_SIZE); + ringbuf = intel_engine_create_ringbuffer(engine, 32 * PAGE_SIZE); if (IS_ERR(ringbuf)) { ret = PTR_ERR(ringbuf); goto error; } - ring->buffer = ringbuf; + engine->buffer = ringbuf; if (I915_NEED_GFX_HWS(dev)) { - ret = init_status_page(ring); + ret = init_status_page(engine); if (ret) goto error; } else { - WARN_ON(ring->id != RCS); - ret = init_phys_status_page(ring); + WARN_ON(engine->id != RCS); + ret = init_phys_status_page(engine); if (ret) goto error; } @@ -2256,58 +2262,58 @@ static int intel_init_ring_buffer(struct drm_device *dev, ret = intel_pin_and_map_ringbuffer_obj(dev, ringbuf); if (ret) { DRM_ERROR("Failed to pin and map ringbuffer %s: %d\n", - ring->name, ret); + engine->name, ret); intel_destroy_ringbuffer_obj(ringbuf); goto error; } - ret = i915_cmd_parser_init_ring(ring); + ret = i915_cmd_parser_init_ring(engine); if (ret) goto error; return 0; error: - intel_cleanup_ring_buffer(ring); + intel_cleanup_ring_buffer(engine); return ret; } -void intel_cleanup_ring_buffer(struct intel_engine_cs *ring) +void intel_cleanup_ring_buffer(struct intel_engine_cs *engine) { struct drm_i915_private *dev_priv; - if (!intel_ring_initialized(ring)) + if (!intel_ring_initialized(engine)) return; - dev_priv = to_i915(ring->dev); + dev_priv = to_i915(engine->dev); - if (ring->buffer) { - intel_stop_ring_buffer(ring); - WARN_ON(!IS_GEN2(ring->dev) && (I915_READ_MODE(ring) & MODE_IDLE) == 0); + if (engine->buffer) { + intel_stop_ring_buffer(engine); + WARN_ON(!IS_GEN2(engine->dev) && (I915_READ_MODE(engine) & MODE_IDLE) == 0); - intel_unpin_ringbuffer_obj(ring->buffer); - intel_ringbuffer_free(ring->buffer); - ring->buffer = NULL; + intel_unpin_ringbuffer_obj(engine->buffer); + intel_ringbuffer_free(engine->buffer); + engine->buffer = NULL; } - if (ring->cleanup) - ring->cleanup(ring); + if (engine->cleanup) + engine->cleanup(engine); - if (I915_NEED_GFX_HWS(ring->dev)) { - cleanup_status_page(ring); + if (I915_NEED_GFX_HWS(engine->dev)) { + cleanup_status_page(engine); } else { - WARN_ON(ring->id != RCS); - cleanup_phys_status_page(ring); + WARN_ON(engine->id != RCS); + cleanup_phys_status_page(engine); } - i915_cmd_parser_fini_ring(ring); - i915_gem_batch_pool_fini(&ring->batch_pool); - ring->dev = NULL; + i915_cmd_parser_fini_ring(engine); + i915_gem_batch_pool_fini(&engine->batch_pool); + engine->dev = NULL; } -static int ring_wait_for_space(struct intel_engine_cs *ring, int n) +static int ring_wait_for_space(struct intel_engine_cs *engine, int n) { - struct intel_ringbuffer *ringbuf = ring->buffer; + struct intel_ringbuffer *ringbuf = engine->buffer; struct drm_i915_gem_request *request; unsigned space; int ret; @@ -2318,14 +2324,14 @@ static int ring_wait_for_space(struct intel_engine_cs *ring, int n) /* The whole point of reserving space is to not wait! */ WARN_ON(ringbuf->reserved_in_use); - list_for_each_entry(request, &ring->request_list, list) { + list_for_each_entry(request, &engine->request_list, list) { space = __intel_ring_space(request->postfix, ringbuf->tail, ringbuf->size); if (space >= n) break; } - if (WARN_ON(&request->list == &ring->request_list)) + if (WARN_ON(&request->list == &engine->request_list)) return -ENOSPC; ret = i915_wait_request(request); @@ -2350,22 +2356,22 @@ static void __wrap_ring_buffer(struct intel_ringbuffer *ringbuf) intel_ring_update_space(ringbuf); } -int intel_ring_idle(struct intel_engine_cs *ring) +int intel_ring_idle(struct intel_engine_cs *engine) { struct drm_i915_gem_request *req; /* Wait upon the last request to be completed */ - if (list_empty(&ring->request_list)) + if (list_empty(&engine->request_list)) return 0; - req = list_entry(ring->request_list.prev, - struct drm_i915_gem_request, - list); + req = list_entry(engine->request_list.prev, + struct drm_i915_gem_request, + list); /* Make sure we do not trigger any retires */ return __i915_wait_request(req, - atomic_read(&to_i915(ring->dev)->gpu_error.reset_counter), - to_i915(ring->dev)->mm.interruptible, + atomic_read(&to_i915(engine->dev)->gpu_error.reset_counter), + to_i915(engine->dev)->mm.interruptible, NULL, NULL); } @@ -2437,9 +2443,9 @@ void intel_ring_reserved_space_end(struct intel_ringbuffer *ringbuf) ringbuf->reserved_in_use = false; } -static int __intel_ring_prepare(struct intel_engine_cs *ring, int bytes) +static int __intel_ring_prepare(struct intel_engine_cs *engine, int bytes) { - struct intel_ringbuffer *ringbuf = ring->buffer; + struct intel_ringbuffer *ringbuf = engine->buffer; int remain_usable = ringbuf->effective_size - ringbuf->tail; int remain_actual = ringbuf->size - ringbuf->tail; int ret, total_bytes, wait_bytes = 0; @@ -2473,7 +2479,7 @@ static int __intel_ring_prepare(struct intel_engine_cs *ring, int bytes) } if (wait_bytes) { - ret = ring_wait_for_space(ring, wait_bytes); + ret = ring_wait_for_space(engine, wait_bytes); if (unlikely(ret)) return ret; @@ -2531,26 +2537,26 @@ int intel_ring_cacheline_align(struct drm_i915_gem_request *req) return 0; } -void intel_ring_init_seqno(struct intel_engine_cs *ring, u32 seqno) +void intel_ring_init_seqno(struct intel_engine_cs *engine, u32 seqno) { - struct drm_device *dev = ring->dev; + struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; if (INTEL_INFO(dev)->gen == 6 || INTEL_INFO(dev)->gen == 7) { - I915_WRITE(RING_SYNC_0(ring->mmio_base), 0); - I915_WRITE(RING_SYNC_1(ring->mmio_base), 0); + I915_WRITE(RING_SYNC_0(engine->mmio_base), 0); + I915_WRITE(RING_SYNC_1(engine->mmio_base), 0); if (HAS_VEBOX(dev)) - I915_WRITE(RING_SYNC_2(ring->mmio_base), 0); + I915_WRITE(RING_SYNC_2(engine->mmio_base), 0); } - ring->set_seqno(ring, seqno); - ring->hangcheck.seqno = seqno; + engine->set_seqno(engine, seqno); + engine->hangcheck.seqno = seqno; } -static void gen6_bsd_ring_write_tail(struct intel_engine_cs *ring, +static void gen6_bsd_ring_write_tail(struct intel_engine_cs *engine, u32 value) { - struct drm_i915_private *dev_priv = ring->dev->dev_private; + struct drm_i915_private *dev_priv = engine->dev->dev_private; /* Every tail move must follow the sequence below */ @@ -2570,8 +2576,8 @@ static void gen6_bsd_ring_write_tail(struct intel_engine_cs *ring, DRM_ERROR("timed out waiting for the BSD ring to wake up\n"); /* Now that the ring is fully powered up, update the tail */ - I915_WRITE_TAIL(ring, value); - POSTING_READ(RING_TAIL(ring->mmio_base)); + I915_WRITE_TAIL(engine, value); + POSTING_READ(RING_TAIL(engine->mmio_base)); /* Let the ring send IDLE messages to the GT again, * and so let it sleep to conserve power when idle. @@ -3157,17 +3163,17 @@ intel_ring_invalidate_all_caches(struct drm_i915_gem_request *req) } void -intel_stop_ring_buffer(struct intel_engine_cs *ring) +intel_stop_ring_buffer(struct intel_engine_cs *engine) { int ret; - if (!intel_ring_initialized(ring)) + if (!intel_ring_initialized(engine)) return; - ret = intel_ring_idle(ring); - if (ret && !i915_reset_in_progress(&to_i915(ring->dev)->gpu_error)) + ret = intel_ring_idle(engine); + if (ret && !i915_reset_in_progress(&to_i915(engine->dev)->gpu_error)) DRM_ERROR("failed to quiesce %s whilst cleaning up: %d\n", - ring->name, ret); + engine->name, ret); - stop_ring(ring); + stop_ring(engine); } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 24efb57dcd7d..48484639c9da 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -355,19 +355,19 @@ struct intel_engine_cs { }; static inline bool -intel_ring_initialized(struct intel_engine_cs *ring) +intel_ring_initialized(struct intel_engine_cs *engine) { - return ring->dev != NULL; + return engine->dev != NULL; } static inline unsigned -intel_ring_flag(struct intel_engine_cs *ring) +intel_ring_flag(struct intel_engine_cs *engine) { - return 1 << ring->id; + return 1 << engine->id; } static inline u32 -intel_ring_sync_index(struct intel_engine_cs *ring, +intel_ring_sync_index(struct intel_engine_cs *engine, struct intel_engine_cs *other) { int idx; @@ -380,7 +380,7 @@ intel_ring_sync_index(struct intel_engine_cs *ring, * vcs2 -> 0 = rcs, 1 = vcs, 2 = bcs, 3 = vecs; */ - idx = (other - ring) - 1; + idx = (other - engine) - 1; if (idx < 0) idx += I915_NUM_RINGS; @@ -388,26 +388,26 @@ intel_ring_sync_index(struct intel_engine_cs *ring, } static inline void -intel_flush_status_page(struct intel_engine_cs *ring, int reg) +intel_flush_status_page(struct intel_engine_cs *engine, int reg) { - drm_clflush_virt_range(&ring->status_page.page_addr[reg], + drm_clflush_virt_range(&engine->status_page.page_addr[reg], sizeof(uint32_t)); } static inline u32 -intel_read_status_page(struct intel_engine_cs *ring, +intel_read_status_page(struct intel_engine_cs *engine, int reg) { /* Ensure that the compiler doesn't optimize away the load. */ barrier(); - return ring->status_page.page_addr[reg]; + return engine->status_page.page_addr[reg]; } static inline void -intel_write_status_page(struct intel_engine_cs *ring, +intel_write_status_page(struct intel_engine_cs *engine, int reg, u32 value) { - ring->status_page.page_addr[reg] = value; + engine->status_page.page_addr[reg] = value; } /* @@ -438,42 +438,42 @@ int intel_pin_and_map_ringbuffer_obj(struct drm_device *dev, void intel_unpin_ringbuffer_obj(struct intel_ringbuffer *ringbuf); void intel_ringbuffer_free(struct intel_ringbuffer *ring); -void intel_stop_ring_buffer(struct intel_engine_cs *ring); -void intel_cleanup_ring_buffer(struct intel_engine_cs *ring); +void intel_stop_ring_buffer(struct intel_engine_cs *engine); +void intel_cleanup_ring_buffer(struct intel_engine_cs *engine); int intel_ring_alloc_request_extras(struct drm_i915_gem_request *request); int __must_check intel_ring_begin(struct drm_i915_gem_request *req, int n); int __must_check intel_ring_cacheline_align(struct drm_i915_gem_request *req); -static inline void intel_ring_emit(struct intel_engine_cs *ring, +static inline void intel_ring_emit(struct intel_engine_cs *engine, u32 data) { - struct intel_ringbuffer *ringbuf = ring->buffer; + struct intel_ringbuffer *ringbuf = engine->buffer; iowrite32(data, ringbuf->virtual_start + ringbuf->tail); ringbuf->tail += 4; } -static inline void intel_ring_emit_reg(struct intel_engine_cs *ring, +static inline void intel_ring_emit_reg(struct intel_engine_cs *engine, i915_reg_t reg) { - intel_ring_emit(ring, i915_mmio_reg_offset(reg)); + intel_ring_emit(engine, i915_mmio_reg_offset(reg)); } -static inline void intel_ring_advance(struct intel_engine_cs *ring) +static inline void intel_ring_advance(struct intel_engine_cs *engine) { - struct intel_ringbuffer *ringbuf = ring->buffer; + struct intel_ringbuffer *ringbuf = engine->buffer; ringbuf->tail &= ringbuf->size - 1; } int __intel_ring_space(int head, int tail, int size); void intel_ring_update_space(struct intel_ringbuffer *ringbuf); int intel_ring_space(struct intel_ringbuffer *ringbuf); -bool intel_ring_stopped(struct intel_engine_cs *ring); +bool intel_ring_stopped(struct intel_engine_cs *engine); -int __must_check intel_ring_idle(struct intel_engine_cs *ring); -void intel_ring_init_seqno(struct intel_engine_cs *ring, u32 seqno); +int __must_check intel_ring_idle(struct intel_engine_cs *engine); +void intel_ring_init_seqno(struct intel_engine_cs *engine, u32 seqno); int intel_ring_flush_all_caches(struct drm_i915_gem_request *req); int intel_ring_invalidate_all_caches(struct drm_i915_gem_request *req); -void intel_fini_pipe_control(struct intel_engine_cs *ring); -int intel_init_pipe_control(struct intel_engine_cs *ring); +void intel_fini_pipe_control(struct intel_engine_cs *engine); +int intel_init_pipe_control(struct intel_engine_cs *engine); int intel_init_render_ring_buffer(struct drm_device *dev); int intel_init_bsd_ring_buffer(struct drm_device *dev); @@ -481,9 +481,9 @@ int intel_init_bsd2_ring_buffer(struct drm_device *dev); int intel_init_blt_ring_buffer(struct drm_device *dev); int intel_init_vebox_ring_buffer(struct drm_device *dev); -u64 intel_ring_get_active_head(struct intel_engine_cs *ring); +u64 intel_ring_get_active_head(struct intel_engine_cs *engine); -int init_workarounds_ring(struct intel_engine_cs *ring); +int init_workarounds_ring(struct intel_engine_cs *engine); static inline u32 intel_ring_get_tail(struct intel_ringbuffer *ringbuf) { -- cgit v1.2.3 From 4a570db57c051644093c20eea934ee02b6ea84fd Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Wed, 16 Mar 2016 11:00:38 +0000 Subject: drm/i915: Rename intel_engine_cs struct members below and a couple manual fixups. @@ identifier I, J; @@ struct I { ... - struct intel_engine_cs *J; + struct intel_engine_cs *engine; ... } @@ identifier I, J; @@ struct I { ... - struct intel_engine_cs J; + struct intel_engine_cs engine; ... } @@ struct drm_i915_private *d; @@ ( - d->ring + d->engine ) @@ struct i915_execbuffer_params *p; @@ ( - p->ring + p->engine ) @@ struct intel_ringbuffer *r; @@ ( - r->ring + r->engine ) @@ struct drm_i915_gem_request *req; @@ ( - req->ring + req->engine ) v2: Script missed the tracepoint code - fixed up by hand. Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 2 +- drivers/gpu/drm/i915/i915_dma.c | 8 +-- drivers/gpu/drm/i915/i915_drv.h | 18 +++---- drivers/gpu/drm/i915/i915_gem.c | 38 +++++++------- drivers/gpu/drm/i915/i915_gem_context.c | 24 ++++----- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 24 ++++----- drivers/gpu/drm/i915/i915_gem_gtt.c | 14 ++--- drivers/gpu/drm/i915/i915_gem_render_state.c | 6 +-- drivers/gpu/drm/i915/i915_gpu_error.c | 18 +++---- drivers/gpu/drm/i915/i915_guc_submission.c | 9 ++-- drivers/gpu/drm/i915/i915_irq.c | 40 +++++++-------- drivers/gpu/drm/i915/i915_trace.h | 46 ++++++++--------- drivers/gpu/drm/i915/intel_display.c | 18 +++---- drivers/gpu/drm/i915/intel_lrc.c | 76 ++++++++++++++-------------- drivers/gpu/drm/i915/intel_mocs.c | 2 +- drivers/gpu/drm/i915/intel_overlay.c | 8 +-- drivers/gpu/drm/i915/intel_pm.c | 2 +- drivers/gpu/drm/i915/intel_ringbuffer.c | 74 +++++++++++++-------------- drivers/gpu/drm/i915/intel_ringbuffer.h | 2 +- 19 files changed, 215 insertions(+), 214 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 164e1432d41f..a71ffaaf380d 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -984,7 +984,7 @@ static int i915_hws_info(struct seq_file *m, void *data) const u32 *hws; int i; - engine = &dev_priv->ring[(uintptr_t)node->info_ent->data]; + engine = &dev_priv->engine[(uintptr_t)node->info_ent->data]; hws = engine->status_page.page_addr; if (hws == NULL) return 0; diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 4aa3db61a535..19f605b0cd6d 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -87,16 +87,16 @@ static int i915_getparam(struct drm_device *dev, void *data, value = 1; break; case I915_PARAM_HAS_BSD: - value = intel_ring_initialized(&dev_priv->ring[VCS]); + value = intel_ring_initialized(&dev_priv->engine[VCS]); break; case I915_PARAM_HAS_BLT: - value = intel_ring_initialized(&dev_priv->ring[BCS]); + value = intel_ring_initialized(&dev_priv->engine[BCS]); break; case I915_PARAM_HAS_VEBOX: - value = intel_ring_initialized(&dev_priv->ring[VECS]); + value = intel_ring_initialized(&dev_priv->engine[VECS]); break; case I915_PARAM_HAS_BSD2: - value = intel_ring_initialized(&dev_priv->ring[VCS2]); + value = intel_ring_initialized(&dev_priv->engine[VCS2]); break; case I915_PARAM_HAS_RELAXED_FENCING: value = 1; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 8d87242ce601..0187a560aa51 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1652,7 +1652,7 @@ struct i915_execbuffer_params { uint32_t dispatch_flags; uint32_t args_batch_start_offset; uint64_t batch_obj_vm_offset; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; struct drm_i915_gem_object *batch_obj; struct intel_context *ctx; struct drm_i915_gem_request *request; @@ -1704,7 +1704,7 @@ struct drm_i915_private { wait_queue_head_t gmbus_wait_queue; struct pci_dev *bridge_dev; - struct intel_engine_cs ring[I915_NUM_RINGS]; + struct intel_engine_cs engine[I915_NUM_RINGS]; struct drm_i915_gem_object *semaphore_obj; uint32_t last_seqno, next_seqno; @@ -1969,7 +1969,7 @@ static inline struct drm_i915_private *guc_to_i915(struct intel_guc *guc) /* Iterate over initialised rings */ #define for_each_ring(ring__, dev_priv__, i__) \ for ((i__) = 0; (i__) < I915_NUM_RINGS; (i__)++) \ - for_each_if ((((ring__) = &(dev_priv__)->ring[(i__)]), intel_ring_initialized((ring__)))) + for_each_if ((((ring__) = &(dev_priv__)->engine[(i__)]), intel_ring_initialized((ring__)))) enum hdmi_force_audio { HDMI_AUDIO_OFF_DVI = -2, /* no aux data for HDMI-DVI converter */ @@ -2184,7 +2184,7 @@ struct drm_i915_gem_request { /** On Which ring this request was generated */ struct drm_i915_private *i915; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; /** GEM sequence number associated with the previous request, * when the HWS breadcrumb is equal to this the GPU is processing @@ -2279,7 +2279,7 @@ i915_gem_request_get_seqno(struct drm_i915_gem_request *req) static inline struct intel_engine_cs * i915_gem_request_get_ring(struct drm_i915_gem_request *req) { - return req ? req->ring : NULL; + return req ? req->engine : NULL; } static inline struct drm_i915_gem_request * @@ -2293,7 +2293,7 @@ i915_gem_request_reference(struct drm_i915_gem_request *req) static inline void i915_gem_request_unreference(struct drm_i915_gem_request *req) { - WARN_ON(!mutex_is_locked(&req->ring->dev->struct_mutex)); + WARN_ON(!mutex_is_locked(&req->engine->dev->struct_mutex)); kref_put(&req->ref, i915_gem_request_free); } @@ -2305,7 +2305,7 @@ i915_gem_request_unreference__unlocked(struct drm_i915_gem_request *req) if (!req) return; - dev = req->ring->dev; + dev = req->engine->dev; if (kref_put_mutex(&req->ref, i915_gem_request_free, &dev->struct_mutex)) mutex_unlock(&dev->struct_mutex); } @@ -2949,14 +2949,14 @@ i915_seqno_passed(uint32_t seq1, uint32_t seq2) static inline bool i915_gem_request_started(struct drm_i915_gem_request *req, bool lazy_coherency) { - u32 seqno = req->ring->get_seqno(req->ring, lazy_coherency); + u32 seqno = req->engine->get_seqno(req->engine, lazy_coherency); return i915_seqno_passed(seqno, req->previous_seqno); } static inline bool i915_gem_request_completed(struct drm_i915_gem_request *req, bool lazy_coherency) { - u32 seqno = req->ring->get_seqno(req->ring, lazy_coherency); + u32 seqno = req->engine->get_seqno(req->engine, lazy_coherency); return i915_seqno_passed(seqno, req->seqno); } diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 1119b8f46f09..cd68a86437f1 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1193,7 +1193,7 @@ static int __i915_spin_request(struct drm_i915_gem_request *req, int state) * takes to sleep on a request, on the order of a microsecond. */ - if (req->ring->irq_refcount) + if (req->engine->irq_refcount) return -EBUSY; /* Only spin if we know the GPU is processing this request */ @@ -1381,7 +1381,7 @@ int i915_gem_request_add_to_client(struct drm_i915_gem_request *req, if (req->file_priv) return -EINVAL; - dev_private = req->ring->dev->dev_private; + dev_private = req->engine->dev->dev_private; file_priv = file->driver_priv; spin_lock(&file_priv->mm.lock); @@ -1434,7 +1434,7 @@ static void i915_gem_request_retire(struct drm_i915_gem_request *request) static void __i915_gem_request_retire__upto(struct drm_i915_gem_request *req) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; struct drm_i915_gem_request *tmp; lockdep_assert_held(&engine->dev->struct_mutex); @@ -1466,7 +1466,7 @@ i915_wait_request(struct drm_i915_gem_request *req) BUG_ON(req == NULL); - dev = req->ring->dev; + dev = req->engine->dev; dev_priv = dev->dev_private; interruptible = dev_priv->mm.interruptible; @@ -1505,7 +1505,7 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj, if (ret) return ret; - i = obj->last_write_req->ring->id; + i = obj->last_write_req->engine->id; if (obj->last_read_req[i] == obj->last_write_req) i915_gem_object_retire__read(obj, i); else @@ -1532,7 +1532,7 @@ static void i915_gem_object_retire_request(struct drm_i915_gem_object *obj, struct drm_i915_gem_request *req) { - int ring = req->ring->id; + int ring = req->engine->id; if (obj->last_read_req[ring] == req) i915_gem_object_retire__read(obj, ring); @@ -2423,7 +2423,7 @@ static void i915_gem_object_retire__write(struct drm_i915_gem_object *obj) { RQ_BUG_ON(obj->last_write_req == NULL); - RQ_BUG_ON(!(obj->active & intel_ring_flag(obj->last_write_req->ring))); + RQ_BUG_ON(!(obj->active & intel_ring_flag(obj->last_write_req->engine))); i915_gem_request_assign(&obj->last_write_req, NULL); intel_fb_obj_flush(obj, true, ORIGIN_CS); @@ -2440,7 +2440,7 @@ i915_gem_object_retire__read(struct drm_i915_gem_object *obj, int ring) list_del_init(&obj->ring_list[ring]); i915_gem_request_assign(&obj->last_read_req[ring], NULL); - if (obj->last_write_req && obj->last_write_req->ring->id == ring) + if (obj->last_write_req && obj->last_write_req->engine->id == ring) i915_gem_object_retire__write(obj); obj->active &= ~(1 << ring); @@ -2551,7 +2551,7 @@ void __i915_add_request(struct drm_i915_gem_request *request, if (WARN_ON(request == NULL)) return; - engine = request->ring; + engine = request->engine; dev_priv = engine->dev->dev_private; ringbuf = request->ringbuf; @@ -2680,7 +2680,7 @@ void i915_gem_request_free(struct kref *req_ref) if (ctx) { if (i915.enable_execlists && ctx != req->i915->kernel_context) - intel_lr_context_unpin(ctx, req->ring); + intel_lr_context_unpin(ctx, req->engine); i915_gem_context_unreference(ctx); } @@ -2712,7 +2712,7 @@ __i915_gem_request_alloc(struct intel_engine_cs *engine, kref_init(&req->ref); req->i915 = dev_priv; - req->ring = engine; + req->engine = engine; req->ctx = ctx; i915_gem_context_reference(req->ctx); @@ -4364,10 +4364,10 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, req = obj->last_read_req[i]; if (req) - args->busy |= 1 << (16 + req->ring->exec_id); + args->busy |= 1 << (16 + req->engine->exec_id); } if (obj->last_write_req) - args->busy |= obj->last_write_req->ring->exec_id; + args->busy |= obj->last_write_req->engine->exec_id; } unref: @@ -4697,7 +4697,7 @@ err: int i915_gem_l3_remap(struct drm_i915_gem_request *req, int slice) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; u32 *remap_info = dev_priv->l3_parity.remap_info[slice]; @@ -4814,13 +4814,13 @@ int i915_gem_init_rings(struct drm_device *dev) return 0; cleanup_vebox_ring: - intel_cleanup_ring_buffer(&dev_priv->ring[VECS]); + intel_cleanup_ring_buffer(&dev_priv->engine[VECS]); cleanup_blt_ring: - intel_cleanup_ring_buffer(&dev_priv->ring[BCS]); + intel_cleanup_ring_buffer(&dev_priv->engine[BCS]); cleanup_bsd_ring: - intel_cleanup_ring_buffer(&dev_priv->ring[VCS]); + intel_cleanup_ring_buffer(&dev_priv->engine[VCS]); cleanup_render_ring: - intel_cleanup_ring_buffer(&dev_priv->ring[RCS]); + intel_cleanup_ring_buffer(&dev_priv->engine[RCS]); return ret; } @@ -5056,7 +5056,7 @@ i915_gem_load_init(struct drm_device *dev) INIT_LIST_HEAD(&dev_priv->mm.bound_list); INIT_LIST_HEAD(&dev_priv->mm.fence_list); for (i = 0; i < I915_NUM_RINGS; i++) - init_ring_lists(&dev_priv->ring[i]); + init_ring_lists(&dev_priv->engine[i]); for (i = 0; i < I915_MAX_NUM_FENCES; i++) INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list); INIT_DELAYED_WORK(&dev_priv->mm.retire_work, diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 44f582988094..6c325e4c7556 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -346,7 +346,7 @@ void i915_gem_context_reset(struct drm_device *dev) } for (i = 0; i < I915_NUM_RINGS; i++) { - struct intel_engine_cs *engine = &dev_priv->ring[i]; + struct intel_engine_cs *engine = &dev_priv->engine[i]; if (engine->last_context) { i915_gem_context_unpin(engine->last_context, engine); @@ -421,13 +421,13 @@ void i915_gem_context_fini(struct drm_device *dev) * to default context. So we need to unreference the base object once * to offset the do_switch part, so that i915_gem_context_unreference() * can then free the base object correctly. */ - WARN_ON(!dev_priv->ring[RCS].last_context); + WARN_ON(!dev_priv->engine[RCS].last_context); i915_gem_object_ggtt_unpin(dctx->legacy_hw_ctx.rcs_state); } for (i = I915_NUM_RINGS; --i >= 0;) { - struct intel_engine_cs *engine = &dev_priv->ring[i]; + struct intel_engine_cs *engine = &dev_priv->engine[i]; if (engine->last_context) { i915_gem_context_unpin(engine->last_context, engine); @@ -441,7 +441,7 @@ void i915_gem_context_fini(struct drm_device *dev) int i915_gem_context_enable(struct drm_i915_gem_request *req) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; int ret; if (i915.enable_execlists) { @@ -510,7 +510,7 @@ i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id) static inline int mi_set_context(struct drm_i915_gem_request *req, u32 hw_flags) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; u32 flags = hw_flags | MI_MM_SPACE_GTT; const int num_rings = /* Use an extended w/a on ivb+ if signalling from other rings */ @@ -625,7 +625,7 @@ needs_pd_load_pre(struct intel_engine_cs *engine, struct intel_context *to) if (INTEL_INFO(engine->dev)->gen < 8) return true; - if (engine != &dev_priv->ring[RCS]) + if (engine != &dev_priv->engine[RCS]) return true; return false; @@ -643,7 +643,7 @@ needs_pd_load_post(struct intel_engine_cs *engine, struct intel_context *to, if (!IS_GEN8(engine->dev)) return false; - if (engine != &dev_priv->ring[RCS]) + if (engine != &dev_priv->engine[RCS]) return false; if (hw_flags & MI_RESTORE_INHIBIT) @@ -655,14 +655,14 @@ needs_pd_load_post(struct intel_engine_cs *engine, struct intel_context *to, static int do_switch(struct drm_i915_gem_request *req) { struct intel_context *to = req->ctx; - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; struct drm_i915_private *dev_priv = engine->dev->dev_private; struct intel_context *from = engine->last_context; u32 hw_flags = 0; bool uninitialized = false; int ret, i; - if (from != NULL && engine == &dev_priv->ring[RCS]) { + if (from != NULL && engine == &dev_priv->engine[RCS]) { BUG_ON(from->legacy_hw_ctx.rcs_state == NULL); BUG_ON(!i915_gem_obj_is_pinned(from->legacy_hw_ctx.rcs_state)); } @@ -671,7 +671,7 @@ static int do_switch(struct drm_i915_gem_request *req) return 0; /* Trying to pin first makes error handling easier. */ - if (engine == &dev_priv->ring[RCS]) { + if (engine == &dev_priv->engine[RCS]) { ret = i915_gem_obj_ggtt_pin(to->legacy_hw_ctx.rcs_state, get_context_alignment(engine->dev), 0); @@ -700,7 +700,7 @@ static int do_switch(struct drm_i915_gem_request *req) to->ppgtt->pd_dirty_rings &= ~intel_ring_flag(engine); } - if (engine != &dev_priv->ring[RCS]) { + if (engine != &dev_priv->engine[RCS]) { if (from) i915_gem_context_unreference(from); goto done; @@ -828,7 +828,7 @@ unpin_out: */ int i915_switch_context(struct drm_i915_gem_request *req) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; struct drm_i915_private *dev_priv = engine->dev->dev_private; WARN_ON(i915.enable_execlists); diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index f94d756828e8..bb1ed8c4bcb4 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -942,7 +942,7 @@ static int i915_gem_execbuffer_move_to_gpu(struct drm_i915_gem_request *req, struct list_head *vmas) { - const unsigned other_rings = ~intel_ring_flag(req->ring); + const unsigned other_rings = ~intel_ring_flag(req->engine); struct i915_vma *vma; uint32_t flush_domains = 0; bool flush_chipset = false; @@ -952,7 +952,7 @@ i915_gem_execbuffer_move_to_gpu(struct drm_i915_gem_request *req, struct drm_i915_gem_object *obj = vma->obj; if (obj->active & other_rings) { - ret = i915_gem_object_sync(obj, req->ring, &req); + ret = i915_gem_object_sync(obj, req->engine, &req); if (ret) return ret; } @@ -964,7 +964,7 @@ i915_gem_execbuffer_move_to_gpu(struct drm_i915_gem_request *req, } if (flush_chipset) - i915_gem_chipset_flush(req->ring->dev); + i915_gem_chipset_flush(req->engine->dev); if (flush_domains & I915_GEM_DOMAIN_GTT) wmb(); @@ -1140,7 +1140,7 @@ void i915_gem_execbuffer_retire_commands(struct i915_execbuffer_params *params) { /* Unconditionally force add_request to emit a full flush. */ - params->ring->gpu_caches_dirty = true; + params->engine->gpu_caches_dirty = true; /* Add a breadcrumb for the completion of the batch buffer */ __i915_add_request(params->request, params->batch_obj, true); @@ -1150,11 +1150,11 @@ static int i915_reset_gen7_sol_offsets(struct drm_device *dev, struct drm_i915_gem_request *req) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; struct drm_i915_private *dev_priv = dev->dev_private; int ret, i; - if (!IS_GEN7(dev) || engine != &dev_priv->ring[RCS]) { + if (!IS_GEN7(dev) || engine != &dev_priv->engine[RCS]) { DRM_DEBUG("sol reset is gen7/rcs only\n"); return -EINVAL; } @@ -1233,7 +1233,7 @@ i915_gem_ringbuffer_submission(struct i915_execbuffer_params *params, struct list_head *vmas) { struct drm_device *dev = params->dev; - struct intel_engine_cs *engine = params->ring; + struct intel_engine_cs *engine = params->engine; struct drm_i915_private *dev_priv = dev->dev_private; u64 exec_start, exec_len; int instp_mode; @@ -1257,7 +1257,7 @@ i915_gem_ringbuffer_submission(struct i915_execbuffer_params *params, case I915_EXEC_CONSTANTS_REL_GENERAL: case I915_EXEC_CONSTANTS_ABSOLUTE: case I915_EXEC_CONSTANTS_REL_SURFACE: - if (instp_mode != 0 && engine != &dev_priv->ring[RCS]) { + if (instp_mode != 0 && engine != &dev_priv->engine[RCS]) { DRM_DEBUG("non-0 rel constants mode on non-RCS\n"); return -EINVAL; } @@ -1284,7 +1284,7 @@ i915_gem_ringbuffer_submission(struct i915_execbuffer_params *params, return -EINVAL; } - if (engine == &dev_priv->ring[RCS] && + if (engine == &dev_priv->engine[RCS] && instp_mode != dev_priv->relative_constants_mode) { ret = intel_ring_begin(params->request, 4); if (ret) @@ -1412,9 +1412,9 @@ eb_select_ring(struct drm_i915_private *dev_priv, return -EINVAL; } - *ring = &dev_priv->ring[_VCS(bsd_idx)]; + *ring = &dev_priv->engine[_VCS(bsd_idx)]; } else { - *ring = &dev_priv->ring[user_ring_map[user_ring_id]]; + *ring = &dev_priv->engine[user_ring_map[user_ring_id]]; } if (!intel_ring_initialized(*ring)) { @@ -1632,7 +1632,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, */ params->dev = dev; params->file = file; - params->ring = engine; + params->engine = engine; params->dispatch_flags = dispatch_flags; params->batch_obj = batch_obj; params->ctx = ctx; diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 1bc77791bc96..ab54396029ca 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -658,7 +658,7 @@ static int gen8_write_pdp(struct drm_i915_gem_request *req, unsigned entry, dma_addr_t addr) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; int ret; BUG_ON(entry >= 4); @@ -1650,7 +1650,7 @@ static uint32_t get_pd_offset(struct i915_hw_ppgtt *ppgtt) static int hsw_mm_switch(struct i915_hw_ppgtt *ppgtt, struct drm_i915_gem_request *req) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; int ret; /* NB: TLBs must be flushed and invalidated before a switch */ @@ -1676,7 +1676,7 @@ static int hsw_mm_switch(struct i915_hw_ppgtt *ppgtt, static int vgpu_mm_switch(struct i915_hw_ppgtt *ppgtt, struct drm_i915_gem_request *req) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; struct drm_i915_private *dev_priv = to_i915(ppgtt->base.dev); I915_WRITE(RING_PP_DIR_DCLV(engine), PP_DIR_DCLV_2G); @@ -1687,7 +1687,7 @@ static int vgpu_mm_switch(struct i915_hw_ppgtt *ppgtt, static int gen7_mm_switch(struct i915_hw_ppgtt *ppgtt, struct drm_i915_gem_request *req) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; int ret; /* NB: TLBs must be flushed and invalidated before a switch */ @@ -1720,7 +1720,7 @@ static int gen7_mm_switch(struct i915_hw_ppgtt *ppgtt, static int gen6_mm_switch(struct i915_hw_ppgtt *ppgtt, struct drm_i915_gem_request *req) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; struct drm_device *dev = ppgtt->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -2192,7 +2192,7 @@ int i915_ppgtt_init_hw(struct drm_device *dev) int i915_ppgtt_init_ring(struct drm_i915_gem_request *req) { - struct drm_i915_private *dev_priv = req->ring->dev->dev_private; + struct drm_i915_private *dev_priv = req->engine->dev->dev_private; struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; if (i915.enable_execlists) @@ -2309,7 +2309,7 @@ void i915_check_and_clear_faults(struct drm_device *dev) fault_reg & ~RING_FAULT_VALID); } } - POSTING_READ(RING_FAULT_REG(&dev_priv->ring[RCS])); + POSTING_READ(RING_FAULT_REG(&dev_priv->engine[RCS])); } static void i915_ggtt_flush(struct drm_i915_private *dev_priv) diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/i915/i915_gem_render_state.c index b21f72ec895c..71611bf21fca 100644 --- a/drivers/gpu/drm/i915/i915_gem_render_state.c +++ b/drivers/gpu/drm/i915/i915_gem_render_state.c @@ -198,21 +198,21 @@ int i915_gem_render_state_init(struct drm_i915_gem_request *req) struct render_state so; int ret; - ret = i915_gem_render_state_prepare(req->ring, &so); + ret = i915_gem_render_state_prepare(req->engine, &so); if (ret) return ret; if (so.rodata == NULL) return 0; - ret = req->ring->dispatch_execbuffer(req, so.ggtt_offset, + ret = req->engine->dispatch_execbuffer(req, so.ggtt_offset, so.rodata->batch_items * 4, I915_DISPATCH_SECURE); if (ret) goto out; if (so.aux_batch_size > 8) { - ret = req->ring->dispatch_execbuffer(req, + ret = req->engine->dispatch_execbuffer(req, (so.ggtt_offset + so.aux_batch_offset), so.aux_batch_size, diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 029ed4031edf..a73f7057e875 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -431,7 +431,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, for (i = 0; i < ARRAY_SIZE(error->ring); i++) { obj = error->ring[i].batchbuffer; if (obj) { - err_puts(m, dev_priv->ring[i].name); + err_puts(m, dev_priv->engine[i].name); if (error->ring[i].pid != -1) err_printf(m, " (submitted by %s [%d])", error->ring[i].comm, @@ -445,14 +445,14 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, obj = error->ring[i].wa_batchbuffer; if (obj) { err_printf(m, "%s (w/a) --- gtt_offset = 0x%08x\n", - dev_priv->ring[i].name, + dev_priv->engine[i].name, lower_32_bits(obj->gtt_offset)); print_error_obj(m, obj); } if (error->ring[i].num_requests) { err_printf(m, "%s --- %d requests\n", - dev_priv->ring[i].name, + dev_priv->engine[i].name, error->ring[i].num_requests); for (j = 0; j < error->ring[i].num_requests; j++) { err_printf(m, " seqno 0x%08x, emitted %ld, tail 0x%08x\n", @@ -464,7 +464,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, if ((obj = error->ring[i].ringbuffer)) { err_printf(m, "%s --- ringbuffer = 0x%08x\n", - dev_priv->ring[i].name, + dev_priv->engine[i].name, lower_32_bits(obj->gtt_offset)); print_error_obj(m, obj); } @@ -478,7 +478,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, hws_page = &obj->pages[LRC_PPHWSP_PN][0]; } err_printf(m, "%s --- HW Status = 0x%08llx\n", - dev_priv->ring[i].name, hws_offset); + dev_priv->engine[i].name, hws_offset); offset = 0; for (elt = 0; elt < PAGE_SIZE/16; elt += 4) { err_printf(m, "[%04x] %08x %08x %08x %08x\n", @@ -495,12 +495,12 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, if (obj) { u64 wa_ctx_offset = obj->gtt_offset; u32 *wa_ctx_page = &obj->pages[0][0]; - struct intel_engine_cs *engine = &dev_priv->ring[RCS]; + struct intel_engine_cs *engine = &dev_priv->engine[RCS]; u32 wa_ctx_size = (engine->wa_ctx.indirect_ctx.size + engine->wa_ctx.per_ctx.size); err_printf(m, "%s --- WA ctx batch buffer = 0x%08llx\n", - dev_priv->ring[i].name, wa_ctx_offset); + dev_priv->engine[i].name, wa_ctx_offset); offset = 0; for (elt = 0; elt < wa_ctx_size; elt += 4) { err_printf(m, "[%04x] %08x %08x %08x %08x\n", @@ -515,7 +515,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, if ((obj = error->ring[i].ctx)) { err_printf(m, "%s --- HW Context = 0x%08x\n", - dev_priv->ring[i].name, + dev_priv->engine[i].name, lower_32_bits(obj->gtt_offset)); print_error_obj(m, obj); } @@ -1020,7 +1020,7 @@ static void i915_gem_record_rings(struct drm_device *dev, int i, count; for (i = 0; i < I915_NUM_RINGS; i++) { - struct intel_engine_cs *engine = &dev_priv->ring[i]; + struct intel_engine_cs *engine = &dev_priv->engine[i]; struct intel_ringbuffer *rbuf; error->ring[i].pid = -1; diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 15a4beb387d4..ed4f0762b263 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -542,11 +542,12 @@ static int guc_add_workqueue_item(struct i915_guc_client *gc, wq_len = sizeof(struct guc_wq_item) / sizeof(u32) - 1; wqi->header = WQ_TYPE_INORDER | (wq_len << WQ_LEN_SHIFT) | - (rq->ring->guc_id << WQ_TARGET_SHIFT) | + (rq->engine->guc_id << WQ_TARGET_SHIFT) | WQ_NO_WCFLUSH_WAIT; /* The GuC wants only the low-order word of the context descriptor */ - wqi->context_desc = (u32)intel_lr_context_descriptor(rq->ctx, rq->ring); + wqi->context_desc = (u32)intel_lr_context_descriptor(rq->ctx, + rq->engine); /* The GuC firmware wants the tail index in QWords, not bytes */ tail = rq->ringbuf->tail >> 3; @@ -569,7 +570,7 @@ int i915_guc_submit(struct i915_guc_client *client, struct drm_i915_gem_request *rq) { struct intel_guc *guc = client->guc; - unsigned int engine_id = rq->ring->guc_id; + unsigned int engine_id = rq->engine->guc_id; int q_ret, b_ret; q_ret = guc_add_workqueue_item(client, rq); @@ -867,7 +868,7 @@ static void guc_create_ads(struct intel_guc *guc) * so its address won't change after we've told the GuC where * to find it. */ - engine = &dev_priv->ring[RCS]; + engine = &dev_priv->engine[RCS]; ads->golden_context_lrca = engine->status_page.gfx_addr; for_each_ring(engine, dev_priv, i) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 64658961a7e5..6b7bee59e0c7 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1291,9 +1291,9 @@ static void ilk_gt_irq_handler(struct drm_device *dev, { if (gt_iir & (GT_RENDER_USER_INTERRUPT | GT_RENDER_PIPECTL_NOTIFY_INTERRUPT)) - notify_ring(&dev_priv->ring[RCS]); + notify_ring(&dev_priv->engine[RCS]); if (gt_iir & ILK_BSD_USER_INTERRUPT) - notify_ring(&dev_priv->ring[VCS]); + notify_ring(&dev_priv->engine[VCS]); } static void snb_gt_irq_handler(struct drm_device *dev, @@ -1303,11 +1303,11 @@ static void snb_gt_irq_handler(struct drm_device *dev, if (gt_iir & (GT_RENDER_USER_INTERRUPT | GT_RENDER_PIPECTL_NOTIFY_INTERRUPT)) - notify_ring(&dev_priv->ring[RCS]); + notify_ring(&dev_priv->engine[RCS]); if (gt_iir & GT_BSD_USER_INTERRUPT) - notify_ring(&dev_priv->ring[VCS]); + notify_ring(&dev_priv->engine[VCS]); if (gt_iir & GT_BLT_USER_INTERRUPT) - notify_ring(&dev_priv->ring[BCS]); + notify_ring(&dev_priv->engine[BCS]); if (gt_iir & (GT_BLT_CS_ERROR_INTERRUPT | GT_BSD_CS_ERROR_INTERRUPT | @@ -1338,11 +1338,11 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_i915_private *dev_priv, I915_WRITE_FW(GEN8_GT_IIR(0), iir); ret = IRQ_HANDLED; - gen8_cs_irq_handler(&dev_priv->ring[RCS], - iir, GEN8_RCS_IRQ_SHIFT); + gen8_cs_irq_handler(&dev_priv->engine[RCS], + iir, GEN8_RCS_IRQ_SHIFT); - gen8_cs_irq_handler(&dev_priv->ring[BCS], - iir, GEN8_BCS_IRQ_SHIFT); + gen8_cs_irq_handler(&dev_priv->engine[BCS], + iir, GEN8_BCS_IRQ_SHIFT); } else DRM_ERROR("The master control interrupt lied (GT0)!\n"); } @@ -1353,11 +1353,11 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_i915_private *dev_priv, I915_WRITE_FW(GEN8_GT_IIR(1), iir); ret = IRQ_HANDLED; - gen8_cs_irq_handler(&dev_priv->ring[VCS], - iir, GEN8_VCS1_IRQ_SHIFT); + gen8_cs_irq_handler(&dev_priv->engine[VCS], + iir, GEN8_VCS1_IRQ_SHIFT); - gen8_cs_irq_handler(&dev_priv->ring[VCS2], - iir, GEN8_VCS2_IRQ_SHIFT); + gen8_cs_irq_handler(&dev_priv->engine[VCS2], + iir, GEN8_VCS2_IRQ_SHIFT); } else DRM_ERROR("The master control interrupt lied (GT1)!\n"); } @@ -1368,8 +1368,8 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_i915_private *dev_priv, I915_WRITE_FW(GEN8_GT_IIR(3), iir); ret = IRQ_HANDLED; - gen8_cs_irq_handler(&dev_priv->ring[VECS], - iir, GEN8_VECS_IRQ_SHIFT); + gen8_cs_irq_handler(&dev_priv->engine[VECS], + iir, GEN8_VECS_IRQ_SHIFT); } else DRM_ERROR("The master control interrupt lied (GT3)!\n"); } @@ -1629,7 +1629,7 @@ static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir) if (HAS_VEBOX(dev_priv->dev)) { if (pm_iir & PM_VEBOX_USER_INTERRUPT) - notify_ring(&dev_priv->ring[VECS]); + notify_ring(&dev_priv->engine[VECS]); if (pm_iir & PM_VEBOX_CS_ERROR_INTERRUPT) DRM_DEBUG("Command parser error, pm_iir 0x%08x\n", pm_iir); @@ -4042,7 +4042,7 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg) new_iir = I915_READ16(IIR); /* Flush posted writes */ if (iir & I915_USER_INTERRUPT) - notify_ring(&dev_priv->ring[RCS]); + notify_ring(&dev_priv->engine[RCS]); for_each_pipe(dev_priv, pipe) { int plane = pipe; @@ -4238,7 +4238,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) new_iir = I915_READ(IIR); /* Flush posted writes */ if (iir & I915_USER_INTERRUPT) - notify_ring(&dev_priv->ring[RCS]); + notify_ring(&dev_priv->engine[RCS]); for_each_pipe(dev_priv, pipe) { int plane = pipe; @@ -4468,9 +4468,9 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) new_iir = I915_READ(IIR); /* Flush posted writes */ if (iir & I915_USER_INTERRUPT) - notify_ring(&dev_priv->ring[RCS]); + notify_ring(&dev_priv->engine[RCS]); if (iir & I915_BSD_USER_INTERRUPT) - notify_ring(&dev_priv->ring[VCS]); + notify_ring(&dev_priv->engine[VCS]); for_each_pipe(dev_priv, pipe) { if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS && diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index fa09e5581137..923cf6e4d8b6 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h @@ -464,7 +464,7 @@ TRACE_EVENT(i915_gem_ring_sync_to, TP_fast_assign( __entry->dev = from->dev->primary->index; __entry->sync_from = from->id; - __entry->sync_to = to_req->ring->id; + __entry->sync_to = to_req->engine->id; __entry->seqno = i915_gem_request_get_seqno(req); ), @@ -486,13 +486,13 @@ TRACE_EVENT(i915_gem_ring_dispatch, ), TP_fast_assign( - struct intel_engine_cs *ring = + struct intel_engine_cs *engine = i915_gem_request_get_ring(req); - __entry->dev = ring->dev->primary->index; - __entry->ring = ring->id; + __entry->dev = engine->dev->primary->index; + __entry->ring = engine->id; __entry->seqno = i915_gem_request_get_seqno(req); __entry->flags = flags; - i915_trace_irq_get(ring, req); + i915_trace_irq_get(engine, req); ), TP_printk("dev=%u, ring=%u, seqno=%u, flags=%x", @@ -511,8 +511,8 @@ TRACE_EVENT(i915_gem_ring_flush, ), TP_fast_assign( - __entry->dev = req->ring->dev->primary->index; - __entry->ring = req->ring->id; + __entry->dev = req->engine->dev->primary->index; + __entry->ring = req->engine->id; __entry->invalidate = invalidate; __entry->flush = flush; ), @@ -533,10 +533,10 @@ DECLARE_EVENT_CLASS(i915_gem_request, ), TP_fast_assign( - struct intel_engine_cs *ring = + struct intel_engine_cs *engine = i915_gem_request_get_ring(req); - __entry->dev = ring->dev->primary->index; - __entry->ring = ring->id; + __entry->dev = engine->dev->primary->index; + __entry->ring = engine->id; __entry->seqno = i915_gem_request_get_seqno(req); ), @@ -550,8 +550,8 @@ DEFINE_EVENT(i915_gem_request, i915_gem_request_add, ); TRACE_EVENT(i915_gem_request_notify, - TP_PROTO(struct intel_engine_cs *ring), - TP_ARGS(ring), + TP_PROTO(struct intel_engine_cs *engine), + TP_ARGS(engine), TP_STRUCT__entry( __field(u32, dev) @@ -560,9 +560,9 @@ TRACE_EVENT(i915_gem_request_notify, ), TP_fast_assign( - __entry->dev = ring->dev->primary->index; - __entry->ring = ring->id; - __entry->seqno = ring->get_seqno(ring, false); + __entry->dev = engine->dev->primary->index; + __entry->ring = engine->id; + __entry->seqno = engine->get_seqno(engine, false); ), TP_printk("dev=%u, ring=%u, seqno=%u", @@ -597,13 +597,13 @@ TRACE_EVENT(i915_gem_request_wait_begin, * less desirable. */ TP_fast_assign( - struct intel_engine_cs *ring = + struct intel_engine_cs *engine = i915_gem_request_get_ring(req); - __entry->dev = ring->dev->primary->index; - __entry->ring = ring->id; + __entry->dev = engine->dev->primary->index; + __entry->ring = engine->id; __entry->seqno = i915_gem_request_get_seqno(req); __entry->blocking = - mutex_is_locked(&ring->dev->struct_mutex); + mutex_is_locked(&engine->dev->struct_mutex); ), TP_printk("dev=%u, ring=%u, seqno=%u, blocking=%s", @@ -777,9 +777,9 @@ DEFINE_EVENT(i915_context, i915_context_free, * called only if full ppgtt is enabled. */ TRACE_EVENT(switch_mm, - TP_PROTO(struct intel_engine_cs *ring, struct intel_context *to), + TP_PROTO(struct intel_engine_cs *engine, struct intel_context *to), - TP_ARGS(ring, to), + TP_ARGS(engine, to), TP_STRUCT__entry( __field(u32, ring) @@ -789,10 +789,10 @@ TRACE_EVENT(switch_mm, ), TP_fast_assign( - __entry->ring = ring->id; + __entry->ring = engine->id; __entry->to = to; __entry->vm = to->ppgtt? &to->ppgtt->base : NULL; - __entry->dev = ring->dev->primary->index; + __entry->dev = engine->dev->primary->index; ), TP_printk("dev=%u, ring=%u, ctx=%p, ctx_vm=%p", diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 317b55b0b596..f271b0f706e4 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10984,7 +10984,7 @@ static int intel_gen2_queue_flip(struct drm_device *dev, struct drm_i915_gem_request *req, uint32_t flags) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); u32 flip_mask; int ret; @@ -11019,7 +11019,7 @@ static int intel_gen3_queue_flip(struct drm_device *dev, struct drm_i915_gem_request *req, uint32_t flags) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); u32 flip_mask; int ret; @@ -11051,7 +11051,7 @@ static int intel_gen4_queue_flip(struct drm_device *dev, struct drm_i915_gem_request *req, uint32_t flags) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); uint32_t pf, pipesrc; @@ -11090,7 +11090,7 @@ static int intel_gen6_queue_flip(struct drm_device *dev, struct drm_i915_gem_request *req, uint32_t flags) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); uint32_t pf, pipesrc; @@ -11126,7 +11126,7 @@ static int intel_gen7_queue_flip(struct drm_device *dev, struct drm_i915_gem_request *req, uint32_t flags) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); uint32_t plane_bit = 0; int len, ret; @@ -11575,18 +11575,18 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, work->flip_count = I915_READ(PIPE_FLIPCOUNT_G4X(pipe)) + 1; if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) { - engine = &dev_priv->ring[BCS]; + engine = &dev_priv->engine[BCS]; if (obj->tiling_mode != intel_fb_obj(work->old_fb)->tiling_mode) /* vlv: DISPLAY_FLIP fails to change tiling */ engine = NULL; } else if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) { - engine = &dev_priv->ring[BCS]; + engine = &dev_priv->engine[BCS]; } else if (INTEL_INFO(dev)->gen >= 7) { engine = i915_gem_request_get_ring(obj->last_write_req); if (engine == NULL || engine->id != RCS) - engine = &dev_priv->ring[BCS]; + engine = &dev_priv->engine[BCS]; } else { - engine = &dev_priv->ring[RCS]; + engine = &dev_priv->engine[RCS]; } mmio_flip = use_mmio_flip(engine, obj); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 25514e91479a..bbcc31f4b15d 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -360,19 +360,19 @@ static void execlists_elsp_write(struct drm_i915_gem_request *rq0, struct drm_i915_gem_request *rq1) { - struct intel_engine_cs *engine = rq0->ring; + struct intel_engine_cs *engine = rq0->engine; struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; uint64_t desc[2]; if (rq1) { - desc[1] = intel_lr_context_descriptor(rq1->ctx, rq1->ring); + desc[1] = intel_lr_context_descriptor(rq1->ctx, rq1->engine); rq1->elsp_submitted++; } else { desc[1] = 0; } - desc[0] = intel_lr_context_descriptor(rq0->ctx, rq0->ring); + desc[0] = intel_lr_context_descriptor(rq0->ctx, rq0->engine); rq0->elsp_submitted++; /* You must always write both descriptors in the order below. */ @@ -398,7 +398,7 @@ execlists_update_context_pdps(struct i915_hw_ppgtt *ppgtt, u32 *reg_state) static void execlists_update_context(struct drm_i915_gem_request *rq) { - struct intel_engine_cs *engine = rq->ring; + struct intel_engine_cs *engine = rq->engine; struct i915_hw_ppgtt *ppgtt = rq->ctx->ppgtt; uint32_t *reg_state = rq->ctx->engine[engine->id].lrc_reg_state; @@ -611,7 +611,7 @@ void intel_lrc_irq_handler(struct intel_engine_cs *engine) static void execlists_context_queue(struct drm_i915_gem_request *request) { - struct intel_engine_cs *engine = request->ring; + struct intel_engine_cs *engine = request->engine; struct drm_i915_gem_request *cursor; int num_elements = 0; @@ -650,7 +650,7 @@ static void execlists_context_queue(struct drm_i915_gem_request *request) static int logical_ring_invalidate_all_caches(struct drm_i915_gem_request *req) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; uint32_t flush_domains; int ret; @@ -669,7 +669,7 @@ static int logical_ring_invalidate_all_caches(struct drm_i915_gem_request *req) static int execlists_move_to_gpu(struct drm_i915_gem_request *req, struct list_head *vmas) { - const unsigned other_rings = ~intel_ring_flag(req->ring); + const unsigned other_rings = ~intel_ring_flag(req->engine); struct i915_vma *vma; uint32_t flush_domains = 0; bool flush_chipset = false; @@ -679,7 +679,7 @@ static int execlists_move_to_gpu(struct drm_i915_gem_request *req, struct drm_i915_gem_object *obj = vma->obj; if (obj->active & other_rings) { - ret = i915_gem_object_sync(obj, req->ring, &req); + ret = i915_gem_object_sync(obj, req->engine, &req); if (ret) return ret; } @@ -703,7 +703,7 @@ int intel_logical_ring_alloc_request_extras(struct drm_i915_gem_request *request { int ret = 0; - request->ringbuf = request->ctx->engine[request->ring->id].ringbuf; + request->ringbuf = request->ctx->engine[request->engine->id].ringbuf; if (i915.enable_guc_submission) { /* @@ -719,7 +719,7 @@ int intel_logical_ring_alloc_request_extras(struct drm_i915_gem_request *request } if (request->ctx != request->i915->kernel_context) - ret = intel_lr_context_pin(request->ctx, request->ring); + ret = intel_lr_context_pin(request->ctx, request->engine); return ret; } @@ -728,7 +728,7 @@ static int logical_ring_wait_for_space(struct drm_i915_gem_request *req, int bytes) { struct intel_ringbuffer *ringbuf = req->ringbuf; - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; struct drm_i915_gem_request *target; unsigned space; int ret; @@ -780,7 +780,7 @@ intel_logical_ring_advance_and_submit(struct drm_i915_gem_request *request) { struct intel_ringbuffer *ringbuf = request->ringbuf; struct drm_i915_private *dev_priv = request->i915; - struct intel_engine_cs *engine = request->ring; + struct intel_engine_cs *engine = request->engine; intel_logical_ring_advance(ringbuf); request->tail = ringbuf->tail; @@ -897,7 +897,7 @@ int intel_logical_ring_begin(struct drm_i915_gem_request *req, int num_dwords) int ret; WARN_ON(req == NULL); - dev_priv = req->ring->dev->dev_private; + dev_priv = req->engine->dev->dev_private; ret = i915_gem_check_wedge(&dev_priv->gpu_error, dev_priv->mm.interruptible); @@ -949,7 +949,7 @@ int intel_execlists_submission(struct i915_execbuffer_params *params, struct list_head *vmas) { struct drm_device *dev = params->dev; - struct intel_engine_cs *engine = params->ring; + struct intel_engine_cs *engine = params->engine; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_ringbuffer *ringbuf = params->ctx->engine[engine->id].ringbuf; u64 exec_start; @@ -963,7 +963,7 @@ int intel_execlists_submission(struct i915_execbuffer_params *params, case I915_EXEC_CONSTANTS_REL_GENERAL: case I915_EXEC_CONSTANTS_ABSOLUTE: case I915_EXEC_CONSTANTS_REL_SURFACE: - if (instp_mode != 0 && engine != &dev_priv->ring[RCS]) { + if (instp_mode != 0 && engine != &dev_priv->engine[RCS]) { DRM_DEBUG("non-0 rel constants mode on non-RCS\n"); return -EINVAL; } @@ -992,7 +992,7 @@ int intel_execlists_submission(struct i915_execbuffer_params *params, if (ret) return ret; - if (engine == &dev_priv->ring[RCS] && + if (engine == &dev_priv->engine[RCS] && instp_mode != dev_priv->relative_constants_mode) { ret = intel_logical_ring_begin(params->request, 4); if (ret) @@ -1073,7 +1073,7 @@ void intel_logical_ring_stop(struct intel_engine_cs *engine) int logical_ring_flush_all_caches(struct drm_i915_gem_request *req) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; int ret; if (!engine->gpu_caches_dirty) @@ -1174,7 +1174,7 @@ void intel_lr_context_unpin(struct intel_context *ctx, static int intel_logical_ring_workarounds_emit(struct drm_i915_gem_request *req) { int ret, i; - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; struct intel_ringbuffer *ringbuf = req->ringbuf; struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -1647,7 +1647,7 @@ static int gen9_init_render_ring(struct intel_engine_cs *engine) static int intel_logical_ring_emit_pdps(struct drm_i915_gem_request *req) { struct i915_hw_ppgtt *ppgtt = req->ctx->ppgtt; - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; struct intel_ringbuffer *ringbuf = req->ringbuf; const int num_lri_cmds = GEN8_LEGACY_PDPES * 2; int i, ret; @@ -1688,7 +1688,7 @@ static int gen8_emit_bb_start(struct drm_i915_gem_request *req, * not idle). PML4 is allocated during ppgtt init so this is * not needed in 48-bit.*/ if (req->ctx->ppgtt && - (intel_ring_flag(req->ring) & req->ctx->ppgtt->pd_dirty_rings)) { + (intel_ring_flag(req->engine) & req->ctx->ppgtt->pd_dirty_rings)) { if (!USES_FULL_48BIT_PPGTT(req->i915) && !intel_vgpu_active(req->i915->dev)) { ret = intel_logical_ring_emit_pdps(req); @@ -1696,7 +1696,7 @@ static int gen8_emit_bb_start(struct drm_i915_gem_request *req, return ret; } - req->ctx->ppgtt->pd_dirty_rings &= ~intel_ring_flag(req->ring); + req->ctx->ppgtt->pd_dirty_rings &= ~intel_ring_flag(req->engine); } ret = intel_logical_ring_begin(req, 4); @@ -1755,7 +1755,7 @@ static int gen8_emit_flush(struct drm_i915_gem_request *request, u32 unused) { struct intel_ringbuffer *ringbuf = request->ringbuf; - struct intel_engine_cs *engine = ringbuf->ring; + struct intel_engine_cs *engine = ringbuf->engine; struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; uint32_t cmd; @@ -1776,7 +1776,7 @@ static int gen8_emit_flush(struct drm_i915_gem_request *request, if (invalidate_domains & I915_GEM_GPU_DOMAINS) { cmd |= MI_INVALIDATE_TLB; - if (engine == &dev_priv->ring[VCS]) + if (engine == &dev_priv->engine[VCS]) cmd |= MI_INVALIDATE_BSD; } @@ -1796,7 +1796,7 @@ static int gen8_emit_flush_render(struct drm_i915_gem_request *request, u32 flush_domains) { struct intel_ringbuffer *ringbuf = request->ringbuf; - struct intel_engine_cs *engine = ringbuf->ring; + struct intel_engine_cs *engine = ringbuf->engine; u32 scratch_addr = engine->scratch.gtt_offset + 2 * CACHELINE_BYTES; bool vf_flush_wa = false; u32 flags = 0; @@ -1919,7 +1919,7 @@ static int gen8_emit_request(struct drm_i915_gem_request *request) intel_logical_ring_emit(ringbuf, (MI_FLUSH_DW + 1) | MI_FLUSH_DW_OP_STOREDW); intel_logical_ring_emit(ringbuf, - hws_seqno_address(request->ring) | + hws_seqno_address(request->engine) | MI_FLUSH_DW_USE_GTT); intel_logical_ring_emit(ringbuf, 0); intel_logical_ring_emit(ringbuf, i915_gem_request_get_seqno(request)); @@ -1946,7 +1946,7 @@ static int gen8_emit_request_render(struct drm_i915_gem_request *request) (PIPE_CONTROL_GLOBAL_GTT_IVB | PIPE_CONTROL_CS_STALL | PIPE_CONTROL_QW_WRITE)); - intel_logical_ring_emit(ringbuf, hws_seqno_address(request->ring)); + intel_logical_ring_emit(ringbuf, hws_seqno_address(request->engine)); intel_logical_ring_emit(ringbuf, 0); intel_logical_ring_emit(ringbuf, i915_gem_request_get_seqno(request)); intel_logical_ring_emit(ringbuf, MI_USER_INTERRUPT); @@ -1958,19 +1958,19 @@ static int intel_lr_context_render_state_init(struct drm_i915_gem_request *req) struct render_state so; int ret; - ret = i915_gem_render_state_prepare(req->ring, &so); + ret = i915_gem_render_state_prepare(req->engine, &so); if (ret) return ret; if (so.rodata == NULL) return 0; - ret = req->ring->emit_bb_start(req, so.ggtt_offset, + ret = req->engine->emit_bb_start(req, so.ggtt_offset, I915_DISPATCH_SECURE); if (ret) goto out; - ret = req->ring->emit_bb_start(req, + ret = req->engine->emit_bb_start(req, (so.ggtt_offset + so.aux_batch_offset), I915_DISPATCH_SECURE); if (ret) @@ -2117,7 +2117,7 @@ error: static int logical_render_ring_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *engine = &dev_priv->ring[RCS]; + struct intel_engine_cs *engine = &dev_priv->engine[RCS]; int ret; engine->name = "render ring"; @@ -2170,7 +2170,7 @@ static int logical_render_ring_init(struct drm_device *dev) static int logical_bsd_ring_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *engine = &dev_priv->ring[VCS]; + struct intel_engine_cs *engine = &dev_priv->engine[VCS]; engine->name = "bsd ring"; engine->id = VCS; @@ -2187,7 +2187,7 @@ static int logical_bsd_ring_init(struct drm_device *dev) static int logical_bsd2_ring_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *engine = &dev_priv->ring[VCS2]; + struct intel_engine_cs *engine = &dev_priv->engine[VCS2]; engine->name = "bsd2 ring"; engine->id = VCS2; @@ -2204,7 +2204,7 @@ static int logical_bsd2_ring_init(struct drm_device *dev) static int logical_blt_ring_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *engine = &dev_priv->ring[BCS]; + struct intel_engine_cs *engine = &dev_priv->engine[BCS]; engine->name = "blitter ring"; engine->id = BCS; @@ -2221,7 +2221,7 @@ static int logical_blt_ring_init(struct drm_device *dev) static int logical_vebox_ring_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *engine = &dev_priv->ring[VECS]; + struct intel_engine_cs *engine = &dev_priv->engine[VECS]; engine->name = "video enhancement ring"; engine->id = VECS; @@ -2281,13 +2281,13 @@ int intel_logical_rings_init(struct drm_device *dev) return 0; cleanup_vebox_ring: - intel_logical_ring_cleanup(&dev_priv->ring[VECS]); + intel_logical_ring_cleanup(&dev_priv->engine[VECS]); cleanup_blt_ring: - intel_logical_ring_cleanup(&dev_priv->ring[BCS]); + intel_logical_ring_cleanup(&dev_priv->engine[BCS]); cleanup_bsd_ring: - intel_logical_ring_cleanup(&dev_priv->ring[VCS]); + intel_logical_ring_cleanup(&dev_priv->engine[VCS]); cleanup_render_ring: - intel_logical_ring_cleanup(&dev_priv->ring[RCS]); + intel_logical_ring_cleanup(&dev_priv->engine[RCS]); return ret; } diff --git a/drivers/gpu/drm/i915/intel_mocs.c b/drivers/gpu/drm/i915/intel_mocs.c index d55925987ebf..2c895637ab50 100644 --- a/drivers/gpu/drm/i915/intel_mocs.c +++ b/drivers/gpu/drm/i915/intel_mocs.c @@ -322,7 +322,7 @@ int intel_rcs_context_init_mocs(struct drm_i915_gem_request *req) struct drm_i915_mocs_table t; int ret; - if (get_mocs_settings(req->ring->dev, &t)) { + if (get_mocs_settings(req->engine->dev, &t)) { struct drm_i915_private *dev_priv = req->i915; struct intel_engine_cs *engine; enum intel_ring_id ring_id; diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 13b27632636e..13e22f52666c 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -233,7 +233,7 @@ static int intel_overlay_on(struct intel_overlay *overlay) { struct drm_device *dev = overlay->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *engine = &dev_priv->ring[RCS]; + struct intel_engine_cs *engine = &dev_priv->engine[RCS]; struct drm_i915_gem_request *req; int ret; @@ -267,7 +267,7 @@ static int intel_overlay_continue(struct intel_overlay *overlay, { struct drm_device *dev = overlay->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *engine = &dev_priv->ring[RCS]; + struct intel_engine_cs *engine = &dev_priv->engine[RCS]; struct drm_i915_gem_request *req; u32 flip_addr = overlay->flip_addr; u32 tmp; @@ -336,7 +336,7 @@ static int intel_overlay_off(struct intel_overlay *overlay) { struct drm_device *dev = overlay->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *engine = &dev_priv->ring[RCS]; + struct intel_engine_cs *engine = &dev_priv->engine[RCS]; struct drm_i915_gem_request *req; u32 flip_addr = overlay->flip_addr; int ret; @@ -409,7 +409,7 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay) { struct drm_device *dev = overlay->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *engine = &dev_priv->ring[RCS]; + struct intel_engine_cs *engine = &dev_priv->engine[RCS]; int ret; WARN_ON(!mutex_is_locked(&dev->struct_mutex)); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index c54a7df7c2c9..e51c28487696 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -7365,7 +7365,7 @@ static void __intel_rps_boost_work(struct work_struct *work) struct drm_i915_gem_request *req = boost->req; if (!i915_gem_request_completed(req, true)) - gen6_rps_boost(to_i915(req->ring->dev), NULL, + gen6_rps_boost(to_i915(req->engine->dev), NULL, req->emitted_jiffies); i915_gem_request_unreference__unlocked(req); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 53237616ce19..7075b93a8fc9 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -79,7 +79,7 @@ gen2_render_ring_flush(struct drm_i915_gem_request *req, u32 invalidate_domains, u32 flush_domains) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; u32 cmd; int ret; @@ -106,7 +106,7 @@ gen4_render_ring_flush(struct drm_i915_gem_request *req, u32 invalidate_domains, u32 flush_domains) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; struct drm_device *dev = engine->dev; u32 cmd; int ret; @@ -200,7 +200,7 @@ gen4_render_ring_flush(struct drm_i915_gem_request *req, static int intel_emit_post_sync_nonzero_flush(struct drm_i915_gem_request *req) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; u32 scratch_addr = engine->scratch.gtt_offset + 2 * CACHELINE_BYTES; int ret; @@ -236,7 +236,7 @@ static int gen6_render_ring_flush(struct drm_i915_gem_request *req, u32 invalidate_domains, u32 flush_domains) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; u32 flags = 0; u32 scratch_addr = engine->scratch.gtt_offset + 2 * CACHELINE_BYTES; int ret; @@ -288,7 +288,7 @@ gen6_render_ring_flush(struct drm_i915_gem_request *req, static int gen7_render_ring_cs_stall_wa(struct drm_i915_gem_request *req) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; int ret; ret = intel_ring_begin(req, 4); @@ -309,7 +309,7 @@ static int gen7_render_ring_flush(struct drm_i915_gem_request *req, u32 invalidate_domains, u32 flush_domains) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; u32 flags = 0; u32 scratch_addr = engine->scratch.gtt_offset + 2 * CACHELINE_BYTES; int ret; @@ -373,7 +373,7 @@ static int gen8_emit_pipe_control(struct drm_i915_gem_request *req, u32 flags, u32 scratch_addr) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; int ret; ret = intel_ring_begin(req, 6); @@ -396,7 +396,7 @@ gen8_render_ring_flush(struct drm_i915_gem_request *req, u32 invalidate_domains, u32 flush_domains) { u32 flags = 0; - u32 scratch_addr = req->ring->scratch.gtt_offset + 2 * CACHELINE_BYTES; + u32 scratch_addr = req->engine->scratch.gtt_offset + 2 * CACHELINE_BYTES; int ret; flags |= PIPE_CONTROL_CS_STALL; @@ -704,7 +704,7 @@ err: static int intel_ring_workarounds_emit(struct drm_i915_gem_request *req) { int ret, i; - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct i915_workarounds *w = &dev_priv->workarounds; @@ -1269,7 +1269,7 @@ static int gen8_rcs_signal(struct drm_i915_gem_request *signaller_req, unsigned int num_dwords) { #define MBOX_UPDATE_DWORDS 8 - struct intel_engine_cs *signaller = signaller_req->ring; + struct intel_engine_cs *signaller = signaller_req->engine; struct drm_device *dev = signaller->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *waiter; @@ -1310,7 +1310,7 @@ static int gen8_xcs_signal(struct drm_i915_gem_request *signaller_req, unsigned int num_dwords) { #define MBOX_UPDATE_DWORDS 6 - struct intel_engine_cs *signaller = signaller_req->ring; + struct intel_engine_cs *signaller = signaller_req->engine; struct drm_device *dev = signaller->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *waiter; @@ -1348,7 +1348,7 @@ static int gen8_xcs_signal(struct drm_i915_gem_request *signaller_req, static int gen6_signal(struct drm_i915_gem_request *signaller_req, unsigned int num_dwords) { - struct intel_engine_cs *signaller = signaller_req->ring; + struct intel_engine_cs *signaller = signaller_req->engine; struct drm_device *dev = signaller->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *useless; @@ -1393,7 +1393,7 @@ static int gen6_signal(struct drm_i915_gem_request *signaller_req, static int gen6_add_request(struct drm_i915_gem_request *req) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; int ret; if (engine->semaphore.signal) @@ -1434,7 +1434,7 @@ gen8_ring_sync(struct drm_i915_gem_request *waiter_req, struct intel_engine_cs *signaller, u32 seqno) { - struct intel_engine_cs *waiter = waiter_req->ring; + struct intel_engine_cs *waiter = waiter_req->engine; struct drm_i915_private *dev_priv = waiter->dev->dev_private; int ret; @@ -1460,7 +1460,7 @@ gen6_ring_sync(struct drm_i915_gem_request *waiter_req, struct intel_engine_cs *signaller, u32 seqno) { - struct intel_engine_cs *waiter = waiter_req->ring; + struct intel_engine_cs *waiter = waiter_req->engine; u32 dw1 = MI_SEMAPHORE_MBOX | MI_SEMAPHORE_COMPARE | MI_SEMAPHORE_REGISTER; @@ -1508,7 +1508,7 @@ do { \ static int pc_render_add_request(struct drm_i915_gem_request *req) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; u32 scratch_addr = engine->scratch.gtt_offset + 2 * CACHELINE_BYTES; int ret; @@ -1706,7 +1706,7 @@ bsd_ring_flush(struct drm_i915_gem_request *req, u32 invalidate_domains, u32 flush_domains) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; int ret; ret = intel_ring_begin(req, 2); @@ -1722,7 +1722,7 @@ bsd_ring_flush(struct drm_i915_gem_request *req, static int i9xx_add_request(struct drm_i915_gem_request *req) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; int ret; ret = intel_ring_begin(req, 4); @@ -1868,7 +1868,7 @@ i965_dispatch_execbuffer(struct drm_i915_gem_request *req, u64 offset, u32 length, unsigned dispatch_flags) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; int ret; ret = intel_ring_begin(req, 2); @@ -1895,7 +1895,7 @@ i830_dispatch_execbuffer(struct drm_i915_gem_request *req, u64 offset, u32 len, unsigned dispatch_flags) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; u32 cs_offset = engine->scratch.gtt_offset; int ret; @@ -1957,7 +1957,7 @@ i915_dispatch_execbuffer(struct drm_i915_gem_request *req, u64 offset, u32 len, unsigned dispatch_flags) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; int ret; ret = intel_ring_begin(req, 2); @@ -2187,7 +2187,7 @@ intel_engine_create_ringbuffer(struct intel_engine_cs *engine, int size) return ERR_PTR(-ENOMEM); } - ring->ring = engine; + ring->engine = engine; list_add(&ring->link, &engine->buffers); ring->size = size; @@ -2377,7 +2377,7 @@ int intel_ring_idle(struct intel_engine_cs *engine) int intel_ring_alloc_request_extras(struct drm_i915_gem_request *request) { - request->ringbuf = request->ring->buffer; + request->ringbuf = request->engine->buffer; return 0; } @@ -2498,7 +2498,7 @@ int intel_ring_begin(struct drm_i915_gem_request *req, int ret; WARN_ON(req == NULL); - engine = req->ring; + engine = req->engine; dev_priv = engine->dev->dev_private; ret = i915_gem_check_wedge(&dev_priv->gpu_error, @@ -2517,7 +2517,7 @@ int intel_ring_begin(struct drm_i915_gem_request *req, /* Align the ring tail to a cacheline boundary */ int intel_ring_cacheline_align(struct drm_i915_gem_request *req) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; int num_dwords = (engine->buffer->tail & (CACHELINE_BYTES - 1)) / sizeof(uint32_t); int ret; @@ -2589,7 +2589,7 @@ static void gen6_bsd_ring_write_tail(struct intel_engine_cs *engine, static int gen6_bsd_ring_flush(struct drm_i915_gem_request *req, u32 invalidate, u32 flush) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; uint32_t cmd; int ret; @@ -2636,7 +2636,7 @@ gen8_ring_dispatch_execbuffer(struct drm_i915_gem_request *req, u64 offset, u32 len, unsigned dispatch_flags) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; bool ppgtt = USES_PPGTT(engine->dev) && !(dispatch_flags & I915_DISPATCH_SECURE); int ret; @@ -2662,7 +2662,7 @@ hsw_ring_dispatch_execbuffer(struct drm_i915_gem_request *req, u64 offset, u32 len, unsigned dispatch_flags) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; int ret; ret = intel_ring_begin(req, 2); @@ -2687,7 +2687,7 @@ gen6_ring_dispatch_execbuffer(struct drm_i915_gem_request *req, u64 offset, u32 len, unsigned dispatch_flags) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; int ret; ret = intel_ring_begin(req, 2); @@ -2710,7 +2710,7 @@ gen6_ring_dispatch_execbuffer(struct drm_i915_gem_request *req, static int gen6_ring_flush(struct drm_i915_gem_request *req, u32 invalidate, u32 flush) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; struct drm_device *dev = engine->dev; uint32_t cmd; int ret; @@ -2756,7 +2756,7 @@ static int gen6_ring_flush(struct drm_i915_gem_request *req, int intel_init_render_ring_buffer(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *engine = &dev_priv->ring[RCS]; + struct intel_engine_cs *engine = &dev_priv->engine[RCS]; struct drm_i915_gem_object *obj; int ret; @@ -2907,7 +2907,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev) int intel_init_bsd_ring_buffer(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *engine = &dev_priv->ring[VCS]; + struct intel_engine_cs *engine = &dev_priv->engine[VCS]; engine->name = "bsd ring"; engine->id = VCS; @@ -2984,7 +2984,7 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) int intel_init_bsd2_ring_buffer(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *engine = &dev_priv->ring[VCS2]; + struct intel_engine_cs *engine = &dev_priv->engine[VCS2]; engine->name = "bsd2 ring"; engine->id = VCS2; @@ -3015,7 +3015,7 @@ int intel_init_bsd2_ring_buffer(struct drm_device *dev) int intel_init_blt_ring_buffer(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *engine = &dev_priv->ring[BCS]; + struct intel_engine_cs *engine = &dev_priv->engine[BCS]; engine->name = "blitter ring"; engine->id = BCS; @@ -3073,7 +3073,7 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) int intel_init_vebox_ring_buffer(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *engine = &dev_priv->ring[VECS]; + struct intel_engine_cs *engine = &dev_priv->engine[VECS]; engine->name = "video enhancement ring"; engine->id = VECS; @@ -3125,7 +3125,7 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev) int intel_ring_flush_all_caches(struct drm_i915_gem_request *req) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; int ret; if (!engine->gpu_caches_dirty) @@ -3144,7 +3144,7 @@ intel_ring_flush_all_caches(struct drm_i915_gem_request *req) int intel_ring_invalidate_all_caches(struct drm_i915_gem_request *req) { - struct intel_engine_cs *engine = req->ring; + struct intel_engine_cs *engine = req->engine; uint32_t flush_domains; int ret; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 48484639c9da..4b0114e3c467 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -99,7 +99,7 @@ struct intel_ringbuffer { void __iomem *virtual_start; struct i915_vma *vma; - struct intel_engine_cs *ring; + struct intel_engine_cs *engine; struct list_head link; u32 head; -- cgit v1.2.3 From 666796da7abbc9c8c1805efa6d43bf078ddb282e Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Wed, 16 Mar 2016 11:00:39 +0000 Subject: drm/i915: More intel_engine_cs renaming Some trivial ones, first pass done with Coccinelle: @@ @@ ( - I915_NUM_RINGS + I915_NUM_ENGINES | - intel_ring_flag + intel_engine_flag | - for_each_ring + for_each_engine | - i915_gem_request_get_ring + i915_gem_request_get_engine | - intel_ring_idle + intel_engine_idle | - i915_gem_reset_ring_status + i915_gem_reset_engine_status | - i915_gem_reset_ring_cleanup + i915_gem_reset_engine_cleanup | - init_ring_lists + init_engine_lists ) But that didn't fully work so I cleaned it up with: for f in *.[hc]; do sed -i -e s/I915_NUM_RINGS/I915_NUM_ENGINES/ $f; done for f in *.[hc]; do sed -i -e s/i915_gem_request_get_ring/i915_gem_request_get_engine/ $f; done for f in *.[hc]; do sed -i -e s/intel_ring_flag/intel_engine_flag/ $f; done for f in *.[hc]; do sed -i -e s/intel_ring_idle/intel_engine_idle/ $f; done for f in *.[hc]; do sed -i -e s/init_ring_lists/init_engine_lists/ $f; done for f in *.[hc]; do sed -i -e s/i915_gem_reset_ring_cleanup/i915_gem_reset_engine_cleanup/ $f; done for f in *.[hc]; do sed -i -e s/i915_gem_reset_ring_status/i915_gem_reset_engine_status/ $f; done v2: Rebase. Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 52 ++++++++++----------- drivers/gpu/drm/i915/i915_drv.h | 26 +++++------ drivers/gpu/drm/i915/i915_gem.c | 74 +++++++++++++++--------------- drivers/gpu/drm/i915/i915_gem_context.c | 16 +++---- drivers/gpu/drm/i915/i915_gem_debug.c | 2 +- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 4 +- drivers/gpu/drm/i915/i915_gem_gtt.c | 6 +-- drivers/gpu/drm/i915/i915_gpu_error.c | 12 ++--- drivers/gpu/drm/i915/i915_guc_submission.c | 6 +-- drivers/gpu/drm/i915/i915_irq.c | 20 ++++---- drivers/gpu/drm/i915/i915_trace.h | 6 +-- drivers/gpu/drm/i915/intel_display.c | 4 +- drivers/gpu/drm/i915/intel_guc_loader.c | 4 +- drivers/gpu/drm/i915/intel_lrc.c | 12 ++--- drivers/gpu/drm/i915/intel_mocs.c | 2 +- drivers/gpu/drm/i915/intel_pm.c | 12 ++--- drivers/gpu/drm/i915/intel_ringbuffer.c | 12 ++--- drivers/gpu/drm/i915/intel_ringbuffer.h | 20 ++++---- drivers/gpu/drm/i915/intel_uncore.c | 4 +- 19 files changed, 147 insertions(+), 147 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index a71ffaaf380d..dabce8403d56 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -143,7 +143,7 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) obj->base.size / 1024, obj->base.read_domains, obj->base.write_domain); - for_each_ring(engine, dev_priv, i) + for_each_engine(engine, dev_priv, i) seq_printf(m, "%x ", i915_gem_request_get_seqno(obj->last_read_req[i])); seq_printf(m, "] %x %x%s%s%s", @@ -184,7 +184,7 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) } if (obj->last_write_req != NULL) seq_printf(m, " (%s)", - i915_gem_request_get_ring(obj->last_write_req)->name); + i915_gem_request_get_engine(obj->last_write_req)->name); if (obj->frontbuffer_bits) seq_printf(m, " (frontbuffer: 0x%03x)", obj->frontbuffer_bits); } @@ -402,7 +402,7 @@ static void print_batch_pool_stats(struct seq_file *m, memset(&stats, 0, sizeof(stats)); - for_each_ring(engine, dev_priv, i) { + for_each_engine(engine, dev_priv, i) { for (j = 0; j < ARRAY_SIZE(engine->batch_pool.cache_list); j++) { list_for_each_entry(obj, &engine->batch_pool.cache_list[j], @@ -591,7 +591,7 @@ static int i915_gem_pageflip_info(struct seq_file *m, void *data) pipe, plane); } if (work->flip_queued_req) { - struct intel_engine_cs *engine = i915_gem_request_get_ring(work->flip_queued_req); + struct intel_engine_cs *engine = i915_gem_request_get_engine(work->flip_queued_req); seq_printf(m, "Flip queued on %s at seqno %x, next seqno %x [current breadcrumb %x], completed? %d\n", engine->name, @@ -644,7 +644,7 @@ static int i915_gem_batch_pool_info(struct seq_file *m, void *data) if (ret) return ret; - for_each_ring(engine, dev_priv, i) { + for_each_engine(engine, dev_priv, i) { for (j = 0; j < ARRAY_SIZE(engine->batch_pool.cache_list); j++) { int count; @@ -689,7 +689,7 @@ static int i915_gem_request_info(struct seq_file *m, void *data) return ret; any = 0; - for_each_ring(engine, dev_priv, i) { + for_each_engine(engine, dev_priv, i) { int count; count = 0; @@ -746,7 +746,7 @@ static int i915_gem_seqno_info(struct seq_file *m, void *data) return ret; intel_runtime_pm_get(dev_priv); - for_each_ring(engine, dev_priv, i) + for_each_engine(engine, dev_priv, i) i915_ring_seqno_info(m, engine); intel_runtime_pm_put(dev_priv); @@ -933,7 +933,7 @@ static int i915_interrupt_info(struct seq_file *m, void *data) seq_printf(m, "Graphics Interrupt mask: %08x\n", I915_READ(GTIMR)); } - for_each_ring(engine, dev_priv, i) { + for_each_engine(engine, dev_priv, i) { if (INTEL_INFO(dev)->gen >= 6) { seq_printf(m, "Graphics Interrupt mask (%s): %08x\n", @@ -1331,8 +1331,8 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused) struct drm_device *dev = node->minor->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *engine; - u64 acthd[I915_NUM_RINGS]; - u32 seqno[I915_NUM_RINGS]; + u64 acthd[I915_NUM_ENGINES]; + u32 seqno[I915_NUM_ENGINES]; u32 instdone[I915_NUM_INSTDONE_REG]; int i, j; @@ -1343,7 +1343,7 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused) intel_runtime_pm_get(dev_priv); - for_each_ring(engine, dev_priv, i) { + for_each_engine(engine, dev_priv, i) { seqno[i] = engine->get_seqno(engine, false); acthd[i] = intel_ring_get_active_head(engine); } @@ -1359,7 +1359,7 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused) } else seq_printf(m, "Hangcheck inactive\n"); - for_each_ring(engine, dev_priv, i) { + for_each_engine(engine, dev_priv, i) { seq_printf(m, "%s:\n", engine->name); seq_printf(m, "\tseqno = %x [current %x]\n", engine->hangcheck.seqno, seqno[i]); @@ -1965,7 +1965,7 @@ static int i915_context_status(struct seq_file *m, void *unused) if (i915.enable_execlists) { seq_putc(m, '\n'); - for_each_ring(engine, dev_priv, i) { + for_each_engine(engine, dev_priv, i) { struct drm_i915_gem_object *ctx_obj = ctx->engine[i].state; struct intel_ringbuffer *ringbuf = @@ -2055,7 +2055,7 @@ static int i915_dump_lrc(struct seq_file *m, void *unused) list_for_each_entry(ctx, &dev_priv->context_list, link) if (ctx != dev_priv->kernel_context) - for_each_ring(engine, dev_priv, i) + for_each_engine(engine, dev_priv, i) i915_dump_lrc_obj(m, ctx, engine); mutex_unlock(&dev->struct_mutex); @@ -2089,7 +2089,7 @@ static int i915_execlists(struct seq_file *m, void *data) intel_runtime_pm_get(dev_priv); - for_each_ring(engine, dev_priv, ring_id) { + for_each_engine(engine, dev_priv, ring_id) { struct drm_i915_gem_request *head_req = NULL; int count = 0; unsigned long flags; @@ -2253,7 +2253,7 @@ static void gen8_ppgtt_info(struct seq_file *m, struct drm_device *dev) if (!ppgtt) return; - for_each_ring(engine, dev_priv, unused) { + for_each_engine(engine, dev_priv, unused) { seq_printf(m, "%s\n", engine->name); for (i = 0; i < 4; i++) { u64 pdp = I915_READ(GEN8_RING_PDP_UDW(engine, i)); @@ -2273,7 +2273,7 @@ static void gen6_ppgtt_info(struct seq_file *m, struct drm_device *dev) if (INTEL_INFO(dev)->gen == 6) seq_printf(m, "GFX_MODE: 0x%08x\n", I915_READ(GFX_MODE)); - for_each_ring(engine, dev_priv, i) { + for_each_engine(engine, dev_priv, i) { seq_printf(m, "%s\n", engine->name); if (INTEL_INFO(dev)->gen == 7) seq_printf(m, "GFX_MODE: 0x%08x\n", @@ -2342,7 +2342,7 @@ static int count_irq_waiters(struct drm_i915_private *i915) int count = 0; int i; - for_each_ring(engine, i915, i) + for_each_engine(engine, i915, i) count += engine->irq_refcount; return count; @@ -2466,7 +2466,7 @@ static void i915_guc_client_info(struct seq_file *m, seq_printf(m, "\tFailed doorbell: %u\n", client->b_fail); seq_printf(m, "\tLast submission result: %d\n", client->retcode); - for_each_ring(engine, dev_priv, i) { + for_each_engine(engine, dev_priv, i) { seq_printf(m, "\tSubmissions: %llu %s\n", client->submissions[engine->guc_id], engine->name); @@ -2506,7 +2506,7 @@ static int i915_guc_info(struct seq_file *m, void *data) seq_printf(m, "GuC last action error code: %d\n", guc.action_err); seq_printf(m, "\nGuC submissions:\n"); - for_each_ring(engine, dev_priv, i) { + for_each_engine(engine, dev_priv, i) { seq_printf(m, "\t%-24s: %10llu, last seqno 0x%08x\n", engine->name, guc.submissions[engine->guc_id], guc.last_seqno[engine->guc_id]); @@ -3153,14 +3153,14 @@ static int i915_semaphore_status(struct seq_file *m, void *unused) page = i915_gem_object_get_page(dev_priv->semaphore_obj, 0); seqno = (uint64_t *)kmap_atomic(page); - for_each_ring(engine, dev_priv, i) { + for_each_engine(engine, dev_priv, i) { uint64_t offset; seq_printf(m, "%s\n", engine->name); seq_puts(m, " Last signal:"); for (j = 0; j < num_rings; j++) { - offset = i * I915_NUM_RINGS + j; + offset = i * I915_NUM_ENGINES + j; seq_printf(m, "0x%08llx (0x%02llx) ", seqno[offset], offset * 8); } @@ -3168,7 +3168,7 @@ static int i915_semaphore_status(struct seq_file *m, void *unused) seq_puts(m, " Last wait: "); for (j = 0; j < num_rings; j++) { - offset = i + (j * I915_NUM_RINGS); + offset = i + (j * I915_NUM_ENGINES); seq_printf(m, "0x%08llx (0x%02llx) ", seqno[offset], offset * 8); } @@ -3178,7 +3178,7 @@ static int i915_semaphore_status(struct seq_file *m, void *unused) kunmap_atomic(seqno); } else { seq_puts(m, " Last signal:"); - for_each_ring(engine, dev_priv, i) + for_each_engine(engine, dev_priv, i) for (j = 0; j < num_rings; j++) seq_printf(m, "0x%08x\n", I915_READ(engine->semaphore.mbox.signal[j])); @@ -3186,7 +3186,7 @@ static int i915_semaphore_status(struct seq_file *m, void *unused) } seq_puts(m, "\nSync seqno:\n"); - for_each_ring(engine, dev_priv, i) { + for_each_engine(engine, dev_priv, i) { for (j = 0; j < num_rings; j++) { seq_printf(m, " 0x%08x ", engine->semaphore.sync_seqno[j]); @@ -3244,7 +3244,7 @@ static int i915_wa_registers(struct seq_file *m, void *unused) intel_runtime_pm_get(dev_priv); seq_printf(m, "Workarounds applied: %d\n", workarounds->count); - for_each_ring(engine, dev_priv, i) + for_each_engine(engine, dev_priv, i) seq_printf(m, "HW whitelist count for %s: %d\n", engine->name, workarounds->hw_whitelist_count[i]); for (i = 0; i < workarounds->count; ++i) { diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0187a560aa51..db999c24c192 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -459,7 +459,7 @@ struct drm_i915_error_state { u32 cpu_ring_head; u32 cpu_ring_tail; - u32 semaphore_seqno[I915_NUM_RINGS - 1]; + u32 semaphore_seqno[I915_NUM_ENGINES - 1]; /* Register state */ u32 start; @@ -479,7 +479,7 @@ struct drm_i915_error_state { u32 fault_reg; u64 faddr; u32 rc_psmi; /* sleep state */ - u32 semaphore_mboxes[I915_NUM_RINGS - 1]; + u32 semaphore_mboxes[I915_NUM_ENGINES - 1]; struct drm_i915_error_object { int page_count; @@ -505,12 +505,12 @@ struct drm_i915_error_state { pid_t pid; char comm[TASK_COMM_LEN]; - } ring[I915_NUM_RINGS]; + } ring[I915_NUM_ENGINES]; struct drm_i915_error_buffer { u32 size; u32 name; - u32 rseqno[I915_NUM_RINGS], wseqno; + u32 rseqno[I915_NUM_ENGINES], wseqno; u64 gtt_offset; u32 read_domains; u32 write_domain; @@ -824,7 +824,7 @@ struct intel_context { struct i915_vma *lrc_vma; u64 lrc_desc; uint32_t *lrc_reg_state; - } engine[I915_NUM_RINGS]; + } engine[I915_NUM_ENGINES]; struct list_head link; }; @@ -1639,7 +1639,7 @@ struct i915_wa_reg { struct i915_workarounds { struct i915_wa_reg reg[I915_MAX_WA_REGS]; u32 count; - u32 hw_whitelist_count[I915_NUM_RINGS]; + u32 hw_whitelist_count[I915_NUM_ENGINES]; }; struct i915_virtual_gpu { @@ -1704,7 +1704,7 @@ struct drm_i915_private { wait_queue_head_t gmbus_wait_queue; struct pci_dev *bridge_dev; - struct intel_engine_cs engine[I915_NUM_RINGS]; + struct intel_engine_cs engine[I915_NUM_ENGINES]; struct drm_i915_gem_object *semaphore_obj; uint32_t last_seqno, next_seqno; @@ -1967,8 +1967,8 @@ static inline struct drm_i915_private *guc_to_i915(struct intel_guc *guc) } /* Iterate over initialised rings */ -#define for_each_ring(ring__, dev_priv__, i__) \ - for ((i__) = 0; (i__) < I915_NUM_RINGS; (i__)++) \ +#define for_each_engine(ring__, dev_priv__, i__) \ + for ((i__) = 0; (i__) < I915_NUM_ENGINES; (i__)++) \ for_each_if ((((ring__) = &(dev_priv__)->engine[(i__)]), intel_ring_initialized((ring__)))) enum hdmi_force_audio { @@ -2039,7 +2039,7 @@ struct drm_i915_gem_object { struct drm_mm_node *stolen; struct list_head global_list; - struct list_head ring_list[I915_NUM_RINGS]; + struct list_head ring_list[I915_NUM_ENGINES]; /** Used in execbuf to temporarily hold a ref */ struct list_head obj_exec_link; @@ -2050,7 +2050,7 @@ struct drm_i915_gem_object { * rendering and so a non-zero seqno), and is not set if it i s on * inactive (ready to be unbound) list. */ - unsigned int active:I915_NUM_RINGS; + unsigned int active:I915_NUM_ENGINES; /** * This is set if the object has been written to since last bound @@ -2129,7 +2129,7 @@ struct drm_i915_gem_object { * read request. This allows for the CPU to read from an active * buffer by only waiting for the write to complete. * */ - struct drm_i915_gem_request *last_read_req[I915_NUM_RINGS]; + struct drm_i915_gem_request *last_read_req[I915_NUM_ENGINES]; struct drm_i915_gem_request *last_write_req; /** Breadcrumb of last fenced GPU access to the buffer. */ struct drm_i915_gem_request *last_fenced_req; @@ -2277,7 +2277,7 @@ i915_gem_request_get_seqno(struct drm_i915_gem_request *req) } static inline struct intel_engine_cs * -i915_gem_request_get_ring(struct drm_i915_gem_request *req) +i915_gem_request_get_engine(struct drm_i915_gem_request *req) { return req ? req->engine : NULL; } diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index cd68a86437f1..0ae193f9bcbe 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1243,11 +1243,11 @@ int __i915_wait_request(struct drm_i915_gem_request *req, s64 *timeout, struct intel_rps_client *rps) { - struct intel_engine_cs *engine = i915_gem_request_get_ring(req); + struct intel_engine_cs *engine = i915_gem_request_get_engine(req); struct drm_device *dev = engine->dev; struct drm_i915_private *dev_priv = dev->dev_private; const bool irq_test_in_progress = - ACCESS_ONCE(dev_priv->gpu_error.test_irq_rings) & intel_ring_flag(engine); + ACCESS_ONCE(dev_priv->gpu_error.test_irq_rings) & intel_engine_flag(engine); int state = interruptible ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE; DEFINE_WAIT(wait); unsigned long timeout_expire; @@ -1512,7 +1512,7 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj, i915_gem_object_retire__write(obj); } } else { - for (i = 0; i < I915_NUM_RINGS; i++) { + for (i = 0; i < I915_NUM_ENGINES; i++) { if (obj->last_read_req[i] == NULL) continue; @@ -1552,7 +1552,7 @@ i915_gem_object_wait_rendering__nonblocking(struct drm_i915_gem_object *obj, { struct drm_device *dev = obj->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_request *requests[I915_NUM_RINGS]; + struct drm_i915_gem_request *requests[I915_NUM_ENGINES]; unsigned reset_counter; int ret, i, n = 0; @@ -1577,7 +1577,7 @@ i915_gem_object_wait_rendering__nonblocking(struct drm_i915_gem_object *obj, requests[n++] = i915_gem_request_reference(req); } else { - for (i = 0; i < I915_NUM_RINGS; i++) { + for (i = 0; i < I915_NUM_ENGINES; i++) { struct drm_i915_gem_request *req; req = obj->last_read_req[i]; @@ -2406,12 +2406,12 @@ void i915_vma_move_to_active(struct i915_vma *vma, struct drm_i915_gem_object *obj = vma->obj; struct intel_engine_cs *engine; - engine = i915_gem_request_get_ring(req); + engine = i915_gem_request_get_engine(req); /* Add a reference if we're newly entering the active list. */ if (obj->active == 0) drm_gem_object_reference(&obj->base); - obj->active |= intel_ring_flag(engine); + obj->active |= intel_engine_flag(engine); list_move_tail(&obj->ring_list[engine->id], &engine->active_list); i915_gem_request_assign(&obj->last_read_req[engine->id], req); @@ -2423,7 +2423,7 @@ static void i915_gem_object_retire__write(struct drm_i915_gem_object *obj) { RQ_BUG_ON(obj->last_write_req == NULL); - RQ_BUG_ON(!(obj->active & intel_ring_flag(obj->last_write_req->engine))); + RQ_BUG_ON(!(obj->active & intel_engine_flag(obj->last_write_req->engine))); i915_gem_request_assign(&obj->last_write_req, NULL); intel_fb_obj_flush(obj, true, ORIGIN_CS); @@ -2471,15 +2471,15 @@ i915_gem_init_seqno(struct drm_device *dev, u32 seqno) int ret, i, j; /* Carefully retire all requests without writing to the rings */ - for_each_ring(engine, dev_priv, i) { - ret = intel_ring_idle(engine); + for_each_engine(engine, dev_priv, i) { + ret = intel_engine_idle(engine); if (ret) return ret; } i915_gem_retire_requests(dev); /* Finally reset hw state */ - for_each_ring(engine, dev_priv, i) { + for_each_engine(engine, dev_priv, i) { intel_ring_init_seqno(engine, seqno); for (j = 0; j < ARRAY_SIZE(engine->semaphore.sync_seqno); j++) @@ -2801,7 +2801,7 @@ i915_gem_find_active_request(struct intel_engine_cs *engine) return NULL; } -static void i915_gem_reset_ring_status(struct drm_i915_private *dev_priv, +static void i915_gem_reset_engine_status(struct drm_i915_private *dev_priv, struct intel_engine_cs *engine) { struct drm_i915_gem_request *request; @@ -2820,7 +2820,7 @@ static void i915_gem_reset_ring_status(struct drm_i915_private *dev_priv, i915_set_reset_status(dev_priv, request->ctx, false); } -static void i915_gem_reset_ring_cleanup(struct drm_i915_private *dev_priv, +static void i915_gem_reset_engine_cleanup(struct drm_i915_private *dev_priv, struct intel_engine_cs *engine) { struct intel_ringbuffer *buffer; @@ -2893,11 +2893,11 @@ void i915_gem_reset(struct drm_device *dev) * them for finding the guilty party. As the requests only borrow * their reference to the objects, the inspection must be done first. */ - for_each_ring(engine, dev_priv, i) - i915_gem_reset_ring_status(dev_priv, engine); + for_each_engine(engine, dev_priv, i) + i915_gem_reset_engine_status(dev_priv, engine); - for_each_ring(engine, dev_priv, i) - i915_gem_reset_ring_cleanup(dev_priv, engine); + for_each_engine(engine, dev_priv, i) + i915_gem_reset_engine_cleanup(dev_priv, engine); i915_gem_context_reset(dev); @@ -2966,7 +2966,7 @@ i915_gem_retire_requests(struct drm_device *dev) bool idle = true; int i; - for_each_ring(engine, dev_priv, i) { + for_each_engine(engine, dev_priv, i) { i915_gem_retire_requests_ring(engine); idle &= list_empty(&engine->request_list); if (i915.enable_execlists) { @@ -3014,7 +3014,7 @@ i915_gem_idle_work_handler(struct work_struct *work) struct intel_engine_cs *ring; int i; - for_each_ring(ring, dev_priv, i) + for_each_engine(ring, dev_priv, i) if (!list_empty(&ring->request_list)) return; @@ -3028,7 +3028,7 @@ i915_gem_idle_work_handler(struct work_struct *work) struct intel_engine_cs *engine; int i; - for_each_ring(engine, dev_priv, i) + for_each_engine(engine, dev_priv, i) i915_gem_batch_pool_fini(&engine->batch_pool); mutex_unlock(&dev->struct_mutex); @@ -3048,7 +3048,7 @@ i915_gem_object_flush_active(struct drm_i915_gem_object *obj) if (!obj->active) return 0; - for (i = 0; i < I915_NUM_RINGS; i++) { + for (i = 0; i < I915_NUM_ENGINES; i++) { struct drm_i915_gem_request *req; req = obj->last_read_req[i]; @@ -3096,7 +3096,7 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file) struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_wait *args = data; struct drm_i915_gem_object *obj; - struct drm_i915_gem_request *req[I915_NUM_RINGS]; + struct drm_i915_gem_request *req[I915_NUM_ENGINES]; unsigned reset_counter; int i, n = 0; int ret; @@ -3133,7 +3133,7 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file) drm_gem_object_unreference(&obj->base); reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter); - for (i = 0; i < I915_NUM_RINGS; i++) { + for (i = 0; i < I915_NUM_ENGINES; i++) { if (obj->last_read_req[i] == NULL) continue; @@ -3166,7 +3166,7 @@ __i915_gem_object_sync(struct drm_i915_gem_object *obj, struct intel_engine_cs *from; int ret; - from = i915_gem_request_get_ring(from_req); + from = i915_gem_request_get_engine(from_req); if (to == from) return 0; @@ -3260,7 +3260,7 @@ i915_gem_object_sync(struct drm_i915_gem_object *obj, struct drm_i915_gem_request **to_req) { const bool readonly = obj->base.pending_write_domain == 0; - struct drm_i915_gem_request *req[I915_NUM_RINGS]; + struct drm_i915_gem_request *req[I915_NUM_ENGINES]; int ret, i, n; if (!obj->active) @@ -3274,7 +3274,7 @@ i915_gem_object_sync(struct drm_i915_gem_object *obj, if (obj->last_write_req) req[n++] = obj->last_write_req; } else { - for (i = 0; i < I915_NUM_RINGS; i++) + for (i = 0; i < I915_NUM_ENGINES; i++) if (obj->last_read_req[i]) req[n++] = obj->last_read_req[i]; } @@ -3395,7 +3395,7 @@ int i915_gpu_idle(struct drm_device *dev) int ret, i; /* Flush everything onto the inactive list. */ - for_each_ring(engine, dev_priv, i) { + for_each_engine(engine, dev_priv, i) { if (!i915.enable_execlists) { struct drm_i915_gem_request *req; @@ -3412,7 +3412,7 @@ int i915_gpu_idle(struct drm_device *dev) i915_add_request_no_flush(req); } - ret = intel_ring_idle(engine); + ret = intel_engine_idle(engine); if (ret) return ret; } @@ -4359,7 +4359,7 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, if (obj->active) { int i; - for (i = 0; i < I915_NUM_RINGS; i++) { + for (i = 0; i < I915_NUM_ENGINES; i++) { struct drm_i915_gem_request *req; req = obj->last_read_req[i]; @@ -4447,7 +4447,7 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj, int i; INIT_LIST_HEAD(&obj->global_list); - for (i = 0; i < I915_NUM_RINGS; i++) + for (i = 0; i < I915_NUM_ENGINES; i++) INIT_LIST_HEAD(&obj->ring_list[i]); INIT_LIST_HEAD(&obj->obj_exec_link); INIT_LIST_HEAD(&obj->vma_list); @@ -4659,7 +4659,7 @@ i915_gem_stop_ringbuffers(struct drm_device *dev) struct intel_engine_cs *engine; int i; - for_each_ring(engine, dev_priv, i) + for_each_engine(engine, dev_priv, i) dev_priv->gt.stop_ring(engine); } @@ -4876,7 +4876,7 @@ i915_gem_init_hw(struct drm_device *dev) } /* Need to do basic initialisation of all rings first: */ - for_each_ring(engine, dev_priv, i) { + for_each_engine(engine, dev_priv, i) { ret = engine->init_hw(engine); if (ret) goto out; @@ -4901,7 +4901,7 @@ i915_gem_init_hw(struct drm_device *dev) goto out; /* Now it is safe to go back round and do everything else: */ - for_each_ring(engine, dev_priv, i) { + for_each_engine(engine, dev_priv, i) { struct drm_i915_gem_request *req; req = i915_gem_request_alloc(engine, NULL); @@ -5009,7 +5009,7 @@ i915_gem_cleanup_ringbuffer(struct drm_device *dev) struct intel_engine_cs *engine; int i; - for_each_ring(engine, dev_priv, i) + for_each_engine(engine, dev_priv, i) dev_priv->gt.cleanup_ring(engine); if (i915.enable_execlists) @@ -5022,7 +5022,7 @@ i915_gem_cleanup_ringbuffer(struct drm_device *dev) } static void -init_ring_lists(struct intel_engine_cs *engine) +init_engine_lists(struct intel_engine_cs *engine) { INIT_LIST_HEAD(&engine->active_list); INIT_LIST_HEAD(&engine->request_list); @@ -5055,8 +5055,8 @@ i915_gem_load_init(struct drm_device *dev) INIT_LIST_HEAD(&dev_priv->mm.unbound_list); INIT_LIST_HEAD(&dev_priv->mm.bound_list); INIT_LIST_HEAD(&dev_priv->mm.fence_list); - for (i = 0; i < I915_NUM_RINGS; i++) - init_ring_lists(&dev_priv->engine[i]); + for (i = 0; i < I915_NUM_ENGINES; i++) + init_engine_lists(&dev_priv->engine[i]); for (i = 0; i < I915_MAX_NUM_FENCES; i++) INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list); INIT_DELAYED_WORK(&dev_priv->mm.retire_work, diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 6c325e4c7556..1993449ab7c5 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -345,7 +345,7 @@ void i915_gem_context_reset(struct drm_device *dev) intel_lr_context_reset(dev, ctx); } - for (i = 0; i < I915_NUM_RINGS; i++) { + for (i = 0; i < I915_NUM_ENGINES; i++) { struct intel_engine_cs *engine = &dev_priv->engine[i]; if (engine->last_context) { @@ -426,7 +426,7 @@ void i915_gem_context_fini(struct drm_device *dev) i915_gem_object_ggtt_unpin(dctx->legacy_hw_ctx.rcs_state); } - for (i = I915_NUM_RINGS; --i >= 0;) { + for (i = I915_NUM_ENGINES; --i >= 0;) { struct intel_engine_cs *engine = &dev_priv->engine[i]; if (engine->last_context) { @@ -553,7 +553,7 @@ mi_set_context(struct drm_i915_gem_request *req, u32 hw_flags) intel_ring_emit(engine, MI_LOAD_REGISTER_IMM(num_rings)); - for_each_ring(signaller, to_i915(engine->dev), i) { + for_each_engine(signaller, to_i915(engine->dev), i) { if (signaller == engine) continue; @@ -582,7 +582,7 @@ mi_set_context(struct drm_i915_gem_request *req, u32 hw_flags) intel_ring_emit(engine, MI_LOAD_REGISTER_IMM(num_rings)); - for_each_ring(signaller, to_i915(engine->dev), i) { + for_each_engine(signaller, to_i915(engine->dev), i) { if (signaller == engine) continue; @@ -608,7 +608,7 @@ static inline bool should_skip_switch(struct intel_engine_cs *engine, return false; if (to->ppgtt && from == to && - !(intel_ring_flag(engine) & to->ppgtt->pd_dirty_rings)) + !(intel_engine_flag(engine) & to->ppgtt->pd_dirty_rings)) return true; return false; @@ -697,7 +697,7 @@ static int do_switch(struct drm_i915_gem_request *req) goto unpin_out; /* Doing a PD load always reloads the page dirs */ - to->ppgtt->pd_dirty_rings &= ~intel_ring_flag(engine); + to->ppgtt->pd_dirty_rings &= ~intel_engine_flag(engine); } if (engine != &dev_priv->engine[RCS]) { @@ -725,9 +725,9 @@ static int do_switch(struct drm_i915_gem_request *req) * space. This means we must enforce that a page table load * occur when this occurs. */ } else if (to->ppgtt && - (intel_ring_flag(engine) & to->ppgtt->pd_dirty_rings)) { + (intel_engine_flag(engine) & to->ppgtt->pd_dirty_rings)) { hw_flags |= MI_FORCE_RESTORE; - to->ppgtt->pd_dirty_rings &= ~intel_ring_flag(engine); + to->ppgtt->pd_dirty_rings &= ~intel_engine_flag(engine); } /* We should never emit switch_mm more than once */ diff --git a/drivers/gpu/drm/i915/i915_gem_debug.c b/drivers/gpu/drm/i915/i915_gem_debug.c index 202a7e6ae295..e0bca7d5b0d6 100644 --- a/drivers/gpu/drm/i915/i915_gem_debug.c +++ b/drivers/gpu/drm/i915/i915_gem_debug.c @@ -43,7 +43,7 @@ i915_verify_lists(struct drm_device *dev) if (warned) return 0; - for_each_ring(engine, dev_priv, i) { + for_each_engine(engine, dev_priv, i) { list_for_each_entry(obj, &engine->active_list, ring_list[engine->id]) { if (obj->base.dev != dev || diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index bb1ed8c4bcb4..c0545db85a8c 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -942,7 +942,7 @@ static int i915_gem_execbuffer_move_to_gpu(struct drm_i915_gem_request *req, struct list_head *vmas) { - const unsigned other_rings = ~intel_ring_flag(req->engine); + const unsigned other_rings = ~intel_engine_flag(req->engine); struct i915_vma *vma; uint32_t flush_domains = 0; bool flush_chipset = false; @@ -1099,7 +1099,7 @@ void i915_gem_execbuffer_move_to_active(struct list_head *vmas, struct drm_i915_gem_request *req) { - struct intel_engine_cs *engine = i915_gem_request_get_ring(req); + struct intel_engine_cs *engine = i915_gem_request_get_engine(req); struct i915_vma *vma; list_for_each_entry(vma, vmas, exec_list) { diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index ab54396029ca..9c752fe0f730 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1739,7 +1739,7 @@ static void gen8_ppgtt_enable(struct drm_device *dev) struct intel_engine_cs *engine; int j; - for_each_ring(engine, dev_priv, j) { + for_each_engine(engine, dev_priv, j) { u32 four_level = USES_FULL_48BIT_PPGTT(dev) ? GEN8_GFX_PPGTT_48B : 0; I915_WRITE(RING_MODE_GEN7(engine), _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE | four_level)); @@ -1765,7 +1765,7 @@ static void gen7_ppgtt_enable(struct drm_device *dev) } I915_WRITE(GAM_ECOCHK, ecochk); - for_each_ring(engine, dev_priv, i) { + for_each_engine(engine, dev_priv, i) { /* GFX_MODE is per-ring on gen7+ */ I915_WRITE(RING_MODE_GEN7(engine), _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE)); @@ -2292,7 +2292,7 @@ void i915_check_and_clear_faults(struct drm_device *dev) if (INTEL_INFO(dev)->gen < 6) return; - for_each_ring(engine, dev_priv, i) { + for_each_engine(engine, dev_priv, i) { u32 fault_reg; fault_reg = I915_READ(RING_FAULT_REG(engine)); if (fault_reg & RING_FAULT_VALID) { diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index a73f7057e875..34397a67b09e 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -198,7 +198,7 @@ static void print_error_buffers(struct drm_i915_error_state_buf *m, err->size, err->read_domains, err->write_domain); - for (i = 0; i < I915_NUM_RINGS; i++) + for (i = 0; i < I915_NUM_ENGINES; i++) err_printf(m, "%02x ", err->rseqno[i]); err_printf(m, "] %02x", err->wseqno); @@ -732,7 +732,7 @@ static void capture_bo(struct drm_i915_error_buffer *err, err->size = obj->base.size; err->name = obj->base.name; - for (i = 0; i < I915_NUM_RINGS; i++) + for (i = 0; i < I915_NUM_ENGINES; i++) err->rseqno[i] = i915_gem_request_get_seqno(obj->last_read_req[i]); err->wseqno = i915_gem_request_get_seqno(obj->last_write_req); err->gtt_offset = vma->node.start; @@ -747,7 +747,7 @@ static void capture_bo(struct drm_i915_error_buffer *err, err->purgeable = obj->madv != I915_MADV_WILLNEED; err->userptr = obj->userptr.mm != NULL; err->ring = obj->last_write_req ? - i915_gem_request_get_ring(obj->last_write_req)->id : -1; + i915_gem_request_get_engine(obj->last_write_req)->id : -1; err->cache_level = obj->cache_level; } @@ -809,7 +809,7 @@ static uint32_t i915_error_generate_code(struct drm_i915_private *dev_priv, * synchronization commands which almost always appear in the case * strictly a client bug. Use instdone to differentiate those some. */ - for (i = 0; i < I915_NUM_RINGS; i++) { + for (i = 0; i < I915_NUM_ENGINES; i++) { if (error->ring[i].hangcheck_action == HANGCHECK_HUNG) { if (ring_id) *ring_id = i; @@ -856,7 +856,7 @@ static void gen8_record_semaphore_state(struct drm_i915_private *dev_priv, i915_error_ggtt_object_create(dev_priv, dev_priv->semaphore_obj); - for_each_ring(to, dev_priv, i) { + for_each_engine(to, dev_priv, i) { int idx; u16 signal_offset; u32 *tmp; @@ -1019,7 +1019,7 @@ static void i915_gem_record_rings(struct drm_device *dev, struct drm_i915_gem_request *request; int i, count; - for (i = 0; i < I915_NUM_RINGS; i++) { + for (i = 0; i < I915_NUM_ENGINES; i++) { struct intel_engine_cs *engine = &dev_priv->engine[i]; struct intel_ringbuffer *rbuf; diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index ed4f0762b263..ae1f58d073f2 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -390,7 +390,7 @@ static void guc_init_ctx_desc(struct intel_guc *guc, desc.priority = client->priority; desc.db_id = client->doorbell_id; - for_each_ring(engine, dev_priv, i) { + for_each_engine(engine, dev_priv, i) { struct guc_execlist_context *lrc = &desc.lrc[engine->guc_id]; struct drm_i915_gem_object *obj; uint64_t ctx_desc; @@ -871,7 +871,7 @@ static void guc_create_ads(struct intel_guc *guc) engine = &dev_priv->engine[RCS]; ads->golden_context_lrca = engine->status_page.gfx_addr; - for_each_ring(engine, dev_priv, i) + for_each_engine(engine, dev_priv, i) ads->eng_state_size[engine->guc_id] = intel_lr_context_size(engine); /* GuC scheduling policies */ @@ -884,7 +884,7 @@ static void guc_create_ads(struct intel_guc *guc) /* MMIO reg state */ reg_state = (void *)policies + sizeof(struct guc_policies); - for_each_ring(engine, dev_priv, i) { + for_each_engine(engine, dev_priv, i) { reg_state->mmio_white_list[engine->guc_id].mmio_start = engine->mmio_base + GUC_MMIO_WHITE_LIST_START; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 6b7bee59e0c7..63ed77fe6bc4 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1082,7 +1082,7 @@ static bool any_waiters(struct drm_i915_private *dev_priv) struct intel_engine_cs *engine; int i; - for_each_ring(engine, dev_priv, i) + for_each_engine(engine, dev_priv, i) if (engine->irq_refcount) return true; @@ -2460,7 +2460,7 @@ static void i915_error_wake_up(struct drm_i915_private *dev_priv, */ /* Wake up __wait_seqno, potentially holding dev->struct_mutex. */ - for_each_ring(engine, dev_priv, i) + for_each_engine(engine, dev_priv, i) wake_up_all(&engine->irq_queue); /* Wake up intel_crtc_wait_for_pending_flips, holding crtc->mutex. */ @@ -2832,7 +2832,7 @@ semaphore_wait_to_signaller_ring(struct intel_engine_cs *engine, u32 ipehr, int i; if (INTEL_INFO(dev_priv->dev)->gen >= 8) { - for_each_ring(signaller, dev_priv, i) { + for_each_engine(signaller, dev_priv, i) { if (engine == signaller) continue; @@ -2842,7 +2842,7 @@ semaphore_wait_to_signaller_ring(struct intel_engine_cs *engine, u32 ipehr, } else { u32 sync_bits = ipehr & MI_SEMAPHORE_SYNC_MASK; - for_each_ring(signaller, dev_priv, i) { + for_each_engine(signaller, dev_priv, i) { if(engine == signaller) continue; @@ -2941,7 +2941,7 @@ static int semaphore_passed(struct intel_engine_cs *engine) return -1; /* Prevent pathological recursion due to driver bugs */ - if (signaller->hangcheck.deadlock >= I915_NUM_RINGS) + if (signaller->hangcheck.deadlock >= I915_NUM_ENGINES) return -1; if (i915_seqno_passed(signaller->get_seqno(signaller, false), seqno)) @@ -2960,7 +2960,7 @@ static void semaphore_clear_deadlocks(struct drm_i915_private *dev_priv) struct intel_engine_cs *engine; int i; - for_each_ring(engine, dev_priv, i) + for_each_engine(engine, dev_priv, i) engine->hangcheck.deadlock = 0; } @@ -3075,7 +3075,7 @@ static void i915_hangcheck_elapsed(struct work_struct *work) struct intel_engine_cs *engine; int i; int busy_count = 0, rings_hung = 0; - bool stuck[I915_NUM_RINGS] = { 0 }; + bool stuck[I915_NUM_ENGINES] = { 0 }; #define BUSY 1 #define KICK 5 #define HUNG 20 @@ -3097,7 +3097,7 @@ static void i915_hangcheck_elapsed(struct work_struct *work) */ intel_uncore_arm_unclaimed_mmio_detection(dev_priv); - for_each_ring(engine, dev_priv, i) { + for_each_engine(engine, dev_priv, i) { u64 acthd; u32 seqno; bool busy = true; @@ -3114,7 +3114,7 @@ static void i915_hangcheck_elapsed(struct work_struct *work) if (waitqueue_active(&engine->irq_queue)) { /* Issue a wake-up to catch stuck h/w. */ if (!test_and_set_bit(engine->id, &dev_priv->gpu_error.missed_irq_rings)) { - if (!(dev_priv->gpu_error.test_irq_rings & intel_ring_flag(engine))) + if (!(dev_priv->gpu_error.test_irq_rings & intel_engine_flag(engine))) DRM_ERROR("Hangcheck timer elapsed... %s idle\n", engine->name); else @@ -3184,7 +3184,7 @@ static void i915_hangcheck_elapsed(struct work_struct *work) busy_count += busy; } - for_each_ring(engine, dev_priv, i) { + for_each_engine(engine, dev_priv, i) { if (engine->hangcheck.score >= HANGCHECK_SCORE_RING_HUNG) { DRM_INFO("%s on %s\n", stuck[i] ? "stuck" : "no progress", diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index 923cf6e4d8b6..afdd8aefb5b7 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h @@ -487,7 +487,7 @@ TRACE_EVENT(i915_gem_ring_dispatch, TP_fast_assign( struct intel_engine_cs *engine = - i915_gem_request_get_ring(req); + i915_gem_request_get_engine(req); __entry->dev = engine->dev->primary->index; __entry->ring = engine->id; __entry->seqno = i915_gem_request_get_seqno(req); @@ -534,7 +534,7 @@ DECLARE_EVENT_CLASS(i915_gem_request, TP_fast_assign( struct intel_engine_cs *engine = - i915_gem_request_get_ring(req); + i915_gem_request_get_engine(req); __entry->dev = engine->dev->primary->index; __entry->ring = engine->id; __entry->seqno = i915_gem_request_get_seqno(req); @@ -598,7 +598,7 @@ TRACE_EVENT(i915_gem_request_wait_begin, */ TP_fast_assign( struct intel_engine_cs *engine = - i915_gem_request_get_ring(req); + i915_gem_request_get_engine(req); __entry->dev = engine->dev->primary->index; __entry->ring = engine->id; __entry->seqno = i915_gem_request_get_seqno(req); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f271b0f706e4..79eea3d94276 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11242,7 +11242,7 @@ static bool use_mmio_flip(struct intel_engine_cs *engine, false)) return true; else - return engine != i915_gem_request_get_ring(obj->last_write_req); + return engine != i915_gem_request_get_engine(obj->last_write_req); } static void skl_do_mmio_flip(struct intel_crtc *intel_crtc, @@ -11582,7 +11582,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, } else if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) { engine = &dev_priv->engine[BCS]; } else if (INTEL_INFO(dev)->gen >= 7) { - engine = i915_gem_request_get_ring(obj->last_write_req); + engine = i915_gem_request_get_engine(obj->last_write_req); if (engine == NULL || engine->id != RCS) engine = &dev_priv->engine[BCS]; } else { diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c index fc2c5188b095..9f309211939a 100644 --- a/drivers/gpu/drm/i915/intel_guc_loader.c +++ b/drivers/gpu/drm/i915/intel_guc_loader.c @@ -87,7 +87,7 @@ static void direct_interrupts_to_host(struct drm_i915_private *dev_priv) /* tell all command streamers NOT to forward interrupts and vblank to GuC */ irqs = _MASKED_FIELD(GFX_FORWARD_VBLANK_MASK, GFX_FORWARD_VBLANK_NEVER); irqs |= _MASKED_BIT_DISABLE(GFX_INTERRUPT_STEERING); - for_each_ring(engine, dev_priv, i) + for_each_engine(engine, dev_priv, i) I915_WRITE(RING_MODE_GEN7(engine), irqs); /* route all GT interrupts to the host */ @@ -104,7 +104,7 @@ static void direct_interrupts_to_guc(struct drm_i915_private *dev_priv) /* tell all command streamers to forward interrupts and vblank to GuC */ irqs = _MASKED_FIELD(GFX_FORWARD_VBLANK_MASK, GFX_FORWARD_VBLANK_ALWAYS); irqs |= _MASKED_BIT_ENABLE(GFX_INTERRUPT_STEERING); - for_each_ring(engine, dev_priv, i) + for_each_engine(engine, dev_priv, i) I915_WRITE(RING_MODE_GEN7(engine), irqs); /* route USER_INTERRUPT to Host, all others are sent to GuC. */ diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index bbcc31f4b15d..f2cf0e168141 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -669,7 +669,7 @@ static int logical_ring_invalidate_all_caches(struct drm_i915_gem_request *req) static int execlists_move_to_gpu(struct drm_i915_gem_request *req, struct list_head *vmas) { - const unsigned other_rings = ~intel_ring_flag(req->engine); + const unsigned other_rings = ~intel_engine_flag(req->engine); struct i915_vma *vma; uint32_t flush_domains = 0; bool flush_chipset = false; @@ -1057,7 +1057,7 @@ void intel_logical_ring_stop(struct intel_engine_cs *engine) if (!intel_ring_initialized(engine)) return; - ret = intel_ring_idle(engine); + ret = intel_engine_idle(engine); if (ret && !i915_reset_in_progress(&to_i915(engine->dev)->gpu_error)) DRM_ERROR("failed to quiesce %s whilst cleaning up: %d\n", engine->name, ret); @@ -1688,7 +1688,7 @@ static int gen8_emit_bb_start(struct drm_i915_gem_request *req, * not idle). PML4 is allocated during ppgtt init so this is * not needed in 48-bit.*/ if (req->ctx->ppgtt && - (intel_ring_flag(req->engine) & req->ctx->ppgtt->pd_dirty_rings)) { + (intel_engine_flag(req->engine) & req->ctx->ppgtt->pd_dirty_rings)) { if (!USES_FULL_48BIT_PPGTT(req->i915) && !intel_vgpu_active(req->i915->dev)) { ret = intel_logical_ring_emit_pdps(req); @@ -1696,7 +1696,7 @@ static int gen8_emit_bb_start(struct drm_i915_gem_request *req, return ret; } - req->ctx->ppgtt->pd_dirty_rings &= ~intel_ring_flag(req->engine); + req->ctx->ppgtt->pd_dirty_rings &= ~intel_engine_flag(req->engine); } ret = intel_logical_ring_begin(req, 4); @@ -2511,7 +2511,7 @@ void intel_lr_context_free(struct intel_context *ctx) { int i; - for (i = I915_NUM_RINGS; --i >= 0; ) { + for (i = I915_NUM_ENGINES; --i >= 0; ) { struct intel_ringbuffer *ringbuf = ctx->engine[i].ringbuf; struct drm_i915_gem_object *ctx_obj = ctx->engine[i].state; @@ -2674,7 +2674,7 @@ void intel_lr_context_reset(struct drm_device *dev, struct intel_engine_cs *engine; int i; - for_each_ring(engine, dev_priv, i) { + for_each_engine(engine, dev_priv, i) { struct drm_i915_gem_object *ctx_obj = ctx->engine[engine->id].state; struct intel_ringbuffer *ringbuf = diff --git a/drivers/gpu/drm/i915/intel_mocs.c b/drivers/gpu/drm/i915/intel_mocs.c index 2c895637ab50..6e936c7e382a 100644 --- a/drivers/gpu/drm/i915/intel_mocs.c +++ b/drivers/gpu/drm/i915/intel_mocs.c @@ -328,7 +328,7 @@ int intel_rcs_context_init_mocs(struct drm_i915_gem_request *req) enum intel_ring_id ring_id; /* Program the control registers */ - for_each_ring(engine, dev_priv, ring_id) { + for_each_engine(engine, dev_priv, ring_id) { ret = emit_mocs_control_table(req, &t, ring_id); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index e51c28487696..20c8243ef705 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4838,7 +4838,7 @@ static void gen9_enable_rc6(struct drm_device *dev) I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16); I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */ I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */ - for_each_ring(engine, dev_priv, unused) + for_each_engine(engine, dev_priv, unused) I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10); if (HAS_GUC_UCODE(dev)) @@ -4906,7 +4906,7 @@ static void gen8_enable_rps(struct drm_device *dev) I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16); I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */ I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */ - for_each_ring(engine, dev_priv, unused) + for_each_engine(engine, dev_priv, unused) I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10); I915_WRITE(GEN6_RC_SLEEP, 0); if (IS_BROADWELL(dev)) @@ -5003,7 +5003,7 @@ static void gen6_enable_rps(struct drm_device *dev) I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); - for_each_ring(engine, dev_priv, i) + for_each_engine(engine, dev_priv, i) I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10); I915_WRITE(GEN6_RC_SLEEP, 0); @@ -5522,7 +5522,7 @@ static void cherryview_enable_rps(struct drm_device *dev) I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */ I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */ - for_each_ring(engine, dev_priv, i) + for_each_engine(engine, dev_priv, i) I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10); I915_WRITE(GEN6_RC_SLEEP, 0); @@ -5633,7 +5633,7 @@ static void valleyview_enable_rps(struct drm_device *dev) I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); - for_each_ring(engine, dev_priv, i) + for_each_engine(engine, dev_priv, i) I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10); I915_WRITE(GEN6_RC6_THRESHOLD, 0x557); @@ -6019,7 +6019,7 @@ bool i915_gpu_busy(void) goto out_unlock; dev_priv = i915_mch_dev; - for_each_ring(engine, dev_priv, i) + for_each_engine(engine, dev_priv, i) ret |= !list_empty(&engine->request_list); out_unlock: diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 7075b93a8fc9..f7493c5bff07 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -62,7 +62,7 @@ int intel_ring_space(struct intel_ringbuffer *ringbuf) bool intel_ring_stopped(struct intel_engine_cs *engine) { struct drm_i915_private *dev_priv = engine->dev->dev_private; - return dev_priv->gpu_error.stop_rings & intel_ring_flag(engine); + return dev_priv->gpu_error.stop_rings & intel_engine_flag(engine); } static void __intel_ring_advance(struct intel_engine_cs *engine) @@ -1283,7 +1283,7 @@ static int gen8_rcs_signal(struct drm_i915_gem_request *signaller_req, if (ret) return ret; - for_each_ring(waiter, dev_priv, i) { + for_each_engine(waiter, dev_priv, i) { u32 seqno; u64 gtt_offset = signaller->semaphore.signal_ggtt[i]; if (gtt_offset == MI_SEMAPHORE_SYNC_INVALID) @@ -1324,7 +1324,7 @@ static int gen8_xcs_signal(struct drm_i915_gem_request *signaller_req, if (ret) return ret; - for_each_ring(waiter, dev_priv, i) { + for_each_engine(waiter, dev_priv, i) { u32 seqno; u64 gtt_offset = signaller->semaphore.signal_ggtt[i]; if (gtt_offset == MI_SEMAPHORE_SYNC_INVALID) @@ -1363,7 +1363,7 @@ static int gen6_signal(struct drm_i915_gem_request *signaller_req, if (ret) return ret; - for_each_ring(useless, dev_priv, i) { + for_each_engine(useless, dev_priv, i) { i915_reg_t mbox_reg = signaller->semaphore.mbox.signal[i]; if (i915_mmio_reg_valid(mbox_reg)) { @@ -2356,7 +2356,7 @@ static void __wrap_ring_buffer(struct intel_ringbuffer *ringbuf) intel_ring_update_space(ringbuf); } -int intel_ring_idle(struct intel_engine_cs *engine) +int intel_engine_idle(struct intel_engine_cs *engine) { struct drm_i915_gem_request *req; @@ -3170,7 +3170,7 @@ intel_stop_ring_buffer(struct intel_engine_cs *engine) if (!intel_ring_initialized(engine)) return; - ret = intel_ring_idle(engine); + ret = intel_engine_idle(engine); if (ret && !i915_reset_in_progress(&to_i915(engine->dev)->gpu_error)) DRM_ERROR("failed to quiesce %s whilst cleaning up: %d\n", engine->name, ret); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 4b0114e3c467..ee4d9a8ddc04 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -55,12 +55,12 @@ struct intel_hw_status_page { #define i915_semaphore_seqno_size sizeof(uint64_t) #define GEN8_SIGNAL_OFFSET(__ring, to) \ (i915_gem_obj_ggtt_offset(dev_priv->semaphore_obj) + \ - ((__ring)->id * I915_NUM_RINGS * i915_semaphore_seqno_size) + \ + ((__ring)->id * I915_NUM_ENGINES * i915_semaphore_seqno_size) + \ (i915_semaphore_seqno_size * (to))) #define GEN8_WAIT_OFFSET(__ring, from) \ (i915_gem_obj_ggtt_offset(dev_priv->semaphore_obj) + \ - ((from) * I915_NUM_RINGS * i915_semaphore_seqno_size) + \ + ((from) * I915_NUM_ENGINES * i915_semaphore_seqno_size) + \ (i915_semaphore_seqno_size * (__ring)->id)) #define GEN8_RING_SEMAPHORE_INIT(e) do { \ @@ -153,7 +153,7 @@ struct intel_engine_cs { VCS2, /* Keep instances of the same type engine together. */ VECS } id; -#define I915_NUM_RINGS 5 +#define I915_NUM_ENGINES 5 #define _VCS(n) (VCS + (n)) unsigned int exec_id; unsigned int guc_id; @@ -244,16 +244,16 @@ struct intel_engine_cs { * ie. transpose of f(x, y) */ struct { - u32 sync_seqno[I915_NUM_RINGS-1]; + u32 sync_seqno[I915_NUM_ENGINES-1]; union { struct { /* our mbox written by others */ - u32 wait[I915_NUM_RINGS]; + u32 wait[I915_NUM_ENGINES]; /* mboxes this ring signals to */ - i915_reg_t signal[I915_NUM_RINGS]; + i915_reg_t signal[I915_NUM_ENGINES]; } mbox; - u64 signal_ggtt[I915_NUM_RINGS]; + u64 signal_ggtt[I915_NUM_ENGINES]; }; /* AKA wait() */ @@ -361,7 +361,7 @@ intel_ring_initialized(struct intel_engine_cs *engine) } static inline unsigned -intel_ring_flag(struct intel_engine_cs *engine) +intel_engine_flag(struct intel_engine_cs *engine) { return 1 << engine->id; } @@ -382,7 +382,7 @@ intel_ring_sync_index(struct intel_engine_cs *engine, idx = (other - engine) - 1; if (idx < 0) - idx += I915_NUM_RINGS; + idx += I915_NUM_ENGINES; return idx; } @@ -467,7 +467,7 @@ void intel_ring_update_space(struct intel_ringbuffer *ringbuf); int intel_ring_space(struct intel_ringbuffer *ringbuf); bool intel_ring_stopped(struct intel_engine_cs *engine); -int __must_check intel_ring_idle(struct intel_engine_cs *engine); +int __must_check intel_engine_idle(struct intel_engine_cs *engine); void intel_ring_init_seqno(struct intel_engine_cs *engine, u32 seqno); int intel_ring_flush_all_caches(struct drm_i915_gem_request *req); int intel_ring_invalidate_all_caches(struct drm_i915_gem_request *req); diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index d31447f6fa32..02add02e0ce4 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -1573,14 +1573,14 @@ static int gen8_do_reset(struct drm_device *dev) struct intel_engine_cs *engine; int i; - for_each_ring(engine, dev_priv, i) + for_each_engine(engine, dev_priv, i) if (gen8_request_engine_reset(engine)) goto not_ready; return gen6_do_reset(dev); not_ready: - for_each_ring(engine, dev_priv, i) + for_each_engine(engine, dev_priv, i) gen8_unrequest_engine_reset(engine); return -EIO; -- cgit v1.2.3 From 117897f42c87c11a3a8315507d38cbd99ea46fda Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Wed, 16 Mar 2016 11:00:40 +0000 Subject: drm/i915: More renaming of rings to engines This time using only sed and a few by hand. v2: Rename also intel_ring_id and intel_ring_initialized. v3: Fixed typo in intel_ring_initialized. Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1458126040-33105-1-git-send-email-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/i915_debugfs.c | 2 +- drivers/gpu/drm/i915/i915_dma.c | 12 +++---- drivers/gpu/drm/i915/i915_drv.h | 14 ++++----- drivers/gpu/drm/i915/i915_gem.c | 50 +++++++++++++++--------------- drivers/gpu/drm/i915/i915_gem_debug.c | 2 +- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 4 +-- drivers/gpu/drm/i915/i915_irq.c | 2 +- drivers/gpu/drm/i915/intel_lrc.c | 8 ++--- drivers/gpu/drm/i915/intel_mocs.c | 6 ++-- drivers/gpu/drm/i915/intel_ringbuffer.c | 16 +++++----- drivers/gpu/drm/i915/intel_ringbuffer.h | 10 +++--- 11 files changed, 63 insertions(+), 63 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index dabce8403d56..1d8c3ef29318 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2483,7 +2483,7 @@ static int i915_guc_info(struct seq_file *m, void *data) struct intel_guc guc; struct i915_guc_client client = {}; struct intel_engine_cs *engine; - enum intel_ring_id i; + enum intel_engine_id i; u64 total = 0; if (!HAS_GUC_SCHED(dev_priv->dev)) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 19f605b0cd6d..85b31300103d 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -87,16 +87,16 @@ static int i915_getparam(struct drm_device *dev, void *data, value = 1; break; case I915_PARAM_HAS_BSD: - value = intel_ring_initialized(&dev_priv->engine[VCS]); + value = intel_engine_initialized(&dev_priv->engine[VCS]); break; case I915_PARAM_HAS_BLT: - value = intel_ring_initialized(&dev_priv->engine[BCS]); + value = intel_engine_initialized(&dev_priv->engine[BCS]); break; case I915_PARAM_HAS_VEBOX: - value = intel_ring_initialized(&dev_priv->engine[VECS]); + value = intel_engine_initialized(&dev_priv->engine[VECS]); break; case I915_PARAM_HAS_BSD2: - value = intel_ring_initialized(&dev_priv->engine[VCS2]); + value = intel_engine_initialized(&dev_priv->engine[VCS2]); break; case I915_PARAM_HAS_RELAXED_FENCING: value = 1; @@ -444,7 +444,7 @@ static int i915_load_modeset_init(struct drm_device *dev) cleanup_gem: mutex_lock(&dev->struct_mutex); - i915_gem_cleanup_ringbuffer(dev); + i915_gem_cleanup_engines(dev); i915_gem_context_fini(dev); mutex_unlock(&dev->struct_mutex); cleanup_irq: @@ -1261,7 +1261,7 @@ int i915_driver_unload(struct drm_device *dev) intel_guc_ucode_fini(dev); mutex_lock(&dev->struct_mutex); - i915_gem_cleanup_ringbuffer(dev); + i915_gem_cleanup_engines(dev); i915_gem_context_fini(dev); mutex_unlock(&dev->struct_mutex); intel_fbc_cleanup_cfb(dev_priv); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index db999c24c192..fd1ed66dd298 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1931,9 +1931,9 @@ struct drm_i915_private { int (*execbuf_submit)(struct i915_execbuffer_params *params, struct drm_i915_gem_execbuffer2 *args, struct list_head *vmas); - int (*init_rings)(struct drm_device *dev); - void (*cleanup_ring)(struct intel_engine_cs *ring); - void (*stop_ring)(struct intel_engine_cs *ring); + int (*init_engines)(struct drm_device *dev); + void (*cleanup_engine)(struct intel_engine_cs *engine); + void (*stop_engine)(struct intel_engine_cs *engine); } gt; struct intel_context *kernel_context; @@ -1969,7 +1969,7 @@ static inline struct drm_i915_private *guc_to_i915(struct intel_guc *guc) /* Iterate over initialised rings */ #define for_each_engine(ring__, dev_priv__, i__) \ for ((i__) = 0; (i__) < I915_NUM_ENGINES; (i__)++) \ - for_each_if ((((ring__) = &(dev_priv__)->engine[(i__)]), intel_ring_initialized((ring__)))) + for_each_if ((((ring__) = &(dev_priv__)->engine[(i__)]), intel_engine_initialized((ring__)))) enum hdmi_force_audio { HDMI_AUDIO_OFF_DVI = -2, /* no aux data for HDMI-DVI converter */ @@ -2039,7 +2039,7 @@ struct drm_i915_gem_object { struct drm_mm_node *stolen; struct list_head global_list; - struct list_head ring_list[I915_NUM_ENGINES]; + struct list_head engine_list[I915_NUM_ENGINES]; /** Used in execbuf to temporarily hold a ref */ struct list_head obj_exec_link; @@ -3002,11 +3002,11 @@ static inline bool i915_stop_ring_allow_warn(struct drm_i915_private *dev_priv) void i915_gem_reset(struct drm_device *dev); bool i915_gem_clflush_object(struct drm_i915_gem_object *obj, bool force); int __must_check i915_gem_init(struct drm_device *dev); -int i915_gem_init_rings(struct drm_device *dev); +int i915_gem_init_engines(struct drm_device *dev); int __must_check i915_gem_init_hw(struct drm_device *dev); int i915_gem_l3_remap(struct drm_i915_gem_request *req, int slice); void i915_gem_init_swizzling(struct drm_device *dev); -void i915_gem_cleanup_ringbuffer(struct drm_device *dev); +void i915_gem_cleanup_engines(struct drm_device *dev); int __must_check i915_gpu_idle(struct drm_device *dev); int __must_check i915_gem_suspend(struct drm_device *dev); void __i915_add_request(struct drm_i915_gem_request *req, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0ae193f9bcbe..31652c1da761 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2413,7 +2413,7 @@ void i915_vma_move_to_active(struct i915_vma *vma, drm_gem_object_reference(&obj->base); obj->active |= intel_engine_flag(engine); - list_move_tail(&obj->ring_list[engine->id], &engine->active_list); + list_move_tail(&obj->engine_list[engine->id], &engine->active_list); i915_gem_request_assign(&obj->last_read_req[engine->id], req); list_move_tail(&vma->vm_link, &vma->vm->active_list); @@ -2437,7 +2437,7 @@ i915_gem_object_retire__read(struct drm_i915_gem_object *obj, int ring) RQ_BUG_ON(obj->last_read_req[ring] == NULL); RQ_BUG_ON(!(obj->active & (1 << ring))); - list_del_init(&obj->ring_list[ring]); + list_del_init(&obj->engine_list[ring]); i915_gem_request_assign(&obj->last_read_req[ring], NULL); if (obj->last_write_req && obj->last_write_req->engine->id == ring) @@ -2830,7 +2830,7 @@ static void i915_gem_reset_engine_cleanup(struct drm_i915_private *dev_priv, obj = list_first_entry(&engine->active_list, struct drm_i915_gem_object, - ring_list[engine->id]); + engine_list[engine->id]); i915_gem_object_retire__read(obj, engine->id); } @@ -2941,7 +2941,7 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *engine) obj = list_first_entry(&engine->active_list, struct drm_i915_gem_object, - ring_list[engine->id]); + engine_list[engine->id]); if (!list_empty(&obj->last_read_req[engine->id]->list)) break; @@ -4448,7 +4448,7 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj, INIT_LIST_HEAD(&obj->global_list); for (i = 0; i < I915_NUM_ENGINES; i++) - INIT_LIST_HEAD(&obj->ring_list[i]); + INIT_LIST_HEAD(&obj->engine_list[i]); INIT_LIST_HEAD(&obj->obj_exec_link); INIT_LIST_HEAD(&obj->vma_list); INIT_LIST_HEAD(&obj->batch_pool_link); @@ -4653,14 +4653,14 @@ void i915_gem_vma_destroy(struct i915_vma *vma) } static void -i915_gem_stop_ringbuffers(struct drm_device *dev) +i915_gem_stop_engines(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *engine; int i; for_each_engine(engine, dev_priv, i) - dev_priv->gt.stop_ring(engine); + dev_priv->gt.stop_engine(engine); } int @@ -4676,7 +4676,7 @@ i915_gem_suspend(struct drm_device *dev) i915_gem_retire_requests(dev); - i915_gem_stop_ringbuffers(dev); + i915_gem_stop_engines(dev); mutex_unlock(&dev->struct_mutex); cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work); @@ -4778,7 +4778,7 @@ static void init_unused_rings(struct drm_device *dev) } } -int i915_gem_init_rings(struct drm_device *dev) +int i915_gem_init_engines(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; int ret; @@ -4814,13 +4814,13 @@ int i915_gem_init_rings(struct drm_device *dev) return 0; cleanup_vebox_ring: - intel_cleanup_ring_buffer(&dev_priv->engine[VECS]); + intel_cleanup_engine(&dev_priv->engine[VECS]); cleanup_blt_ring: - intel_cleanup_ring_buffer(&dev_priv->engine[BCS]); + intel_cleanup_engine(&dev_priv->engine[BCS]); cleanup_bsd_ring: - intel_cleanup_ring_buffer(&dev_priv->engine[VCS]); + intel_cleanup_engine(&dev_priv->engine[VCS]); cleanup_render_ring: - intel_cleanup_ring_buffer(&dev_priv->engine[RCS]); + intel_cleanup_engine(&dev_priv->engine[RCS]); return ret; } @@ -4907,7 +4907,7 @@ i915_gem_init_hw(struct drm_device *dev) req = i915_gem_request_alloc(engine, NULL); if (IS_ERR(req)) { ret = PTR_ERR(req); - i915_gem_cleanup_ringbuffer(dev); + i915_gem_cleanup_engines(dev); goto out; } @@ -4920,7 +4920,7 @@ i915_gem_init_hw(struct drm_device *dev) if (ret && ret != -EIO) { DRM_ERROR("PPGTT enable ring #%d failed %d\n", i, ret); i915_gem_request_cancel(req); - i915_gem_cleanup_ringbuffer(dev); + i915_gem_cleanup_engines(dev); goto out; } @@ -4928,7 +4928,7 @@ i915_gem_init_hw(struct drm_device *dev) if (ret && ret != -EIO) { DRM_ERROR("Context enable ring #%d failed %d\n", i, ret); i915_gem_request_cancel(req); - i915_gem_cleanup_ringbuffer(dev); + i915_gem_cleanup_engines(dev); goto out; } @@ -4952,14 +4952,14 @@ int i915_gem_init(struct drm_device *dev) if (!i915.enable_execlists) { dev_priv->gt.execbuf_submit = i915_gem_ringbuffer_submission; - dev_priv->gt.init_rings = i915_gem_init_rings; - dev_priv->gt.cleanup_ring = intel_cleanup_ring_buffer; - dev_priv->gt.stop_ring = intel_stop_ring_buffer; + dev_priv->gt.init_engines = i915_gem_init_engines; + dev_priv->gt.cleanup_engine = intel_cleanup_engine; + dev_priv->gt.stop_engine = intel_stop_engine; } else { dev_priv->gt.execbuf_submit = intel_execlists_submission; - dev_priv->gt.init_rings = intel_logical_rings_init; - dev_priv->gt.cleanup_ring = intel_logical_ring_cleanup; - dev_priv->gt.stop_ring = intel_logical_ring_stop; + dev_priv->gt.init_engines = intel_logical_rings_init; + dev_priv->gt.cleanup_engine = intel_logical_ring_cleanup; + dev_priv->gt.stop_engine = intel_logical_ring_stop; } /* This is just a security blanket to placate dragons. @@ -4980,7 +4980,7 @@ int i915_gem_init(struct drm_device *dev) if (ret) goto out_unlock; - ret = dev_priv->gt.init_rings(dev); + ret = dev_priv->gt.init_engines(dev); if (ret) goto out_unlock; @@ -5003,14 +5003,14 @@ out_unlock: } void -i915_gem_cleanup_ringbuffer(struct drm_device *dev) +i915_gem_cleanup_engines(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *engine; int i; for_each_engine(engine, dev_priv, i) - dev_priv->gt.cleanup_ring(engine); + dev_priv->gt.cleanup_engine(engine); if (i915.enable_execlists) /* diff --git a/drivers/gpu/drm/i915/i915_gem_debug.c b/drivers/gpu/drm/i915/i915_gem_debug.c index e0bca7d5b0d6..ef9cd700f02f 100644 --- a/drivers/gpu/drm/i915/i915_gem_debug.c +++ b/drivers/gpu/drm/i915/i915_gem_debug.c @@ -45,7 +45,7 @@ i915_verify_lists(struct drm_device *dev) for_each_engine(engine, dev_priv, i) { list_for_each_entry(obj, &engine->active_list, - ring_list[engine->id]) { + engine_list[engine->id]) { if (obj->base.dev != dev || !atomic_read(&obj->base.refcount.refcount)) { DRM_ERROR("%s: freed active obj %p\n", diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index c0545db85a8c..dac01ee8cfa3 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -1369,7 +1369,7 @@ eb_get_batch(struct eb_vmas *eb) #define I915_USER_RINGS (4) -static const enum intel_ring_id user_ring_map[I915_USER_RINGS + 1] = { +static const enum intel_engine_id user_ring_map[I915_USER_RINGS + 1] = { [I915_EXEC_DEFAULT] = RCS, [I915_EXEC_RENDER] = RCS, [I915_EXEC_BLT] = BCS, @@ -1417,7 +1417,7 @@ eb_select_ring(struct drm_i915_private *dev_priv, *ring = &dev_priv->engine[user_ring_map[user_ring_id]]; } - if (!intel_ring_initialized(*ring)) { + if (!intel_engine_initialized(*ring)) { DRM_DEBUG("execbuf with invalid ring: %u\n", user_ring_id); return -EINVAL; } diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 63ed77fe6bc4..0f61ae0ff609 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -996,7 +996,7 @@ static void ironlake_rps_change_irq_handler(struct drm_device *dev) static void notify_ring(struct intel_engine_cs *engine) { - if (!intel_ring_initialized(engine)) + if (!intel_engine_initialized(engine)) return; trace_i915_gem_request_notify(engine); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index f2cf0e168141..f72782200226 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -795,7 +795,7 @@ intel_logical_ring_advance_and_submit(struct drm_i915_gem_request *request) intel_logical_ring_emit(ringbuf, MI_NOOP); intel_logical_ring_advance(ringbuf); - if (intel_ring_stopped(engine)) + if (intel_engine_stopped(engine)) return 0; if (engine->last_context != request->ctx) { @@ -1054,7 +1054,7 @@ void intel_logical_ring_stop(struct intel_engine_cs *engine) struct drm_i915_private *dev_priv = engine->dev->dev_private; int ret; - if (!intel_ring_initialized(engine)) + if (!intel_engine_initialized(engine)) return; ret = intel_engine_idle(engine); @@ -2012,7 +2012,7 @@ void intel_logical_ring_cleanup(struct intel_engine_cs *engine) { struct drm_i915_private *dev_priv; - if (!intel_ring_initialized(engine)) + if (!intel_engine_initialized(engine)) return; dev_priv = engine->dev->dev_private; @@ -2240,7 +2240,7 @@ static int logical_vebox_ring_init(struct drm_device *dev) * @dev: DRM device. * * This function inits the engines for an Execlists submission style (the equivalent in the - * legacy ringbuffer submission world would be i915_gem_init_rings). It does it only for + * legacy ringbuffer submission world would be i915_gem_init_engines). It does it only for * those engines that are present in the hardware. * * Return: non-zero if the initialization failed. diff --git a/drivers/gpu/drm/i915/intel_mocs.c b/drivers/gpu/drm/i915/intel_mocs.c index 6e936c7e382a..3c725dde16ed 100644 --- a/drivers/gpu/drm/i915/intel_mocs.c +++ b/drivers/gpu/drm/i915/intel_mocs.c @@ -159,7 +159,7 @@ static bool get_mocs_settings(struct drm_device *dev, return result; } -static i915_reg_t mocs_register(enum intel_ring_id ring, int index) +static i915_reg_t mocs_register(enum intel_engine_id ring, int index) { switch (ring) { case RCS: @@ -191,7 +191,7 @@ static i915_reg_t mocs_register(enum intel_ring_id ring, int index) */ static int emit_mocs_control_table(struct drm_i915_gem_request *req, const struct drm_i915_mocs_table *table, - enum intel_ring_id ring) + enum intel_engine_id ring) { struct intel_ringbuffer *ringbuf = req->ringbuf; unsigned int index; @@ -325,7 +325,7 @@ int intel_rcs_context_init_mocs(struct drm_i915_gem_request *req) if (get_mocs_settings(req->engine->dev, &t)) { struct drm_i915_private *dev_priv = req->i915; struct intel_engine_cs *engine; - enum intel_ring_id ring_id; + enum intel_engine_id ring_id; /* Program the control registers */ for_each_engine(engine, dev_priv, ring_id) { diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index f7493c5bff07..015dc7db32b7 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -59,7 +59,7 @@ int intel_ring_space(struct intel_ringbuffer *ringbuf) return ringbuf->space; } -bool intel_ring_stopped(struct intel_engine_cs *engine) +bool intel_engine_stopped(struct intel_engine_cs *engine) { struct drm_i915_private *dev_priv = engine->dev->dev_private; return dev_priv->gpu_error.stop_rings & intel_engine_flag(engine); @@ -69,7 +69,7 @@ static void __intel_ring_advance(struct intel_engine_cs *engine) { struct intel_ringbuffer *ringbuf = engine->buffer; ringbuf->tail &= ringbuf->size - 1; - if (intel_ring_stopped(engine)) + if (intel_engine_stopped(engine)) return; engine->write_tail(engine, ringbuf->tail); } @@ -2274,21 +2274,21 @@ static int intel_init_ring_buffer(struct drm_device *dev, return 0; error: - intel_cleanup_ring_buffer(engine); + intel_cleanup_engine(engine); return ret; } -void intel_cleanup_ring_buffer(struct intel_engine_cs *engine) +void intel_cleanup_engine(struct intel_engine_cs *engine) { struct drm_i915_private *dev_priv; - if (!intel_ring_initialized(engine)) + if (!intel_engine_initialized(engine)) return; dev_priv = to_i915(engine->dev); if (engine->buffer) { - intel_stop_ring_buffer(engine); + intel_stop_engine(engine); WARN_ON(!IS_GEN2(engine->dev) && (I915_READ_MODE(engine) & MODE_IDLE) == 0); intel_unpin_ringbuffer_obj(engine->buffer); @@ -3163,11 +3163,11 @@ intel_ring_invalidate_all_caches(struct drm_i915_gem_request *req) } void -intel_stop_ring_buffer(struct intel_engine_cs *engine) +intel_stop_engine(struct intel_engine_cs *engine) { int ret; - if (!intel_ring_initialized(engine)) + if (!intel_engine_initialized(engine)) return; ret = intel_engine_idle(engine); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index ee4d9a8ddc04..3e40f7bf2147 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -146,7 +146,7 @@ struct i915_ctx_workarounds { struct intel_engine_cs { const char *name; - enum intel_ring_id { + enum intel_engine_id { RCS = 0, BCS, VCS, @@ -355,7 +355,7 @@ struct intel_engine_cs { }; static inline bool -intel_ring_initialized(struct intel_engine_cs *engine) +intel_engine_initialized(struct intel_engine_cs *engine) { return engine->dev != NULL; } @@ -438,8 +438,8 @@ int intel_pin_and_map_ringbuffer_obj(struct drm_device *dev, void intel_unpin_ringbuffer_obj(struct intel_ringbuffer *ringbuf); void intel_ringbuffer_free(struct intel_ringbuffer *ring); -void intel_stop_ring_buffer(struct intel_engine_cs *engine); -void intel_cleanup_ring_buffer(struct intel_engine_cs *engine); +void intel_stop_engine(struct intel_engine_cs *engine); +void intel_cleanup_engine(struct intel_engine_cs *engine); int intel_ring_alloc_request_extras(struct drm_i915_gem_request *request); @@ -465,7 +465,7 @@ static inline void intel_ring_advance(struct intel_engine_cs *engine) int __intel_ring_space(int head, int tail, int size); void intel_ring_update_space(struct intel_ringbuffer *ringbuf); int intel_ring_space(struct intel_ringbuffer *ringbuf); -bool intel_ring_stopped(struct intel_engine_cs *engine); +bool intel_engine_stopped(struct intel_engine_cs *engine); int __must_check intel_engine_idle(struct intel_engine_cs *engine); void intel_ring_init_seqno(struct intel_engine_cs *engine, u32 seqno); -- cgit v1.2.3 From 7cc96139d9e3f627bd18e5ee6a5e4e305369865b Mon Sep 17 00:00:00 2001 From: Nathan Schulte Date: Tue, 15 Mar 2016 10:14:05 -0500 Subject: drm/i915: add module param "enable_dp_mst" Adds an (unsafe; auto-kernel-tainting) boolean module parameter to the i915 drm driver: "enable_dp_mst", which is enabled by default. Disabling the parameter forces newly connected DisplayPort sinks to report as not supporting multi-stream transport (MST), thus "forcing" the use of single-stream transport (SST). v2: rename parameter to conform to style v3: add signoff Signed-off-by: Nathan Schulte Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1458054845-5837-1-git-send-email-nmschulte@gmail.com --- drivers/gpu/drm/i915/i915_params.c | 5 +++++ drivers/gpu/drm/i915/i915_params.h | 1 + drivers/gpu/drm/i915/intel_dp.c | 3 +++ 3 files changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index 278c9c40c2e0..97691f1f679c 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -56,6 +56,7 @@ struct i915_params i915 __read_mostly = { .edp_vswing = 0, .enable_guc_submission = false, .guc_log_level = -1, + .enable_dp_mst = true, }; module_param_named(modeset, i915.modeset, int, 0400); @@ -201,3 +202,7 @@ MODULE_PARM_DESC(enable_guc_submission, "Enable GuC submission (default:false)") module_param_named(guc_log_level, i915.guc_log_level, int, 0400); MODULE_PARM_DESC(guc_log_level, "GuC firmware logging level (-1:disabled (default), 0-3:enabled)"); + +module_param_named_unsafe(enable_dp_mst, i915.enable_dp_mst, bool, 0600); +MODULE_PARM_DESC(enable_dp_mst, + "Enable multi-stream transport (MST) for new DisplayPort sinks. (default: true)"); diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h index bd5026b15d3e..87153b0199cd 100644 --- a/drivers/gpu/drm/i915/i915_params.h +++ b/drivers/gpu/drm/i915/i915_params.h @@ -59,6 +59,7 @@ struct i915_params { bool enable_guc_submission; bool verbose_state_checks; bool nuclear_pageflip; + bool enable_dp_mst; }; extern struct i915_params i915 __read_mostly; diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 0e326e776e8f..ba2d0242d532 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3882,6 +3882,9 @@ intel_dp_probe_mst(struct intel_dp *intel_dp) { u8 buf[1]; + if (!i915.enable_dp_mst) + return false; + if (!intel_dp->can_mst) return false; -- cgit v1.2.3 From 1bb4308e7130428917bfa54c556daa98f7aa1ac9 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 7 Mar 2016 12:05:57 +0000 Subject: drm/i915/csr: Allow matching unknown HW steppings with generic firmware If the firmware is generic and has a run-anywhere mode, enable it rather than completely failing on unknown HW revisions. Signed-off-by: Chris Wilson Cc: Damien Lespiau Cc: Imre Deak Cc: Sunil Kamath Cc: Daniel Vetter Cc: Animesh Manna Cc: Jani Nikula Reviewed-by: Imre Deak Signed-off-by: Imre Deak Link: http://patchwork.freedesktop.org/patch/msgid/1457352357-8433-1-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_csr.c | 46 +++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c index d417d9ab49b5..3f57cb94d9ad 100644 --- a/drivers/gpu/drm/i915/intel_csr.c +++ b/drivers/gpu/drm/i915/intel_csr.c @@ -188,28 +188,31 @@ static const struct stepping_info bxt_stepping_info[] = { {'B', '0'}, {'B', '1'}, {'B', '2'} }; -static const struct stepping_info *intel_get_stepping_info(struct drm_device *dev) +static const struct stepping_info no_stepping_info = { '*', '*' }; + +static const struct stepping_info * +intel_get_stepping_info(struct drm_i915_private *dev_priv) { const struct stepping_info *si; unsigned int size; - if (IS_KABYLAKE(dev)) { + if (IS_KABYLAKE(dev_priv)) { size = ARRAY_SIZE(kbl_stepping_info); si = kbl_stepping_info; - } else if (IS_SKYLAKE(dev)) { + } else if (IS_SKYLAKE(dev_priv)) { size = ARRAY_SIZE(skl_stepping_info); si = skl_stepping_info; - } else if (IS_BROXTON(dev)) { + } else if (IS_BROXTON(dev_priv)) { size = ARRAY_SIZE(bxt_stepping_info); si = bxt_stepping_info; } else { - return NULL; + size = 0; } - if (INTEL_REVID(dev) < size) - return si + INTEL_REVID(dev); + if (INTEL_REVID(dev_priv) < size) + return si + INTEL_REVID(dev_priv); - return NULL; + return &no_stepping_info; } static void gen9_set_dc_state_debugmask(struct drm_i915_private *dev_priv) @@ -270,13 +273,11 @@ void intel_csr_load_program(struct drm_i915_private *dev_priv) static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, const struct firmware *fw) { - struct drm_device *dev = dev_priv->dev; struct intel_css_header *css_header; struct intel_package_header *package_header; struct intel_dmc_header *dmc_header; struct intel_csr *csr = &dev_priv->csr; - const struct stepping_info *stepping_info = intel_get_stepping_info(dev); - char stepping, substepping; + const struct stepping_info *si = intel_get_stepping_info(dev_priv); uint32_t dmc_offset = CSR_DEFAULT_FW_OFFSET, readcount = 0, nbytes; uint32_t i; uint32_t *dmc_payload; @@ -284,14 +285,6 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, if (!fw) return NULL; - if (!stepping_info) { - DRM_ERROR("Unknown stepping info, firmware loading failed\n"); - return NULL; - } - - stepping = stepping_info->stepping; - substepping = stepping_info->substepping; - /* Extract CSS Header information*/ css_header = (struct intel_css_header *)fw->data; if (sizeof(struct intel_css_header) != @@ -303,7 +296,7 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, csr->version = css_header->version; - if ((IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) && + if ((IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) && csr->version < SKL_CSR_VERSION_REQUIRED) { DRM_INFO("Refusing to load old Skylake DMC firmware v%u.%u," " please upgrade to v%u.%u or later" @@ -331,11 +324,11 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, /* Search for dmc_offset to find firware binary. */ for (i = 0; i < package_header->num_entries; i++) { if (package_header->fw_info[i].substepping == '*' && - stepping == package_header->fw_info[i].stepping) { + si->stepping == package_header->fw_info[i].stepping) { dmc_offset = package_header->fw_info[i].offset; break; - } else if (stepping == package_header->fw_info[i].stepping && - substepping == package_header->fw_info[i].substepping) { + } else if (si->stepping == package_header->fw_info[i].stepping && + si->substepping == package_header->fw_info[i].substepping) { dmc_offset = package_header->fw_info[i].offset; break; } else if (package_header->fw_info[i].stepping == '*' && @@ -343,7 +336,8 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, dmc_offset = package_header->fw_info[i].offset; } if (dmc_offset == CSR_DEFAULT_FW_OFFSET) { - DRM_ERROR("Firmware not supported for %c stepping\n", stepping); + DRM_ERROR("Firmware not supported for %c stepping\n", + si->stepping); return NULL; } readcount += dmc_offset; @@ -389,9 +383,7 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, return NULL; } - memcpy(dmc_payload, &fw->data[readcount], nbytes); - - return dmc_payload; + return memcpy(dmc_payload, &fw->data[readcount], nbytes); } static void csr_load_work_fn(struct work_struct *work) -- cgit v1.2.3 From 42c151e65e80d22b611ba07812374ed726ebb947 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 16 Mar 2016 12:21:39 +0200 Subject: drm/i915/dsi: lose the loose 666 format name in favor of packed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The enum mipi_dsi_pixel_format defines MIPI_DSI_FMT_RGB666 for the "loose" 24 bpp format and MIPI_DSI_FMT_RGB666_PACKED for the 18 bpp format. We have this the other way round, defining a loose version for 24 bpp. Follow suit with what's in enum mipi_dsi_pixel_format to avoid future confusion. Rename VID_MODE_FORMAT_RGB666 -> VID_MODE_FORMAT_RGB666_PACKED VID_MODE_FORMAT_RGB666_LOOSE -> VID_MODE_FORMAT_RGB666 Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1458123700-16003-1-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 4 ++-- drivers/gpu/drm/i915/intel_dsi_pll.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 7dfc4007f3fa..85ceec611412 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7887,8 +7887,8 @@ enum skl_disp_power_wells { #define VID_MODE_FORMAT_MASK (0xf << 7) #define VID_MODE_NOT_SUPPORTED (0 << 7) #define VID_MODE_FORMAT_RGB565 (1 << 7) -#define VID_MODE_FORMAT_RGB666 (2 << 7) -#define VID_MODE_FORMAT_RGB666_LOOSE (3 << 7) +#define VID_MODE_FORMAT_RGB666_PACKED (2 << 7) +#define VID_MODE_FORMAT_RGB666 (3 << 7) #define VID_MODE_FORMAT_RGB888 (4 << 7) #define CMD_MODE_CHANNEL_NUMBER_SHIFT 5 #define CMD_MODE_CHANNEL_NUMBER_MASK (3 << 5) diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c index 2451c84949bd..9ef0f7806e4a 100644 --- a/drivers/gpu/drm/i915/intel_dsi_pll.c +++ b/drivers/gpu/drm/i915/intel_dsi_pll.c @@ -37,10 +37,10 @@ int dsi_pixel_format_bpp(int pixel_format) switch (pixel_format) { default: case VID_MODE_FORMAT_RGB888: - case VID_MODE_FORMAT_RGB666_LOOSE: + case VID_MODE_FORMAT_RGB666: bpp = 24; break; - case VID_MODE_FORMAT_RGB666: + case VID_MODE_FORMAT_RGB666_PACKED: bpp = 18; break; case VID_MODE_FORMAT_RGB565: -- cgit v1.2.3 From 1e78aa014b84ff23f99daa0e0832b01337244062 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 16 Mar 2016 12:21:40 +0200 Subject: drm/i915/dsi: start using enum mipi_dsi_pixel_format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A small step moving us closer to DRM MIPI DSI code. Use enum mipi_dsi_pixel_format instead of our own. The first benefit is being able to use common mipi_dsi_pixel_format_to_bpp(). There's a little back and forth conversion with the VBT -> enum -> register, since we have just shoved the VBT value into the register directly. Longer term, all the VBT parsing and deciphering should be done in intel_bios.c, and abstracted there. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1458123700-16003-2-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_dsi.c | 25 +++++++++++++++++----- drivers/gpu/drm/i915/intel_dsi.h | 10 +++++---- drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 33 ++++++++++++++++++++++-------- drivers/gpu/drm/i915/intel_dsi_pll.c | 30 +++++---------------------- 4 files changed, 56 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 01b8e9f4c272..ea78b0bf7e14 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -787,7 +787,7 @@ static void set_dsi_timings(struct drm_encoder *encoder, struct drm_i915_private *dev_priv = dev->dev_private; struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); enum port port; - unsigned int bpp = dsi_pixel_format_bpp(intel_dsi->pixel_format); + unsigned int bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format); unsigned int lane_count = intel_dsi->lane_count; u16 hactive, hfp, hsync, hbp, vfp, vsync, vbp; @@ -849,6 +849,23 @@ static void set_dsi_timings(struct drm_encoder *encoder, } } +static u32 pixel_format_to_reg(enum mipi_dsi_pixel_format fmt) +{ + switch (fmt) { + case MIPI_DSI_FMT_RGB888: + return VID_MODE_FORMAT_RGB888; + case MIPI_DSI_FMT_RGB666: + return VID_MODE_FORMAT_RGB666; + case MIPI_DSI_FMT_RGB666_PACKED: + return VID_MODE_FORMAT_RGB666_PACKED; + case MIPI_DSI_FMT_RGB565: + return VID_MODE_FORMAT_RGB565; + default: + MISSING_CASE(fmt); + return VID_MODE_FORMAT_RGB666; + } +} + static void intel_dsi_prepare(struct intel_encoder *intel_encoder) { struct drm_encoder *encoder = &intel_encoder->base; @@ -858,7 +875,7 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder) struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); const struct drm_display_mode *adjusted_mode = &intel_crtc->config->base.adjusted_mode; enum port port; - unsigned int bpp = dsi_pixel_format_bpp(intel_dsi->pixel_format); + unsigned int bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format); u32 val, tmp; u16 mode_hdisplay; @@ -917,9 +934,7 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder) val |= CMD_MODE_DATA_WIDTH_8_BIT; /* XXX */ } else { val |= intel_dsi->channel << VID_MODE_CHANNEL_NUMBER_SHIFT; - - /* XXX: cross-check bpp vs. pixel format? */ - val |= intel_dsi->pixel_format; + val |= pixel_format_to_reg(intel_dsi->pixel_format); } tmp = 0; diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index 92f39227b361..54f072cd78f1 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h @@ -34,8 +34,6 @@ #define DSI_DUAL_LINK_FRONT_BACK 1 #define DSI_DUAL_LINK_PIXEL_ALT 2 -int dsi_pixel_format_bpp(int pixel_format); - struct intel_dsi_host; struct intel_dsi { @@ -64,8 +62,12 @@ struct intel_dsi { /* number of DSI lanes */ unsigned int lane_count; - /* video mode pixel format for MIPI_DSI_FUNC_PRG register */ - u32 pixel_format; + /* + * video mode pixel format + * + * XXX: consolidate on .format in struct mipi_dsi_device. + */ + enum mipi_dsi_pixel_format pixel_format; /* video mode format for MIPI_VIDEO_MODE_FORMAT register */ u32 video_mode_format; diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c index 7f145b4fec6a..8302a972d2d4 100644 --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c @@ -412,6 +412,25 @@ static const struct drm_panel_funcs vbt_panel_funcs = { .get_modes = vbt_panel_get_modes, }; +/* XXX: This should be done when parsing the VBT in intel_bios.c */ +static enum mipi_dsi_pixel_format pixel_format_from_vbt(u32 fmt) +{ + /* It just so happens the VBT matches register contents. */ + switch (fmt) { + case VID_MODE_FORMAT_RGB888: + return MIPI_DSI_FMT_RGB888; + case VID_MODE_FORMAT_RGB666: + return MIPI_DSI_FMT_RGB666; + case VID_MODE_FORMAT_RGB666_PACKED: + return MIPI_DSI_FMT_RGB666_PACKED; + case VID_MODE_FORMAT_RGB565: + return MIPI_DSI_FMT_RGB565; + default: + MISSING_CASE(fmt); + return MIPI_DSI_FMT_RGB666; + } +} + struct drm_panel *vbt_panel_init(struct intel_dsi *intel_dsi, u16 panel_id) { struct drm_device *dev = intel_dsi->base.base.dev; @@ -420,7 +439,7 @@ struct drm_panel *vbt_panel_init(struct intel_dsi *intel_dsi, u16 panel_id) struct mipi_pps_data *pps = dev_priv->vbt.dsi.pps; struct drm_display_mode *mode = dev_priv->vbt.lfp_lvds_vbt_mode; struct vbt_panel *vbt_panel; - u32 bits_per_pixel = 24; + u32 bpp; u32 tlpx_ns, extra_byte_count, bitrate, tlpx_ui; u32 ui_num, ui_den; u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt; @@ -436,12 +455,11 @@ struct drm_panel *vbt_panel_init(struct intel_dsi *intel_dsi, u16 panel_id) intel_dsi->eotp_pkt = mipi_config->eot_pkt_disabled ? 0 : 1; intel_dsi->clock_stop = mipi_config->enable_clk_stop ? 1 : 0; intel_dsi->lane_count = mipi_config->lane_cnt + 1; - intel_dsi->pixel_format = mipi_config->videomode_color_format << 7; + intel_dsi->pixel_format = pixel_format_from_vbt(mipi_config->videomode_color_format << 7); + bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format); + intel_dsi->dual_link = mipi_config->dual_link; intel_dsi->pixel_overlap = mipi_config->pixel_overlap; - - bits_per_pixel = dsi_pixel_format_bpp(intel_dsi->pixel_format); - intel_dsi->operation_mode = mipi_config->is_cmd_mode; intel_dsi->video_mode_format = mipi_config->video_transfer_mode; intel_dsi->escape_clk_div = mipi_config->byte_clk_sel; @@ -475,8 +493,7 @@ struct drm_panel *vbt_panel_init(struct intel_dsi *intel_dsi, u16 panel_id) */ if (intel_dsi->video_mode_format == VIDEO_MODE_BURST) { if (mipi_config->target_burst_mode_freq) { - computed_ddr = - (pclk * bits_per_pixel) / intel_dsi->lane_count; + computed_ddr = (pclk * bpp) / intel_dsi->lane_count; if (mipi_config->target_burst_mode_freq < computed_ddr) { @@ -499,7 +516,7 @@ struct drm_panel *vbt_panel_init(struct intel_dsi *intel_dsi, u16 panel_id) intel_dsi->burst_mode_ratio = burst_mode_ratio; intel_dsi->pclk = pclk; - bitrate = (pclk * bits_per_pixel) / intel_dsi->lane_count; + bitrate = (pclk * bpp) / intel_dsi->lane_count; switch (intel_dsi->escape_clk_div) { case 0: diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c index 9ef0f7806e4a..e3e343c80221 100644 --- a/drivers/gpu/drm/i915/intel_dsi_pll.c +++ b/drivers/gpu/drm/i915/intel_dsi_pll.c @@ -30,27 +30,6 @@ #include "i915_drv.h" #include "intel_dsi.h" -int dsi_pixel_format_bpp(int pixel_format) -{ - int bpp; - - switch (pixel_format) { - default: - case VID_MODE_FORMAT_RGB888: - case VID_MODE_FORMAT_RGB666: - bpp = 24; - break; - case VID_MODE_FORMAT_RGB666_PACKED: - bpp = 18; - break; - case VID_MODE_FORMAT_RGB565: - bpp = 16; - break; - } - - return bpp; -} - struct dsi_mnp { u32 dsi_pll_ctrl; u32 dsi_pll_div; @@ -64,10 +43,11 @@ static const u32 lfsr_converts[] = { }; /* Get DSI clock from pixel clock */ -static u32 dsi_clk_from_pclk(u32 pclk, int pixel_format, int lane_count) +static u32 dsi_clk_from_pclk(u32 pclk, enum mipi_dsi_pixel_format fmt, + int lane_count) { u32 dsi_clk_khz; - u32 bpp = dsi_pixel_format_bpp(pixel_format); + u32 bpp = mipi_dsi_pixel_format_to_bpp(fmt); /* DSI data rate = pixel clock * bits per pixel / lane count pixel clock is converted from KHz to Hz */ @@ -232,9 +212,9 @@ static void bxt_disable_dsi_pll(struct intel_encoder *encoder) DRM_ERROR("Timeout waiting for PLL lock deassertion\n"); } -static void assert_bpp_mismatch(int pixel_format, int pipe_bpp) +static void assert_bpp_mismatch(enum mipi_dsi_pixel_format fmt, int pipe_bpp) { - int bpp = dsi_pixel_format_bpp(pixel_format); + int bpp = mipi_dsi_pixel_format_to_bpp(fmt); WARN(bpp != pipe_bpp, "bpp match assertion failure (expected %d, current %d)\n", -- cgit v1.2.3 From c3aeadc8d3580b319d51c62fb82255b06a1c4fd8 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 15 Mar 2016 21:51:09 +0200 Subject: drm/i915: add for_each_port_masked macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same as for_each_dsi_port, but for general use. Leave the for_each_dsi_port version around as an "alias" for now to not cause too much churn. No functional changes. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/a0ef5bf33395e1fcd87178b17d6687b022042cf7.1458070700.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 4 ++++ drivers/gpu/drm/i915/intel_dsi.h | 4 +--- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index fd1ed66dd298..e5e2982cbd83 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -274,6 +274,10 @@ struct i915_hotplug { (__s) < INTEL_INFO(__dev_priv)->num_sprites[(__p)]; \ (__s)++) +#define for_each_port_masked(__port, __ports_mask) \ + for ((__port) = PORT_A; (__port) < I915_MAX_PORTS; (__port)++) \ + for_each_if ((__ports_mask) & (1 << (__port))) + #define for_each_crtc(dev, crtc) \ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index 54f072cd78f1..e582ef8f3dac 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h @@ -119,9 +119,7 @@ static inline struct intel_dsi_host *to_intel_dsi_host(struct mipi_dsi_host *h) return container_of(h, struct intel_dsi_host, base); } -#define for_each_dsi_port(__port, __ports_mask) \ - for ((__port) = PORT_A; (__port) < I915_MAX_PORTS; (__port)++) \ - for_each_if ((__ports_mask) & (1 << (__port))) +#define for_each_dsi_port(__port, __ports_mask) for_each_port_masked(__port, __ports_mask) static inline struct intel_dsi *enc_to_intel_dsi(struct drm_encoder *encoder) { -- cgit v1.2.3 From da20563097796cdba10e253581861ad0e2b0c695 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 15 Mar 2016 21:51:10 +0200 Subject: drm/i915: make transcoder_name return a string MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nicer for eDP (actually "EDP" instead of "D"), and makes future expansion for DSI transcoders easier. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/2ac55ed584e450fe154daecb6453dff8eede5e7d.1458070700.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 17 ++++++++++++++++- drivers/gpu/drm/i915/intel_display.c | 4 ++-- drivers/gpu/drm/i915/intel_fifo_underrun.c | 6 +++--- 3 files changed, 21 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index e5e2982cbd83..33e13116854b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -125,7 +125,22 @@ enum transcoder { TRANSCODER_EDP, I915_MAX_TRANSCODERS }; -#define transcoder_name(t) ((t) + 'A') + +static inline const char *transcoder_name(enum transcoder transcoder) +{ + switch (transcoder) { + case TRANSCODER_A: + return "A"; + case TRANSCODER_B: + return "B"; + case TRANSCODER_C: + return "C"; + case TRANSCODER_EDP: + return "EDP"; + default: + return ""; + } +} /* * I915_MAX_PLANES in the enum below is the maximum (across all platforms) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 79eea3d94276..f3bcafa22e84 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12092,7 +12092,7 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc, DRM_DEBUG_KMS("[CRTC:%d]%s config %p for pipe %c\n", crtc->base.base.id, context, pipe_config, pipe_name(crtc->pipe)); - DRM_DEBUG_KMS("cpu_transcoder: %c\n", transcoder_name(pipe_config->cpu_transcoder)); + DRM_DEBUG_KMS("cpu_transcoder: %s\n", transcoder_name(pipe_config->cpu_transcoder)); DRM_DEBUG_KMS("pipe bpp: %i, dithering: %i\n", pipe_config->pipe_bpp, pipe_config->dither); DRM_DEBUG_KMS("fdi/pch: %i, lanes: %i, gmch_m: %u, gmch_n: %u, link_m: %u, link_n: %u, tu: %u\n", @@ -16221,7 +16221,7 @@ intel_display_print_error_state(struct drm_i915_error_state_buf *m, } for (i = 0; i < error->num_transcoders; i++) { - err_printf(m, "CPU transcoder: %c\n", + err_printf(m, "CPU transcoder: %s\n", transcoder_name(error->transcoder[i].cpu_transcoder)); err_printf(m, " Power: %s\n", onoff(error->transcoder[i].power_domain_on)); diff --git a/drivers/gpu/drm/i915/intel_fifo_underrun.c b/drivers/gpu/drm/i915/intel_fifo_underrun.c index bda526660e20..19e50fdf9a91 100644 --- a/drivers/gpu/drm/i915/intel_fifo_underrun.c +++ b/drivers/gpu/drm/i915/intel_fifo_underrun.c @@ -212,7 +212,7 @@ static void cpt_check_pch_fifo_underruns(struct intel_crtc *crtc) I915_WRITE(SERR_INT, SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)); POSTING_READ(SERR_INT); - DRM_ERROR("pch fifo underrun on pch transcoder %c\n", + DRM_ERROR("pch fifo underrun on pch transcoder %s\n", transcoder_name(pch_transcoder)); } @@ -235,7 +235,7 @@ static void cpt_set_fifo_underrun_reporting(struct drm_device *dev, if (old && I915_READ(SERR_INT) & SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)) { - DRM_ERROR("uncleared pch fifo underrun on pch transcoder %c\n", + DRM_ERROR("uncleared pch fifo underrun on pch transcoder %s\n", transcoder_name(pch_transcoder)); } } @@ -386,7 +386,7 @@ void intel_pch_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, { if (intel_set_pch_fifo_underrun_reporting(dev_priv, pch_transcoder, false)) - DRM_ERROR("PCH transcoder %c FIFO underrun\n", + DRM_ERROR("PCH transcoder %s FIFO underrun\n", transcoder_name(pch_transcoder)); } -- cgit v1.2.3 From 1dcec2f39f128d3cb4784a0889f6c70aab675ed2 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 15 Mar 2016 21:51:11 +0200 Subject: drm/i915/dsi: refactor dsi get hw state readout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make the code easier to read and update. No functional changes. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/04b20a9be6a9481ca2eb2a42cdcdc27358152e5f.1458070700.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_dsi.c | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index ea78b0bf7e14..32606652bb58 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -667,7 +667,7 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, struct drm_device *dev = encoder->base.dev; enum intel_display_power_domain power_domain; enum port port; - bool ret; + bool active = false; DRM_DEBUG_KMS("\n"); @@ -675,38 +675,39 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) return false; - ret = false; - /* XXX: this only works for one DSI output */ for_each_dsi_port(port, intel_dsi->ports) { i915_reg_t ctrl_reg = IS_BROXTON(dev) ? BXT_MIPI_PORT_CTRL(port) : MIPI_PORT_CTRL(port); - u32 dpi_enabled, func; - - func = I915_READ(MIPI_DSI_FUNC_PRG(port)); - dpi_enabled = I915_READ(ctrl_reg) & DPI_ENABLE; + bool enabled = I915_READ(ctrl_reg) & DPI_ENABLE; /* Due to some hardware limitations on BYT, MIPI Port C DPI * Enable bit does not get set. To check whether DSI Port C * was enabled in BIOS, check the Pipe B enable bit */ if (IS_VALLEYVIEW(dev) && port == PORT_C) - dpi_enabled = I915_READ(PIPECONF(PIPE_B)) & - PIPECONF_ENABLE; + enabled = I915_READ(PIPECONF(PIPE_B)) & PIPECONF_ENABLE; - if (dpi_enabled || (func & CMD_MODE_DATA_WIDTH_MASK)) { - if (I915_READ(MIPI_DEVICE_READY(port)) & DEVICE_READY) { - *pipe = port == PORT_A ? PIPE_A : PIPE_B; - ret = true; - - goto out; - } + /* Try command mode if video mode not enabled */ + if (!enabled) { + u32 tmp = I915_READ(MIPI_DSI_FUNC_PRG(port)); + enabled = tmp & CMD_MODE_DATA_WIDTH_MASK; } + + if (!enabled) + continue; + + if (!(I915_READ(MIPI_DEVICE_READY(port)) & DEVICE_READY)) + continue; + + *pipe = port == PORT_A ? PIPE_A : PIPE_B; + active = true; + break; } -out: + intel_display_power_put(dev_priv, power_domain); - return ret; + return active; } static void intel_dsi_get_config(struct intel_encoder *encoder, -- cgit v1.2.3 From 6b93e9c89ee553c1f062cd5c7dcd35e06846568f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 15 Mar 2016 21:51:12 +0200 Subject: drm/i915/bxt: fix dsi hw state pipe readout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BXT isn't as limited as BYT and CHT regarding DSI pipes and ports. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/8bea85b86aaf7a15f854a656bf8d3208a3afe0bd.1458070700.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_dsi.c | 14 +++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 85ceec611412..d4a298f715f4 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -8144,6 +8144,7 @@ enum skl_disp_power_wells { #define READ_REQUEST_PRIORITY_HIGH (3 << 3) #define RGB_FLIP_TO_BGR (1 << 2) +#define BXT_PIPE_SELECT_SHIFT 7 #define BXT_PIPE_SELECT_MASK (7 << 7) #define BXT_PIPE_SELECT(pipe) ((pipe) << 7) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 32606652bb58..475634667222 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -700,7 +700,19 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, if (!(I915_READ(MIPI_DEVICE_READY(port)) & DEVICE_READY)) continue; - *pipe = port == PORT_A ? PIPE_A : PIPE_B; + if (IS_BROXTON(dev_priv)) { + u32 tmp = I915_READ(MIPI_CTRL(port)); + tmp &= BXT_PIPE_SELECT_MASK; + tmp >>= BXT_PIPE_SELECT_SHIFT; + + if (WARN_ON(tmp > PIPE_C)) + continue; + + *pipe = tmp; + } else { + *pipe = port == PORT_A ? PIPE_A : PIPE_B; + } + active = true; break; } -- cgit v1.2.3 From 3bdd14d542c207528b6ca71946c79b39af39ea51 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 16 Mar 2016 12:43:29 +0200 Subject: drm/i915: move VBT based TV presence check to intel_bios.c Hide knowledge about VBT child devices in intel_bios.c. v2: also move int_tv_support check to intel_bios.c (Sivakumar) Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1458125015-7931-1-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_bios.c | 41 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_tv.c | 46 +-------------------------------------- 3 files changed, 43 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 33e13116854b..3724edda7436 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3353,6 +3353,7 @@ extern void intel_i2c_reset(struct drm_device *dev); /* intel_bios.c */ int intel_bios_init(struct drm_i915_private *dev_priv); bool intel_bios_is_valid_vbt(const void *buf, size_t size); +bool intel_bios_is_tv_present(struct drm_i915_private *dev_priv); /* intel_opregion.c */ #ifdef CONFIG_ACPI diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index bf62a19c8f69..d5e6da01adaa 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -1431,3 +1431,44 @@ intel_bios_init(struct drm_i915_private *dev_priv) return 0; } + +/** + * intel_bios_is_tv_present - is integrated TV present in VBT + * @dev_priv: i915 device instance + * + * Return true if TV is present. If no child devices were parsed from VBT, + * assume TV is present. + */ +bool intel_bios_is_tv_present(struct drm_i915_private *dev_priv) +{ + union child_device_config *p_child; + int i; + + if (!dev_priv->vbt.int_tv_support) + return false; + + if (!dev_priv->vbt.child_dev_num) + return true; + + for (i = 0; i < dev_priv->vbt.child_dev_num; i++) { + p_child = dev_priv->vbt.child_dev + i; + /* + * If the device type is not TV, continue. + */ + switch (p_child->old.device_type) { + case DEVICE_TYPE_INT_TV: + case DEVICE_TYPE_TV: + case DEVICE_TYPE_TV_SVIDEO_COMPOSITE: + break; + default: + continue; + } + /* Only when the addin_offset is non-zero, it is regarded + * as present. + */ + if (p_child->old.addin_offset) + return true; + } + + return false; +} diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index d5570c859009..223129d3c765 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -1519,47 +1519,6 @@ static const struct drm_encoder_funcs intel_tv_enc_funcs = { .destroy = intel_encoder_destroy, }; -/* - * Enumerate the child dev array parsed from VBT to check whether - * the integrated TV is present. - * If it is present, return 1. - * If it is not present, return false. - * If no child dev is parsed from VBT, it assumes that the TV is present. - */ -static int tv_is_present_in_vbt(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - union child_device_config *p_child; - int i, ret; - - if (!dev_priv->vbt.child_dev_num) - return 1; - - ret = 0; - for (i = 0; i < dev_priv->vbt.child_dev_num; i++) { - p_child = dev_priv->vbt.child_dev + i; - /* - * If the device type is not TV, continue. - */ - switch (p_child->old.device_type) { - case DEVICE_TYPE_INT_TV: - case DEVICE_TYPE_TV: - case DEVICE_TYPE_TV_SVIDEO_COMPOSITE: - break; - default: - continue; - } - /* Only when the addin_offset is non-zero, it is regarded - * as present. - */ - if (p_child->old.addin_offset) { - ret = 1; - break; - } - } - return ret; -} - void intel_tv_init(struct drm_device *dev) { @@ -1575,13 +1534,10 @@ intel_tv_init(struct drm_device *dev) if ((I915_READ(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED) return; - if (!tv_is_present_in_vbt(dev)) { + if (!intel_bios_is_tv_present(dev_priv)) { DRM_DEBUG_KMS("Integrated TV is not present.\n"); return; } - /* Even if we have an encoder we may not have a connector */ - if (!dev_priv->vbt.int_tv_support) - return; /* * Sanity check the TV output by checking to see if the -- cgit v1.2.3 From 5a69d13d78d730261edcf83a96704f388c6357d1 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 16 Mar 2016 12:43:30 +0200 Subject: drm/i915: move VBT based LVDS presence check to intel_bios.c Hide knowledge about VBT child devices in intel_bios.c. Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1458125015-7931-2-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_bios.c | 50 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_lvds.c | 53 +-------------------------------------- 3 files changed, 52 insertions(+), 52 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 3724edda7436..c3c8663573bc 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3354,6 +3354,7 @@ extern void intel_i2c_reset(struct drm_device *dev); int intel_bios_init(struct drm_i915_private *dev_priv); bool intel_bios_is_valid_vbt(const void *buf, size_t size); bool intel_bios_is_tv_present(struct drm_i915_private *dev_priv); +bool intel_bios_is_lvds_present(struct drm_i915_private *dev_priv, u8 *i2c_pin); /* intel_opregion.c */ #ifdef CONFIG_ACPI diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index d5e6da01adaa..4f7eba36a849 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -1472,3 +1472,53 @@ bool intel_bios_is_tv_present(struct drm_i915_private *dev_priv) return false; } + +/** + * intel_bios_is_lvds_present - is LVDS present in VBT + * @dev_priv: i915 device instance + * @i2c_pin: i2c pin for LVDS if present + * + * Return true if LVDS is present. If no child devices were parsed from VBT, + * assume LVDS is present. + */ +bool intel_bios_is_lvds_present(struct drm_i915_private *dev_priv, u8 *i2c_pin) +{ + int i; + + if (!dev_priv->vbt.child_dev_num) + return true; + + for (i = 0; i < dev_priv->vbt.child_dev_num; i++) { + union child_device_config *uchild = dev_priv->vbt.child_dev + i; + struct old_child_dev_config *child = &uchild->old; + + /* If the device type is not LFP, continue. + * We have to check both the new identifiers as well as the + * old for compatibility with some BIOSes. + */ + if (child->device_type != DEVICE_TYPE_INT_LFP && + child->device_type != DEVICE_TYPE_LFP) + continue; + + if (intel_gmbus_is_valid_pin(dev_priv, child->i2c_pin)) + *i2c_pin = child->i2c_pin; + + /* However, we cannot trust the BIOS writers to populate + * the VBT correctly. Since LVDS requires additional + * information from AIM blocks, a non-zero addin offset is + * a good indicator that the LVDS is actually present. + */ + if (child->addin_offset) + return true; + + /* But even then some BIOS writers perform some black magic + * and instantiate the device without reference to any + * additional data. Trust that if the VBT was written into + * the OpRegion then they have validated the LVDS's existence. + */ + if (dev_priv->opregion.vbt) + return true; + } + + return false; +} diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index cbd1b0d547ee..766ba566fef1 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -775,57 +775,6 @@ static const struct dmi_system_id intel_no_lvds[] = { { } /* terminating entry */ }; -/* - * Enumerate the child dev array parsed from VBT to check whether - * the LVDS is present. - * If it is present, return 1. - * If it is not present, return false. - * If no child dev is parsed from VBT, it assumes that the LVDS is present. - */ -static bool lvds_is_present_in_vbt(struct drm_device *dev, - u8 *i2c_pin) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int i; - - if (!dev_priv->vbt.child_dev_num) - return true; - - for (i = 0; i < dev_priv->vbt.child_dev_num; i++) { - union child_device_config *uchild = dev_priv->vbt.child_dev + i; - struct old_child_dev_config *child = &uchild->old; - - /* If the device type is not LFP, continue. - * We have to check both the new identifiers as well as the - * old for compatibility with some BIOSes. - */ - if (child->device_type != DEVICE_TYPE_INT_LFP && - child->device_type != DEVICE_TYPE_LFP) - continue; - - if (intel_gmbus_is_valid_pin(dev_priv, child->i2c_pin)) - *i2c_pin = child->i2c_pin; - - /* However, we cannot trust the BIOS writers to populate - * the VBT correctly. Since LVDS requires additional - * information from AIM blocks, a non-zero addin offset is - * a good indicator that the LVDS is actually present. - */ - if (child->addin_offset) - return true; - - /* But even then some BIOS writers perform some black magic - * and instantiate the device without reference to any - * additional data. Trust that if the VBT was written into - * the OpRegion then they have validated the LVDS's existence. - */ - if (dev_priv->opregion.vbt) - return true; - } - - return false; -} - static int intel_dual_link_lvds_callback(const struct dmi_system_id *id) { DRM_INFO("Forcing lvds to dual link mode on %s\n", id->ident); @@ -982,7 +931,7 @@ void intel_lvds_init(struct drm_device *dev) } pin = GMBUS_PIN_PANEL; - if (!lvds_is_present_in_vbt(dev, &pin)) { + if (!intel_bios_is_lvds_present(dev_priv, &pin)) { if ((lvds & LVDS_PORT_EN) == 0) { DRM_DEBUG_KMS("LVDS is not present in VBT\n"); return; -- cgit v1.2.3 From 951d9efe07877a3f1bb04e8932d11eafbfad02bf Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 16 Mar 2016 12:43:31 +0200 Subject: drm/i915: move VBT based eDP port check to intel_bios.c Hide knowledge about VBT child devices in intel_bios.c. Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1458125015-7931-3-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_bios.c | 33 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_dp.c | 21 +-------------------- 3 files changed, 35 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index c3c8663573bc..e252978d6f1b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3355,6 +3355,7 @@ int intel_bios_init(struct drm_i915_private *dev_priv); bool intel_bios_is_valid_vbt(const void *buf, size_t size); bool intel_bios_is_tv_present(struct drm_i915_private *dev_priv); bool intel_bios_is_lvds_present(struct drm_i915_private *dev_priv, u8 *i2c_pin); +bool intel_bios_is_port_edp(struct drm_i915_private *dev_priv, enum port port); /* intel_opregion.c */ #ifdef CONFIG_ACPI diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 4f7eba36a849..7f61ca8165f0 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -1522,3 +1522,36 @@ bool intel_bios_is_lvds_present(struct drm_i915_private *dev_priv, u8 *i2c_pin) return false; } + +/** + * intel_bios_is_port_edp - is the device in given port eDP + * @dev_priv: i915 device instance + * @port: port to check + * + * Return true if the device in %port is eDP. + */ +bool intel_bios_is_port_edp(struct drm_i915_private *dev_priv, enum port port) +{ + union child_device_config *p_child; + static const short port_mapping[] = { + [PORT_B] = DVO_PORT_DPB, + [PORT_C] = DVO_PORT_DPC, + [PORT_D] = DVO_PORT_DPD, + [PORT_E] = DVO_PORT_DPE, + }; + int i; + + if (!dev_priv->vbt.child_dev_num) + return false; + + for (i = 0; i < dev_priv->vbt.child_dev_num; i++) { + p_child = dev_priv->vbt.child_dev + i; + + if (p_child->common.dvo_port == port_mapping[port] && + (p_child->common.device_type & DEVICE_TYPE_eDP_BITS) == + (DEVICE_TYPE_eDP & DEVICE_TYPE_eDP_BITS)) + return true; + } + + return false; +} diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index ba2d0242d532..3ff8f1d67594 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4993,14 +4993,6 @@ put_power: bool intel_dp_is_edp(struct drm_device *dev, enum port port) { struct drm_i915_private *dev_priv = dev->dev_private; - union child_device_config *p_child; - int i; - static const short port_mapping[] = { - [PORT_B] = DVO_PORT_DPB, - [PORT_C] = DVO_PORT_DPC, - [PORT_D] = DVO_PORT_DPD, - [PORT_E] = DVO_PORT_DPE, - }; /* * eDP not supported on g4x. so bail out early just @@ -5012,18 +5004,7 @@ bool intel_dp_is_edp(struct drm_device *dev, enum port port) if (port == PORT_A) return true; - if (!dev_priv->vbt.child_dev_num) - return false; - - for (i = 0; i < dev_priv->vbt.child_dev_num; i++) { - p_child = dev_priv->vbt.child_dev + i; - - if (p_child->common.dvo_port == port_mapping[port] && - (p_child->common.device_type & DEVICE_TYPE_eDP_BITS) == - (DEVICE_TYPE_eDP & DEVICE_TYPE_eDP_BITS)) - return true; - } - return false; + return intel_bios_is_port_edp(dev_priv, port); } void -- cgit v1.2.3 From 7137aec1cfd3fd417023ce4edd0f348e5d72115f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 16 Mar 2016 12:43:32 +0200 Subject: drm/i915: move VBT based DSI presence check to intel_bios.c Hide knowledge about VBT child devices in intel_bios.c. v2: Move port check to intel_bios.c (Sivakumar) Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1458125015-7931-4-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/intel_bios.c | 39 ++++++++++++++++++++++++++++++++++++++- drivers/gpu/drm/i915/intel_dsi.c | 17 ++++++++--------- 3 files changed, 47 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index e252978d6f1b..f6a84baa02bd 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1468,7 +1468,6 @@ struct intel_vbt_data { /* MIPI DSI */ struct { - u16 port; u16 panel_id; struct mipi_config *config; struct mipi_pps_data *pps; @@ -3356,6 +3355,7 @@ bool intel_bios_is_valid_vbt(const void *buf, size_t size); bool intel_bios_is_tv_present(struct drm_i915_private *dev_priv); bool intel_bios_is_lvds_present(struct drm_i915_private *dev_priv, u8 *i2c_pin); bool intel_bios_is_port_edp(struct drm_i915_private *dev_priv, enum port port); +bool intel_bios_is_dsi_present(struct drm_i915_private *dev_priv, enum port *port); /* intel_opregion.c */ #ifdef CONFIG_ACPI diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 7f61ca8165f0..4b6bd6f2e193 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -1237,7 +1237,6 @@ parse_device_mapping(struct drm_i915_private *dev_priv, &&p_child->common.device_type & DEVICE_TYPE_MIPI_OUTPUT) { DRM_DEBUG_KMS("Found MIPI as LFP\n"); dev_priv->vbt.has_mipi = 1; - dev_priv->vbt.dsi.port = p_child->common.dvo_port; } child_dev_ptr = dev_priv->vbt.child_dev + count; @@ -1555,3 +1554,41 @@ bool intel_bios_is_port_edp(struct drm_i915_private *dev_priv, enum port port) return false; } + +/** + * intel_bios_is_dsi_present - is DSI present in VBT + * @dev_priv: i915 device instance + * @port: port for DSI if present + * + * Return true if DSI is present, and return the port in %port. + */ +bool intel_bios_is_dsi_present(struct drm_i915_private *dev_priv, + enum port *port) +{ + union child_device_config *p_child; + u8 dvo_port; + int i; + + for (i = 0; i < dev_priv->vbt.child_dev_num; i++) { + p_child = dev_priv->vbt.child_dev + i; + + if (!(p_child->common.device_type & DEVICE_TYPE_MIPI_OUTPUT)) + continue; + + dvo_port = p_child->common.dvo_port; + + switch (dvo_port) { + case DVO_PORT_MIPIA: + case DVO_PORT_MIPIC: + *port = dvo_port - DVO_PORT_MIPIA; + return true; + case DVO_PORT_MIPIB: + case DVO_PORT_MIPID: + DRM_DEBUG_KMS("VBT has unsupported DSI port %c\n", + port_name(dvo_port - DVO_PORT_MIPIA)); + break; + } + } + + return false; +} diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 475634667222..3562bf337e62 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -1149,7 +1149,7 @@ void intel_dsi_init(struct drm_device *dev) DRM_DEBUG_KMS("\n"); /* There is no detection method for MIPI so rely on VBT */ - if (!dev_priv->vbt.has_mipi) + if (!intel_bios_is_dsi_present(dev_priv, &port)) return; if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) { @@ -1190,16 +1190,15 @@ void intel_dsi_init(struct drm_device *dev) intel_connector->unregister = intel_connector_unregister; /* Pipe A maps to MIPI DSI port A, pipe B maps to MIPI DSI port C */ - if (dev_priv->vbt.dsi.port == DVO_PORT_MIPIA) { - intel_encoder->crtc_mask = (1 << PIPE_A); - intel_dsi->ports = (1 << PORT_A); - } else if (dev_priv->vbt.dsi.port == DVO_PORT_MIPIC) { - intel_encoder->crtc_mask = (1 << PIPE_B); - intel_dsi->ports = (1 << PORT_C); - } + if (port == PORT_A) + intel_encoder->crtc_mask = 1 << PIPE_A; + else + intel_encoder->crtc_mask = 1 << PIPE_B; if (dev_priv->vbt.dsi.config->dual_link) - intel_dsi->ports = ((1 << PORT_A) | (1 << PORT_C)); + intel_dsi->ports = (1 << PORT_A) | (1 << PORT_C); + else + intel_dsi->ports = 1 << port; /* Create a DSI host (and a device) for each port. */ for_each_dsi_port(port, intel_dsi->ports) { -- cgit v1.2.3 From 92c4565e93609314b34bb810ba54cb73eb006987 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 16 Mar 2016 12:43:33 +0200 Subject: drm/i915/panel: setup pwm backlight based on connector type Use the connector type instead of VBT directly to decide which backlight mechanism to use on VLV/CHV. (Indirectly, this is the same thing, but hides the VBT use.) Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1458125015-7931-5-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_panel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 0fe059bc7d80..8c8996fcbaf5 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -1743,7 +1743,7 @@ intel_panel_init_backlight_funcs(struct intel_panel *panel) panel->backlight.get = pch_get_backlight; panel->backlight.hz_to_pwm = pch_hz_to_pwm; } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { - if (dev_priv->vbt.has_mipi) { + if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI) { panel->backlight.setup = pwm_setup_backlight; panel->backlight.enable = pwm_enable_backlight; panel->backlight.disable = pwm_disable_backlight; -- cgit v1.2.3 From 7caaef332abaae872ddd2cd65bbe8a8bc0d8f5cc Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 16 Mar 2016 12:43:34 +0200 Subject: drm/i915/bios: drop has_mipi in favor of intel_bios_is_dsi_present Favor a single point of truth instead of duplicating the information. The change also filters out unsupported DSI ports at this stage, accepting only ports A and C, instead of waiting until the port checks. Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1458125015-7931-6-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 1 - drivers/gpu/drm/i915/intel_bios.c | 12 +++--------- 2 files changed, 3 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f6a84baa02bd..8a10c4b39a7f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1434,7 +1434,6 @@ struct intel_vbt_data { unsigned int lvds_use_ssc:1; unsigned int display_clock_mode:1; unsigned int fdi_rx_polarity_inverted:1; - unsigned int has_mipi:1; int lvds_ssc_freq; unsigned int bios_lvds_val; /* initial [PCH_]LVDS reg val in VBIOS */ diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 4b6bd6f2e193..aa90dc662e7f 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -706,7 +706,7 @@ parse_mipi_config(struct drm_i915_private *dev_priv, const struct mipi_pps_data *pps; /* parse MIPI blocks only if LFP type is MIPI */ - if (!dev_priv->vbt.has_mipi) + if (!intel_bios_is_dsi_present(dev_priv, NULL)) return; /* Initialize this to undefined indicating no generic MIPI support */ @@ -1232,13 +1232,6 @@ parse_device_mapping(struct drm_i915_private *dev_priv, continue; } - if (p_child->common.dvo_port >= DVO_PORT_MIPIA - && p_child->common.dvo_port <= DVO_PORT_MIPID - &&p_child->common.device_type & DEVICE_TYPE_MIPI_OUTPUT) { - DRM_DEBUG_KMS("Found MIPI as LFP\n"); - dev_priv->vbt.has_mipi = 1; - } - child_dev_ptr = dev_priv->vbt.child_dev + count; count++; @@ -1580,7 +1573,8 @@ bool intel_bios_is_dsi_present(struct drm_i915_private *dev_priv, switch (dvo_port) { case DVO_PORT_MIPIA: case DVO_PORT_MIPIC: - *port = dvo_port - DVO_PORT_MIPIA; + if (port) + *port = dvo_port - DVO_PORT_MIPIA; return true; case DVO_PORT_MIPIB: case DVO_PORT_MIPID: -- cgit v1.2.3 From ab65cce821cc46ccdc0b62f99bb79f75c1c7412c Mon Sep 17 00:00:00 2001 From: Alex Dai Date: Wed, 16 Mar 2016 15:24:13 -0700 Subject: drm/i915/guc: Support GuC SKL v6.1 This version of GuC firmware fixes the engine reset issue where golden context LRC address is treated as page index by mistake. It also fixes the problem that scheduler stops submiting to one engine when the other engine work queue is full. Signed-off-by: Alex Dai Reviewed-by: Dave Gordon Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/intel_guc_loader.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c index 9f309211939a..e1aff6263077 100644 --- a/drivers/gpu/drm/i915/intel_guc_loader.c +++ b/drivers/gpu/drm/i915/intel_guc_loader.c @@ -59,7 +59,7 @@ * */ -#define I915_SKL_GUC_UCODE "i915/skl_guc_ver4.bin" +#define I915_SKL_GUC_UCODE "i915/skl_guc_ver6.bin" MODULE_FIRMWARE(I915_SKL_GUC_UCODE); /* User-friendly representation of an enum */ @@ -595,8 +595,8 @@ void intel_guc_ucode_init(struct drm_device *dev) fw_path = NULL; } else if (IS_SKYLAKE(dev)) { fw_path = I915_SKL_GUC_UCODE; - guc_fw->guc_fw_major_wanted = 4; - guc_fw->guc_fw_minor_wanted = 3; + guc_fw->guc_fw_major_wanted = 6; + guc_fw->guc_fw_minor_wanted = 1; } else { i915.enable_guc_submission = false; fw_path = ""; /* unknown device */ -- cgit v1.2.3 From 1f7717552ef1306be3b7ed28c66c6eff550e3a23 Mon Sep 17 00:00:00 2001 From: Lyude Date: Wed, 16 Mar 2016 15:18:04 -0400 Subject: drm/i915: Fix race condition in intel_dp_destroy_mst_connector() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After unplugging a DP MST display from the system, we have to go through and destroy all of the DRM connectors associated with it since none of them are valid anymore. Unfortunately, intel_dp_destroy_mst_connector() doesn't do a good enough job of ensuring that throughout the destruction process that no modesettings can be done with the connectors. As it is right now, intel_dp_destroy_mst_connector() works like this: * Take all modeset locks * Clear the configuration of the crtc on the connector, if there is one * Drop all modeset locks, this is required because of circular dependency issues that arise with trying to remove the connector from sysfs with modeset locks held * Unregister the connector * Take all modeset locks, again * Do the rest of the required cleaning for destroying the connector * Finally drop all modeset locks for good This only works sometimes. During the destruction process, it's very possible that a userspace application will attempt to do a modesetting using the connector. When we drop the modeset locks, an ioctl handler such as drm_mode_setcrtc has the oppurtunity to take all of the modeset locks from us. When this happens, one thing leads to another and eventually we end up committing a mode with the non-existent connector: [drm:intel_dp_link_training_clock_recovery [i915]] *ERROR* failed to enable link training [drm:intel_dp_aux_ch] dp_aux_ch timeout status 0x7cf0001f [drm:intel_dp_start_link_train [i915]] *ERROR* failed to start channel equalization [drm:intel_dp_aux_ch] dp_aux_ch timeout status 0x7cf0001f [drm:intel_mst_pre_enable_dp [i915]] *ERROR* failed to allocate vcpi And in some cases, such as with the T460s using an MST dock, this results in breaking modesetting and/or panicking the system. To work around this, we now unregister the connector at the very beginning of intel_dp_destroy_mst_connector(), grab all the modesetting locks, and then hold them until we finish the rest of the function. CC: stable@vger.kernel.org Signed-off-by: Lyude Signed-off-by: Rob Clark Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1458155884-13877-1-git-send-email-cpaul@redhat.com --- drivers/gpu/drm/i915/intel_dp_mst.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index 8d1b7033aaba..94b4e833dadd 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -502,6 +502,8 @@ static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, struct intel_connector *intel_connector = to_intel_connector(connector); struct drm_device *dev = connector->dev; + intel_connector->unregister(intel_connector); + /* need to nuke the connector */ drm_modeset_lock_all(dev); if (connector->state->crtc) { @@ -515,11 +517,7 @@ static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, WARN(ret, "Disabling mst crtc failed with %i\n", ret); } - drm_modeset_unlock_all(dev); - intel_connector->unregister(intel_connector); - - drm_modeset_lock_all(dev); intel_connector_remove_from_fbdev(intel_connector); drm_connector_cleanup(connector); drm_modeset_unlock_all(dev); -- cgit v1.2.3 From 2dd66ebde4431c93bfa211bc967a6f2089283aa6 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Mon, 14 Mar 2016 09:27:52 +0100 Subject: drm/i915: Use a crtc mask instead of a refcount for dpll functions, v2. This makes it easier to verify correct dpll setup with only a single crtc. It is also useful to detect double dpll enable/disable. Changes since v1: - Rebase on top of Ander's dpll rework. - Change debugfs active to a mask. - Change enabled_crtcs and active_crtcs to unsigned. Signed-off-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1457944075-14123-2-git-send-email-maarten.lankhorst@linux.intel.com Reviewed-by: Ander Conselvan de Oliveira --- drivers/gpu/drm/i915/i915_debugfs.c | 4 ++-- drivers/gpu/drm/i915/intel_display.c | 43 +++++++++++++++++------------------ drivers/gpu/drm/i915/intel_dpll_mgr.c | 35 +++++++++++++++------------- drivers/gpu/drm/i915/intel_dpll_mgr.h | 2 +- 4 files changed, 43 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 1d8c3ef29318..ccdca2c7d799 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -3212,8 +3212,8 @@ static int i915_shared_dplls_info(struct seq_file *m, void *unused) struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i]; seq_printf(m, "DPLL%i: %s, id: %i\n", i, pll->name, pll->id); - seq_printf(m, " crtc_mask: 0x%08x, active: %d, on: %s\n", - pll->config.crtc_mask, pll->active, yesno(pll->on)); + seq_printf(m, " crtc_mask: 0x%08x, active: 0x%x, on: %s\n", + pll->config.crtc_mask, pll->active_mask, yesno(pll->on)); seq_printf(m, " tracked hardware state:\n"); seq_printf(m, " dpll: 0x%08x\n", pll->config.hw_state.dpll); seq_printf(m, " dpll_md: 0x%08x\n", diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f3bcafa22e84..089d65eaef75 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12962,7 +12962,7 @@ check_shared_dpll_state(struct drm_device *dev) for (i = 0; i < dev_priv->num_shared_dpll; i++) { struct intel_shared_dpll *pll = intel_get_shared_dpll_by_id(dev_priv, i); - int enabled_crtcs = 0, active_crtcs = 0; + unsigned enabled_crtcs = 0, active_crtcs = 0; bool active; memset(&dpll_hw_state, 0, sizeof(dpll_hw_state)); @@ -12971,15 +12971,15 @@ check_shared_dpll_state(struct drm_device *dev) active = pll->funcs.get_hw_state(dev_priv, pll, &dpll_hw_state); - I915_STATE_WARN(pll->active > hweight32(pll->config.crtc_mask), - "more active pll users than references: %i vs %i\n", - pll->active, hweight32(pll->config.crtc_mask)); - I915_STATE_WARN(pll->active && !pll->on, - "pll in active use but not on in sw tracking\n"); + I915_STATE_WARN(pll->active_mask & ~pll->config.crtc_mask, + "more active pll users than references: %x vs %x\n", + pll->active_mask, pll->config.crtc_mask); if (!(pll->flags & INTEL_DPLL_ALWAYS_ON)) { - I915_STATE_WARN(pll->on && !pll->active, - "pll in on but not on in use in sw tracking\n"); + I915_STATE_WARN(!pll->on && pll->active_mask, + "pll in active use but not on in sw tracking\n"); + I915_STATE_WARN(pll->on && !pll->active_mask, + "pll is on but not used by any active crtc\n"); I915_STATE_WARN(pll->on != active, "pll on state mismatch (expected %i, found %i)\n", pll->on, active); @@ -12987,16 +12987,17 @@ check_shared_dpll_state(struct drm_device *dev) for_each_intel_crtc(dev, crtc) { if (crtc->base.state->enable && crtc->config->shared_dpll == pll) - enabled_crtcs++; - if (crtc->active && crtc->config->shared_dpll == pll) - active_crtcs++; + enabled_crtcs |= 1 << drm_crtc_index(&crtc->base); + if (crtc->base.state->active && crtc->config->shared_dpll == pll) + active_crtcs |= 1 << drm_crtc_index(&crtc->base); } - I915_STATE_WARN(pll->active != active_crtcs, - "pll active crtcs mismatch (expected %i, found %i)\n", - pll->active, active_crtcs); - I915_STATE_WARN(hweight32(pll->config.crtc_mask) != enabled_crtcs, - "pll enabled crtcs mismatch (expected %i, found %i)\n", - hweight32(pll->config.crtc_mask), enabled_crtcs); + + I915_STATE_WARN(pll->active_mask != active_crtcs, + "pll active crtcs mismatch (expected %x, found %x)\n", + pll->active_mask, active_crtcs); + I915_STATE_WARN(pll->config.crtc_mask != enabled_crtcs, + "pll enabled crtcs mismatch (expected %x, found %x)\n", + pll->config.crtc_mask, enabled_crtcs); I915_STATE_WARN(pll->on && memcmp(&pll->config.hw_state, &dpll_hw_state, sizeof(dpll_hw_state)), @@ -15694,14 +15695,12 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) pll->on = pll->funcs.get_hw_state(dev_priv, pll, &pll->config.hw_state); - pll->active = 0; pll->config.crtc_mask = 0; for_each_intel_crtc(dev, crtc) { - if (crtc->active && crtc->config->shared_dpll == pll) { - pll->active++; + if (crtc->active && crtc->config->shared_dpll == pll) pll->config.crtc_mask |= 1 << crtc->pipe; - } } + pll->active_mask = pll->config.crtc_mask; DRM_DEBUG_KMS("%s hw state readout: crtc_mask 0x%08x, on %i\n", pll->name, pll->config.crtc_mask, pll->on); @@ -15825,7 +15824,7 @@ intel_modeset_setup_hw_state(struct drm_device *dev) for (i = 0; i < dev_priv->num_shared_dpll; i++) { struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i]; - if (!pll->on || pll->active) + if (!pll->on || pll->active_mask) continue; DRM_DEBUG_KMS("%s enabled but not in use, disabling\n", pll->name); diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c index 74d5aecc0be5..9bf2c3914625 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c @@ -90,7 +90,7 @@ void intel_prepare_shared_dpll(struct intel_crtc *crtc) return; WARN_ON(!pll->config.crtc_mask); - if (pll->active == 0) { + if (pll->active_mask == 0) { DRM_DEBUG_DRIVER("setting up %s\n", pll->name); WARN_ON(pll->on); assert_shared_dpll_disabled(dev_priv, pll); @@ -112,18 +112,23 @@ void intel_enable_shared_dpll(struct intel_crtc *crtc) struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_shared_dpll *pll = crtc->config->shared_dpll; + unsigned crtc_mask = 1 << drm_crtc_index(&crtc->base); + unsigned old_mask = pll->active_mask; if (WARN_ON(pll == NULL)) return; - if (WARN_ON(pll->config.crtc_mask == 0)) + if (WARN_ON(!(pll->config.crtc_mask & crtc_mask)) || + WARN_ON(pll->active_mask & crtc_mask)) return; - DRM_DEBUG_KMS("enable %s (active %d, on? %d) for crtc %d\n", - pll->name, pll->active, pll->on, + pll->active_mask |= crtc_mask; + + DRM_DEBUG_KMS("enable %s (active %x, on? %d) for crtc %d\n", + pll->name, pll->active_mask, pll->on, crtc->base.base.id); - if (pll->active++) { + if (old_mask) { WARN_ON(!pll->on); assert_shared_dpll_enabled(dev_priv, pll); return; @@ -142,6 +147,7 @@ void intel_disable_shared_dpll(struct intel_crtc *crtc) struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_shared_dpll *pll = crtc->config->shared_dpll; + unsigned crtc_mask = 1 << drm_crtc_index(&crtc->base); /* PCH only available on ILK+ */ if (INTEL_INFO(dev)->gen < 5) @@ -150,21 +156,18 @@ void intel_disable_shared_dpll(struct intel_crtc *crtc) if (pll == NULL) return; - if (WARN_ON(!(pll->config.crtc_mask & (1 << drm_crtc_index(&crtc->base))))) + if (WARN_ON(!(pll->config.crtc_mask & crtc_mask))) return; - DRM_DEBUG_KMS("disable %s (active %d, on? %d) for crtc %d\n", - pll->name, pll->active, pll->on, + DRM_DEBUG_KMS("disable %s (active %x, on? %d) for crtc %d\n", + pll->name, pll->active_mask, pll->on, crtc->base.base.id); - if (WARN_ON(pll->active == 0)) { - assert_shared_dpll_disabled(dev_priv, pll); - return; - } - assert_shared_dpll_enabled(dev_priv, pll); WARN_ON(!pll->on); - if (--pll->active) + + pll->active_mask &= ~crtc_mask; + if (pll->active_mask) return; DRM_DEBUG_KMS("disabling %s\n", pll->name); @@ -197,10 +200,10 @@ intel_find_shared_dpll(struct intel_crtc *crtc, if (memcmp(&crtc_state->dpll_hw_state, &shared_dpll[i].hw_state, sizeof(crtc_state->dpll_hw_state)) == 0) { - DRM_DEBUG_KMS("CRTC:%d sharing existing %s (crtc mask 0x%08x, ative %d)\n", + DRM_DEBUG_KMS("CRTC:%d sharing existing %s (crtc mask 0x%08x, active %x)\n", crtc->base.base.id, pll->name, shared_dpll[i].crtc_mask, - pll->active); + pll->active_mask); return pll; } } diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h index 1d341472f8b0..89c5ada1a315 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.h +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h @@ -115,7 +115,7 @@ struct intel_shared_dpll_funcs { struct intel_shared_dpll { struct intel_shared_dpll_config config; - int active; /* count of number of active CRTCs (i.e. DPMS on) */ + unsigned active_mask; /* mask of active CRTCs (i.e. DPMS on) */ bool on; /* is the PLL actually active? Disabled during modeset */ const char *name; /* should match the index in the dev_priv->shared_dplls array */ -- cgit v1.2.3 From a1475e775edc7bc8c0528d834d90a0ee93e57b1e Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Mon, 14 Mar 2016 09:27:53 +0100 Subject: drm/i915: Perform dpll commit first, v2. Warn for the wrong mask in enable only. Disable will have the wrong mask now because the new state is committed before disabling the old state. Changes since v1: - Use crtc_mask (Durgadoss) - Rebase. Signed-off-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1457944075-14123-3-git-send-email-maarten.lankhorst@linux.intel.com Reviewed-by: Ander Conselvan de Oliveira --- drivers/gpu/drm/i915/intel_display.c | 5 ++--- drivers/gpu/drm/i915/intel_dpll_mgr.c | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 089d65eaef75..80aa51c98a2d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13525,7 +13525,8 @@ static int intel_atomic_commit(struct drm_device *dev, } drm_atomic_helper_swap_state(dev, state); - dev_priv->wm.config = to_intel_atomic_state(state)->wm_config; + dev_priv->wm.config = intel_state->wm_config; + intel_shared_dpll_commit(state); if (intel_state->modeset) { memcpy(dev_priv->min_pixclk, intel_state->min_pixclk, @@ -13577,8 +13578,6 @@ static int intel_atomic_commit(struct drm_device *dev, intel_modeset_update_crtc_state(state); if (intel_state->modeset) { - intel_shared_dpll_commit(state); - drm_atomic_helper_update_legacy_modeset_state(state->dev, state); if (dev_priv->display.modeset_commit_cdclk && diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c index 9bf2c3914625..2c98610213f4 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c @@ -156,7 +156,7 @@ void intel_disable_shared_dpll(struct intel_crtc *crtc) if (pll == NULL) return; - if (WARN_ON(!(pll->config.crtc_mask & crtc_mask))) + if (WARN_ON(!(pll->active_mask & crtc_mask))) return; DRM_DEBUG_KMS("disable %s (active %x, on? %d) for crtc %d\n", -- cgit v1.2.3 From 15e7ec29ce5555a7b6048a1cfdaeb172de75a649 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Mon, 14 Mar 2016 09:27:54 +0100 Subject: drm/i915: Move pll power state to crtc power domains. Signed-off-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1457944075-14123-4-git-send-email-maarten.lankhorst@linux.intel.com Reviewed-by: Ander Conselvan de Oliveira --- drivers/gpu/drm/i915/intel_display.c | 6 +++--- drivers/gpu/drm/i915/intel_dpll_mgr.c | 4 ---- 2 files changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 80aa51c98a2d..e3e158175256 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5273,6 +5273,9 @@ static unsigned long get_crtc_power_domains(struct drm_crtc *crtc, mask |= BIT(intel_display_port_power_domain(intel_encoder)); } + if (crtc_state->shared_dpll) + mask |= BIT(POWER_DOMAIN_PLLS); + return mask; } @@ -15703,9 +15706,6 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) DRM_DEBUG_KMS("%s hw state readout: crtc_mask 0x%08x, on %i\n", pll->name, pll->config.crtc_mask, pll->on); - - if (pll->config.crtc_mask) - intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS); } for_each_intel_encoder(dev, encoder) { diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c index 2c98610213f4..fc5cfc89a026 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c @@ -135,8 +135,6 @@ void intel_enable_shared_dpll(struct intel_crtc *crtc) } WARN_ON(pll->on); - intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS); - DRM_DEBUG_KMS("enabling %s\n", pll->name); pll->funcs.enable(dev_priv, pll); pll->on = true; @@ -173,8 +171,6 @@ void intel_disable_shared_dpll(struct intel_crtc *crtc) DRM_DEBUG_KMS("disabling %s\n", pll->name); pll->funcs.disable(dev_priv, pll); pll->on = false; - - intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); } static struct intel_shared_dpll * -- cgit v1.2.3 From 52e2abb30cf0560edbb8f898d6c308e5ef80dd3f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 16 Mar 2016 18:06:58 +0200 Subject: drm/i915: fix sparse warning for using false as NULL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/gpu/drm/i915/intel_dpll_mgr.c:1200:32: warning: Using plain integer as NULL pointer Fixes: 304b65cbdc8d ("drm/i915: Move SKL/KLB pll selection logic to intel_dpll_mgr.c") Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1458144418-20046-1-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_dpll_mgr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c index fc5cfc89a026..19bfe6743ef2 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c @@ -1196,7 +1196,7 @@ skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, ctrl1 |= DPLL_CTRL1_HDMI_MODE(0); if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params)) - return false; + return NULL; cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE | DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) | -- cgit v1.2.3 From 72341af4285ae1337c0dfdfa3e68318b52b8757c Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 16 Mar 2016 12:43:35 +0200 Subject: drm/i915: hide away VBT private data in a separate header We've been accumulating code across the driver that depends on the VBT specific structures and defines. The VBT is an uncontrollable beast. Encourage encapsulation of the VBT data by hiding the structures and defines in a private header only to be included from intel_bios.c. Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1458125015-7931-7-git-send-email-jani.nikula@intel.com --- Documentation/DocBook/gpu.tmpl | 2 +- drivers/gpu/drm/i915/intel_bios.c | 4 +- drivers/gpu/drm/i915/intel_bios.h | 861 ++-------------------------------- drivers/gpu/drm/i915/intel_vbt_defs.h | 826 ++++++++++++++++++++++++++++++++ 4 files changed, 865 insertions(+), 828 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_vbt_defs.h (limited to 'drivers') diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl index 1692c4dd5487..ab7ffebf4b95 100644 --- a/Documentation/DocBook/gpu.tmpl +++ b/Documentation/DocBook/gpu.tmpl @@ -3334,7 +3334,7 @@ int num_ioctls; Video BIOS Table (VBT) !Pdrivers/gpu/drm/i915/intel_bios.c Video BIOS Table (VBT) !Idrivers/gpu/drm/i915/intel_bios.c -!Idrivers/gpu/drm/i915/intel_bios.h +!Idrivers/gpu/drm/i915/intel_vbt_defs.h diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index aa90dc662e7f..083003b015f5 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -29,7 +29,9 @@ #include #include #include "i915_drv.h" -#include "intel_bios.h" + +#define _INTEL_BIOS_PRIVATE +#include "intel_vbt_defs.h" /** * DOC: Video BIOS Table (VBT) diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h index 350d4e0f75a4..ab0ea315eddb 100644 --- a/drivers/gpu/drm/i915/intel_bios.h +++ b/drivers/gpu/drm/i915/intel_bios.h @@ -1,5 +1,5 @@ /* - * Copyright © 2006 Intel Corporation + * Copyright © 2016 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -19,543 +19,16 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * Authors: - * Eric Anholt - * - */ - -#ifndef _INTEL_BIOS_H_ -#define _INTEL_BIOS_H_ - -/** - * struct vbt_header - VBT Header structure - * @signature: VBT signature, always starts with "$VBT" - * @version: Version of this structure - * @header_size: Size of this structure - * @vbt_size: Size of VBT (VBT Header, BDB Header and data blocks) - * @vbt_checksum: Checksum - * @reserved0: Reserved - * @bdb_offset: Offset of &struct bdb_header from beginning of VBT - * @aim_offset: Offsets of add-in data blocks from beginning of VBT - */ -struct vbt_header { - u8 signature[20]; - u16 version; - u16 header_size; - u16 vbt_size; - u8 vbt_checksum; - u8 reserved0; - u32 bdb_offset; - u32 aim_offset[4]; -} __packed; - -/** - * struct bdb_header - BDB Header structure - * @signature: BDB signature "BIOS_DATA_BLOCK" - * @version: Version of the data block definitions - * @header_size: Size of this structure - * @bdb_size: Size of BDB (BDB Header and data blocks) - */ -struct bdb_header { - u8 signature[16]; - u16 version; - u16 header_size; - u16 bdb_size; -} __packed; - -/* strictly speaking, this is a "skip" block, but it has interesting info */ -struct vbios_data { - u8 type; /* 0 == desktop, 1 == mobile */ - u8 relstage; - u8 chipset; - u8 lvds_present:1; - u8 tv_present:1; - u8 rsvd2:6; /* finish byte */ - u8 rsvd3[4]; - u8 signon[155]; - u8 copyright[61]; - u16 code_segment; - u8 dos_boot_mode; - u8 bandwidth_percent; - u8 rsvd4; /* popup memory size */ - u8 resize_pci_bios; - u8 rsvd5; /* is crt already on ddc2 */ -} __packed; - -/* - * There are several types of BIOS data blocks (BDBs), each block has - * an ID and size in the first 3 bytes (ID in first, size in next 2). - * Known types are listed below. */ -#define BDB_GENERAL_FEATURES 1 -#define BDB_GENERAL_DEFINITIONS 2 -#define BDB_OLD_TOGGLE_LIST 3 -#define BDB_MODE_SUPPORT_LIST 4 -#define BDB_GENERIC_MODE_TABLE 5 -#define BDB_EXT_MMIO_REGS 6 -#define BDB_SWF_IO 7 -#define BDB_SWF_MMIO 8 -#define BDB_PSR 9 -#define BDB_MODE_REMOVAL_TABLE 10 -#define BDB_CHILD_DEVICE_TABLE 11 -#define BDB_DRIVER_FEATURES 12 -#define BDB_DRIVER_PERSISTENCE 13 -#define BDB_EXT_TABLE_PTRS 14 -#define BDB_DOT_CLOCK_OVERRIDE 15 -#define BDB_DISPLAY_SELECT 16 -/* 17 rsvd */ -#define BDB_DRIVER_ROTATION 18 -#define BDB_DISPLAY_REMOVE 19 -#define BDB_OEM_CUSTOM 20 -#define BDB_EFP_LIST 21 /* workarounds for VGA hsync/vsync */ -#define BDB_SDVO_LVDS_OPTIONS 22 -#define BDB_SDVO_PANEL_DTDS 23 -#define BDB_SDVO_LVDS_PNP_IDS 24 -#define BDB_SDVO_LVDS_POWER_SEQ 25 -#define BDB_TV_OPTIONS 26 -#define BDB_EDP 27 -#define BDB_LVDS_OPTIONS 40 -#define BDB_LVDS_LFP_DATA_PTRS 41 -#define BDB_LVDS_LFP_DATA 42 -#define BDB_LVDS_BACKLIGHT 43 -#define BDB_LVDS_POWER 44 -#define BDB_MIPI_CONFIG 52 -#define BDB_MIPI_SEQUENCE 53 -#define BDB_SKIP 254 /* VBIOS private block, ignore */ - -struct bdb_general_features { - /* bits 1 */ - u8 panel_fitting:2; - u8 flexaim:1; - u8 msg_enable:1; - u8 clear_screen:3; - u8 color_flip:1; - - /* bits 2 */ - u8 download_ext_vbt:1; - u8 enable_ssc:1; - u8 ssc_freq:1; - u8 enable_lfp_on_override:1; - u8 disable_ssc_ddt:1; - u8 rsvd7:1; - u8 display_clock_mode:1; - u8 rsvd8:1; /* finish byte */ - - /* bits 3 */ - u8 disable_smooth_vision:1; - u8 single_dvi:1; - u8 rsvd9:1; - u8 fdi_rx_polarity_inverted:1; - u8 rsvd10:4; /* finish byte */ - - /* bits 4 */ - u8 legacy_monitor_detect; - - /* bits 5 */ - u8 int_crt_support:1; - u8 int_tv_support:1; - u8 int_efp_support:1; - u8 dp_ssc_enb:1; /* PCH attached eDP supports SSC */ - u8 dp_ssc_freq:1; /* SSC freq for PCH attached eDP */ - u8 rsvd11:3; /* finish byte */ -} __packed; - -/* pre-915 */ -#define GPIO_PIN_DVI_LVDS 0x03 /* "DVI/LVDS DDC GPIO pins" */ -#define GPIO_PIN_ADD_I2C 0x05 /* "ADDCARD I2C GPIO pins" */ -#define GPIO_PIN_ADD_DDC 0x04 /* "ADDCARD DDC GPIO pins" */ -#define GPIO_PIN_ADD_DDC_I2C 0x06 /* "ADDCARD DDC/I2C GPIO pins" */ - -/* Pre 915 */ -#define DEVICE_TYPE_NONE 0x00 -#define DEVICE_TYPE_CRT 0x01 -#define DEVICE_TYPE_TV 0x09 -#define DEVICE_TYPE_EFP 0x12 -#define DEVICE_TYPE_LFP 0x22 -/* On 915+ */ -#define DEVICE_TYPE_CRT_DPMS 0x6001 -#define DEVICE_TYPE_CRT_DPMS_HOTPLUG 0x4001 -#define DEVICE_TYPE_TV_COMPOSITE 0x0209 -#define DEVICE_TYPE_TV_MACROVISION 0x0289 -#define DEVICE_TYPE_TV_RF_COMPOSITE 0x020c -#define DEVICE_TYPE_TV_SVIDEO_COMPOSITE 0x0609 -#define DEVICE_TYPE_TV_SCART 0x0209 -#define DEVICE_TYPE_TV_CODEC_HOTPLUG_PWR 0x6009 -#define DEVICE_TYPE_EFP_HOTPLUG_PWR 0x6012 -#define DEVICE_TYPE_EFP_DVI_HOTPLUG_PWR 0x6052 -#define DEVICE_TYPE_EFP_DVI_I 0x6053 -#define DEVICE_TYPE_EFP_DVI_D_DUAL 0x6152 -#define DEVICE_TYPE_EFP_DVI_D_HDCP 0x60d2 -#define DEVICE_TYPE_OPENLDI_HOTPLUG_PWR 0x6062 -#define DEVICE_TYPE_OPENLDI_DUALPIX 0x6162 -#define DEVICE_TYPE_LFP_PANELLINK 0x5012 -#define DEVICE_TYPE_LFP_CMOS_PWR 0x5042 -#define DEVICE_TYPE_LFP_LVDS_PWR 0x5062 -#define DEVICE_TYPE_LFP_LVDS_DUAL 0x5162 -#define DEVICE_TYPE_LFP_LVDS_DUAL_HDCP 0x51e2 - -#define DEVICE_CFG_NONE 0x00 -#define DEVICE_CFG_12BIT_DVOB 0x01 -#define DEVICE_CFG_12BIT_DVOC 0x02 -#define DEVICE_CFG_24BIT_DVOBC 0x09 -#define DEVICE_CFG_24BIT_DVOCB 0x0a -#define DEVICE_CFG_DUAL_DVOB 0x11 -#define DEVICE_CFG_DUAL_DVOC 0x12 -#define DEVICE_CFG_DUAL_DVOBC 0x13 -#define DEVICE_CFG_DUAL_LINK_DVOBC 0x19 -#define DEVICE_CFG_DUAL_LINK_DVOCB 0x1a - -#define DEVICE_WIRE_NONE 0x00 -#define DEVICE_WIRE_DVOB 0x01 -#define DEVICE_WIRE_DVOC 0x02 -#define DEVICE_WIRE_DVOBC 0x03 -#define DEVICE_WIRE_DVOBB 0x05 -#define DEVICE_WIRE_DVOCC 0x06 -#define DEVICE_WIRE_DVOB_MASTER 0x0d -#define DEVICE_WIRE_DVOC_MASTER 0x0e - -#define DEVICE_PORT_DVOA 0x00 /* none on 845+ */ -#define DEVICE_PORT_DVOB 0x01 -#define DEVICE_PORT_DVOC 0x02 /* - * We used to keep this struct but without any version control. We should avoid - * using it in the future, but it should be safe to keep using it in the old - * code. Do not change; we rely on its size. + * Please use intel_vbt_defs.h for VBT private data, to hide and abstract away + * the VBT from the rest of the driver. Add the parsed, clean data to struct + * intel_vbt_data within struct drm_i915_private. */ -struct old_child_dev_config { - u16 handle; - u16 device_type; - u8 device_id[10]; /* ascii string */ - u16 addin_offset; - u8 dvo_port; /* See Device_PORT_* above */ - u8 i2c_pin; - u8 slave_addr; - u8 ddc_pin; - u16 edid_ptr; - u8 dvo_cfg; /* See DEVICE_CFG_* above */ - u8 dvo2_port; - u8 i2c2_pin; - u8 slave2_addr; - u8 ddc2_pin; - u8 capabilities; - u8 dvo_wiring;/* See DEVICE_WIRE_* above */ - u8 dvo2_wiring; - u16 extended_type; - u8 dvo_function; -} __packed; - -/* This one contains field offsets that are known to be common for all BDB - * versions. Notice that the meaning of the contents contents may still change, - * but at least the offsets are consistent. */ - -/* Definitions for flags_1 */ -#define IBOOST_ENABLE (1<<3) - -struct common_child_dev_config { - u16 handle; - u16 device_type; - u8 not_common1[12]; - u8 dvo_port; - u8 not_common2[2]; - u8 ddc_pin; - u16 edid_ptr; - u8 obsolete; - u8 flags_1; - u8 not_common3[13]; - u8 iboost_level; -} __packed; - - -/* This field changes depending on the BDB version, so the most reliable way to - * read it is by checking the BDB version and reading the raw pointer. */ -union child_device_config { - /* This one is safe to be used anywhere, but the code should still check - * the BDB version. */ - u8 raw[33]; - /* This one should only be kept for legacy code. */ - struct old_child_dev_config old; - /* This one should also be safe to use anywhere, even without version - * checks. */ - struct common_child_dev_config common; -} __packed; - -struct bdb_general_definitions { - /* DDC GPIO */ - u8 crt_ddc_gmbus_pin; - - /* DPMS bits */ - u8 dpms_acpi:1; - u8 skip_boot_crt_detect:1; - u8 dpms_aim:1; - u8 rsvd1:5; /* finish byte */ - - /* boot device bits */ - u8 boot_display[2]; - u8 child_dev_size; - - /* - * Device info: - * If TV is present, it'll be at devices[0]. - * LVDS will be next, either devices[0] or [1], if present. - * On some platforms the number of device is 6. But could be as few as - * 4 if both TV and LVDS are missing. - * And the device num is related with the size of general definition - * block. It is obtained by using the following formula: - * number = (block_size - sizeof(bdb_general_definitions))/ - * defs->child_dev_size; - */ - uint8_t devices[0]; -} __packed; - -/* Mask for DRRS / Panel Channel / SSC / BLT control bits extraction */ -#define MODE_MASK 0x3 - -struct bdb_lvds_options { - u8 panel_type; - u8 rsvd1; - /* LVDS capabilities, stored in a dword */ - u8 pfit_mode:2; - u8 pfit_text_mode_enhanced:1; - u8 pfit_gfx_mode_enhanced:1; - u8 pfit_ratio_auto:1; - u8 pixel_dither:1; - u8 lvds_edid:1; - u8 rsvd2:1; - u8 rsvd4; - /* LVDS Panel channel bits stored here */ - u32 lvds_panel_channel_bits; - /* LVDS SSC (Spread Spectrum Clock) bits stored here. */ - u16 ssc_bits; - u16 ssc_freq; - u16 ssc_ddt; - /* Panel color depth defined here */ - u16 panel_color_depth; - /* LVDS panel type bits stored here */ - u32 dps_panel_type_bits; - /* LVDS backlight control type bits stored here */ - u32 blt_control_type_bits; -} __packed; - -/* LFP pointer table contains entries to the struct below */ -struct bdb_lvds_lfp_data_ptr { - u16 fp_timing_offset; /* offsets are from start of bdb */ - u8 fp_table_size; - u16 dvo_timing_offset; - u8 dvo_table_size; - u16 panel_pnp_id_offset; - u8 pnp_table_size; -} __packed; - -struct bdb_lvds_lfp_data_ptrs { - u8 lvds_entries; /* followed by one or more lvds_data_ptr structs */ - struct bdb_lvds_lfp_data_ptr ptr[16]; -} __packed; - -/* LFP data has 3 blocks per entry */ -struct lvds_fp_timing { - u16 x_res; - u16 y_res; - u32 lvds_reg; - u32 lvds_reg_val; - u32 pp_on_reg; - u32 pp_on_reg_val; - u32 pp_off_reg; - u32 pp_off_reg_val; - u32 pp_cycle_reg; - u32 pp_cycle_reg_val; - u32 pfit_reg; - u32 pfit_reg_val; - u16 terminator; -} __packed; - -struct lvds_dvo_timing { - u16 clock; /**< In 10khz */ - u8 hactive_lo; - u8 hblank_lo; - u8 hblank_hi:4; - u8 hactive_hi:4; - u8 vactive_lo; - u8 vblank_lo; - u8 vblank_hi:4; - u8 vactive_hi:4; - u8 hsync_off_lo; - u8 hsync_pulse_width; - u8 vsync_pulse_width:4; - u8 vsync_off:4; - u8 rsvd0:6; - u8 hsync_off_hi:2; - u8 h_image; - u8 v_image; - u8 max_hv; - u8 h_border; - u8 v_border; - u8 rsvd1:3; - u8 digital:2; - u8 vsync_positive:1; - u8 hsync_positive:1; - u8 rsvd2:1; -} __packed; - -struct lvds_pnp_id { - u16 mfg_name; - u16 product_code; - u32 serial; - u8 mfg_week; - u8 mfg_year; -} __packed; - -struct bdb_lvds_lfp_data_entry { - struct lvds_fp_timing fp_timing; - struct lvds_dvo_timing dvo_timing; - struct lvds_pnp_id pnp_id; -} __packed; - -struct bdb_lvds_lfp_data { - struct bdb_lvds_lfp_data_entry data[16]; -} __packed; - -#define BDB_BACKLIGHT_TYPE_NONE 0 -#define BDB_BACKLIGHT_TYPE_PWM 2 - -struct bdb_lfp_backlight_data_entry { - u8 type:2; - u8 active_low_pwm:1; - u8 obsolete1:5; - u16 pwm_freq_hz; - u8 min_brightness; - u8 obsolete2; - u8 obsolete3; -} __packed; - -struct bdb_lfp_backlight_data { - u8 entry_size; - struct bdb_lfp_backlight_data_entry data[16]; - u8 level[16]; -} __packed; - -struct aimdb_header { - char signature[16]; - char oem_device[20]; - u16 aimdb_version; - u16 aimdb_header_size; - u16 aimdb_size; -} __packed; - -struct aimdb_block { - u8 aimdb_id; - u16 aimdb_size; -} __packed; -struct vch_panel_data { - u16 fp_timing_offset; - u8 fp_timing_size; - u16 dvo_timing_offset; - u8 dvo_timing_size; - u16 text_fitting_offset; - u8 text_fitting_size; - u16 graphics_fitting_offset; - u8 graphics_fitting_size; -} __packed; - -struct vch_bdb_22 { - struct aimdb_block aimdb_block; - struct vch_panel_data panels[16]; -} __packed; - -struct bdb_sdvo_lvds_options { - u8 panel_backlight; - u8 h40_set_panel_type; - u8 panel_type; - u8 ssc_clk_freq; - u16 als_low_trip; - u16 als_high_trip; - u8 sclalarcoeff_tab_row_num; - u8 sclalarcoeff_tab_row_size; - u8 coefficient[8]; - u8 panel_misc_bits_1; - u8 panel_misc_bits_2; - u8 panel_misc_bits_3; - u8 panel_misc_bits_4; -} __packed; - - -#define BDB_DRIVER_FEATURE_NO_LVDS 0 -#define BDB_DRIVER_FEATURE_INT_LVDS 1 -#define BDB_DRIVER_FEATURE_SDVO_LVDS 2 -#define BDB_DRIVER_FEATURE_EDP 3 - -struct bdb_driver_features { - u8 boot_dev_algorithm:1; - u8 block_display_switch:1; - u8 allow_display_switch:1; - u8 hotplug_dvo:1; - u8 dual_view_zoom:1; - u8 int15h_hook:1; - u8 sprite_in_clone:1; - u8 primary_lfp_id:1; - - u16 boot_mode_x; - u16 boot_mode_y; - u8 boot_mode_bpp; - u8 boot_mode_refresh; - - u16 enable_lfp_primary:1; - u16 selective_mode_pruning:1; - u16 dual_frequency:1; - u16 render_clock_freq:1; /* 0: high freq; 1: low freq */ - u16 nt_clone_support:1; - u16 power_scheme_ui:1; /* 0: CUI; 1: 3rd party */ - u16 sprite_display_assign:1; /* 0: secondary; 1: primary */ - u16 cui_aspect_scaling:1; - u16 preserve_aspect_ratio:1; - u16 sdvo_device_power_down:1; - u16 crt_hotplug:1; - u16 lvds_config:2; - u16 tv_hotplug:1; - u16 hdmi_config:2; - - u8 static_display:1; - u8 reserved2:7; - u16 legacy_crt_max_x; - u16 legacy_crt_max_y; - u8 legacy_crt_max_refresh; - - u8 hdmi_termination; - u8 custom_vbt_version; - /* Driver features data block */ - u16 rmpm_enabled:1; - u16 s2ddt_enabled:1; - u16 dpst_enabled:1; - u16 bltclt_enabled:1; - u16 adb_enabled:1; - u16 drrs_enabled:1; - u16 grs_enabled:1; - u16 gpmt_enabled:1; - u16 tbt_enabled:1; - u16 psr_enabled:1; - u16 ips_enabled:1; - u16 reserved3:4; - u16 pc_feature_valid:1; -} __packed; - -#define EDP_18BPP 0 -#define EDP_24BPP 1 -#define EDP_30BPP 2 -#define EDP_RATE_1_62 0 -#define EDP_RATE_2_7 1 -#define EDP_LANE_1 0 -#define EDP_LANE_2 1 -#define EDP_LANE_4 3 -#define EDP_PREEMPHASIS_NONE 0 -#define EDP_PREEMPHASIS_3_5dB 1 -#define EDP_PREEMPHASIS_6dB 2 -#define EDP_PREEMPHASIS_9_5dB 3 -#define EDP_VSWING_0_4V 0 -#define EDP_VSWING_0_6V 1 -#define EDP_VSWING_0_8V 2 -#define EDP_VSWING_1_2V 3 +#ifndef _INTEL_BIOS_H_ +#define _INTEL_BIOS_H_ struct edp_power_seq { u16 t1_t3; @@ -565,245 +38,37 @@ struct edp_power_seq { u16 t11_t12; } __packed; -struct edp_link_params { - u8 rate:4; - u8 lanes:4; - u8 preemphasis:4; - u8 vswing:4; -} __packed; - -struct bdb_edp { - struct edp_power_seq power_seqs[16]; - u32 color_depth; - struct edp_link_params link_params[16]; - u32 sdrrs_msa_timing_delay; - - /* ith bit indicates enabled/disabled for (i+1)th panel */ - u16 edp_s3d_feature; - u16 edp_t3_optimization; - u64 edp_vswing_preemph; /* v173 */ -} __packed; - -struct psr_table { - /* Feature bits */ - u8 full_link:1; - u8 require_aux_to_wakeup:1; - u8 feature_bits_rsvd:6; - - /* Wait times */ - u8 idle_frames:4; - u8 lines_to_wait:3; - u8 wait_times_rsvd:1; - - /* TP wake up time in multiple of 100 */ - u16 tp1_wakeup_time; - u16 tp2_tp3_wakeup_time; -} __packed; - -struct bdb_psr { - struct psr_table psr_table[16]; -} __packed; - -/* - * Driver<->VBIOS interaction occurs through scratch bits in - * GR18 & SWF*. - */ - -/* GR18 bits are set on display switch and hotkey events */ -#define GR18_DRIVER_SWITCH_EN (1<<7) /* 0: VBIOS control, 1: driver control */ -#define GR18_HOTKEY_MASK 0x78 /* See also SWF4 15:0 */ -#define GR18_HK_NONE (0x0<<3) -#define GR18_HK_LFP_STRETCH (0x1<<3) -#define GR18_HK_TOGGLE_DISP (0x2<<3) -#define GR18_HK_DISP_SWITCH (0x4<<3) /* see SWF14 15:0 for what to enable */ -#define GR18_HK_POPUP_DISABLED (0x6<<3) -#define GR18_HK_POPUP_ENABLED (0x7<<3) -#define GR18_HK_PFIT (0x8<<3) -#define GR18_HK_APM_CHANGE (0xa<<3) -#define GR18_HK_MULTIPLE (0xc<<3) -#define GR18_USER_INT_EN (1<<2) -#define GR18_A0000_FLUSH_EN (1<<1) -#define GR18_SMM_EN (1<<0) - -/* Set by driver, cleared by VBIOS */ -#define SWF00_YRES_SHIFT 16 -#define SWF00_XRES_SHIFT 0 -#define SWF00_RES_MASK 0xffff - -/* Set by VBIOS at boot time and driver at runtime */ -#define SWF01_TV2_FORMAT_SHIFT 8 -#define SWF01_TV1_FORMAT_SHIFT 0 -#define SWF01_TV_FORMAT_MASK 0xffff - -#define SWF10_VBIOS_BLC_I2C_EN (1<<29) -#define SWF10_GTT_OVERRIDE_EN (1<<28) -#define SWF10_LFP_DPMS_OVR (1<<27) /* override DPMS on display switch */ -#define SWF10_ACTIVE_TOGGLE_LIST_MASK (7<<24) -#define SWF10_OLD_TOGGLE 0x0 -#define SWF10_TOGGLE_LIST_1 0x1 -#define SWF10_TOGGLE_LIST_2 0x2 -#define SWF10_TOGGLE_LIST_3 0x3 -#define SWF10_TOGGLE_LIST_4 0x4 -#define SWF10_PANNING_EN (1<<23) -#define SWF10_DRIVER_LOADED (1<<22) -#define SWF10_EXTENDED_DESKTOP (1<<21) -#define SWF10_EXCLUSIVE_MODE (1<<20) -#define SWF10_OVERLAY_EN (1<<19) -#define SWF10_PLANEB_HOLDOFF (1<<18) -#define SWF10_PLANEA_HOLDOFF (1<<17) -#define SWF10_VGA_HOLDOFF (1<<16) -#define SWF10_ACTIVE_DISP_MASK 0xffff -#define SWF10_PIPEB_LFP2 (1<<15) -#define SWF10_PIPEB_EFP2 (1<<14) -#define SWF10_PIPEB_TV2 (1<<13) -#define SWF10_PIPEB_CRT2 (1<<12) -#define SWF10_PIPEB_LFP (1<<11) -#define SWF10_PIPEB_EFP (1<<10) -#define SWF10_PIPEB_TV (1<<9) -#define SWF10_PIPEB_CRT (1<<8) -#define SWF10_PIPEA_LFP2 (1<<7) -#define SWF10_PIPEA_EFP2 (1<<6) -#define SWF10_PIPEA_TV2 (1<<5) -#define SWF10_PIPEA_CRT2 (1<<4) -#define SWF10_PIPEA_LFP (1<<3) -#define SWF10_PIPEA_EFP (1<<2) -#define SWF10_PIPEA_TV (1<<1) -#define SWF10_PIPEA_CRT (1<<0) - -#define SWF11_MEMORY_SIZE_SHIFT 16 -#define SWF11_SV_TEST_EN (1<<15) -#define SWF11_IS_AGP (1<<14) -#define SWF11_DISPLAY_HOLDOFF (1<<13) -#define SWF11_DPMS_REDUCED (1<<12) -#define SWF11_IS_VBE_MODE (1<<11) -#define SWF11_PIPEB_ACCESS (1<<10) /* 0 here means pipe a */ -#define SWF11_DPMS_MASK 0x07 -#define SWF11_DPMS_OFF (1<<2) -#define SWF11_DPMS_SUSPEND (1<<1) -#define SWF11_DPMS_STANDBY (1<<0) -#define SWF11_DPMS_ON 0 - -#define SWF14_GFX_PFIT_EN (1<<31) -#define SWF14_TEXT_PFIT_EN (1<<30) -#define SWF14_LID_STATUS_CLOSED (1<<29) /* 0 here means open */ -#define SWF14_POPUP_EN (1<<28) -#define SWF14_DISPLAY_HOLDOFF (1<<27) -#define SWF14_DISP_DETECT_EN (1<<26) -#define SWF14_DOCKING_STATUS_DOCKED (1<<25) /* 0 here means undocked */ -#define SWF14_DRIVER_STATUS (1<<24) -#define SWF14_OS_TYPE_WIN9X (1<<23) -#define SWF14_OS_TYPE_WINNT (1<<22) -/* 21:19 rsvd */ -#define SWF14_PM_TYPE_MASK 0x00070000 -#define SWF14_PM_ACPI_VIDEO (0x4 << 16) -#define SWF14_PM_ACPI (0x3 << 16) -#define SWF14_PM_APM_12 (0x2 << 16) -#define SWF14_PM_APM_11 (0x1 << 16) -#define SWF14_HK_REQUEST_MASK 0x0000ffff /* see GR18 6:3 for event type */ - /* if GR18 indicates a display switch */ -#define SWF14_DS_PIPEB_LFP2_EN (1<<15) -#define SWF14_DS_PIPEB_EFP2_EN (1<<14) -#define SWF14_DS_PIPEB_TV2_EN (1<<13) -#define SWF14_DS_PIPEB_CRT2_EN (1<<12) -#define SWF14_DS_PIPEB_LFP_EN (1<<11) -#define SWF14_DS_PIPEB_EFP_EN (1<<10) -#define SWF14_DS_PIPEB_TV_EN (1<<9) -#define SWF14_DS_PIPEB_CRT_EN (1<<8) -#define SWF14_DS_PIPEA_LFP2_EN (1<<7) -#define SWF14_DS_PIPEA_EFP2_EN (1<<6) -#define SWF14_DS_PIPEA_TV2_EN (1<<5) -#define SWF14_DS_PIPEA_CRT2_EN (1<<4) -#define SWF14_DS_PIPEA_LFP_EN (1<<3) -#define SWF14_DS_PIPEA_EFP_EN (1<<2) -#define SWF14_DS_PIPEA_TV_EN (1<<1) -#define SWF14_DS_PIPEA_CRT_EN (1<<0) - /* if GR18 indicates a panel fitting request */ -#define SWF14_PFIT_EN (1<<0) /* 0 means disable */ - /* if GR18 indicates an APM change request */ -#define SWF14_APM_HIBERNATE 0x4 -#define SWF14_APM_SUSPEND 0x3 -#define SWF14_APM_STANDBY 0x1 -#define SWF14_APM_RESTORE 0x0 - -/* Add the device class for LFP, TV, HDMI */ -#define DEVICE_TYPE_INT_LFP 0x1022 -#define DEVICE_TYPE_INT_TV 0x1009 -#define DEVICE_TYPE_HDMI 0x60D2 -#define DEVICE_TYPE_DP 0x68C6 -#define DEVICE_TYPE_eDP 0x78C6 - -#define DEVICE_TYPE_CLASS_EXTENSION (1 << 15) -#define DEVICE_TYPE_POWER_MANAGEMENT (1 << 14) -#define DEVICE_TYPE_HOTPLUG_SIGNALING (1 << 13) -#define DEVICE_TYPE_INTERNAL_CONNECTOR (1 << 12) -#define DEVICE_TYPE_NOT_HDMI_OUTPUT (1 << 11) -#define DEVICE_TYPE_MIPI_OUTPUT (1 << 10) -#define DEVICE_TYPE_COMPOSITE_OUTPUT (1 << 9) -#define DEVICE_TYPE_DUAL_CHANNEL (1 << 8) -#define DEVICE_TYPE_HIGH_SPEED_LINK (1 << 6) -#define DEVICE_TYPE_LVDS_SINGALING (1 << 5) -#define DEVICE_TYPE_TMDS_DVI_SIGNALING (1 << 4) -#define DEVICE_TYPE_VIDEO_SIGNALING (1 << 3) -#define DEVICE_TYPE_DISPLAYPORT_OUTPUT (1 << 2) -#define DEVICE_TYPE_DIGITAL_OUTPUT (1 << 1) -#define DEVICE_TYPE_ANALOG_OUTPUT (1 << 0) - -/* - * Bits we care about when checking for DEVICE_TYPE_eDP - * Depending on the system, the other bits may or may not - * be set for eDP outputs. - */ -#define DEVICE_TYPE_eDP_BITS \ - (DEVICE_TYPE_INTERNAL_CONNECTOR | \ - DEVICE_TYPE_MIPI_OUTPUT | \ - DEVICE_TYPE_COMPOSITE_OUTPUT | \ - DEVICE_TYPE_DUAL_CHANNEL | \ - DEVICE_TYPE_LVDS_SINGALING | \ - DEVICE_TYPE_TMDS_DVI_SIGNALING | \ - DEVICE_TYPE_VIDEO_SIGNALING | \ - DEVICE_TYPE_DISPLAYPORT_OUTPUT | \ - DEVICE_TYPE_ANALOG_OUTPUT) - -/* define the DVO port for HDMI output type */ -#define DVO_B 1 -#define DVO_C 2 -#define DVO_D 3 - -/* Possible values for the "DVO Port" field for versions >= 155: */ -#define DVO_PORT_HDMIA 0 -#define DVO_PORT_HDMIB 1 -#define DVO_PORT_HDMIC 2 -#define DVO_PORT_HDMID 3 -#define DVO_PORT_LVDS 4 -#define DVO_PORT_TV 5 -#define DVO_PORT_CRT 6 -#define DVO_PORT_DPB 7 -#define DVO_PORT_DPC 8 -#define DVO_PORT_DPD 9 -#define DVO_PORT_DPA 10 -#define DVO_PORT_DPE 11 -#define DVO_PORT_HDMIE 12 -#define DVO_PORT_MIPIA 21 -#define DVO_PORT_MIPIB 22 -#define DVO_PORT_MIPIC 23 -#define DVO_PORT_MIPID 24 +/* MIPI Sequence Block definitions */ +enum mipi_seq { + MIPI_SEQ_END = 0, + MIPI_SEQ_ASSERT_RESET, + MIPI_SEQ_INIT_OTP, + MIPI_SEQ_DISPLAY_ON, + MIPI_SEQ_DISPLAY_OFF, + MIPI_SEQ_DEASSERT_RESET, + MIPI_SEQ_BACKLIGHT_ON, /* sequence block v2+ */ + MIPI_SEQ_BACKLIGHT_OFF, /* sequence block v2+ */ + MIPI_SEQ_TEAR_ON, /* sequence block v2+ */ + MIPI_SEQ_TEAR_OFF, /* sequence block v3+ */ + MIPI_SEQ_POWER_ON, /* sequence block v3+ */ + MIPI_SEQ_POWER_OFF, /* sequence block v3+ */ + MIPI_SEQ_MAX +}; -/* Block 52 contains MIPI Panel info - * 6 such enteries will there. Index into correct - * entery is based on the panel_index in #40 LFP - */ -#define MAX_MIPI_CONFIGURATIONS 6 +enum mipi_seq_element { + MIPI_SEQ_ELEM_END = 0, + MIPI_SEQ_ELEM_SEND_PKT, + MIPI_SEQ_ELEM_DELAY, + MIPI_SEQ_ELEM_GPIO, + MIPI_SEQ_ELEM_I2C, /* sequence block v2+ */ + MIPI_SEQ_ELEM_SPI, /* sequence block v3+ */ + MIPI_SEQ_ELEM_PMIC, /* sequence block v3+ */ + MIPI_SEQ_ELEM_MAX +}; #define MIPI_DSI_UNDEFINED_PANEL_ID 0 #define MIPI_DSI_GENERIC_PANEL_ID 1 -/* - * PMIC vs SoC Backlight support specified in pwm_blc - * field in mipi_config block below. -*/ -#define PPS_BLC_PMIC 0 -#define PPS_BLC_SOC 1 - struct mipi_config { u16 panel_id; @@ -821,6 +86,8 @@ struct mipi_config { u32 video_transfer_mode:2; u32 cabc_supported:1; +#define PPS_BLC_PMIC 0 +#define PPS_BLC_SOC 1 u32 pwm_blc:1; /* Bit 13:10 */ @@ -924,12 +191,7 @@ struct mipi_config { } __packed; -/* Block 52 contains MIPI configuration block - * 6 * bdb_mipi_config, followed by 6 pps data - * block below - * - * all delays has a unit of 100us - */ +/* all delays have a unit of 100us */ struct mipi_pps_data { u16 panel_on_delay; u16 bl_enable_delay; @@ -938,57 +200,4 @@ struct mipi_pps_data { u16 panel_power_cycle_delay; } __packed; -struct bdb_mipi_config { - struct mipi_config config[MAX_MIPI_CONFIGURATIONS]; - struct mipi_pps_data pps[MAX_MIPI_CONFIGURATIONS]; -} __packed; - -/* Block 53 contains MIPI sequences as needed by the panel - * for enabling it. This block can be variable in size and - * can be maximum of 6 blocks - */ -struct bdb_mipi_sequence { - u8 version; - u8 data[0]; -} __packed; - -/* MIPI Sequnece Block definitions */ -enum mipi_seq { - MIPI_SEQ_END = 0, - MIPI_SEQ_ASSERT_RESET, - MIPI_SEQ_INIT_OTP, - MIPI_SEQ_DISPLAY_ON, - MIPI_SEQ_DISPLAY_OFF, - MIPI_SEQ_DEASSERT_RESET, - MIPI_SEQ_BACKLIGHT_ON, /* sequence block v2+ */ - MIPI_SEQ_BACKLIGHT_OFF, /* sequence block v2+ */ - MIPI_SEQ_TEAR_ON, /* sequence block v2+ */ - MIPI_SEQ_TEAR_OFF, /* sequence block v3+ */ - MIPI_SEQ_POWER_ON, /* sequence block v3+ */ - MIPI_SEQ_POWER_OFF, /* sequence block v3+ */ - MIPI_SEQ_MAX -}; - -enum mipi_seq_element { - MIPI_SEQ_ELEM_END = 0, - MIPI_SEQ_ELEM_SEND_PKT, - MIPI_SEQ_ELEM_DELAY, - MIPI_SEQ_ELEM_GPIO, - MIPI_SEQ_ELEM_I2C, /* sequence block v2+ */ - MIPI_SEQ_ELEM_SPI, /* sequence block v3+ */ - MIPI_SEQ_ELEM_PMIC, /* sequence block v3+ */ - MIPI_SEQ_ELEM_MAX -}; - -enum mipi_gpio_pin_index { - MIPI_GPIO_UNDEFINED = 0, - MIPI_GPIO_PANEL_ENABLE, - MIPI_GPIO_BL_ENABLE, - MIPI_GPIO_PWM_ENABLE, - MIPI_GPIO_RESET_N, - MIPI_GPIO_PWR_DOWN_R, - MIPI_GPIO_STDBY_RST_N, - MIPI_GPIO_MAX -}; - #endif /* _INTEL_BIOS_H_ */ diff --git a/drivers/gpu/drm/i915/intel_vbt_defs.h b/drivers/gpu/drm/i915/intel_vbt_defs.h new file mode 100644 index 000000000000..749dceab7c02 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_vbt_defs.h @@ -0,0 +1,826 @@ +/* + * Copyright © 2006-2016 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors: + * Eric Anholt + * + */ + +/* + * This information is private to VBT parsing in intel_bios.c. + * + * Please do NOT include anywhere else. + */ +#ifndef _INTEL_BIOS_PRIVATE +#error "intel_vbt_defs.h is private to intel_bios.c" +#endif + +#ifndef _INTEL_VBT_DEFS_H_ +#define _INTEL_VBT_DEFS_H_ + +#include "intel_bios.h" + +/** + * struct vbt_header - VBT Header structure + * @signature: VBT signature, always starts with "$VBT" + * @version: Version of this structure + * @header_size: Size of this structure + * @vbt_size: Size of VBT (VBT Header, BDB Header and data blocks) + * @vbt_checksum: Checksum + * @reserved0: Reserved + * @bdb_offset: Offset of &struct bdb_header from beginning of VBT + * @aim_offset: Offsets of add-in data blocks from beginning of VBT + */ +struct vbt_header { + u8 signature[20]; + u16 version; + u16 header_size; + u16 vbt_size; + u8 vbt_checksum; + u8 reserved0; + u32 bdb_offset; + u32 aim_offset[4]; +} __packed; + +/** + * struct bdb_header - BDB Header structure + * @signature: BDB signature "BIOS_DATA_BLOCK" + * @version: Version of the data block definitions + * @header_size: Size of this structure + * @bdb_size: Size of BDB (BDB Header and data blocks) + */ +struct bdb_header { + u8 signature[16]; + u16 version; + u16 header_size; + u16 bdb_size; +} __packed; + +/* strictly speaking, this is a "skip" block, but it has interesting info */ +struct vbios_data { + u8 type; /* 0 == desktop, 1 == mobile */ + u8 relstage; + u8 chipset; + u8 lvds_present:1; + u8 tv_present:1; + u8 rsvd2:6; /* finish byte */ + u8 rsvd3[4]; + u8 signon[155]; + u8 copyright[61]; + u16 code_segment; + u8 dos_boot_mode; + u8 bandwidth_percent; + u8 rsvd4; /* popup memory size */ + u8 resize_pci_bios; + u8 rsvd5; /* is crt already on ddc2 */ +} __packed; + +/* + * There are several types of BIOS data blocks (BDBs), each block has + * an ID and size in the first 3 bytes (ID in first, size in next 2). + * Known types are listed below. + */ +#define BDB_GENERAL_FEATURES 1 +#define BDB_GENERAL_DEFINITIONS 2 +#define BDB_OLD_TOGGLE_LIST 3 +#define BDB_MODE_SUPPORT_LIST 4 +#define BDB_GENERIC_MODE_TABLE 5 +#define BDB_EXT_MMIO_REGS 6 +#define BDB_SWF_IO 7 +#define BDB_SWF_MMIO 8 +#define BDB_PSR 9 +#define BDB_MODE_REMOVAL_TABLE 10 +#define BDB_CHILD_DEVICE_TABLE 11 +#define BDB_DRIVER_FEATURES 12 +#define BDB_DRIVER_PERSISTENCE 13 +#define BDB_EXT_TABLE_PTRS 14 +#define BDB_DOT_CLOCK_OVERRIDE 15 +#define BDB_DISPLAY_SELECT 16 +/* 17 rsvd */ +#define BDB_DRIVER_ROTATION 18 +#define BDB_DISPLAY_REMOVE 19 +#define BDB_OEM_CUSTOM 20 +#define BDB_EFP_LIST 21 /* workarounds for VGA hsync/vsync */ +#define BDB_SDVO_LVDS_OPTIONS 22 +#define BDB_SDVO_PANEL_DTDS 23 +#define BDB_SDVO_LVDS_PNP_IDS 24 +#define BDB_SDVO_LVDS_POWER_SEQ 25 +#define BDB_TV_OPTIONS 26 +#define BDB_EDP 27 +#define BDB_LVDS_OPTIONS 40 +#define BDB_LVDS_LFP_DATA_PTRS 41 +#define BDB_LVDS_LFP_DATA 42 +#define BDB_LVDS_BACKLIGHT 43 +#define BDB_LVDS_POWER 44 +#define BDB_MIPI_CONFIG 52 +#define BDB_MIPI_SEQUENCE 53 +#define BDB_SKIP 254 /* VBIOS private block, ignore */ + +struct bdb_general_features { + /* bits 1 */ + u8 panel_fitting:2; + u8 flexaim:1; + u8 msg_enable:1; + u8 clear_screen:3; + u8 color_flip:1; + + /* bits 2 */ + u8 download_ext_vbt:1; + u8 enable_ssc:1; + u8 ssc_freq:1; + u8 enable_lfp_on_override:1; + u8 disable_ssc_ddt:1; + u8 rsvd7:1; + u8 display_clock_mode:1; + u8 rsvd8:1; /* finish byte */ + + /* bits 3 */ + u8 disable_smooth_vision:1; + u8 single_dvi:1; + u8 rsvd9:1; + u8 fdi_rx_polarity_inverted:1; + u8 rsvd10:4; /* finish byte */ + + /* bits 4 */ + u8 legacy_monitor_detect; + + /* bits 5 */ + u8 int_crt_support:1; + u8 int_tv_support:1; + u8 int_efp_support:1; + u8 dp_ssc_enb:1; /* PCH attached eDP supports SSC */ + u8 dp_ssc_freq:1; /* SSC freq for PCH attached eDP */ + u8 rsvd11:3; /* finish byte */ +} __packed; + +/* pre-915 */ +#define GPIO_PIN_DVI_LVDS 0x03 /* "DVI/LVDS DDC GPIO pins" */ +#define GPIO_PIN_ADD_I2C 0x05 /* "ADDCARD I2C GPIO pins" */ +#define GPIO_PIN_ADD_DDC 0x04 /* "ADDCARD DDC GPIO pins" */ +#define GPIO_PIN_ADD_DDC_I2C 0x06 /* "ADDCARD DDC/I2C GPIO pins" */ + +/* Pre 915 */ +#define DEVICE_TYPE_NONE 0x00 +#define DEVICE_TYPE_CRT 0x01 +#define DEVICE_TYPE_TV 0x09 +#define DEVICE_TYPE_EFP 0x12 +#define DEVICE_TYPE_LFP 0x22 +/* On 915+ */ +#define DEVICE_TYPE_CRT_DPMS 0x6001 +#define DEVICE_TYPE_CRT_DPMS_HOTPLUG 0x4001 +#define DEVICE_TYPE_TV_COMPOSITE 0x0209 +#define DEVICE_TYPE_TV_MACROVISION 0x0289 +#define DEVICE_TYPE_TV_RF_COMPOSITE 0x020c +#define DEVICE_TYPE_TV_SVIDEO_COMPOSITE 0x0609 +#define DEVICE_TYPE_TV_SCART 0x0209 +#define DEVICE_TYPE_TV_CODEC_HOTPLUG_PWR 0x6009 +#define DEVICE_TYPE_EFP_HOTPLUG_PWR 0x6012 +#define DEVICE_TYPE_EFP_DVI_HOTPLUG_PWR 0x6052 +#define DEVICE_TYPE_EFP_DVI_I 0x6053 +#define DEVICE_TYPE_EFP_DVI_D_DUAL 0x6152 +#define DEVICE_TYPE_EFP_DVI_D_HDCP 0x60d2 +#define DEVICE_TYPE_OPENLDI_HOTPLUG_PWR 0x6062 +#define DEVICE_TYPE_OPENLDI_DUALPIX 0x6162 +#define DEVICE_TYPE_LFP_PANELLINK 0x5012 +#define DEVICE_TYPE_LFP_CMOS_PWR 0x5042 +#define DEVICE_TYPE_LFP_LVDS_PWR 0x5062 +#define DEVICE_TYPE_LFP_LVDS_DUAL 0x5162 +#define DEVICE_TYPE_LFP_LVDS_DUAL_HDCP 0x51e2 + +#define DEVICE_CFG_NONE 0x00 +#define DEVICE_CFG_12BIT_DVOB 0x01 +#define DEVICE_CFG_12BIT_DVOC 0x02 +#define DEVICE_CFG_24BIT_DVOBC 0x09 +#define DEVICE_CFG_24BIT_DVOCB 0x0a +#define DEVICE_CFG_DUAL_DVOB 0x11 +#define DEVICE_CFG_DUAL_DVOC 0x12 +#define DEVICE_CFG_DUAL_DVOBC 0x13 +#define DEVICE_CFG_DUAL_LINK_DVOBC 0x19 +#define DEVICE_CFG_DUAL_LINK_DVOCB 0x1a + +#define DEVICE_WIRE_NONE 0x00 +#define DEVICE_WIRE_DVOB 0x01 +#define DEVICE_WIRE_DVOC 0x02 +#define DEVICE_WIRE_DVOBC 0x03 +#define DEVICE_WIRE_DVOBB 0x05 +#define DEVICE_WIRE_DVOCC 0x06 +#define DEVICE_WIRE_DVOB_MASTER 0x0d +#define DEVICE_WIRE_DVOC_MASTER 0x0e + +#define DEVICE_PORT_DVOA 0x00 /* none on 845+ */ +#define DEVICE_PORT_DVOB 0x01 +#define DEVICE_PORT_DVOC 0x02 + +/* + * We used to keep this struct but without any version control. We should avoid + * using it in the future, but it should be safe to keep using it in the old + * code. Do not change; we rely on its size. + */ +struct old_child_dev_config { + u16 handle; + u16 device_type; + u8 device_id[10]; /* ascii string */ + u16 addin_offset; + u8 dvo_port; /* See Device_PORT_* above */ + u8 i2c_pin; + u8 slave_addr; + u8 ddc_pin; + u16 edid_ptr; + u8 dvo_cfg; /* See DEVICE_CFG_* above */ + u8 dvo2_port; + u8 i2c2_pin; + u8 slave2_addr; + u8 ddc2_pin; + u8 capabilities; + u8 dvo_wiring;/* See DEVICE_WIRE_* above */ + u8 dvo2_wiring; + u16 extended_type; + u8 dvo_function; +} __packed; + +/* This one contains field offsets that are known to be common for all BDB + * versions. Notice that the meaning of the contents contents may still change, + * but at least the offsets are consistent. */ + +/* Definitions for flags_1 */ +#define IBOOST_ENABLE (1<<3) + +struct common_child_dev_config { + u16 handle; + u16 device_type; + u8 not_common1[12]; + u8 dvo_port; + u8 not_common2[2]; + u8 ddc_pin; + u16 edid_ptr; + u8 obsolete; + u8 flags_1; + u8 not_common3[13]; + u8 iboost_level; +} __packed; + + +/* This field changes depending on the BDB version, so the most reliable way to + * read it is by checking the BDB version and reading the raw pointer. */ +union child_device_config { + /* This one is safe to be used anywhere, but the code should still check + * the BDB version. */ + u8 raw[33]; + /* This one should only be kept for legacy code. */ + struct old_child_dev_config old; + /* This one should also be safe to use anywhere, even without version + * checks. */ + struct common_child_dev_config common; +} __packed; + +struct bdb_general_definitions { + /* DDC GPIO */ + u8 crt_ddc_gmbus_pin; + + /* DPMS bits */ + u8 dpms_acpi:1; + u8 skip_boot_crt_detect:1; + u8 dpms_aim:1; + u8 rsvd1:5; /* finish byte */ + + /* boot device bits */ + u8 boot_display[2]; + u8 child_dev_size; + + /* + * Device info: + * If TV is present, it'll be at devices[0]. + * LVDS will be next, either devices[0] or [1], if present. + * On some platforms the number of device is 6. But could be as few as + * 4 if both TV and LVDS are missing. + * And the device num is related with the size of general definition + * block. It is obtained by using the following formula: + * number = (block_size - sizeof(bdb_general_definitions))/ + * defs->child_dev_size; + */ + uint8_t devices[0]; +} __packed; + +/* Mask for DRRS / Panel Channel / SSC / BLT control bits extraction */ +#define MODE_MASK 0x3 + +struct bdb_lvds_options { + u8 panel_type; + u8 rsvd1; + /* LVDS capabilities, stored in a dword */ + u8 pfit_mode:2; + u8 pfit_text_mode_enhanced:1; + u8 pfit_gfx_mode_enhanced:1; + u8 pfit_ratio_auto:1; + u8 pixel_dither:1; + u8 lvds_edid:1; + u8 rsvd2:1; + u8 rsvd4; + /* LVDS Panel channel bits stored here */ + u32 lvds_panel_channel_bits; + /* LVDS SSC (Spread Spectrum Clock) bits stored here. */ + u16 ssc_bits; + u16 ssc_freq; + u16 ssc_ddt; + /* Panel color depth defined here */ + u16 panel_color_depth; + /* LVDS panel type bits stored here */ + u32 dps_panel_type_bits; + /* LVDS backlight control type bits stored here */ + u32 blt_control_type_bits; +} __packed; + +/* LFP pointer table contains entries to the struct below */ +struct bdb_lvds_lfp_data_ptr { + u16 fp_timing_offset; /* offsets are from start of bdb */ + u8 fp_table_size; + u16 dvo_timing_offset; + u8 dvo_table_size; + u16 panel_pnp_id_offset; + u8 pnp_table_size; +} __packed; + +struct bdb_lvds_lfp_data_ptrs { + u8 lvds_entries; /* followed by one or more lvds_data_ptr structs */ + struct bdb_lvds_lfp_data_ptr ptr[16]; +} __packed; + +/* LFP data has 3 blocks per entry */ +struct lvds_fp_timing { + u16 x_res; + u16 y_res; + u32 lvds_reg; + u32 lvds_reg_val; + u32 pp_on_reg; + u32 pp_on_reg_val; + u32 pp_off_reg; + u32 pp_off_reg_val; + u32 pp_cycle_reg; + u32 pp_cycle_reg_val; + u32 pfit_reg; + u32 pfit_reg_val; + u16 terminator; +} __packed; + +struct lvds_dvo_timing { + u16 clock; /**< In 10khz */ + u8 hactive_lo; + u8 hblank_lo; + u8 hblank_hi:4; + u8 hactive_hi:4; + u8 vactive_lo; + u8 vblank_lo; + u8 vblank_hi:4; + u8 vactive_hi:4; + u8 hsync_off_lo; + u8 hsync_pulse_width; + u8 vsync_pulse_width:4; + u8 vsync_off:4; + u8 rsvd0:6; + u8 hsync_off_hi:2; + u8 h_image; + u8 v_image; + u8 max_hv; + u8 h_border; + u8 v_border; + u8 rsvd1:3; + u8 digital:2; + u8 vsync_positive:1; + u8 hsync_positive:1; + u8 rsvd2:1; +} __packed; + +struct lvds_pnp_id { + u16 mfg_name; + u16 product_code; + u32 serial; + u8 mfg_week; + u8 mfg_year; +} __packed; + +struct bdb_lvds_lfp_data_entry { + struct lvds_fp_timing fp_timing; + struct lvds_dvo_timing dvo_timing; + struct lvds_pnp_id pnp_id; +} __packed; + +struct bdb_lvds_lfp_data { + struct bdb_lvds_lfp_data_entry data[16]; +} __packed; + +#define BDB_BACKLIGHT_TYPE_NONE 0 +#define BDB_BACKLIGHT_TYPE_PWM 2 + +struct bdb_lfp_backlight_data_entry { + u8 type:2; + u8 active_low_pwm:1; + u8 obsolete1:5; + u16 pwm_freq_hz; + u8 min_brightness; + u8 obsolete2; + u8 obsolete3; +} __packed; + +struct bdb_lfp_backlight_data { + u8 entry_size; + struct bdb_lfp_backlight_data_entry data[16]; + u8 level[16]; +} __packed; + +struct aimdb_header { + char signature[16]; + char oem_device[20]; + u16 aimdb_version; + u16 aimdb_header_size; + u16 aimdb_size; +} __packed; + +struct aimdb_block { + u8 aimdb_id; + u16 aimdb_size; +} __packed; + +struct vch_panel_data { + u16 fp_timing_offset; + u8 fp_timing_size; + u16 dvo_timing_offset; + u8 dvo_timing_size; + u16 text_fitting_offset; + u8 text_fitting_size; + u16 graphics_fitting_offset; + u8 graphics_fitting_size; +} __packed; + +struct vch_bdb_22 { + struct aimdb_block aimdb_block; + struct vch_panel_data panels[16]; +} __packed; + +struct bdb_sdvo_lvds_options { + u8 panel_backlight; + u8 h40_set_panel_type; + u8 panel_type; + u8 ssc_clk_freq; + u16 als_low_trip; + u16 als_high_trip; + u8 sclalarcoeff_tab_row_num; + u8 sclalarcoeff_tab_row_size; + u8 coefficient[8]; + u8 panel_misc_bits_1; + u8 panel_misc_bits_2; + u8 panel_misc_bits_3; + u8 panel_misc_bits_4; +} __packed; + + +#define BDB_DRIVER_FEATURE_NO_LVDS 0 +#define BDB_DRIVER_FEATURE_INT_LVDS 1 +#define BDB_DRIVER_FEATURE_SDVO_LVDS 2 +#define BDB_DRIVER_FEATURE_EDP 3 + +struct bdb_driver_features { + u8 boot_dev_algorithm:1; + u8 block_display_switch:1; + u8 allow_display_switch:1; + u8 hotplug_dvo:1; + u8 dual_view_zoom:1; + u8 int15h_hook:1; + u8 sprite_in_clone:1; + u8 primary_lfp_id:1; + + u16 boot_mode_x; + u16 boot_mode_y; + u8 boot_mode_bpp; + u8 boot_mode_refresh; + + u16 enable_lfp_primary:1; + u16 selective_mode_pruning:1; + u16 dual_frequency:1; + u16 render_clock_freq:1; /* 0: high freq; 1: low freq */ + u16 nt_clone_support:1; + u16 power_scheme_ui:1; /* 0: CUI; 1: 3rd party */ + u16 sprite_display_assign:1; /* 0: secondary; 1: primary */ + u16 cui_aspect_scaling:1; + u16 preserve_aspect_ratio:1; + u16 sdvo_device_power_down:1; + u16 crt_hotplug:1; + u16 lvds_config:2; + u16 tv_hotplug:1; + u16 hdmi_config:2; + + u8 static_display:1; + u8 reserved2:7; + u16 legacy_crt_max_x; + u16 legacy_crt_max_y; + u8 legacy_crt_max_refresh; + + u8 hdmi_termination; + u8 custom_vbt_version; + /* Driver features data block */ + u16 rmpm_enabled:1; + u16 s2ddt_enabled:1; + u16 dpst_enabled:1; + u16 bltclt_enabled:1; + u16 adb_enabled:1; + u16 drrs_enabled:1; + u16 grs_enabled:1; + u16 gpmt_enabled:1; + u16 tbt_enabled:1; + u16 psr_enabled:1; + u16 ips_enabled:1; + u16 reserved3:4; + u16 pc_feature_valid:1; +} __packed; + +#define EDP_18BPP 0 +#define EDP_24BPP 1 +#define EDP_30BPP 2 +#define EDP_RATE_1_62 0 +#define EDP_RATE_2_7 1 +#define EDP_LANE_1 0 +#define EDP_LANE_2 1 +#define EDP_LANE_4 3 +#define EDP_PREEMPHASIS_NONE 0 +#define EDP_PREEMPHASIS_3_5dB 1 +#define EDP_PREEMPHASIS_6dB 2 +#define EDP_PREEMPHASIS_9_5dB 3 +#define EDP_VSWING_0_4V 0 +#define EDP_VSWING_0_6V 1 +#define EDP_VSWING_0_8V 2 +#define EDP_VSWING_1_2V 3 + + +struct edp_link_params { + u8 rate:4; + u8 lanes:4; + u8 preemphasis:4; + u8 vswing:4; +} __packed; + +struct bdb_edp { + struct edp_power_seq power_seqs[16]; + u32 color_depth; + struct edp_link_params link_params[16]; + u32 sdrrs_msa_timing_delay; + + /* ith bit indicates enabled/disabled for (i+1)th panel */ + u16 edp_s3d_feature; + u16 edp_t3_optimization; + u64 edp_vswing_preemph; /* v173 */ +} __packed; + +struct psr_table { + /* Feature bits */ + u8 full_link:1; + u8 require_aux_to_wakeup:1; + u8 feature_bits_rsvd:6; + + /* Wait times */ + u8 idle_frames:4; + u8 lines_to_wait:3; + u8 wait_times_rsvd:1; + + /* TP wake up time in multiple of 100 */ + u16 tp1_wakeup_time; + u16 tp2_tp3_wakeup_time; +} __packed; + +struct bdb_psr { + struct psr_table psr_table[16]; +} __packed; + +/* + * Driver<->VBIOS interaction occurs through scratch bits in + * GR18 & SWF*. + */ + +/* GR18 bits are set on display switch and hotkey events */ +#define GR18_DRIVER_SWITCH_EN (1<<7) /* 0: VBIOS control, 1: driver control */ +#define GR18_HOTKEY_MASK 0x78 /* See also SWF4 15:0 */ +#define GR18_HK_NONE (0x0<<3) +#define GR18_HK_LFP_STRETCH (0x1<<3) +#define GR18_HK_TOGGLE_DISP (0x2<<3) +#define GR18_HK_DISP_SWITCH (0x4<<3) /* see SWF14 15:0 for what to enable */ +#define GR18_HK_POPUP_DISABLED (0x6<<3) +#define GR18_HK_POPUP_ENABLED (0x7<<3) +#define GR18_HK_PFIT (0x8<<3) +#define GR18_HK_APM_CHANGE (0xa<<3) +#define GR18_HK_MULTIPLE (0xc<<3) +#define GR18_USER_INT_EN (1<<2) +#define GR18_A0000_FLUSH_EN (1<<1) +#define GR18_SMM_EN (1<<0) + +/* Set by driver, cleared by VBIOS */ +#define SWF00_YRES_SHIFT 16 +#define SWF00_XRES_SHIFT 0 +#define SWF00_RES_MASK 0xffff + +/* Set by VBIOS at boot time and driver at runtime */ +#define SWF01_TV2_FORMAT_SHIFT 8 +#define SWF01_TV1_FORMAT_SHIFT 0 +#define SWF01_TV_FORMAT_MASK 0xffff + +#define SWF10_VBIOS_BLC_I2C_EN (1<<29) +#define SWF10_GTT_OVERRIDE_EN (1<<28) +#define SWF10_LFP_DPMS_OVR (1<<27) /* override DPMS on display switch */ +#define SWF10_ACTIVE_TOGGLE_LIST_MASK (7<<24) +#define SWF10_OLD_TOGGLE 0x0 +#define SWF10_TOGGLE_LIST_1 0x1 +#define SWF10_TOGGLE_LIST_2 0x2 +#define SWF10_TOGGLE_LIST_3 0x3 +#define SWF10_TOGGLE_LIST_4 0x4 +#define SWF10_PANNING_EN (1<<23) +#define SWF10_DRIVER_LOADED (1<<22) +#define SWF10_EXTENDED_DESKTOP (1<<21) +#define SWF10_EXCLUSIVE_MODE (1<<20) +#define SWF10_OVERLAY_EN (1<<19) +#define SWF10_PLANEB_HOLDOFF (1<<18) +#define SWF10_PLANEA_HOLDOFF (1<<17) +#define SWF10_VGA_HOLDOFF (1<<16) +#define SWF10_ACTIVE_DISP_MASK 0xffff +#define SWF10_PIPEB_LFP2 (1<<15) +#define SWF10_PIPEB_EFP2 (1<<14) +#define SWF10_PIPEB_TV2 (1<<13) +#define SWF10_PIPEB_CRT2 (1<<12) +#define SWF10_PIPEB_LFP (1<<11) +#define SWF10_PIPEB_EFP (1<<10) +#define SWF10_PIPEB_TV (1<<9) +#define SWF10_PIPEB_CRT (1<<8) +#define SWF10_PIPEA_LFP2 (1<<7) +#define SWF10_PIPEA_EFP2 (1<<6) +#define SWF10_PIPEA_TV2 (1<<5) +#define SWF10_PIPEA_CRT2 (1<<4) +#define SWF10_PIPEA_LFP (1<<3) +#define SWF10_PIPEA_EFP (1<<2) +#define SWF10_PIPEA_TV (1<<1) +#define SWF10_PIPEA_CRT (1<<0) + +#define SWF11_MEMORY_SIZE_SHIFT 16 +#define SWF11_SV_TEST_EN (1<<15) +#define SWF11_IS_AGP (1<<14) +#define SWF11_DISPLAY_HOLDOFF (1<<13) +#define SWF11_DPMS_REDUCED (1<<12) +#define SWF11_IS_VBE_MODE (1<<11) +#define SWF11_PIPEB_ACCESS (1<<10) /* 0 here means pipe a */ +#define SWF11_DPMS_MASK 0x07 +#define SWF11_DPMS_OFF (1<<2) +#define SWF11_DPMS_SUSPEND (1<<1) +#define SWF11_DPMS_STANDBY (1<<0) +#define SWF11_DPMS_ON 0 + +#define SWF14_GFX_PFIT_EN (1<<31) +#define SWF14_TEXT_PFIT_EN (1<<30) +#define SWF14_LID_STATUS_CLOSED (1<<29) /* 0 here means open */ +#define SWF14_POPUP_EN (1<<28) +#define SWF14_DISPLAY_HOLDOFF (1<<27) +#define SWF14_DISP_DETECT_EN (1<<26) +#define SWF14_DOCKING_STATUS_DOCKED (1<<25) /* 0 here means undocked */ +#define SWF14_DRIVER_STATUS (1<<24) +#define SWF14_OS_TYPE_WIN9X (1<<23) +#define SWF14_OS_TYPE_WINNT (1<<22) +/* 21:19 rsvd */ +#define SWF14_PM_TYPE_MASK 0x00070000 +#define SWF14_PM_ACPI_VIDEO (0x4 << 16) +#define SWF14_PM_ACPI (0x3 << 16) +#define SWF14_PM_APM_12 (0x2 << 16) +#define SWF14_PM_APM_11 (0x1 << 16) +#define SWF14_HK_REQUEST_MASK 0x0000ffff /* see GR18 6:3 for event type */ + /* if GR18 indicates a display switch */ +#define SWF14_DS_PIPEB_LFP2_EN (1<<15) +#define SWF14_DS_PIPEB_EFP2_EN (1<<14) +#define SWF14_DS_PIPEB_TV2_EN (1<<13) +#define SWF14_DS_PIPEB_CRT2_EN (1<<12) +#define SWF14_DS_PIPEB_LFP_EN (1<<11) +#define SWF14_DS_PIPEB_EFP_EN (1<<10) +#define SWF14_DS_PIPEB_TV_EN (1<<9) +#define SWF14_DS_PIPEB_CRT_EN (1<<8) +#define SWF14_DS_PIPEA_LFP2_EN (1<<7) +#define SWF14_DS_PIPEA_EFP2_EN (1<<6) +#define SWF14_DS_PIPEA_TV2_EN (1<<5) +#define SWF14_DS_PIPEA_CRT2_EN (1<<4) +#define SWF14_DS_PIPEA_LFP_EN (1<<3) +#define SWF14_DS_PIPEA_EFP_EN (1<<2) +#define SWF14_DS_PIPEA_TV_EN (1<<1) +#define SWF14_DS_PIPEA_CRT_EN (1<<0) + /* if GR18 indicates a panel fitting request */ +#define SWF14_PFIT_EN (1<<0) /* 0 means disable */ + /* if GR18 indicates an APM change request */ +#define SWF14_APM_HIBERNATE 0x4 +#define SWF14_APM_SUSPEND 0x3 +#define SWF14_APM_STANDBY 0x1 +#define SWF14_APM_RESTORE 0x0 + +/* Add the device class for LFP, TV, HDMI */ +#define DEVICE_TYPE_INT_LFP 0x1022 +#define DEVICE_TYPE_INT_TV 0x1009 +#define DEVICE_TYPE_HDMI 0x60D2 +#define DEVICE_TYPE_DP 0x68C6 +#define DEVICE_TYPE_eDP 0x78C6 + +#define DEVICE_TYPE_CLASS_EXTENSION (1 << 15) +#define DEVICE_TYPE_POWER_MANAGEMENT (1 << 14) +#define DEVICE_TYPE_HOTPLUG_SIGNALING (1 << 13) +#define DEVICE_TYPE_INTERNAL_CONNECTOR (1 << 12) +#define DEVICE_TYPE_NOT_HDMI_OUTPUT (1 << 11) +#define DEVICE_TYPE_MIPI_OUTPUT (1 << 10) +#define DEVICE_TYPE_COMPOSITE_OUTPUT (1 << 9) +#define DEVICE_TYPE_DUAL_CHANNEL (1 << 8) +#define DEVICE_TYPE_HIGH_SPEED_LINK (1 << 6) +#define DEVICE_TYPE_LVDS_SINGALING (1 << 5) +#define DEVICE_TYPE_TMDS_DVI_SIGNALING (1 << 4) +#define DEVICE_TYPE_VIDEO_SIGNALING (1 << 3) +#define DEVICE_TYPE_DISPLAYPORT_OUTPUT (1 << 2) +#define DEVICE_TYPE_DIGITAL_OUTPUT (1 << 1) +#define DEVICE_TYPE_ANALOG_OUTPUT (1 << 0) + +/* + * Bits we care about when checking for DEVICE_TYPE_eDP + * Depending on the system, the other bits may or may not + * be set for eDP outputs. + */ +#define DEVICE_TYPE_eDP_BITS \ + (DEVICE_TYPE_INTERNAL_CONNECTOR | \ + DEVICE_TYPE_MIPI_OUTPUT | \ + DEVICE_TYPE_COMPOSITE_OUTPUT | \ + DEVICE_TYPE_DUAL_CHANNEL | \ + DEVICE_TYPE_LVDS_SINGALING | \ + DEVICE_TYPE_TMDS_DVI_SIGNALING | \ + DEVICE_TYPE_VIDEO_SIGNALING | \ + DEVICE_TYPE_DISPLAYPORT_OUTPUT | \ + DEVICE_TYPE_ANALOG_OUTPUT) + +/* define the DVO port for HDMI output type */ +#define DVO_B 1 +#define DVO_C 2 +#define DVO_D 3 + +/* Possible values for the "DVO Port" field for versions >= 155: */ +#define DVO_PORT_HDMIA 0 +#define DVO_PORT_HDMIB 1 +#define DVO_PORT_HDMIC 2 +#define DVO_PORT_HDMID 3 +#define DVO_PORT_LVDS 4 +#define DVO_PORT_TV 5 +#define DVO_PORT_CRT 6 +#define DVO_PORT_DPB 7 +#define DVO_PORT_DPC 8 +#define DVO_PORT_DPD 9 +#define DVO_PORT_DPA 10 +#define DVO_PORT_DPE 11 +#define DVO_PORT_HDMIE 12 +#define DVO_PORT_MIPIA 21 +#define DVO_PORT_MIPIB 22 +#define DVO_PORT_MIPIC 23 +#define DVO_PORT_MIPID 24 + +/* Block 52 contains MIPI configuration block + * 6 * bdb_mipi_config, followed by 6 pps data block + * block below + */ +#define MAX_MIPI_CONFIGURATIONS 6 + +struct bdb_mipi_config { + struct mipi_config config[MAX_MIPI_CONFIGURATIONS]; + struct mipi_pps_data pps[MAX_MIPI_CONFIGURATIONS]; +} __packed; + +/* Block 53 contains MIPI sequences as needed by the panel + * for enabling it. This block can be variable in size and + * can be maximum of 6 blocks + */ +struct bdb_mipi_sequence { + u8 version; + u8 data[0]; +} __packed; + +enum mipi_gpio_pin_index { + MIPI_GPIO_UNDEFINED = 0, + MIPI_GPIO_PANEL_ENABLE, + MIPI_GPIO_BL_ENABLE, + MIPI_GPIO_PWM_ENABLE, + MIPI_GPIO_RESET_N, + MIPI_GPIO_PWR_DOWN_R, + MIPI_GPIO_STDBY_RST_N, + MIPI_GPIO_MAX +}; + +#endif /* _INTEL_VBT_DEFS_H_ */ -- cgit v1.2.3 From ee4b6faf96a990d2acc30084f4edf015ca21b9c4 Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Wed, 16 Mar 2016 17:54:00 +0200 Subject: drm/i915: Modify reset func to handle per engine resets In full gpu reset we prime all engines and reset domains corresponding to each engine. Per engine reset is just a special case of this process wherein only a single engine is reset. This change is aimed to modify relevant functions to achieve this. There are some other steps we carry out in case of engine reset which are addressed in later patches. Reset func now accepts a mask of all engines that need to be reset. Where per engine resets are supported, error handler populates the mask accordingly otherwise all engines are specified. v2: ALL_ENGINES mask fixup, better for_each_ring_masked (Chris) v3: Whitespace fixes (Chris) v4: Rebase due to s/ring/engine Cc: Chris Wilson Signed-off-by: Mika Kuoppala Signed-off-by: Arun Siluvery Reviewed-by: Chris Wilson Signed-off-by: Mika Kuoppala Link: http://patchwork.freedesktop.org/patch/msgid/1458143640-20563-1-git-send-email-mika.kuoppala@intel.com --- drivers/gpu/drm/i915/i915_drv.c | 2 +- drivers/gpu/drm/i915/i915_drv.h | 8 ++- drivers/gpu/drm/i915/i915_gem.c | 14 +++--- drivers/gpu/drm/i915/i915_gem_context.c | 2 +- drivers/gpu/drm/i915/i915_reg.h | 2 + drivers/gpu/drm/i915/intel_uncore.c | 87 ++++++++++++++++++++++++--------- 6 files changed, 82 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 20e82008b8b6..3648b73b48da 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -881,7 +881,7 @@ int i915_reset(struct drm_device *dev) simulated = dev_priv->gpu_error.stop_rings != 0; - ret = intel_gpu_reset(dev); + ret = intel_gpu_reset(dev, ALL_ENGINES); /* Also reset the gpu hangman. */ if (simulated) { diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 8a10c4b39a7f..f2ab5452f12d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1988,6 +1988,10 @@ static inline struct drm_i915_private *guc_to_i915(struct intel_guc *guc) for ((i__) = 0; (i__) < I915_NUM_ENGINES; (i__)++) \ for_each_if ((((ring__) = &(dev_priv__)->engine[(i__)]), intel_engine_initialized((ring__)))) +#define for_each_engine_masked(engine__, dev_priv__, mask__) \ + for ((engine__) = &dev_priv->engine[0]; (engine__) < &dev_priv->engine[I915_NUM_ENGINES]; (engine__)++) \ + for_each_if (intel_engine_flag((engine__)) & (mask__) && intel_engine_initialized((engine__))) + enum hdmi_force_audio { HDMI_AUDIO_OFF_DVI = -2, /* no aux data for HDMI-DVI converter */ HDMI_AUDIO_OFF, /* force turn off HDMI audio */ @@ -2570,6 +2574,8 @@ struct drm_i915_cmd_table { #define BLT_RING (1<ring_mask & BSD_RING) #define HAS_BSD2(dev) (INTEL_INFO(dev)->ring_mask & BSD2_RING) #define HAS_BLT(dev) (INTEL_INFO(dev)->ring_mask & BLT_RING) @@ -2698,7 +2704,7 @@ extern void i915_driver_postclose(struct drm_device *dev, extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); #endif -extern int intel_gpu_reset(struct drm_device *dev); +extern int intel_gpu_reset(struct drm_device *dev, u32 engine_mask); extern bool intel_has_gpu_reset(struct drm_device *dev); extern int i915_reset(struct drm_device *dev); extern unsigned long i915_chipset_val(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 31652c1da761..a25109aa033c 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -5012,13 +5012,13 @@ i915_gem_cleanup_engines(struct drm_device *dev) for_each_engine(engine, dev_priv, i) dev_priv->gt.cleanup_engine(engine); - if (i915.enable_execlists) - /* - * Neither the BIOS, ourselves or any other kernel - * expects the system to be in execlists mode on startup, - * so we need to reset the GPU back to legacy mode. - */ - intel_gpu_reset(dev); + if (i915.enable_execlists) + /* + * Neither the BIOS, ourselves or any other kernel + * expects the system to be in execlists mode on startup, + * so we need to reset the GPU back to legacy mode. + */ + intel_gpu_reset(dev, ALL_ENGINES); } static void diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 1993449ab7c5..c114665a24b3 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -413,7 +413,7 @@ void i915_gem_context_fini(struct drm_device *dev) /* The only known way to stop the gpu from accessing the hw context is * to reset it. Do this as the very last operation to avoid confusing * other code, leading to spurious errors. */ - intel_gpu_reset(dev); + intel_gpu_reset(dev, ALL_ENGINES); /* When default context is created and switched to, base object refcount * will be 2 (+1 from object creation and +1 from do_switch()). diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index d4a298f715f4..07e04495cd9a 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -164,6 +164,8 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) #define GEN6_GRDOM_RENDER (1 << 1) #define GEN6_GRDOM_MEDIA (1 << 2) #define GEN6_GRDOM_BLT (1 << 3) +#define GEN6_GRDOM_VECS (1 << 4) +#define GEN8_GRDOM_MEDIA2 (1 << 7) #define RING_PP_DIR_BASE(ring) _MMIO((ring)->mmio_base+0x228) #define RING_PP_DIR_BASE_READ(ring) _MMIO((ring)->mmio_base+0x518) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 02add02e0ce4..512b7faedefd 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -1433,7 +1433,7 @@ static int i915_reset_complete(struct drm_device *dev) return (gdrst & GRDOM_RESET_STATUS) == 0; } -static int i915_do_reset(struct drm_device *dev) +static int i915_do_reset(struct drm_device *dev, unsigned engine_mask) { /* assert reset for at least 20 usec */ pci_write_config_byte(dev->pdev, I915_GDRST, GRDOM_RESET_ENABLE); @@ -1450,13 +1450,13 @@ static int g4x_reset_complete(struct drm_device *dev) return (gdrst & GRDOM_RESET_ENABLE) == 0; } -static int g33_do_reset(struct drm_device *dev) +static int g33_do_reset(struct drm_device *dev, unsigned engine_mask) { pci_write_config_byte(dev->pdev, I915_GDRST, GRDOM_RESET_ENABLE); return wait_for(g4x_reset_complete(dev), 500); } -static int g4x_do_reset(struct drm_device *dev) +static int g4x_do_reset(struct drm_device *dev, unsigned engine_mask) { struct drm_i915_private *dev_priv = dev->dev_private; int ret; @@ -1486,7 +1486,7 @@ static int g4x_do_reset(struct drm_device *dev) return 0; } -static int ironlake_do_reset(struct drm_device *dev) +static int ironlake_do_reset(struct drm_device *dev, unsigned engine_mask) { struct drm_i915_private *dev_priv = dev->dev_private; int ret; @@ -1510,21 +1510,62 @@ static int ironlake_do_reset(struct drm_device *dev) return 0; } -static int gen6_do_reset(struct drm_device *dev) +/* Reset the hardware domains (GENX_GRDOM_*) specified by mask */ +static int gen6_hw_domain_reset(struct drm_i915_private *dev_priv, + u32 hw_domain_mask) { - struct drm_i915_private *dev_priv = dev->dev_private; - int ret; - - /* Reset the chip */ + int ret; /* GEN6_GDRST is not in the gt power well, no need to check * for fifo space for the write or forcewake the chip for * the read */ - __raw_i915_write32(dev_priv, GEN6_GDRST, GEN6_GRDOM_FULL); + __raw_i915_write32(dev_priv, GEN6_GDRST, hw_domain_mask); - /* Spin waiting for the device to ack the reset request */ - ret = wait_for((__raw_i915_read32(dev_priv, GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500); +#define ACKED ((__raw_i915_read32(dev_priv, GEN6_GDRST) & hw_domain_mask) == 0) + /* Spin waiting for the device to ack the reset requests */ + ret = wait_for(ACKED, 500); +#undef ACKED + + return ret; +} + +/** + * gen6_reset_engines - reset individual engines + * @dev: DRM device + * @engine_mask: mask of intel_ring_flag() engines or ALL_ENGINES for full reset + * + * This function will reset the individual engines that are set in engine_mask. + * If you provide ALL_ENGINES as mask, full global domain reset will be issued. + * + * Note: It is responsibility of the caller to handle the difference between + * asking full domain reset versus reset for all available individual engines. + * + * Returns 0 on success, nonzero on error. + */ +static int gen6_reset_engines(struct drm_device *dev, unsigned engine_mask) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_engine_cs *engine; + const u32 hw_engine_mask[I915_NUM_ENGINES] = { + [RCS] = GEN6_GRDOM_RENDER, + [BCS] = GEN6_GRDOM_BLT, + [VCS] = GEN6_GRDOM_MEDIA, + [VCS2] = GEN8_GRDOM_MEDIA2, + [VECS] = GEN6_GRDOM_VECS, + }; + u32 hw_mask; + int ret; + + if (engine_mask == ALL_ENGINES) { + hw_mask = GEN6_GRDOM_FULL; + } else { + hw_mask = 0; + for_each_engine_masked(engine, dev_priv, engine_mask) + hw_mask |= hw_engine_mask[engine->id]; + } + + ret = gen6_hw_domain_reset(dev_priv, hw_mask); intel_uncore_forcewake_reset(dev, true); @@ -1567,34 +1608,34 @@ static void gen8_unrequest_engine_reset(struct intel_engine_cs *engine) _MASKED_BIT_DISABLE(RESET_CTL_REQUEST_RESET)); } -static int gen8_do_reset(struct drm_device *dev) +static int gen8_reset_engines(struct drm_device *dev, unsigned engine_mask) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *engine; - int i; - for_each_engine(engine, dev_priv, i) + for_each_engine_masked(engine, dev_priv, engine_mask) if (gen8_request_engine_reset(engine)) goto not_ready; - return gen6_do_reset(dev); + return gen6_reset_engines(dev, engine_mask); not_ready: - for_each_engine(engine, dev_priv, i) + for_each_engine_masked(engine, dev_priv, engine_mask) gen8_unrequest_engine_reset(engine); return -EIO; } -static int (*intel_get_gpu_reset(struct drm_device *dev))(struct drm_device *) +static int (*intel_get_gpu_reset(struct drm_device *dev))(struct drm_device *, + unsigned engine_mask) { if (!i915.reset) return NULL; if (INTEL_INFO(dev)->gen >= 8) - return gen8_do_reset; + return gen8_reset_engines; else if (INTEL_INFO(dev)->gen >= 6) - return gen6_do_reset; + return gen6_reset_engines; else if (IS_GEN5(dev)) return ironlake_do_reset; else if (IS_G4X(dev)) @@ -1607,10 +1648,10 @@ static int (*intel_get_gpu_reset(struct drm_device *dev))(struct drm_device *) return NULL; } -int intel_gpu_reset(struct drm_device *dev) +int intel_gpu_reset(struct drm_device *dev, unsigned engine_mask) { struct drm_i915_private *dev_priv = to_i915(dev); - int (*reset)(struct drm_device *); + int (*reset)(struct drm_device *, unsigned); int ret; reset = intel_get_gpu_reset(dev); @@ -1621,7 +1662,7 @@ int intel_gpu_reset(struct drm_device *dev) * request may be dropped and never completes (causing -EIO). */ intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); - ret = reset(dev); + ret = reset(dev, engine_mask); intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); return ret; -- cgit v1.2.3 From 066de1aadf6aba1911560cf90a5bc8e25ca1aae9 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 16 Mar 2016 13:38:50 +0200 Subject: Fix MCHBAR cleanup on the driver init error path MCHBAR is cleaned up in i915_mmio_cleanup(), so the separate call in i915_driver_load() is incorrect. CC: David Weinehall Fixes: ad5c3d3ffbb2 ("drm/i915: Move MCHBAR setup earlier during init") Signed-off-by: Imre Deak Reviewed-by: David Weinehall Link: http://patchwork.freedesktop.org/patch/msgid/1458128348-15730-2-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_dma.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 85b31300103d..1cbd99528329 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1175,7 +1175,6 @@ out_gem_unload: if (dev->pdev->msi_enabled) pci_disable_msi(dev->pdev); - intel_teardown_mchbar(dev); pm_qos_remove_request(&dev_priv->pm_qos); arch_phys_wc_del(dev_priv->gtt.mtrr); io_mapping_free(dev_priv->gtt.mappable); -- cgit v1.2.3 From 861f878e6a7a8bc152c92de358b96eb3bd086f78 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 16 Mar 2016 13:38:51 +0200 Subject: drm/i915: Move load time PCH detect, DPIO, power domain SW init earlier These are all SW only init steps not accessing the device and they only need the platform identification macros to work, which are already available earlier, so move these init steps earlier. Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1458128348-15730-3-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_dma.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 1cbd99528329..c79f53292a6f 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1020,7 +1020,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) if (ret < 0) goto out_free_priv; + /* This must be called before any calls to HAS_PCH_* */ + intel_detect_pch(dev); + intel_pm_setup(dev); + intel_init_dpio(dev_priv); + intel_power_domains_init(dev_priv); intel_runtime_pm_get(dev_priv); @@ -1045,9 +1050,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) if (ret < 0) goto put_bridge; - /* This must be called before any calls to HAS_PCH_* */ - intel_detect_pch(dev); - intel_uncore_init(dev); ret = i915_gem_gtt_init(dev); @@ -1124,16 +1126,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) intel_device_info_runtime_init(dev); - intel_init_dpio(dev_priv); - if (INTEL_INFO(dev)->num_pipes) { ret = drm_vblank_init(dev, INTEL_INFO(dev)->num_pipes); if (ret) goto out_gem_unload; } - intel_power_domains_init(dev_priv); - ret = i915_load_modeset_init(dev); if (ret < 0) { DRM_ERROR("failed to init modeset\n"); -- cgit v1.2.3 From bd39ec5ddae8807644196cadbb62bb2b3d88607b Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 16 Mar 2016 13:38:52 +0200 Subject: drm/i915: Move load time IRQ SW init earlier Most of the IRQ init is setting up hooks so move that part earlier. Leave the pm_qos_add_request() call in place. Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1458128348-15730-4-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_dma.c | 5 ++++- drivers/gpu/drm/i915/i915_irq.c | 2 -- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index c79f53292a6f..e23cdadc1bee 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1026,6 +1026,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) intel_pm_setup(dev); intel_init_dpio(dev_priv); intel_power_domains_init(dev_priv); + intel_irq_init(dev_priv); intel_runtime_pm_get(dev_priv); @@ -1100,7 +1101,9 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) dev_priv->gtt.mtrr = arch_phys_wc_add(dev_priv->gtt.mappable_base, aperture_size); - intel_irq_init(dev_priv); + pm_qos_add_request(&dev_priv->pm_qos, PM_QOS_CPU_DMA_LATENCY, + PM_QOS_DEFAULT_VALUE); + intel_uncore_sanitize(dev); intel_opregion_setup(dev); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 0f61ae0ff609..8f3e3309c3ab 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -4565,8 +4565,6 @@ void intel_irq_init(struct drm_i915_private *dev_priv) INIT_DELAYED_WORK(&dev_priv->gpu_error.hangcheck_work, i915_hangcheck_elapsed); - pm_qos_add_request(&dev_priv->pm_qos, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); - if (IS_GEN2(dev_priv)) { dev->max_vblank_count = 0; dev->driver->get_vblank_counter = i8xx_get_vblank_counter; -- cgit v1.2.3 From 8821294172f0f807b7928909aeadd4e7467d2ed0 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 16 Mar 2016 13:38:53 +0200 Subject: drm/i915: Move load time init of display/audio hooks earlier All of this is SW only initialization so we can move them earlier. Move the mutex init where the rest of the locks are inited. While at it also convert dev to dev_priv. v2: - use the term hook instead of callback for these functions (Jani) CC: Jani Nikula Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1458128348-15730-5-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_dma.c | 3 ++ drivers/gpu/drm/i915/intel_audio.c | 16 +++---- drivers/gpu/drm/i915/intel_display.c | 82 +++++++++++++++++------------------- drivers/gpu/drm/i915/intel_drv.h | 3 +- 4 files changed, 51 insertions(+), 53 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index e23cdadc1bee..b90d2d9feda8 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1015,6 +1015,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) mutex_init(&dev_priv->modeset_restore_lock); mutex_init(&dev_priv->av_mutex); mutex_init(&dev_priv->wm.wm_mutex); + mutex_init(&dev_priv->pps_mutex); ret = i915_workqueues_init(dev_priv); if (ret < 0) @@ -1027,6 +1028,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) intel_init_dpio(dev_priv); intel_power_domains_init(dev_priv); intel_irq_init(dev_priv); + intel_init_display_hooks(dev_priv); + intel_init_audio_hooks(dev_priv); intel_runtime_pm_get(dev_priv); diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 30f921421b0c..fdc8b2a1d0ae 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -564,23 +564,21 @@ void intel_audio_codec_disable(struct intel_encoder *intel_encoder) } /** - * intel_init_audio - Set up chip specific audio functions - * @dev: drm device + * intel_init_audio_hooks - Set up chip specific audio hooks + * @dev_priv: device private */ -void intel_init_audio(struct drm_device *dev) +void intel_init_audio_hooks(struct drm_i915_private *dev_priv) { - struct drm_i915_private *dev_priv = dev->dev_private; - - if (IS_G4X(dev)) { + if (IS_G4X(dev_priv)) { dev_priv->display.audio_codec_enable = g4x_audio_codec_enable; dev_priv->display.audio_codec_disable = g4x_audio_codec_disable; - } else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) { + } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { dev_priv->display.audio_codec_enable = ilk_audio_codec_enable; dev_priv->display.audio_codec_disable = ilk_audio_codec_disable; - } else if (IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8) { + } else if (IS_HASWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >= 8) { dev_priv->display.audio_codec_enable = hsw_audio_codec_enable; dev_priv->display.audio_codec_disable = hsw_audio_codec_disable; - } else if (HAS_PCH_SPLIT(dev)) { + } else if (HAS_PCH_SPLIT(dev_priv)) { dev_priv->display.audio_codec_enable = ilk_audio_codec_enable; dev_priv->display.audio_codec_disable = ilk_audio_codec_disable; } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e3e158175256..ab1ec8daae92 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -14824,23 +14824,24 @@ static const struct drm_mode_config_funcs intel_mode_funcs = { .atomic_state_clear = intel_atomic_state_clear, }; -/* Set up chip specific display functions */ -static void intel_init_display(struct drm_device *dev) +/** + * intel_init_display_hooks - initialize the display modesetting hooks + * @dev_priv: device private + */ +void intel_init_display_hooks(struct drm_i915_private *dev_priv) { - struct drm_i915_private *dev_priv = dev->dev_private; - - if (HAS_PCH_SPLIT(dev) || IS_G4X(dev)) + if (HAS_PCH_SPLIT(dev_priv) || IS_G4X(dev_priv)) dev_priv->display.find_dpll = g4x_find_best_dpll; - else if (IS_CHERRYVIEW(dev)) + else if (IS_CHERRYVIEW(dev_priv)) dev_priv->display.find_dpll = chv_find_best_dpll; - else if (IS_VALLEYVIEW(dev)) + else if (IS_VALLEYVIEW(dev_priv)) dev_priv->display.find_dpll = vlv_find_best_dpll; - else if (IS_PINEVIEW(dev)) + else if (IS_PINEVIEW(dev_priv)) dev_priv->display.find_dpll = pnv_find_best_dpll; else dev_priv->display.find_dpll = i9xx_find_best_dpll; - if (INTEL_INFO(dev)->gen >= 9) { + if (INTEL_INFO(dev_priv)->gen >= 9) { dev_priv->display.get_pipe_config = haswell_get_pipe_config; dev_priv->display.get_initial_plane_config = skylake_get_initial_plane_config; @@ -14848,7 +14849,7 @@ static void intel_init_display(struct drm_device *dev) haswell_crtc_compute_clock; dev_priv->display.crtc_enable = haswell_crtc_enable; dev_priv->display.crtc_disable = haswell_crtc_disable; - } else if (HAS_DDI(dev)) { + } else if (HAS_DDI(dev_priv)) { dev_priv->display.get_pipe_config = haswell_get_pipe_config; dev_priv->display.get_initial_plane_config = ironlake_get_initial_plane_config; @@ -14856,7 +14857,7 @@ static void intel_init_display(struct drm_device *dev) haswell_crtc_compute_clock; dev_priv->display.crtc_enable = haswell_crtc_enable; dev_priv->display.crtc_disable = haswell_crtc_disable; - } else if (HAS_PCH_SPLIT(dev)) { + } else if (HAS_PCH_SPLIT(dev_priv)) { dev_priv->display.get_pipe_config = ironlake_get_pipe_config; dev_priv->display.get_initial_plane_config = ironlake_get_initial_plane_config; @@ -14864,7 +14865,7 @@ static void intel_init_display(struct drm_device *dev) ironlake_crtc_compute_clock; dev_priv->display.crtc_enable = ironlake_crtc_enable; dev_priv->display.crtc_disable = ironlake_crtc_disable; - } else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) { + } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { dev_priv->display.get_pipe_config = i9xx_get_pipe_config; dev_priv->display.get_initial_plane_config = i9xx_get_initial_plane_config; @@ -14881,89 +14882,89 @@ static void intel_init_display(struct drm_device *dev) } /* Returns the core display clock speed */ - if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) + if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) dev_priv->display.get_display_clock_speed = skylake_get_display_clock_speed; - else if (IS_BROXTON(dev)) + else if (IS_BROXTON(dev_priv)) dev_priv->display.get_display_clock_speed = broxton_get_display_clock_speed; - else if (IS_BROADWELL(dev)) + else if (IS_BROADWELL(dev_priv)) dev_priv->display.get_display_clock_speed = broadwell_get_display_clock_speed; - else if (IS_HASWELL(dev)) + else if (IS_HASWELL(dev_priv)) dev_priv->display.get_display_clock_speed = haswell_get_display_clock_speed; - else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) + else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) dev_priv->display.get_display_clock_speed = valleyview_get_display_clock_speed; - else if (IS_GEN5(dev)) + else if (IS_GEN5(dev_priv)) dev_priv->display.get_display_clock_speed = ilk_get_display_clock_speed; - else if (IS_I945G(dev) || IS_BROADWATER(dev) || - IS_GEN6(dev) || IS_IVYBRIDGE(dev)) + else if (IS_I945G(dev_priv) || IS_BROADWATER(dev_priv) || + IS_GEN6(dev_priv) || IS_IVYBRIDGE(dev_priv)) dev_priv->display.get_display_clock_speed = i945_get_display_clock_speed; - else if (IS_GM45(dev)) + else if (IS_GM45(dev_priv)) dev_priv->display.get_display_clock_speed = gm45_get_display_clock_speed; - else if (IS_CRESTLINE(dev)) + else if (IS_CRESTLINE(dev_priv)) dev_priv->display.get_display_clock_speed = i965gm_get_display_clock_speed; - else if (IS_PINEVIEW(dev)) + else if (IS_PINEVIEW(dev_priv)) dev_priv->display.get_display_clock_speed = pnv_get_display_clock_speed; - else if (IS_G33(dev) || IS_G4X(dev)) + else if (IS_G33(dev_priv) || IS_G4X(dev_priv)) dev_priv->display.get_display_clock_speed = g33_get_display_clock_speed; - else if (IS_I915G(dev)) + else if (IS_I915G(dev_priv)) dev_priv->display.get_display_clock_speed = i915_get_display_clock_speed; - else if (IS_I945GM(dev) || IS_845G(dev)) + else if (IS_I945GM(dev_priv) || IS_845G(dev_priv)) dev_priv->display.get_display_clock_speed = i9xx_misc_get_display_clock_speed; - else if (IS_I915GM(dev)) + else if (IS_I915GM(dev_priv)) dev_priv->display.get_display_clock_speed = i915gm_get_display_clock_speed; - else if (IS_I865G(dev)) + else if (IS_I865G(dev_priv)) dev_priv->display.get_display_clock_speed = i865_get_display_clock_speed; - else if (IS_I85X(dev)) + else if (IS_I85X(dev_priv)) dev_priv->display.get_display_clock_speed = i85x_get_display_clock_speed; else { /* 830 */ - WARN(!IS_I830(dev), "Unknown platform. Assuming 133 MHz CDCLK\n"); + WARN(!IS_I830(dev_priv), "Unknown platform. Assuming 133 MHz CDCLK\n"); dev_priv->display.get_display_clock_speed = i830_get_display_clock_speed; } - if (IS_GEN5(dev)) { + if (IS_GEN5(dev_priv)) { dev_priv->display.fdi_link_train = ironlake_fdi_link_train; - } else if (IS_GEN6(dev)) { + } else if (IS_GEN6(dev_priv)) { dev_priv->display.fdi_link_train = gen6_fdi_link_train; - } else if (IS_IVYBRIDGE(dev)) { + } else if (IS_IVYBRIDGE(dev_priv)) { /* FIXME: detect B0+ stepping and use auto training */ dev_priv->display.fdi_link_train = ivb_manual_fdi_link_train; - } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { + } else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { dev_priv->display.fdi_link_train = hsw_fdi_link_train; - if (IS_BROADWELL(dev)) { + if (IS_BROADWELL(dev_priv)) { dev_priv->display.modeset_commit_cdclk = broadwell_modeset_commit_cdclk; dev_priv->display.modeset_calc_cdclk = broadwell_modeset_calc_cdclk; } - } else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) { + } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { dev_priv->display.modeset_commit_cdclk = valleyview_modeset_commit_cdclk; dev_priv->display.modeset_calc_cdclk = valleyview_modeset_calc_cdclk; - } else if (IS_BROXTON(dev)) { + } else if (IS_BROXTON(dev_priv)) { dev_priv->display.modeset_commit_cdclk = broxton_modeset_commit_cdclk; dev_priv->display.modeset_calc_cdclk = broxton_modeset_calc_cdclk; } - switch (INTEL_INFO(dev)->gen) { + switch (INTEL_INFO(dev_priv)->gen) { case 2: dev_priv->display.queue_flip = intel_gen2_queue_flip; break; @@ -14990,8 +14991,6 @@ static void intel_init_display(struct drm_device *dev) /* Default just returns -ENODEV to indicate unsupported */ dev_priv->display.queue_flip = intel_default_queue_flip; } - - mutex_init(&dev_priv->pps_mutex); } /* @@ -15318,9 +15317,6 @@ void intel_modeset_init(struct drm_device *dev) } } - intel_init_display(dev); - intel_init_audio(dev); - if (IS_GEN2(dev)) { dev->mode_config.max_width = 2048; dev->mode_config.max_height = 2048; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 0786246b8a88..7c0d12d4ce36 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1091,7 +1091,7 @@ u32 intel_fb_stride_alignment(const struct drm_i915_private *dev_priv, uint64_t fb_modifier, uint32_t pixel_format); /* intel_audio.c */ -void intel_init_audio(struct drm_device *dev); +void intel_init_audio_hooks(struct drm_i915_private *dev_priv); void intel_audio_codec_enable(struct intel_encoder *encoder); void intel_audio_codec_disable(struct intel_encoder *encoder); void i915_audio_component_init(struct drm_i915_private *dev_priv); @@ -1099,6 +1099,7 @@ void i915_audio_component_cleanup(struct drm_i915_private *dev_priv); /* intel_display.c */ extern const struct drm_plane_funcs intel_plane_funcs; +void intel_init_display_hooks(struct drm_i915_private *dev_priv); unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info); bool intel_has_pending_fb_unpin(struct drm_device *dev); void intel_mark_busy(struct drm_device *dev); -- cgit v1.2.3 From bb400da99836793ade6f1a007db58af2f1b57e9e Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 16 Mar 2016 13:38:54 +0200 Subject: drm/i915: Move load time init of clock gating hooks earlier Split out the part initing the clock gating hooks and move it earlier. Add a new NOP hook for platforms without the need to apply clockgating or workaround settings, so that the hook can be called unconditionally. Also add a WARN for future platforms that forget to add a hook. The rest of the hooks in intel_init_pm() should be inited in the same way, but atm some of the hooks are set only conditionally, so before doing this we need to make the setup unconditional and use instead some flags. v2: - add a NOP hook and WARN if no hook is set for the platform (Chris) - use the term hook instead of callback for these functions (Jani) v3: - remove the GEN4() check it's already covered by earlier platform checks (Chris) CC: Jani Nikula CC: Chris Wilson Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1458128348-15730-6-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_dma.c | 1 + drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_pm.c | 90 ++++++++++++++++++++++++---------------- 3 files changed, 57 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index b90d2d9feda8..a3c5621dec8f 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1029,6 +1029,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) intel_power_domains_init(dev_priv); intel_irq_init(dev_priv); intel_init_display_hooks(dev_priv); + intel_init_clock_gating_hooks(dev_priv); intel_init_audio_hooks(dev_priv); intel_runtime_pm_get(dev_priv); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 7c0d12d4ce36..5136eeffc24e 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1569,6 +1569,7 @@ void intel_suspend_hw(struct drm_device *dev); int ilk_wm_max_level(const struct drm_device *dev); void intel_update_watermarks(struct drm_crtc *crtc); void intel_init_pm(struct drm_device *dev); +void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv); void intel_pm_setup(struct drm_device *dev); void intel_gpu_ips_init(struct drm_i915_private *dev_priv); void intel_gpu_ips_teardown(void); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 20c8243ef705..a539fbc0c051 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -7097,8 +7097,7 @@ void intel_init_clock_gating(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - if (dev_priv->display.init_clock_gating) - dev_priv->display.init_clock_gating(dev); + dev_priv->display.init_clock_gating(dev); } void intel_suspend_hw(struct drm_device *dev) @@ -7107,6 +7106,60 @@ void intel_suspend_hw(struct drm_device *dev) lpt_suspend_hw(dev); } +static void nop_init_clock_gating(struct drm_device *dev) +{ + DRM_DEBUG_KMS("No clock gating settings or workarounds applied.\n"); +} + +/** + * intel_init_clock_gating_hooks - setup the clock gating hooks + * @dev_priv: device private + * + * Setup the hooks that configure which clocks of a given platform can be + * gated and also apply various GT and display specific workarounds for these + * platforms. Note that some GT specific workarounds are applied separately + * when GPU contexts or batchbuffers start their execution. + */ +void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv) +{ + if (IS_SKYLAKE(dev_priv)) + dev_priv->display.init_clock_gating = nop_init_clock_gating; + else if (IS_KABYLAKE(dev_priv)) + dev_priv->display.init_clock_gating = nop_init_clock_gating; + else if (IS_BROXTON(dev_priv)) + dev_priv->display.init_clock_gating = bxt_init_clock_gating; + else if (IS_BROADWELL(dev_priv)) + dev_priv->display.init_clock_gating = broadwell_init_clock_gating; + else if (IS_CHERRYVIEW(dev_priv)) + dev_priv->display.init_clock_gating = cherryview_init_clock_gating; + else if (IS_HASWELL(dev_priv)) + dev_priv->display.init_clock_gating = haswell_init_clock_gating; + else if (IS_IVYBRIDGE(dev_priv)) + dev_priv->display.init_clock_gating = ivybridge_init_clock_gating; + else if (IS_VALLEYVIEW(dev_priv)) + dev_priv->display.init_clock_gating = valleyview_init_clock_gating; + else if (IS_GEN6(dev_priv)) + dev_priv->display.init_clock_gating = gen6_init_clock_gating; + else if (IS_GEN5(dev_priv)) + dev_priv->display.init_clock_gating = ironlake_init_clock_gating; + else if (IS_G4X(dev_priv)) + dev_priv->display.init_clock_gating = g4x_init_clock_gating; + else if (IS_CRESTLINE(dev_priv)) + dev_priv->display.init_clock_gating = crestline_init_clock_gating; + else if (IS_BROADWATER(dev_priv)) + dev_priv->display.init_clock_gating = broadwater_init_clock_gating; + else if (IS_GEN3(dev_priv)) + dev_priv->display.init_clock_gating = gen3_init_clock_gating; + else if (IS_I85X(dev_priv) || IS_I865G(dev_priv)) + dev_priv->display.init_clock_gating = i85x_init_clock_gating; + else if (IS_GEN2(dev_priv)) + dev_priv->display.init_clock_gating = i830_init_clock_gating; + else { + MISSING_CASE(INTEL_DEVID(dev_priv)); + dev_priv->display.init_clock_gating = nop_init_clock_gating; + } +} + /* Set up chip specific power management-related functions */ void intel_init_pm(struct drm_device *dev) { @@ -7123,10 +7176,6 @@ void intel_init_pm(struct drm_device *dev) /* For FIFO watermark updates */ if (INTEL_INFO(dev)->gen >= 9) { skl_setup_wm_latency(dev); - - if (IS_BROXTON(dev)) - dev_priv->display.init_clock_gating = - bxt_init_clock_gating; dev_priv->display.update_wm = skl_update_wm; } else if (HAS_PCH_SPLIT(dev)) { ilk_setup_wm_latency(dev); @@ -7146,29 +7195,12 @@ void intel_init_pm(struct drm_device *dev) DRM_DEBUG_KMS("Failed to read display plane latency. " "Disable CxSR\n"); } - - if (IS_GEN5(dev)) - dev_priv->display.init_clock_gating = ironlake_init_clock_gating; - else if (IS_GEN6(dev)) - dev_priv->display.init_clock_gating = gen6_init_clock_gating; - else if (IS_IVYBRIDGE(dev)) - dev_priv->display.init_clock_gating = ivybridge_init_clock_gating; - else if (IS_HASWELL(dev)) - dev_priv->display.init_clock_gating = haswell_init_clock_gating; - else if (INTEL_INFO(dev)->gen == 8) - dev_priv->display.init_clock_gating = broadwell_init_clock_gating; } else if (IS_CHERRYVIEW(dev)) { vlv_setup_wm_latency(dev); - dev_priv->display.update_wm = vlv_update_wm; - dev_priv->display.init_clock_gating = - cherryview_init_clock_gating; } else if (IS_VALLEYVIEW(dev)) { vlv_setup_wm_latency(dev); - dev_priv->display.update_wm = vlv_update_wm; - dev_priv->display.init_clock_gating = - valleyview_init_clock_gating; } else if (IS_PINEVIEW(dev)) { if (!intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->is_ddr3, @@ -7184,20 +7216,13 @@ void intel_init_pm(struct drm_device *dev) dev_priv->display.update_wm = NULL; } else dev_priv->display.update_wm = pineview_update_wm; - dev_priv->display.init_clock_gating = gen3_init_clock_gating; } else if (IS_G4X(dev)) { dev_priv->display.update_wm = g4x_update_wm; - dev_priv->display.init_clock_gating = g4x_init_clock_gating; } else if (IS_GEN4(dev)) { dev_priv->display.update_wm = i965_update_wm; - if (IS_CRESTLINE(dev)) - dev_priv->display.init_clock_gating = crestline_init_clock_gating; - else if (IS_BROADWATER(dev)) - dev_priv->display.init_clock_gating = broadwater_init_clock_gating; } else if (IS_GEN3(dev)) { dev_priv->display.update_wm = i9xx_update_wm; dev_priv->display.get_fifo_size = i9xx_get_fifo_size; - dev_priv->display.init_clock_gating = gen3_init_clock_gating; } else if (IS_GEN2(dev)) { if (INTEL_INFO(dev)->num_pipes == 1) { dev_priv->display.update_wm = i845_update_wm; @@ -7206,11 +7231,6 @@ void intel_init_pm(struct drm_device *dev) dev_priv->display.update_wm = i9xx_update_wm; dev_priv->display.get_fifo_size = i830_get_fifo_size; } - - if (IS_I85X(dev) || IS_I865G(dev)) - dev_priv->display.init_clock_gating = i85x_init_clock_gating; - else - dev_priv->display.init_clock_gating = i830_init_clock_gating; } else { DRM_ERROR("unexpected fall-through in intel_init_pm\n"); } -- cgit v1.2.3 From 13c8f4c8cd481ec80bfe3b71f1f21e18bad98efb Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 16 Mar 2016 13:38:55 +0200 Subject: drm/i915: Move load time runtime device info init earlier This init step accesses the device, but doesn't have any device specific side effect. It also sets up some platform specific attributes that may be required early, so move it earlier. Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1458128348-15730-7-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_dma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index a3c5621dec8f..a94610a6e2c8 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1057,6 +1057,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) intel_uncore_init(dev); + intel_device_info_runtime_init(dev); + ret = i915_gem_gtt_init(dev); if (ret) goto out_uncore_fini; @@ -1131,8 +1133,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) DRM_DEBUG_DRIVER("can't enable MSI"); } - intel_device_info_runtime_init(dev); - if (INTEL_INFO(dev)->num_pipes) { ret = drm_vblank_init(dev, INTEL_INFO(dev)->num_pipes); if (ret) -- cgit v1.2.3 From 40ae4e1661cd2ef67ca888b36ea636999bd0be73 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 16 Mar 2016 14:54:03 +0200 Subject: drm/i915: Move load time gem_load_init earlier The only steps requiring device access is the fence and swizzling initialization, so split these out keeping them in their current place and move the rest of init steps earlier. v2-v3: - unchanged v4: - move call to i915_gem_detect_bit_6_swizzle() to i915_gem_load_init_fences() and preserve the original order of the detection of HW fence capailities wrt. swizzling (Chris) CC: Chris Wilson Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1458132843-21860-1-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_dma.c | 12 +++++++----- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_gem.c | 38 ++++++++++++++++++++++++-------------- 3 files changed, 32 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index a94610a6e2c8..b89fa735092f 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1031,6 +1031,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) intel_init_display_hooks(dev_priv); intel_init_clock_gating_hooks(dev_priv); intel_init_audio_hooks(dev_priv); + i915_gem_load_init(dev); intel_runtime_pm_get(dev_priv); @@ -1114,7 +1115,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) intel_opregion_setup(dev); - i915_gem_load_init(dev); + i915_gem_load_init_fences(dev_priv); + i915_gem_shrinker_init(dev_priv); /* On the 945G/GM, the chipset reports the MSI capability on the @@ -1136,7 +1138,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) if (INTEL_INFO(dev)->num_pipes) { ret = drm_vblank_init(dev, INTEL_INFO(dev)->num_pipes); if (ret) - goto out_gem_unload; + goto out_cleanup_shrinker; } ret = i915_load_modeset_init(dev); @@ -1174,7 +1176,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) out_power_well: intel_power_domains_fini(dev_priv); drm_vblank_cleanup(dev); -out_gem_unload: +out_cleanup_shrinker: i915_gem_shrinker_cleanup(dev_priv); if (dev->pdev->msi_enabled) @@ -1190,9 +1192,9 @@ out_uncore_fini: i915_mmio_cleanup(dev); put_bridge: pci_dev_put(dev_priv->bridge_dev); - i915_gem_load_cleanup(dev); out_runtime_pm_put: intel_runtime_pm_put(dev_priv); + i915_gem_load_cleanup(dev); i915_workqueues_cleanup(dev_priv); out_free_priv: kfree(dev_priv); @@ -1277,8 +1279,8 @@ int i915_driver_unload(struct drm_device *dev) intel_uncore_fini(dev); i915_mmio_cleanup(dev); - i915_gem_load_cleanup(dev); pci_dev_put(dev_priv->bridge_dev); + i915_gem_load_cleanup(dev); i915_workqueues_cleanup(dev_priv); kfree(dev_priv); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f2ab5452f12d..e6d4b1ce130e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2859,6 +2859,7 @@ int i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); void i915_gem_load_init(struct drm_device *dev); void i915_gem_load_cleanup(struct drm_device *dev); +void i915_gem_load_init_fences(struct drm_i915_private *dev_priv); void *i915_gem_object_alloc(struct drm_device *dev); void i915_gem_object_free(struct drm_i915_gem_object *obj); void i915_gem_object_init(struct drm_i915_gem_object *obj, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index a25109aa033c..a4e015530b0c 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -5028,6 +5028,30 @@ init_engine_lists(struct intel_engine_cs *engine) INIT_LIST_HEAD(&engine->request_list); } +void +i915_gem_load_init_fences(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + + if (INTEL_INFO(dev_priv)->gen >= 7 && !IS_VALLEYVIEW(dev_priv) && + !IS_CHERRYVIEW(dev_priv)) + dev_priv->num_fence_regs = 32; + else if (INTEL_INFO(dev_priv)->gen >= 4 || IS_I945G(dev_priv) || + IS_I945GM(dev_priv) || IS_G33(dev_priv)) + dev_priv->num_fence_regs = 16; + else + dev_priv->num_fence_regs = 8; + + if (intel_vgpu_active(dev)) + dev_priv->num_fence_regs = + I915_READ(vgtif_reg(avail_rs.fence_num)); + + /* Initialize fence registers to zero */ + i915_gem_restore_fences(dev); + + i915_gem_detect_bit_6_swizzle(dev); +} + void i915_gem_load_init(struct drm_device *dev) { @@ -5067,17 +5091,6 @@ i915_gem_load_init(struct drm_device *dev) dev_priv->relative_constants_mode = I915_EXEC_CONSTANTS_REL_GENERAL; - if (INTEL_INFO(dev)->gen >= 7 && !IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev)) - dev_priv->num_fence_regs = 32; - else if (INTEL_INFO(dev)->gen >= 4 || IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) - dev_priv->num_fence_regs = 16; - else - dev_priv->num_fence_regs = 8; - - if (intel_vgpu_active(dev)) - dev_priv->num_fence_regs = - I915_READ(vgtif_reg(avail_rs.fence_num)); - /* * Set initial sequence number for requests. * Using this number allows the wraparound to happen early, @@ -5086,11 +5099,8 @@ i915_gem_load_init(struct drm_device *dev) dev_priv->next_seqno = ((u32)~0 - 0x1100); dev_priv->last_seqno = ((u32)~0 - 0x1101); - /* Initialize fence registers to zero */ INIT_LIST_HEAD(&dev_priv->mm.fence_list); - i915_gem_restore_fences(dev); - i915_gem_detect_bit_6_swizzle(dev); init_waitqueue_head(&dev_priv->pending_flip_queue); dev_priv->mm.interruptible = true; -- cgit v1.2.3 From 802cbbc09b96eed654233020d8f6d486ddc5123b Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 16 Mar 2016 13:38:57 +0200 Subject: drm/i915: Move load time runtime PM get later We require the device to be powered only before accessing it, so we can move this call later. Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1458128348-15730-9-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_dma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index b89fa735092f..a07e359b1ace 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1033,8 +1033,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) intel_init_audio_hooks(dev_priv); i915_gem_load_init(dev); - intel_runtime_pm_get(dev_priv); - intel_display_crc_init(dev); i915_dump_device_info(dev_priv); @@ -1047,6 +1045,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) DRM_INFO("This is an early pre-production Haswell machine. " "It may not be fully functional.\n"); + intel_runtime_pm_get(dev_priv); + if (i915_get_bridge_dev(dev)) { ret = -EIO; goto out_runtime_pm_put; -- cgit v1.2.3 From 80741e99282a3672a2259386f3f1dc4c3ef3d54f Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 16 Mar 2016 13:38:58 +0200 Subject: drm/i915: Move load time shrinker registration later According to the new init phases scheme we should register the driver with frameworks/userspace only one the device is setup fully. So move the shrinker registration later accordingly. Also fix the shrinker unregistration order wrt. the acpi unregistration to fix the corresponding init order. Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1458128348-15730-10-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_dma.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index a07e359b1ace..2d279a60d3c4 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1117,8 +1117,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) i915_gem_load_init_fences(dev_priv); - i915_gem_shrinker_init(dev_priv); - /* On the 945G/GM, the chipset reports the MSI capability on the * integrated graphics even though the support isn't actually there * according to the published specs. It doesn't appear to function @@ -1138,7 +1136,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) if (INTEL_INFO(dev)->num_pipes) { ret = drm_vblank_init(dev, INTEL_INFO(dev)->num_pipes); if (ret) - goto out_cleanup_shrinker; + goto out_disable_msi; } ret = i915_load_modeset_init(dev); @@ -1147,6 +1145,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) goto out_power_well; } + i915_gem_shrinker_init(dev_priv); /* * Notify a valid surface after modesetting, * when running inside a VM. @@ -1176,9 +1175,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) out_power_well: intel_power_domains_fini(dev_priv); drm_vblank_cleanup(dev); -out_cleanup_shrinker: - i915_gem_shrinker_cleanup(dev_priv); - +out_disable_msi: if (dev->pdev->msi_enabled) pci_disable_msi(dev->pdev); @@ -1223,12 +1220,11 @@ int i915_driver_unload(struct drm_device *dev) i915_teardown_sysfs(dev); - i915_gem_shrinker_cleanup(dev_priv); - io_mapping_free(dev_priv->gtt.mappable); arch_phys_wc_del(dev_priv->gtt.mtrr); acpi_video_unregister(); + i915_gem_shrinker_cleanup(dev_priv); drm_vblank_cleanup(dev); -- cgit v1.2.3 From 3487b66ba13c1a7ba1185028ad0dae95e97bd4d2 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 16 Mar 2016 13:38:59 +0200 Subject: drm/i915: Move load time audio component registration earlier We should register all the interfaces before we enable runtime PM. Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1458128348-15730-11-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_dma.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 2d279a60d3c4..2bdafa998704 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1164,10 +1164,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) if (IS_GEN5(dev)) intel_gpu_ips_init(dev_priv); - intel_runtime_pm_enable(dev_priv); - i915_audio_component_init(dev_priv); + intel_runtime_pm_enable(dev_priv); + intel_runtime_pm_put(dev_priv); return 0; @@ -1206,8 +1206,6 @@ int i915_driver_unload(struct drm_device *dev) intel_fbdev_fini(dev); - i915_audio_component_cleanup(dev_priv); - ret = i915_gem_suspend(dev); if (ret) { DRM_ERROR("failed to idle hardware: %d\n", ret); @@ -1216,6 +1214,8 @@ int i915_driver_unload(struct drm_device *dev) intel_power_domains_fini(dev_priv); + i915_audio_component_cleanup(dev_priv); + intel_gpu_ips_teardown(); i915_teardown_sysfs(dev); -- cgit v1.2.3 From 250ad48e2e2f2aeebafd52d67768392eca5077ad Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 16 Mar 2016 13:39:00 +0200 Subject: drm/i915: Move unload time display power domain uninit later Move the power domain uninitialization later so that it matches its corresponding init order. Since we access the HW during the later unitialization steps keep a wake reference until after the last such step. Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1458128348-15730-12-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_dma.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 2bdafa998704..40a5af4038ca 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1212,7 +1212,7 @@ int i915_driver_unload(struct drm_device *dev) return ret; } - intel_power_domains_fini(dev_priv); + intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); i915_audio_component_cleanup(dev_priv); @@ -1268,6 +1268,8 @@ int i915_driver_unload(struct drm_device *dev) mutex_unlock(&dev->struct_mutex); intel_fbc_cleanup_cfb(dev_priv); + intel_power_domains_fini(dev_priv); + pm_qos_remove_request(&dev_priv->pm_qos); i915_global_gtt_cleanup(dev); @@ -1276,6 +1278,9 @@ int i915_driver_unload(struct drm_device *dev) i915_mmio_cleanup(dev); pci_dev_put(dev_priv->bridge_dev); + + intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); + i915_gem_load_cleanup(dev); i915_workqueues_cleanup(dev_priv); kfree(dev_priv); -- cgit v1.2.3 From 882c5a83b5116bff597aefec16ad016641dfea05 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 16 Mar 2016 13:39:01 +0200 Subject: drm/i915: Move unload time GTT, MSI IRQ cleanup later Move the GTT,MSI IRQ cleanup later so that it matches their corresponding init order. Also fix the order of these calls wrt. each other to match their corresponding init order. Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1458128348-15730-13-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_dma.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 40a5af4038ca..fb28a03e96c6 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1220,9 +1220,6 @@ int i915_driver_unload(struct drm_device *dev) i915_teardown_sysfs(dev); - io_mapping_free(dev_priv->gtt.mappable); - arch_phys_wc_del(dev_priv->gtt.mtrr); - acpi_video_unregister(); i915_gem_shrinker_cleanup(dev_priv); @@ -1253,9 +1250,6 @@ int i915_driver_unload(struct drm_device *dev) cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work); i915_destroy_error_state(dev); - if (dev->pdev->msi_enabled) - pci_disable_msi(dev->pdev); - intel_opregion_fini(dev); /* Flush any outstanding unpin_work. */ @@ -1270,8 +1264,11 @@ int i915_driver_unload(struct drm_device *dev) intel_power_domains_fini(dev_priv); + if (dev->pdev->msi_enabled) + pci_disable_msi(dev->pdev); pm_qos_remove_request(&dev_priv->pm_qos); - + arch_phys_wc_del(dev_priv->gtt.mtrr); + io_mapping_free(dev_priv->gtt.mappable); i915_global_gtt_cleanup(dev); intel_uncore_fini(dev); -- cgit v1.2.3 From fbf107bdbd449494e6b17589f0a8a02094b52a19 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 16 Mar 2016 13:39:02 +0200 Subject: drm/i915: Move unload time opregion unregistration earlier Move the opregion unregistration earlier to match its corresponding registration order. Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1458128348-15730-14-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_dma.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index fb28a03e96c6..7618a3f4c21f 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1221,6 +1221,7 @@ int i915_driver_unload(struct drm_device *dev) i915_teardown_sysfs(dev); acpi_video_unregister(); + intel_opregion_fini(dev); i915_gem_shrinker_cleanup(dev_priv); drm_vblank_cleanup(dev); @@ -1250,8 +1251,6 @@ int i915_driver_unload(struct drm_device *dev) cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work); i915_destroy_error_state(dev); - intel_opregion_fini(dev); - /* Flush any outstanding unpin_work. */ flush_workqueue(dev_priv->wq); -- cgit v1.2.3 From 5d7a6eefc3b025725dd1b5a643e90ce068e9dbd4 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 16 Mar 2016 13:39:03 +0200 Subject: drm/i915: Split out load time early initialization According to the new init phases scheme we should initialize "SW-only" state not requiring accessing the device as the very first step, so that the reasoning about dependencies of later steps becomes easier. So move these init steps into a separate function. This also has the benefit of making the error path cleaner both in the new function and int i915_driver_load()/unload(). No functional change. Suggested by Chris. CC: Chris Wilson Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1458128348-15730-15-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_dma.c | 130 +++++++++++++++++++++++++--------------- 1 file changed, 81 insertions(+), 49 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 7618a3f4c21f..182770dee746 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -933,6 +933,83 @@ static void i915_workqueues_cleanup(struct drm_i915_private *dev_priv) destroy_workqueue(dev_priv->wq); } +/** + * i915_driver_init_early - setup state not requiring device access + * @dev_priv: device private + * + * Initialize everything that is a "SW-only" state, that is state not + * requiring accessing the device or exposing the driver via kernel internal + * or userspace interfaces. Example steps belonging here: lock initialization, + * system memory allocation, setting up device specific attributes and + * function hooks not requiring accessing the device. + */ +static int i915_driver_init_early(struct drm_i915_private *dev_priv, + struct drm_device *dev, + struct intel_device_info *info) +{ + struct intel_device_info *device_info; + int ret = 0; + + dev_priv->dev = dev; + + /* Setup the write-once "constant" device info */ + device_info = (struct intel_device_info *)&dev_priv->info; + memcpy(device_info, info, sizeof(dev_priv->info)); + device_info->device_id = dev->pdev->device; + + spin_lock_init(&dev_priv->irq_lock); + spin_lock_init(&dev_priv->gpu_error.lock); + mutex_init(&dev_priv->backlight_lock); + spin_lock_init(&dev_priv->uncore.lock); + spin_lock_init(&dev_priv->mm.object_stat_lock); + spin_lock_init(&dev_priv->mmio_flip_lock); + mutex_init(&dev_priv->sb_lock); + mutex_init(&dev_priv->modeset_restore_lock); + mutex_init(&dev_priv->av_mutex); + mutex_init(&dev_priv->wm.wm_mutex); + mutex_init(&dev_priv->pps_mutex); + + ret = i915_workqueues_init(dev_priv); + if (ret < 0) + return ret; + + /* This must be called before any calls to HAS_PCH_* */ + intel_detect_pch(dev); + + intel_pm_setup(dev); + intel_init_dpio(dev_priv); + intel_power_domains_init(dev_priv); + intel_irq_init(dev_priv); + intel_init_display_hooks(dev_priv); + intel_init_clock_gating_hooks(dev_priv); + intel_init_audio_hooks(dev_priv); + i915_gem_load_init(dev); + + intel_display_crc_init(dev); + + i915_dump_device_info(dev_priv); + + /* Not all pre-production machines fall into this category, only the + * very first ones. Almost everything should work, except for maybe + * suspend/resume. And we don't implement workarounds that affect only + * pre-production machines. */ + if (IS_HSW_EARLY_SDV(dev)) + DRM_INFO("This is an early pre-production Haswell machine. " + "It may not be fully functional.\n"); + + return 0; +} + +/** + * i915_driver_cleanup_early - cleanup the setup done in i915_driver_init_early() + * @dev_priv: device private + */ +static void i915_driver_cleanup_early(struct drm_i915_private *dev_priv) +{ + i915_gem_load_cleanup(dev_priv->dev); + i915_workqueues_cleanup(dev_priv); +} + static int i915_mmio_setup(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); @@ -987,64 +1064,21 @@ static void i915_mmio_cleanup(struct drm_device *dev) int i915_driver_load(struct drm_device *dev, unsigned long flags) { struct drm_i915_private *dev_priv; - struct intel_device_info *info, *device_info; int ret = 0; uint32_t aperture_size; - info = (struct intel_device_info *) flags; - dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); if (dev_priv == NULL) return -ENOMEM; dev->dev_private = dev_priv; - dev_priv->dev = dev; - /* Setup the write-once "constant" device info */ - device_info = (struct intel_device_info *)&dev_priv->info; - memcpy(device_info, info, sizeof(dev_priv->info)); - device_info->device_id = dev->pdev->device; + ret = i915_driver_init_early(dev_priv, dev, + (struct intel_device_info *)flags); - spin_lock_init(&dev_priv->irq_lock); - spin_lock_init(&dev_priv->gpu_error.lock); - mutex_init(&dev_priv->backlight_lock); - spin_lock_init(&dev_priv->uncore.lock); - spin_lock_init(&dev_priv->mm.object_stat_lock); - spin_lock_init(&dev_priv->mmio_flip_lock); - mutex_init(&dev_priv->sb_lock); - mutex_init(&dev_priv->modeset_restore_lock); - mutex_init(&dev_priv->av_mutex); - mutex_init(&dev_priv->wm.wm_mutex); - mutex_init(&dev_priv->pps_mutex); - - ret = i915_workqueues_init(dev_priv); if (ret < 0) goto out_free_priv; - /* This must be called before any calls to HAS_PCH_* */ - intel_detect_pch(dev); - - intel_pm_setup(dev); - intel_init_dpio(dev_priv); - intel_power_domains_init(dev_priv); - intel_irq_init(dev_priv); - intel_init_display_hooks(dev_priv); - intel_init_clock_gating_hooks(dev_priv); - intel_init_audio_hooks(dev_priv); - i915_gem_load_init(dev); - - intel_display_crc_init(dev); - - i915_dump_device_info(dev_priv); - - /* Not all pre-production machines fall into this category, only the - * very first ones. Almost everything should work, except for maybe - * suspend/resume. And we don't implement workarounds that affect only - * pre-production machines. */ - if (IS_HSW_EARLY_SDV(dev)) - DRM_INFO("This is an early pre-production Haswell machine. " - "It may not be fully functional.\n"); - intel_runtime_pm_get(dev_priv); if (i915_get_bridge_dev(dev)) { @@ -1191,8 +1225,7 @@ put_bridge: pci_dev_put(dev_priv->bridge_dev); out_runtime_pm_put: intel_runtime_pm_put(dev_priv); - i915_gem_load_cleanup(dev); - i915_workqueues_cleanup(dev_priv); + i915_driver_cleanup_early(dev_priv); out_free_priv: kfree(dev_priv); @@ -1277,8 +1310,7 @@ int i915_driver_unload(struct drm_device *dev) intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); - i915_gem_load_cleanup(dev); - i915_workqueues_cleanup(dev_priv); + i915_driver_cleanup_early(dev_priv); kfree(dev_priv); return 0; -- cgit v1.2.3 From f28cea45e5a9e1680753ce1b91f033dc3ceda7d0 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 16 Mar 2016 13:39:04 +0200 Subject: drm/i915: Split out load time MMIO initialization According to the new init phases scheme we should have a definite step in the init sequence where MMIO access is setup, so move the corresponding code to a separate function. This also has the benefit of making the error path cleaner both in the new function and in i915_driver_load()/unload(). No functional change. Suggested by Chris. Cc: Chris Wilson Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1458128348-15730-16-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_dma.c | 69 +++++++++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 182770dee746..142d59acb632 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1050,6 +1050,50 @@ static void i915_mmio_cleanup(struct drm_device *dev) pci_iounmap(dev->pdev, dev_priv->regs); } +/** + * i915_driver_init_mmio - setup device MMIO + * @dev_priv: device private + * + * Setup minimal device state necessary for MMIO accesses later in the + * initialization sequence. The setup here should avoid any other device-wide + * side effects or exposing the driver via kernel internal or user space + * interfaces. + */ +static int i915_driver_init_mmio(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + int ret; + + if (i915_get_bridge_dev(dev)) + return -EIO; + + ret = i915_mmio_setup(dev); + if (ret < 0) + goto put_bridge; + + intel_uncore_init(dev); + + return 0; + +put_bridge: + pci_dev_put(dev_priv->bridge_dev); + + return ret; +} + +/** + * i915_driver_cleanup_mmio - cleanup the setup done in i915_driver_init_mmio() + * @dev_priv: device private + */ +static void i915_driver_cleanup_mmio(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + + intel_uncore_fini(dev); + i915_mmio_cleanup(dev); + pci_dev_put(dev_priv->bridge_dev); +} + /** * i915_driver_load - setup chip and create an initial config * @dev: DRM device @@ -1081,22 +1125,15 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) intel_runtime_pm_get(dev_priv); - if (i915_get_bridge_dev(dev)) { - ret = -EIO; - goto out_runtime_pm_put; - } - - ret = i915_mmio_setup(dev); + ret = i915_driver_init_mmio(dev_priv); if (ret < 0) - goto put_bridge; - - intel_uncore_init(dev); + goto out_runtime_pm_put; intel_device_info_runtime_init(dev); ret = i915_gem_gtt_init(dev); if (ret) - goto out_uncore_fini; + goto out_cleanup_mmio; /* WARNING: Apparently we must kick fbdev drivers before vgacon, * otherwise the vga fbdev driver falls over. */ @@ -1218,11 +1255,8 @@ out_disable_msi: io_mapping_free(dev_priv->gtt.mappable); out_gtt: i915_global_gtt_cleanup(dev); -out_uncore_fini: - intel_uncore_fini(dev); - i915_mmio_cleanup(dev); -put_bridge: - pci_dev_put(dev_priv->bridge_dev); +out_cleanup_mmio: + i915_driver_cleanup_mmio(dev_priv); out_runtime_pm_put: intel_runtime_pm_put(dev_priv); i915_driver_cleanup_early(dev_priv); @@ -1303,10 +1337,7 @@ int i915_driver_unload(struct drm_device *dev) io_mapping_free(dev_priv->gtt.mappable); i915_global_gtt_cleanup(dev); - intel_uncore_fini(dev); - i915_mmio_cleanup(dev); - - pci_dev_put(dev_priv->bridge_dev); + i915_driver_cleanup_mmio(dev_priv); intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); -- cgit v1.2.3 From 09cfcb456941222021f378131b1b2fa4c59cc495 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 16 Mar 2016 13:39:05 +0200 Subject: drm/i915: Split out load time HW initialization According to the new init phases scheme we should have a definite step in the init sequence where we setup things requiring accessing the device, so move the corresponding code to separate function. The steps in this init phase should avoid exposing the driver via some interface, which is done in the last registration init phase. This changae also has the benefit of making the error path cleaner both in the new function and i915_driver_load()/unload(). No functional change. Suggested by Chris. CC: Chris Wilson Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1458128348-15730-17-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_dma.c | 122 ++++++++++++++++++++++++---------------- 1 file changed, 75 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 142d59acb632..ec8ad5e61836 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1095,45 +1095,23 @@ static void i915_driver_cleanup_mmio(struct drm_i915_private *dev_priv) } /** - * i915_driver_load - setup chip and create an initial config - * @dev: DRM device - * @flags: startup flags + * i915_driver_init_hw - setup state requiring device access + * @dev_priv: device private * - * The driver load routine has to do several things: - * - drive output discovery via intel_modeset_init() - * - initialize the memory manager - * - allocate initial config memory - * - setup the DRM framebuffer with the allocated memory + * Setup state that requires accessing the device, but doesn't require + * exposing the driver via kernel internal or userspace interfaces. */ -int i915_driver_load(struct drm_device *dev, unsigned long flags) +static int i915_driver_init_hw(struct drm_i915_private *dev_priv) { - struct drm_i915_private *dev_priv; - int ret = 0; + struct drm_device *dev = dev_priv->dev; uint32_t aperture_size; - - dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); - if (dev_priv == NULL) - return -ENOMEM; - - dev->dev_private = dev_priv; - - ret = i915_driver_init_early(dev_priv, dev, - (struct intel_device_info *)flags); - - if (ret < 0) - goto out_free_priv; - - intel_runtime_pm_get(dev_priv); - - ret = i915_driver_init_mmio(dev_priv); - if (ret < 0) - goto out_runtime_pm_put; + int ret; intel_device_info_runtime_init(dev); ret = i915_gem_gtt_init(dev); if (ret) - goto out_cleanup_mmio; + return ret; /* WARNING: Apparently we must kick fbdev drivers before vgacon, * otherwise the vga fbdev driver falls over. */ @@ -1204,10 +1182,73 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) DRM_DEBUG_DRIVER("can't enable MSI"); } + return 0; + +out_gtt: + i915_global_gtt_cleanup(dev); + + return ret; +} + +/** + * i915_driver_cleanup_hw - cleanup the setup done in i915_driver_init_hw() + * @dev_priv: device private + */ +static void i915_driver_cleanup_hw(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + + if (dev->pdev->msi_enabled) + pci_disable_msi(dev->pdev); + + pm_qos_remove_request(&dev_priv->pm_qos); + arch_phys_wc_del(dev_priv->gtt.mtrr); + io_mapping_free(dev_priv->gtt.mappable); + i915_global_gtt_cleanup(dev); +} + +/** + * i915_driver_load - setup chip and create an initial config + * @dev: DRM device + * @flags: startup flags + * + * The driver load routine has to do several things: + * - drive output discovery via intel_modeset_init() + * - initialize the memory manager + * - allocate initial config memory + * - setup the DRM framebuffer with the allocated memory + */ +int i915_driver_load(struct drm_device *dev, unsigned long flags) +{ + struct drm_i915_private *dev_priv; + int ret = 0; + + dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); + if (dev_priv == NULL) + return -ENOMEM; + + dev->dev_private = dev_priv; + + ret = i915_driver_init_early(dev_priv, dev, + (struct intel_device_info *)flags); + + if (ret < 0) + goto out_free_priv; + + intel_runtime_pm_get(dev_priv); + + ret = i915_driver_init_mmio(dev_priv); + if (ret < 0) + goto out_runtime_pm_put; + + ret = i915_driver_init_hw(dev_priv); + if (ret < 0) + goto out_cleanup_mmio; + if (INTEL_INFO(dev)->num_pipes) { ret = drm_vblank_init(dev, INTEL_INFO(dev)->num_pipes); if (ret) - goto out_disable_msi; + goto out_cleanup_hw; } ret = i915_load_modeset_init(dev); @@ -1246,15 +1287,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) out_power_well: intel_power_domains_fini(dev_priv); drm_vblank_cleanup(dev); -out_disable_msi: - if (dev->pdev->msi_enabled) - pci_disable_msi(dev->pdev); - - pm_qos_remove_request(&dev_priv->pm_qos); - arch_phys_wc_del(dev_priv->gtt.mtrr); - io_mapping_free(dev_priv->gtt.mappable); -out_gtt: - i915_global_gtt_cleanup(dev); +out_cleanup_hw: + i915_driver_cleanup_hw(dev_priv); out_cleanup_mmio: i915_driver_cleanup_mmio(dev_priv); out_runtime_pm_put: @@ -1330,13 +1364,7 @@ int i915_driver_unload(struct drm_device *dev) intel_power_domains_fini(dev_priv); - if (dev->pdev->msi_enabled) - pci_disable_msi(dev->pdev); - pm_qos_remove_request(&dev_priv->pm_qos); - arch_phys_wc_del(dev_priv->gtt.mtrr); - io_mapping_free(dev_priv->gtt.mappable); - i915_global_gtt_cleanup(dev); - + i915_driver_cleanup_hw(dev_priv); i915_driver_cleanup_mmio(dev_priv); intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); -- cgit v1.2.3 From 432f856d8b4963f2f1d95844794266d7c9a9ca97 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 16 Mar 2016 13:39:06 +0200 Subject: drm/i915: Split out load time interface registration According to the new init phases scheme we should register the device making it available via some kernel internal or user space interface as the last step in the init sequence, so move the corresponding code to a separate function. Also add a TODO comment about code that still needs to be moved around to one of the init phases functions depending on what the role and effect of that code is. No functional change, except for the reordering of the unload time unregistration steps of sysfs wrt. acpi and opregion. Suggested by Chris. v3: - rename i915_driver_init_register to i915_driver_init_frameworks (Chris) - rename i915_driver_init_frameworks to i915_driver_register (Daniel) CC: Chris Wilson CC: Daniel Vetter Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1458128348-15730-18-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_dma.c | 83 +++++++++++++++++++++++++++-------------- 1 file changed, 54 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index ec8ad5e61836..b8c5fd0a99aa 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1207,6 +1207,53 @@ static void i915_driver_cleanup_hw(struct drm_i915_private *dev_priv) i915_global_gtt_cleanup(dev); } +/** + * i915_driver_register - register the driver with the rest of the system + * @dev_priv: device private + * + * Perform any steps necessary to make the driver available via kernel + * internal or userspace interfaces. + */ +static void i915_driver_register(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + + i915_gem_shrinker_init(dev_priv); + /* + * Notify a valid surface after modesetting, + * when running inside a VM. + */ + if (intel_vgpu_active(dev)) + I915_WRITE(vgtif_reg(display_ready), VGT_DRV_DISPLAY_READY); + + i915_setup_sysfs(dev); + + if (INTEL_INFO(dev_priv)->num_pipes) { + /* Must be done after probing outputs */ + intel_opregion_init(dev); + acpi_video_register(); + } + + if (IS_GEN5(dev_priv)) + intel_gpu_ips_init(dev_priv); + + i915_audio_component_init(dev_priv); +} + +/** + * i915_driver_unregister - cleanup the registration done in i915_driver_regiser() + * @dev_priv: device private + */ +static void i915_driver_unregister(struct drm_i915_private *dev_priv) +{ + i915_audio_component_cleanup(dev_priv); + intel_gpu_ips_teardown(); + acpi_video_unregister(); + intel_opregion_fini(dev_priv->dev); + i915_teardown_sysfs(dev_priv->dev); + i915_gem_shrinker_cleanup(dev_priv); +} + /** * i915_driver_load - setup chip and create an initial config * @dev: DRM device @@ -1245,6 +1292,11 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) if (ret < 0) goto out_cleanup_mmio; + /* + * TODO: move the vblank init and parts of modeset init steps into one + * of the i915_driver_init_/i915_driver_register functions according + * to the role/effect of the given init step. + */ if (INTEL_INFO(dev)->num_pipes) { ret = drm_vblank_init(dev, INTEL_INFO(dev)->num_pipes); if (ret) @@ -1257,26 +1309,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) goto out_power_well; } - i915_gem_shrinker_init(dev_priv); - /* - * Notify a valid surface after modesetting, - * when running inside a VM. - */ - if (intel_vgpu_active(dev)) - I915_WRITE(vgtif_reg(display_ready), VGT_DRV_DISPLAY_READY); - - i915_setup_sysfs(dev); - - if (INTEL_INFO(dev)->num_pipes) { - /* Must be done after probing outputs */ - intel_opregion_init(dev); - acpi_video_register(); - } - - if (IS_GEN5(dev)) - intel_gpu_ips_init(dev_priv); - - i915_audio_component_init(dev_priv); + i915_driver_register(dev_priv); intel_runtime_pm_enable(dev_priv); @@ -1315,15 +1348,7 @@ int i915_driver_unload(struct drm_device *dev) intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); - i915_audio_component_cleanup(dev_priv); - - intel_gpu_ips_teardown(); - - i915_teardown_sysfs(dev); - - acpi_video_unregister(); - intel_opregion_fini(dev); - i915_gem_shrinker_cleanup(dev_priv); + i915_driver_unregister(dev_priv); drm_vblank_cleanup(dev); -- cgit v1.2.3 From 65ff442f6bca0e2247ff7acac6014bcea69d1f7e Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 16 Mar 2016 13:39:07 +0200 Subject: drm/i915: Fix power domain HW state cleanup on error path Move the cleanup of the power domain HW state on the error path to the same function where the corresponding init call was called from. I noticed this problem when loading the module with load failure injection enabled, making i915_load_modeset_init() fail. CC: Chris Wilson Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1458128348-15730-19-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_dma.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index b8c5fd0a99aa..7466e739887d 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -453,6 +453,7 @@ cleanup_irq: intel_teardown_gmbus(dev); cleanup_csr: intel_csr_ucode_fini(dev_priv); + intel_power_domains_fini(dev_priv); vga_switcheroo_unregister_client(dev->pdev); cleanup_vga_client: vga_client_register(dev->pdev, NULL, NULL, NULL); @@ -1306,7 +1307,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) ret = i915_load_modeset_init(dev); if (ret < 0) { DRM_ERROR("failed to init modeset\n"); - goto out_power_well; + goto out_cleanup_vblank; } i915_driver_register(dev_priv); @@ -1317,8 +1318,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) return 0; -out_power_well: - intel_power_domains_fini(dev_priv); +out_cleanup_vblank: drm_vblank_cleanup(dev); out_cleanup_hw: i915_driver_cleanup_hw(dev_priv); -- cgit v1.2.3 From 4fec15d1bd8352b6fc1edd71ae35ab138df010fc Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 16 Mar 2016 13:39:08 +0200 Subject: drm/i915: Add fault injection support Add support for forcing an error at selected places in the driver. As an example add 4 options to fail during driver loading. Requested by Chris. v2: - Add fault point for modeset initialization - Print debug message when injecting an error v3: - Rename inject_fault to inject_load_failure, rename the related macros and helper accordingly (Chris) - Use a counter instead of a mask to identify the failure point (Daniel) - Mark the module option as _unsafe and keep i915_params ordered (Joonas) v4: - Rebase on latest -nightly v5: - Use DRM_INFO instead of DRM_DEBUG_DRIVER, making it clearer in CI reports that a following error message is expected (IRC r-b from Chris on v5) CC: Chris Wilson CC: Daniel Vetter CC: Joonas Lahtinen Signed-off-by: Imre Deak Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/i915_dma.c | 27 +++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_drv.h | 4 ++++ drivers/gpu/drm/i915/i915_params.c | 4 ++++ drivers/gpu/drm/i915/i915_params.h | 1 + 4 files changed, 36 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 7466e739887d..68592b0de874 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -50,6 +50,21 @@ #include #include +static unsigned int i915_load_fail_count; + +bool __i915_inject_load_failure(const char *func, int line) +{ + if (i915_load_fail_count >= i915.inject_load_failure) + return false; + + if (++i915_load_fail_count == i915.inject_load_failure) { + DRM_INFO("Injecting failure at checkpoint %u [%s:%d]\n", + i915.inject_load_failure, func, line); + return true; + } + + return false; +} static int i915_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -370,6 +385,9 @@ static int i915_load_modeset_init(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; int ret; + if (i915_inject_load_failure()) + return -ENODEV; + ret = intel_bios_init(dev_priv); if (ret) DRM_INFO("failed to find VBIOS tables\n"); @@ -951,6 +969,9 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv, struct intel_device_info *device_info; int ret = 0; + if (i915_inject_load_failure()) + return -ENODEV; + dev_priv->dev = dev; /* Setup the write-once "constant" device info */ @@ -1065,6 +1086,9 @@ static int i915_driver_init_mmio(struct drm_i915_private *dev_priv) struct drm_device *dev = dev_priv->dev; int ret; + if (i915_inject_load_failure()) + return -ENODEV; + if (i915_get_bridge_dev(dev)) return -EIO; @@ -1108,6 +1132,9 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv) uint32_t aperture_size; int ret; + if (i915_inject_load_failure()) + return -ENODEV; + intel_device_info_runtime_init(dev); ret = i915_gem_gtt_init(dev); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index e6d4b1ce130e..00c41a4bde2a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -98,6 +98,10 @@ #define I915_STATE_WARN_ON(x) \ I915_STATE_WARN((x), "%s", "WARN_ON(" __stringify(x) ")") +bool __i915_inject_load_failure(const char *func, int line); +#define i915_inject_load_failure() \ + __i915_inject_load_failure(__func__, __LINE__) + static inline const char *yesno(bool v) { return v ? "yes" : "no"; diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index 97691f1f679c..1779f02e6df8 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -57,6 +57,7 @@ struct i915_params i915 __read_mostly = { .enable_guc_submission = false, .guc_log_level = -1, .enable_dp_mst = true, + .inject_load_failure = 0, }; module_param_named(modeset, i915.modeset, int, 0400); @@ -206,3 +207,6 @@ MODULE_PARM_DESC(guc_log_level, module_param_named_unsafe(enable_dp_mst, i915.enable_dp_mst, bool, 0600); MODULE_PARM_DESC(enable_dp_mst, "Enable multi-stream transport (MST) for new DisplayPort sinks. (default: true)"); +module_param_named_unsafe(inject_load_failure, i915.inject_load_failure, uint, 0400); +MODULE_PARM_DESC(inject_load_failure, + "Force an error after a number of failure check points (0:disabled (default), N:force failure at the Nth failure check point)"); diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h index 87153b0199cd..02bc27804291 100644 --- a/drivers/gpu/drm/i915/i915_params.h +++ b/drivers/gpu/drm/i915/i915_params.h @@ -49,6 +49,7 @@ struct i915_params { int use_mmio_flip; int mmio_debug; int edp_vswing; + unsigned int inject_load_failure; /* leave bools at the end to not create holes */ bool enable_hangcheck; bool fastboot; -- cgit v1.2.3 From 6727f086cfe4ddcc651eb2bf4301abfcf619be06 Mon Sep 17 00:00:00 2001 From: Martin Sperl Date: Mon, 29 Feb 2016 11:39:17 +0000 Subject: clk: bcm2835: pll_off should only update CM_PLL_ANARST bcm2835_pll_off is currently assigning CM_PLL_ANARST to the control register, which may lose the other bits that are currently set by the clock dividers. It also now locks during the read/modify/write cycle of both registers. Fixes: 41691b8862e2 ("clk: bcm2835: Add support for programming the audio domain clocks") Signed-off-by: Martin Sperl Signed-off-by: Eric Anholt Reviewed-by: Eric Anholt --- drivers/clk/bcm/clk-bcm2835.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index c74ed3fd496d..adbaa55e939c 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -910,8 +910,14 @@ static void bcm2835_pll_off(struct clk_hw *hw) struct bcm2835_cprman *cprman = pll->cprman; const struct bcm2835_pll_data *data = pll->data; - cprman_write(cprman, data->cm_ctrl_reg, CM_PLL_ANARST); - cprman_write(cprman, data->a2w_ctrl_reg, A2W_PLL_CTRL_PWRDN); + spin_lock(&cprman->regs_lock); + cprman_write(cprman, data->cm_ctrl_reg, + cprman_read(cprman, data->cm_ctrl_reg) | + CM_PLL_ANARST); + cprman_write(cprman, data->a2w_ctrl_reg, + cprman_read(cprman, data->a2w_ctrl_reg) | + A2W_PLL_CTRL_PWRDN); + spin_unlock(&cprman->regs_lock); } static int bcm2835_pll_on(struct clk_hw *hw) -- cgit v1.2.3 From ec36a5c6682fdd5328abf15c3c67281bed0241d7 Mon Sep 17 00:00:00 2001 From: Martin Sperl Date: Mon, 29 Feb 2016 11:39:18 +0000 Subject: clk: bcm2835: add locking to pll*_on/off methods Add missing locking to: * bcm2835_pll_divider_on * bcm2835_pll_divider_off to protect the read modify write cycle for the register access protecting both cm_reg and a2w_reg registers. Fixes: 41691b8862e2 ("clk: bcm2835: Add support for programming the audio domain clocks") Signed-off-by: Martin Sperl Signed-off-by: Eric Anholt Reviewed-by: Eric Anholt --- drivers/clk/bcm/clk-bcm2835.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index adbaa55e939c..a39f8a7b6410 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -1085,10 +1085,12 @@ static void bcm2835_pll_divider_off(struct clk_hw *hw) struct bcm2835_cprman *cprman = divider->cprman; const struct bcm2835_pll_divider_data *data = divider->data; + spin_lock(&cprman->regs_lock); cprman_write(cprman, data->cm_reg, (cprman_read(cprman, data->cm_reg) & ~data->load_mask) | data->hold_mask); cprman_write(cprman, data->a2w_reg, A2W_PLL_CHANNEL_DISABLE); + spin_unlock(&cprman->regs_lock); } static int bcm2835_pll_divider_on(struct clk_hw *hw) @@ -1097,12 +1099,14 @@ static int bcm2835_pll_divider_on(struct clk_hw *hw) struct bcm2835_cprman *cprman = divider->cprman; const struct bcm2835_pll_divider_data *data = divider->data; + spin_lock(&cprman->regs_lock); cprman_write(cprman, data->a2w_reg, cprman_read(cprman, data->a2w_reg) & ~A2W_PLL_CHANNEL_DISABLE); cprman_write(cprman, data->cm_reg, cprman_read(cprman, data->cm_reg) & ~data->hold_mask); + spin_unlock(&cprman->regs_lock); return 0; } -- cgit v1.2.3 From 997f16bd5d2e9b3456027f96fcadfe1e2bf12f4e Mon Sep 17 00:00:00 2001 From: Martin Sperl Date: Mon, 29 Feb 2016 11:39:20 +0000 Subject: clk: bcm2835: divider value has to be 1 or more Current clamping of a normal divider allows a value < 1 to be valid. A divider of < 1 would actually only be possible if we had a PLL... So this patch clamps the divider to 1. Fixes: 41691b8862e2 ("clk: bcm2835: Add support for programming the audio domain clocks") Signed-off-by: Martin Sperl Signed-off-by: Eric Anholt Reviewed-by: Eric Anholt --- drivers/clk/bcm/clk-bcm2835.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index a39f8a7b6410..1fee1fd87cea 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -1190,8 +1190,9 @@ static u32 bcm2835_clock_choose_div(struct clk_hw *hw, div += unused_frac_mask + 1; div &= ~unused_frac_mask; - /* Clamp to the limits. */ - div = max(div, unused_frac_mask + 1); + /* clamp to min divider of 1 */ + div = max_t(u32, div, 1 << CM_DIV_FRAC_BITS); + /* clamp to the highest possible fractional divider */ div = min_t(u32, div, GENMASK(data->int_bits + CM_DIV_FRAC_BITS - 1, CM_DIV_FRAC_BITS - data->frac_bits)); -- cgit v1.2.3 From 959ca92a3235fc4b17c1e18483fc390b3d612254 Mon Sep 17 00:00:00 2001 From: Martin Sperl Date: Mon, 29 Feb 2016 11:39:21 +0000 Subject: clk: bcm2835: correctly enable fractional clock support The current driver calculates the clock divider with fractional support enabled. But it does not enable fractional support in the control register itself resulting in an integer only divider, but in clk_set_rate responds back the fractionally divided clock frequency. This patch enables fractional support in the control register whenever there is a fractional bit set in the requested clock divider. Mash clock limits are are also handled for the PWM clock applying the correct divider limits (2 and max_int) applicable to basic fractional divider support (mash order of 1). It also adds locking to protect the read/modify/write cycle of the register modification. Fixes: 41691b8862e2 ("clk: bcm2835: Add support for programming the audio domain clocks") Signed-off-by: Martin Sperl Signed-off-by: Eric Anholt Reviewed-by: Eric Anholt --- drivers/clk/bcm/clk-bcm2835.c | 45 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 1fee1fd87cea..1ee9a3549473 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -51,6 +51,7 @@ #define CM_GNRICCTL 0x000 #define CM_GNRICDIV 0x004 # define CM_DIV_FRAC_BITS 12 +# define CM_DIV_FRAC_MASK GENMASK(CM_DIV_FRAC_BITS - 1, 0) #define CM_VPUCTL 0x008 #define CM_VPUDIV 0x00c @@ -128,6 +129,7 @@ # define CM_GATE BIT(CM_GATE_BIT) # define CM_BUSY BIT(7) # define CM_BUSYD BIT(8) +# define CM_FRAC BIT(9) # define CM_SRC_SHIFT 0 # define CM_SRC_BITS 4 # define CM_SRC_MASK 0xf @@ -644,6 +646,7 @@ struct bcm2835_clock_data { u32 frac_bits; bool is_vpu_clock; + bool is_mash_clock; }; static const char *const bcm2835_clock_per_parents[] = { @@ -825,6 +828,7 @@ static const struct bcm2835_clock_data bcm2835_clock_pwm_data = { .div_reg = CM_PWMDIV, .int_bits = 12, .frac_bits = 12, + .is_mash_clock = true, }; struct bcm2835_pll { @@ -1180,7 +1184,7 @@ static u32 bcm2835_clock_choose_div(struct clk_hw *hw, GENMASK(CM_DIV_FRAC_BITS - data->frac_bits, 0) >> 1; u64 temp = (u64)parent_rate << CM_DIV_FRAC_BITS; u64 rem; - u32 div; + u32 div, mindiv, maxdiv; rem = do_div(temp, rate); div = temp; @@ -1190,11 +1194,23 @@ static u32 bcm2835_clock_choose_div(struct clk_hw *hw, div += unused_frac_mask + 1; div &= ~unused_frac_mask; - /* clamp to min divider of 1 */ - div = max_t(u32, div, 1 << CM_DIV_FRAC_BITS); - /* clamp to the highest possible fractional divider */ - div = min_t(u32, div, GENMASK(data->int_bits + CM_DIV_FRAC_BITS - 1, - CM_DIV_FRAC_BITS - data->frac_bits)); + /* different clamping limits apply for a mash clock */ + if (data->is_mash_clock) { + /* clamp to min divider of 2 */ + mindiv = 2 << CM_DIV_FRAC_BITS; + /* clamp to the highest possible integer divider */ + maxdiv = (BIT(data->int_bits) - 1) << CM_DIV_FRAC_BITS; + } else { + /* clamp to min divider of 1 */ + mindiv = 1 << CM_DIV_FRAC_BITS; + /* clamp to the highest possible fractional divider */ + maxdiv = GENMASK(data->int_bits + CM_DIV_FRAC_BITS - 1, + CM_DIV_FRAC_BITS - data->frac_bits); + } + + /* apply the clamping limits */ + div = max_t(u32, div, mindiv); + div = min_t(u32, div, maxdiv); return div; } @@ -1288,9 +1304,26 @@ static int bcm2835_clock_set_rate(struct clk_hw *hw, struct bcm2835_cprman *cprman = clock->cprman; const struct bcm2835_clock_data *data = clock->data; u32 div = bcm2835_clock_choose_div(hw, rate, parent_rate, false); + u32 ctl; + + spin_lock(&cprman->regs_lock); + + /* + * Setting up frac support + * + * In principle it is recommended to stop/start the clock first, + * but as we set CLK_SET_RATE_GATE during registration of the + * clock this requirement should be take care of by the + * clk-framework. + */ + ctl = cprman_read(cprman, data->ctl_reg) & ~CM_FRAC; + ctl |= (div & CM_DIV_FRAC_MASK) ? CM_FRAC : 0; + cprman_write(cprman, data->ctl_reg, ctl); cprman_write(cprman, data->div_reg, div); + spin_unlock(&cprman->regs_lock); + return 0; } -- cgit v1.2.3 From 6e1e60dacee7b32aef1468ea461b02e4c7a90a45 Mon Sep 17 00:00:00 2001 From: Martin Sperl Date: Mon, 29 Feb 2016 11:39:22 +0000 Subject: clk: bcm2835: clean up coding style issues Fix all the checkpatch complaints for clk-bcm2835.c Signed-off-by: Martin Sperl Signed-off-by: Eric Anholt --- drivers/clk/bcm/clk-bcm2835.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 1ee9a3549473..5e55b4797b36 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -12,9 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** @@ -299,7 +296,7 @@ struct bcm2835_cprman { struct device *dev; void __iomem *regs; - spinlock_t regs_lock; + spinlock_t regs_lock; /* spinlock for all clocks */ const char *osc_name; struct clk_onecell_data onecell; @@ -1328,7 +1325,7 @@ static int bcm2835_clock_set_rate(struct clk_hw *hw, } static int bcm2835_clock_determine_rate(struct clk_hw *hw, - struct clk_rate_request *req) + struct clk_rate_request *req) { struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); struct clk_hw *parent, *best_parent = NULL; @@ -1386,7 +1383,6 @@ static u8 bcm2835_clock_get_parent(struct clk_hw *hw) return (src & CM_SRC_MASK) >> CM_SRC_SHIFT; } - static const struct clk_ops bcm2835_clock_clk_ops = { .is_prepared = bcm2835_clock_is_on, .prepare = bcm2835_clock_on, -- cgit v1.2.3 From 96bf9c69d5729781018a00f08e2ae395ec3346b4 Mon Sep 17 00:00:00 2001 From: Martin Sperl Date: Mon, 29 Feb 2016 14:20:15 +0000 Subject: clk: bcm2835: expose raw clock-registers via debugfs For debugging purposes under some circumstance it helps to be able to see the actual clock registers. E.g: when looking at the clock divider it is helpful to see what the actual clock divider is. This patch exposes all the clock registers specific to each clock/pll/pll-divider via debugfs. Signed-off-by: Martin Sperl Signed-off-by: Eric Anholt Acked-by: Eric Anholt --- drivers/clk/bcm/clk-bcm2835.c | 101 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 5e55b4797b36..b3ab7f8a9688 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -313,6 +314,27 @@ static inline u32 cprman_read(struct bcm2835_cprman *cprman, u32 reg) return readl(cprman->regs + reg); } +static int bcm2835_debugfs_regset(struct bcm2835_cprman *cprman, u32 base, + struct debugfs_reg32 *regs, size_t nregs, + struct dentry *dentry) +{ + struct dentry *regdump; + struct debugfs_regset32 *regset; + + regset = devm_kzalloc(cprman->dev, sizeof(*regset), GFP_KERNEL); + if (!regset) + return -ENOMEM; + + regset->regs = regs; + regset->nregs = nregs; + regset->base = cprman->regs + base; + + regdump = debugfs_create_regset32("regdump", S_IRUGO, dentry, + regset); + + return regdump ? 0 : -ENOMEM; +} + /* * These are fixed clocks. They're probably not all root clocks and it may * be possible to turn them on and off but until this is mapped out better @@ -1037,6 +1059,36 @@ static int bcm2835_pll_set_rate(struct clk_hw *hw, return 0; } +static int bcm2835_pll_debug_init(struct clk_hw *hw, + struct dentry *dentry) +{ + struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw); + struct bcm2835_cprman *cprman = pll->cprman; + const struct bcm2835_pll_data *data = pll->data; + struct debugfs_reg32 *regs; + + regs = devm_kzalloc(cprman->dev, 7 * sizeof(*regs), GFP_KERNEL); + if (!regs) + return -ENOMEM; + + regs[0].name = "cm_ctrl"; + regs[0].offset = data->cm_ctrl_reg; + regs[1].name = "a2w_ctrl"; + regs[1].offset = data->a2w_ctrl_reg; + regs[2].name = "frac"; + regs[2].offset = data->frac_reg; + regs[3].name = "ana0"; + regs[3].offset = data->ana_reg_base + 0 * 4; + regs[4].name = "ana1"; + regs[4].offset = data->ana_reg_base + 1 * 4; + regs[5].name = "ana2"; + regs[5].offset = data->ana_reg_base + 2 * 4; + regs[6].name = "ana3"; + regs[6].offset = data->ana_reg_base + 3 * 4; + + return bcm2835_debugfs_regset(cprman, 0, regs, 7, dentry); +} + static const struct clk_ops bcm2835_pll_clk_ops = { .is_prepared = bcm2835_pll_is_on, .prepare = bcm2835_pll_on, @@ -1044,6 +1096,7 @@ static const struct clk_ops bcm2835_pll_clk_ops = { .recalc_rate = bcm2835_pll_get_rate, .set_rate = bcm2835_pll_set_rate, .round_rate = bcm2835_pll_round_rate, + .debug_init = bcm2835_pll_debug_init, }; struct bcm2835_pll_divider { @@ -1135,6 +1188,26 @@ static int bcm2835_pll_divider_set_rate(struct clk_hw *hw, return 0; } +static int bcm2835_pll_divider_debug_init(struct clk_hw *hw, + struct dentry *dentry) +{ + struct bcm2835_pll_divider *divider = bcm2835_pll_divider_from_hw(hw); + struct bcm2835_cprman *cprman = divider->cprman; + const struct bcm2835_pll_divider_data *data = divider->data; + struct debugfs_reg32 *regs; + + regs = devm_kzalloc(cprman->dev, 7 * sizeof(*regs), GFP_KERNEL); + if (!regs) + return -ENOMEM; + + regs[0].name = "cm"; + regs[0].offset = data->cm_reg; + regs[1].name = "a2w"; + regs[1].offset = data->a2w_reg; + + return bcm2835_debugfs_regset(cprman, 0, regs, 2, dentry); +} + static const struct clk_ops bcm2835_pll_divider_clk_ops = { .is_prepared = bcm2835_pll_divider_is_on, .prepare = bcm2835_pll_divider_on, @@ -1142,6 +1215,7 @@ static const struct clk_ops bcm2835_pll_divider_clk_ops = { .recalc_rate = bcm2835_pll_divider_get_rate, .set_rate = bcm2835_pll_divider_set_rate, .round_rate = bcm2835_pll_divider_round_rate, + .debug_init = bcm2835_pll_divider_debug_init, }; /* @@ -1383,6 +1457,31 @@ static u8 bcm2835_clock_get_parent(struct clk_hw *hw) return (src & CM_SRC_MASK) >> CM_SRC_SHIFT; } +static struct debugfs_reg32 bcm2835_debugfs_clock_reg32[] = { + { + .name = "ctl", + .offset = 0, + }, + { + .name = "div", + .offset = 4, + }, +}; + +static int bcm2835_clock_debug_init(struct clk_hw *hw, + struct dentry *dentry) +{ + struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); + struct bcm2835_cprman *cprman = clock->cprman; + const struct bcm2835_clock_data *data = clock->data; + + return bcm2835_debugfs_regset( + cprman, data->ctl_reg, + bcm2835_debugfs_clock_reg32, + ARRAY_SIZE(bcm2835_debugfs_clock_reg32), + dentry); +} + static const struct clk_ops bcm2835_clock_clk_ops = { .is_prepared = bcm2835_clock_is_on, .prepare = bcm2835_clock_on, @@ -1392,6 +1491,7 @@ static const struct clk_ops bcm2835_clock_clk_ops = { .determine_rate = bcm2835_clock_determine_rate, .set_parent = bcm2835_clock_set_parent, .get_parent = bcm2835_clock_get_parent, + .debug_init = bcm2835_clock_debug_init, }; static int bcm2835_vpu_clock_is_on(struct clk_hw *hw) @@ -1410,6 +1510,7 @@ static const struct clk_ops bcm2835_vpu_clock_clk_ops = { .determine_rate = bcm2835_clock_determine_rate, .set_parent = bcm2835_clock_set_parent, .get_parent = bcm2835_clock_get_parent, + .debug_init = bcm2835_clock_debug_init, }; static struct clk *bcm2835_register_pll(struct bcm2835_cprman *cprman, -- cgit v1.2.3 From 56eb3a2ed9726961e1bcfa69d4a3f86d68f0eb52 Mon Sep 17 00:00:00 2001 From: Martin Sperl Date: Mon, 29 Feb 2016 12:51:41 +0000 Subject: clk: bcm2835: remove use of BCM2835_CLOCK_COUNT in driver As the use of BCM2835_CLOCK_COUNT in include/dt-bindings/clock/bcm2835.h is frowned upon as it needs to get modified every time a new clock gets introduced this patch changes the clk-bcm2835 driver to use a different scheme for registration of clocks and pll, so that there is no more need for BCM2835_CLOCK_COUNT to be defined. Signed-off-by: Martin Sperl Signed-off-by: Eric Anholt Reviewed-by: Eric Anholt --- drivers/clk/bcm/clk-bcm2835.c | 167 ++++++++++++++++++++---------------- include/dt-bindings/clock/bcm2835.h | 2 - 2 files changed, 94 insertions(+), 75 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index b3ab7f8a9688..71504a81cb0c 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -301,7 +301,7 @@ struct bcm2835_cprman { const char *osc_name; struct clk_onecell_data onecell; - struct clk *clks[BCM2835_CLOCK_COUNT]; + struct clk *clks[]; }; static inline void cprman_write(struct bcm2835_cprman *cprman, u32 reg, u32 val) @@ -850,6 +850,25 @@ static const struct bcm2835_clock_data bcm2835_clock_pwm_data = { .is_mash_clock = true, }; +struct bcm2835_gate_data { + const char *name; + const char *parent; + + u32 ctl_reg; +}; + +/* + * CM_PERIICTL (and CM_PERIACTL, CM_SYSCTL and CM_VPUCTL if + * you have the debug bit set in the power manager, which we + * don't bother exposing) are individual gates off of the + * non-stop vpu clock. + */ +static const struct bcm2835_gate_data bcm2835_clock_peri_image_data = { + .name = "peri_image", + .parent = "vpu", + .ctl_reg = CM_PERIICTL, +}; + struct bcm2835_pll { struct clk_hw hw; struct bcm2835_cprman *cprman; @@ -1642,14 +1661,81 @@ static struct clk *bcm2835_register_clock(struct bcm2835_cprman *cprman, return devm_clk_register(cprman->dev, &clock->hw); } +static struct clk *bcm2835_register_gate(struct bcm2835_cprman *cprman, + const struct bcm2835_gate_data *data) +{ + return clk_register_gate(cprman->dev, data->name, data->parent, + CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, + cprman->regs + data->ctl_reg, + CM_GATE_BIT, 0, &cprman->regs_lock); +} + +typedef struct clk *(*bcm2835_clk_register)(struct bcm2835_cprman *cprman, + const void *data); +struct bcm2835_clk_desc { + bcm2835_clk_register clk_register; + const void *data; +}; + +#define _REGISTER(f, d) { .clk_register = (bcm2835_clk_register)f, \ + .data = d } +#define REGISTER_PLL(d) _REGISTER(&bcm2835_register_pll, d) +#define REGISTER_PLL_DIV(d) _REGISTER(&bcm2835_register_pll_divider, d) +#define REGISTER_CLK(d) _REGISTER(&bcm2835_register_clock, d) +#define REGISTER_GATE(d) _REGISTER(&bcm2835_register_gate, d) + +static const struct bcm2835_clk_desc clk_desc_array[] = { + /* register PLL */ + [BCM2835_PLLA] = REGISTER_PLL(&bcm2835_plla_data), + [BCM2835_PLLB] = REGISTER_PLL(&bcm2835_pllb_data), + [BCM2835_PLLC] = REGISTER_PLL(&bcm2835_pllc_data), + [BCM2835_PLLD] = REGISTER_PLL(&bcm2835_plld_data), + [BCM2835_PLLH] = REGISTER_PLL(&bcm2835_pllh_data), + /* the PLL dividers */ + [BCM2835_PLLA_CORE] = REGISTER_PLL_DIV(&bcm2835_plla_core_data), + [BCM2835_PLLA_PER] = REGISTER_PLL_DIV(&bcm2835_plla_per_data), + [BCM2835_PLLC_CORE0] = REGISTER_PLL_DIV(&bcm2835_pllc_core0_data), + [BCM2835_PLLC_CORE1] = REGISTER_PLL_DIV(&bcm2835_pllc_core1_data), + [BCM2835_PLLC_CORE2] = REGISTER_PLL_DIV(&bcm2835_pllc_core2_data), + [BCM2835_PLLC_PER] = REGISTER_PLL_DIV(&bcm2835_pllc_per_data), + [BCM2835_PLLD_CORE] = REGISTER_PLL_DIV(&bcm2835_plld_core_data), + [BCM2835_PLLD_PER] = REGISTER_PLL_DIV(&bcm2835_plld_per_data), + [BCM2835_PLLH_RCAL] = REGISTER_PLL_DIV(&bcm2835_pllh_rcal_data), + [BCM2835_PLLH_AUX] = REGISTER_PLL_DIV(&bcm2835_pllh_aux_data), + [BCM2835_PLLH_PIX] = REGISTER_PLL_DIV(&bcm2835_pllh_pix_data), + /* the clocks */ + [BCM2835_CLOCK_TIMER] = REGISTER_CLK(&bcm2835_clock_timer_data), + [BCM2835_CLOCK_OTP] = REGISTER_CLK(&bcm2835_clock_otp_data), + [BCM2835_CLOCK_TSENS] = REGISTER_CLK(&bcm2835_clock_tsens_data), + [BCM2835_CLOCK_VPU] = REGISTER_CLK(&bcm2835_clock_vpu_data), + [BCM2835_CLOCK_V3D] = REGISTER_CLK(&bcm2835_clock_v3d_data), + [BCM2835_CLOCK_ISP] = REGISTER_CLK(&bcm2835_clock_isp_data), + [BCM2835_CLOCK_H264] = REGISTER_CLK(&bcm2835_clock_h264_data), + [BCM2835_CLOCK_V3D] = REGISTER_CLK(&bcm2835_clock_v3d_data), + [BCM2835_CLOCK_SDRAM] = REGISTER_CLK(&bcm2835_clock_sdram_data), + [BCM2835_CLOCK_UART] = REGISTER_CLK(&bcm2835_clock_uart_data), + [BCM2835_CLOCK_VEC] = REGISTER_CLK(&bcm2835_clock_vec_data), + [BCM2835_CLOCK_HSM] = REGISTER_CLK(&bcm2835_clock_hsm_data), + [BCM2835_CLOCK_EMMC] = REGISTER_CLK(&bcm2835_clock_emmc_data), + [BCM2835_CLOCK_PWM] = REGISTER_CLK(&bcm2835_clock_pwm_data), + /* the gates */ + [BCM2835_CLOCK_PERI_IMAGE] = REGISTER_GATE( + &bcm2835_clock_peri_image_data), +}; + static int bcm2835_clk_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct clk **clks; struct bcm2835_cprman *cprman; struct resource *res; + const struct bcm2835_clk_desc *desc; + const size_t asize = ARRAY_SIZE(clk_desc_array); + size_t i; - cprman = devm_kzalloc(dev, sizeof(*cprman), GFP_KERNEL); + cprman = devm_kzalloc(dev, + sizeof(*cprman) + asize * sizeof(*clks), + GFP_KERNEL); if (!cprman) return -ENOMEM; @@ -1666,80 +1752,15 @@ static int bcm2835_clk_probe(struct platform_device *pdev) platform_set_drvdata(pdev, cprman); - cprman->onecell.clk_num = BCM2835_CLOCK_COUNT; + cprman->onecell.clk_num = asize; cprman->onecell.clks = cprman->clks; clks = cprman->clks; - clks[BCM2835_PLLA] = bcm2835_register_pll(cprman, &bcm2835_plla_data); - clks[BCM2835_PLLB] = bcm2835_register_pll(cprman, &bcm2835_pllb_data); - clks[BCM2835_PLLC] = bcm2835_register_pll(cprman, &bcm2835_pllc_data); - clks[BCM2835_PLLD] = bcm2835_register_pll(cprman, &bcm2835_plld_data); - clks[BCM2835_PLLH] = bcm2835_register_pll(cprman, &bcm2835_pllh_data); - - clks[BCM2835_PLLA_CORE] = - bcm2835_register_pll_divider(cprman, &bcm2835_plla_core_data); - clks[BCM2835_PLLA_PER] = - bcm2835_register_pll_divider(cprman, &bcm2835_plla_per_data); - clks[BCM2835_PLLC_CORE0] = - bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core0_data); - clks[BCM2835_PLLC_CORE1] = - bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core1_data); - clks[BCM2835_PLLC_CORE2] = - bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core2_data); - clks[BCM2835_PLLC_PER] = - bcm2835_register_pll_divider(cprman, &bcm2835_pllc_per_data); - clks[BCM2835_PLLD_CORE] = - bcm2835_register_pll_divider(cprman, &bcm2835_plld_core_data); - clks[BCM2835_PLLD_PER] = - bcm2835_register_pll_divider(cprman, &bcm2835_plld_per_data); - clks[BCM2835_PLLH_RCAL] = - bcm2835_register_pll_divider(cprman, &bcm2835_pllh_rcal_data); - clks[BCM2835_PLLH_AUX] = - bcm2835_register_pll_divider(cprman, &bcm2835_pllh_aux_data); - clks[BCM2835_PLLH_PIX] = - bcm2835_register_pll_divider(cprman, &bcm2835_pllh_pix_data); - - clks[BCM2835_CLOCK_TIMER] = - bcm2835_register_clock(cprman, &bcm2835_clock_timer_data); - clks[BCM2835_CLOCK_OTP] = - bcm2835_register_clock(cprman, &bcm2835_clock_otp_data); - clks[BCM2835_CLOCK_TSENS] = - bcm2835_register_clock(cprman, &bcm2835_clock_tsens_data); - clks[BCM2835_CLOCK_VPU] = - bcm2835_register_clock(cprman, &bcm2835_clock_vpu_data); - clks[BCM2835_CLOCK_V3D] = - bcm2835_register_clock(cprman, &bcm2835_clock_v3d_data); - clks[BCM2835_CLOCK_ISP] = - bcm2835_register_clock(cprman, &bcm2835_clock_isp_data); - clks[BCM2835_CLOCK_H264] = - bcm2835_register_clock(cprman, &bcm2835_clock_h264_data); - clks[BCM2835_CLOCK_V3D] = - bcm2835_register_clock(cprman, &bcm2835_clock_v3d_data); - clks[BCM2835_CLOCK_SDRAM] = - bcm2835_register_clock(cprman, &bcm2835_clock_sdram_data); - clks[BCM2835_CLOCK_UART] = - bcm2835_register_clock(cprman, &bcm2835_clock_uart_data); - clks[BCM2835_CLOCK_VEC] = - bcm2835_register_clock(cprman, &bcm2835_clock_vec_data); - clks[BCM2835_CLOCK_HSM] = - bcm2835_register_clock(cprman, &bcm2835_clock_hsm_data); - clks[BCM2835_CLOCK_EMMC] = - bcm2835_register_clock(cprman, &bcm2835_clock_emmc_data); - - /* - * CM_PERIICTL (and CM_PERIACTL, CM_SYSCTL and CM_VPUCTL if - * you have the debug bit set in the power manager, which we - * don't bother exposing) are individual gates off of the - * non-stop vpu clock. - */ - clks[BCM2835_CLOCK_PERI_IMAGE] = - clk_register_gate(dev, "peri_image", "vpu", - CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, - cprman->regs + CM_PERIICTL, CM_GATE_BIT, - 0, &cprman->regs_lock); - - clks[BCM2835_CLOCK_PWM] = - bcm2835_register_clock(cprman, &bcm2835_clock_pwm_data); + for (i = 0; i < asize; i++) { + desc = &clk_desc_array[i]; + if (desc->clk_register && desc->data) + clks[i] = desc->clk_register(cprman, desc->data); + } return of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, &cprman->onecell); diff --git a/include/dt-bindings/clock/bcm2835.h b/include/dt-bindings/clock/bcm2835.h index 61f1d20c2a67..87235ac76ef1 100644 --- a/include/dt-bindings/clock/bcm2835.h +++ b/include/dt-bindings/clock/bcm2835.h @@ -44,5 +44,3 @@ #define BCM2835_CLOCK_EMMC 28 #define BCM2835_CLOCK_PERI_IMAGE 29 #define BCM2835_CLOCK_PWM 30 - -#define BCM2835_CLOCK_COUNT 31 -- cgit v1.2.3 From 3b15afefbef9b5952e3d68ad73d93f981b9faca8 Mon Sep 17 00:00:00 2001 From: Martin Sperl Date: Mon, 29 Feb 2016 12:51:42 +0000 Subject: clk: bcm2835: reorganize bcm2835_clock_array assignment Reorganize bcm2835_clock_array so that there is no more need for separate bcm2835_*_data structures to be defined. Instead the required structures are generated inline via helper macros. To allow this to also work for pll alone it was required that the parent_pll was changed from a pointer to bcm2835_pll_data to the name of the pll instead. Signed-off-by: Martin Sperl Signed-off-by: Eric Anholt Reviewed-by: Eric Anholt --- drivers/clk/bcm/clk-bcm2835.c | 852 +++++++++++++++++++----------------------- 1 file changed, 393 insertions(+), 459 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 71504a81cb0c..a4b91a4233af 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -415,115 +415,10 @@ static const struct bcm2835_pll_ana_bits bcm2835_ana_pllh = { .fb_prediv_mask = BIT(11), }; -/* - * PLLA is the auxiliary PLL, used to drive the CCP2 (Compact Camera - * Port 2) transmitter clock. - * - * It is in the PX LDO power domain, which is on when the AUDIO domain - * is on. - */ -static const struct bcm2835_pll_data bcm2835_plla_data = { - .name = "plla", - .cm_ctrl_reg = CM_PLLA, - .a2w_ctrl_reg = A2W_PLLA_CTRL, - .frac_reg = A2W_PLLA_FRAC, - .ana_reg_base = A2W_PLLA_ANA0, - .reference_enable_mask = A2W_XOSC_CTRL_PLLA_ENABLE, - .lock_mask = CM_LOCK_FLOCKA, - - .ana = &bcm2835_ana_default, - - .min_rate = 600000000u, - .max_rate = 2400000000u, - .max_fb_rate = BCM2835_MAX_FB_RATE, -}; - -/* PLLB is used for the ARM's clock. */ -static const struct bcm2835_pll_data bcm2835_pllb_data = { - .name = "pllb", - .cm_ctrl_reg = CM_PLLB, - .a2w_ctrl_reg = A2W_PLLB_CTRL, - .frac_reg = A2W_PLLB_FRAC, - .ana_reg_base = A2W_PLLB_ANA0, - .reference_enable_mask = A2W_XOSC_CTRL_PLLB_ENABLE, - .lock_mask = CM_LOCK_FLOCKB, - - .ana = &bcm2835_ana_default, - - .min_rate = 600000000u, - .max_rate = 3000000000u, - .max_fb_rate = BCM2835_MAX_FB_RATE, -}; - -/* - * PLLC is the core PLL, used to drive the core VPU clock. - * - * It is in the PX LDO power domain, which is on when the AUDIO domain - * is on. -*/ -static const struct bcm2835_pll_data bcm2835_pllc_data = { - .name = "pllc", - .cm_ctrl_reg = CM_PLLC, - .a2w_ctrl_reg = A2W_PLLC_CTRL, - .frac_reg = A2W_PLLC_FRAC, - .ana_reg_base = A2W_PLLC_ANA0, - .reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE, - .lock_mask = CM_LOCK_FLOCKC, - - .ana = &bcm2835_ana_default, - - .min_rate = 600000000u, - .max_rate = 3000000000u, - .max_fb_rate = BCM2835_MAX_FB_RATE, -}; - -/* - * PLLD is the display PLL, used to drive DSI display panels. - * - * It is in the PX LDO power domain, which is on when the AUDIO domain - * is on. - */ -static const struct bcm2835_pll_data bcm2835_plld_data = { - .name = "plld", - .cm_ctrl_reg = CM_PLLD, - .a2w_ctrl_reg = A2W_PLLD_CTRL, - .frac_reg = A2W_PLLD_FRAC, - .ana_reg_base = A2W_PLLD_ANA0, - .reference_enable_mask = A2W_XOSC_CTRL_DDR_ENABLE, - .lock_mask = CM_LOCK_FLOCKD, - - .ana = &bcm2835_ana_default, - - .min_rate = 600000000u, - .max_rate = 2400000000u, - .max_fb_rate = BCM2835_MAX_FB_RATE, -}; - -/* - * PLLH is used to supply the pixel clock or the AUX clock for the TV - * encoder. - * - * It is in the HDMI power domain. - */ -static const struct bcm2835_pll_data bcm2835_pllh_data = { - "pllh", - .cm_ctrl_reg = CM_PLLH, - .a2w_ctrl_reg = A2W_PLLH_CTRL, - .frac_reg = A2W_PLLH_FRAC, - .ana_reg_base = A2W_PLLH_ANA0, - .reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE, - .lock_mask = CM_LOCK_FLOCKH, - - .ana = &bcm2835_ana_pllh, - - .min_rate = 600000000u, - .max_rate = 3000000000u, - .max_fb_rate = BCM2835_MAX_FB_RATE, -}; - struct bcm2835_pll_divider_data { const char *name; - const struct bcm2835_pll_data *source_pll; + const char *source_pll; + u32 cm_reg; u32 a2w_reg; @@ -532,124 +427,6 @@ struct bcm2835_pll_divider_data { u32 fixed_divider; }; -static const struct bcm2835_pll_divider_data bcm2835_plla_core_data = { - .name = "plla_core", - .source_pll = &bcm2835_plla_data, - .cm_reg = CM_PLLA, - .a2w_reg = A2W_PLLA_CORE, - .load_mask = CM_PLLA_LOADCORE, - .hold_mask = CM_PLLA_HOLDCORE, - .fixed_divider = 1, -}; - -static const struct bcm2835_pll_divider_data bcm2835_plla_per_data = { - .name = "plla_per", - .source_pll = &bcm2835_plla_data, - .cm_reg = CM_PLLA, - .a2w_reg = A2W_PLLA_PER, - .load_mask = CM_PLLA_LOADPER, - .hold_mask = CM_PLLA_HOLDPER, - .fixed_divider = 1, -}; - -static const struct bcm2835_pll_divider_data bcm2835_pllb_arm_data = { - .name = "pllb_arm", - .source_pll = &bcm2835_pllb_data, - .cm_reg = CM_PLLB, - .a2w_reg = A2W_PLLB_ARM, - .load_mask = CM_PLLB_LOADARM, - .hold_mask = CM_PLLB_HOLDARM, - .fixed_divider = 1, -}; - -static const struct bcm2835_pll_divider_data bcm2835_pllc_core0_data = { - .name = "pllc_core0", - .source_pll = &bcm2835_pllc_data, - .cm_reg = CM_PLLC, - .a2w_reg = A2W_PLLC_CORE0, - .load_mask = CM_PLLC_LOADCORE0, - .hold_mask = CM_PLLC_HOLDCORE0, - .fixed_divider = 1, -}; - -static const struct bcm2835_pll_divider_data bcm2835_pllc_core1_data = { - .name = "pllc_core1", .source_pll = &bcm2835_pllc_data, - .cm_reg = CM_PLLC, A2W_PLLC_CORE1, - .load_mask = CM_PLLC_LOADCORE1, - .hold_mask = CM_PLLC_HOLDCORE1, - .fixed_divider = 1, -}; - -static const struct bcm2835_pll_divider_data bcm2835_pllc_core2_data = { - .name = "pllc_core2", - .source_pll = &bcm2835_pllc_data, - .cm_reg = CM_PLLC, - .a2w_reg = A2W_PLLC_CORE2, - .load_mask = CM_PLLC_LOADCORE2, - .hold_mask = CM_PLLC_HOLDCORE2, - .fixed_divider = 1, -}; - -static const struct bcm2835_pll_divider_data bcm2835_pllc_per_data = { - .name = "pllc_per", - .source_pll = &bcm2835_pllc_data, - .cm_reg = CM_PLLC, - .a2w_reg = A2W_PLLC_PER, - .load_mask = CM_PLLC_LOADPER, - .hold_mask = CM_PLLC_HOLDPER, - .fixed_divider = 1, -}; - -static const struct bcm2835_pll_divider_data bcm2835_plld_core_data = { - .name = "plld_core", - .source_pll = &bcm2835_plld_data, - .cm_reg = CM_PLLD, - .a2w_reg = A2W_PLLD_CORE, - .load_mask = CM_PLLD_LOADCORE, - .hold_mask = CM_PLLD_HOLDCORE, - .fixed_divider = 1, -}; - -static const struct bcm2835_pll_divider_data bcm2835_plld_per_data = { - .name = "plld_per", - .source_pll = &bcm2835_plld_data, - .cm_reg = CM_PLLD, - .a2w_reg = A2W_PLLD_PER, - .load_mask = CM_PLLD_LOADPER, - .hold_mask = CM_PLLD_HOLDPER, - .fixed_divider = 1, -}; - -static const struct bcm2835_pll_divider_data bcm2835_pllh_rcal_data = { - .name = "pllh_rcal", - .source_pll = &bcm2835_pllh_data, - .cm_reg = CM_PLLH, - .a2w_reg = A2W_PLLH_RCAL, - .load_mask = CM_PLLH_LOADRCAL, - .hold_mask = 0, - .fixed_divider = 10, -}; - -static const struct bcm2835_pll_divider_data bcm2835_pllh_aux_data = { - .name = "pllh_aux", - .source_pll = &bcm2835_pllh_data, - .cm_reg = CM_PLLH, - .a2w_reg = A2W_PLLH_AUX, - .load_mask = CM_PLLH_LOADAUX, - .hold_mask = 0, - .fixed_divider = 10, -}; - -static const struct bcm2835_pll_divider_data bcm2835_pllh_pix_data = { - .name = "pllh_pix", - .source_pll = &bcm2835_pllh_data, - .cm_reg = CM_PLLH, - .a2w_reg = A2W_PLLH_PIX, - .load_mask = CM_PLLH_LOADPIX, - .hold_mask = 0, - .fixed_divider = 10, -}; - struct bcm2835_clock_data { const char *name; @@ -668,188 +445,6 @@ struct bcm2835_clock_data { bool is_mash_clock; }; -static const char *const bcm2835_clock_per_parents[] = { - "gnd", - "xosc", - "testdebug0", - "testdebug1", - "plla_per", - "pllc_per", - "plld_per", - "pllh_aux", -}; - -static const char *const bcm2835_clock_vpu_parents[] = { - "gnd", - "xosc", - "testdebug0", - "testdebug1", - "plla_core", - "pllc_core0", - "plld_core", - "pllh_aux", - "pllc_core1", - "pllc_core2", -}; - -static const char *const bcm2835_clock_osc_parents[] = { - "gnd", - "xosc", - "testdebug0", - "testdebug1" -}; - -/* - * Used for a 1Mhz clock for the system clocksource, and also used by - * the watchdog timer and the camera pulse generator. - */ -static const struct bcm2835_clock_data bcm2835_clock_timer_data = { - .name = "timer", - .num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents), - .parents = bcm2835_clock_osc_parents, - .ctl_reg = CM_TIMERCTL, - .div_reg = CM_TIMERDIV, - .int_bits = 6, - .frac_bits = 12, -}; - -/* One Time Programmable Memory clock. Maximum 10Mhz. */ -static const struct bcm2835_clock_data bcm2835_clock_otp_data = { - .name = "otp", - .num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents), - .parents = bcm2835_clock_osc_parents, - .ctl_reg = CM_OTPCTL, - .div_reg = CM_OTPDIV, - .int_bits = 4, - .frac_bits = 0, -}; - -/* - * VPU clock. This doesn't have an enable bit, since it drives the - * bus for everything else, and is special so it doesn't need to be - * gated for rate changes. It is also known as "clk_audio" in various - * hardware documentation. - */ -static const struct bcm2835_clock_data bcm2835_clock_vpu_data = { - .name = "vpu", - .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents), - .parents = bcm2835_clock_vpu_parents, - .ctl_reg = CM_VPUCTL, - .div_reg = CM_VPUDIV, - .int_bits = 12, - .frac_bits = 8, - .is_vpu_clock = true, -}; - -static const struct bcm2835_clock_data bcm2835_clock_v3d_data = { - .name = "v3d", - .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents), - .parents = bcm2835_clock_vpu_parents, - .ctl_reg = CM_V3DCTL, - .div_reg = CM_V3DDIV, - .int_bits = 4, - .frac_bits = 8, -}; - -static const struct bcm2835_clock_data bcm2835_clock_isp_data = { - .name = "isp", - .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents), - .parents = bcm2835_clock_vpu_parents, - .ctl_reg = CM_ISPCTL, - .div_reg = CM_ISPDIV, - .int_bits = 4, - .frac_bits = 8, -}; - -static const struct bcm2835_clock_data bcm2835_clock_h264_data = { - .name = "h264", - .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents), - .parents = bcm2835_clock_vpu_parents, - .ctl_reg = CM_H264CTL, - .div_reg = CM_H264DIV, - .int_bits = 4, - .frac_bits = 8, -}; - -/* TV encoder clock. Only operating frequency is 108Mhz. */ -static const struct bcm2835_clock_data bcm2835_clock_vec_data = { - .name = "vec", - .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), - .parents = bcm2835_clock_per_parents, - .ctl_reg = CM_VECCTL, - .div_reg = CM_VECDIV, - .int_bits = 4, - .frac_bits = 0, -}; - -static const struct bcm2835_clock_data bcm2835_clock_uart_data = { - .name = "uart", - .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), - .parents = bcm2835_clock_per_parents, - .ctl_reg = CM_UARTCTL, - .div_reg = CM_UARTDIV, - .int_bits = 10, - .frac_bits = 12, -}; - -/* HDMI state machine */ -static const struct bcm2835_clock_data bcm2835_clock_hsm_data = { - .name = "hsm", - .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), - .parents = bcm2835_clock_per_parents, - .ctl_reg = CM_HSMCTL, - .div_reg = CM_HSMDIV, - .int_bits = 4, - .frac_bits = 8, -}; - -/* - * Secondary SDRAM clock. Used for low-voltage modes when the PLL in - * the SDRAM controller can't be used. - */ -static const struct bcm2835_clock_data bcm2835_clock_sdram_data = { - .name = "sdram", - .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents), - .parents = bcm2835_clock_vpu_parents, - .ctl_reg = CM_SDCCTL, - .div_reg = CM_SDCDIV, - .int_bits = 6, - .frac_bits = 0, -}; - -/* Clock for the temperature sensor. Generally run at 2Mhz, max 5Mhz. */ -static const struct bcm2835_clock_data bcm2835_clock_tsens_data = { - .name = "tsens", - .num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents), - .parents = bcm2835_clock_osc_parents, - .ctl_reg = CM_TSENSCTL, - .div_reg = CM_TSENSDIV, - .int_bits = 5, - .frac_bits = 0, -}; - -/* Arasan EMMC clock */ -static const struct bcm2835_clock_data bcm2835_clock_emmc_data = { - .name = "emmc", - .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), - .parents = bcm2835_clock_per_parents, - .ctl_reg = CM_EMMCCTL, - .div_reg = CM_EMMCDIV, - .int_bits = 4, - .frac_bits = 8, -}; - -static const struct bcm2835_clock_data bcm2835_clock_pwm_data = { - .name = "pwm", - .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), - .parents = bcm2835_clock_per_parents, - .ctl_reg = CM_PWMCTL, - .div_reg = CM_PWMDIV, - .int_bits = 12, - .frac_bits = 12, - .is_mash_clock = true, -}; - struct bcm2835_gate_data { const char *name; const char *parent; @@ -857,18 +452,6 @@ struct bcm2835_gate_data { u32 ctl_reg; }; -/* - * CM_PERIICTL (and CM_PERIACTL, CM_SYSCTL and CM_VPUCTL if - * you have the debug bit set in the power manager, which we - * don't bother exposing) are individual gates off of the - * non-stop vpu clock. - */ -static const struct bcm2835_gate_data bcm2835_clock_peri_image_data = { - .name = "peri_image", - .parent = "vpu", - .ctl_reg = CM_PERIICTL, -}; - struct bcm2835_pll { struct clk_hw hw; struct bcm2835_cprman *cprman; @@ -1578,7 +1161,7 @@ bcm2835_register_pll_divider(struct bcm2835_cprman *cprman, memset(&init, 0, sizeof(init)); - init.parent_names = &data->source_pll->name; + init.parent_names = &data->source_pll; init.num_parents = 1; init.name = divider_name; init.ops = &bcm2835_pll_divider_clk_ops; @@ -1677,50 +1260,401 @@ struct bcm2835_clk_desc { const void *data; }; -#define _REGISTER(f, d) { .clk_register = (bcm2835_clk_register)f, \ - .data = d } -#define REGISTER_PLL(d) _REGISTER(&bcm2835_register_pll, d) -#define REGISTER_PLL_DIV(d) _REGISTER(&bcm2835_register_pll_divider, d) -#define REGISTER_CLK(d) _REGISTER(&bcm2835_register_clock, d) -#define REGISTER_GATE(d) _REGISTER(&bcm2835_register_gate, d) +/* assignment helper macros for different clock types */ +#define _REGISTER(f, ...) { .clk_register = (bcm2835_clk_register)f, \ + .data = __VA_ARGS__ } +#define REGISTER_PLL(...) _REGISTER(&bcm2835_register_pll, \ + &(struct bcm2835_pll_data) \ + {__VA_ARGS__}) +#define REGISTER_PLL_DIV(...) _REGISTER(&bcm2835_register_pll_divider, \ + &(struct bcm2835_pll_divider_data) \ + {__VA_ARGS__}) +#define REGISTER_CLK(...) _REGISTER(&bcm2835_register_clock, \ + &(struct bcm2835_clock_data) \ + {__VA_ARGS__}) +#define REGISTER_GATE(...) _REGISTER(&bcm2835_register_gate, \ + &(struct bcm2835_gate_data) \ + {__VA_ARGS__}) + +/* parent mux arrays plus helper macros */ + +/* main oscillator parent mux */ +static const char *const bcm2835_clock_osc_parents[] = { + "gnd", + "xosc", + "testdebug0", + "testdebug1" +}; + +#define REGISTER_OSC_CLK(...) REGISTER_CLK( \ + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents), \ + .parents = bcm2835_clock_osc_parents, \ + __VA_ARGS__) + +/* main peripherial parent mux */ +static const char *const bcm2835_clock_per_parents[] = { + "gnd", + "xosc", + "testdebug0", + "testdebug1", + "plla_per", + "pllc_per", + "plld_per", + "pllh_aux", +}; + +#define REGISTER_PER_CLK(...) REGISTER_CLK( \ + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), \ + .parents = bcm2835_clock_per_parents, \ + __VA_ARGS__) +/* main vpu parent mux */ +static const char *const bcm2835_clock_vpu_parents[] = { + "gnd", + "xosc", + "testdebug0", + "testdebug1", + "plla_core", + "pllc_core0", + "plld_core", + "pllh_aux", + "pllc_core1", + "pllc_core2", +}; + +#define REGISTER_VPU_CLK(...) REGISTER_CLK( \ + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents), \ + .parents = bcm2835_clock_vpu_parents, \ + __VA_ARGS__) + +/* + * the real definition of all the pll, pll_dividers and clocks + * these make use of the above REGISTER_* macros + */ static const struct bcm2835_clk_desc clk_desc_array[] = { - /* register PLL */ - [BCM2835_PLLA] = REGISTER_PLL(&bcm2835_plla_data), - [BCM2835_PLLB] = REGISTER_PLL(&bcm2835_pllb_data), - [BCM2835_PLLC] = REGISTER_PLL(&bcm2835_pllc_data), - [BCM2835_PLLD] = REGISTER_PLL(&bcm2835_plld_data), - [BCM2835_PLLH] = REGISTER_PLL(&bcm2835_pllh_data), - /* the PLL dividers */ - [BCM2835_PLLA_CORE] = REGISTER_PLL_DIV(&bcm2835_plla_core_data), - [BCM2835_PLLA_PER] = REGISTER_PLL_DIV(&bcm2835_plla_per_data), - [BCM2835_PLLC_CORE0] = REGISTER_PLL_DIV(&bcm2835_pllc_core0_data), - [BCM2835_PLLC_CORE1] = REGISTER_PLL_DIV(&bcm2835_pllc_core1_data), - [BCM2835_PLLC_CORE2] = REGISTER_PLL_DIV(&bcm2835_pllc_core2_data), - [BCM2835_PLLC_PER] = REGISTER_PLL_DIV(&bcm2835_pllc_per_data), - [BCM2835_PLLD_CORE] = REGISTER_PLL_DIV(&bcm2835_plld_core_data), - [BCM2835_PLLD_PER] = REGISTER_PLL_DIV(&bcm2835_plld_per_data), - [BCM2835_PLLH_RCAL] = REGISTER_PLL_DIV(&bcm2835_pllh_rcal_data), - [BCM2835_PLLH_AUX] = REGISTER_PLL_DIV(&bcm2835_pllh_aux_data), - [BCM2835_PLLH_PIX] = REGISTER_PLL_DIV(&bcm2835_pllh_pix_data), + /* the PLL + PLL dividers */ + + /* + * PLLA is the auxiliary PLL, used to drive the CCP2 + * (Compact Camera Port 2) transmitter clock. + * + * It is in the PX LDO power domain, which is on when the + * AUDIO domain is on. + */ + [BCM2835_PLLA] = REGISTER_PLL( + .name = "plla", + .cm_ctrl_reg = CM_PLLA, + .a2w_ctrl_reg = A2W_PLLA_CTRL, + .frac_reg = A2W_PLLA_FRAC, + .ana_reg_base = A2W_PLLA_ANA0, + .reference_enable_mask = A2W_XOSC_CTRL_PLLA_ENABLE, + .lock_mask = CM_LOCK_FLOCKA, + + .ana = &bcm2835_ana_default, + + .min_rate = 600000000u, + .max_rate = 2400000000u, + .max_fb_rate = BCM2835_MAX_FB_RATE), + [BCM2835_PLLA_CORE] = REGISTER_PLL_DIV( + .name = "plla_core", + .source_pll = "plla", + .cm_reg = CM_PLLA, + .a2w_reg = A2W_PLLA_CORE, + .load_mask = CM_PLLA_LOADCORE, + .hold_mask = CM_PLLA_HOLDCORE, + .fixed_divider = 1), + [BCM2835_PLLA_PER] = REGISTER_PLL_DIV( + .name = "plla_per", + .source_pll = "plla", + .cm_reg = CM_PLLA, + .a2w_reg = A2W_PLLA_PER, + .load_mask = CM_PLLA_LOADPER, + .hold_mask = CM_PLLA_HOLDPER, + .fixed_divider = 1), + + /* PLLB is used for the ARM's clock. */ + [BCM2835_PLLB] = REGISTER_PLL( + .name = "pllb", + .cm_ctrl_reg = CM_PLLB, + .a2w_ctrl_reg = A2W_PLLB_CTRL, + .frac_reg = A2W_PLLB_FRAC, + .ana_reg_base = A2W_PLLB_ANA0, + .reference_enable_mask = A2W_XOSC_CTRL_PLLB_ENABLE, + .lock_mask = CM_LOCK_FLOCKB, + + .ana = &bcm2835_ana_default, + + .min_rate = 600000000u, + .max_rate = 3000000000u, + .max_fb_rate = BCM2835_MAX_FB_RATE), + [BCM2835_PLLB_ARM] = REGISTER_PLL_DIV( + .name = "pllb_arm", + .source_pll = "pllb", + .cm_reg = CM_PLLB, + .a2w_reg = A2W_PLLB_ARM, + .load_mask = CM_PLLB_LOADARM, + .hold_mask = CM_PLLB_HOLDARM, + .fixed_divider = 1), + + /* + * PLLC is the core PLL, used to drive the core VPU clock. + * + * It is in the PX LDO power domain, which is on when the + * AUDIO domain is on. + */ + [BCM2835_PLLC] = REGISTER_PLL( + .name = "pllc", + .cm_ctrl_reg = CM_PLLC, + .a2w_ctrl_reg = A2W_PLLC_CTRL, + .frac_reg = A2W_PLLC_FRAC, + .ana_reg_base = A2W_PLLC_ANA0, + .reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE, + .lock_mask = CM_LOCK_FLOCKC, + + .ana = &bcm2835_ana_default, + + .min_rate = 600000000u, + .max_rate = 3000000000u, + .max_fb_rate = BCM2835_MAX_FB_RATE), + [BCM2835_PLLC_CORE0] = REGISTER_PLL_DIV( + .name = "pllc_core0", + .source_pll = "pllc", + .cm_reg = CM_PLLC, + .a2w_reg = A2W_PLLC_CORE0, + .load_mask = CM_PLLC_LOADCORE0, + .hold_mask = CM_PLLC_HOLDCORE0, + .fixed_divider = 1), + [BCM2835_PLLC_CORE1] = REGISTER_PLL_DIV( + .name = "pllc_core1", + .source_pll = "pllc", + .cm_reg = CM_PLLC, + .a2w_reg = A2W_PLLC_CORE1, + .load_mask = CM_PLLC_LOADCORE1, + .hold_mask = CM_PLLC_HOLDCORE1, + .fixed_divider = 1), + [BCM2835_PLLC_CORE2] = REGISTER_PLL_DIV( + .name = "pllc_core2", + .source_pll = "pllc", + .cm_reg = CM_PLLC, + .a2w_reg = A2W_PLLC_CORE2, + .load_mask = CM_PLLC_LOADCORE2, + .hold_mask = CM_PLLC_HOLDCORE2, + .fixed_divider = 1), + [BCM2835_PLLC_PER] = REGISTER_PLL_DIV( + .name = "pllc_per", + .source_pll = "pllc", + .cm_reg = CM_PLLC, + .a2w_reg = A2W_PLLC_PER, + .load_mask = CM_PLLC_LOADPER, + .hold_mask = CM_PLLC_HOLDPER, + .fixed_divider = 1), + + /* + * PLLD is the display PLL, used to drive DSI display panels. + * + * It is in the PX LDO power domain, which is on when the + * AUDIO domain is on. + */ + [BCM2835_PLLD] = REGISTER_PLL( + .name = "plld", + .cm_ctrl_reg = CM_PLLD, + .a2w_ctrl_reg = A2W_PLLD_CTRL, + .frac_reg = A2W_PLLD_FRAC, + .ana_reg_base = A2W_PLLD_ANA0, + .reference_enable_mask = A2W_XOSC_CTRL_DDR_ENABLE, + .lock_mask = CM_LOCK_FLOCKD, + + .ana = &bcm2835_ana_default, + + .min_rate = 600000000u, + .max_rate = 2400000000u, + .max_fb_rate = BCM2835_MAX_FB_RATE), + [BCM2835_PLLD_CORE] = REGISTER_PLL_DIV( + .name = "plld_core", + .source_pll = "plld", + .cm_reg = CM_PLLD, + .a2w_reg = A2W_PLLD_CORE, + .load_mask = CM_PLLD_LOADCORE, + .hold_mask = CM_PLLD_HOLDCORE, + .fixed_divider = 1), + [BCM2835_PLLD_PER] = REGISTER_PLL_DIV( + .name = "plld_per", + .source_pll = "plld", + .cm_reg = CM_PLLD, + .a2w_reg = A2W_PLLD_PER, + .load_mask = CM_PLLD_LOADPER, + .hold_mask = CM_PLLD_HOLDPER, + .fixed_divider = 1), + + /* + * PLLH is used to supply the pixel clock or the AUX clock for the + * TV encoder. + * + * It is in the HDMI power domain. + */ + [BCM2835_PLLH] = REGISTER_PLL( + "pllh", + .cm_ctrl_reg = CM_PLLH, + .a2w_ctrl_reg = A2W_PLLH_CTRL, + .frac_reg = A2W_PLLH_FRAC, + .ana_reg_base = A2W_PLLH_ANA0, + .reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE, + .lock_mask = CM_LOCK_FLOCKH, + + .ana = &bcm2835_ana_pllh, + + .min_rate = 600000000u, + .max_rate = 3000000000u, + .max_fb_rate = BCM2835_MAX_FB_RATE), + [BCM2835_PLLH_RCAL] = REGISTER_PLL_DIV( + .name = "pllh_rcal", + .source_pll = "pllh", + .cm_reg = CM_PLLH, + .a2w_reg = A2W_PLLH_RCAL, + .load_mask = CM_PLLH_LOADRCAL, + .hold_mask = 0, + .fixed_divider = 10), + [BCM2835_PLLH_AUX] = REGISTER_PLL_DIV( + .name = "pllh_aux", + .source_pll = "pllh", + .cm_reg = CM_PLLH, + .a2w_reg = A2W_PLLH_AUX, + .load_mask = CM_PLLH_LOADAUX, + .hold_mask = 0, + .fixed_divider = 10), + [BCM2835_PLLH_PIX] = REGISTER_PLL_DIV( + .name = "pllh_pix", + .source_pll = "pllh", + .cm_reg = CM_PLLH, + .a2w_reg = A2W_PLLH_PIX, + .load_mask = CM_PLLH_LOADPIX, + .hold_mask = 0, + .fixed_divider = 10), + /* the clocks */ - [BCM2835_CLOCK_TIMER] = REGISTER_CLK(&bcm2835_clock_timer_data), - [BCM2835_CLOCK_OTP] = REGISTER_CLK(&bcm2835_clock_otp_data), - [BCM2835_CLOCK_TSENS] = REGISTER_CLK(&bcm2835_clock_tsens_data), - [BCM2835_CLOCK_VPU] = REGISTER_CLK(&bcm2835_clock_vpu_data), - [BCM2835_CLOCK_V3D] = REGISTER_CLK(&bcm2835_clock_v3d_data), - [BCM2835_CLOCK_ISP] = REGISTER_CLK(&bcm2835_clock_isp_data), - [BCM2835_CLOCK_H264] = REGISTER_CLK(&bcm2835_clock_h264_data), - [BCM2835_CLOCK_V3D] = REGISTER_CLK(&bcm2835_clock_v3d_data), - [BCM2835_CLOCK_SDRAM] = REGISTER_CLK(&bcm2835_clock_sdram_data), - [BCM2835_CLOCK_UART] = REGISTER_CLK(&bcm2835_clock_uart_data), - [BCM2835_CLOCK_VEC] = REGISTER_CLK(&bcm2835_clock_vec_data), - [BCM2835_CLOCK_HSM] = REGISTER_CLK(&bcm2835_clock_hsm_data), - [BCM2835_CLOCK_EMMC] = REGISTER_CLK(&bcm2835_clock_emmc_data), - [BCM2835_CLOCK_PWM] = REGISTER_CLK(&bcm2835_clock_pwm_data), + + /* clocks with oscillator parent mux */ + + /* One Time Programmable Memory clock. Maximum 10Mhz. */ + [BCM2835_CLOCK_OTP] = REGISTER_OSC_CLK( + .name = "otp", + .ctl_reg = CM_OTPCTL, + .div_reg = CM_OTPDIV, + .int_bits = 4, + .frac_bits = 0), + /* + * Used for a 1Mhz clock for the system clocksource, and also used + * bythe watchdog timer and the camera pulse generator. + */ + [BCM2835_CLOCK_TIMER] = REGISTER_OSC_CLK( + .name = "timer", + .ctl_reg = CM_TIMERCTL, + .div_reg = CM_TIMERDIV, + .int_bits = 6, + .frac_bits = 12), + /* + * Clock for the temperature sensor. + * Generally run at 2Mhz, max 5Mhz. + */ + [BCM2835_CLOCK_TSENS] = REGISTER_OSC_CLK( + .name = "tsens", + .ctl_reg = CM_TSENSCTL, + .div_reg = CM_TSENSDIV, + .int_bits = 5, + .frac_bits = 0), + + /* clocks with vpu parent mux */ + [BCM2835_CLOCK_H264] = REGISTER_VPU_CLK( + .name = "h264", + .ctl_reg = CM_H264CTL, + .div_reg = CM_H264DIV, + .int_bits = 4, + .frac_bits = 8), + [BCM2835_CLOCK_ISP] = REGISTER_VPU_CLK( + .name = "isp", + .ctl_reg = CM_ISPCTL, + .div_reg = CM_ISPDIV, + .int_bits = 4, + .frac_bits = 8), + /* + * Secondary SDRAM clock. Used for low-voltage modes when the PLL + * in the SDRAM controller can't be used. + */ + [BCM2835_CLOCK_SDRAM] = REGISTER_VPU_CLK( + .name = "sdram", + .ctl_reg = CM_SDCCTL, + .div_reg = CM_SDCDIV, + .int_bits = 6, + .frac_bits = 0), + [BCM2835_CLOCK_V3D] = REGISTER_VPU_CLK( + .name = "v3d", + .ctl_reg = CM_V3DCTL, + .div_reg = CM_V3DDIV, + .int_bits = 4, + .frac_bits = 8), + /* + * VPU clock. This doesn't have an enable bit, since it drives + * the bus for everything else, and is special so it doesn't need + * to be gated for rate changes. It is also known as "clk_audio" + * in various hardware documentation. + */ + [BCM2835_CLOCK_VPU] = REGISTER_VPU_CLK( + .name = "vpu", + .ctl_reg = CM_VPUCTL, + .div_reg = CM_VPUDIV, + .int_bits = 12, + .frac_bits = 8, + .is_vpu_clock = true), + + /* clocks with per parent mux */ + + /* Arasan EMMC clock */ + [BCM2835_CLOCK_EMMC] = REGISTER_PER_CLK( + .name = "emmc", + .ctl_reg = CM_EMMCCTL, + .div_reg = CM_EMMCDIV, + .int_bits = 4, + .frac_bits = 8), + /* HDMI state machine */ + [BCM2835_CLOCK_HSM] = REGISTER_PER_CLK( + .name = "hsm", + .ctl_reg = CM_HSMCTL, + .div_reg = CM_HSMDIV, + .int_bits = 4, + .frac_bits = 8), + [BCM2835_CLOCK_PWM] = REGISTER_PER_CLK( + .name = "pwm", + .ctl_reg = CM_PWMCTL, + .div_reg = CM_PWMDIV, + .int_bits = 12, + .frac_bits = 12, + .is_mash_clock = true), + [BCM2835_CLOCK_UART] = REGISTER_PER_CLK( + .name = "uart", + .ctl_reg = CM_UARTCTL, + .div_reg = CM_UARTDIV, + .int_bits = 10, + .frac_bits = 12), + /* TV encoder clock. Only operating frequency is 108Mhz. */ + [BCM2835_CLOCK_VEC] = REGISTER_PER_CLK( + .name = "vec", + .ctl_reg = CM_VECCTL, + .div_reg = CM_VECDIV, + .int_bits = 4, + .frac_bits = 0), + /* the gates */ + + /* + * CM_PERIICTL (and CM_PERIACTL, CM_SYSCTL and CM_VPUCTL if + * you have the debug bit set in the power manager, which we + * don't bother exposing) are individual gates off of the + * non-stop vpu clock. + */ [BCM2835_CLOCK_PERI_IMAGE] = REGISTER_GATE( - &bcm2835_clock_peri_image_data), + .name = "peri_image", + .parent = "vpu", + .ctl_reg = CM_PERIICTL), }; static int bcm2835_clk_probe(struct platform_device *pdev) -- cgit v1.2.3 From 33b689600f43094a9316a1b582f2286d17bc737b Mon Sep 17 00:00:00 2001 From: Martin Sperl Date: Mon, 29 Feb 2016 12:51:43 +0000 Subject: clk: bcm2835: enable management of PCM clock Enable the PCM clock in the SOC, which is used by the bcm2835-i2s driver. Signed-off-by: Martin Sperl Signed-off-by: Eric Anholt Reviewed-by: Eric Anholt --- drivers/clk/bcm/clk-bcm2835.c | 7 +++++++ include/dt-bindings/clock/bcm2835.h | 1 + 2 files changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index a4b91a4233af..156ce548ebf5 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -1622,6 +1622,13 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { .div_reg = CM_HSMDIV, .int_bits = 4, .frac_bits = 8), + [BCM2835_CLOCK_PCM] = REGISTER_PER_CLK( + .name = "pcm", + .ctl_reg = CM_PCMCTL, + .div_reg = CM_PCMDIV, + .int_bits = 12, + .frac_bits = 12, + .is_mash_clock = true), [BCM2835_CLOCK_PWM] = REGISTER_PER_CLK( .name = "pwm", .ctl_reg = CM_PWMCTL, diff --git a/include/dt-bindings/clock/bcm2835.h b/include/dt-bindings/clock/bcm2835.h index 87235ac76ef1..9a7b4a5cd6e6 100644 --- a/include/dt-bindings/clock/bcm2835.h +++ b/include/dt-bindings/clock/bcm2835.h @@ -44,3 +44,4 @@ #define BCM2835_CLOCK_EMMC 28 #define BCM2835_CLOCK_PERI_IMAGE 29 #define BCM2835_CLOCK_PWM 30 +#define BCM2835_CLOCK_PCM 31 -- cgit v1.2.3 From 728436956aa172b24a3212295f8b53feb6479f32 Mon Sep 17 00:00:00 2001 From: Martin Sperl Date: Mon, 29 Feb 2016 15:43:56 +0000 Subject: clk: bcm2835: add missing PLL clock dividers Signed-off-by: Martin Sperl Signed-off-by: Eric Anholt Reviewed-by: Eric Anholt --- drivers/clk/bcm/clk-bcm2835.c | 32 ++++++++++++++++++++++++++++++++ include/dt-bindings/clock/bcm2835.h | 5 +++++ 2 files changed, 37 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 156ce548ebf5..fa444d09c2d4 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -1371,6 +1371,22 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { .load_mask = CM_PLLA_LOADPER, .hold_mask = CM_PLLA_HOLDPER, .fixed_divider = 1), + [BCM2835_PLLA_DSI0] = REGISTER_PLL_DIV( + .name = "plla_dsi0", + .source_pll = "plla", + .cm_reg = CM_PLLA, + .a2w_reg = A2W_PLLA_DSI0, + .load_mask = CM_PLLA_LOADDSI0, + .hold_mask = CM_PLLA_HOLDDSI0, + .fixed_divider = 1), + [BCM2835_PLLA_CCP2] = REGISTER_PLL_DIV( + .name = "plla_ccp2", + .source_pll = "plla", + .cm_reg = CM_PLLA, + .a2w_reg = A2W_PLLA_CCP2, + .load_mask = CM_PLLA_LOADCCP2, + .hold_mask = CM_PLLA_HOLDCCP2, + .fixed_divider = 1), /* PLLB is used for the ARM's clock. */ [BCM2835_PLLB] = REGISTER_PLL( @@ -1485,6 +1501,22 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { .load_mask = CM_PLLD_LOADPER, .hold_mask = CM_PLLD_HOLDPER, .fixed_divider = 1), + [BCM2835_PLLD_DSI0] = REGISTER_PLL_DIV( + .name = "plld_dsi0", + .source_pll = "plld", + .cm_reg = CM_PLLD, + .a2w_reg = A2W_PLLD_DSI0, + .load_mask = CM_PLLD_LOADDSI0, + .hold_mask = CM_PLLD_HOLDDSI0, + .fixed_divider = 1), + [BCM2835_PLLD_DSI1] = REGISTER_PLL_DIV( + .name = "plld_dsi1", + .source_pll = "plld", + .cm_reg = CM_PLLD, + .a2w_reg = A2W_PLLD_DSI1, + .load_mask = CM_PLLD_LOADDSI1, + .hold_mask = CM_PLLD_HOLDDSI1, + .fixed_divider = 1), /* * PLLH is used to supply the pixel clock or the AUX clock for the diff --git a/include/dt-bindings/clock/bcm2835.h b/include/dt-bindings/clock/bcm2835.h index 9a7b4a5cd6e6..a001e3865134 100644 --- a/include/dt-bindings/clock/bcm2835.h +++ b/include/dt-bindings/clock/bcm2835.h @@ -45,3 +45,8 @@ #define BCM2835_CLOCK_PERI_IMAGE 29 #define BCM2835_CLOCK_PWM 30 #define BCM2835_CLOCK_PCM 31 + +#define BCM2835_PLLA_DSI0 32 +#define BCM2835_PLLA_CCP2 33 +#define BCM2835_PLLD_DSI0 34 +#define BCM2835_PLLD_DSI1 35 -- cgit v1.2.3 From d3d6f15fd376e3dbba851724057b112558c70b79 Mon Sep 17 00:00:00 2001 From: Martin Sperl Date: Mon, 29 Feb 2016 15:43:57 +0000 Subject: clk: bcm2835: add missing osc and per clocks Add AVE0, DFT, GP0, GP1, GP2, SLIM, SMI, TEC, DPI, CAM0, CAM1, DSI0E, and DSI1E. PULSE is not added because it has an extra divider. Signed-off-by: Martin Sperl Signed-off-by: Eric Anholt Reviewed-by: Eric Anholt --- drivers/clk/bcm/clk-bcm2835.c | 90 +++++++++++++++++++++++++++++++++++++ include/dt-bindings/clock/bcm2835.h | 14 ++++++ 2 files changed, 104 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index fa444d09c2d4..4c0f1b504e2f 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -117,6 +117,8 @@ #define CM_SDCCTL 0x1a8 #define CM_SDCDIV 0x1ac #define CM_ARMCTL 0x1b0 +#define CM_AVEOCTL 0x1b8 +#define CM_AVEODIV 0x1bc #define CM_EMMCCTL 0x1c0 #define CM_EMMCDIV 0x1c4 @@ -1594,6 +1596,12 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { .div_reg = CM_TSENSDIV, .int_bits = 5, .frac_bits = 0), + [BCM2835_CLOCK_TEC] = REGISTER_OSC_CLK( + .name = "tec", + .ctl_reg = CM_TECCTL, + .div_reg = CM_TECDIV, + .int_bits = 6, + .frac_bits = 0), /* clocks with vpu parent mux */ [BCM2835_CLOCK_H264] = REGISTER_VPU_CLK( @@ -1608,6 +1616,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { .div_reg = CM_ISPDIV, .int_bits = 4, .frac_bits = 8), + /* * Secondary SDRAM clock. Used for low-voltage modes when the PLL * in the SDRAM controller can't be used. @@ -1639,6 +1648,36 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { .is_vpu_clock = true), /* clocks with per parent mux */ + [BCM2835_CLOCK_AVEO] = REGISTER_PER_CLK( + .name = "aveo", + .ctl_reg = CM_AVEOCTL, + .div_reg = CM_AVEODIV, + .int_bits = 4, + .frac_bits = 0), + [BCM2835_CLOCK_CAM0] = REGISTER_PER_CLK( + .name = "cam0", + .ctl_reg = CM_CAM0CTL, + .div_reg = CM_CAM0DIV, + .int_bits = 4, + .frac_bits = 8), + [BCM2835_CLOCK_CAM1] = REGISTER_PER_CLK( + .name = "cam1", + .ctl_reg = CM_CAM1CTL, + .div_reg = CM_CAM1DIV, + .int_bits = 4, + .frac_bits = 8), + [BCM2835_CLOCK_DFT] = REGISTER_PER_CLK( + .name = "dft", + .ctl_reg = CM_DFTCTL, + .div_reg = CM_DFTDIV, + .int_bits = 5, + .frac_bits = 0), + [BCM2835_CLOCK_DPI] = REGISTER_PER_CLK( + .name = "dpi", + .ctl_reg = CM_DPICTL, + .div_reg = CM_DPIDIV, + .int_bits = 4, + .frac_bits = 8), /* Arasan EMMC clock */ [BCM2835_CLOCK_EMMC] = REGISTER_PER_CLK( @@ -1647,6 +1686,29 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { .div_reg = CM_EMMCDIV, .int_bits = 4, .frac_bits = 8), + + /* General purpose (GPIO) clocks */ + [BCM2835_CLOCK_GP0] = REGISTER_PER_CLK( + .name = "gp0", + .ctl_reg = CM_GP0CTL, + .div_reg = CM_GP0DIV, + .int_bits = 12, + .frac_bits = 12, + .is_mash_clock = true), + [BCM2835_CLOCK_GP1] = REGISTER_PER_CLK( + .name = "gp1", + .ctl_reg = CM_GP1CTL, + .div_reg = CM_GP1DIV, + .int_bits = 12, + .frac_bits = 12, + .is_mash_clock = true), + [BCM2835_CLOCK_GP2] = REGISTER_PER_CLK( + .name = "gp2", + .ctl_reg = CM_GP2CTL, + .div_reg = CM_GP2DIV, + .int_bits = 12, + .frac_bits = 12), + /* HDMI state machine */ [BCM2835_CLOCK_HSM] = REGISTER_PER_CLK( .name = "hsm", @@ -1668,12 +1730,26 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { .int_bits = 12, .frac_bits = 12, .is_mash_clock = true), + [BCM2835_CLOCK_SLIM] = REGISTER_PER_CLK( + .name = "slim", + .ctl_reg = CM_SLIMCTL, + .div_reg = CM_SLIMDIV, + .int_bits = 12, + .frac_bits = 12, + .is_mash_clock = true), + [BCM2835_CLOCK_SMI] = REGISTER_PER_CLK( + .name = "smi", + .ctl_reg = CM_SMICTL, + .div_reg = CM_SMIDIV, + .int_bits = 4, + .frac_bits = 8), [BCM2835_CLOCK_UART] = REGISTER_PER_CLK( .name = "uart", .ctl_reg = CM_UARTCTL, .div_reg = CM_UARTDIV, .int_bits = 10, .frac_bits = 12), + /* TV encoder clock. Only operating frequency is 108Mhz. */ [BCM2835_CLOCK_VEC] = REGISTER_PER_CLK( .name = "vec", @@ -1682,6 +1758,20 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { .int_bits = 4, .frac_bits = 0), + /* dsi clocks */ + [BCM2835_CLOCK_DSI0E] = REGISTER_PER_CLK( + .name = "dsi0e", + .ctl_reg = CM_DSI0ECTL, + .div_reg = CM_DSI0EDIV, + .int_bits = 4, + .frac_bits = 8), + [BCM2835_CLOCK_DSI1E] = REGISTER_PER_CLK( + .name = "dsi1e", + .ctl_reg = CM_DSI1ECTL, + .div_reg = CM_DSI1EDIV, + .int_bits = 4, + .frac_bits = 8), + /* the gates */ /* diff --git a/include/dt-bindings/clock/bcm2835.h b/include/dt-bindings/clock/bcm2835.h index a001e3865134..360e00cefd35 100644 --- a/include/dt-bindings/clock/bcm2835.h +++ b/include/dt-bindings/clock/bcm2835.h @@ -50,3 +50,17 @@ #define BCM2835_PLLA_CCP2 33 #define BCM2835_PLLD_DSI0 34 #define BCM2835_PLLD_DSI1 35 + +#define BCM2835_CLOCK_AVEO 36 +#define BCM2835_CLOCK_DFT 37 +#define BCM2835_CLOCK_GP0 38 +#define BCM2835_CLOCK_GP1 39 +#define BCM2835_CLOCK_GP2 40 +#define BCM2835_CLOCK_SLIM 41 +#define BCM2835_CLOCK_SMI 42 +#define BCM2835_CLOCK_TEC 43 +#define BCM2835_CLOCK_DPI 44 +#define BCM2835_CLOCK_CAM0 45 +#define BCM2835_CLOCK_CAM1 46 +#define BCM2835_CLOCK_DSI0E 47 +#define BCM2835_CLOCK_DSI1E 48 -- cgit v1.2.3 From a112dbad44c4584ca565333d58d1bbb38799c12d Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Thu, 17 Mar 2016 13:04:09 +0000 Subject: drm/i915: Remove unused variable in i915_gem_request_add_to_client Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index a4e015530b0c..85963b0407b2 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1370,7 +1370,6 @@ out: int i915_gem_request_add_to_client(struct drm_i915_gem_request *req, struct drm_file *file) { - struct drm_i915_private *dev_private; struct drm_i915_file_private *file_priv; WARN_ON(!req || !file || req->file_priv); @@ -1381,7 +1380,6 @@ int i915_gem_request_add_to_client(struct drm_i915_gem_request *req, if (req->file_priv) return -EINVAL; - dev_private = req->engine->dev->dev_private; file_priv = file->driver_priv; spin_lock(&file_priv->mm.lock); -- cgit v1.2.3 From 39dabecd991b0a914f044af5824774825fb0923e Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Thu, 17 Mar 2016 13:04:10 +0000 Subject: drm/i915: Use shorter route to dev_private where possible Where we have a request we can use req->i915 directly instead of going through the engine and device. Coccinelle script: @@ function f; identifier r; @@ f(..., struct drm_i915_gem_request *r, ...) { ... - engine->dev->dev_private + r->i915 ... } @@ struct drm_i915_gem_request *req; @@ ( req-> - engine->dev->dev_private + i915 ) Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1458219850-21007-1-git-send-email-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/i915_gem.c | 2 +- drivers/gpu/drm/i915/i915_gem_context.c | 4 ++-- drivers/gpu/drm/i915/i915_gem_gtt.c | 2 +- drivers/gpu/drm/i915/intel_lrc.c | 2 +- drivers/gpu/drm/i915/intel_ringbuffer.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 85963b0407b2..f45856d7084c 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2550,7 +2550,7 @@ void __i915_add_request(struct drm_i915_gem_request *request, return; engine = request->engine; - dev_priv = engine->dev->dev_private; + dev_priv = request->i915; ringbuf = request->ringbuf; /* diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index c114665a24b3..6627bbe9ea24 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -656,7 +656,7 @@ static int do_switch(struct drm_i915_gem_request *req) { struct intel_context *to = req->ctx; struct intel_engine_cs *engine = req->engine; - struct drm_i915_private *dev_priv = engine->dev->dev_private; + struct drm_i915_private *dev_priv = req->i915; struct intel_context *from = engine->last_context; u32 hw_flags = 0; bool uninitialized = false; @@ -829,7 +829,7 @@ unpin_out: int i915_switch_context(struct drm_i915_gem_request *req) { struct intel_engine_cs *engine = req->engine; - struct drm_i915_private *dev_priv = engine->dev->dev_private; + struct drm_i915_private *dev_priv = req->i915; WARN_ON(i915.enable_execlists); WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 9c752fe0f730..fb0f9637d46f 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -2192,7 +2192,7 @@ int i915_ppgtt_init_hw(struct drm_device *dev) int i915_ppgtt_init_ring(struct drm_i915_gem_request *req) { - struct drm_i915_private *dev_priv = req->engine->dev->dev_private; + struct drm_i915_private *dev_priv = req->i915; struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; if (i915.enable_execlists) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index f72782200226..7c636b3db156 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -897,7 +897,7 @@ int intel_logical_ring_begin(struct drm_i915_gem_request *req, int num_dwords) int ret; WARN_ON(req == NULL); - dev_priv = req->engine->dev->dev_private; + dev_priv = req->i915; ret = i915_gem_check_wedge(&dev_priv->gpu_error, dev_priv->mm.interruptible); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 015dc7db32b7..b7c8fc1a73a3 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -2499,7 +2499,7 @@ int intel_ring_begin(struct drm_i915_gem_request *req, WARN_ON(req == NULL); engine = req->engine; - dev_priv = engine->dev->dev_private; + dev_priv = req->i915; ret = i915_gem_check_wedge(&dev_priv->gpu_error, dev_priv->mm.interruptible); -- cgit v1.2.3 From 26720ab97feac7153a7b5c3c79cf5d53a8531126 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Thu, 17 Mar 2016 12:59:46 +0000 Subject: drm/i915: Move CSB MMIO reads out of the execlists lock By reading the CSB (slow MMIO accesses) into a temporary local buffer we can decrease the duration of holding the execlist lock. Main advantage is that during heavy batch buffer submission we reduce the execlist lock contention, which should decrease the latency and CPU usage between the submitting userspace process and interrupt handling. Downside is that we need to grab and relase the forcewake twice, but as the below numbers will show this is completely hidden by the primary gains. Testing with "gem_latency -n 100" (submit batch buffers with a hundred nops each) shows more than doubling of the throughput and more than halving of the dispatch latency, overall latency and CPU time spend in the submitting process. Submitting empty batches ("gem_latency -n 0") does not seem significantly affected by this change with throughput and CPU time improving by half a percent, and overall latency worsening by the same amount. Above tests were done in a hundred runs on a big core Broadwell. v2: * Overflow protection to local CSB buffer. * Use closer dev_priv in execlists_submit_requests. (Chris Wilson) v3: Rebase. v4: Added commend about irq needed to be disabled in execlists_submit_request. (Chris Wilson) Signed-off-by: Tvrtko Ursulin Cc: Chris Wilson Reviewed-by: Chris Wilsno Link: http://patchwork.freedesktop.org/patch/msgid/1458219586-20452-1-git-send-email-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/intel_lrc.c | 79 ++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 7c636b3db156..3a23b9549f7b 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -416,15 +416,25 @@ static void execlists_update_context(struct drm_i915_gem_request *rq) static void execlists_submit_requests(struct drm_i915_gem_request *rq0, struct drm_i915_gem_request *rq1) { + struct drm_i915_private *dev_priv = rq0->i915; + + /* BUG_ON(!irqs_disabled()); */ + execlists_update_context(rq0); if (rq1) execlists_update_context(rq1); + spin_lock(&dev_priv->uncore.lock); + intel_uncore_forcewake_get__locked(dev_priv, FORCEWAKE_ALL); + execlists_elsp_write(rq0, rq1); + + intel_uncore_forcewake_put__locked(dev_priv, FORCEWAKE_ALL); + spin_unlock(&dev_priv->uncore.lock); } -static void execlists_context_unqueue__locked(struct intel_engine_cs *engine) +static void execlists_context_unqueue(struct intel_engine_cs *engine) { struct drm_i915_gem_request *req0 = NULL, *req1 = NULL; struct drm_i915_gem_request *cursor, *tmp; @@ -478,19 +488,6 @@ static void execlists_context_unqueue__locked(struct intel_engine_cs *engine) execlists_submit_requests(req0, req1); } -static void execlists_context_unqueue(struct intel_engine_cs *engine) -{ - struct drm_i915_private *dev_priv = engine->dev->dev_private; - - spin_lock(&dev_priv->uncore.lock); - intel_uncore_forcewake_get__locked(dev_priv, FORCEWAKE_ALL); - - execlists_context_unqueue__locked(engine); - - intel_uncore_forcewake_put__locked(dev_priv, FORCEWAKE_ALL); - spin_unlock(&dev_priv->uncore.lock); -} - static unsigned int execlists_check_remove_request(struct intel_engine_cs *engine, u32 request_id) { @@ -551,12 +548,10 @@ void intel_lrc_irq_handler(struct intel_engine_cs *engine) struct drm_i915_private *dev_priv = engine->dev->dev_private; u32 status_pointer; unsigned int read_pointer, write_pointer; - u32 status = 0; - u32 status_id; + u32 csb[GEN8_CSB_ENTRIES][2]; + unsigned int csb_read = 0, i; unsigned int submit_contexts = 0; - spin_lock(&engine->execlist_lock); - spin_lock(&dev_priv->uncore.lock); intel_uncore_forcewake_get__locked(dev_priv, FORCEWAKE_ALL); @@ -568,41 +563,47 @@ void intel_lrc_irq_handler(struct intel_engine_cs *engine) write_pointer += GEN8_CSB_ENTRIES; while (read_pointer < write_pointer) { - status = get_context_status(engine, ++read_pointer, - &status_id); + if (WARN_ON_ONCE(csb_read == GEN8_CSB_ENTRIES)) + break; + csb[csb_read][0] = get_context_status(engine, ++read_pointer, + &csb[csb_read][1]); + csb_read++; + } - if (unlikely(status & GEN8_CTX_STATUS_PREEMPTED)) { - if (status & GEN8_CTX_STATUS_LITE_RESTORE) { - if (execlists_check_remove_request(engine, status_id)) + engine->next_context_status_buffer = write_pointer % GEN8_CSB_ENTRIES; + + /* Update the read pointer to the old write pointer. Manual ringbuffer + * management ftw */ + I915_WRITE_FW(RING_CONTEXT_STATUS_PTR(engine), + _MASKED_FIELD(GEN8_CSB_READ_PTR_MASK, + engine->next_context_status_buffer << 8)); + + intel_uncore_forcewake_put__locked(dev_priv, FORCEWAKE_ALL); + spin_unlock(&dev_priv->uncore.lock); + + spin_lock(&engine->execlist_lock); + + for (i = 0; i < csb_read; i++) { + if (unlikely(csb[i][0] & GEN8_CTX_STATUS_PREEMPTED)) { + if (csb[i][0] & GEN8_CTX_STATUS_LITE_RESTORE) { + if (execlists_check_remove_request(engine, csb[i][1])) WARN(1, "Lite Restored request removed from queue\n"); } else WARN(1, "Preemption without Lite Restore\n"); } - if (status & (GEN8_CTX_STATUS_ACTIVE_IDLE | + if (csb[i][0] & (GEN8_CTX_STATUS_ACTIVE_IDLE | GEN8_CTX_STATUS_ELEMENT_SWITCH)) submit_contexts += - execlists_check_remove_request(engine, - status_id); + execlists_check_remove_request(engine, csb[i][1]); } if (submit_contexts) { if (!engine->disable_lite_restore_wa || - (status & GEN8_CTX_STATUS_ACTIVE_IDLE)) - execlists_context_unqueue__locked(engine); + (csb[i][0] & GEN8_CTX_STATUS_ACTIVE_IDLE)) + execlists_context_unqueue(engine); } - engine->next_context_status_buffer = write_pointer % GEN8_CSB_ENTRIES; - - /* Update the read pointer to the old write pointer. Manual ringbuffer - * management ftw */ - I915_WRITE_FW(RING_CONTEXT_STATUS_PTR(engine), - _MASKED_FIELD(GEN8_CSB_READ_PTR_MASK, - engine->next_context_status_buffer << 8)); - - intel_uncore_forcewake_put__locked(dev_priv, FORCEWAKE_ALL); - spin_unlock(&dev_priv->uncore.lock); - spin_unlock(&engine->execlist_lock); if (unlikely(submit_contexts > 2)) -- cgit v1.2.3 From 950b2aaeea6960561425fc80adfb5b2fc0ac020f Mon Sep 17 00:00:00 2001 From: Tim Gore Date: Wed, 16 Mar 2016 16:13:46 +0000 Subject: drm/i915/gen9: add WaClearFlowControlGpgpuContextSave This allows writes to EU flow control registers. Together with SIP code from the user-mode driver this resolves a hang seen in some pre-emption scenarios. Note that this patch is just the kernel mode part of this workaround. v2. Oops, add FLOW_CONTROL_ENABLE macro to i915_reg.h. Signed-off-by: Tim Gore Reviewed-by: Arun Siluvery Signed-off-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1458144826-17269-1-git-send-email-tim.gore@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_ringbuffer.c | 2 ++ 2 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 07e04495cd9a..264885fc245d 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7105,6 +7105,7 @@ enum skl_disp_power_wells { #define GEN9_CCS_TLB_PREFETCH_ENABLE (1<<3) #define GEN8_ROW_CHICKEN _MMIO(0xe4f0) +#define FLOW_CONTROL_ENABLE (1<<15) #define PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE (1<<8) #define STALL_DOP_GATING_DISABLE (1<<5) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index b7c8fc1a73a3..9c59ede5dd9a 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -925,8 +925,10 @@ static int gen9_init_workarounds(struct intel_engine_cs *engine) I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | ECOCHK_DIS_TLB); + /* WaClearFlowControlGpgpuContextSave:skl,bxt */ /* WaDisablePartialInstShootdown:skl,bxt */ WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, + FLOW_CONTROL_ENABLE | PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE); /* Syncing dependencies between camera and graphics:skl,bxt */ -- cgit v1.2.3 From dc3b04fbf43227e21fa95dbe6c7a13def655c891 Mon Sep 17 00:00:00 2001 From: Joonas Lahtinen Date: Fri, 18 Mar 2016 10:42:56 +0200 Subject: drm/i915/gtt: Reference mappable_end variable from pointer Reference variable value from pointer, not assumed pointer destination. Since: commit c44ef60e437019b8ca1dab8b4d2e8761fd4ce1e9 Author: Mika Kuoppala Date: Thu Jun 25 18:35:05 2015 +0300 drm/i915/gtt: Allow >= 4GB sizes for vm. Cc: Mika Kuoppala Reviewed-by: Chris Wilson Signed-off-by: Joonas Lahtinen Reviewed-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/i915_gem_gtt.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index fb0f9637d46f..be204076f8dc 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -3103,8 +3103,7 @@ static int gen6_gmch_probe(struct drm_device *dev, * a coarse sanity check. */ if ((*mappable_end < (64<<20) || (*mappable_end > (512<<20)))) { - DRM_ERROR("Unknown GMADR size (%llx)\n", - dev_priv->gtt.mappable_end); + DRM_ERROR("Unknown GMADR size (%llx)\n", *mappable_end); return -ENXIO; } -- cgit v1.2.3 From 62106b4f6b9118073ec59e3e34ec393ed76cf24f Mon Sep 17 00:00:00 2001 From: Joonas Lahtinen Date: Fri, 18 Mar 2016 10:42:57 +0200 Subject: drm/i915: Rename dev_priv->gtt to dev_priv->ggtt Refer to Global GTT consistently as GGTT, thus rename dev_priv->gtt to dev_priv->ggtt and struct i915_gtt to struct i915_ggtt. Fix a couple of whitespace problems while at it. v2: - Fix a typo in commit message. Reviewed-by: Chris Wilson Signed-off-by: Joonas Lahtinen --- drivers/gpu/drm/i915/i915_debugfs.c | 8 +- drivers/gpu/drm/i915/i915_dma.c | 18 ++-- drivers/gpu/drm/i915/i915_drv.h | 4 +- drivers/gpu/drm/i915/i915_gem.c | 16 ++-- drivers/gpu/drm/i915/i915_gem_context.c | 2 +- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 6 +- drivers/gpu/drm/i915/i915_gem_gtt.c | 147 ++++++++++++++--------------- drivers/gpu/drm/i915/i915_gem_gtt.h | 9 +- drivers/gpu/drm/i915/i915_gem_stolen.c | 50 +++++----- drivers/gpu/drm/i915/i915_gpu_error.c | 10 +- drivers/gpu/drm/i915/i915_vgpu.c | 14 +-- drivers/gpu/drm/i915/intel_display.c | 4 +- drivers/gpu/drm/i915/intel_fbc.c | 4 +- drivers/gpu/drm/i915/intel_fbdev.c | 6 +- drivers/gpu/drm/i915/intel_overlay.c | 4 +- drivers/gpu/drm/i915/intel_pm.c | 10 +- drivers/gpu/drm/i915/intel_ringbuffer.c | 2 +- 17 files changed, 156 insertions(+), 158 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index ccdca2c7d799..e0ba3e38000f 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -203,7 +203,7 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) struct list_head *head; struct drm_device *dev = node->minor->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct i915_address_space *vm = &dev_priv->gtt.base; + struct i915_address_space *vm = &dev_priv->ggtt.base; struct i915_vma *vma; u64 total_obj_size, total_gtt_size; int count, ret; @@ -433,7 +433,7 @@ static int i915_gem_object_info(struct seq_file *m, void* data) u32 count, mappable_count, purgeable_count; u64 size, mappable_size, purgeable_size; struct drm_i915_gem_object *obj; - struct i915_address_space *vm = &dev_priv->gtt.base; + struct i915_address_space *vm = &dev_priv->ggtt.base; struct drm_file *file; struct i915_vma *vma; int ret; @@ -492,8 +492,8 @@ static int i915_gem_object_info(struct seq_file *m, void* data) count, size); seq_printf(m, "%llu [%llu] gtt total\n", - dev_priv->gtt.base.total, - (u64)dev_priv->gtt.mappable_end - dev_priv->gtt.base.start); + dev_priv->ggtt.base.total, + (u64)dev_priv->ggtt.mappable_end - dev_priv->ggtt.base.start); seq_putc(m, '\n'); print_batch_pool_stats(m, dev_priv); diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 68592b0de874..3565163d7b31 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -491,8 +491,8 @@ static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv) if (!ap) return -ENOMEM; - ap->ranges[0].base = dev_priv->gtt.mappable_base; - ap->ranges[0].size = dev_priv->gtt.mappable_end; + ap->ranges[0].base = dev_priv->ggtt.mappable_base; + ap->ranges[0].size = dev_priv->ggtt.mappable_end; primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; @@ -1172,17 +1172,17 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv) if (IS_BROADWATER(dev) || IS_CRESTLINE(dev)) dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(32)); - aperture_size = dev_priv->gtt.mappable_end; + aperture_size = dev_priv->ggtt.mappable_end; - dev_priv->gtt.mappable = - io_mapping_create_wc(dev_priv->gtt.mappable_base, + dev_priv->ggtt.mappable = + io_mapping_create_wc(dev_priv->ggtt.mappable_base, aperture_size); - if (dev_priv->gtt.mappable == NULL) { + if (dev_priv->ggtt.mappable == NULL) { ret = -EIO; goto out_gtt; } - dev_priv->gtt.mtrr = arch_phys_wc_add(dev_priv->gtt.mappable_base, + dev_priv->ggtt.mtrr = arch_phys_wc_add(dev_priv->ggtt.mappable_base, aperture_size); pm_qos_add_request(&dev_priv->pm_qos, PM_QOS_CPU_DMA_LATENCY, @@ -1230,8 +1230,8 @@ static void i915_driver_cleanup_hw(struct drm_i915_private *dev_priv) pci_disable_msi(dev->pdev); pm_qos_remove_request(&dev_priv->pm_qos); - arch_phys_wc_del(dev_priv->gtt.mtrr); - io_mapping_free(dev_priv->gtt.mappable); + arch_phys_wc_del(dev_priv->ggtt.mtrr); + io_mapping_free(dev_priv->ggtt.mappable); i915_global_gtt_cleanup(dev); } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 00c41a4bde2a..b1d65540b48b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1810,7 +1810,7 @@ struct drm_i915_private { struct drm_atomic_state *modeset_restore_state; struct list_head vm_list; /* Global list of all address spaces */ - struct i915_gtt gtt; /* VM representing the global address space */ + struct i915_ggtt ggtt; /* VM representing the global address space */ struct i915_gem_mm mm; DECLARE_HASHTABLE(mm_structs, 7); @@ -3126,7 +3126,7 @@ bool i915_gem_obj_is_pinned(struct drm_i915_gem_object *obj); /* Some GGTT VM helpers */ #define i915_obj_to_ggtt(obj) \ - (&((struct drm_i915_private *)(obj)->base.dev->dev_private)->gtt.base) + (&((struct drm_i915_private *)(obj)->base.dev->dev_private)->ggtt.base) static inline struct i915_hw_ppgtt * i915_vm_to_ppgtt(struct i915_address_space *vm) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index f45856d7084c..8588c83abb35 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -132,7 +132,7 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_get_aperture *args = data; - struct i915_gtt *ggtt = &dev_priv->gtt; + struct i915_ggtt *ggtt = &dev_priv->ggtt; struct i915_vma *vma; size_t pinned; @@ -146,7 +146,7 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, pinned += vma->node.size; mutex_unlock(&dev->struct_mutex); - args->aper_size = dev_priv->gtt.base.total; + args->aper_size = dev_priv->ggtt.base.total; args->aper_available_size = args->aper_size - pinned; return 0; @@ -807,7 +807,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, * source page isn't available. Return the error and we'll * retry in the slow path. */ - if (fast_user_write(dev_priv->gtt.mappable, page_base, + if (fast_user_write(dev_priv->ggtt.mappable, page_base, page_offset, user_data, page_length)) { ret = -EFAULT; goto out_flush; @@ -1825,7 +1825,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) } /* Use a partial view if the object is bigger than the aperture. */ - if (obj->base.size >= dev_priv->gtt.mappable_end && + if (obj->base.size >= dev_priv->ggtt.mappable_end && obj->tiling_mode == I915_TILING_NONE) { static const unsigned int chunk_size = 256; // 1 MiB @@ -1853,7 +1853,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) goto unpin; /* Finally, remap it using the new GTT offset */ - pfn = dev_priv->gtt.mappable_base + + pfn = dev_priv->ggtt.mappable_base + i915_gem_obj_ggtt_offset_view(obj, &view); pfn >>= PAGE_SHIFT; @@ -3511,7 +3511,7 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj, start = flags & PIN_OFFSET_BIAS ? flags & PIN_OFFSET_MASK : 0; end = vm->total; if (flags & PIN_MAPPABLE) - end = min_t(u64, end, dev_priv->gtt.mappable_end); + end = min_t(u64, end, dev_priv->ggtt.mappable_end); if (flags & PIN_ZONE_4G) end = min_t(u64, end, (1ULL << 32) - PAGE_SIZE); @@ -3772,7 +3772,7 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) vma = i915_gem_obj_to_ggtt(obj); if (vma && drm_mm_node_allocated(&vma->node) && !obj->active) list_move_tail(&vma->vm_link, - &to_i915(obj->base.dev)->gtt.base.inactive_list); + &to_i915(obj->base.dev)->ggtt.base.inactive_list); return 0; } @@ -4209,7 +4209,7 @@ void __i915_vma_set_map_and_fenceable(struct i915_vma *vma) (vma->node.start & (fence_alignment - 1)) == 0); mappable = (vma->node.start + fence_size <= - to_i915(obj->base.dev)->gtt.mappable_end); + to_i915(obj->base.dev)->ggtt.mappable_end); obj->map_and_fenceable = mappable && fenceable; } diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 6627bbe9ea24..394e525e55f1 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -945,7 +945,7 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data, else if (to_i915(dev)->mm.aliasing_ppgtt) args->value = to_i915(dev)->mm.aliasing_ppgtt->base.total; else - args->value = to_i915(dev)->gtt.base.total; + args->value = to_i915(dev)->ggtt.base.total; break; default: ret = -EINVAL; diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index dac01ee8cfa3..374a0cb7a092 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -330,7 +330,7 @@ relocate_entry_gtt(struct drm_i915_gem_object *obj, /* Map the page containing the relocation we're going to perform. */ offset = i915_gem_obj_ggtt_offset(obj); offset += reloc->offset; - reloc_page = io_mapping_map_atomic_wc(dev_priv->gtt.mappable, + reloc_page = io_mapping_map_atomic_wc(dev_priv->ggtt.mappable, offset & PAGE_MASK); iowrite32(lower_32_bits(delta), reloc_page + offset_in_page(offset)); @@ -340,7 +340,7 @@ relocate_entry_gtt(struct drm_i915_gem_object *obj, if (offset_in_page(offset) == 0) { io_mapping_unmap_atomic(reloc_page); reloc_page = - io_mapping_map_atomic_wc(dev_priv->gtt.mappable, + io_mapping_map_atomic_wc(dev_priv->ggtt.mappable, offset); } @@ -1504,7 +1504,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, if (ctx->ppgtt) vm = &ctx->ppgtt->base; else - vm = &dev_priv->gtt.base; + vm = &dev_priv->ggtt.base; memset(¶ms_master, 0x00, sizeof(params_master)); diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index be204076f8dc..41b4606293d1 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1637,7 +1637,7 @@ static void gen6_write_page_range(struct drm_i915_private *dev_priv, /* Make sure write is complete before other code can use this page * table. Also require for WC mapped PTEs */ - readl(dev_priv->gtt.gsm); + readl(dev_priv->ggtt.gsm); } static uint32_t get_pd_offset(struct i915_hw_ppgtt *ppgtt) @@ -1932,7 +1932,7 @@ static int gen6_alloc_va_range(struct i915_address_space *vm, /* Make sure write is complete before other code can use this page * table. Also require for WC mapped PTEs */ - readl(dev_priv->gtt.gsm); + readl(dev_priv->ggtt.gsm); mark_tlbs_dirty(ppgtt); return 0; @@ -2005,23 +2005,23 @@ static int gen6_ppgtt_allocate_page_directories(struct i915_hw_ppgtt *ppgtt) * allocator works in address space sizes, so it's multiplied by page * size. We allocate at the top of the GTT to avoid fragmentation. */ - BUG_ON(!drm_mm_initialized(&dev_priv->gtt.base.mm)); + BUG_ON(!drm_mm_initialized(&dev_priv->ggtt.base.mm)); ret = gen6_init_scratch(vm); if (ret) return ret; alloc: - ret = drm_mm_insert_node_in_range_generic(&dev_priv->gtt.base.mm, + ret = drm_mm_insert_node_in_range_generic(&dev_priv->ggtt.base.mm, &ppgtt->node, GEN6_PD_SIZE, GEN6_PD_ALIGN, 0, - 0, dev_priv->gtt.base.total, + 0, dev_priv->ggtt.base.total, DRM_MM_TOPDOWN); if (ret == -ENOSPC && !retried) { - ret = i915_gem_evict_something(dev, &dev_priv->gtt.base, + ret = i915_gem_evict_something(dev, &dev_priv->ggtt.base, GEN6_PD_SIZE, GEN6_PD_ALIGN, I915_CACHE_NONE, - 0, dev_priv->gtt.base.total, + 0, dev_priv->ggtt.base.total, 0); if (ret) goto err_out; @@ -2034,7 +2034,7 @@ alloc: goto err_out; - if (ppgtt->node.start < dev_priv->gtt.mappable_end) + if (ppgtt->node.start < dev_priv->ggtt.mappable_end) DRM_DEBUG("Forced to use aperture for PDEs\n"); return 0; @@ -2065,7 +2065,7 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) struct drm_i915_private *dev_priv = dev->dev_private; int ret; - ppgtt->base.pte_encode = dev_priv->gtt.base.pte_encode; + ppgtt->base.pte_encode = dev_priv->ggtt.base.pte_encode; if (IS_GEN6(dev)) { ppgtt->switch_mm = gen6_mm_switch; } else if (IS_HASWELL(dev)) { @@ -2095,7 +2095,7 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) ppgtt->pd.base.ggtt_offset = ppgtt->node.start / PAGE_SIZE * sizeof(gen6_pte_t); - ppgtt->pd_addr = (gen6_pte_t __iomem *)dev_priv->gtt.gsm + + ppgtt->pd_addr = (gen6_pte_t __iomem *)dev_priv->ggtt.gsm + ppgtt->pd.base.ggtt_offset / sizeof(gen6_pte_t); gen6_scratch_va_range(ppgtt, 0, ppgtt->base.total); @@ -2265,7 +2265,7 @@ static bool do_idling(struct drm_i915_private *dev_priv) { bool ret = dev_priv->mm.interruptible; - if (unlikely(dev_priv->gtt.do_idle_maps)) { + if (unlikely(dev_priv->ggtt.do_idle_maps)) { dev_priv->mm.interruptible = false; if (i915_gpu_idle(dev_priv->dev)) { DRM_ERROR("Couldn't idle GPU\n"); @@ -2279,7 +2279,7 @@ static bool do_idling(struct drm_i915_private *dev_priv) static void undo_idling(struct drm_i915_private *dev_priv, bool interruptible) { - if (unlikely(dev_priv->gtt.do_idle_maps)) + if (unlikely(dev_priv->ggtt.do_idle_maps)) dev_priv->mm.interruptible = interruptible; } @@ -2334,9 +2334,9 @@ void i915_gem_suspend_gtt_mappings(struct drm_device *dev) i915_check_and_clear_faults(dev); - dev_priv->gtt.base.clear_range(&dev_priv->gtt.base, - dev_priv->gtt.base.start, - dev_priv->gtt.base.total, + dev_priv->ggtt.base.clear_range(&dev_priv->ggtt.base, + dev_priv->ggtt.base.start, + dev_priv->ggtt.base.total, true); i915_ggtt_flush(dev_priv); @@ -2370,7 +2370,7 @@ static void gen8_ggtt_insert_entries(struct i915_address_space *vm, struct drm_i915_private *dev_priv = vm->dev->dev_private; unsigned first_entry = start >> PAGE_SHIFT; gen8_pte_t __iomem *gtt_entries = - (gen8_pte_t __iomem *)dev_priv->gtt.gsm + first_entry; + (gen8_pte_t __iomem *)dev_priv->ggtt.gsm + first_entry; int i = 0; struct sg_page_iter sg_iter; dma_addr_t addr = 0; /* shut up gcc */ @@ -2447,7 +2447,7 @@ static void gen6_ggtt_insert_entries(struct i915_address_space *vm, struct drm_i915_private *dev_priv = vm->dev->dev_private; unsigned first_entry = start >> PAGE_SHIFT; gen6_pte_t __iomem *gtt_entries = - (gen6_pte_t __iomem *)dev_priv->gtt.gsm + first_entry; + (gen6_pte_t __iomem *)dev_priv->ggtt.gsm + first_entry; int i = 0; struct sg_page_iter sg_iter; dma_addr_t addr = 0; @@ -2491,8 +2491,8 @@ static void gen8_ggtt_clear_range(struct i915_address_space *vm, unsigned first_entry = start >> PAGE_SHIFT; unsigned num_entries = length >> PAGE_SHIFT; gen8_pte_t scratch_pte, __iomem *gtt_base = - (gen8_pte_t __iomem *) dev_priv->gtt.gsm + first_entry; - const int max_entries = gtt_total_entries(dev_priv->gtt) - first_entry; + (gen8_pte_t __iomem *) dev_priv->ggtt.gsm + first_entry; + const int max_entries = gtt_total_entries(dev_priv->ggtt) - first_entry; int i; int rpm_atomic_seq; @@ -2522,8 +2522,8 @@ static void gen6_ggtt_clear_range(struct i915_address_space *vm, unsigned first_entry = start >> PAGE_SHIFT; unsigned num_entries = length >> PAGE_SHIFT; gen6_pte_t scratch_pte, __iomem *gtt_base = - (gen6_pte_t __iomem *) dev_priv->gtt.gsm + first_entry; - const int max_entries = gtt_total_entries(dev_priv->gtt) - first_entry; + (gen6_pte_t __iomem *) dev_priv->ggtt.gsm + first_entry; + const int max_entries = gtt_total_entries(dev_priv->ggtt) - first_entry; int i; int rpm_atomic_seq; @@ -2718,7 +2718,7 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev, * of the aperture. */ struct drm_i915_private *dev_priv = dev->dev_private; - struct i915_address_space *ggtt_vm = &dev_priv->gtt.base; + struct i915_address_space *ggtt_vm = &dev_priv->ggtt.base; struct drm_mm_node *entry; struct drm_i915_gem_object *obj; unsigned long hole_start, hole_end; @@ -2801,8 +2801,8 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev, true); dev_priv->mm.aliasing_ppgtt = ppgtt; - WARN_ON(dev_priv->gtt.base.bind_vma != ggtt_bind_vma); - dev_priv->gtt.base.bind_vma = aliasing_gtt_bind_vma; + WARN_ON(dev_priv->ggtt.base.bind_vma != ggtt_bind_vma); + dev_priv->ggtt.base.bind_vma = aliasing_gtt_bind_vma; } return 0; @@ -2813,8 +2813,8 @@ void i915_gem_init_global_gtt(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; u64 gtt_size, mappable_size; - gtt_size = dev_priv->gtt.base.total; - mappable_size = dev_priv->gtt.mappable_end; + gtt_size = dev_priv->ggtt.base.total; + mappable_size = dev_priv->ggtt.mappable_end; i915_gem_setup_global_gtt(dev, 0, mappable_size, gtt_size); } @@ -2822,7 +2822,7 @@ void i915_gem_init_global_gtt(struct drm_device *dev) void i915_global_gtt_cleanup(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct i915_address_space *vm = &dev_priv->gtt.base; + struct i915_address_space *vm = &dev_priv->ggtt.base; if (dev_priv->mm.aliasing_ppgtt) { struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; @@ -2940,10 +2940,10 @@ static int ggtt_probe_common(struct drm_device *dev, * readback check when writing GTT PTE entries. */ if (IS_BROXTON(dev)) - dev_priv->gtt.gsm = ioremap_nocache(gtt_phys_addr, gtt_size); + dev_priv->ggtt.gsm = ioremap_nocache(gtt_phys_addr, gtt_size); else - dev_priv->gtt.gsm = ioremap_wc(gtt_phys_addr, gtt_size); - if (!dev_priv->gtt.gsm) { + dev_priv->ggtt.gsm = ioremap_wc(gtt_phys_addr, gtt_size); + if (!dev_priv->ggtt.gsm) { DRM_ERROR("Failed to map the gtt page table\n"); return -ENOMEM; } @@ -2952,11 +2952,11 @@ static int ggtt_probe_common(struct drm_device *dev, if (IS_ERR(scratch_page)) { DRM_ERROR("Scratch setup failed\n"); /* iounmap will also get called at remove, but meh */ - iounmap(dev_priv->gtt.gsm); + iounmap(dev_priv->ggtt.gsm); return PTR_ERR(scratch_page); } - dev_priv->gtt.base.scratch_page = scratch_page; + dev_priv->ggtt.base.scratch_page = scratch_page; return 0; } @@ -3074,13 +3074,13 @@ static int gen8_gmch_probe(struct drm_device *dev, ret = ggtt_probe_common(dev, gtt_size); - dev_priv->gtt.base.clear_range = gen8_ggtt_clear_range; - dev_priv->gtt.base.insert_entries = gen8_ggtt_insert_entries; - dev_priv->gtt.base.bind_vma = ggtt_bind_vma; - dev_priv->gtt.base.unbind_vma = ggtt_unbind_vma; + dev_priv->ggtt.base.clear_range = gen8_ggtt_clear_range; + dev_priv->ggtt.base.insert_entries = gen8_ggtt_insert_entries; + dev_priv->ggtt.base.bind_vma = ggtt_bind_vma; + dev_priv->ggtt.base.unbind_vma = ggtt_unbind_vma; if (IS_CHERRYVIEW(dev_priv)) - dev_priv->gtt.base.insert_entries = gen8_ggtt_insert_entries__BKL; + dev_priv->ggtt.base.insert_entries = gen8_ggtt_insert_entries__BKL; return ret; } @@ -3118,20 +3118,19 @@ static int gen6_gmch_probe(struct drm_device *dev, ret = ggtt_probe_common(dev, gtt_size); - dev_priv->gtt.base.clear_range = gen6_ggtt_clear_range; - dev_priv->gtt.base.insert_entries = gen6_ggtt_insert_entries; - dev_priv->gtt.base.bind_vma = ggtt_bind_vma; - dev_priv->gtt.base.unbind_vma = ggtt_unbind_vma; + dev_priv->ggtt.base.clear_range = gen6_ggtt_clear_range; + dev_priv->ggtt.base.insert_entries = gen6_ggtt_insert_entries; + dev_priv->ggtt.base.bind_vma = ggtt_bind_vma; + dev_priv->ggtt.base.unbind_vma = ggtt_unbind_vma; return ret; } static void gen6_gmch_remove(struct i915_address_space *vm) { + struct i915_ggtt *ggtt = container_of(vm, struct i915_ggtt, base); - struct i915_gtt *gtt = container_of(vm, struct i915_gtt, base); - - iounmap(gtt->gsm); + iounmap(ggtt->gsm); free_scratch_page(vm->dev, vm->scratch_page); } @@ -3152,13 +3151,13 @@ static int i915_gmch_probe(struct drm_device *dev, intel_gtt_get(gtt_total, stolen, mappable_base, mappable_end); - dev_priv->gtt.do_idle_maps = needs_idle_maps(dev_priv->dev); - dev_priv->gtt.base.insert_entries = i915_ggtt_insert_entries; - dev_priv->gtt.base.clear_range = i915_ggtt_clear_range; - dev_priv->gtt.base.bind_vma = ggtt_bind_vma; - dev_priv->gtt.base.unbind_vma = ggtt_unbind_vma; + dev_priv->ggtt.do_idle_maps = needs_idle_maps(dev_priv->dev); + dev_priv->ggtt.base.insert_entries = i915_ggtt_insert_entries; + dev_priv->ggtt.base.clear_range = i915_ggtt_clear_range; + dev_priv->ggtt.base.bind_vma = ggtt_bind_vma; + dev_priv->ggtt.base.unbind_vma = ggtt_unbind_vma; - if (unlikely(dev_priv->gtt.do_idle_maps)) + if (unlikely(dev_priv->ggtt.do_idle_maps)) DRM_INFO("applying Ironlake quirks for intel_iommu\n"); return 0; @@ -3172,35 +3171,35 @@ static void i915_gmch_remove(struct i915_address_space *vm) int i915_gem_gtt_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct i915_gtt *gtt = &dev_priv->gtt; + struct i915_ggtt *ggtt = &dev_priv->ggtt; int ret; if (INTEL_INFO(dev)->gen <= 5) { - gtt->gtt_probe = i915_gmch_probe; - gtt->base.cleanup = i915_gmch_remove; + ggtt->probe = i915_gmch_probe; + ggtt->base.cleanup = i915_gmch_remove; } else if (INTEL_INFO(dev)->gen < 8) { - gtt->gtt_probe = gen6_gmch_probe; - gtt->base.cleanup = gen6_gmch_remove; + ggtt->probe = gen6_gmch_probe; + ggtt->base.cleanup = gen6_gmch_remove; if (IS_HASWELL(dev) && dev_priv->ellc_size) - gtt->base.pte_encode = iris_pte_encode; + ggtt->base.pte_encode = iris_pte_encode; else if (IS_HASWELL(dev)) - gtt->base.pte_encode = hsw_pte_encode; + ggtt->base.pte_encode = hsw_pte_encode; else if (IS_VALLEYVIEW(dev)) - gtt->base.pte_encode = byt_pte_encode; + ggtt->base.pte_encode = byt_pte_encode; else if (INTEL_INFO(dev)->gen >= 7) - gtt->base.pte_encode = ivb_pte_encode; + ggtt->base.pte_encode = ivb_pte_encode; else - gtt->base.pte_encode = snb_pte_encode; + ggtt->base.pte_encode = snb_pte_encode; } else { - dev_priv->gtt.gtt_probe = gen8_gmch_probe; - dev_priv->gtt.base.cleanup = gen6_gmch_remove; + ggtt->probe = gen8_gmch_probe; + ggtt->base.cleanup = gen6_gmch_remove; } - gtt->base.dev = dev; - gtt->base.is_ggtt = true; + ggtt->base.dev = dev; + ggtt->base.is_ggtt = true; - ret = gtt->gtt_probe(dev, >t->base.total, >t->stolen_size, - >t->mappable_base, >t->mappable_end); + ret = ggtt->probe(dev, &ggtt->base.total, &ggtt->stolen_size, + &ggtt->mappable_base, &ggtt->mappable_end); if (ret) return ret; @@ -3214,9 +3213,9 @@ int i915_gem_gtt_init(struct drm_device *dev) /* GMADR is the PCI mmio aperture into the global GTT. */ DRM_INFO("Memory usable by graphics device = %lluM\n", - gtt->base.total >> 20); - DRM_DEBUG_DRIVER("GMADR size = %lldM\n", gtt->mappable_end >> 20); - DRM_DEBUG_DRIVER("GTT stolen size = %zdM\n", gtt->stolen_size >> 20); + ggtt->base.total >> 20); + DRM_DEBUG_DRIVER("GMADR size = %lldM\n", ggtt->mappable_end >> 20); + DRM_DEBUG_DRIVER("GTT stolen size = %zdM\n", ggtt->stolen_size >> 20); #ifdef CONFIG_INTEL_IOMMU if (intel_iommu_gfx_mapped) DRM_INFO("VT-d active for gfx access\n"); @@ -3233,7 +3232,7 @@ int i915_gem_gtt_init(struct drm_device *dev) return 0; out_gtt_cleanup: - gtt->base.cleanup(&dev_priv->gtt.base); + ggtt->base.cleanup(&dev_priv->ggtt.base); return ret; } @@ -3249,13 +3248,13 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev) i915_check_and_clear_faults(dev); /* First fill our portion of the GTT with scratch pages */ - dev_priv->gtt.base.clear_range(&dev_priv->gtt.base, - dev_priv->gtt.base.start, - dev_priv->gtt.base.total, + dev_priv->ggtt.base.clear_range(&dev_priv->ggtt.base, + dev_priv->ggtt.base.start, + dev_priv->ggtt.base.total, true); /* Cache flush objects bound into GGTT and rebind them. */ - vm = &dev_priv->gtt.base; + vm = &dev_priv->ggtt.base; list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { flush = false; list_for_each_entry(vma, &obj->vma_list, obj_link) { diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index dc208c05cd2c..2906bb1ee290 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -339,7 +339,7 @@ struct i915_address_space { * and correct (in cases like swizzling). That region is referred to as GMADR in * the spec. */ -struct i915_gtt { +struct i915_ggtt { struct i915_address_space base; size_t stolen_size; /* Total size of stolen memory */ @@ -357,10 +357,9 @@ struct i915_gtt { int mtrr; - /* global gtt ops */ - int (*gtt_probe)(struct drm_device *dev, u64 *gtt_total, - size_t *stolen, phys_addr_t *mappable_base, - u64 *mappable_end); + int (*probe)(struct drm_device *dev, u64 *gtt_total, + size_t *stolen, phys_addr_t *mappable_base, + u64 *mappable_end); }; struct i915_hw_ppgtt { diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c index 2e6e9fb6f80d..de891c928b2f 100644 --- a/drivers/gpu/drm/i915/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c @@ -74,7 +74,7 @@ int i915_gem_stolen_insert_node(struct drm_i915_private *dev_priv, { return i915_gem_stolen_insert_node_in_range(dev_priv, node, size, alignment, 0, - dev_priv->gtt.stolen_usable_size); + dev_priv->ggtt.stolen_usable_size); } void i915_gem_stolen_remove_node(struct drm_i915_private *dev_priv, @@ -134,7 +134,7 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) I85X_DRB3, &tmp); tom = tmp * MB(32); - base = tom - tseg_size - dev_priv->gtt.stolen_size; + base = tom - tseg_size - dev_priv->ggtt.stolen_size; } else if (IS_845G(dev)) { u32 tseg_size = 0; u32 tom; @@ -158,7 +158,7 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) I830_DRB3, &tmp); tom = tmp * MB(32); - base = tom - tseg_size - dev_priv->gtt.stolen_size; + base = tom - tseg_size - dev_priv->ggtt.stolen_size; } else if (IS_I830(dev)) { u32 tseg_size = 0; u32 tom; @@ -178,7 +178,7 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) I830_DRB3, &tmp); tom = tmp * MB(32); - base = tom - tseg_size - dev_priv->gtt.stolen_size; + base = tom - tseg_size - dev_priv->ggtt.stolen_size; } if (base == 0) @@ -189,8 +189,8 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) struct { u32 start, end; } stolen[2] = { - { .start = base, .end = base + dev_priv->gtt.stolen_size, }, - { .start = base, .end = base + dev_priv->gtt.stolen_size, }, + { .start = base, .end = base + dev_priv->ggtt.stolen_size, }, + { .start = base, .end = base + dev_priv->ggtt.stolen_size, }, }; u64 gtt_start, gtt_end; @@ -200,7 +200,7 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) (gtt_start & PGTBL_ADDRESS_HI_MASK) << 28; else gtt_start &= PGTBL_ADDRESS_LO_MASK; - gtt_end = gtt_start + gtt_total_entries(dev_priv->gtt) * 4; + gtt_end = gtt_start + gtt_total_entries(dev_priv->ggtt) * 4; if (gtt_start >= stolen[0].start && gtt_start < stolen[0].end) stolen[0].end = gtt_start; @@ -211,10 +211,10 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) if (stolen[0].end - stolen[0].start > stolen[1].end - stolen[1].start) { base = stolen[0].start; - dev_priv->gtt.stolen_size = stolen[0].end - stolen[0].start; + dev_priv->ggtt.stolen_size = stolen[0].end - stolen[0].start; } else { base = stolen[1].start; - dev_priv->gtt.stolen_size = stolen[1].end - stolen[1].start; + dev_priv->ggtt.stolen_size = stolen[1].end - stolen[1].start; } if (stolen[0].start != stolen[1].start || @@ -223,7 +223,7 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) (unsigned long long) gtt_start, (unsigned long long) gtt_end - 1); DRM_DEBUG_KMS("Stolen memory adjusted to 0x%x-0x%x\n", - base, base + (u32) dev_priv->gtt.stolen_size - 1); + base, base + (u32) dev_priv->ggtt.stolen_size - 1); } } @@ -233,7 +233,7 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) * kernel. So if the region is already marked as busy, something * is seriously wrong. */ - r = devm_request_mem_region(dev->dev, base, dev_priv->gtt.stolen_size, + r = devm_request_mem_region(dev->dev, base, dev_priv->ggtt.stolen_size, "Graphics Stolen Memory"); if (r == NULL) { /* @@ -245,7 +245,7 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) * reservation starting from 1 instead of 0. */ r = devm_request_mem_region(dev->dev, base + 1, - dev_priv->gtt.stolen_size - 1, + dev_priv->ggtt.stolen_size - 1, "Graphics Stolen Memory"); /* * GEN3 firmware likes to smash pci bridges into the stolen @@ -253,7 +253,7 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) */ if (r == NULL && !IS_GEN3(dev)) { DRM_ERROR("conflict detected with stolen region: [0x%08x - 0x%08x]\n", - base, base + (uint32_t)dev_priv->gtt.stolen_size); + base, base + (uint32_t)dev_priv->ggtt.stolen_size); base = 0; } } @@ -278,7 +278,7 @@ static void g4x_get_stolen_reserved(struct drm_i915_private *dev_priv, CTG_STOLEN_RESERVED : ELK_STOLEN_RESERVED); unsigned long stolen_top = dev_priv->mm.stolen_base + - dev_priv->gtt.stolen_size; + dev_priv->ggtt.stolen_size; *base = (reg_val & G4X_STOLEN_RESERVED_ADDR2_MASK) << 16; @@ -372,7 +372,7 @@ static void bdw_get_stolen_reserved(struct drm_i915_private *dev_priv, uint32_t reg_val = I915_READ(GEN6_STOLEN_RESERVED); unsigned long stolen_top; - stolen_top = dev_priv->mm.stolen_base + dev_priv->gtt.stolen_size; + stolen_top = dev_priv->mm.stolen_base + dev_priv->ggtt.stolen_size; *base = reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK; @@ -401,14 +401,14 @@ int i915_gem_init_stolen(struct drm_device *dev) } #endif - if (dev_priv->gtt.stolen_size == 0) + if (dev_priv->ggtt.stolen_size == 0) return 0; dev_priv->mm.stolen_base = i915_stolen_to_physical(dev); if (dev_priv->mm.stolen_base == 0) return 0; - stolen_top = dev_priv->mm.stolen_base + dev_priv->gtt.stolen_size; + stolen_top = dev_priv->mm.stolen_base + dev_priv->ggtt.stolen_size; switch (INTEL_INFO(dev_priv)->gen) { case 2: @@ -458,18 +458,18 @@ int i915_gem_init_stolen(struct drm_device *dev) return 0; } - dev_priv->gtt.stolen_reserved_base = reserved_base; - dev_priv->gtt.stolen_reserved_size = reserved_size; + dev_priv->ggtt.stolen_reserved_base = reserved_base; + dev_priv->ggtt.stolen_reserved_size = reserved_size; /* It is possible for the reserved area to end before the end of stolen * memory, so just consider the start. */ reserved_total = stolen_top - reserved_base; DRM_DEBUG_KMS("Memory reserved for graphics device: %zuK, usable: %luK\n", - dev_priv->gtt.stolen_size >> 10, - (dev_priv->gtt.stolen_size - reserved_total) >> 10); + dev_priv->ggtt.stolen_size >> 10, + (dev_priv->ggtt.stolen_size - reserved_total) >> 10); - dev_priv->gtt.stolen_usable_size = dev_priv->gtt.stolen_size - + dev_priv->ggtt.stolen_usable_size = dev_priv->ggtt.stolen_size - reserved_total; /* @@ -483,7 +483,7 @@ int i915_gem_init_stolen(struct drm_device *dev) * i915_gem_stolen_insert_node_in_range(). We may want to fix the fbcon * problem later. */ - drm_mm_init(&dev_priv->mm.stolen, 0, dev_priv->gtt.stolen_usable_size); + drm_mm_init(&dev_priv->mm.stolen, 0, dev_priv->ggtt.stolen_usable_size); return 0; } @@ -497,7 +497,7 @@ i915_pages_create_for_stolen(struct drm_device *dev, struct scatterlist *sg; DRM_DEBUG_DRIVER("offset=0x%x, size=%d\n", offset, size); - BUG_ON(offset > dev_priv->gtt.stolen_size - size); + BUG_ON(offset > dev_priv->ggtt.stolen_size - size); /* We hide that we have no struct page backing our stolen object * by wrapping the contiguous physical allocation with a fake @@ -629,7 +629,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, u32 size) { struct drm_i915_private *dev_priv = dev->dev_private; - struct i915_address_space *ggtt = &dev_priv->gtt.base; + struct i915_address_space *ggtt = &dev_priv->ggtt.base; struct drm_i915_gem_object *obj; struct drm_mm_node *stolen; struct i915_vma *vma; diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 34397a67b09e..db8600ae5a54 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -653,7 +653,7 @@ i915_error_object_create(struct drm_i915_private *dev_priv, vma = i915_gem_obj_to_ggtt(src); use_ggtt = (src->cache_level == I915_CACHE_NONE && vma && (vma->bound & GLOBAL_BIND) && - reloc_offset + num_pages * PAGE_SIZE <= dev_priv->gtt.mappable_end); + reloc_offset + num_pages * PAGE_SIZE <= dev_priv->ggtt.mappable_end); /* Cannot access stolen address directly, try to use the aperture */ if (src->stolen) { @@ -663,7 +663,7 @@ i915_error_object_create(struct drm_i915_private *dev_priv, goto unwind; reloc_offset = i915_gem_obj_ggtt_offset(src); - if (reloc_offset + num_pages * PAGE_SIZE > dev_priv->gtt.mappable_end) + if (reloc_offset + num_pages * PAGE_SIZE > dev_priv->ggtt.mappable_end) goto unwind; } @@ -689,7 +689,7 @@ i915_error_object_create(struct drm_i915_private *dev_priv, * captures what the GPU read. */ - s = io_mapping_map_atomic_wc(dev_priv->gtt.mappable, + s = io_mapping_map_atomic_wc(dev_priv->ggtt.mappable, reloc_offset); memcpy_fromio(d, s, PAGE_SIZE); io_mapping_unmap_atomic(s); @@ -722,7 +722,7 @@ unwind: return NULL; } #define i915_error_ggtt_object_create(dev_priv, src) \ - i915_error_object_create((dev_priv), (src), &(dev_priv)->gtt.base) + i915_error_object_create((dev_priv), (src), &(dev_priv)->ggtt.base) static void capture_bo(struct drm_i915_error_buffer *err, struct i915_vma *vma) @@ -1038,7 +1038,7 @@ static void i915_gem_record_rings(struct drm_device *dev, vm = request->ctx && request->ctx->ppgtt ? &request->ctx->ppgtt->base : - &dev_priv->gtt.base; + &dev_priv->ggtt.base; /* We need to copy these to an anonymous buffer * as the simplest method to avoid being overwritten diff --git a/drivers/gpu/drm/i915/i915_vgpu.c b/drivers/gpu/drm/i915/i915_vgpu.c index dea7429be4d0..2891bcfcd71e 100644 --- a/drivers/gpu/drm/i915/i915_vgpu.c +++ b/drivers/gpu/drm/i915/i915_vgpu.c @@ -181,7 +181,7 @@ static int vgt_balloon_space(struct drm_mm *mm, int intel_vgt_balloon(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); - struct i915_address_space *ggtt_vm = &dev_priv->gtt.base; + struct i915_address_space *ggtt_vm = &dev_priv->ggtt.base; unsigned long ggtt_vm_end = ggtt_vm->start + ggtt_vm->total; unsigned long mappable_base, mappable_size, mappable_end; @@ -203,18 +203,18 @@ int intel_vgt_balloon(struct drm_device *dev) unmappable_base, unmappable_size / 1024); if (mappable_base < ggtt_vm->start || - mappable_end > dev_priv->gtt.mappable_end || - unmappable_base < dev_priv->gtt.mappable_end || + mappable_end > dev_priv->ggtt.mappable_end || + unmappable_base < dev_priv->ggtt.mappable_end || unmappable_end > ggtt_vm_end) { DRM_ERROR("Invalid ballooning configuration!\n"); return -EINVAL; } /* Unmappable graphic memory ballooning */ - if (unmappable_base > dev_priv->gtt.mappable_end) { + if (unmappable_base > dev_priv->ggtt.mappable_end) { ret = vgt_balloon_space(&ggtt_vm->mm, &bl_info.space[2], - dev_priv->gtt.mappable_end, + dev_priv->ggtt.mappable_end, unmappable_base); if (ret) @@ -244,11 +244,11 @@ int intel_vgt_balloon(struct drm_device *dev) goto err; } - if (mappable_end < dev_priv->gtt.mappable_end) { + if (mappable_end < dev_priv->ggtt.mappable_end) { ret = vgt_balloon_space(&ggtt_vm->mm, &bl_info.space[1], mappable_end, - dev_priv->gtt.mappable_end); + dev_priv->ggtt.mappable_end); if (ret) goto err; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ab1ec8daae92..74b0165238dc 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2503,7 +2503,7 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc, /* If the FB is too big, just don't use it since fbdev is not very * important and we should probably use that space with FBC or other * features. */ - if (size_aligned * 2 > dev_priv->gtt.stolen_usable_size) + if (size_aligned * 2 > dev_priv->ggtt.stolen_usable_size) return false; mutex_lock(&dev->struct_mutex); @@ -15339,7 +15339,7 @@ void intel_modeset_init(struct drm_device *dev) dev->mode_config.cursor_height = MAX_CURSOR_HEIGHT; } - dev->mode_config.fb_base = dev_priv->gtt.mappable_base; + dev->mode_config.fb_base = dev_priv->ggtt.mappable_base; DRM_DEBUG_KMS("%d display pipe%s available.\n", INTEL_INFO(dev)->num_pipes, diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 0f0492f4a357..2e571f5f3b22 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -516,9 +516,9 @@ static int find_compression_threshold(struct drm_i915_private *dev_priv, * underruns, even if that range is not reserved by the BIOS. */ if (IS_BROADWELL(dev_priv) || IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) - end = dev_priv->gtt.stolen_size - 8 * 1024 * 1024; + end = dev_priv->ggtt.stolen_size - 8 * 1024 * 1024; else - end = dev_priv->gtt.stolen_usable_size; + end = dev_priv->ggtt.stolen_usable_size; /* HACK: This code depends on what we will do in *_enable_fbc. If that * code changes, this code needs to change as well. diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index ae9cf6fcb870..ea4188ac2e73 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -146,7 +146,7 @@ static int intelfb_alloc(struct drm_fb_helper *helper, /* If the FB is too big, just don't use it since fbdev is not very * important and we should probably use that space with FBC or other * features. */ - if (size * 2 < dev_priv->gtt.stolen_usable_size) + if (size * 2 < dev_priv->ggtt.stolen_usable_size) obj = i915_gem_object_create_stolen(dev, size); if (obj == NULL) obj = i915_gem_alloc_object(dev, size); @@ -244,13 +244,13 @@ static int intelfb_create(struct drm_fb_helper *helper, /* setup aperture base/size for vesafb takeover */ info->apertures->ranges[0].base = dev->mode_config.fb_base; - info->apertures->ranges[0].size = dev_priv->gtt.mappable_end; + info->apertures->ranges[0].size = dev_priv->ggtt.mappable_end; info->fix.smem_start = dev->mode_config.fb_base + i915_gem_obj_ggtt_offset(obj); info->fix.smem_len = size; info->screen_base = - ioremap_wc(dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(obj), + ioremap_wc(dev_priv->ggtt.mappable_base + i915_gem_obj_ggtt_offset(obj), size); if (!info->screen_base) { DRM_ERROR("Failed to remap framebuffer into virtual memory\n"); diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 13e22f52666c..e1acb41f187a 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -196,7 +196,7 @@ intel_overlay_map_regs(struct intel_overlay *overlay) if (OVERLAY_NEEDS_PHYSICAL(overlay->dev)) regs = (struct overlay_registers __iomem *)overlay->reg_bo->phys_handle->vaddr; else - regs = io_mapping_map_wc(dev_priv->gtt.mappable, + regs = io_mapping_map_wc(dev_priv->ggtt.mappable, i915_gem_obj_ggtt_offset(overlay->reg_bo)); return regs; @@ -1490,7 +1490,7 @@ intel_overlay_map_regs_atomic(struct intel_overlay *overlay) regs = (struct overlay_registers __iomem *) overlay->reg_bo->phys_handle->vaddr; else - regs = io_mapping_map_atomic_wc(dev_priv->gtt.mappable, + regs = io_mapping_map_atomic_wc(dev_priv->ggtt.mappable, i915_gem_obj_ggtt_offset(overlay->reg_bo)); return regs; diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index a539fbc0c051..521cf4564329 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4644,9 +4644,9 @@ static bool bxt_check_bios_rc6_setup(const struct drm_device *dev) * for this check. */ rc6_ctx_base = I915_READ(RC6_CTX_BASE) & RC6_CTX_BASE_MASK; - if (!((rc6_ctx_base >= dev_priv->gtt.stolen_reserved_base) && - (rc6_ctx_base + PAGE_SIZE <= dev_priv->gtt.stolen_reserved_base + - dev_priv->gtt.stolen_reserved_size))) { + if (!((rc6_ctx_base >= dev_priv->ggtt.stolen_reserved_base) && + (rc6_ctx_base + PAGE_SIZE <= dev_priv->ggtt.stolen_reserved_base + + dev_priv->ggtt.stolen_reserved_size))) { DRM_DEBUG_KMS("RC6 Base address not as expected.\n"); enable_rc6 = false; } @@ -5291,7 +5291,7 @@ static void cherryview_setup_pctx(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; unsigned long pctx_paddr, paddr; - struct i915_gtt *gtt = &dev_priv->gtt; + struct i915_ggtt *ggtt = &dev_priv->ggtt; u32 pcbr; int pctx_size = 32*1024; @@ -5299,7 +5299,7 @@ static void cherryview_setup_pctx(struct drm_device *dev) if ((pcbr >> VLV_PCBR_ADDR_SHIFT) == 0) { DRM_DEBUG_DRIVER("BIOS didn't set up PCBR, fixing up\n"); paddr = (dev_priv->mm.stolen_base + - (gtt->stolen_size - pctx_size)); + (ggtt->stolen_size - pctx_size)); pctx_paddr = (paddr & (~4095)); I915_WRITE(VLV_PCBR, pctx_paddr); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 9c59ede5dd9a..df0ef5bba8e5 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -2136,7 +2136,7 @@ int intel_pin_and_map_ringbuffer_obj(struct drm_device *dev, /* Access through the GTT requires the device to be awake. */ assert_rpm_wakelock_held(dev_priv); - ringbuf->virtual_start = ioremap_wc(dev_priv->gtt.mappable_base + + ringbuf->virtual_start = ioremap_wc(dev_priv->ggtt.mappable_base + i915_gem_obj_ggtt_offset(obj), ringbuf->size); if (ringbuf->virtual_start == NULL) { i915_gem_object_ggtt_unpin(obj); -- cgit v1.2.3 From d507d73578ef7aa1ffcd122e51caa59e4492cb46 Mon Sep 17 00:00:00 2001 From: Joonas Lahtinen Date: Fri, 18 Mar 2016 10:42:58 +0200 Subject: drm/i915/gtt: Clean up GGTT probing code Use less pointers with the probing code, making it much less confusing to read. Cc: Mika Kuoppala Reviewed-by: Chris Wilson Signed-off-by: Joonas Lahtinen --- drivers/gpu/drm/i915/i915_gem_gtt.c | 100 ++++++++++++++++-------------------- drivers/gpu/drm/i915/i915_gem_gtt.h | 5 +- 2 files changed, 46 insertions(+), 59 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 41b4606293d1..799576e13f65 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -3034,20 +3034,16 @@ static void chv_setup_private_ppat(struct drm_i915_private *dev_priv) I915_WRITE(GEN8_PRIVATE_PAT_HI, pat >> 32); } -static int gen8_gmch_probe(struct drm_device *dev, - u64 *gtt_total, - size_t *stolen, - phys_addr_t *mappable_base, - u64 *mappable_end) +static int gen8_gmch_probe(struct i915_ggtt *ggtt) { + struct drm_device *dev = ggtt->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - u64 gtt_size; u16 snb_gmch_ctl; int ret; /* TODO: We're not aware of mappable constraints on gen8 yet */ - *mappable_base = pci_resource_start(dev->pdev, 2); - *mappable_end = pci_resource_len(dev->pdev, 2); + ggtt->mappable_base = pci_resource_start(dev->pdev, 2); + ggtt->mappable_end = pci_resource_len(dev->pdev, 2); if (!pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(39))) pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(39)); @@ -3055,55 +3051,51 @@ static int gen8_gmch_probe(struct drm_device *dev, pci_read_config_word(dev->pdev, SNB_GMCH_CTRL, &snb_gmch_ctl); if (INTEL_INFO(dev)->gen >= 9) { - *stolen = gen9_get_stolen_size(snb_gmch_ctl); - gtt_size = gen8_get_total_gtt_size(snb_gmch_ctl); + ggtt->stolen_size = gen9_get_stolen_size(snb_gmch_ctl); + ggtt->size = gen8_get_total_gtt_size(snb_gmch_ctl); } else if (IS_CHERRYVIEW(dev)) { - *stolen = chv_get_stolen_size(snb_gmch_ctl); - gtt_size = chv_get_total_gtt_size(snb_gmch_ctl); + ggtt->stolen_size = chv_get_stolen_size(snb_gmch_ctl); + ggtt->size = chv_get_total_gtt_size(snb_gmch_ctl); } else { - *stolen = gen8_get_stolen_size(snb_gmch_ctl); - gtt_size = gen8_get_total_gtt_size(snb_gmch_ctl); + ggtt->stolen_size = gen8_get_stolen_size(snb_gmch_ctl); + ggtt->size = gen8_get_total_gtt_size(snb_gmch_ctl); } - *gtt_total = (gtt_size / sizeof(gen8_pte_t)) << PAGE_SHIFT; + ggtt->base.total = (ggtt->size / sizeof(gen8_pte_t)) << PAGE_SHIFT; if (IS_CHERRYVIEW(dev) || IS_BROXTON(dev)) chv_setup_private_ppat(dev_priv); else bdw_setup_private_ppat(dev_priv); - ret = ggtt_probe_common(dev, gtt_size); - - dev_priv->ggtt.base.clear_range = gen8_ggtt_clear_range; - dev_priv->ggtt.base.insert_entries = gen8_ggtt_insert_entries; - dev_priv->ggtt.base.bind_vma = ggtt_bind_vma; - dev_priv->ggtt.base.unbind_vma = ggtt_unbind_vma; + ret = ggtt_probe_common(dev, ggtt->size); + ggtt->base.clear_range = gen8_ggtt_clear_range; if (IS_CHERRYVIEW(dev_priv)) - dev_priv->ggtt.base.insert_entries = gen8_ggtt_insert_entries__BKL; + ggtt->base.insert_entries = gen8_ggtt_insert_entries__BKL; + else + ggtt->base.insert_entries = gen8_ggtt_insert_entries; + ggtt->base.bind_vma = ggtt_bind_vma; + ggtt->base.unbind_vma = ggtt_unbind_vma; + return ret; } -static int gen6_gmch_probe(struct drm_device *dev, - u64 *gtt_total, - size_t *stolen, - phys_addr_t *mappable_base, - u64 *mappable_end) +static int gen6_gmch_probe(struct i915_ggtt *ggtt) { - struct drm_i915_private *dev_priv = dev->dev_private; - unsigned int gtt_size; + struct drm_device *dev = ggtt->base.dev; u16 snb_gmch_ctl; int ret; - *mappable_base = pci_resource_start(dev->pdev, 2); - *mappable_end = pci_resource_len(dev->pdev, 2); + ggtt->mappable_base = pci_resource_start(dev->pdev, 2); + ggtt->mappable_end = pci_resource_len(dev->pdev, 2); /* 64/512MB is the current min/max we actually know of, but this is just * a coarse sanity check. */ - if ((*mappable_end < (64<<20) || (*mappable_end > (512<<20)))) { - DRM_ERROR("Unknown GMADR size (%llx)\n", *mappable_end); + if ((ggtt->mappable_end < (64<<20) || (ggtt->mappable_end > (512<<20)))) { + DRM_ERROR("Unknown GMADR size (%llx)\n", ggtt->mappable_end); return -ENXIO; } @@ -3111,17 +3103,16 @@ static int gen6_gmch_probe(struct drm_device *dev, pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(40)); pci_read_config_word(dev->pdev, SNB_GMCH_CTRL, &snb_gmch_ctl); - *stolen = gen6_get_stolen_size(snb_gmch_ctl); - - gtt_size = gen6_get_total_gtt_size(snb_gmch_ctl); - *gtt_total = (gtt_size / sizeof(gen6_pte_t)) << PAGE_SHIFT; + ggtt->stolen_size = gen6_get_stolen_size(snb_gmch_ctl); + ggtt->size = gen6_get_total_gtt_size(snb_gmch_ctl); + ggtt->base.total = (ggtt->size / sizeof(gen6_pte_t)) << PAGE_SHIFT; - ret = ggtt_probe_common(dev, gtt_size); + ret = ggtt_probe_common(dev, ggtt->size); - dev_priv->ggtt.base.clear_range = gen6_ggtt_clear_range; - dev_priv->ggtt.base.insert_entries = gen6_ggtt_insert_entries; - dev_priv->ggtt.base.bind_vma = ggtt_bind_vma; - dev_priv->ggtt.base.unbind_vma = ggtt_unbind_vma; + ggtt->base.clear_range = gen6_ggtt_clear_range; + ggtt->base.insert_entries = gen6_ggtt_insert_entries; + ggtt->base.bind_vma = ggtt_bind_vma; + ggtt->base.unbind_vma = ggtt_unbind_vma; return ret; } @@ -3134,12 +3125,9 @@ static void gen6_gmch_remove(struct i915_address_space *vm) free_scratch_page(vm->dev, vm->scratch_page); } -static int i915_gmch_probe(struct drm_device *dev, - u64 *gtt_total, - size_t *stolen, - phys_addr_t *mappable_base, - u64 *mappable_end) +static int i915_gmch_probe(struct i915_ggtt *ggtt) { + struct drm_device *dev = ggtt->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; int ret; @@ -3149,15 +3137,16 @@ static int i915_gmch_probe(struct drm_device *dev, return -EIO; } - intel_gtt_get(gtt_total, stolen, mappable_base, mappable_end); + intel_gtt_get(&ggtt->base.total, &ggtt->stolen_size, + &ggtt->mappable_base, &ggtt->mappable_end); - dev_priv->ggtt.do_idle_maps = needs_idle_maps(dev_priv->dev); - dev_priv->ggtt.base.insert_entries = i915_ggtt_insert_entries; - dev_priv->ggtt.base.clear_range = i915_ggtt_clear_range; - dev_priv->ggtt.base.bind_vma = ggtt_bind_vma; - dev_priv->ggtt.base.unbind_vma = ggtt_unbind_vma; + ggtt->do_idle_maps = needs_idle_maps(dev_priv->dev); + ggtt->base.insert_entries = i915_ggtt_insert_entries; + ggtt->base.clear_range = i915_ggtt_clear_range; + ggtt->base.bind_vma = ggtt_bind_vma; + ggtt->base.unbind_vma = ggtt_unbind_vma; - if (unlikely(dev_priv->ggtt.do_idle_maps)) + if (unlikely(ggtt->do_idle_maps)) DRM_INFO("applying Ironlake quirks for intel_iommu\n"); return 0; @@ -3198,8 +3187,7 @@ int i915_gem_gtt_init(struct drm_device *dev) ggtt->base.dev = dev; ggtt->base.is_ggtt = true; - ret = ggtt->probe(dev, &ggtt->base.total, &ggtt->stolen_size, - &ggtt->mappable_base, &ggtt->mappable_end); + ret = ggtt->probe(ggtt); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index 2906bb1ee290..d804be00ab41 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -346,6 +346,7 @@ struct i915_ggtt { size_t stolen_usable_size; /* Total size minus BIOS reserved */ size_t stolen_reserved_base; size_t stolen_reserved_size; + size_t size; /* Total size of Global GTT */ u64 mappable_end; /* End offset that we can CPU map */ struct io_mapping *mappable; /* Mapping to our CPU mappable region */ phys_addr_t mappable_base; /* PA of our GMADR */ @@ -357,9 +358,7 @@ struct i915_ggtt { int mtrr; - int (*probe)(struct drm_device *dev, u64 *gtt_total, - size_t *stolen, phys_addr_t *mappable_base, - u64 *mappable_end); + int (*probe)(struct i915_ggtt *ggtt); }; struct i915_hw_ppgtt { -- cgit v1.2.3 From c890e2d5313e8e8f4fb54258dc2bbb2c7dd901ce Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 18 Mar 2016 10:42:59 +0200 Subject: drm/i915: Codify our assumption that the Global GTT is <= 4GiB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Throughout the code base, we use u32 for offsets into the global GTT. If we ever see any hardware with a larger GGTT, then we run the real risk of silent corruption. So test for our assumption up front so that we have a nice reminder should the time come when it fails. Signed-off-by: Chris Wilson Cc: Ville Syrjälä Cc: Daniel Vetter Signed-off-by: Joonas Lahtinen [Rebased and changed 1ull -> 1ULL, cut 80 char line] Reviewed-by: Tvrtko Ursulin Reviewed-by: Mika Kuoppala Link: http://patchwork.freedesktop.org/patch/msgid/1458290579-27783-1-git-send-email-joonas.lahtinen@linux.intel.com --- drivers/gpu/drm/i915/i915_gem_gtt.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 799576e13f65..0715bb74d306 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -3191,6 +3191,14 @@ int i915_gem_gtt_init(struct drm_device *dev) if (ret) return ret; + if ((ggtt->base.total - 1) >> 32) { + DRM_ERROR("We never expected a Global GTT with more than 32bits" + "of address space! Found %lldM!\n", + ggtt->base.total >> 20); + ggtt->base.total = 1ULL << 32; + ggtt->mappable_end = min(ggtt->mappable_end, ggtt->base.total); + } + /* * Initialise stolen early so that we may reserve preallocated * objects for the BIOS to KMS transition. -- cgit v1.2.3 From d15d7538c6d210b2a10df94d131b70b025ee9cd2 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 18 Mar 2016 10:46:10 +0200 Subject: drm/i915: Tune down init error message due to failure injection Atm, in case failure injection forces an error the subsequent "*ERROR* failed to init modeset" error message will make automated tests (CI) report this event as a breakage even though the event is expected. To fix this print the error message with debug log level in this case. While at it print the error message for any init failure and change it to """ Device initialization failed (errno) Please file a bug at https://bugs.freedesktop.org/enter_bug.cgi?product=DRI against DRM/Intel providing the dmesg log by booting with drm.debug=0xf """ and export a helper printing error messages using this same format. A follow-up patch will convert all uses of DRM_ERROR reporting a user facing problem to use this new helper instead. v2: - Include the problematic error message in the commit log, add a request to file an fdo bug to the message (Chris) v3: - Include the new error message too in the commit log, make the fdo link more precise and print part of the message with info log level (Chris) v4: (Chris) - Use dev_printk instead of DRM_ERROR/INFO and use NOTICE instead of INFO loglevel - Export a helper for printing user facing error messages v5: - Keep the DRM_ERROR message prefix used by piglit-igt/CI to filter relevant dmesg lines - Use dev_notice(), instead of dev_printk(KERN_NOTICE,...) v6: - Print the fdo bug link only once (Chris) CC: Chris Wilson Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1458290770-15480-1-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_dma.c | 51 +++++++++++++++++++++++++++++++++++++---- drivers/gpu/drm/i915/i915_drv.h | 7 ++++++ 2 files changed, 53 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 3565163d7b31..3f439a08387e 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -66,6 +66,47 @@ bool __i915_inject_load_failure(const char *func, int line) return false; } +#define FDO_BUG_URL "https://bugs.freedesktop.org/enter_bug.cgi?product=DRI" +#define FDO_BUG_MSG "Please file a bug at " FDO_BUG_URL " against DRM/Intel " \ + "providing the dmesg log by booting with drm.debug=0xf" + +void +__i915_printk(struct drm_i915_private *dev_priv, const char *level, + const char *fmt, ...) +{ + static bool shown_bug_once; + struct device *dev = dev_priv->dev->dev; + bool is_error = level[1] <= KERN_ERR[1]; + struct va_format vaf; + va_list args; + + va_start(args, fmt); + + vaf.fmt = fmt; + vaf.va = &args; + + dev_printk(level, dev, "[" DRM_NAME ":%ps] %pV", + __builtin_return_address(0), &vaf); + + if (is_error && !shown_bug_once) { + dev_notice(dev, "%s", FDO_BUG_MSG); + shown_bug_once = true; + } + + va_end(args); +} + +static bool i915_error_injected(struct drm_i915_private *dev_priv) +{ + return i915.inject_load_failure && + i915_load_fail_count == i915.inject_load_failure; +} + +#define i915_load_error(dev_priv, fmt, ...) \ + __i915_printk(dev_priv, \ + i915_error_injected(dev_priv) ? KERN_DEBUG : KERN_ERR, \ + fmt, ##__VA_ARGS__) + static int i915_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv) { @@ -972,8 +1013,6 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv, if (i915_inject_load_failure()) return -ENODEV; - dev_priv->dev = dev; - /* Setup the write-once "constant" device info */ device_info = (struct intel_device_info *)&dev_priv->info; memcpy(device_info, info, sizeof(dev_priv->info)); @@ -1303,6 +1342,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) return -ENOMEM; dev->dev_private = dev_priv; + /* Must be set before calling __i915_printk */ + dev_priv->dev = dev; ret = i915_driver_init_early(dev_priv, dev, (struct intel_device_info *)flags); @@ -1332,10 +1373,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) } ret = i915_load_modeset_init(dev); - if (ret < 0) { - DRM_ERROR("failed to init modeset\n"); + if (ret < 0) goto out_cleanup_vblank; - } i915_driver_register(dev_priv); @@ -1357,6 +1396,8 @@ out_runtime_pm_put: out_free_priv: kfree(dev_priv); + i915_load_error(dev_priv, "Device initialization failed (%d)\n", ret); + return ret; } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b1d65540b48b..f330a53c19b9 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2696,6 +2696,13 @@ extern int i915_suspend_switcheroo(struct drm_device *dev, pm_message_t state); extern int i915_resume_switcheroo(struct drm_device *dev); /* i915_dma.c */ +void __printf(3, 4) +__i915_printk(struct drm_i915_private *dev_priv, const char *level, + const char *fmt, ...); + +#define i915_report_error(dev_priv, fmt, ...) \ + __i915_printk(dev_priv, KERN_ERR, fmt, ##__VA_ARGS__) + extern int i915_driver_load(struct drm_device *, unsigned long flags); extern int i915_driver_unload(struct drm_device *); extern int i915_driver_open(struct drm_device *dev, struct drm_file *file); -- cgit v1.2.3 From ddb851affbb8a669cdfe237745aaab7523a31919 Mon Sep 17 00:00:00 2001 From: Martin Kepplinger Date: Mon, 14 Mar 2016 12:33:14 +0100 Subject: iio: mma8452: add i2c_device_id for mma8451 This was forgotten about and is added for consistency now Signed-off-by: Martin Kepplinger Signed-off-by: Jonathan Cameron --- drivers/iio/accel/mma8452.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c index 305ed0e37dfb..6aa2517b4688 100644 --- a/drivers/iio/accel/mma8452.c +++ b/drivers/iio/accel/mma8452.c @@ -1535,6 +1535,7 @@ static const struct dev_pm_ops mma8452_pm_ops = { }; static const struct i2c_device_id mma8452_id[] = { + { "mma8451", mma8451 }, { "mma8452", mma8452 }, { "mma8453", mma8453 }, { "mma8652", mma8652 }, -- cgit v1.2.3 From bce59b602dace036b797144b1a5851318cbc85f0 Mon Sep 17 00:00:00 2001 From: Martin Kepplinger Date: Mon, 14 Mar 2016 12:26:29 +0100 Subject: iio: mma8452: use runtime pm instead of device specific autosleep What is this autosleep? ----------------------- It slows down the device after x seconds of inactivity. The thing is, we have really achieved almost the same by runtime pm. differnces are: autosleep * uses more power during inactivity * the first read after inactivity slightly faster * complicated to understand for the user * no documented sysfs interface (afaik) * complicated to read and maintain runtime pm * already merged in mma8452 * uses less power during inactivity * first read after inactivity slower * easy to use. well documented. * easy to maintain and understand The two approaches solve the same problem. runtime pm has more advantages than autosleep and comes quite close to it's behaviour anyways. As I see it, autosleep, even if somehow supported, would never be used anyways. So resolve this issue by "ignoring" autosleep. Signed-off-by: Martin Kepplinger Reviewed-by: Martina Kepplinger Signed-off-by: Jonathan Cameron --- drivers/iio/accel/mma8452.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c index 6aa2517b4688..e225d3c53bd5 100644 --- a/drivers/iio/accel/mma8452.c +++ b/drivers/iio/accel/mma8452.c @@ -17,7 +17,7 @@ * * 7-bit I2C slave address 0x1c/0x1d (pin selectable) * - * TODO: orientation events, autosleep + * TODO: orientation events */ #include -- cgit v1.2.3 From 722fc31663d506d668e6a3bea4e9dca8ab957d3a Mon Sep 17 00:00:00 2001 From: Alison Schofield Date: Tue, 15 Mar 2016 11:49:12 -0700 Subject: staging: iio: isl29028: use regmap to retrieve struct device Driver includes struct regmap and struct device in its global data. Remove the struct device and use regmap API to retrieve device info. Simplified version of Coccinelle semantic patch used: @ a @ identifier drvdata, r; position p; @@ struct drvdata@p { ... struct regmap *r; ... }; @ b @ identifier a.drvdata, d; position a.p; @@ struct drvdata@p { ... - struct device *d; ... }; @ passed depends on b @ identifier a.drvdata, a.r, b.d, i, f; @@ f (..., struct drvdata *i ,...) { + struct device *dev = regmap_get_device(i->r); <+... - i->d + dev ...+> } Signed-off-by: Alison Schofield Signed-off-by: Jonathan Cameron --- drivers/staging/iio/light/isl29028.c | 55 ++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/light/isl29028.c b/drivers/staging/iio/light/isl29028.c index 6e2ba458c24d..2e3b1d64e32a 100644 --- a/drivers/staging/iio/light/isl29028.c +++ b/drivers/staging/iio/light/isl29028.c @@ -69,7 +69,6 @@ enum als_ir_mode { }; struct isl29028_chip { - struct device *dev; struct mutex lock; struct regmap *regmap; @@ -166,20 +165,21 @@ static int isl29028_set_als_ir_mode(struct isl29028_chip *chip, static int isl29028_read_als_ir(struct isl29028_chip *chip, int *als_ir) { + struct device *dev = regmap_get_device(chip->regmap); unsigned int lsb; unsigned int msb; int ret; ret = regmap_read(chip->regmap, ISL29028_REG_ALSIR_L, &lsb); if (ret < 0) { - dev_err(chip->dev, + dev_err(dev, "Error in reading register ALSIR_L err %d\n", ret); return ret; } ret = regmap_read(chip->regmap, ISL29028_REG_ALSIR_U, &msb); if (ret < 0) { - dev_err(chip->dev, + dev_err(dev, "Error in reading register ALSIR_U err %d\n", ret); return ret; } @@ -190,12 +190,13 @@ static int isl29028_read_als_ir(struct isl29028_chip *chip, int *als_ir) static int isl29028_read_proxim(struct isl29028_chip *chip, int *prox) { + struct device *dev = regmap_get_device(chip->regmap); unsigned int data; int ret; ret = regmap_read(chip->regmap, ISL29028_REG_PROX_DATA, &data); if (ret < 0) { - dev_err(chip->dev, "Error in reading register %d, error %d\n", + dev_err(dev, "Error in reading register %d, error %d\n", ISL29028_REG_PROX_DATA, ret); return ret; } @@ -218,13 +219,14 @@ static int isl29028_proxim_get(struct isl29028_chip *chip, int *prox_data) static int isl29028_als_get(struct isl29028_chip *chip, int *als_data) { + struct device *dev = regmap_get_device(chip->regmap); int ret; int als_ir_data; if (chip->als_ir_mode != MODE_ALS) { ret = isl29028_set_als_ir_mode(chip, MODE_ALS); if (ret < 0) { - dev_err(chip->dev, + dev_err(dev, "Error in enabling ALS mode err %d\n", ret); return ret; } @@ -251,12 +253,13 @@ static int isl29028_als_get(struct isl29028_chip *chip, int *als_data) static int isl29028_ir_get(struct isl29028_chip *chip, int *ir_data) { + struct device *dev = regmap_get_device(chip->regmap); int ret; if (chip->als_ir_mode != MODE_IR) { ret = isl29028_set_als_ir_mode(chip, MODE_IR); if (ret < 0) { - dev_err(chip->dev, + dev_err(dev, "Error in enabling IR mode err %d\n", ret); return ret; } @@ -271,25 +274,26 @@ static int isl29028_write_raw(struct iio_dev *indio_dev, int val, int val2, long mask) { struct isl29028_chip *chip = iio_priv(indio_dev); + struct device *dev = regmap_get_device(chip->regmap); int ret = -EINVAL; mutex_lock(&chip->lock); switch (chan->type) { case IIO_PROXIMITY: if (mask != IIO_CHAN_INFO_SAMP_FREQ) { - dev_err(chip->dev, + dev_err(dev, "proximity: mask value 0x%08lx not supported\n", mask); break; } if (val < 1 || val > 100) { - dev_err(chip->dev, + dev_err(dev, "Samp_freq %d is not in range[1:100]\n", val); break; } ret = isl29028_set_proxim_sampling(chip, val); if (ret < 0) { - dev_err(chip->dev, + dev_err(dev, "Setting proximity samp_freq fail, err %d\n", ret); break; @@ -299,19 +303,19 @@ static int isl29028_write_raw(struct iio_dev *indio_dev, case IIO_LIGHT: if (mask != IIO_CHAN_INFO_SCALE) { - dev_err(chip->dev, + dev_err(dev, "light: mask value 0x%08lx not supported\n", mask); break; } if ((val != 125) && (val != 2000)) { - dev_err(chip->dev, + dev_err(dev, "lux scale %d is invalid [125, 2000]\n", val); break; } ret = isl29028_set_als_scale(chip, val); if (ret < 0) { - dev_err(chip->dev, + dev_err(dev, "Setting lux scale fail with error %d\n", ret); break; } @@ -319,7 +323,7 @@ static int isl29028_write_raw(struct iio_dev *indio_dev, break; default: - dev_err(chip->dev, "Unsupported channel type\n"); + dev_err(dev, "Unsupported channel type\n"); break; } mutex_unlock(&chip->lock); @@ -331,6 +335,7 @@ static int isl29028_read_raw(struct iio_dev *indio_dev, int *val, int *val2, long mask) { struct isl29028_chip *chip = iio_priv(indio_dev); + struct device *dev = regmap_get_device(chip->regmap); int ret = -EINVAL; mutex_lock(&chip->lock); @@ -370,7 +375,7 @@ static int isl29028_read_raw(struct iio_dev *indio_dev, break; default: - dev_err(chip->dev, "mask value 0x%08lx not supported\n", mask); + dev_err(dev, "mask value 0x%08lx not supported\n", mask); break; } mutex_unlock(&chip->lock); @@ -417,6 +422,7 @@ static const struct iio_info isl29028_info = { static int isl29028_chip_init(struct isl29028_chip *chip) { + struct device *dev = regmap_get_device(chip->regmap); int ret; chip->enable_prox = false; @@ -426,35 +432,33 @@ static int isl29028_chip_init(struct isl29028_chip *chip) ret = regmap_write(chip->regmap, ISL29028_REG_TEST1_MODE, 0x0); if (ret < 0) { - dev_err(chip->dev, "%s(): write to reg %d failed, err = %d\n", + dev_err(dev, "%s(): write to reg %d failed, err = %d\n", __func__, ISL29028_REG_TEST1_MODE, ret); return ret; } ret = regmap_write(chip->regmap, ISL29028_REG_TEST2_MODE, 0x0); if (ret < 0) { - dev_err(chip->dev, "%s(): write to reg %d failed, err = %d\n", + dev_err(dev, "%s(): write to reg %d failed, err = %d\n", __func__, ISL29028_REG_TEST2_MODE, ret); return ret; } ret = regmap_write(chip->regmap, ISL29028_REG_CONFIGURE, 0x0); if (ret < 0) { - dev_err(chip->dev, "%s(): write to reg %d failed, err = %d\n", + dev_err(dev, "%s(): write to reg %d failed, err = %d\n", __func__, ISL29028_REG_CONFIGURE, ret); return ret; } ret = isl29028_set_proxim_sampling(chip, chip->prox_sampling); if (ret < 0) { - dev_err(chip->dev, "setting the proximity, err = %d\n", - ret); + dev_err(dev, "setting the proximity, err = %d\n", ret); return ret; } ret = isl29028_set_als_scale(chip, chip->lux_scale); if (ret < 0) - dev_err(chip->dev, - "setting als scale failed, err = %d\n", ret); + dev_err(dev, "setting als scale failed, err = %d\n", ret); return ret; } @@ -496,19 +500,19 @@ static int isl29028_probe(struct i2c_client *client, chip = iio_priv(indio_dev); i2c_set_clientdata(client, indio_dev); - chip->dev = &client->dev; mutex_init(&chip->lock); chip->regmap = devm_regmap_init_i2c(client, &isl29028_regmap_config); if (IS_ERR(chip->regmap)) { ret = PTR_ERR(chip->regmap); - dev_err(chip->dev, "regmap initialization failed: %d\n", ret); + dev_err(&client->dev, "regmap initialization failed: %d\n", + ret); return ret; } ret = isl29028_chip_init(chip); if (ret < 0) { - dev_err(chip->dev, "chip initialization failed: %d\n", ret); + dev_err(&client->dev, "chip initialization failed: %d\n", ret); return ret; } @@ -520,7 +524,8 @@ static int isl29028_probe(struct i2c_client *client, indio_dev->modes = INDIO_DIRECT_MODE; ret = devm_iio_device_register(indio_dev->dev.parent, indio_dev); if (ret < 0) { - dev_err(chip->dev, "iio registration fails with error %d\n", + dev_err(&client->dev, + "iio registration fails with error %d\n", ret); return ret; } -- cgit v1.2.3 From ae549a72212c94c757fa3ecbcaa986cc9d2e2b96 Mon Sep 17 00:00:00 2001 From: David Wu Date: Wed, 16 Mar 2016 01:44:15 +0800 Subject: iio: adc: rockchip_saradc: add saradc support for rk3399 The ADC is a 6-channel signal-ended 10-bit Successive Approximation Register (SAR) A/D Converter. Signed-off-by: David Wu Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/adc/rockchip-saradc.txt | 6 +++++- drivers/iio/adc/rockchip_saradc.c | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.txt b/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.txt index a9a5fe19ff2a..bf99e2f24788 100644 --- a/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.txt +++ b/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.txt @@ -1,7 +1,11 @@ Rockchip Successive Approximation Register (SAR) A/D Converter bindings Required properties: -- compatible: Should be "rockchip,saradc" or "rockchip,rk3066-tsadc" +- compatible: should be "rockchip,-saradc" or "rockchip,rk3066-tsadc" + - "rockchip,saradc": for rk3188, rk3288 + - "rockchip,rk3066-tsadc": for rk3036 + - "rockchip,rk3399-saradc": for rk3399 + - reg: physical base address of the controller and length of memory mapped region. - interrupts: The interrupt number to the cpu. The interrupt specifier format diff --git a/drivers/iio/adc/rockchip_saradc.c b/drivers/iio/adc/rockchip_saradc.c index 9c311c1e1ac7..f9ad6c2d6821 100644 --- a/drivers/iio/adc/rockchip_saradc.c +++ b/drivers/iio/adc/rockchip_saradc.c @@ -159,6 +159,22 @@ static const struct rockchip_saradc_data rk3066_tsadc_data = { .clk_rate = 50000, }; +static const struct iio_chan_spec rockchip_rk3399_saradc_iio_channels[] = { + ADC_CHANNEL(0, "adc0"), + ADC_CHANNEL(1, "adc1"), + ADC_CHANNEL(2, "adc2"), + ADC_CHANNEL(3, "adc3"), + ADC_CHANNEL(4, "adc4"), + ADC_CHANNEL(5, "adc5"), +}; + +static const struct rockchip_saradc_data rk3399_saradc_data = { + .num_bits = 10, + .channels = rockchip_rk3399_saradc_iio_channels, + .num_channels = ARRAY_SIZE(rockchip_rk3399_saradc_iio_channels), + .clk_rate = 1000000, +}; + static const struct of_device_id rockchip_saradc_match[] = { { .compatible = "rockchip,saradc", @@ -166,6 +182,9 @@ static const struct of_device_id rockchip_saradc_match[] = { }, { .compatible = "rockchip,rk3066-tsadc", .data = &rk3066_tsadc_data, + }, { + .compatible = "rockchip,rk3399-saradc", + .data = &rk3399_saradc_data, }, {}, }; -- cgit v1.2.3 From 718ba46e5f4e21e45141bf55fd4cccd4b3ba9939 Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Thu, 17 Mar 2016 18:32:44 +0200 Subject: iio: imu: mpu6050: Fix name/chip_id when using ACPI When using ACPI, id is NULL and the current code automatically defaults name to NULL and chip id to 0. We should instead use the data provided in the ACPI device table. Fixes: c816d9e7a57b ("iio: imu: mpu6050: fix possible NULL dereferences") Signed-off-by: Daniel Baluta Reviewed-By: Matt Ranostay Signed-off-by: Jonathan Cameron --- drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c index d0c0e20c7122..5ee4e0dc093e 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c @@ -104,6 +104,19 @@ static int inv_mpu6050_deselect_bypass(struct i2c_adapter *adap, return 0; } +static const char *inv_mpu_match_acpi_device(struct device *dev, int *chip_id) +{ + const struct acpi_device_id *id; + + id = acpi_match_device(dev->driver->acpi_match_table, dev); + if (!id) + return NULL; + + *chip_id = (int)id->driver_data; + + return dev_name(dev); +} + /** * inv_mpu_probe() - probe function. * @client: i2c client. @@ -115,15 +128,25 @@ static int inv_mpu_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct inv_mpu6050_state *st; - int result; - const char *name = id ? id->name : NULL; - const int chip_type = id ? id->driver_data : 0; + int result, chip_type; struct regmap *regmap; + const char *name; if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) return -EOPNOTSUPP; + if (id) { + chip_type = (int)id->driver_data; + name = id->name; + } else if (ACPI_HANDLE(&client->dev)) { + name = inv_mpu_match_acpi_device(&client->dev, &chip_type); + if (!name) + return -ENODEV; + } else { + return -ENOSYS; + } + regmap = devm_regmap_init_i2c(client, &inv_mpu_regmap_config); if (IS_ERR(regmap)) { dev_err(&client->dev, "Failed to register i2c regmap %d\n", -- cgit v1.2.3 From 334ecdd0ba45bb68bce0f1429a4a1e9584ba437e Mon Sep 17 00:00:00 2001 From: Gregor Boirie Date: Thu, 17 Mar 2016 12:55:03 +0100 Subject: iio:pressure:ms5611: fix missing regulator_disable Ensure optional regulator is properly disabled when present. Fixes: 3145229f9191 ("iio:pressure:ms5611: power regulator support") Signed-off-by: Gregor Boirie Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/ms5611.h | 3 +++ drivers/iio/pressure/ms5611_core.c | 41 +++++++++++++++++++++++++++++--------- 2 files changed, 35 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/pressure/ms5611.h b/drivers/iio/pressure/ms5611.h index d725a3077a17..ccda63c5b3c3 100644 --- a/drivers/iio/pressure/ms5611.h +++ b/drivers/iio/pressure/ms5611.h @@ -16,6 +16,8 @@ #include #include +struct regulator; + #define MS5611_RESET 0x1e #define MS5611_READ_ADC 0x00 #define MS5611_READ_PROM_WORD 0xA0 @@ -57,6 +59,7 @@ struct ms5611_state { s32 *temp, s32 *pressure); struct ms5611_chip_info *chip_info; + struct regulator *vdd; }; int ms5611_probe(struct iio_dev *indio_dev, struct device *dev, diff --git a/drivers/iio/pressure/ms5611_core.c b/drivers/iio/pressure/ms5611_core.c index 37dbc0401599..c4e65868bc28 100644 --- a/drivers/iio/pressure/ms5611_core.c +++ b/drivers/iio/pressure/ms5611_core.c @@ -387,24 +387,45 @@ static const struct iio_info ms5611_info = { static int ms5611_init(struct iio_dev *indio_dev) { int ret; - struct regulator *vdd = devm_regulator_get(indio_dev->dev.parent, - "vdd"); + struct ms5611_state *st = iio_priv(indio_dev); /* Enable attached regulator if any. */ - if (!IS_ERR(vdd)) { - ret = regulator_enable(vdd); + st->vdd = devm_regulator_get(indio_dev->dev.parent, "vdd"); + if (!IS_ERR(st->vdd)) { + ret = regulator_enable(st->vdd); if (ret) { dev_err(indio_dev->dev.parent, - "failed to enable Vdd supply: %d\n", ret); + "failed to enable Vdd supply: %d\n", ret); return ret; } + } else { + ret = PTR_ERR(st->vdd); + if (ret != -ENODEV) + return ret; } ret = ms5611_reset(indio_dev); if (ret < 0) - return ret; + goto err_regulator_disable; + + ret = ms5611_read_prom(indio_dev); + if (ret < 0) + goto err_regulator_disable; + + return 0; - return ms5611_read_prom(indio_dev); +err_regulator_disable: + if (!IS_ERR_OR_NULL(st->vdd)) + regulator_disable(st->vdd); + return ret; +} + +static void ms5611_fini(const struct iio_dev *indio_dev) +{ + const struct ms5611_state *st = iio_priv(indio_dev); + + if (!IS_ERR_OR_NULL(st->vdd)) + regulator_disable(st->vdd); } int ms5611_probe(struct iio_dev *indio_dev, struct device *dev, @@ -436,7 +457,7 @@ int ms5611_probe(struct iio_dev *indio_dev, struct device *dev, ms5611_trigger_handler, NULL); if (ret < 0) { dev_err(dev, "iio triggered buffer setup failed\n"); - return ret; + goto err_fini; } ret = iio_device_register(indio_dev); @@ -449,7 +470,8 @@ int ms5611_probe(struct iio_dev *indio_dev, struct device *dev, err_buffer_cleanup: iio_triggered_buffer_cleanup(indio_dev); - +err_fini: + ms5611_fini(indio_dev); return ret; } EXPORT_SYMBOL(ms5611_probe); @@ -458,6 +480,7 @@ int ms5611_remove(struct iio_dev *indio_dev) { iio_device_unregister(indio_dev); iio_triggered_buffer_cleanup(indio_dev); + ms5611_fini(indio_dev); return 0; } -- cgit v1.2.3 From 9e61d901155bcd4e58cbce5eb4aaa8e870267334 Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Thu, 17 Mar 2016 19:25:11 +0530 Subject: iio: light: tsl2563: Remove flush_scheduled_work flush_scheduled_work is scheduled for deprecation. Replace cancel_delayed_work and flush_scheduled_work with cancel_delayed_work_sync instead to ensure there is no pending or running work item. Since there is only one work item, chip->poweroff_work, there are no further dependencies of flush_scheduled_work(). Acked-by: Tejun Heo Signed-off-by: Amitoj Kaur Chawla Signed-off-by: Jonathan Cameron --- drivers/iio/light/tsl2563.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/light/tsl2563.c b/drivers/iio/light/tsl2563.c index 12731d6b89ec..57b108c30e98 100644 --- a/drivers/iio/light/tsl2563.c +++ b/drivers/iio/light/tsl2563.c @@ -806,8 +806,7 @@ static int tsl2563_probe(struct i2c_client *client, return 0; fail: - cancel_delayed_work(&chip->poweroff_work); - flush_scheduled_work(); + cancel_delayed_work_sync(&chip->poweroff_work); return err; } -- cgit v1.2.3 From a9b72c90fc1a7cd547a333e382b3a7c2201fc3e4 Mon Sep 17 00:00:00 2001 From: Gregor Boirie Date: Thu, 17 Mar 2016 17:43:26 +0100 Subject: iio:magnetometer:ak8975: fix missing regulator_disable Ensure optional regulator is properly disabled when present. Fixes: 63d5d525cbbc ("iio:magnetometer:ak8975: power regulator support") Signed-off-by: Gregor Boirie Signed-off-by: Jonathan Cameron --- drivers/iio/magnetometer/ak8975.c | 78 ++++++++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c index 72c03d9fbeb2..48d127a45d90 100644 --- a/drivers/iio/magnetometer/ak8975.c +++ b/drivers/iio/magnetometer/ak8975.c @@ -370,8 +370,40 @@ struct ak8975_data { wait_queue_head_t data_ready_queue; unsigned long flags; u8 cntl_cache; + struct regulator *vdd; }; +/* Enable attached power regulator if any. */ +static int ak8975_power_on(struct i2c_client *client) +{ + const struct iio_dev *indio_dev = i2c_get_clientdata(client); + struct ak8975_data *data = iio_priv(indio_dev); + int ret; + + data->vdd = devm_regulator_get(&client->dev, "vdd"); + if (IS_ERR_OR_NULL(data->vdd)) { + ret = PTR_ERR(data->vdd); + if (ret == -ENODEV) + ret = 0; + } else { + ret = regulator_enable(data->vdd); + } + + if (ret) + dev_err(&client->dev, "failed to enable Vdd supply: %d\n", ret); + return ret; +} + +/* Disable attached power regulator if any. */ +static void ak8975_power_off(const struct i2c_client *client) +{ + const struct iio_dev *indio_dev = i2c_get_clientdata(client); + const struct ak8975_data *data = iio_priv(indio_dev); + + if (!IS_ERR_OR_NULL(data->vdd)) + regulator_disable(data->vdd); +} + /* * Return 0 if the i2c device is the one we expect. * return a negative error number otherwise @@ -380,23 +412,8 @@ static int ak8975_who_i_am(struct i2c_client *client, enum asahi_compass_chipset type) { u8 wia_val[2]; - struct regulator *vdd = devm_regulator_get_optional(&client->dev, - "vdd"); int ret; - /* Enable attached regulator if any. */ - if (!IS_ERR(vdd)) { - ret = regulator_enable(vdd); - if (ret) { - dev_err(&client->dev, "Failed to enable Vdd supply\n"); - return ret; - } - } else { - ret = PTR_ERR(vdd); - if (ret != -ENODEV) - return ret; - } - /* * Signature for each device: * Device | WIA1 | WIA2 @@ -804,10 +821,15 @@ static int ak8975_probe(struct i2c_client *client, } data->def = &ak_def_array[chipset]; + + err = ak8975_power_on(client); + if (err) + return err; + err = ak8975_who_i_am(client, data->def->type); if (err < 0) { dev_err(&client->dev, "Unexpected device\n"); - return err; + goto power_off; } dev_dbg(&client->dev, "Asahi compass chip %s\n", name); @@ -815,7 +837,7 @@ static int ak8975_probe(struct i2c_client *client, err = ak8975_setup(client); if (err < 0) { dev_err(&client->dev, "%s initialization fails\n", name); - return err; + goto power_off; } mutex_init(&data->lock); @@ -825,7 +847,26 @@ static int ak8975_probe(struct i2c_client *client, indio_dev->info = &ak8975_info; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->name = name; - return devm_iio_device_register(&client->dev, indio_dev); + + err = iio_device_register(indio_dev); + if (err) + goto power_off; + + return 0; + +power_off: + ak8975_power_off(client); + return err; +} + +static int ak8975_remove(struct i2c_client *client) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(client); + + iio_device_unregister(indio_dev); + ak8975_power_off(client); + + return 0; } static const struct i2c_device_id ak8975_id[] = { @@ -859,6 +900,7 @@ static struct i2c_driver ak8975_driver = { .acpi_match_table = ACPI_PTR(ak_acpi_match), }, .probe = ak8975_probe, + .remove = ak8975_remove, .id_table = ak8975_id, }; module_i2c_driver(ak8975_driver); -- cgit v1.2.3 From a6573e1f54b713f837ac08d87961f610c63246ba Mon Sep 17 00:00:00 2001 From: Jordan Justen Date: Sun, 6 Mar 2016 23:30:26 -0800 Subject: drm/i915: Add TIMESTAMP to register whitelist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is needed for the Mesa Vulkan driver on Haswell. Signed-off-by: Jordan Justen Cc: Kristian Høgsberg Cc: Kenneth Graunke Reviewed-by: Francisco Jerez Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1457335830-30923-2-git-send-email-jordan.l.justen@intel.com --- drivers/gpu/drm/i915/i915_cmd_parser.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index 2c50142be559..a5ebe9a13a11 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c @@ -444,6 +444,7 @@ static const struct drm_i915_reg_descriptor gen7_render_regs[] = { REG64(CL_PRIMITIVES_COUNT), REG64(PS_INVOCATION_COUNT), REG64(PS_DEPTH_COUNT), + REG64_IDX(RING_TIMESTAMP, RENDER_RING_BASE), REG32(OACONTROL), /* Only allowed for LRI and SRM. See below. */ REG64(MI_PREDICATE_SRC0), REG64(MI_PREDICATE_SRC1), -- cgit v1.2.3 From 361b027bc6ae8501756829043ac98e42e40494f8 Mon Sep 17 00:00:00 2001 From: Jordan Justen Date: Sun, 6 Mar 2016 23:30:27 -0800 Subject: drm/i915: Use an array of register tables in command parser For Haswell, we will want another table of registers while retaining the large common table of whitelisted registers shared by all gen7 devices. Signed-off-by: Jordan Justen Reviewed-by: Francisco Jerez [danvet: Pipe patch through sed -e 's/\/engine/g' to make it apply.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_cmd_parser.c | 101 +++++++++++++++++++++++--------- drivers/gpu/drm/i915/intel_ringbuffer.h | 13 +--- 2 files changed, 75 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index a5ebe9a13a11..ce753d3a817f 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c @@ -501,6 +501,32 @@ static const struct drm_i915_reg_descriptor hsw_master_regs[] = { #undef REG64 #undef REG32 +struct drm_i915_reg_table { + const struct drm_i915_reg_descriptor *regs; + int num_regs; + bool master; +}; + +static const struct drm_i915_reg_table ivb_render_reg_tables[] = { + { gen7_render_regs, ARRAY_SIZE(gen7_render_regs), false }, + { ivb_master_regs, ARRAY_SIZE(ivb_master_regs), true }, +}; + +static const struct drm_i915_reg_table ivb_blt_reg_tables[] = { + { gen7_blt_regs, ARRAY_SIZE(gen7_blt_regs), false }, + { ivb_master_regs, ARRAY_SIZE(ivb_master_regs), true }, +}; + +static const struct drm_i915_reg_table hsw_render_reg_tables[] = { + { gen7_render_regs, ARRAY_SIZE(gen7_render_regs), false }, + { hsw_master_regs, ARRAY_SIZE(hsw_master_regs), true }, +}; + +static const struct drm_i915_reg_table hsw_blt_reg_tables[] = { + { gen7_blt_regs, ARRAY_SIZE(gen7_blt_regs), false }, + { hsw_master_regs, ARRAY_SIZE(hsw_master_regs), true }, +}; + static u32 gen7_render_get_cmd_length_mask(u32 cmd_header) { u32 client = (cmd_header & INSTR_CLIENT_MASK) >> INSTR_CLIENT_SHIFT; @@ -614,9 +640,16 @@ static bool check_sorted(int ring_id, static bool validate_regs_sorted(struct intel_engine_cs *engine) { - return check_sorted(engine->id, engine->reg_table, engine->reg_count) && - check_sorted(engine->id, engine->master_reg_table, - engine->master_reg_count); + int i; + const struct drm_i915_reg_table *table; + + for (i = 0; i < engine->reg_table_count; i++) { + table = &engine->reg_tables[i]; + if (!check_sorted(engine->id, table->regs, table->num_regs)) + return false; + } + + return true; } struct cmd_node { @@ -711,15 +744,12 @@ int i915_cmd_parser_init_ring(struct intel_engine_cs *engine) cmd_table_count = ARRAY_SIZE(gen7_render_cmds); } - engine->reg_table = gen7_render_regs; - engine->reg_count = ARRAY_SIZE(gen7_render_regs); - if (IS_HASWELL(engine->dev)) { - engine->master_reg_table = hsw_master_regs; - engine->master_reg_count = ARRAY_SIZE(hsw_master_regs); + engine->reg_tables = hsw_render_reg_tables; + engine->reg_table_count = ARRAY_SIZE(hsw_render_reg_tables); } else { - engine->master_reg_table = ivb_master_regs; - engine->master_reg_count = ARRAY_SIZE(ivb_master_regs); + engine->reg_tables = ivb_render_reg_tables; + engine->reg_table_count = ARRAY_SIZE(ivb_render_reg_tables); } engine->get_cmd_length_mask = gen7_render_get_cmd_length_mask; @@ -738,15 +768,12 @@ int i915_cmd_parser_init_ring(struct intel_engine_cs *engine) cmd_table_count = ARRAY_SIZE(gen7_blt_cmds); } - engine->reg_table = gen7_blt_regs; - engine->reg_count = ARRAY_SIZE(gen7_blt_regs); - if (IS_HASWELL(engine->dev)) { - engine->master_reg_table = hsw_master_regs; - engine->master_reg_count = ARRAY_SIZE(hsw_master_regs); + engine->reg_tables = hsw_blt_reg_tables; + engine->reg_table_count = ARRAY_SIZE(hsw_blt_reg_tables); } else { - engine->master_reg_table = ivb_master_regs; - engine->master_reg_count = ARRAY_SIZE(ivb_master_regs); + engine->reg_tables = ivb_blt_reg_tables; + engine->reg_table_count = ARRAY_SIZE(ivb_blt_reg_tables); } engine->get_cmd_length_mask = gen7_blt_get_cmd_length_mask; @@ -849,12 +876,31 @@ static const struct drm_i915_reg_descriptor * find_reg(const struct drm_i915_reg_descriptor *table, int count, u32 addr) { - if (table) { - int i; + int i; + + for (i = 0; i < count; i++) { + if (i915_mmio_reg_offset(table[i].addr) == addr) + return &table[i]; + } - for (i = 0; i < count; i++) { - if (i915_mmio_reg_offset(table[i].addr) == addr) - return &table[i]; + return NULL; +} + +static const struct drm_i915_reg_descriptor * +find_reg_in_tables(const struct drm_i915_reg_table *tables, + int count, bool is_master, u32 addr) +{ + int i; + const struct drm_i915_reg_table *table; + const struct drm_i915_reg_descriptor *reg; + + for (i = 0; i < count; i++) { + table = &tables[i]; + if (!table->master || is_master) { + reg = find_reg(table->regs, table->num_regs, + addr); + if (reg != NULL) + return reg; } } @@ -1005,13 +1051,10 @@ static bool check_cmd(const struct intel_engine_cs *engine, offset += step) { const u32 reg_addr = cmd[offset] & desc->reg.mask; const struct drm_i915_reg_descriptor *reg = - find_reg(engine->reg_table, engine->reg_count, - reg_addr); - - if (!reg && is_master) - reg = find_reg(engine->master_reg_table, - engine->master_reg_count, - reg_addr); + find_reg_in_tables(engine->reg_tables, + engine->reg_table_count, + is_master, + reg_addr); if (!reg) { DRM_DEBUG_DRIVER("CMD: Rejected register 0x%08X in command: 0x%08X (ring=%d)\n", diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 3e40f7bf2147..221a94627aab 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -123,7 +123,7 @@ struct intel_ringbuffer { }; struct intel_context; -struct drm_i915_reg_descriptor; +struct drm_i915_reg_table; /* * we use a single page to load ctx workarounds so all of these @@ -331,15 +331,8 @@ struct intel_engine_cs { /* * Table of registers allowed in commands that read/write registers. */ - const struct drm_i915_reg_descriptor *reg_table; - int reg_count; - - /* - * Table of registers allowed in commands that read/write registers, but - * only from the DRM master. - */ - const struct drm_i915_reg_descriptor *master_reg_table; - int master_reg_count; + const struct drm_i915_reg_table *reg_tables; + int reg_table_count; /* * Returns the bitmask for the length field of the specified command. -- cgit v1.2.3 From 99c5aeca94a506a2b279022fae5de3f8606730bd Mon Sep 17 00:00:00 2001 From: Jordan Justen Date: Sun, 6 Mar 2016 23:30:28 -0800 Subject: drm/i915: Move Haswell registers to separate whitelist table Now that we can whitelist registers only on Haswell, move HSW_SCRATCH1 and HSW_ROW_CHICKEN3 into a separate Haswell only table. Signed-off-by: Jordan Justen Cc: Francisco Jerez Reviewed-by: Francisco Jerez Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1457335830-30923-4-git-send-email-jordan.l.justen@intel.com --- drivers/gpu/drm/i915/i915_cmd_parser.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index ce753d3a817f..6c81c700d746 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c @@ -472,6 +472,9 @@ static const struct drm_i915_reg_descriptor gen7_render_regs[] = { REG32(GEN7_L3SQCREG1), REG32(GEN7_L3CNTLREG2), REG32(GEN7_L3CNTLREG3), +}; + +static const struct drm_i915_reg_descriptor hsw_render_regs[] = { REG32(HSW_SCRATCH1, .mask = ~HSW_SCRATCH1_L3_DATA_ATOMICS_DISABLE, .value = 0), @@ -519,6 +522,7 @@ static const struct drm_i915_reg_table ivb_blt_reg_tables[] = { static const struct drm_i915_reg_table hsw_render_reg_tables[] = { { gen7_render_regs, ARRAY_SIZE(gen7_render_regs), false }, + { hsw_render_regs, ARRAY_SIZE(hsw_render_regs), false }, { hsw_master_regs, ARRAY_SIZE(hsw_master_regs), true }, }; -- cgit v1.2.3 From 1b85066bb1332e4298e533b7f15e04d82990ceaf Mon Sep 17 00:00:00 2001 From: Jordan Justen Date: Sun, 6 Mar 2016 23:30:29 -0800 Subject: drm/i915: Add Haswell CS GPR registers to whitelist This is needed for the Mesa Vulkan driver on Haswell. Signed-off-by: Jordan Justen Reviewed-by: Francisco Jerez Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1457335830-30923-5-git-send-email-jordan.l.justen@intel.com --- drivers/gpu/drm/i915/i915_cmd_parser.c | 16 ++++++++++++++++ drivers/gpu/drm/i915/i915_reg.h | 4 ++++ 2 files changed, 20 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index 6c81c700d746..546dfccdf6dd 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c @@ -475,6 +475,22 @@ static const struct drm_i915_reg_descriptor gen7_render_regs[] = { }; static const struct drm_i915_reg_descriptor hsw_render_regs[] = { + REG64_IDX(HSW_CS_GPR, 0), + REG64_IDX(HSW_CS_GPR, 1), + REG64_IDX(HSW_CS_GPR, 2), + REG64_IDX(HSW_CS_GPR, 3), + REG64_IDX(HSW_CS_GPR, 4), + REG64_IDX(HSW_CS_GPR, 5), + REG64_IDX(HSW_CS_GPR, 6), + REG64_IDX(HSW_CS_GPR, 7), + REG64_IDX(HSW_CS_GPR, 8), + REG64_IDX(HSW_CS_GPR, 9), + REG64_IDX(HSW_CS_GPR, 10), + REG64_IDX(HSW_CS_GPR, 11), + REG64_IDX(HSW_CS_GPR, 12), + REG64_IDX(HSW_CS_GPR, 13), + REG64_IDX(HSW_CS_GPR, 14), + REG64_IDX(HSW_CS_GPR, 15), REG32(HSW_SCRATCH1, .mask = ~HSW_SCRATCH1_L3_DATA_ATOMICS_DISABLE, .value = 0), diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 264885fc245d..06fb589bbe6b 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -588,6 +588,10 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) #define GEN7_GPGPU_DISPATCHDIMY _MMIO(0x2504) #define GEN7_GPGPU_DISPATCHDIMZ _MMIO(0x2508) +/* There are the 16 64-bit CS General Purpose Registers */ +#define HSW_CS_GPR(n) _MMIO(0x2600 + (n) * 8) +#define HSW_CS_GPR_UDW(n) _MMIO(0x2600 + (n) * 8 + 4) + #define OACONTROL _MMIO(0x2360) #define _GEN7_PIPEA_DE_LOAD_SL 0x70068 -- cgit v1.2.3 From 6cf0716c0321344fdc72205d590e968e53492088 Mon Sep 17 00:00:00 2001 From: Jordan Justen Date: Sun, 6 Mar 2016 23:30:30 -0800 Subject: drm/i915: Bump command parser version for new whitelisted registers Signed-off-by: Jordan Justen Reviewed-by: Francisco Jerez Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1457335830-30923-6-git-send-email-jordan.l.justen@intel.com --- drivers/gpu/drm/i915/i915_cmd_parser.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index 546dfccdf6dd..a337f33bec5b 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c @@ -1287,6 +1287,7 @@ int i915_cmd_parser_get_version(void) * 3. Allow access to the GPGPU_THREADS_DISPATCHED register. * 4. L3 atomic chicken bits of HSW_SCRATCH1 and HSW_ROW_CHICKEN3. * 5. GPGPU dispatch compute indirect registers. + * 6. TIMESTAMP register and Haswell CS GPR registers */ - return 5; + return 6; } -- cgit v1.2.3 From 1844a66b98800b3cfd92aea4e801641304ac07d7 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 16 Mar 2016 13:31:30 -0700 Subject: drm/i915: add another virtual PCH bridge for passthrough support Some configs use the P2X type but some use a P3X type PCH, so add that to the detect_pch function so things work correctly. Signed-off-by: Jesse Barnes Reviewed-by: Allen Kay Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1458160290-16710-1-git-send-email-jbarnes@virtuousgeek.org --- drivers/gpu/drm/i915/i915_drv.c | 1 + drivers/gpu/drm/i915/i915_drv.h | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 3648b73b48da..2a076b005af9 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -504,6 +504,7 @@ void intel_detect_pch(struct drm_device *dev) WARN_ON(!IS_SKYLAKE(dev) && !IS_KABYLAKE(dev)); } else if ((id == INTEL_PCH_P2X_DEVICE_ID_TYPE) || + (id == INTEL_PCH_P3X_DEVICE_ID_TYPE) || ((id == INTEL_PCH_QEMU_DEVICE_ID_TYPE) && pch->subsystem_vendor == 0x1af4 && pch->subsystem_device == 0x1100)) { diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f330a53c19b9..8727746cecd2 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2665,6 +2665,7 @@ struct drm_i915_cmd_table { #define INTEL_PCH_SPT_DEVICE_ID_TYPE 0xA100 #define INTEL_PCH_SPT_LP_DEVICE_ID_TYPE 0x9D00 #define INTEL_PCH_P2X_DEVICE_ID_TYPE 0x7100 +#define INTEL_PCH_P3X_DEVICE_ID_TYPE 0x7000 #define INTEL_PCH_QEMU_DEVICE_ID_TYPE 0x2900 /* qemu q35 has 2918 */ #define INTEL_PCH_TYPE(dev) (__I915__(dev)->pch_type) -- cgit v1.2.3 From bc58be6058d65f05c5bce8c562ec196e70760a9a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 18 Mar 2016 17:05:39 +0200 Subject: drm/i915: split get/set pipe timings to timings and src size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prep work for DSI transcoders. No functional changes. v2: call split functions at a higher level (Ville) Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/8d67a05eb869a7b0c4ee17c2d3b0b029de34851c.1458313400.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_display.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 74b0165238dc..a356a0a78b82 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -96,6 +96,7 @@ static int intel_framebuffer_init(struct drm_device *dev, struct drm_i915_gem_object *obj); static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc); static void intel_set_pipe_timings(struct intel_crtc *intel_crtc); +static void intel_set_pipe_src_size(struct intel_crtc *intel_crtc); static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc, struct intel_link_m_n *m_n, struct intel_link_m_n *m2_n2); @@ -4827,6 +4828,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) intel_dp_set_m_n(intel_crtc, M1_N1); intel_set_pipe_timings(intel_crtc); + intel_set_pipe_src_size(intel_crtc); if (intel_crtc->config->has_pch_encoder) { intel_cpu_transcoder_set_m_n(intel_crtc, @@ -4913,6 +4915,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) intel_dp_set_m_n(intel_crtc, M1_N1); intel_set_pipe_timings(intel_crtc); + intel_set_pipe_src_size(intel_crtc); if (intel_crtc->config->cpu_transcoder != TRANSCODER_EDP) { I915_WRITE(PIPE_MULT(intel_crtc->config->cpu_transcoder), @@ -6120,6 +6123,7 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) intel_dp_set_m_n(intel_crtc, M1_N1); intel_set_pipe_timings(intel_crtc); + intel_set_pipe_src_size(intel_crtc); if (IS_CHERRYVIEW(dev) && pipe == PIPE_B) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -6192,6 +6196,7 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) intel_dp_set_m_n(intel_crtc, M1_N1); intel_set_pipe_timings(intel_crtc); + intel_set_pipe_src_size(intel_crtc); i9xx_set_pipeconf(intel_crtc); @@ -7719,6 +7724,14 @@ static void intel_set_pipe_timings(struct intel_crtc *intel_crtc) (pipe == PIPE_B || pipe == PIPE_C)) I915_WRITE(VTOTAL(pipe), I915_READ(VTOTAL(cpu_transcoder))); +} + +static void intel_set_pipe_src_size(struct intel_crtc *intel_crtc) +{ + struct drm_device *dev = intel_crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + enum pipe pipe = intel_crtc->pipe; + /* pipesrc controls the size that is scaled from, which should * always be the user's requested size. */ @@ -7760,6 +7773,14 @@ static void intel_get_pipe_timings(struct intel_crtc *crtc, pipe_config->base.adjusted_mode.crtc_vtotal += 1; pipe_config->base.adjusted_mode.crtc_vblank_end += 1; } +} + +static void intel_get_pipe_src_size(struct intel_crtc *crtc, + struct intel_crtc_state *pipe_config) +{ + struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + u32 tmp; tmp = I915_READ(PIPESRC(crtc->pipe)); pipe_config->pipe_src_h = (tmp & 0xffff) + 1; @@ -8125,6 +8146,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, pipe_config->double_wide = tmp & PIPECONF_DOUBLE_WIDE; intel_get_pipe_timings(crtc, pipe_config); + intel_get_pipe_src_size(crtc, pipe_config); i9xx_get_pfit_config(crtc, pipe_config); @@ -9364,6 +9386,7 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, } intel_get_pipe_timings(crtc, pipe_config); + intel_get_pipe_src_size(crtc, pipe_config); ironlake_get_pfit_config(crtc, pipe_config); @@ -9972,6 +9995,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, haswell_get_ddi_port_state(crtc, pipe_config); intel_get_pipe_timings(crtc, pipe_config); + intel_get_pipe_src_size(crtc, pipe_config); if (INTEL_INFO(dev)->gen >= 9) { skl_init_scalers(dev, crtc, pipe_config); -- cgit v1.2.3 From 391bf04862feab95beffcb3634e8aba8961f4d35 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 18 Mar 2016 17:05:40 +0200 Subject: drm/i915: split set pipeconf to pipeconf, pipemisc, pipe_gamma MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prep work for DSI transcoders. No functional changes. v2: call split functions at a higher level (Ville) Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/981252d5d5f82d009d73e1b2ae93d9ab7bee8de8.1458313400.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_display.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a356a0a78b82..eece50ed3ea6 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -102,6 +102,8 @@ static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc, struct intel_link_m_n *m2_n2); static void ironlake_set_pipeconf(struct drm_crtc *crtc); static void haswell_set_pipeconf(struct drm_crtc *crtc); +static void haswell_set_pipe_gamma(struct drm_crtc *crtc); +static void haswell_set_pipemisc(struct drm_crtc *crtc); static void intel_set_pipe_csc(struct drm_crtc *crtc); static void vlv_prepare_pll(struct intel_crtc *crtc, const struct intel_crtc_state *pipe_config); @@ -4928,6 +4930,8 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) } haswell_set_pipeconf(crtc); + haswell_set_pipe_gamma(crtc); + haswell_set_pipemisc(crtc); intel_set_pipe_csc(crtc); @@ -8764,16 +8768,12 @@ static void intel_set_pipe_csc(struct drm_crtc *crtc) static void haswell_set_pipeconf(struct drm_crtc *crtc) { - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = crtc->dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - enum pipe pipe = intel_crtc->pipe; enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; - uint32_t val; + u32 val = 0; - val = 0; - - if (IS_HASWELL(dev) && intel_crtc->config->dither) + if (IS_HASWELL(dev_priv) && intel_crtc->config->dither) val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP); if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) @@ -8783,12 +8783,24 @@ static void haswell_set_pipeconf(struct drm_crtc *crtc) I915_WRITE(PIPECONF(cpu_transcoder), val); POSTING_READ(PIPECONF(cpu_transcoder)); +} + +static void haswell_set_pipe_gamma(struct drm_crtc *crtc) +{ + struct drm_i915_private *dev_priv = crtc->dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); I915_WRITE(GAMMA_MODE(intel_crtc->pipe), GAMMA_MODE_MODE_8BIT); POSTING_READ(GAMMA_MODE(intel_crtc->pipe)); +} + +static void haswell_set_pipemisc(struct drm_crtc *crtc) +{ + struct drm_i915_private *dev_priv = crtc->dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - if (IS_BROADWELL(dev) || INTEL_INFO(dev)->gen >= 9) { - val = 0; + if (IS_BROADWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >= 9) { + u32 val = 0; switch (intel_crtc->config->pipe_bpp) { case 18: @@ -8811,7 +8823,7 @@ static void haswell_set_pipeconf(struct drm_crtc *crtc) if (intel_crtc->config->dither) val |= PIPEMISC_DITHER_ENABLE | PIPEMISC_DITHER_TYPE_SP; - I915_WRITE(PIPEMISC(pipe), val); + I915_WRITE(PIPEMISC(intel_crtc->pipe), val); } } -- cgit v1.2.3 From cf30429e9420556399aab92995ff23e15c22de6b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 18 Mar 2016 17:05:41 +0200 Subject: drm/i915: abstract get config for cpu transcoder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Makes it neater to add the same for DSI transcoder. No functional changes. v2: rename to hsw_get_transcoder_state and add a comment about grabbing power reference (Ville) Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/c473a73d69dcd61584419d85ff7908a8717b0594.1458313400.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_display.c | 87 +++++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index eece50ed3ea6..98d8b563b9a1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9910,6 +9910,53 @@ static void haswell_get_ddi_pll(struct drm_i915_private *dev_priv, pipe_config->shared_dpll = intel_get_shared_dpll_by_id(dev_priv, id); } +static bool hsw_get_transcoder_state(struct intel_crtc *crtc, + struct intel_crtc_state *pipe_config, + unsigned long *power_domain_mask) +{ + struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + enum intel_display_power_domain power_domain; + u32 tmp; + + pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe; + + /* + * XXX: Do intel_display_power_get_if_enabled before reading this (for + * consistency and less surprising code; it's in always on power). + */ + tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)); + if (tmp & TRANS_DDI_FUNC_ENABLE) { + enum pipe trans_edp_pipe; + switch (tmp & TRANS_DDI_EDP_INPUT_MASK) { + default: + WARN(1, "unknown pipe linked to edp transcoder\n"); + case TRANS_DDI_EDP_INPUT_A_ONOFF: + case TRANS_DDI_EDP_INPUT_A_ON: + trans_edp_pipe = PIPE_A; + break; + case TRANS_DDI_EDP_INPUT_B_ONOFF: + trans_edp_pipe = PIPE_B; + break; + case TRANS_DDI_EDP_INPUT_C_ONOFF: + trans_edp_pipe = PIPE_C; + break; + } + + if (trans_edp_pipe == crtc->pipe) + pipe_config->cpu_transcoder = TRANSCODER_EDP; + } + + power_domain = POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder); + if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) + return false; + *power_domain_mask |= BIT(power_domain); + + tmp = I915_READ(PIPECONF(pipe_config->cpu_transcoder)); + + return tmp & PIPECONF_ENABLE; +} + static void haswell_get_ddi_port_state(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { @@ -9960,48 +10007,18 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, struct drm_i915_private *dev_priv = dev->dev_private; enum intel_display_power_domain power_domain; unsigned long power_domain_mask; - uint32_t tmp; - bool ret; + bool active; power_domain = POWER_DOMAIN_PIPE(crtc->pipe); if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) return false; power_domain_mask = BIT(power_domain); - ret = false; - - pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe; pipe_config->shared_dpll = NULL; - tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)); - if (tmp & TRANS_DDI_FUNC_ENABLE) { - enum pipe trans_edp_pipe; - switch (tmp & TRANS_DDI_EDP_INPUT_MASK) { - default: - WARN(1, "unknown pipe linked to edp transcoder\n"); - case TRANS_DDI_EDP_INPUT_A_ONOFF: - case TRANS_DDI_EDP_INPUT_A_ON: - trans_edp_pipe = PIPE_A; - break; - case TRANS_DDI_EDP_INPUT_B_ONOFF: - trans_edp_pipe = PIPE_B; - break; - case TRANS_DDI_EDP_INPUT_C_ONOFF: - trans_edp_pipe = PIPE_C; - break; - } - - if (trans_edp_pipe == crtc->pipe) - pipe_config->cpu_transcoder = TRANSCODER_EDP; - } + active = hsw_get_transcoder_state(crtc, pipe_config, &power_domain_mask); - power_domain = POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder); - if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) - goto out; - power_domain_mask |= BIT(power_domain); - - tmp = I915_READ(PIPECONF(pipe_config->cpu_transcoder)); - if (!(tmp & PIPECONF_ENABLE)) + if (!active) goto out; haswell_get_ddi_port_state(crtc, pipe_config); @@ -10038,13 +10055,11 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, pipe_config->pixel_multiplier = 1; } - ret = true; - out: for_each_power_domain(power_domain, power_domain_mask) intel_display_power_put(dev_priv, power_domain); - return ret; + return active; } static void i845_update_cursor(struct drm_crtc *crtc, u32 base, -- cgit v1.2.3 From 4d1de97568321828b9e63522c60ee77d23925471 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 18 Mar 2016 17:05:42 +0200 Subject: drm/i915/bxt: add dsi transcoders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The BXT display connections have DSI transcoders A and C that can be muxed to any pipe, not unlike the eDP transcoder. Add the notion of DSI transcoders. The "normal" transcoders A, B and C are not used with BXT DSI, so care must be taken to avoid accessing those registers with DSI transcoders in the hardware state readout, modeset, and generally everywhere. v2: addressing comments by Ville: - rename the dsi get config function to hsw_get_dsi_transcoder_state - rebase onto the higher level split of pipe/transcoder functions - use more has_dsi_encoder as we can now because of the above, with no need to look at the transcoder so much - rename IS_DSI_TRANSCODER to transcoder_is_dsi - use the above a bit more instead of comparing to < TRANSCODER_EDP Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/299740536b7941e31b2744f3ce34f7afe936a771.1458313400.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 13 +++++ drivers/gpu/drm/i915/intel_ddi.c | 6 +++ drivers/gpu/drm/i915/intel_display.c | 91 +++++++++++++++++++++++++++++---- drivers/gpu/drm/i915/intel_drv.h | 3 +- drivers/gpu/drm/i915/intel_dsi.c | 9 ++++ drivers/gpu/drm/i915/intel_runtime_pm.c | 6 +++ 6 files changed, 116 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 8727746cecd2..efca534f9b29 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -127,6 +127,8 @@ enum transcoder { TRANSCODER_B, TRANSCODER_C, TRANSCODER_EDP, + TRANSCODER_DSI_A, + TRANSCODER_DSI_C, I915_MAX_TRANSCODERS }; @@ -141,11 +143,20 @@ static inline const char *transcoder_name(enum transcoder transcoder) return "C"; case TRANSCODER_EDP: return "EDP"; + case TRANSCODER_DSI_A: + return "DSI A"; + case TRANSCODER_DSI_C: + return "DSI C"; default: return ""; } } +static inline bool transcoder_is_dsi(enum transcoder transcoder) +{ + return transcoder == TRANSCODER_DSI_A || transcoder == TRANSCODER_DSI_C; +} + /* * I915_MAX_PLANES in the enum below is the maximum (across all platforms) * number of planes per CRTC. Not all platforms really have this many planes, @@ -196,6 +207,8 @@ enum intel_display_power_domain { POWER_DOMAIN_TRANSCODER_B, POWER_DOMAIN_TRANSCODER_C, POWER_DOMAIN_TRANSCODER_EDP, + POWER_DOMAIN_TRANSCODER_DSI_A, + POWER_DOMAIN_TRANSCODER_DSI_C, POWER_DOMAIN_PORT_DDI_A_LANES, POWER_DOMAIN_PORT_DDI_B_LANES, POWER_DOMAIN_PORT_DDI_C_LANES, diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 91654ffc3a42..e6c3a80e1360 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1061,6 +1061,8 @@ void intel_ddi_set_pipe_settings(struct drm_crtc *crtc) uint32_t temp; if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) { + WARN_ON(transcoder_is_dsi(cpu_transcoder)); + temp = TRANS_MSA_SYNC_CLK; switch (intel_crtc->config->pipe_bpp) { case 18: @@ -1942,6 +1944,10 @@ void intel_ddi_get_config(struct intel_encoder *encoder, struct intel_hdmi *intel_hdmi; u32 temp, flags = 0; + /* XXX: DSI transcoder paranoia */ + if (WARN_ON(transcoder_is_dsi(cpu_transcoder))) + return; + temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); if (temp & TRANS_DDI_PHSYNC) flags |= DRM_MODE_FLAG_PHSYNC; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 98d8b563b9a1..28ead66ed987 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4900,6 +4900,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_encoder *encoder; int pipe = intel_crtc->pipe, hsw_workaround_pipe; + enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc->state); @@ -4916,11 +4917,14 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) if (intel_crtc->config->has_dp_encoder) intel_dp_set_m_n(intel_crtc, M1_N1); - intel_set_pipe_timings(intel_crtc); + if (!intel_crtc->config->has_dsi_encoder) + intel_set_pipe_timings(intel_crtc); + intel_set_pipe_src_size(intel_crtc); - if (intel_crtc->config->cpu_transcoder != TRANSCODER_EDP) { - I915_WRITE(PIPE_MULT(intel_crtc->config->cpu_transcoder), + if (cpu_transcoder != TRANSCODER_EDP && + !transcoder_is_dsi(cpu_transcoder)) { + I915_WRITE(PIPE_MULT(cpu_transcoder), intel_crtc->config->pixel_multiplier - 1); } @@ -4929,7 +4933,9 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) &intel_crtc->config->fdi_m_n, NULL); } - haswell_set_pipeconf(crtc); + if (!intel_crtc->config->has_dsi_encoder) + haswell_set_pipeconf(crtc); + haswell_set_pipe_gamma(crtc); haswell_set_pipemisc(crtc); @@ -4972,7 +4978,10 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) dev_priv->display.initial_watermarks(pipe_config); else intel_update_watermarks(crtc); - intel_enable_pipe(intel_crtc); + + /* XXX: Do the pipe assertions at the right place for BXT DSI. */ + if (!intel_crtc->config->has_dsi_encoder) + intel_enable_pipe(intel_crtc); if (intel_crtc->config->has_pch_encoder) lpt_pch_enable(crtc); @@ -5105,7 +5114,9 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) drm_crtc_vblank_off(crtc); assert_vblank_disabled(crtc); - intel_disable_pipe(intel_crtc); + /* XXX: Do the pipe assertions at the right place for BXT DSI. */ + if (!intel_crtc->config->has_dsi_encoder) + intel_disable_pipe(intel_crtc); if (intel_crtc->config->dp_encoder_is_mst) intel_ddi_set_vc_payload_alloc(crtc, false); @@ -9957,6 +9968,47 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc, return tmp & PIPECONF_ENABLE; } +static bool bxt_get_dsi_transcoder_state(struct intel_crtc *crtc, + struct intel_crtc_state *pipe_config, + unsigned long *power_domain_mask) +{ + struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + enum intel_display_power_domain power_domain; + enum port port; + enum transcoder cpu_transcoder; + u32 tmp; + + pipe_config->has_dsi_encoder = false; + + for_each_port_masked(port, BIT(PORT_A) | BIT(PORT_C)) { + if (port == PORT_A) + cpu_transcoder = TRANSCODER_DSI_A; + else + cpu_transcoder = TRANSCODER_DSI_C; + + power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder); + if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) + continue; + *power_domain_mask |= BIT(power_domain); + + /* XXX: this works for video mode only */ + tmp = I915_READ(BXT_MIPI_PORT_CTRL(port)); + if (!(tmp & DPI_ENABLE)) + continue; + + tmp = I915_READ(MIPI_CTRL(port)); + if ((tmp & BXT_PIPE_SELECT_MASK) != BXT_PIPE_SELECT(crtc->pipe)) + continue; + + pipe_config->cpu_transcoder = cpu_transcoder; + pipe_config->has_dsi_encoder = true; + break; + } + + return pipe_config->has_dsi_encoder; +} + static void haswell_get_ddi_port_state(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { @@ -10018,12 +10070,22 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, active = hsw_get_transcoder_state(crtc, pipe_config, &power_domain_mask); + if (IS_BROXTON(dev_priv)) { + bxt_get_dsi_transcoder_state(crtc, pipe_config, + &power_domain_mask); + WARN_ON(active && pipe_config->has_dsi_encoder); + if (pipe_config->has_dsi_encoder) + active = true; + } + if (!active) goto out; - haswell_get_ddi_port_state(crtc, pipe_config); + if (!pipe_config->has_dsi_encoder) { + haswell_get_ddi_port_state(crtc, pipe_config); + intel_get_pipe_timings(crtc, pipe_config); + } - intel_get_pipe_timings(crtc, pipe_config); intel_get_pipe_src_size(crtc, pipe_config); if (INTEL_INFO(dev)->gen >= 9) { @@ -10048,7 +10110,8 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, pipe_config->ips_enabled = hsw_crtc_supports_ips(crtc) && (I915_READ(IPS_CTL) & IPS_ENABLE); - if (pipe_config->cpu_transcoder != TRANSCODER_EDP) { + if (pipe_config->cpu_transcoder != TRANSCODER_EDP && + !transcoder_is_dsi(pipe_config->cpu_transcoder)) { pipe_config->pixel_multiplier = I915_READ(PIPE_MULT(pipe_config->cpu_transcoder)) + 1; } else { @@ -15520,10 +15583,15 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - i915_reg_t reg = PIPECONF(crtc->config->cpu_transcoder); + enum transcoder cpu_transcoder = crtc->config->cpu_transcoder; /* Clear any frame start delays used for debugging left by the BIOS */ - I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK); + if (!transcoder_is_dsi(cpu_transcoder)) { + i915_reg_t reg = PIPECONF(cpu_transcoder); + + I915_WRITE(reg, + I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK); + } /* restore vblank interrupts to correct state */ drm_crtc_vblank_reset(&crtc->base); @@ -16194,6 +16262,7 @@ intel_display_capture_error_state(struct drm_device *dev) error->pipe[i].stat = I915_READ(PIPESTAT(i)); } + /* Note: this does not include DSI transcoders. */ error->num_transcoders = INTEL_INFO(dev)->num_pipes; if (HAS_DDI(dev_priv->dev)) error->num_transcoders++; /* Account for eDP. */ diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 5136eeffc24e..ba45245ad6c8 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -437,7 +437,8 @@ struct intel_crtc_state { bool has_infoframe; /* CPU Transcoder for the pipe. Currently this can only differ from the - * pipe on Haswell (where we have a special eDP transcoder). */ + * pipe on Haswell and later (where we have a special eDP transcoder) + * and Broxton (where we have special DSI transcoders). */ enum transcoder cpu_transcoder; /* diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 3562bf337e62..1981212ffc8d 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -268,6 +268,7 @@ static inline bool is_cmd_mode(struct intel_dsi *intel_dsi) static bool intel_dsi_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; struct intel_dsi *intel_dsi = container_of(encoder, struct intel_dsi, base); struct intel_connector *intel_connector = intel_dsi->attached_connector; @@ -284,6 +285,14 @@ static bool intel_dsi_compute_config(struct intel_encoder *encoder, /* DSI uses short packets for sync events, so clear mode flags for DSI */ adjusted_mode->flags = 0; + if (IS_BROXTON(dev_priv)) { + /* Dual link goes to DSI transcoder A. */ + if (intel_dsi->ports == BIT(PORT_C)) + pipe_config->cpu_transcoder = TRANSCODER_DSI_C; + else + pipe_config->cpu_transcoder = TRANSCODER_DSI_A; + } + return true; } diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 2e88a5e06884..d189a0012277 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -89,6 +89,10 @@ intel_display_power_domain_str(enum intel_display_power_domain domain) return "TRANSCODER_C"; case POWER_DOMAIN_TRANSCODER_EDP: return "TRANSCODER_EDP"; + case POWER_DOMAIN_TRANSCODER_DSI_A: + return "TRANSCODER_DSI_A"; + case POWER_DOMAIN_TRANSCODER_DSI_C: + return "TRANSCODER_DSI_C"; case POWER_DOMAIN_PORT_DDI_A_LANES: return "PORT_DDI_A_LANES"; case POWER_DOMAIN_PORT_DDI_B_LANES: @@ -419,6 +423,8 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv, BXT_DISPLAY_POWERWELL_2_POWER_DOMAINS | \ BIT(POWER_DOMAIN_PIPE_A) | \ BIT(POWER_DOMAIN_TRANSCODER_EDP) | \ + BIT(POWER_DOMAIN_TRANSCODER_DSI_A) | \ + BIT(POWER_DOMAIN_TRANSCODER_DSI_C) | \ BIT(POWER_DOMAIN_PIPE_A_PANEL_FITTER) | \ BIT(POWER_DOMAIN_PORT_DDI_A_LANES) | \ BIT(POWER_DOMAIN_PORT_DSI) | \ -- cgit v1.2.3 From 701d25b40c2e69a0b8e472a8b40a13a0b051bb43 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 18 Mar 2016 17:05:43 +0200 Subject: drm/i915/dsi: use the BIT macro for clarity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No functional changes. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/9115c0a80ad57075700e006db965dd31cc4358fc.1458313400.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_dsi.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 1981212ffc8d..dd6f7bc4f444 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -412,7 +412,7 @@ static void intel_dsi_port_enable(struct intel_encoder *encoder) temp &= ~LANE_CONFIGURATION_MASK; temp &= ~DUAL_LINK_MODE_MASK; - if (intel_dsi->ports == ((1 << PORT_A) | (1 << PORT_C))) { + if (intel_dsi->ports == (BIT(PORT_A) | BIT(PORT_C))) { temp |= (intel_dsi->dual_link - 1) << DUAL_LINK_MODE_SHIFT; temp |= intel_crtc->pipe ? @@ -1200,14 +1200,14 @@ void intel_dsi_init(struct drm_device *dev) /* Pipe A maps to MIPI DSI port A, pipe B maps to MIPI DSI port C */ if (port == PORT_A) - intel_encoder->crtc_mask = 1 << PIPE_A; + intel_encoder->crtc_mask = BIT(PIPE_A); else - intel_encoder->crtc_mask = 1 << PIPE_B; + intel_encoder->crtc_mask = BIT(PIPE_B); if (dev_priv->vbt.dsi.config->dual_link) - intel_dsi->ports = (1 << PORT_A) | (1 << PORT_C); + intel_dsi->ports = BIT(PORT_A) | BIT(PORT_C); else - intel_dsi->ports = 1 << port; + intel_dsi->ports = BIT(port); /* Create a DSI host (and a device) for each port. */ for_each_dsi_port(port, intel_dsi->ports) { -- cgit v1.2.3 From 2e85ab4fed5762f86ae12c0347e64b89412191ca Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 18 Mar 2016 17:05:44 +0200 Subject: drm/i915/bxt: allow dsi on any pipe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BXT isn't as limited as BYT and CHT regarding DSI pipes and ports. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/0375f1e237092d0ae3f39ecfc5702024918acbfd.1458313400.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_dsi.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index dd6f7bc4f444..456676c00059 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -1198,8 +1198,13 @@ void intel_dsi_init(struct drm_device *dev) intel_connector->get_hw_state = intel_connector_get_hw_state; intel_connector->unregister = intel_connector_unregister; - /* Pipe A maps to MIPI DSI port A, pipe B maps to MIPI DSI port C */ - if (port == PORT_A) + /* + * On BYT/CHV, pipe A maps to MIPI DSI port A, pipe B maps to MIPI DSI + * port C. BXT isn't limited like this. + */ + if (IS_BROXTON(dev_priv)) + intel_encoder->crtc_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C); + else if (port == PORT_A) intel_encoder->crtc_mask = BIT(PIPE_A); else intel_encoder->crtc_mask = BIT(PIPE_B); -- cgit v1.2.3 From 3ae36c8b67e450dcb7011181658c198bec386e98 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 20 Mar 2016 08:54:46 +0800 Subject: spi: octeon: Convert to use devm_ioremap_resource Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/spi/spi-octeon.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-octeon.c b/drivers/spi/spi-octeon.c index 07e4ce8273df..3b170093989f 100644 --- a/drivers/spi/spi-octeon.c +++ b/drivers/spi/spi-octeon.c @@ -175,6 +175,7 @@ err: static int octeon_spi_probe(struct platform_device *pdev) { struct resource *res_mem; + void __iomem *reg_base; struct spi_master *master; struct octeon_spi *p; int err = -ENOENT; @@ -186,19 +187,13 @@ static int octeon_spi_probe(struct platform_device *pdev) platform_set_drvdata(pdev, master); res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - if (res_mem == NULL) { - dev_err(&pdev->dev, "found no memory resource\n"); - err = -ENXIO; - goto fail; - } - if (!devm_request_mem_region(&pdev->dev, res_mem->start, - resource_size(res_mem), res_mem->name)) { - dev_err(&pdev->dev, "request_mem_region failed\n"); + reg_base = devm_ioremap_resource(&pdev->dev, res_mem); + if (IS_ERR(reg_base)) { + err = PTR_ERR(reg_base); goto fail; } - p->register_base = (u64)devm_ioremap(&pdev->dev, res_mem->start, - resource_size(res_mem)); + + p->register_base = (u64)reg_base; master->num_chipselect = 4; master->mode_bits = SPI_CPHA | -- cgit v1.2.3 From 8563b1e8ef88c8bdb824ab1c00ebb7d66308fef0 Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Wed, 16 Mar 2016 10:57:14 +0000 Subject: drm/i915: Extract out gamma table and CSC to their own file The moves a couple of functions programming the gamma LUT and CSC units into their own file. On generations prior to Haswell there is only a gamma LUT. From haswell on there is also a new enhanced color correction unit that isn't used yet. This is why we need to set the GAMMA_MODE register, either we're using the legacy 8bits LUT or enhanced LUTs (of 10 or 12bits). The CSC unit is only available from Haswell on. We also need to make a special case for CherryView which is recognized as a gen 8 but doesn't have the same enhanced color correction unit from Haswell on. v2: Fix access to GAMMA_MODE register on older generations than Haswell (from Matt Roper's comments) Signed-off-by: Lionel Landwerlin Reviewed-by: Matt Roper Signed-off-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/1458125837-2576-2-git-send-email-lionel.g.landwerlin@intel.com --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/intel_color.c | 191 +++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_display.c | 171 +++---------------------------- drivers/gpu/drm/i915/intel_drv.h | 10 ++ 5 files changed, 216 insertions(+), 159 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_color.c (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 5558a0312558..7ffb51b0cbc2 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -55,6 +55,7 @@ i915-y += intel_audio.o \ intel_atomic.o \ intel_atomic_plane.o \ intel_bios.o \ + intel_color.o \ intel_display.o \ intel_dpll_mgr.o \ intel_fbc.o \ diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index efca534f9b29..8e5527b1f634 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -629,6 +629,8 @@ struct drm_i915_display_funcs { /* render clock increase/decrease */ /* display clock increase/decrease */ /* pll clock increase/decrease */ + + void (*load_luts)(struct drm_crtc *crtc); }; enum forcewake_domain_id { diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c new file mode 100644 index 000000000000..35b7f62428fc --- /dev/null +++ b/drivers/gpu/drm/i915/intel_color.c @@ -0,0 +1,191 @@ +/* + * Copyright © 2016 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "intel_drv.h" + +/* + * Set up the pipe CSC unit. + * + * Currently only full range RGB to limited range RGB conversion + * is supported, but eventually this should handle various + * RGB<->YCbCr scenarios as well. + */ +static void i9xx_load_csc_matrix(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int pipe = intel_crtc->pipe; + uint16_t coeff = 0x7800; /* 1.0 */ + + /* + * TODO: Check what kind of values actually come out of the pipe + * with these coeff/postoff values and adjust to get the best + * accuracy. Perhaps we even need to take the bpc value into + * consideration. + */ + + if (intel_crtc->config->limited_color_range) + coeff = ((235 - 16) * (1 << 12) / 255) & 0xff8; /* 0.xxx... */ + + I915_WRITE(PIPE_CSC_COEFF_RY_GY(pipe), coeff << 16); + I915_WRITE(PIPE_CSC_COEFF_BY(pipe), 0); + + I915_WRITE(PIPE_CSC_COEFF_RU_GU(pipe), coeff); + I915_WRITE(PIPE_CSC_COEFF_BU(pipe), 0); + + I915_WRITE(PIPE_CSC_COEFF_RV_GV(pipe), 0); + I915_WRITE(PIPE_CSC_COEFF_BV(pipe), coeff << 16); + + I915_WRITE(PIPE_CSC_PREOFF_HI(pipe), 0); + I915_WRITE(PIPE_CSC_PREOFF_ME(pipe), 0); + I915_WRITE(PIPE_CSC_PREOFF_LO(pipe), 0); + + if (INTEL_INFO(dev)->gen > 6) { + uint16_t postoff = 0; + + if (intel_crtc->config->limited_color_range) + postoff = (16 * (1 << 12) / 255) & 0x1fff; + + I915_WRITE(PIPE_CSC_POSTOFF_HI(pipe), postoff); + I915_WRITE(PIPE_CSC_POSTOFF_ME(pipe), postoff); + I915_WRITE(PIPE_CSC_POSTOFF_LO(pipe), postoff); + + I915_WRITE(PIPE_CSC_MODE(pipe), 0); + } else { + uint32_t mode = CSC_MODE_YUV_TO_RGB; + + if (intel_crtc->config->limited_color_range) + mode |= CSC_BLACK_SCREEN_OFFSET; + + I915_WRITE(PIPE_CSC_MODE(pipe), mode); + } +} + +void intel_color_set_csc(struct drm_crtc *crtc) +{ + i9xx_load_csc_matrix(crtc); +} + +/* Loads the palette/gamma unit for the CRTC with the prepared values. */ +static void i9xx_load_luts(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + enum pipe pipe = intel_crtc->pipe; + int i; + + if (HAS_GMCH_DISPLAY(dev)) { + if (intel_crtc->config->has_dsi_encoder) + assert_dsi_pll_enabled(dev_priv); + else + assert_pll_enabled(dev_priv, pipe); + } + + for (i = 0; i < 256; i++) { + uint32_t word = (intel_crtc->lut_r[i] << 16) | + (intel_crtc->lut_g[i] << 8) | + intel_crtc->lut_b[i]; + if (HAS_GMCH_DISPLAY(dev)) + I915_WRITE(PALETTE(pipe, i), word); + else + I915_WRITE(LGC_PALETTE(pipe, i), word); + } +} + +/* Loads the legacy palette/gamma unit for the CRTC on Haswell+. */ +static void haswell_load_luts(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + bool reenable_ips = false; + + /* + * Workaround : Do not read or write the pipe palette/gamma data while + * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled. + */ + if (IS_HASWELL(dev) && intel_crtc->config->ips_enabled && + ((I915_READ(GAMMA_MODE(intel_crtc->pipe)) & GAMMA_MODE_MODE_MASK) == + GAMMA_MODE_MODE_SPLIT)) { + hsw_disable_ips(intel_crtc); + reenable_ips = true; + } + I915_WRITE(GAMMA_MODE(intel_crtc->pipe), GAMMA_MODE_MODE_8BIT); + + i9xx_load_luts(crtc); + + if (reenable_ips) + hsw_enable_ips(intel_crtc); +} + +void intel_color_load_luts(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + + /* The clocks have to be on to load the palette. */ + if (!crtc->state->active) + return; + + dev_priv->display.load_luts(crtc); +} + +void intel_color_legacy_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, + u16 *blue, uint32_t start, uint32_t size) +{ + int end = (start + size > 256) ? 256 : start + size, i; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + + for (i = start; i < end; i++) { + intel_crtc->lut_r[i] = red[i] >> 8; + intel_crtc->lut_g[i] = green[i] >> 8; + intel_crtc->lut_b[i] = blue[i] >> 8; + } + + intel_color_load_luts(crtc); +} + +void intel_color_init(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int i; + + drm_mode_crtc_set_gamma_size(crtc, 256); + for (i = 0; i < 256; i++) { + intel_crtc->lut_r[i] = i; + intel_crtc->lut_g[i] = i; + intel_crtc->lut_b[i] = i; + } + + if (IS_HASWELL(dev) || + (INTEL_INFO(dev)->gen >= 8 && !IS_CHERRYVIEW(dev))) { + dev_priv->display.load_luts = haswell_load_luts; + } else { + dev_priv->display.load_luts = i9xx_load_luts; + } +} diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 28ead66ed987..4e0695dde3d0 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -102,9 +102,7 @@ static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc, struct intel_link_m_n *m2_n2); static void ironlake_set_pipeconf(struct drm_crtc *crtc); static void haswell_set_pipeconf(struct drm_crtc *crtc); -static void haswell_set_pipe_gamma(struct drm_crtc *crtc); static void haswell_set_pipemisc(struct drm_crtc *crtc); -static void intel_set_pipe_csc(struct drm_crtc *crtc); static void vlv_prepare_pll(struct intel_crtc *crtc, const struct intel_crtc_state *pipe_config); static void chv_prepare_pll(struct intel_crtc *crtc, @@ -1183,7 +1181,7 @@ void assert_pll(struct drm_i915_private *dev_priv, } /* XXX: the dsi pll is shared between MIPI DSI ports */ -static void assert_dsi_pll(struct drm_i915_private *dev_priv, bool state) +void assert_dsi_pll(struct drm_i915_private *dev_priv, bool state) { u32 val; bool cur_state; @@ -1197,8 +1195,6 @@ static void assert_dsi_pll(struct drm_i915_private *dev_priv, bool state) "DSI PLL state assertion failure (expected %s, current %s)\n", onoff(state), onoff(cur_state)); } -#define assert_dsi_pll_enabled(d) assert_dsi_pll(d, true) -#define assert_dsi_pll_disabled(d) assert_dsi_pll(d, false) static void assert_fdi_tx(struct drm_i915_private *dev_priv, enum pipe pipe, bool state) @@ -3270,7 +3266,7 @@ static void intel_update_pipe_config(struct intel_crtc *crtc, pipe_config->pipe_src_w, pipe_config->pipe_src_h); if (HAS_DDI(dev)) - intel_set_pipe_csc(&crtc->base); + intel_color_set_csc(&crtc->base); /* * Update pipe size and adjust fitter if needed: the reason for this is @@ -4510,55 +4506,6 @@ void hsw_disable_ips(struct intel_crtc *crtc) intel_wait_for_vblank(dev, crtc->pipe); } -/** Loads the palette/gamma unit for the CRTC with the prepared values */ -static void intel_crtc_load_lut(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - enum pipe pipe = intel_crtc->pipe; - int i; - bool reenable_ips = false; - - /* The clocks have to be on to load the palette. */ - if (!crtc->state->active) - return; - - if (HAS_GMCH_DISPLAY(dev_priv->dev)) { - if (intel_crtc->config->has_dsi_encoder) - assert_dsi_pll_enabled(dev_priv); - else - assert_pll_enabled(dev_priv, pipe); - } - - /* Workaround : Do not read or write the pipe palette/gamma data while - * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled. - */ - if (IS_HASWELL(dev) && intel_crtc->config->ips_enabled && - ((I915_READ(GAMMA_MODE(pipe)) & GAMMA_MODE_MODE_MASK) == - GAMMA_MODE_MODE_SPLIT)) { - hsw_disable_ips(intel_crtc); - reenable_ips = true; - } - - for (i = 0; i < 256; i++) { - i915_reg_t palreg; - - if (HAS_GMCH_DISPLAY(dev)) - palreg = PALETTE(pipe, i); - else - palreg = LGC_PALETTE(pipe, i); - - I915_WRITE(palreg, - (intel_crtc->lut_r[i] << 16) | - (intel_crtc->lut_g[i] << 8) | - intel_crtc->lut_b[i]); - } - - if (reenable_ips) - hsw_enable_ips(intel_crtc); -} - static void intel_crtc_dpms_overlay_disable(struct intel_crtc *intel_crtc) { if (intel_crtc->overlay) { @@ -4863,7 +4810,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) * On ILK+ LUT must be loaded before the pipe is running but with * clocks enabled */ - intel_crtc_load_lut(crtc); + intel_color_load_luts(crtc); if (dev_priv->display.initial_watermarks != NULL) dev_priv->display.initial_watermarks(intel_crtc->config); @@ -4936,10 +4883,9 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) if (!intel_crtc->config->has_dsi_encoder) haswell_set_pipeconf(crtc); - haswell_set_pipe_gamma(crtc); haswell_set_pipemisc(crtc); - intel_set_pipe_csc(crtc); + intel_color_set_csc(crtc); intel_crtc->active = true; @@ -4968,7 +4914,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) * On ILK+ LUT must be loaded before the pipe is running but with * clocks enabled */ - intel_crtc_load_lut(crtc); + intel_color_load_luts(crtc); intel_ddi_set_pipe_settings(crtc); if (!intel_crtc->config->has_dsi_encoder) @@ -6173,7 +6119,7 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) i9xx_pfit_enable(intel_crtc); - intel_crtc_load_lut(crtc); + intel_color_load_luts(crtc); intel_update_watermarks(crtc); intel_enable_pipe(intel_crtc); @@ -6228,7 +6174,7 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) i9xx_pfit_enable(intel_crtc); - intel_crtc_load_lut(crtc); + intel_color_load_luts(crtc); intel_update_watermarks(crtc); intel_enable_pipe(intel_crtc); @@ -8713,70 +8659,6 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc) POSTING_READ(PIPECONF(pipe)); } -/* - * Set up the pipe CSC unit. - * - * Currently only full range RGB to limited range RGB conversion - * is supported, but eventually this should handle various - * RGB<->YCbCr scenarios as well. - */ -static void intel_set_pipe_csc(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - uint16_t coeff = 0x7800; /* 1.0 */ - - /* - * TODO: Check what kind of values actually come out of the pipe - * with these coeff/postoff values and adjust to get the best - * accuracy. Perhaps we even need to take the bpc value into - * consideration. - */ - - if (intel_crtc->config->limited_color_range) - coeff = ((235 - 16) * (1 << 12) / 255) & 0xff8; /* 0.xxx... */ - - /* - * GY/GU and RY/RU should be the other way around according - * to BSpec, but reality doesn't agree. Just set them up in - * a way that results in the correct picture. - */ - I915_WRITE(PIPE_CSC_COEFF_RY_GY(pipe), coeff << 16); - I915_WRITE(PIPE_CSC_COEFF_BY(pipe), 0); - - I915_WRITE(PIPE_CSC_COEFF_RU_GU(pipe), coeff); - I915_WRITE(PIPE_CSC_COEFF_BU(pipe), 0); - - I915_WRITE(PIPE_CSC_COEFF_RV_GV(pipe), 0); - I915_WRITE(PIPE_CSC_COEFF_BV(pipe), coeff << 16); - - I915_WRITE(PIPE_CSC_PREOFF_HI(pipe), 0); - I915_WRITE(PIPE_CSC_PREOFF_ME(pipe), 0); - I915_WRITE(PIPE_CSC_PREOFF_LO(pipe), 0); - - if (INTEL_INFO(dev)->gen > 6) { - uint16_t postoff = 0; - - if (intel_crtc->config->limited_color_range) - postoff = (16 * (1 << 12) / 255) & 0x1fff; - - I915_WRITE(PIPE_CSC_POSTOFF_HI(pipe), postoff); - I915_WRITE(PIPE_CSC_POSTOFF_ME(pipe), postoff); - I915_WRITE(PIPE_CSC_POSTOFF_LO(pipe), postoff); - - I915_WRITE(PIPE_CSC_MODE(pipe), 0); - } else { - uint32_t mode = CSC_MODE_YUV_TO_RGB; - - if (intel_crtc->config->limited_color_range) - mode |= CSC_BLACK_SCREEN_OFFSET; - - I915_WRITE(PIPE_CSC_MODE(pipe), mode); - } -} - static void haswell_set_pipeconf(struct drm_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->dev->dev_private; @@ -8796,15 +8678,6 @@ static void haswell_set_pipeconf(struct drm_crtc *crtc) POSTING_READ(PIPECONF(cpu_transcoder)); } -static void haswell_set_pipe_gamma(struct drm_crtc *crtc) -{ - struct drm_i915_private *dev_priv = crtc->dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - - I915_WRITE(GAMMA_MODE(intel_crtc->pipe), GAMMA_MODE_MODE_8BIT); - POSTING_READ(GAMMA_MODE(intel_crtc->pipe)); -} - static void haswell_set_pipemisc(struct drm_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->dev->dev_private; @@ -10315,21 +10188,6 @@ static bool cursor_size_ok(struct drm_device *dev, return true; } -static void intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, - u16 *blue, uint32_t start, uint32_t size) -{ - int end = (start + size > 256) ? 256 : start + size, i; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - - for (i = start; i < end; i++) { - intel_crtc->lut_r[i] = red[i] >> 8; - intel_crtc->lut_g[i] = green[i] >> 8; - intel_crtc->lut_b[i] = blue[i] >> 8; - } - - intel_crtc_load_lut(crtc); -} - /* VESA 640x480x72Hz mode to set on the pipe */ static struct drm_display_mode load_detect_mode = { DRM_MODE("640x480", DRM_MODE_TYPE_DEFAULT, 31500, 640, 664, @@ -12092,7 +11950,7 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc, static const struct drm_crtc_helper_funcs intel_helper_funcs = { .mode_set_base_atomic = intel_pipe_set_base_atomic, - .load_lut = intel_crtc_load_lut, + .load_lut = intel_color_load_luts, .atomic_begin = intel_begin_crtc_commit, .atomic_flush = intel_finish_crtc_commit, .atomic_check = intel_crtc_atomic_check, @@ -13825,7 +13683,7 @@ out: #undef for_each_intel_crtc_masked static const struct drm_crtc_funcs intel_crtc_funcs = { - .gamma_set = intel_crtc_gamma_set, + .gamma_set = intel_color_legacy_gamma_set, .set_config = drm_atomic_helper_set_config, .destroy = intel_crtc_destroy, .page_flip = intel_crtc_page_flip, @@ -14329,7 +14187,7 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) struct intel_crtc_state *crtc_state = NULL; struct drm_plane *primary = NULL; struct drm_plane *cursor = NULL; - int i, ret; + int ret; intel_crtc = kzalloc(sizeof(*intel_crtc), GFP_KERNEL); if (intel_crtc == NULL) @@ -14365,13 +14223,6 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) if (ret) goto fail; - drm_mode_crtc_set_gamma_size(&intel_crtc->base, 256); - for (i = 0; i < 256; i++) { - intel_crtc->lut_r[i] = i; - intel_crtc->lut_g[i] = i; - intel_crtc->lut_b[i] = i; - } - /* * On gen2/3 only plane A can do fbc, but the panel fitter and lvds port * is hooked to pipe B. Hence we want plane A feeding pipe B. @@ -14396,6 +14247,8 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); + intel_color_init(&intel_crtc->base); + WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); return; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index ba45245ad6c8..5d0da2290bbc 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1199,6 +1199,9 @@ void assert_pll(struct drm_i915_private *dev_priv, enum pipe pipe, bool state); #define assert_pll_enabled(d, p) assert_pll(d, p, true) #define assert_pll_disabled(d, p) assert_pll(d, p, false) +void assert_dsi_pll(struct drm_i915_private *dev_priv, bool state); +#define assert_dsi_pll_enabled(d) assert_dsi_pll(d, true) +#define assert_dsi_pll_disabled(d) assert_dsi_pll(d, false) void assert_fdi_rx_pll(struct drm_i915_private *dev_priv, enum pipe pipe, bool state); #define assert_fdi_rx_pll_enabled(d, p) assert_fdi_rx_pll(d, p, true) @@ -1660,4 +1663,11 @@ void intel_plane_destroy_state(struct drm_plane *plane, struct drm_plane_state *state); extern const struct drm_plane_helper_funcs intel_plane_helper_funcs; +/* intel_color.c */ +void intel_color_init(struct drm_crtc *crtc); +void intel_color_set_csc(struct drm_crtc *crtc); +void intel_color_load_luts(struct drm_crtc *crtc); +void intel_color_legacy_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, + u16 *blue, uint32_t start, uint32_t size); + #endif /* __INTEL_DRV_H__ */ -- cgit v1.2.3 From 05dc698c2e5c9d4453f62fd1cd5acbc68bc97b0f Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Wed, 16 Mar 2016 10:57:15 +0000 Subject: drm/i915: Do not read GAMMA_MODE register Implement Daniel Stone's recommendation to not read registers to infer the hardware's state. v2: Read GAMMA_MODE register value at init (Matt Roper's comment) v3: Read GAMMA_MODE register in intel_modeset_readout_hw_state along with other registers (Matt Roper's comment). v4: Mask GAMMA_MODE register with interesting bits when reading Signed-off-by: Lionel Landwerlin Reviewed-by: Matt Roper Signed-off-by: Matt Roper Link: http://patchwork.freedesktop.org/patch/msgid/1458125837-2576-3-git-send-email-lionel.g.landwerlin@intel.com --- drivers/gpu/drm/i915/intel_color.c | 7 +++++-- drivers/gpu/drm/i915/intel_display.c | 3 +++ drivers/gpu/drm/i915/intel_drv.h | 3 +++ 3 files changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index 35b7f62428fc..16657ebfbb43 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -121,6 +121,8 @@ static void haswell_load_luts(struct drm_crtc *crtc) struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct intel_crtc_state *intel_crtc_state = + to_intel_crtc_state(crtc->state); bool reenable_ips = false; /* @@ -128,11 +130,12 @@ static void haswell_load_luts(struct drm_crtc *crtc) * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled. */ if (IS_HASWELL(dev) && intel_crtc->config->ips_enabled && - ((I915_READ(GAMMA_MODE(intel_crtc->pipe)) & GAMMA_MODE_MODE_MASK) == - GAMMA_MODE_MODE_SPLIT)) { + (intel_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)) { hsw_disable_ips(intel_crtc); reenable_ips = true; } + + intel_crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT; I915_WRITE(GAMMA_MODE(intel_crtc->pipe), GAMMA_MODE_MODE_8BIT); i9xx_load_luts(crtc); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 4e0695dde3d0..a06c656b01fd 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9961,6 +9961,9 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, intel_get_pipe_src_size(crtc, pipe_config); + pipe_config->gamma_mode = + I915_READ(GAMMA_MODE(crtc->pipe)) & GAMMA_MODE_MODE_MASK; + if (INTEL_INFO(dev)->gen >= 9) { skl_init_scalers(dev, crtc, pipe_config); } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 5d0da2290bbc..d4945bbb7d04 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -578,6 +578,9 @@ struct intel_crtc_state { */ bool need_postvbl_update; } wm; + + /* Gamma mode programmed on the pipe */ + uint32_t gamma_mode; }; struct vlv_wm_state { -- cgit v1.2.3 From 82cf435b3134a5f892971b721b34e4c5d249363d Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Wed, 16 Mar 2016 10:57:16 +0000 Subject: drm/i915: Implement color management on bdw/skl/bxt/kbl Patch based on a previous series by Shashank Sharma. v2: Do not read GAMMA_MODE register to figure what mode we're in v3: Program PREC_PAL_GC_MAX to clamp pixel values > 1.0 Add documentation on how the Broadcast RGB property is affected by CTM v4: Update contributors v5: Refactor degamma/gamma LUTs load into a single function v6: Fix missing intel_crtc variable (bisect issue) v7: Fix & simplify limited range matrix multiplication (Matt Roper's comment) Signed-off-by: Shashank Sharma Signed-off-by: Kumar, Kiran S Signed-off-by: Kausal Malladi Signed-off-by: Lionel Landwerlin Acknowledged-by: Matt Roper Signed-off-by: Matt Roper Link: http://patchwork.freedesktop.org/patch/msgid/1458125837-2576-4-git-send-email-lionel.g.landwerlin@intel.com --- Documentation/DocBook/gpu.tmpl | 6 +- drivers/gpu/drm/i915/i915_drv.c | 24 ++- drivers/gpu/drm/i915/i915_drv.h | 6 + drivers/gpu/drm/i915/i915_reg.h | 22 +++ drivers/gpu/drm/i915/intel_color.c | 345 +++++++++++++++++++++++++++++------ drivers/gpu/drm/i915/intel_display.c | 22 ++- drivers/gpu/drm/i915/intel_drv.h | 3 +- drivers/gpu/drm/i915/intel_fbdev.c | 8 + 8 files changed, 371 insertions(+), 65 deletions(-) (limited to 'drivers') diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl index ab7ffebf4b95..1464fb2f3c46 100644 --- a/Documentation/DocBook/gpu.tmpl +++ b/Documentation/DocBook/gpu.tmpl @@ -2153,7 +2153,11 @@ void intel_crt_init(struct drm_device *dev) ENUM { "Automatic", "Full", "Limited 16:235" } Connector - TBD + When this property is set to Limited 16:235 + and CTM is set, the hardware will be programmed with the + result of the multiplication of CTM by the limited range + matrix to ensure the pixels normaly in the range 0..1.0 are + remapped to the range 16/255..235/255. “audio” diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 2a076b005af9..f118a938dcaf 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -66,6 +66,9 @@ static struct drm_driver driver; #define IVB_CURSOR_OFFSETS \ .cursor_offsets = { CURSOR_A_OFFSET, IVB_CURSOR_B_OFFSET, IVB_CURSOR_C_OFFSET } +#define BDW_COLORS \ + .color = { .degamma_lut_size = 512, .gamma_lut_size = 512 } + static const struct intel_device_info intel_i830_info = { .gen = 2, .is_mobile = 1, .cursor_needs_physical = 1, .num_pipes = 2, .has_overlay = 1, .overlay_needs_physical = 1, @@ -288,24 +291,28 @@ static const struct intel_device_info intel_haswell_m_info = { .is_mobile = 1, }; +#define BDW_FEATURES \ + HSW_FEATURES, \ + BDW_COLORS + static const struct intel_device_info intel_broadwell_d_info = { - HSW_FEATURES, + BDW_FEATURES, .gen = 8, }; static const struct intel_device_info intel_broadwell_m_info = { - HSW_FEATURES, + BDW_FEATURES, .gen = 8, .is_mobile = 1, }; static const struct intel_device_info intel_broadwell_gt3d_info = { - HSW_FEATURES, + BDW_FEATURES, .gen = 8, .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, }; static const struct intel_device_info intel_broadwell_gt3m_info = { - HSW_FEATURES, + BDW_FEATURES, .gen = 8, .is_mobile = 1, .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, }; @@ -321,13 +328,13 @@ static const struct intel_device_info intel_cherryview_info = { }; static const struct intel_device_info intel_skylake_info = { - HSW_FEATURES, + BDW_FEATURES, .is_skylake = 1, .gen = 9, }; static const struct intel_device_info intel_skylake_gt3_info = { - HSW_FEATURES, + BDW_FEATURES, .is_skylake = 1, .gen = 9, .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, @@ -345,17 +352,18 @@ static const struct intel_device_info intel_broxton_info = { .has_fbc = 1, GEN_DEFAULT_PIPEOFFSETS, IVB_CURSOR_OFFSETS, + BDW_COLORS, }; static const struct intel_device_info intel_kabylake_info = { - HSW_FEATURES, + BDW_FEATURES, .is_preliminary = 1, .is_kabylake = 1, .gen = 9, }; static const struct intel_device_info intel_kabylake_gt3_info = { - HSW_FEATURES, + BDW_FEATURES, .is_preliminary = 1, .is_kabylake = 1, .gen = 9, diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 8e5527b1f634..050d860115f1 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -630,6 +630,7 @@ struct drm_i915_display_funcs { /* display clock increase/decrease */ /* pll clock increase/decrease */ + void (*load_csc_matrix)(struct drm_crtc *crtc); void (*load_luts)(struct drm_crtc *crtc); }; @@ -781,6 +782,11 @@ struct intel_device_info { u8 has_slice_pg:1; u8 has_subslice_pg:1; u8 has_eu_pg:1; + + struct color_luts { + u16 degamma_lut_size; + u16 gamma_lut_size; + } color; }; #undef DEFINE_FLAG diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 06fb589bbe6b..77efafdddb7f 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7663,6 +7663,28 @@ enum skl_disp_power_wells { #define PIPE_CSC_POSTOFF_ME(pipe) _MMIO_PIPE(pipe, _PIPE_A_CSC_POSTOFF_ME, _PIPE_B_CSC_POSTOFF_ME) #define PIPE_CSC_POSTOFF_LO(pipe) _MMIO_PIPE(pipe, _PIPE_A_CSC_POSTOFF_LO, _PIPE_B_CSC_POSTOFF_LO) +/* pipe degamma/gamma LUTs on IVB+ */ +#define _PAL_PREC_INDEX_A 0x4A400 +#define _PAL_PREC_INDEX_B 0x4AC00 +#define _PAL_PREC_INDEX_C 0x4B400 +#define PAL_PREC_10_12_BIT (0 << 31) +#define PAL_PREC_SPLIT_MODE (1 << 31) +#define PAL_PREC_AUTO_INCREMENT (1 << 15) +#define _PAL_PREC_DATA_A 0x4A404 +#define _PAL_PREC_DATA_B 0x4AC04 +#define _PAL_PREC_DATA_C 0x4B404 +#define _PAL_PREC_GC_MAX_A 0x4A410 +#define _PAL_PREC_GC_MAX_B 0x4AC10 +#define _PAL_PREC_GC_MAX_C 0x4B410 +#define _PAL_PREC_EXT_GC_MAX_A 0x4A420 +#define _PAL_PREC_EXT_GC_MAX_B 0x4AC20 +#define _PAL_PREC_EXT_GC_MAX_C 0x4B420 + +#define PREC_PAL_INDEX(pipe) _MMIO_PIPE(pipe, _PAL_PREC_INDEX_A, _PAL_PREC_INDEX_B) +#define PREC_PAL_DATA(pipe) _MMIO_PIPE(pipe, _PAL_PREC_DATA_A, _PAL_PREC_DATA_B) +#define PREC_PAL_GC_MAX(pipe, i) _MMIO(_PIPE(pipe, _PAL_PREC_GC_MAX_A, _PAL_PREC_GC_MAX_B) + (i) * 4) +#define PREC_PAL_EXT_GC_MAX(pipe, i) _MMIO(_PIPE(pipe, _PAL_PREC_EXT_GC_MAX_A, _PAL_PREC_EXT_GC_MAX_B) + (i) * 4) + /* MIPI DSI registers */ #define _MIPI_PORT(port, a, c) _PORT3(port, a, 0, c) /* ports A and C only */ diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index 16657ebfbb43..c6340d8321c0 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -24,39 +24,155 @@ #include "intel_drv.h" +#define CTM_COEFF_SIGN (1ULL << 63) + +#define CTM_COEFF_1_0 (1ULL << 32) +#define CTM_COEFF_2_0 (CTM_COEFF_1_0 << 1) +#define CTM_COEFF_4_0 (CTM_COEFF_2_0 << 1) +#define CTM_COEFF_0_5 (CTM_COEFF_1_0 >> 1) +#define CTM_COEFF_0_25 (CTM_COEFF_0_5 >> 1) +#define CTM_COEFF_0_125 (CTM_COEFF_0_25 >> 1) + +#define CTM_COEFF_LIMITED_RANGE ((235ULL - 16ULL) * CTM_COEFF_1_0 / 255) + +#define CTM_COEFF_NEGATIVE(coeff) (((coeff) & CTM_COEFF_SIGN) != 0) +#define CTM_COEFF_ABS(coeff) ((coeff) & (CTM_COEFF_SIGN - 1)) + +#define LEGACY_LUT_LENGTH (sizeof(struct drm_color_lut) * 256) + /* - * Set up the pipe CSC unit. + * Extract the CSC coefficient from a CTM coefficient (in U32.32 fixed point + * format). This macro takes the coefficient we want transformed and the + * number of fractional bits. * - * Currently only full range RGB to limited range RGB conversion - * is supported, but eventually this should handle various - * RGB<->YCbCr scenarios as well. + * We only have a 9 bits precision window which slides depending on the value + * of the CTM coefficient and we write the value from bit 3. We also round the + * value. */ +#define I9XX_CSC_COEFF_FP(coeff, fbits) \ + (clamp_val(((coeff) >> (32 - (fbits) - 3)) + 4, 0, 0xfff) & 0xff8) + +#define I9XX_CSC_COEFF_LIMITED_RANGE \ + I9XX_CSC_COEFF_FP(CTM_COEFF_LIMITED_RANGE, 9) +#define I9XX_CSC_COEFF_1_0 \ + ((7 << 12) | I9XX_CSC_COEFF_FP(CTM_COEFF_1_0, 8)) + +static bool crtc_state_is_legacy(struct drm_crtc_state *state) +{ + return !state->degamma_lut && + !state->ctm && + state->gamma_lut && + state->gamma_lut->length == LEGACY_LUT_LENGTH; +} + +/* + * When using limited range, multiply the matrix given by userspace by + * the matrix that we would use for the limited range. We do the + * multiplication in U2.30 format. + */ +static void ctm_mult_by_limited(uint64_t *result, int64_t *input) +{ + int i; + + for (i = 0; i < 9; i++) + result[i] = 0; + + for (i = 0; i < 3; i++) { + int64_t user_coeff = input[i * 3 + i]; + uint64_t limited_coeff = CTM_COEFF_LIMITED_RANGE >> 2; + uint64_t abs_coeff = clamp_val(CTM_COEFF_ABS(user_coeff), + 0, + CTM_COEFF_4_0 - 1) >> 2; + + result[i * 3 + i] = (limited_coeff * abs_coeff) >> 27; + if (CTM_COEFF_NEGATIVE(user_coeff)) + result[i * 3 + i] |= CTM_COEFF_SIGN; + } +} + +/* Set up the pipe CSC unit. */ static void i9xx_load_csc_matrix(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; + struct drm_crtc_state *crtc_state = crtc->state; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - uint16_t coeff = 0x7800; /* 1.0 */ - - /* - * TODO: Check what kind of values actually come out of the pipe - * with these coeff/postoff values and adjust to get the best - * accuracy. Perhaps we even need to take the bpc value into - * consideration. - */ - - if (intel_crtc->config->limited_color_range) - coeff = ((235 - 16) * (1 << 12) / 255) & 0xff8; /* 0.xxx... */ + int i, pipe = intel_crtc->pipe; + uint16_t coeffs[9] = { 0, }; + + if (crtc_state->ctm) { + struct drm_color_ctm *ctm = + (struct drm_color_ctm *)crtc_state->ctm->data; + uint64_t input[9] = { 0, }; + + if (intel_crtc->config->limited_color_range) { + ctm_mult_by_limited(input, ctm->matrix); + } else { + for (i = 0; i < ARRAY_SIZE(input); i++) + input[i] = ctm->matrix[i]; + } + + /* + * Convert fixed point S31.32 input to format supported by the + * hardware. + */ + for (i = 0; i < ARRAY_SIZE(coeffs); i++) { + uint64_t abs_coeff = ((1ULL << 63) - 1) & input[i]; + + /* + * Clamp input value to min/max supported by + * hardware. + */ + abs_coeff = clamp_val(abs_coeff, 0, CTM_COEFF_4_0 - 1); + + /* sign bit */ + if (CTM_COEFF_NEGATIVE(input[i])) + coeffs[i] |= 1 << 15; + + if (abs_coeff < CTM_COEFF_0_125) + coeffs[i] |= (3 << 12) | + I9XX_CSC_COEFF_FP(abs_coeff, 12); + else if (abs_coeff < CTM_COEFF_0_25) + coeffs[i] |= (2 << 12) | + I9XX_CSC_COEFF_FP(abs_coeff, 11); + else if (abs_coeff < CTM_COEFF_0_5) + coeffs[i] |= (1 << 12) | + I9XX_CSC_COEFF_FP(abs_coeff, 10); + else if (abs_coeff < CTM_COEFF_1_0) + coeffs[i] |= I9XX_CSC_COEFF_FP(abs_coeff, 9); + else if (abs_coeff < CTM_COEFF_2_0) + coeffs[i] |= (7 << 12) | + I9XX_CSC_COEFF_FP(abs_coeff, 8); + else + coeffs[i] |= (6 << 12) | + I9XX_CSC_COEFF_FP(abs_coeff, 7); + } + } else { + /* + * Load an identity matrix if no coefficients are provided. + * + * TODO: Check what kind of values actually come out of the + * pipe with these coeff/postoff values and adjust to get the + * best accuracy. Perhaps we even need to take the bpc value + * into consideration. + */ + for (i = 0; i < 3; i++) { + if (intel_crtc->config->limited_color_range) + coeffs[i * 3 + i] = + I9XX_CSC_COEFF_LIMITED_RANGE; + else + coeffs[i * 3 + i] = I9XX_CSC_COEFF_1_0; + } + } - I915_WRITE(PIPE_CSC_COEFF_RY_GY(pipe), coeff << 16); - I915_WRITE(PIPE_CSC_COEFF_BY(pipe), 0); + I915_WRITE(PIPE_CSC_COEFF_RY_GY(pipe), coeffs[0] << 16 | coeffs[1]); + I915_WRITE(PIPE_CSC_COEFF_BY(pipe), coeffs[2] << 16); - I915_WRITE(PIPE_CSC_COEFF_RU_GU(pipe), coeff); - I915_WRITE(PIPE_CSC_COEFF_BU(pipe), 0); + I915_WRITE(PIPE_CSC_COEFF_RU_GU(pipe), coeffs[3] << 16 | coeffs[4]); + I915_WRITE(PIPE_CSC_COEFF_BU(pipe), coeffs[5] << 16); - I915_WRITE(PIPE_CSC_COEFF_RV_GV(pipe), 0); - I915_WRITE(PIPE_CSC_COEFF_BV(pipe), coeff << 16); + I915_WRITE(PIPE_CSC_COEFF_RV_GV(pipe), coeffs[6] << 16 | coeffs[7]); + I915_WRITE(PIPE_CSC_COEFF_BV(pipe), coeffs[8] << 16); I915_WRITE(PIPE_CSC_PREOFF_HI(pipe), 0); I915_WRITE(PIPE_CSC_PREOFF_ME(pipe), 0); @@ -85,13 +201,18 @@ static void i9xx_load_csc_matrix(struct drm_crtc *crtc) void intel_color_set_csc(struct drm_crtc *crtc) { - i9xx_load_csc_matrix(crtc); + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + + if (dev_priv->display.load_csc_matrix) + dev_priv->display.load_csc_matrix(crtc); } -/* Loads the palette/gamma unit for the CRTC with the prepared values. */ +/* Loads the legacy palette/gamma unit for the CRTC. */ static void i9xx_load_luts(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; + struct drm_crtc_state *state = crtc->state; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); enum pipe pipe = intel_crtc->pipe; @@ -104,18 +225,33 @@ static void i9xx_load_luts(struct drm_crtc *crtc) assert_pll_enabled(dev_priv, pipe); } - for (i = 0; i < 256; i++) { - uint32_t word = (intel_crtc->lut_r[i] << 16) | - (intel_crtc->lut_g[i] << 8) | - intel_crtc->lut_b[i]; - if (HAS_GMCH_DISPLAY(dev)) - I915_WRITE(PALETTE(pipe, i), word); - else - I915_WRITE(LGC_PALETTE(pipe, i), word); + if (state->gamma_lut) { + struct drm_color_lut *lut = + (struct drm_color_lut *) state->gamma_lut->data; + for (i = 0; i < 256; i++) { + uint32_t word = + (drm_color_lut_extract(lut[i].red, 8) << 16) | + (drm_color_lut_extract(lut[i].green, 8) << 8) | + drm_color_lut_extract(lut[i].blue, 8); + + if (HAS_GMCH_DISPLAY(dev)) + I915_WRITE(PALETTE(pipe, i), word); + else + I915_WRITE(LGC_PALETTE(pipe, i), word); + } + } else { + for (i = 0; i < 256; i++) { + uint32_t word = (i << 16) | (i << 8) | i; + + if (HAS_GMCH_DISPLAY(dev)) + I915_WRITE(PALETTE(pipe, i), word); + else + I915_WRITE(LGC_PALETTE(pipe, i), word); + } } } -/* Loads the legacy palette/gamma unit for the CRTC on Haswell+. */ +/* Loads the legacy palette/gamma unit for the CRTC on Haswell. */ static void haswell_load_luts(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; @@ -144,6 +280,89 @@ static void haswell_load_luts(struct drm_crtc *crtc) hsw_enable_ips(intel_crtc); } +/* Loads the palette/gamma unit for the CRTC on Broadwell+. */ +static void broadwell_load_luts(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_crtc_state *state = crtc->state; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc_state *intel_state = to_intel_crtc_state(state); + enum pipe pipe = to_intel_crtc(crtc)->pipe; + uint32_t i, lut_size = INTEL_INFO(dev)->color.degamma_lut_size; + + if (crtc_state_is_legacy(state)) { + haswell_load_luts(crtc); + return; + } + + I915_WRITE(PREC_PAL_INDEX(pipe), + PAL_PREC_SPLIT_MODE | PAL_PREC_AUTO_INCREMENT); + + if (state->degamma_lut) { + struct drm_color_lut *lut = + (struct drm_color_lut *) state->degamma_lut->data; + + for (i = 0; i < lut_size; i++) { + uint32_t word = + drm_color_lut_extract(lut[i].red, 10) << 20 | + drm_color_lut_extract(lut[i].green, 10) << 10 | + drm_color_lut_extract(lut[i].blue, 10); + + I915_WRITE(PREC_PAL_DATA(pipe), word); + } + } else { + for (i = 0; i < lut_size; i++) { + uint32_t v = (i * ((1 << 10) - 1)) / (lut_size - 1); + + I915_WRITE(PREC_PAL_DATA(pipe), + (v << 20) | (v << 10) | v); + } + } + + if (state->gamma_lut) { + struct drm_color_lut *lut = + (struct drm_color_lut *) state->gamma_lut->data; + + for (i = 0; i < lut_size; i++) { + uint32_t word = + (drm_color_lut_extract(lut[i].red, 10) << 20) | + (drm_color_lut_extract(lut[i].green, 10) << 10) | + drm_color_lut_extract(lut[i].blue, 10); + + I915_WRITE(PREC_PAL_DATA(pipe), word); + } + + /* Program the max register to clamp values > 1.0. */ + I915_WRITE(PREC_PAL_GC_MAX(pipe, 0), + drm_color_lut_extract(lut[i].red, 16)); + I915_WRITE(PREC_PAL_GC_MAX(pipe, 1), + drm_color_lut_extract(lut[i].green, 16)); + I915_WRITE(PREC_PAL_GC_MAX(pipe, 2), + drm_color_lut_extract(lut[i].blue, 16)); + } else { + for (i = 0; i < lut_size; i++) { + uint32_t v = (i * ((1 << 10) - 1)) / (lut_size - 1); + + I915_WRITE(PREC_PAL_DATA(pipe), + (v << 20) | (v << 10) | v); + } + + I915_WRITE(PREC_PAL_GC_MAX(pipe, 0), (1 << 16) - 1); + I915_WRITE(PREC_PAL_GC_MAX(pipe, 1), (1 << 16) - 1); + I915_WRITE(PREC_PAL_GC_MAX(pipe, 2), (1 << 16) - 1); + } + + intel_state->gamma_mode = GAMMA_MODE_MODE_SPLIT; + I915_WRITE(GAMMA_MODE(pipe), GAMMA_MODE_MODE_SPLIT); + POSTING_READ(GAMMA_MODE(pipe)); + + /* + * Reset the index, otherwise it prevents the legacy palette to be + * written properly. + */ + I915_WRITE(PREC_PAL_INDEX(pipe), 0); +} + void intel_color_load_luts(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; @@ -156,39 +375,61 @@ void intel_color_load_luts(struct drm_crtc *crtc) dev_priv->display.load_luts(crtc); } -void intel_color_legacy_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, - u16 *blue, uint32_t start, uint32_t size) +int intel_color_check(struct drm_crtc *crtc, + struct drm_crtc_state *crtc_state) { - int end = (start + size > 256) ? 256 : start + size, i; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct drm_device *dev = crtc->dev; + size_t gamma_length, degamma_length; - for (i = start; i < end; i++) { - intel_crtc->lut_r[i] = red[i] >> 8; - intel_crtc->lut_g[i] = green[i] >> 8; - intel_crtc->lut_b[i] = blue[i] >> 8; - } + degamma_length = INTEL_INFO(dev)->color.degamma_lut_size * + sizeof(struct drm_color_lut); + gamma_length = INTEL_INFO(dev)->color.gamma_lut_size * + sizeof(struct drm_color_lut); - intel_color_load_luts(crtc); + /* + * We allow both degamma & gamma luts at the right size or + * NULL. + */ + if ((!crtc_state->degamma_lut || + crtc_state->degamma_lut->length == degamma_length) && + (!crtc_state->gamma_lut || + crtc_state->gamma_lut->length == gamma_length)) + return 0; + + /* + * We also allow no degamma lut and a gamma lut at the legacy + * size (256 entries). + */ + if (!crtc_state->degamma_lut && + crtc_state->gamma_lut && + crtc_state->gamma_lut->length == LEGACY_LUT_LENGTH) + return 0; + + return -EINVAL; } void intel_color_init(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int i; drm_mode_crtc_set_gamma_size(crtc, 256); - for (i = 0; i < 256; i++) { - intel_crtc->lut_r[i] = i; - intel_crtc->lut_g[i] = i; - intel_crtc->lut_b[i] = i; - } - if (IS_HASWELL(dev) || - (INTEL_INFO(dev)->gen >= 8 && !IS_CHERRYVIEW(dev))) { + if (IS_HASWELL(dev)) { + dev_priv->display.load_csc_matrix = i9xx_load_csc_matrix; dev_priv->display.load_luts = haswell_load_luts; + } else if (IS_BROADWELL(dev) || IS_SKYLAKE(dev) || + IS_BROXTON(dev) || IS_KABYLAKE(dev)) { + dev_priv->display.load_csc_matrix = i9xx_load_csc_matrix; + dev_priv->display.load_luts = broadwell_load_luts; } else { dev_priv->display.load_luts = i9xx_load_luts; } + + /* Enable color management support when we have degamma & gamma LUTs. */ + if (INTEL_INFO(dev)->color.degamma_lut_size != 0 && + INTEL_INFO(dev)->color.gamma_lut_size != 0) + drm_helper_crtc_enable_color_mgmt(crtc, + INTEL_INFO(dev)->color.degamma_lut_size, + INTEL_INFO(dev)->color.gamma_lut_size); } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a06c656b01fd..602d23cd2b0c 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11911,6 +11911,12 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc, return ret; } + if (crtc_state->color_mgmt_changed) { + ret = intel_color_check(crtc, crtc_state); + if (ret) + return ret; + } + ret = 0; if (dev_priv->display.compute_pipe_wm) { ret = dev_priv->display.compute_pipe_wm(pipe_config); @@ -11953,7 +11959,6 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc, static const struct drm_crtc_helper_funcs intel_helper_funcs = { .mode_set_base_atomic = intel_pipe_set_base_atomic, - .load_lut = intel_color_load_luts, .atomic_begin = intel_begin_crtc_commit, .atomic_flush = intel_finish_crtc_commit, .atomic_check = intel_crtc_atomic_check, @@ -13576,6 +13581,18 @@ static int intel_atomic_commit(struct drm_device *dev, dev_priv->display.crtc_enable(crtc); } + if (!modeset && + crtc->state->active && + crtc->state->color_mgmt_changed) { + /* + * Only update color management when not doing + * a modeset as this will be done by + * crtc_enable already. + */ + intel_color_set_csc(crtc); + intel_color_load_luts(crtc); + } + if (!modeset) intel_pre_plane_update(to_intel_crtc_state(old_crtc_state)); @@ -13686,8 +13703,9 @@ out: #undef for_each_intel_crtc_masked static const struct drm_crtc_funcs intel_crtc_funcs = { - .gamma_set = intel_color_legacy_gamma_set, + .gamma_set = drm_atomic_helper_legacy_gamma_set, .set_config = drm_atomic_helper_set_config, + .set_property = drm_atomic_helper_crtc_set_property, .destroy = intel_crtc_destroy, .page_flip = intel_crtc_page_flip, .atomic_duplicate_state = intel_crtc_duplicate_state, diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index d4945bbb7d04..c87b4503435d 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1668,9 +1668,8 @@ extern const struct drm_plane_helper_funcs intel_plane_helper_funcs; /* intel_color.c */ void intel_color_init(struct drm_crtc *crtc); +int intel_color_check(struct drm_crtc *crtc, struct drm_crtc_state *state); void intel_color_set_csc(struct drm_crtc *crtc); void intel_color_load_luts(struct drm_crtc *crtc); -void intel_color_legacy_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, - u16 *blue, uint32_t start, uint32_t size); #endif /* __INTEL_DRV_H__ */ diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index ea4188ac2e73..5e0dcb3961be 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -379,6 +379,7 @@ retry: struct drm_connector *connector; struct drm_encoder *encoder; struct drm_fb_helper_crtc *new_crtc; + struct intel_crtc *intel_crtc; fb_conn = fb_helper->connector_info[i]; connector = fb_conn->connector; @@ -420,6 +421,13 @@ retry: num_connectors_enabled++; + intel_crtc = to_intel_crtc(connector->state->crtc); + for (j = 0; j < 256; j++) { + intel_crtc->lut_r[j] = j; + intel_crtc->lut_g[j] = j; + intel_crtc->lut_b[j] = j; + } + new_crtc = intel_fb_helper_crtc(fb_helper, connector->state->crtc); /* -- cgit v1.2.3 From 29dc3739e50da3576ddf89d9ea2704640676135d Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Wed, 16 Mar 2016 10:57:17 +0000 Subject: drm/i915: Implement color management on chv Patch based on a previous series by Shashank Sharma. v2: Update contributors v3: Refactor degamma/gamma LUTs load into a single function v4: Remove unused variable Signed-off-by: Shashank Sharma Signed-off-by: Kumar, Kiran S Signed-off-by: Kausal Malladi Signed-off-by: Lionel Landwerlin Reviewed-by: Matt Roper Signed-off-by: Matt Roper Link: http://patchwork.freedesktop.org/patch/msgid/1458125837-2576-5-git-send-email-lionel.g.landwerlin@intel.com --- drivers/gpu/drm/i915/i915_drv.c | 3 + drivers/gpu/drm/i915/i915_reg.h | 31 +++++++++ drivers/gpu/drm/i915/intel_color.c | 133 +++++++++++++++++++++++++++++++++++-- 3 files changed, 161 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index f118a938dcaf..20f8dbe7b21c 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -68,6 +68,8 @@ static struct drm_driver driver; #define BDW_COLORS \ .color = { .degamma_lut_size = 512, .gamma_lut_size = 512 } +#define CHV_COLORS \ + .color = { .degamma_lut_size = 65, .gamma_lut_size = 257 } static const struct intel_device_info intel_i830_info = { .gen = 2, .is_mobile = 1, .cursor_needs_physical = 1, .num_pipes = 2, @@ -325,6 +327,7 @@ static const struct intel_device_info intel_cherryview_info = { .display_mmio_offset = VLV_DISPLAY_BASE, GEN_CHV_PIPEOFFSETS, CURSOR_OFFSETS, + CHV_COLORS, }; static const struct intel_device_info intel_skylake_info = { diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 77efafdddb7f..23ca6c052e63 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7685,6 +7685,37 @@ enum skl_disp_power_wells { #define PREC_PAL_GC_MAX(pipe, i) _MMIO(_PIPE(pipe, _PAL_PREC_GC_MAX_A, _PAL_PREC_GC_MAX_B) + (i) * 4) #define PREC_PAL_EXT_GC_MAX(pipe, i) _MMIO(_PIPE(pipe, _PAL_PREC_EXT_GC_MAX_A, _PAL_PREC_EXT_GC_MAX_B) + (i) * 4) +/* pipe CSC & degamma/gamma LUTs on CHV */ +#define _CGM_PIPE_A_CSC_COEFF01 (VLV_DISPLAY_BASE + 0x67900) +#define _CGM_PIPE_A_CSC_COEFF23 (VLV_DISPLAY_BASE + 0x67904) +#define _CGM_PIPE_A_CSC_COEFF45 (VLV_DISPLAY_BASE + 0x67908) +#define _CGM_PIPE_A_CSC_COEFF67 (VLV_DISPLAY_BASE + 0x6790C) +#define _CGM_PIPE_A_CSC_COEFF8 (VLV_DISPLAY_BASE + 0x67910) +#define _CGM_PIPE_A_DEGAMMA (VLV_DISPLAY_BASE + 0x66000) +#define _CGM_PIPE_A_GAMMA (VLV_DISPLAY_BASE + 0x67000) +#define _CGM_PIPE_A_MODE (VLV_DISPLAY_BASE + 0x67A00) +#define CGM_PIPE_MODE_GAMMA (1 << 2) +#define CGM_PIPE_MODE_CSC (1 << 1) +#define CGM_PIPE_MODE_DEGAMMA (1 << 0) + +#define _CGM_PIPE_B_CSC_COEFF01 (VLV_DISPLAY_BASE + 0x69900) +#define _CGM_PIPE_B_CSC_COEFF23 (VLV_DISPLAY_BASE + 0x69904) +#define _CGM_PIPE_B_CSC_COEFF45 (VLV_DISPLAY_BASE + 0x69908) +#define _CGM_PIPE_B_CSC_COEFF67 (VLV_DISPLAY_BASE + 0x6990C) +#define _CGM_PIPE_B_CSC_COEFF8 (VLV_DISPLAY_BASE + 0x69910) +#define _CGM_PIPE_B_DEGAMMA (VLV_DISPLAY_BASE + 0x68000) +#define _CGM_PIPE_B_GAMMA (VLV_DISPLAY_BASE + 0x69000) +#define _CGM_PIPE_B_MODE (VLV_DISPLAY_BASE + 0x69A00) + +#define CGM_PIPE_CSC_COEFF01(pipe) _MMIO_PIPE(pipe, _CGM_PIPE_A_CSC_COEFF01, _CGM_PIPE_B_CSC_COEFF01) +#define CGM_PIPE_CSC_COEFF23(pipe) _MMIO_PIPE(pipe, _CGM_PIPE_A_CSC_COEFF23, _CGM_PIPE_B_CSC_COEFF23) +#define CGM_PIPE_CSC_COEFF45(pipe) _MMIO_PIPE(pipe, _CGM_PIPE_A_CSC_COEFF45, _CGM_PIPE_B_CSC_COEFF45) +#define CGM_PIPE_CSC_COEFF67(pipe) _MMIO_PIPE(pipe, _CGM_PIPE_A_CSC_COEFF67, _CGM_PIPE_B_CSC_COEFF67) +#define CGM_PIPE_CSC_COEFF8(pipe) _MMIO_PIPE(pipe, _CGM_PIPE_A_CSC_COEFF8, _CGM_PIPE_B_CSC_COEFF8) +#define CGM_PIPE_DEGAMMA(pipe, i, w) _MMIO(_PIPE(pipe, _CGM_PIPE_A_DEGAMMA, _CGM_PIPE_B_DEGAMMA) + (i) * 8 + (w) * 4) +#define CGM_PIPE_GAMMA(pipe, i, w) _MMIO(_PIPE(pipe, _CGM_PIPE_A_GAMMA, _CGM_PIPE_B_GAMMA) + (i) * 8 + (w) * 4) +#define CGM_PIPE_MODE(pipe) _MMIO_PIPE(pipe, _CGM_PIPE_A_MODE, _CGM_PIPE_B_MODE) + /* MIPI DSI registers */ #define _MIPI_PORT(port, a, c) _PORT3(port, a, 0, c) /* ports A and C only */ diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index c6340d8321c0..aa0b20dcb834 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -29,6 +29,7 @@ #define CTM_COEFF_1_0 (1ULL << 32) #define CTM_COEFF_2_0 (CTM_COEFF_1_0 << 1) #define CTM_COEFF_4_0 (CTM_COEFF_2_0 << 1) +#define CTM_COEFF_8_0 (CTM_COEFF_4_0 << 1) #define CTM_COEFF_0_5 (CTM_COEFF_1_0 >> 1) #define CTM_COEFF_0_25 (CTM_COEFF_0_5 >> 1) #define CTM_COEFF_0_125 (CTM_COEFF_0_25 >> 1) @@ -199,6 +200,58 @@ static void i9xx_load_csc_matrix(struct drm_crtc *crtc) } } +/* + * Set up the pipe CSC unit on CherryView. + */ +static void cherryview_load_csc_matrix(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_crtc_state *state = crtc->state; + struct drm_i915_private *dev_priv = dev->dev_private; + int pipe = to_intel_crtc(crtc)->pipe; + uint32_t mode; + + if (state->ctm) { + struct drm_color_ctm *ctm = + (struct drm_color_ctm *) state->ctm->data; + uint16_t coeffs[9] = { 0, }; + int i; + + for (i = 0; i < ARRAY_SIZE(coeffs); i++) { + uint64_t abs_coeff = + ((1ULL << 63) - 1) & ctm->matrix[i]; + + /* Round coefficient. */ + abs_coeff += 1 << (32 - 13); + /* Clamp to hardware limits. */ + abs_coeff = clamp_val(abs_coeff, 0, CTM_COEFF_8_0 - 1); + + /* Write coefficients in S3.12 format. */ + if (ctm->matrix[i] & (1ULL << 63)) + coeffs[i] = 1 << 15; + coeffs[i] |= ((abs_coeff >> 32) & 7) << 12; + coeffs[i] |= (abs_coeff >> 20) & 0xfff; + } + + I915_WRITE(CGM_PIPE_CSC_COEFF01(pipe), + coeffs[1] << 16 | coeffs[0]); + I915_WRITE(CGM_PIPE_CSC_COEFF23(pipe), + coeffs[3] << 16 | coeffs[2]); + I915_WRITE(CGM_PIPE_CSC_COEFF45(pipe), + coeffs[5] << 16 | coeffs[4]); + I915_WRITE(CGM_PIPE_CSC_COEFF67(pipe), + coeffs[7] << 16 | coeffs[6]); + I915_WRITE(CGM_PIPE_CSC_COEFF8(pipe), coeffs[8]); + } + + mode = (state->ctm ? CGM_PIPE_MODE_CSC : 0); + if (!crtc_state_is_legacy(state)) { + mode |= (state->degamma_lut ? CGM_PIPE_MODE_DEGAMMA : 0) | + (state->gamma_lut ? CGM_PIPE_MODE_GAMMA : 0); + } + I915_WRITE(CGM_PIPE_MODE(pipe), mode); +} + void intel_color_set_csc(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; @@ -209,10 +262,10 @@ void intel_color_set_csc(struct drm_crtc *crtc) } /* Loads the legacy palette/gamma unit for the CRTC. */ -static void i9xx_load_luts(struct drm_crtc *crtc) +static void i9xx_load_luts_internal(struct drm_crtc *crtc, + struct drm_property_blob *blob) { struct drm_device *dev = crtc->dev; - struct drm_crtc_state *state = crtc->state; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); enum pipe pipe = intel_crtc->pipe; @@ -225,9 +278,8 @@ static void i9xx_load_luts(struct drm_crtc *crtc) assert_pll_enabled(dev_priv, pipe); } - if (state->gamma_lut) { - struct drm_color_lut *lut = - (struct drm_color_lut *) state->gamma_lut->data; + if (blob) { + struct drm_color_lut *lut = (struct drm_color_lut *) blob->data; for (i = 0; i < 256; i++) { uint32_t word = (drm_color_lut_extract(lut[i].red, 8) << 16) | @@ -251,6 +303,11 @@ static void i9xx_load_luts(struct drm_crtc *crtc) } } +static void i9xx_load_luts(struct drm_crtc *crtc) +{ + i9xx_load_luts_internal(crtc, crtc->state->gamma_lut); +} + /* Loads the legacy palette/gamma unit for the CRTC on Haswell. */ static void haswell_load_luts(struct drm_crtc *crtc) { @@ -363,6 +420,67 @@ static void broadwell_load_luts(struct drm_crtc *crtc) I915_WRITE(PREC_PAL_INDEX(pipe), 0); } +/* Loads the palette/gamma unit for the CRTC on CherryView. */ +static void cherryview_load_luts(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_crtc_state *state = crtc->state; + enum pipe pipe = to_intel_crtc(crtc)->pipe; + struct drm_color_lut *lut; + uint32_t i, lut_size; + uint32_t word0, word1; + + if (crtc_state_is_legacy(state)) { + /* Turn off degamma/gamma on CGM block. */ + I915_WRITE(CGM_PIPE_MODE(pipe), + (state->ctm ? CGM_PIPE_MODE_CSC : 0)); + i9xx_load_luts_internal(crtc, state->gamma_lut); + return; + } + + if (state->degamma_lut) { + lut = (struct drm_color_lut *) state->degamma_lut->data; + lut_size = INTEL_INFO(dev)->color.degamma_lut_size; + for (i = 0; i < lut_size; i++) { + /* Write LUT in U0.14 format. */ + word0 = + (drm_color_lut_extract(lut[i].green, 14) << 16) | + drm_color_lut_extract(lut[i].blue, 14); + word1 = drm_color_lut_extract(lut[i].red, 14); + + I915_WRITE(CGM_PIPE_DEGAMMA(pipe, i, 0), word0); + I915_WRITE(CGM_PIPE_DEGAMMA(pipe, i, 1), word1); + } + } + + if (state->gamma_lut) { + lut = (struct drm_color_lut *) state->gamma_lut->data; + lut_size = INTEL_INFO(dev)->color.gamma_lut_size; + for (i = 0; i < lut_size; i++) { + /* Write LUT in U0.10 format. */ + word0 = + (drm_color_lut_extract(lut[i].green, 10) << 16) | + drm_color_lut_extract(lut[i].blue, 10); + word1 = drm_color_lut_extract(lut[i].red, 10); + + I915_WRITE(CGM_PIPE_GAMMA(pipe, i, 0), word0); + I915_WRITE(CGM_PIPE_GAMMA(pipe, i, 1), word1); + } + } + + I915_WRITE(CGM_PIPE_MODE(pipe), + (state->ctm ? CGM_PIPE_MODE_CSC : 0) | + (state->degamma_lut ? CGM_PIPE_MODE_DEGAMMA : 0) | + (state->gamma_lut ? CGM_PIPE_MODE_GAMMA : 0)); + + /* + * Also program a linear LUT in the legacy block (behind the + * CGM block). + */ + i9xx_load_luts_internal(crtc, NULL); +} + void intel_color_load_luts(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; @@ -415,7 +533,10 @@ void intel_color_init(struct drm_crtc *crtc) drm_mode_crtc_set_gamma_size(crtc, 256); - if (IS_HASWELL(dev)) { + if (IS_CHERRYVIEW(dev)) { + dev_priv->display.load_csc_matrix = cherryview_load_csc_matrix; + dev_priv->display.load_luts = cherryview_load_luts; + } else if (IS_HASWELL(dev)) { dev_priv->display.load_csc_matrix = i9xx_load_csc_matrix; dev_priv->display.load_luts = haswell_load_luts; } else if (IS_BROADWELL(dev) || IS_SKYLAKE(dev) || -- cgit v1.2.3 From d1ef4f2cae6705925088047554e89c34048f926a Mon Sep 17 00:00:00 2001 From: Marc Titinger Date: Mon, 14 Mar 2016 11:20:44 +0100 Subject: iio: ina2xx-adc: update the CALIB. register when RShunt changes The user (or an init script) may setup RShunt via sysfs after the driver was initialized, for instance based on the EEPROM contents of a modular probe. The calibration register must be set accordingly. Signed-off-by: Marc Titinger Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ina2xx-adc.c | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c index 65909d5858b1..4e56fe3580bf 100644 --- a/drivers/iio/adc/ina2xx-adc.c +++ b/drivers/iio/adc/ina2xx-adc.c @@ -350,6 +350,23 @@ static ssize_t ina2xx_allow_async_readout_store(struct device *dev, return len; } +/* + * Set current LSB to 1mA, shunt is in uOhms + * (equation 13 in datasheet). We hardcode a Current_LSB + * of 1.0 x10-6. The only remaining parameter is RShunt. + * There is no need to expose the CALIBRATION register + * to the user for now. But we need to reset this register + * if the user updates RShunt after driver init, e.g upon + * reading an EEPROM/Probe-type value. + */ +static int ina2xx_set_calibration(struct ina2xx_chip_info *chip) +{ + u16 regval = DIV_ROUND_CLOSEST(chip->config->calibration_factor, + chip->shunt_resistor); + + return regmap_write(chip->regmap, INA2XX_CALIBRATION, regval); +} + static int set_shunt_resistor(struct ina2xx_chip_info *chip, unsigned int val) { if (val <= 0 || val > chip->config->calibration_factor) @@ -385,6 +402,11 @@ static ssize_t ina2xx_shunt_resistor_store(struct device *dev, if (ret) return ret; + /* Update the Calibration register */ + ret = ina2xx_set_calibration(chip); + if (ret) + return ret; + return len; } @@ -602,24 +624,11 @@ static const struct iio_info ina2xx_info = { /* Initialize the configuration and calibration registers. */ static int ina2xx_init(struct ina2xx_chip_info *chip, unsigned int config) { - u16 regval; - int ret; - - ret = regmap_write(chip->regmap, INA2XX_CONFIG, config); + int ret = regmap_write(chip->regmap, INA2XX_CONFIG, config); if (ret) return ret; - /* - * Set current LSB to 1mA, shunt is in uOhms - * (equation 13 in datasheet). We hardcode a Current_LSB - * of 1.0 x10-6. The only remaining parameter is RShunt. - * There is no need to expose the CALIBRATION register - * to the user for now. - */ - regval = DIV_ROUND_CLOSEST(chip->config->calibration_factor, - chip->shunt_resistor); - - return regmap_write(chip->regmap, INA2XX_CALIBRATION, regval); + return ina2xx_set_calibration(chip); } static int ina2xx_probe(struct i2c_client *client, -- cgit v1.2.3 From fc0768ceac126ea6ec2ff8bd56bbe4abe11695bc Mon Sep 17 00:00:00 2001 From: Tomas Elf Date: Mon, 21 Mar 2016 16:26:59 +0000 Subject: drm/i915/tdr: Initialize hangcheck struct for each engine Initialize hangcheck struct during driver load. Since we do the same after recovering from a reset, this is extracted into a helper function. v2: remove redundant hangcheck init during load as this is done when engines are initialized (Chris) Cc: Mika Kuoppala Signed-off-by: Tomas Elf Signed-off-by: Arun Siluvery Reviewed-by: Chris Wilson Signed-off-by: Mika Kuoppala Link: http://patchwork.freedesktop.org/patch/msgid/1458577619-12006-1-git-send-email-arun.siluvery@linux.intel.com --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_lrc.c | 2 +- drivers/gpu/drm/i915/intel_ringbuffer.c | 7 ++++++- 3 files changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 050d860115f1..56eb5f0d9f38 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2740,6 +2740,7 @@ extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, extern int intel_gpu_reset(struct drm_device *dev, u32 engine_mask); extern bool intel_has_gpu_reset(struct drm_device *dev); extern int i915_reset(struct drm_device *dev); +extern void intel_engine_init_hangcheck(struct intel_engine_cs *engine); extern unsigned long i915_chipset_val(struct drm_i915_private *dev_priv); extern unsigned long i915_mch_val(struct drm_i915_private *dev_priv); extern unsigned long i915_gfx_val(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 3a23b9549f7b..40ef4eaf580f 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1606,7 +1606,7 @@ static int gen8_init_common_ring(struct intel_engine_cs *engine) engine->next_context_status_buffer = next_context_status_buffer_hw; DRM_DEBUG_DRIVER("Execlists enabled for %s\n", engine->name); - memset(&engine->hangcheck, 0, sizeof(engine->hangcheck)); + intel_engine_init_hangcheck(engine); return 0; } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index df0ef5bba8e5..ce59850f7e73 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -555,6 +555,11 @@ static bool stop_ring(struct intel_engine_cs *engine) return (I915_READ_HEAD(engine) & HEAD_ADDR) == 0; } +void intel_engine_init_hangcheck(struct intel_engine_cs *engine) +{ + memset(&engine->hangcheck, 0, sizeof(engine->hangcheck)); +} + static int init_ring_common(struct intel_engine_cs *engine) { struct drm_device *dev = engine->dev; @@ -634,7 +639,7 @@ static int init_ring_common(struct intel_engine_cs *engine) ringbuf->tail = I915_READ_TAIL(engine) & TAIL_ADDR; intel_ring_update_space(ringbuf); - memset(&engine->hangcheck, 0, sizeof(engine->hangcheck)); + intel_engine_init_hangcheck(engine); out: intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); -- cgit v1.2.3 From 14b730fcb8d9b9c6fed540829548040ef8d2ca2c Mon Sep 17 00:00:00 2001 From: "arun.siluvery@linux.intel.com" Date: Fri, 18 Mar 2016 20:07:55 +0000 Subject: drm/i915/tdr: Prepare error handler to accept mask of hung engines In preparation for engine reset, the wedged argument of i915_handle_error() is extended to reflect as a mask of engines that are hung. This is further passed down to error state capture functions which are also updated. Engine reset recovery mechanism uses this mask and schedules recovery work for those particular engines. Cc: Chris Wilson Cc: Mika Kuoppala Signed-off-by: Tomas Elf Signed-off-by: Arun Siluvery Reviewed-by: Mika Kuoppala Signed-off-by: Mika Kuoppala Link: http://patchwork.freedesktop.org/patch/msgid/1458331676-567-3-git-send-email-arun.siluvery@linux.intel.com --- drivers/gpu/drm/i915/i915_drv.h | 4 ++-- drivers/gpu/drm/i915/i915_gpu_error.c | 8 ++++---- drivers/gpu/drm/i915/i915_irq.c | 16 ++++++++-------- 3 files changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 56eb5f0d9f38..9d29ab06c99a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2757,7 +2757,7 @@ bool intel_hpd_pin_to_port(enum hpd_pin pin, enum port *port); /* i915_irq.c */ void i915_queue_hangcheck(struct drm_device *dev); __printf(3, 4) -void i915_handle_error(struct drm_device *dev, bool wedged, +void i915_handle_error(struct drm_device *dev, u32 engine_mask, const char *fmt, ...); extern void intel_irq_init(struct drm_i915_private *dev_priv); @@ -3343,7 +3343,7 @@ static inline void i915_error_state_buf_release( { kfree(eb->buf); } -void i915_capture_error_state(struct drm_device *dev, bool wedge, +void i915_capture_error_state(struct drm_device *dev, u32 engine_mask, const char *error_msg); void i915_error_state_get(struct drm_device *dev, struct i915_error_state_file_priv *error_priv); diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index db8600ae5a54..1f8ff06eed6b 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -1301,7 +1301,7 @@ static void i915_capture_reg_state(struct drm_i915_private *dev_priv, static void i915_error_capture_msg(struct drm_device *dev, struct drm_i915_error_state *error, - bool wedged, + u32 engine_mask, const char *error_msg) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -1324,7 +1324,7 @@ static void i915_error_capture_msg(struct drm_device *dev, scnprintf(error->error_msg + len, sizeof(error->error_msg) - len, ", reason: %s, action: %s", error_msg, - wedged ? "reset" : "continue"); + engine_mask ? "reset" : "continue"); } static void i915_capture_gen_state(struct drm_i915_private *dev_priv, @@ -1347,7 +1347,7 @@ static void i915_capture_gen_state(struct drm_i915_private *dev_priv, * out a structure which becomes available in debugfs for user level tools * to pick up. */ -void i915_capture_error_state(struct drm_device *dev, bool wedged, +void i915_capture_error_state(struct drm_device *dev, u32 engine_mask, const char *error_msg) { static bool warned; @@ -1375,7 +1375,7 @@ void i915_capture_error_state(struct drm_device *dev, bool wedged, error->overlay = intel_overlay_capture_error_state(dev); error->display = intel_display_capture_error_state(dev); - i915_error_capture_msg(dev, error, wedged, error_msg); + i915_error_capture_msg(dev, error, engine_mask, error_msg); DRM_INFO("%s\n", error->error_msg); spin_lock_irqsave(&dev_priv->gpu_error.lock, flags); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 8f3e3309c3ab..a55a7cc317f8 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2653,14 +2653,14 @@ static void i915_report_and_clear_eir(struct drm_device *dev) /** * i915_handle_error - handle a gpu error * @dev: drm device - * + * @engine_mask: mask representing engines that are hung * Do some basic checking of register state at error time and * dump it to the syslog. Also call i915_capture_error_state() to make * sure we get a record and make it available in debugfs. Fire a uevent * so userspace knows something bad happened (should trigger collection * of a ring dump etc.). */ -void i915_handle_error(struct drm_device *dev, bool wedged, +void i915_handle_error(struct drm_device *dev, u32 engine_mask, const char *fmt, ...) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -2671,10 +2671,10 @@ void i915_handle_error(struct drm_device *dev, bool wedged, vscnprintf(error_msg, sizeof(error_msg), fmt, args); va_end(args); - i915_capture_error_state(dev, wedged, error_msg); + i915_capture_error_state(dev, engine_mask, error_msg); i915_report_and_clear_eir(dev); - if (wedged) { + if (engine_mask) { atomic_or(I915_RESET_IN_PROGRESS_FLAG, &dev_priv->gpu_error.reset_counter); @@ -3033,7 +3033,7 @@ ring_stuck(struct intel_engine_cs *engine, u64 acthd) */ tmp = I915_READ_CTL(engine); if (tmp & RING_WAIT) { - i915_handle_error(dev, false, + i915_handle_error(dev, 0, "Kicking stuck wait on %s", engine->name); I915_WRITE_CTL(engine, tmp); @@ -3045,7 +3045,7 @@ ring_stuck(struct intel_engine_cs *engine, u64 acthd) default: return HANGCHECK_HUNG; case 1: - i915_handle_error(dev, false, + i915_handle_error(dev, 0, "Kicking stuck semaphore on %s", engine->name); I915_WRITE_CTL(engine, tmp); @@ -3189,12 +3189,12 @@ static void i915_hangcheck_elapsed(struct work_struct *work) DRM_INFO("%s on %s\n", stuck[i] ? "stuck" : "no progress", engine->name); - rings_hung++; + rings_hung |= intel_engine_flag(engine); } } if (rings_hung) { - i915_handle_error(dev, true, "Ring hung"); + i915_handle_error(dev, rings_hung, "Engine(s) hung"); goto out; } -- cgit v1.2.3 From 177246a84d133888b5428e44201282d94635f473 Mon Sep 17 00:00:00 2001 From: Matt Roper Date: Fri, 4 Mar 2016 15:59:39 -0800 Subject: drm/i915: Wait until after wm optimization to drop runtime PM reference MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At the end of an atomic commit, we currently wait for vblanks to complete, call put() on the various runtime PM references, and then try to optimize our watermarks (on platforms that need two-step watermark programming). This can lead to watermark registers being programmed while the power well is powered down. We need to wait until after watermark optimization is complete before dropping our runtime power references. Note that in the future the watermark optimization is probably going to move to an asynchronous workqueue task that happens at some arbitrary point after vblank. When we make that change, we'll no longer necessarily be operating under the power reference held here, so we'll need to wrap the watermark register programmin in a call to intel_runtime_pm_get_if_in_use() or similar. Cc: arun.siluvery@linux.intel.com Cc: ville.syrjala@linux.intel.com Cc: maarten.lankhorst@linux.intel.com Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94349 Fixes: ed4a6a7ca853 ("drm/i915: Add two-stage ILK-style watermark programming (v11)") Signed-off-by: Matt Roper Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1457135979-23727-1-git-send-email-matthew.d.roper@intel.com --- drivers/gpu/drm/i915/intel_display.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 602d23cd2b0c..47332a164fcb 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13613,16 +13613,6 @@ static int intel_atomic_commit(struct drm_device *dev, if (!state->legacy_cursor_update) intel_atomic_wait_for_vblanks(dev, dev_priv, crtc_vblank_mask); - for_each_crtc_in_state(state, crtc, old_crtc_state, i) { - intel_post_plane_update(to_intel_crtc_state(old_crtc_state)); - - if (put_domains[i]) - modeset_put_power_domains(dev_priv, put_domains[i]); - } - - if (intel_state->modeset) - intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET); - /* * Now that the vblank has passed, we can go ahead and program the * optimal watermarks on platforms that need two-step watermark @@ -13637,6 +13627,16 @@ static int intel_atomic_commit(struct drm_device *dev, dev_priv->display.optimize_watermarks(intel_cstate); } + for_each_crtc_in_state(state, crtc, old_crtc_state, i) { + intel_post_plane_update(to_intel_crtc_state(old_crtc_state)); + + if (put_domains[i]) + modeset_put_power_domains(dev_priv, put_domains[i]); + } + + if (intel_state->modeset) + intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET); + mutex_lock(&dev->struct_mutex); drm_atomic_helper_cleanup_planes(dev, state); mutex_unlock(&dev->struct_mutex); -- cgit v1.2.3 From ad45d83968caf8e757cf895f4fd53903a092fad8 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 21 Mar 2016 17:08:57 +0200 Subject: drm/i915: Make __i915_printk debug output behave the same as DRM_DEBUG_DRIVER Joonas and Daniel remarked that our debugging output should stay compatible with the core DRM's debug facility. The recently added __i915_printk() would output debug messages even if debugging is completely disabled via the drm.debug option. To fix this make __i915_printk behave the same as DRM_DEBUG_DRIVER in this case. CC: Joonas Lahtinen CC: Daniel Vetter CC: Chris Wilson Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1458572937-21712-1-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_dma.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 3f439a08387e..a3458fcd83dc 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -77,9 +77,13 @@ __i915_printk(struct drm_i915_private *dev_priv, const char *level, static bool shown_bug_once; struct device *dev = dev_priv->dev->dev; bool is_error = level[1] <= KERN_ERR[1]; + bool is_debug = level[1] == KERN_DEBUG[1]; struct va_format vaf; va_list args; + if (is_debug && !(drm_debug & DRM_UT_DRIVER)) + return; + va_start(args, fmt); vaf.fmt = fmt; -- cgit v1.2.3 From c6c794a2fc5e3bc8976fa318fbc7a003ecd712a1 Mon Sep 17 00:00:00 2001 From: Shashank Sharma Date: Tue, 22 Mar 2016 12:01:50 +0200 Subject: drm/i915/bxt: Initialize MIPI DSI for BXT This patch contains following changes: 1. Add BXT MIPI display address base. 2. Call dsi_init from display_setup function. v2: Rebased on latest nightly branch v3 by Jani: init dsi after ddi Signed-off-by: Shashank Sharma Signed-off-by: Uma Shankar Acked-by: Daniel Vetter Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1458640910-5338-1-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_display.c | 2 ++ drivers/gpu/drm/i915/intel_dsi.c | 2 ++ 3 files changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 23ca6c052e63..f3ba43c2ca22 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1802,6 +1802,7 @@ enum skl_disp_power_wells { #define VLV_DISPLAY_BASE 0x180000 #define VLV_MIPI_BASE VLV_DISPLAY_BASE +#define BXT_MIPI_BASE 0x60000 #define VLV_GU_CTL0 _MMIO(VLV_DISPLAY_BASE + 0x2030) #define VLV_GU_CTL1 _MMIO(VLV_DISPLAY_BASE + 0x2034) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 47332a164fcb..51f913fb199d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -14394,6 +14394,8 @@ static void intel_setup_outputs(struct drm_device *dev) intel_ddi_init(dev, PORT_A); intel_ddi_init(dev, PORT_B); intel_ddi_init(dev, PORT_C); + + intel_dsi_init(dev); } else if (HAS_DDI(dev)) { int found; diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 456676c00059..96ea3f741a89 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -1163,6 +1163,8 @@ void intel_dsi_init(struct drm_device *dev) if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) { dev_priv->mipi_mmio_base = VLV_MIPI_BASE; + } else if (IS_BROXTON(dev)) { + dev_priv->mipi_mmio_base = BXT_MIPI_BASE; } else { DRM_ERROR("Unsupported Mipi device to reg base"); return; -- cgit v1.2.3 From 2dc10cd8bc2662d0311224d92fb82f34be0424bc Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Wed, 23 Mar 2016 10:31:46 +0200 Subject: drm/i915: Fix use after free when printing load failure Commit d15d7538c6d2 ("drm/i915: Tune down init error message due to failure injection") added i915_load_error message to failure path on device initialization. The message is printed after the device is freed. And as the message printing helper uses the device structure, this leads to use after free. Spotted by Kasan. Cc: Imre Deak Cc: Chris Wilson Signed-off-by: Mika Kuoppala Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1458721906-10625-1-git-send-email-mika.kuoppala@intel.com --- drivers/gpu/drm/i915/i915_dma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index a3458fcd83dc..fc8ac98c12d7 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1398,10 +1398,10 @@ out_runtime_pm_put: intel_runtime_pm_put(dev_priv); i915_driver_cleanup_early(dev_priv); out_free_priv: - kfree(dev_priv); - i915_load_error(dev_priv, "Device initialization failed (%d)\n", ret); + kfree(dev_priv); + return ret; } -- cgit v1.2.3 From 90e83e5390a04d31eb2846293cd3db506c2315e7 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Tue, 22 Mar 2016 10:11:24 +0200 Subject: drm/i915: Wait for vblank in i9xx_disable_crtc() for gen 2 only The wait for other gens was added in commit 564ed191f5d8 ("drm/i915: gmch: fix stuck primary plane due to memory self-refresh mode") since that's necessary when disabling cxsr. However, cxsr disabling was later moved to intel_pre_disable_primary() in commit 87d4300a7dbc ("drm/i915: Move intel_(pre_disable/post_enable)_primary to intel_display.c, and use it there.") and that function got its own vblank wait for cxsr in commit 262cd2e154c2 ("drm/i915: CHV DDR DVFS support and another watermark rewrite"). So remove the extra vblank wait from i9xx_crtc_distable(). Cc: Kalyan Kondapally Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1458634284-6080-1-git-send-email-ander.conselvan.de.oliveira@intel.com --- drivers/gpu/drm/i915/intel_display.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 51f913fb199d..d007f048d221 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6212,10 +6212,9 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) /* * On gen2 planes are double buffered but the pipe isn't, so we must * wait for planes to fully turn off before disabling the pipe. - * We also need to wait on all gmch platforms because of the - * self-refresh mode constraint explained above. */ - intel_wait_for_vblank(dev, pipe); + if (IS_GEN2(dev)) + intel_wait_for_vblank(dev, pipe); for_each_encoder_on_crtc(dev, crtc, encoder) encoder->disable(encoder); -- cgit v1.2.3 From ceb41007b42bbc9e4be1cf17575b01de6c3b3b18 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Mon, 21 Mar 2016 18:00:02 +0200 Subject: drm/i915: Remove checks for cloned config with LVDS in dpll code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LVDS is not cloneable, so the check is unnecessary. Removing it makes the code neater. v2: Remove checks from GMCH code too, not only ILK+. (Ville) Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1458576016-30348-2-git-send-email-ander.conselvan.de.oliveira@intel.com --- drivers/gpu/drm/i915/intel_display.c | 70 +++++++++--------------------------- 1 file changed, 16 insertions(+), 54 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d007f048d221..d147d2fe5ada 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -111,8 +111,7 @@ static void intel_begin_crtc_commit(struct drm_crtc *, struct drm_crtc_state *); static void intel_finish_crtc_commit(struct drm_crtc *, struct drm_crtc_state *); static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state); -static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state, - int num_connectors); +static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state); static void skylake_pfit_enable(struct intel_crtc *crtc); static void ironlake_pfit_disable(struct intel_crtc *crtc, bool force); static void ironlake_pfit_enable(struct intel_crtc *crtc); @@ -1074,7 +1073,7 @@ chv_find_best_dpll(const intel_limit_t *limit, bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state, int target_clock, intel_clock_t *best_clock) { - int refclk = i9xx_get_refclk(crtc_state, 0); + int refclk = i9xx_get_refclk(crtc_state); return chv_find_best_dpll(intel_limit(crtc_state, refclk), crtc_state, target_clock, refclk, NULL, best_clock); @@ -7058,8 +7057,7 @@ static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv) && !(dev_priv->quirks & QUIRK_LVDS_SSC_DISABLE); } -static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state, - int num_connectors) +static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state) { struct drm_device *dev = crtc_state->base.crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -7070,7 +7068,7 @@ static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state, if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev) || IS_BROXTON(dev)) { refclk = 100000; } else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) && - intel_panel_use_ssc(dev_priv) && num_connectors < 2) { + intel_panel_use_ssc(dev_priv)) { refclk = dev_priv->vbt.lvds_ssc_freq; DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", refclk); } else if (!IS_GEN2(dev)) { @@ -7511,8 +7509,7 @@ void vlv_force_pll_off(struct drm_device *dev, enum pipe pipe) static void i9xx_compute_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, - intel_clock_t *reduced_clock, - int num_connectors) + intel_clock_t *reduced_clock) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -7571,7 +7568,7 @@ static void i9xx_compute_dpll(struct intel_crtc *crtc, if (crtc_state->sdvo_tv_clock) dpll |= PLL_REF_INPUT_TVCLKINBC; else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) && - intel_panel_use_ssc(dev_priv) && num_connectors < 2) + intel_panel_use_ssc(dev_priv)) dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; else dpll |= PLL_REF_INPUT_DREFCLK; @@ -7588,8 +7585,7 @@ static void i9xx_compute_dpll(struct intel_crtc *crtc, static void i8xx_compute_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, - intel_clock_t *reduced_clock, - int num_connectors) + intel_clock_t *reduced_clock) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -7615,7 +7611,7 @@ static void i8xx_compute_dpll(struct intel_crtc *crtc, dpll |= DPLL_DVO_2X_MODE; if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) && - intel_panel_use_ssc(dev_priv) && num_connectors < 2) + intel_panel_use_ssc(dev_priv)) dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; else dpll |= PLL_REF_INPUT_DREFCLK; @@ -7843,14 +7839,10 @@ static int i9xx_crtc_compute_clock(struct intel_crtc *crtc, { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - int refclk, num_connectors = 0; + int refclk; intel_clock_t clock; bool ok; const intel_limit_t *limit; - struct drm_atomic_state *state = crtc_state->base.state; - struct drm_connector *connector; - struct drm_connector_state *connector_state; - int i; memset(&crtc_state->dpll_hw_state, 0, sizeof(crtc_state->dpll_hw_state)); @@ -7858,13 +7850,8 @@ static int i9xx_crtc_compute_clock(struct intel_crtc *crtc, if (crtc_state->has_dsi_encoder) return 0; - for_each_connector_in_state(state, connector, connector_state, i) { - if (connector_state->crtc == &crtc->base) - num_connectors++; - } - if (!crtc_state->clock_set) { - refclk = i9xx_get_refclk(crtc_state, num_connectors); + refclk = i9xx_get_refclk(crtc_state); /* * Returns a set of divisors for the desired target clock with @@ -7890,15 +7877,13 @@ static int i9xx_crtc_compute_clock(struct intel_crtc *crtc, } if (IS_GEN2(dev)) { - i8xx_compute_dpll(crtc, crtc_state, NULL, - num_connectors); + i8xx_compute_dpll(crtc, crtc_state, NULL); } else if (IS_CHERRYVIEW(dev)) { chv_compute_dpll(crtc, crtc_state); } else if (IS_VALLEYVIEW(dev)) { vlv_compute_dpll(crtc, crtc_state); } else { - i9xx_compute_dpll(crtc, crtc_state, NULL, - num_connectors); + i9xx_compute_dpll(crtc, crtc_state, NULL); } return 0; @@ -8584,30 +8569,9 @@ static int ironlake_get_refclk(struct intel_crtc_state *crtc_state) { struct drm_device *dev = crtc_state->base.crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_atomic_state *state = crtc_state->base.state; - struct drm_connector *connector; - struct drm_connector_state *connector_state; - struct intel_encoder *encoder; - int num_connectors = 0, i; - bool is_lvds = false; - - for_each_connector_in_state(state, connector, connector_state, i) { - if (connector_state->crtc != crtc_state->base.crtc) - continue; - - encoder = to_intel_encoder(connector_state->best_encoder); - - switch (encoder->type) { - case INTEL_OUTPUT_LVDS: - is_lvds = true; - break; - default: - break; - } - num_connectors++; - } - if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) { + if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) && + intel_panel_use_ssc(dev_priv)) { DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", dev_priv->vbt.lvds_ssc_freq); return dev_priv->vbt.lvds_ssc_freq; @@ -8768,7 +8732,7 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, struct drm_connector_state *connector_state; struct intel_encoder *encoder; uint32_t dpll; - int factor, num_connectors = 0, i; + int factor, i; bool is_lvds = false, is_sdvo = false; for_each_connector_in_state(state, connector, connector_state, i) { @@ -8788,8 +8752,6 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, default: break; } - - num_connectors++; } /* Enable autotuning of the PLL clock (if permissible) */ @@ -8843,7 +8805,7 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, break; } - if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) + if (is_lvds && intel_panel_use_ssc(dev_priv)) dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; else dpll |= PLL_REF_INPUT_DREFCLK; -- cgit v1.2.3 From 26ce6d5980fa399e7ca4cb83414ece931ce316ba Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Mon, 21 Mar 2016 18:00:03 +0200 Subject: drm/i915: Merge ironlake_get_refclk() into its only caller A previous patch made ironlake_get_refclk() very simple, so merge it into its only caller. Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1458576016-30348-3-git-send-email-ander.conselvan.de.oliveira@intel.com --- drivers/gpu/drm/i915/intel_display.c | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d147d2fe5ada..78fb86c3808f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8565,21 +8565,6 @@ void intel_init_pch_refclk(struct drm_device *dev) lpt_init_pch_refclk(dev); } -static int ironlake_get_refclk(struct intel_crtc_state *crtc_state) -{ - struct drm_device *dev = crtc_state->base.crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - - if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) && - intel_panel_use_ssc(dev_priv)) { - DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", - dev_priv->vbt.lvds_ssc_freq); - return dev_priv->vbt.lvds_ssc_freq; - } - - return 120000; -} - static void ironlake_set_pipeconf(struct drm_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->dev->dev_private; @@ -8686,7 +8671,14 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc, const intel_limit_t *limit; bool ret; - refclk = ironlake_get_refclk(crtc_state); + if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) && + intel_panel_use_ssc(dev_priv)) { + DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", + dev_priv->vbt.lvds_ssc_freq); + refclk = dev_priv->vbt.lvds_ssc_freq; + } else { + refclk = 120000; + } /* * Returns a set of divisors for the desired target clock with the given -- cgit v1.2.3 From 8f0d5b9b5891d7e29513bba44fe6c5c3d84df1d8 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Mon, 21 Mar 2016 18:00:04 +0200 Subject: drm/i915: Fold intel_ironlake_limit() into clock computation function The function intel_ironlake_limit() is only called by the crtc compute clock path. By merging it into ironlake_compute_clocks(), the code gets clearer, since there's no more if-ladders to follow. Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1458576016-30348-4-git-send-email-ander.conselvan.de.oliveira@intel.com --- drivers/gpu/drm/i915/intel_display.c | 56 +++++++++++++++--------------------- 1 file changed, 23 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 78fb86c3808f..8c90426f001e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -565,30 +565,6 @@ static bool intel_pipe_will_have_type(const struct intel_crtc_state *crtc_state, return false; } -static const intel_limit_t * -intel_ironlake_limit(struct intel_crtc_state *crtc_state, int refclk) -{ - struct drm_device *dev = crtc_state->base.crtc->dev; - const intel_limit_t *limit; - - if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) { - if (intel_is_dual_link_lvds(dev)) { - if (refclk == 100000) - limit = &intel_limits_ironlake_dual_lvds_100m; - else - limit = &intel_limits_ironlake_dual_lvds; - } else { - if (refclk == 100000) - limit = &intel_limits_ironlake_single_lvds_100m; - else - limit = &intel_limits_ironlake_single_lvds; - } - } else - limit = &intel_limits_ironlake_dac; - - return limit; -} - static const intel_limit_t * intel_g4x_limit(struct intel_crtc_state *crtc_state) { @@ -619,8 +595,8 @@ intel_limit(struct intel_crtc_state *crtc_state, int refclk) if (IS_BROXTON(dev)) limit = &intel_limits_bxt; - else if (HAS_PCH_SPLIT(dev)) - limit = intel_ironlake_limit(crtc_state, refclk); + else if (WARN_ON(HAS_PCH_SPLIT(dev))) + limit = NULL; else if (IS_G4X(dev)) { limit = intel_g4x_limit(crtc_state); } else if (IS_PINEVIEW(dev)) { @@ -8671,13 +8647,28 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc, const intel_limit_t *limit; bool ret; - if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) && - intel_panel_use_ssc(dev_priv)) { - DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", - dev_priv->vbt.lvds_ssc_freq); - refclk = dev_priv->vbt.lvds_ssc_freq; + refclk = 120000; + + if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) { + if (intel_panel_use_ssc(dev_priv)) { + DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", + dev_priv->vbt.lvds_ssc_freq); + refclk = dev_priv->vbt.lvds_ssc_freq; + } + + if (intel_is_dual_link_lvds(dev)) { + if (refclk == 100000) + limit = &intel_limits_ironlake_dual_lvds_100m; + else + limit = &intel_limits_ironlake_dual_lvds; + } else { + if (refclk == 100000) + limit = &intel_limits_ironlake_single_lvds_100m; + else + limit = &intel_limits_ironlake_single_lvds; + } } else { - refclk = 120000; + limit = &intel_limits_ironlake_dac; } /* @@ -8685,7 +8676,6 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc, * refclk, or FALSE. The returned values represent the clock equation: * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. */ - limit = intel_limit(crtc_state, refclk); ret = dev_priv->display.find_dpll(limit, crtc_state, crtc_state->port_clock, refclk, NULL, clock); -- cgit v1.2.3 From 2d7feacc817e8882ab87f29e468918f6dbabf611 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Mon, 21 Mar 2016 18:00:05 +0200 Subject: drm/i915: Call g4x_find_best_dpll() directly from ILK+ code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The call to dev_priv->display.find_dpll() is already in platform specific code, so avoid the extra detour. Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Ville Syrjälä Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1458576016-30348-5-git-send-email-ander.conselvan.de.oliveira@intel.com --- drivers/gpu/drm/i915/intel_display.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8c90426f001e..14f6e3055b44 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8676,9 +8676,8 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc, * refclk, or FALSE. The returned values represent the clock equation: * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. */ - ret = dev_priv->display.find_dpll(limit, crtc_state, - crtc_state->port_clock, - refclk, NULL, clock); + ret = g4x_find_best_dpll(limit, crtc_state, crtc_state->port_clock, + refclk, NULL, clock); if (!ret) return false; -- cgit v1.2.3 From bfa044457c8a0ea20f4aee33337232a3bcfa1dcf Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Mon, 21 Mar 2016 18:00:06 +0200 Subject: drm/i915: Simplify ironlake reduced clock logic a bit Check has_reduced_clock only once when setting dpll_hw_state, making the code slightly more readable. Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1458576016-30348-6-git-send-email-ander.conselvan.de.oliveira@intel.com --- drivers/gpu/drm/i915/intel_display.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 14f6e3055b44..25d763918cba 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8832,6 +8832,8 @@ static int ironlake_crtc_compute_clock(struct intel_crtc *crtc, fp = i9xx_dpll_compute_fp(&crtc_state->dpll); if (has_reduced_clock) fp2 = i9xx_dpll_compute_fp(&reduced_clock); + else + fp2 = fp; dpll = ironlake_compute_dpll(crtc, crtc_state, &fp, &reduced_clock, @@ -8839,10 +8841,7 @@ static int ironlake_crtc_compute_clock(struct intel_crtc *crtc, crtc_state->dpll_hw_state.dpll = dpll; crtc_state->dpll_hw_state.fp0 = fp; - if (has_reduced_clock) - crtc_state->dpll_hw_state.fp1 = fp2; - else - crtc_state->dpll_hw_state.fp1 = fp; + crtc_state->dpll_hw_state.fp1 = fp2; pll = intel_get_shared_dpll(crtc, crtc_state, NULL); if (pll == NULL) { -- cgit v1.2.3 From 7ed9f894e55e5a623c640d2e5be5db2b0bf14374 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Mon, 21 Mar 2016 18:00:07 +0200 Subject: drm/i915: Don't calculate a new clock in ILK+ code if it is already set Remove the clock calculation from ironlake_crtc_compute_clock() when the encoder compute_config() already set one. The value was just thrown away in that case. Note that the previously set clock is not validated against the limits anymore. That is ok since the fixed clocks from DP and SDVO are within the supported range, so the call to ironlake_compute_clocks() would never fail in that case. v2: Add note about not checking fixed clocks agains limits. (Maarten) Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1458576016-30348-7-git-send-email-ander.conselvan.de.oliveira@intel.com --- drivers/gpu/drm/i915/intel_display.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 25d763918cba..2df5dbf90692 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8800,7 +8800,7 @@ static int ironlake_crtc_compute_clock(struct intel_crtc *crtc, struct drm_device *dev = crtc->base.dev; intel_clock_t clock, reduced_clock; u32 dpll = 0, fp = 0, fp2 = 0; - bool ok, has_reduced_clock = false; + bool has_reduced_clock = false; bool is_lvds = false; struct intel_shared_dpll *pll; @@ -8812,14 +8812,15 @@ static int ironlake_crtc_compute_clock(struct intel_crtc *crtc, WARN(!(HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)), "Unexpected PCH type %d\n", INTEL_PCH_TYPE(dev)); - ok = ironlake_compute_clocks(&crtc->base, crtc_state, &clock, - &has_reduced_clock, &reduced_clock); - if (!ok && !crtc_state->clock_set) { - DRM_ERROR("Couldn't find PLL settings for mode!\n"); - return -EINVAL; - } - /* Compat-code for transition, will disappear. */ if (!crtc_state->clock_set) { + if (!ironlake_compute_clocks(&crtc->base, crtc_state, &clock, + &has_reduced_clock, + &reduced_clock)) { + DRM_ERROR("Couldn't find PLL settings for mode!\n"); + return -EINVAL; + } + + /* Compat-code for transition, will disappear. */ crtc_state->dpll.n = clock.n; crtc_state->dpll.m1 = clock.m1; crtc_state->dpll.m2 = clock.m2; -- cgit v1.2.3 From fade85ae2122cd6f136cbbfe2c1a392910354cdf Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Mon, 21 Mar 2016 18:00:08 +0200 Subject: drm/i915: Remove PCH type checks from ironlake_crtc_compute_clock() The checks were added in commit 5dc5298bb3e5 ("drm/i915: add proper CPU/PCH checks to crtc_mode_set functions") in a time when there was doubts on what PCHs would be supported by HSW. There are similar checks for PCH type in intel_detect_pch() and the function pointers are initialized based on platform/pch information, so the removed WARN can't ever be reached. v2: Rebase without patch that drops lvds downclock code. (Ville) Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1458576016-30348-8-git-send-email-ander.conselvan.de.oliveira@intel.com --- drivers/gpu/drm/i915/intel_display.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2df5dbf90692..c6920fc17154 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8797,7 +8797,6 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, static int ironlake_crtc_compute_clock(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state) { - struct drm_device *dev = crtc->base.dev; intel_clock_t clock, reduced_clock; u32 dpll = 0, fp = 0, fp2 = 0; bool has_reduced_clock = false; @@ -8809,9 +8808,6 @@ static int ironlake_crtc_compute_clock(struct intel_crtc *crtc, is_lvds = intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS); - WARN(!(HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)), - "Unexpected PCH type %d\n", INTEL_PCH_TYPE(dev)); - if (!crtc_state->clock_set) { if (!ironlake_compute_clocks(&crtc->base, crtc_state, &clock, &has_reduced_clock, -- cgit v1.2.3 From ded220e2513dee45807ba586a566f64b2887c2c4 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Mon, 21 Mar 2016 18:00:09 +0200 Subject: drm/i915: Simplify ironlake_crtc_compute_clock() CPU eDP case None of the code in ironlake_crtc_compute_clock() is relevant for CPU eDP. The CPU eDP PLL is turned on and off in ironlake_edp_pll_{on,off} from the DP code and that doesn't depend on the crtc_state->dpll values, so just return early in that case. v2: Rebase without patch that drops lvds downclock code. (Ville) Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1458576016-30348-9-git-send-email-ander.conselvan.de.oliveira@intel.com --- drivers/gpu/drm/i915/intel_display.c | 47 ++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c6920fc17154..0a5e8553b120 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8800,13 +8800,16 @@ static int ironlake_crtc_compute_clock(struct intel_crtc *crtc, intel_clock_t clock, reduced_clock; u32 dpll = 0, fp = 0, fp2 = 0; bool has_reduced_clock = false; - bool is_lvds = false; struct intel_shared_dpll *pll; memset(&crtc_state->dpll_hw_state, 0, sizeof(crtc_state->dpll_hw_state)); - is_lvds = intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS); + crtc->lowfreq_avail = false; + + /* CPU eDP is the only output that doesn't need a PCH PLL of its own. */ + if (!crtc_state->has_pch_encoder) + return 0; if (!crtc_state->clock_set) { if (!ironlake_compute_clocks(&crtc->base, crtc_state, &clock, @@ -8824,34 +8827,30 @@ static int ironlake_crtc_compute_clock(struct intel_crtc *crtc, crtc_state->dpll.p2 = clock.p2; } - /* CPU eDP is the only output that doesn't need a PCH PLL of its own. */ - if (crtc_state->has_pch_encoder) { - fp = i9xx_dpll_compute_fp(&crtc_state->dpll); - if (has_reduced_clock) - fp2 = i9xx_dpll_compute_fp(&reduced_clock); - else - fp2 = fp; + fp = i9xx_dpll_compute_fp(&crtc_state->dpll); + if (has_reduced_clock) + fp2 = i9xx_dpll_compute_fp(&reduced_clock); + else + fp2 = fp; - dpll = ironlake_compute_dpll(crtc, crtc_state, - &fp, &reduced_clock, - has_reduced_clock ? &fp2 : NULL); + dpll = ironlake_compute_dpll(crtc, crtc_state, + &fp, &reduced_clock, + has_reduced_clock ? &fp2 : NULL); - crtc_state->dpll_hw_state.dpll = dpll; - crtc_state->dpll_hw_state.fp0 = fp; - crtc_state->dpll_hw_state.fp1 = fp2; + crtc_state->dpll_hw_state.dpll = dpll; + crtc_state->dpll_hw_state.fp0 = fp; + crtc_state->dpll_hw_state.fp1 = fp2; - pll = intel_get_shared_dpll(crtc, crtc_state, NULL); - if (pll == NULL) { - DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n", - pipe_name(crtc->pipe)); - return -EINVAL; - } + pll = intel_get_shared_dpll(crtc, crtc_state, NULL); + if (pll == NULL) { + DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n", + pipe_name(crtc->pipe)); + return -EINVAL; } - if (is_lvds && has_reduced_clock) + if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) && + has_reduced_clock) crtc->lowfreq_avail = true; - else - crtc->lowfreq_avail = false; return 0; } -- cgit v1.2.3 From 364ee29d12062458286f560bbca10e523088204e Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Mon, 21 Mar 2016 18:00:10 +0200 Subject: drm/i915: Pass crtc_state->dpll directly to ->find_dpll() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When calculating clocks, just pass a pointer to crtc_state->dpll directly to the find_dpll() hook. Back when this was introduced in commit f47709a9502f3 ("drm/i915: create pipe_config->dpll for clock state") there was no staged crtc config or atomic crtc state, so it was possible to overwrite the current configuration on error. That hasn't been the case for a while now, so finally make it "disappear". Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1458576016-30348-10-git-send-email-ander.conselvan.de.oliveira@intel.com --- drivers/gpu/drm/i915/intel_display.c | 34 ++++++++++------------------------ 1 file changed, 10 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0a5e8553b120..c803006eb718 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -7816,7 +7816,6 @@ static int i9xx_crtc_compute_clock(struct intel_crtc *crtc, struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; int refclk; - intel_clock_t clock; bool ok; const intel_limit_t *limit; @@ -7838,18 +7837,12 @@ static int i9xx_crtc_compute_clock(struct intel_crtc *crtc, limit = intel_limit(crtc_state, refclk); ok = dev_priv->display.find_dpll(limit, crtc_state, crtc_state->port_clock, - refclk, NULL, &clock); + refclk, NULL, + &crtc_state->dpll); if (!ok) { DRM_ERROR("Couldn't find PLL settings for mode!\n"); return -EINVAL; } - - /* Compat-code for transition, will disappear. */ - crtc_state->dpll.n = clock.n; - crtc_state->dpll.m1 = clock.m1; - crtc_state->dpll.m2 = clock.m2; - crtc_state->dpll.p1 = clock.p1; - crtc_state->dpll.p2 = clock.p2; } if (IS_GEN2(dev)) { @@ -8797,7 +8790,7 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, static int ironlake_crtc_compute_clock(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state) { - intel_clock_t clock, reduced_clock; + intel_clock_t reduced_clock; u32 dpll = 0, fp = 0, fp2 = 0; bool has_reduced_clock = false; struct intel_shared_dpll *pll; @@ -8811,20 +8804,13 @@ static int ironlake_crtc_compute_clock(struct intel_crtc *crtc, if (!crtc_state->has_pch_encoder) return 0; - if (!crtc_state->clock_set) { - if (!ironlake_compute_clocks(&crtc->base, crtc_state, &clock, - &has_reduced_clock, - &reduced_clock)) { - DRM_ERROR("Couldn't find PLL settings for mode!\n"); - return -EINVAL; - } - - /* Compat-code for transition, will disappear. */ - crtc_state->dpll.n = clock.n; - crtc_state->dpll.m1 = clock.m1; - crtc_state->dpll.m2 = clock.m2; - crtc_state->dpll.p1 = clock.p1; - crtc_state->dpll.p2 = clock.p2; + if (!crtc_state->clock_set && + !ironlake_compute_clocks(&crtc->base, crtc_state, + &crtc_state->dpll, + &has_reduced_clock, + &reduced_clock)) { + DRM_ERROR("Couldn't find PLL settings for mode!\n"); + return -EINVAL; } fp = i9xx_dpll_compute_fp(&crtc_state->dpll); -- cgit v1.2.3 From b75ca6f62e57923e9c2870bf8d795c410ebb9534 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Mon, 21 Mar 2016 18:00:11 +0200 Subject: drm/i915: Move fp divisor calculation into ironlake_compute_dpll() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow what is done in i8xx_compute_dpll() and i9xx_compute_dpll() and move the lower level details of setting crtc_state->dpll_hw_state into the _compute_dpll() function. Reviewed-by: Ville Syrjälä Signed-off-by: Ander Conselvan de Oliveira Link: http://patchwork.freedesktop.org/patch/msgid/1458576016-30348-11-git-send-email-ander.conselvan.de.oliveira@intel.com --- drivers/gpu/drm/i915/intel_display.c | 45 ++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c803006eb718..9741ee7783b9 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8693,10 +8693,9 @@ static bool ironlake_needs_fb_cb_tune(struct dpll *dpll, int factor) return i9xx_dpll_compute_m(dpll) < factor * dpll->n; } -static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, - struct intel_crtc_state *crtc_state, - u32 *fp, - intel_clock_t *reduced_clock, u32 *fp2) +static void ironlake_compute_dpll(struct intel_crtc *intel_crtc, + struct intel_crtc_state *crtc_state, + intel_clock_t *reduced_clock) { struct drm_crtc *crtc = &intel_crtc->base; struct drm_device *dev = crtc->dev; @@ -8705,7 +8704,7 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, struct drm_connector *connector; struct drm_connector_state *connector_state; struct intel_encoder *encoder; - uint32_t dpll; + u32 dpll, fp, fp2; int factor, i; bool is_lvds = false, is_sdvo = false; @@ -8738,11 +8737,19 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, } else if (crtc_state->sdvo_tv_clock) factor = 20; + fp = i9xx_dpll_compute_fp(&crtc_state->dpll); + if (ironlake_needs_fb_cb_tune(&crtc_state->dpll, factor)) - *fp |= FP_CB_TUNE; + fp |= FP_CB_TUNE; + + if (reduced_clock) { + fp2 = i9xx_dpll_compute_fp(reduced_clock); - if (fp2 && (reduced_clock->m < factor * reduced_clock->n)) - *fp2 |= FP_CB_TUNE; + if (reduced_clock->m < factor * reduced_clock->n) + fp2 |= FP_CB_TUNE; + } else { + fp2 = fp; + } dpll = 0; @@ -8784,14 +8791,17 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, else dpll |= PLL_REF_INPUT_DREFCLK; - return dpll | DPLL_VCO_ENABLE; + dpll |= DPLL_VCO_ENABLE; + + crtc_state->dpll_hw_state.dpll = dpll; + crtc_state->dpll_hw_state.fp0 = fp; + crtc_state->dpll_hw_state.fp1 = fp2; } static int ironlake_crtc_compute_clock(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state) { intel_clock_t reduced_clock; - u32 dpll = 0, fp = 0, fp2 = 0; bool has_reduced_clock = false; struct intel_shared_dpll *pll; @@ -8813,19 +8823,8 @@ static int ironlake_crtc_compute_clock(struct intel_crtc *crtc, return -EINVAL; } - fp = i9xx_dpll_compute_fp(&crtc_state->dpll); - if (has_reduced_clock) - fp2 = i9xx_dpll_compute_fp(&reduced_clock); - else - fp2 = fp; - - dpll = ironlake_compute_dpll(crtc, crtc_state, - &fp, &reduced_clock, - has_reduced_clock ? &fp2 : NULL); - - crtc_state->dpll_hw_state.dpll = dpll; - crtc_state->dpll_hw_state.fp0 = fp; - crtc_state->dpll_hw_state.fp1 = fp2; + ironlake_compute_dpll(crtc, crtc_state, + has_reduced_clock ? &reduced_clock : NULL); pll = intel_get_shared_dpll(crtc, crtc_state, NULL); if (pll == NULL) { -- cgit v1.2.3 From 997c030cfdd0f87ca5ac8b77ef0821c5597263f8 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Mon, 21 Mar 2016 18:00:12 +0200 Subject: drm/i915: Merge ironlake_compute_clocks() and ironlake_crtc_compute_clock() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merge ironlake_compute_clocks() into ironlake_crtc_compute_clock() so the clock computation logic is all in one place. The resulting function is still quite simple. Follow up patches will make the similar code for GMCH platforms look similar. Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1458576016-30348-12-git-send-email-ander.conselvan.de.oliveira@intel.com --- drivers/gpu/drm/i915/intel_display.c | 86 ++++++++++++++---------------------- 1 file changed, 33 insertions(+), 53 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9741ee7783b9..894091fe9dab 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -846,6 +846,11 @@ pnv_find_best_dpll(const intel_limit_t *limit, return (err != target); } +/* + * Returns a set of divisors for the desired target clock with the given + * refclk, or FALSE. The returned values represent the clock equation: + * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. + */ static bool g4x_find_best_dpll(const intel_limit_t *limit, struct intel_crtc_state *crtc_state, @@ -8628,55 +8633,6 @@ static void haswell_set_pipemisc(struct drm_crtc *crtc) } } -static bool ironlake_compute_clocks(struct drm_crtc *crtc, - struct intel_crtc_state *crtc_state, - intel_clock_t *clock, - bool *has_reduced_clock, - intel_clock_t *reduced_clock) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - int refclk; - const intel_limit_t *limit; - bool ret; - - refclk = 120000; - - if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) { - if (intel_panel_use_ssc(dev_priv)) { - DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", - dev_priv->vbt.lvds_ssc_freq); - refclk = dev_priv->vbt.lvds_ssc_freq; - } - - if (intel_is_dual_link_lvds(dev)) { - if (refclk == 100000) - limit = &intel_limits_ironlake_dual_lvds_100m; - else - limit = &intel_limits_ironlake_dual_lvds; - } else { - if (refclk == 100000) - limit = &intel_limits_ironlake_single_lvds_100m; - else - limit = &intel_limits_ironlake_single_lvds; - } - } else { - limit = &intel_limits_ironlake_dac; - } - - /* - * Returns a set of divisors for the desired target clock with the given - * refclk, or FALSE. The returned values represent the clock equation: - * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. - */ - ret = g4x_find_best_dpll(limit, crtc_state, crtc_state->port_clock, - refclk, NULL, clock); - if (!ret) - return false; - - return true; -} - int ironlake_get_lanes_required(int target_clock, int link_bw, int bpp) { /* @@ -8801,9 +8757,13 @@ static void ironlake_compute_dpll(struct intel_crtc *intel_crtc, static int ironlake_crtc_compute_clock(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state) { + struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; intel_clock_t reduced_clock; bool has_reduced_clock = false; struct intel_shared_dpll *pll; + const intel_limit_t *limit; + int refclk = 120000; memset(&crtc_state->dpll_hw_state, 0, sizeof(crtc_state->dpll_hw_state)); @@ -8814,11 +8774,31 @@ static int ironlake_crtc_compute_clock(struct intel_crtc *crtc, if (!crtc_state->has_pch_encoder) return 0; + if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) { + if (intel_panel_use_ssc(dev_priv)) { + DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", + dev_priv->vbt.lvds_ssc_freq); + refclk = dev_priv->vbt.lvds_ssc_freq; + } + + if (intel_is_dual_link_lvds(dev)) { + if (refclk == 100000) + limit = &intel_limits_ironlake_dual_lvds_100m; + else + limit = &intel_limits_ironlake_dual_lvds; + } else { + if (refclk == 100000) + limit = &intel_limits_ironlake_single_lvds_100m; + else + limit = &intel_limits_ironlake_single_lvds; + } + } else { + limit = &intel_limits_ironlake_dac; + } + if (!crtc_state->clock_set && - !ironlake_compute_clocks(&crtc->base, crtc_state, - &crtc_state->dpll, - &has_reduced_clock, - &reduced_clock)) { + !g4x_find_best_dpll(limit, crtc_state, crtc_state->port_clock, + refclk, NULL, &crtc_state->dpll)) { DRM_ERROR("Couldn't find PLL settings for mode!\n"); return -EINVAL; } -- cgit v1.2.3 From 65b3d6a976490bc731ad56e287965223030abe89 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Mon, 21 Mar 2016 18:00:13 +0200 Subject: drm/i915: Split CHV and VLV specific crtc_compute_clock() hooks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order for VLV and CHV to use i9xx_crtc_compute_clocks(), a number of if ladders is necessary: one for setting the find_dpll() hook, one for choosing the limits struct, one for choosing the right compute dpll function and one for initializing the crtc_compute_clock() hook. By extracting a platform specific implementation for each platform, the number of if-ladders is reduced to one. While at it also clean up bxt_find_best_dpll() which depends on some of the CHV code. Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1458576016-30348-13-git-send-email-ander.conselvan.de.oliveira@intel.com --- drivers/gpu/drm/i915/intel_display.c | 102 ++++++++++++++++++++++++++--------- 1 file changed, 78 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 894091fe9dab..688fdb83fdbb 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -111,7 +111,6 @@ static void intel_begin_crtc_commit(struct drm_crtc *, struct drm_crtc_state *); static void intel_finish_crtc_commit(struct drm_crtc *, struct drm_crtc_state *); static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state); -static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state); static void skylake_pfit_enable(struct intel_crtc *crtc); static void ironlake_pfit_disable(struct intel_crtc *crtc, bool force); static void ironlake_pfit_enable(struct intel_crtc *crtc); @@ -593,21 +592,17 @@ intel_limit(struct intel_crtc_state *crtc_state, int refclk) struct drm_device *dev = crtc_state->base.crtc->dev; const intel_limit_t *limit; - if (IS_BROXTON(dev)) - limit = &intel_limits_bxt; - else if (WARN_ON(HAS_PCH_SPLIT(dev))) + if (IS_BROXTON(dev) || IS_CHERRYVIEW(dev) || IS_VALLEYVIEW(dev) || + HAS_PCH_SPLIT(dev)) limit = NULL; - else if (IS_G4X(dev)) { + + if (IS_G4X(dev)) { limit = intel_g4x_limit(crtc_state); } else if (IS_PINEVIEW(dev)) { if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) limit = &intel_limits_pineview_lvds; else limit = &intel_limits_pineview_sdvo; - } else if (IS_CHERRYVIEW(dev)) { - limit = &intel_limits_chv; - } else if (IS_VALLEYVIEW(dev)) { - limit = &intel_limits_vlv; } else if (!IS_GEN2(dev)) { if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) limit = &intel_limits_i9xx_lvds; @@ -621,6 +616,9 @@ intel_limit(struct intel_crtc_state *crtc_state, int refclk) else limit = &intel_limits_i8xx_dac; } + + WARN_ON(limit == NULL); + return limit; } @@ -939,6 +937,11 @@ static bool vlv_PLL_is_optimal(struct drm_device *dev, int target_freq, return *error_ppm + 10 < best_error_ppm; } +/* + * Returns a set of divisors for the desired target clock with the given + * refclk, or FALSE. The returned values represent the clock equation: + * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. + */ static bool vlv_find_best_dpll(const intel_limit_t *limit, struct intel_crtc_state *crtc_state, @@ -993,6 +996,11 @@ vlv_find_best_dpll(const intel_limit_t *limit, return found; } +/* + * Returns a set of divisors for the desired target clock with the given + * refclk, or FALSE. The returned values represent the clock equation: + * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. + */ static bool chv_find_best_dpll(const intel_limit_t *limit, struct intel_crtc_state *crtc_state, @@ -1054,9 +1062,10 @@ chv_find_best_dpll(const intel_limit_t *limit, bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state, int target_clock, intel_clock_t *best_clock) { - int refclk = i9xx_get_refclk(crtc_state); + int refclk = 100000; + const intel_limit_t *limit = &intel_limits_bxt; - return chv_find_best_dpll(intel_limit(crtc_state, refclk), crtc_state, + return chv_find_best_dpll(limit, crtc_state, target_clock, refclk, NULL, best_clock); } @@ -7046,9 +7055,7 @@ static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state) WARN_ON(!crtc_state->base.state); - if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev) || IS_BROXTON(dev)) { - refclk = 100000; - } else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) && + if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) && intel_panel_use_ssc(dev_priv)) { refclk = dev_priv->vbt.lvds_ssc_freq; DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", refclk); @@ -7852,10 +7859,6 @@ static int i9xx_crtc_compute_clock(struct intel_crtc *crtc, if (IS_GEN2(dev)) { i8xx_compute_dpll(crtc, crtc_state, NULL); - } else if (IS_CHERRYVIEW(dev)) { - chv_compute_dpll(crtc, crtc_state); - } else if (IS_VALLEYVIEW(dev)) { - vlv_compute_dpll(crtc, crtc_state); } else { i9xx_compute_dpll(crtc, crtc_state, NULL); } @@ -7863,6 +7866,54 @@ static int i9xx_crtc_compute_clock(struct intel_crtc *crtc, return 0; } +static int chv_crtc_compute_clock(struct intel_crtc *crtc, + struct intel_crtc_state *crtc_state) +{ + int refclk = 100000; + const intel_limit_t *limit = &intel_limits_chv; + + memset(&crtc_state->dpll_hw_state, 0, + sizeof(crtc_state->dpll_hw_state)); + + if (crtc_state->has_dsi_encoder) + return 0; + + if (!crtc_state->clock_set && + !chv_find_best_dpll(limit, crtc_state, crtc_state->port_clock, + refclk, NULL, &crtc_state->dpll)) { + DRM_ERROR("Couldn't find PLL settings for mode!\n"); + return -EINVAL; + } + + chv_compute_dpll(crtc, crtc_state); + + return 0; +} + +static int vlv_crtc_compute_clock(struct intel_crtc *crtc, + struct intel_crtc_state *crtc_state) +{ + int refclk = 100000; + const intel_limit_t *limit = &intel_limits_vlv; + + memset(&crtc_state->dpll_hw_state, 0, + sizeof(crtc_state->dpll_hw_state)); + + if (crtc_state->has_dsi_encoder) + return 0; + + if (!crtc_state->clock_set && + !vlv_find_best_dpll(limit, crtc_state, crtc_state->port_clock, + refclk, NULL, &crtc_state->dpll)) { + DRM_ERROR("Couldn't find PLL settings for mode!\n"); + return -EINVAL; + } + + vlv_compute_dpll(crtc, crtc_state); + + return 0; +} + static void i9xx_get_pfit_config(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { @@ -14724,10 +14775,6 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv) { if (HAS_PCH_SPLIT(dev_priv) || IS_G4X(dev_priv)) dev_priv->display.find_dpll = g4x_find_best_dpll; - else if (IS_CHERRYVIEW(dev_priv)) - dev_priv->display.find_dpll = chv_find_best_dpll; - else if (IS_VALLEYVIEW(dev_priv)) - dev_priv->display.find_dpll = vlv_find_best_dpll; else if (IS_PINEVIEW(dev_priv)) dev_priv->display.find_dpll = pnv_find_best_dpll; else @@ -14757,11 +14804,18 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv) ironlake_crtc_compute_clock; dev_priv->display.crtc_enable = ironlake_crtc_enable; dev_priv->display.crtc_disable = ironlake_crtc_disable; - } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { + } else if (IS_CHERRYVIEW(dev_priv)) { dev_priv->display.get_pipe_config = i9xx_get_pipe_config; dev_priv->display.get_initial_plane_config = i9xx_get_initial_plane_config; - dev_priv->display.crtc_compute_clock = i9xx_crtc_compute_clock; + dev_priv->display.crtc_compute_clock = chv_crtc_compute_clock; + dev_priv->display.crtc_enable = valleyview_crtc_enable; + dev_priv->display.crtc_disable = i9xx_crtc_disable; + } else if (IS_VALLEYVIEW(dev_priv)) { + dev_priv->display.get_pipe_config = i9xx_get_pipe_config; + dev_priv->display.get_initial_plane_config = + i9xx_get_initial_plane_config; + dev_priv->display.crtc_compute_clock = vlv_crtc_compute_clock; dev_priv->display.crtc_enable = valleyview_crtc_enable; dev_priv->display.crtc_disable = i9xx_crtc_disable; } else { -- cgit v1.2.3 From 81c97f522e41c022f96cd009feacb9acb994f115 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Tue, 22 Mar 2016 15:35:23 +0200 Subject: drm/i915: Split i8xx_crtc_compute_clock() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split a GEN2 specific version from i9xx_crtc_compute_clock(). With this there is no need for i9xx_get_refclk() anymore, and the differences between platforms become more obvious. v2: Use i8xx as prefix instead of gen2. (Ville and Daniel) Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1458653723-17951-1-git-send-email-ander.conselvan.de.oliveira@intel.com --- drivers/gpu/drm/i915/intel_display.c | 91 +++++++++++++++++++++--------------- 1 file changed, 53 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 688fdb83fdbb..611757a462a7 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -593,7 +593,7 @@ intel_limit(struct intel_crtc_state *crtc_state, int refclk) const intel_limit_t *limit; if (IS_BROXTON(dev) || IS_CHERRYVIEW(dev) || IS_VALLEYVIEW(dev) || - HAS_PCH_SPLIT(dev)) + HAS_PCH_SPLIT(dev) || IS_GEN2(dev)) limit = NULL; if (IS_G4X(dev)) { @@ -608,13 +608,6 @@ intel_limit(struct intel_crtc_state *crtc_state, int refclk) limit = &intel_limits_i9xx_lvds; else limit = &intel_limits_i9xx_sdvo; - } else { - if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) - limit = &intel_limits_i8xx_lvds; - else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_DVO)) - limit = &intel_limits_i8xx_dvo; - else - limit = &intel_limits_i8xx_dac; } WARN_ON(limit == NULL); @@ -7047,27 +7040,6 @@ static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv) && !(dev_priv->quirks & QUIRK_LVDS_SSC_DISABLE); } -static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state) -{ - struct drm_device *dev = crtc_state->base.crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - int refclk; - - WARN_ON(!crtc_state->base.state); - - if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) && - intel_panel_use_ssc(dev_priv)) { - refclk = dev_priv->vbt.lvds_ssc_freq; - DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", refclk); - } else if (!IS_GEN2(dev)) { - refclk = 96000; - } else { - refclk = 48000; - } - - return refclk; -} - static uint32_t pnv_dpll_compute_fp(struct dpll *dpll) { return (1 << dpll->n) << 16 | dpll->m2; @@ -7822,14 +7794,50 @@ static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc) POSTING_READ(PIPECONF(intel_crtc->pipe)); } +static int i8xx_crtc_compute_clock(struct intel_crtc *crtc, + struct intel_crtc_state *crtc_state) +{ + struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + const intel_limit_t *limit; + int refclk = 48000; + + memset(&crtc_state->dpll_hw_state, 0, + sizeof(crtc_state->dpll_hw_state)); + + if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) { + if (intel_panel_use_ssc(dev_priv)) { + refclk = dev_priv->vbt.lvds_ssc_freq; + DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", refclk); + } + + limit = &intel_limits_i8xx_lvds; + } else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_DVO)) { + limit = &intel_limits_i8xx_dvo; + } else { + limit = &intel_limits_i8xx_dac; + } + + if (!crtc_state->clock_set && + !i9xx_find_best_dpll(limit, crtc_state, crtc_state->port_clock, + refclk, NULL, &crtc_state->dpll)) { + DRM_ERROR("Couldn't find PLL settings for mode!\n"); + return -EINVAL; + } + + i8xx_compute_dpll(crtc, crtc_state, NULL); + + return 0; +} + static int i9xx_crtc_compute_clock(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - int refclk; bool ok; const intel_limit_t *limit; + int refclk = 96000; memset(&crtc_state->dpll_hw_state, 0, sizeof(crtc_state->dpll_hw_state)); @@ -7837,9 +7845,13 @@ static int i9xx_crtc_compute_clock(struct intel_crtc *crtc, if (crtc_state->has_dsi_encoder) return 0; - if (!crtc_state->clock_set) { - refclk = i9xx_get_refclk(crtc_state); + if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) && + intel_panel_use_ssc(dev_priv)) { + refclk = dev_priv->vbt.lvds_ssc_freq; + DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", refclk); + } + if (!crtc_state->clock_set) { /* * Returns a set of divisors for the desired target clock with * the given refclk, or FALSE. The returned values represent @@ -7857,11 +7869,7 @@ static int i9xx_crtc_compute_clock(struct intel_crtc *crtc, } } - if (IS_GEN2(dev)) { - i8xx_compute_dpll(crtc, crtc_state, NULL); - } else { - i9xx_compute_dpll(crtc, crtc_state, NULL); - } + i9xx_compute_dpll(crtc, crtc_state, NULL); return 0; } @@ -14818,13 +14826,20 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv) dev_priv->display.crtc_compute_clock = vlv_crtc_compute_clock; dev_priv->display.crtc_enable = valleyview_crtc_enable; dev_priv->display.crtc_disable = i9xx_crtc_disable; - } else { + } else if (!IS_GEN2(dev_priv)) { dev_priv->display.get_pipe_config = i9xx_get_pipe_config; dev_priv->display.get_initial_plane_config = i9xx_get_initial_plane_config; dev_priv->display.crtc_compute_clock = i9xx_crtc_compute_clock; dev_priv->display.crtc_enable = i9xx_crtc_enable; dev_priv->display.crtc_disable = i9xx_crtc_disable; + } else { + dev_priv->display.get_pipe_config = i9xx_get_pipe_config; + dev_priv->display.get_initial_plane_config = + i9xx_get_initial_plane_config; + dev_priv->display.crtc_compute_clock = i8xx_crtc_compute_clock; + dev_priv->display.crtc_enable = i9xx_crtc_enable; + dev_priv->display.crtc_disable = i9xx_crtc_disable; } /* Returns the core display clock speed */ -- cgit v1.2.3 From 19ec6693098c80d3fd693d9defbc7e46e60e1c1b Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Mon, 21 Mar 2016 18:00:15 +0200 Subject: drm/i915: Split g4x_crtc_compute_clock() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split a G4X specific version from i9xx_crtc_compute_clock(). With this the differences between platforms become more obvious. Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1458576016-30348-15-git-send-email-ander.conselvan.de.oliveira@intel.com --- drivers/gpu/drm/i915/intel_display.c | 82 +++++++++++++++++++++++------------- 1 file changed, 53 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 611757a462a7..2764aded4a66 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -564,28 +564,6 @@ static bool intel_pipe_will_have_type(const struct intel_crtc_state *crtc_state, return false; } -static const intel_limit_t * -intel_g4x_limit(struct intel_crtc_state *crtc_state) -{ - struct drm_device *dev = crtc_state->base.crtc->dev; - const intel_limit_t *limit; - - if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) { - if (intel_is_dual_link_lvds(dev)) - limit = &intel_limits_g4x_dual_channel_lvds; - else - limit = &intel_limits_g4x_single_channel_lvds; - } else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_HDMI) || - intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_ANALOG)) { - limit = &intel_limits_g4x_hdmi; - } else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_SDVO)) { - limit = &intel_limits_g4x_sdvo; - } else /* The option is for other outputs */ - limit = &intel_limits_i9xx_sdvo; - - return limit; -} - static const intel_limit_t * intel_limit(struct intel_crtc_state *crtc_state, int refclk) { @@ -593,12 +571,10 @@ intel_limit(struct intel_crtc_state *crtc_state, int refclk) const intel_limit_t *limit; if (IS_BROXTON(dev) || IS_CHERRYVIEW(dev) || IS_VALLEYVIEW(dev) || - HAS_PCH_SPLIT(dev) || IS_GEN2(dev)) + HAS_PCH_SPLIT(dev) || IS_G4X(dev) || IS_GEN2(dev)) limit = NULL; - if (IS_G4X(dev)) { - limit = intel_g4x_limit(crtc_state); - } else if (IS_PINEVIEW(dev)) { + if (IS_PINEVIEW(dev)) { if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) limit = &intel_limits_pineview_lvds; else @@ -7830,6 +7806,49 @@ static int i8xx_crtc_compute_clock(struct intel_crtc *crtc, return 0; } +static int g4x_crtc_compute_clock(struct intel_crtc *crtc, + struct intel_crtc_state *crtc_state) +{ + struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + const intel_limit_t *limit; + int refclk = 96000; + + memset(&crtc_state->dpll_hw_state, 0, + sizeof(crtc_state->dpll_hw_state)); + + if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) { + if (intel_panel_use_ssc(dev_priv)) { + refclk = dev_priv->vbt.lvds_ssc_freq; + DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", refclk); + } + + if (intel_is_dual_link_lvds(dev)) + limit = &intel_limits_g4x_dual_channel_lvds; + else + limit = &intel_limits_g4x_single_channel_lvds; + } else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_HDMI) || + intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_ANALOG)) { + limit = &intel_limits_g4x_hdmi; + } else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_SDVO)) { + limit = &intel_limits_g4x_sdvo; + } else { + /* The option is for other outputs */ + limit = &intel_limits_i9xx_sdvo; + } + + if (!crtc_state->clock_set && + !g4x_find_best_dpll(limit, crtc_state, crtc_state->port_clock, + refclk, NULL, &crtc_state->dpll)) { + DRM_ERROR("Couldn't find PLL settings for mode!\n"); + return -EINVAL; + } + + i9xx_compute_dpll(crtc, crtc_state, NULL); + + return 0; +} + static int i9xx_crtc_compute_clock(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state) { @@ -14781,9 +14800,7 @@ static const struct drm_mode_config_funcs intel_mode_funcs = { */ void intel_init_display_hooks(struct drm_i915_private *dev_priv) { - if (HAS_PCH_SPLIT(dev_priv) || IS_G4X(dev_priv)) - dev_priv->display.find_dpll = g4x_find_best_dpll; - else if (IS_PINEVIEW(dev_priv)) + if (IS_PINEVIEW(dev_priv)) dev_priv->display.find_dpll = pnv_find_best_dpll; else dev_priv->display.find_dpll = i9xx_find_best_dpll; @@ -14826,6 +14843,13 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv) dev_priv->display.crtc_compute_clock = vlv_crtc_compute_clock; dev_priv->display.crtc_enable = valleyview_crtc_enable; dev_priv->display.crtc_disable = i9xx_crtc_disable; + } else if (IS_G4X(dev_priv)) { + dev_priv->display.get_pipe_config = i9xx_get_pipe_config; + dev_priv->display.get_initial_plane_config = + i9xx_get_initial_plane_config; + dev_priv->display.crtc_compute_clock = g4x_crtc_compute_clock; + dev_priv->display.crtc_enable = i9xx_crtc_enable; + dev_priv->display.crtc_disable = i9xx_crtc_disable; } else if (!IS_GEN2(dev_priv)) { dev_priv->display.get_pipe_config = i9xx_get_pipe_config; dev_priv->display.get_initial_plane_config = -- cgit v1.2.3 From 70e8aa215623b5c4d3d3457fd6e6090ad6bfe9a3 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Mon, 21 Mar 2016 18:00:16 +0200 Subject: drm/i915: Split PNV version of crtc_compute_clock() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split a pnv_crtc_compute_clock(), so the differences between platforms become more obvious. With this, there are no more users of intel_limit() or the ->find_dpll() hook, so get rid of them. Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1458576016-30348-16-git-send-email-ander.conselvan.de.oliveira@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 18 ----- drivers/gpu/drm/i915/intel_display.c | 134 +++++++++++++++++++++-------------- 2 files changed, 79 insertions(+), 73 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 9d29ab06c99a..08b88c043431 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -575,24 +575,6 @@ struct dpll; struct drm_i915_display_funcs { int (*get_display_clock_speed)(struct drm_device *dev); int (*get_fifo_size)(struct drm_device *dev, int plane); - /** - * find_dpll() - Find the best values for the PLL - * @limit: limits for the PLL - * @crtc: current CRTC - * @target: target frequency in kHz - * @refclk: reference clock frequency in kHz - * @match_clock: if provided, @best_clock P divider must - * match the P divider from @match_clock - * used for LVDS downclocking - * @best_clock: best PLL values found - * - * Returns true on success, false on failure. - */ - bool (*find_dpll)(const struct intel_limit *limit, - struct intel_crtc_state *crtc_state, - int target, int refclk, - struct dpll *match_clock, - struct dpll *best_clock); int (*compute_pipe_wm)(struct intel_crtc_state *cstate); int (*compute_intermediate_wm)(struct drm_device *dev, struct intel_crtc *intel_crtc, diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2764aded4a66..009b03b09a40 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -564,33 +564,6 @@ static bool intel_pipe_will_have_type(const struct intel_crtc_state *crtc_state, return false; } -static const intel_limit_t * -intel_limit(struct intel_crtc_state *crtc_state, int refclk) -{ - struct drm_device *dev = crtc_state->base.crtc->dev; - const intel_limit_t *limit; - - if (IS_BROXTON(dev) || IS_CHERRYVIEW(dev) || IS_VALLEYVIEW(dev) || - HAS_PCH_SPLIT(dev) || IS_G4X(dev) || IS_GEN2(dev)) - limit = NULL; - - if (IS_PINEVIEW(dev)) { - if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) - limit = &intel_limits_pineview_lvds; - else - limit = &intel_limits_pineview_sdvo; - } else if (!IS_GEN2(dev)) { - if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) - limit = &intel_limits_i9xx_lvds; - else - limit = &intel_limits_i9xx_sdvo; - } - - WARN_ON(limit == NULL); - - return limit; -} - /* * Platform specific helpers to calculate the port PLL loopback- (clock.m), * and post-divider (clock.p) values, pre- (clock.vco) and post-divided fast @@ -721,6 +694,16 @@ i9xx_select_p2_div(const intel_limit_t *limit, } } +/* + * Returns a set of divisors for the desired target clock with the given + * refclk, or FALSE. The returned values represent the clock equation: + * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. + * + * Target and reference clocks are specified in kHz. + * + * If match_clock is provided, then best_clock P divider must match the P + * divider from @match_clock used for LVDS downclocking. + */ static bool i9xx_find_best_dpll(const intel_limit_t *limit, struct intel_crtc_state *crtc_state, @@ -768,6 +751,16 @@ i9xx_find_best_dpll(const intel_limit_t *limit, return (err != target); } +/* + * Returns a set of divisors for the desired target clock with the given + * refclk, or FALSE. The returned values represent the clock equation: + * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. + * + * Target and reference clocks are specified in kHz. + * + * If match_clock is provided, then best_clock P divider must match the P + * divider from @match_clock used for LVDS downclocking. + */ static bool pnv_find_best_dpll(const intel_limit_t *limit, struct intel_crtc_state *crtc_state, @@ -817,6 +810,11 @@ pnv_find_best_dpll(const intel_limit_t *limit, * Returns a set of divisors for the desired target clock with the given * refclk, or FALSE. The returned values represent the clock equation: * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. + * + * Target and reference clocks are specified in kHz. + * + * If match_clock is provided, then best_clock P divider must match the P + * divider from @match_clock used for LVDS downclocking. */ static bool g4x_find_best_dpll(const intel_limit_t *limit, @@ -7849,43 +7847,67 @@ static int g4x_crtc_compute_clock(struct intel_crtc *crtc, return 0; } +static int pnv_crtc_compute_clock(struct intel_crtc *crtc, + struct intel_crtc_state *crtc_state) +{ + struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + const intel_limit_t *limit; + int refclk = 96000; + + memset(&crtc_state->dpll_hw_state, 0, + sizeof(crtc_state->dpll_hw_state)); + + if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) { + if (intel_panel_use_ssc(dev_priv)) { + refclk = dev_priv->vbt.lvds_ssc_freq; + DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", refclk); + } + + limit = &intel_limits_pineview_lvds; + } else { + limit = &intel_limits_pineview_sdvo; + } + + if (!crtc_state->clock_set && + !pnv_find_best_dpll(limit, crtc_state, crtc_state->port_clock, + refclk, NULL, &crtc_state->dpll)) { + DRM_ERROR("Couldn't find PLL settings for mode!\n"); + return -EINVAL; + } + + i9xx_compute_dpll(crtc, crtc_state, NULL); + + return 0; +} + static int i9xx_crtc_compute_clock(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - bool ok; const intel_limit_t *limit; int refclk = 96000; memset(&crtc_state->dpll_hw_state, 0, sizeof(crtc_state->dpll_hw_state)); - if (crtc_state->has_dsi_encoder) - return 0; + if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) { + if (intel_panel_use_ssc(dev_priv)) { + refclk = dev_priv->vbt.lvds_ssc_freq; + DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", refclk); + } - if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) && - intel_panel_use_ssc(dev_priv)) { - refclk = dev_priv->vbt.lvds_ssc_freq; - DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", refclk); + limit = &intel_limits_i9xx_lvds; + } else { + limit = &intel_limits_i9xx_sdvo; } - if (!crtc_state->clock_set) { - /* - * Returns a set of divisors for the desired target clock with - * the given refclk, or FALSE. The returned values represent - * the clock equation: reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + - * 2) / p1 / p2. - */ - limit = intel_limit(crtc_state, refclk); - ok = dev_priv->display.find_dpll(limit, crtc_state, - crtc_state->port_clock, - refclk, NULL, - &crtc_state->dpll); - if (!ok) { - DRM_ERROR("Couldn't find PLL settings for mode!\n"); - return -EINVAL; - } + if (!crtc_state->clock_set && + !i9xx_find_best_dpll(limit, crtc_state, crtc_state->port_clock, + refclk, NULL, &crtc_state->dpll)) { + DRM_ERROR("Couldn't find PLL settings for mode!\n"); + return -EINVAL; } i9xx_compute_dpll(crtc, crtc_state, NULL); @@ -14800,11 +14822,6 @@ static const struct drm_mode_config_funcs intel_mode_funcs = { */ void intel_init_display_hooks(struct drm_i915_private *dev_priv) { - if (IS_PINEVIEW(dev_priv)) - dev_priv->display.find_dpll = pnv_find_best_dpll; - else - dev_priv->display.find_dpll = i9xx_find_best_dpll; - if (INTEL_INFO(dev_priv)->gen >= 9) { dev_priv->display.get_pipe_config = haswell_get_pipe_config; dev_priv->display.get_initial_plane_config = @@ -14850,6 +14867,13 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv) dev_priv->display.crtc_compute_clock = g4x_crtc_compute_clock; dev_priv->display.crtc_enable = i9xx_crtc_enable; dev_priv->display.crtc_disable = i9xx_crtc_disable; + } else if (IS_PINEVIEW(dev_priv)) { + dev_priv->display.get_pipe_config = i9xx_get_pipe_config; + dev_priv->display.get_initial_plane_config = + i9xx_get_initial_plane_config; + dev_priv->display.crtc_compute_clock = pnv_crtc_compute_clock; + dev_priv->display.crtc_enable = i9xx_crtc_enable; + dev_priv->display.crtc_disable = i9xx_crtc_disable; } else if (!IS_GEN2(dev_priv)) { dev_priv->display.get_pipe_config = i9xx_get_pipe_config; dev_priv->display.get_initial_plane_config = -- cgit v1.2.3 From bf23d1917d551487e85378c4f4a7a0efcfe77f4e Mon Sep 17 00:00:00 2001 From: Kamlakant Patel Date: Tue, 22 Mar 2016 18:38:14 +0530 Subject: spi: xlp: Enable SPI driver for Broadcom Vulcan ARM64 - Vulcan spi controller is compatible with netlogic,xlp832-spi. - Add depends on ARCH_VULCAN to Kconfig to enable spi controller driver for Broadcom Vulcan ARM64 SoCs. Signed-off-by: Kamlakant Patel Signed-off-by: Mark Brown --- drivers/spi/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 9d8c84bb1544..6536068ce74f 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -656,7 +656,7 @@ config SPI_XILINX config SPI_XLP tristate "Netlogic XLP SPI controller driver" - depends on CPU_XLP || COMPILE_TEST + depends on CPU_XLP || ARCH_VULCAN || COMPILE_TEST help Enable support for the SPI controller on the Netlogic XLP SoCs. Currently supported XLP variants are XLP8XX, XLP3XX, XLP2XX, XLP9XX -- cgit v1.2.3 From 9419b2006cf47c75985ea51d36ddc51346d29efd Mon Sep 17 00:00:00 2001 From: Bhuvanchandra DV Date: Tue, 22 Mar 2016 01:41:52 +0530 Subject: spi: fsl-dspi: Set max_speed_hz for master Calculate and update max speed from bus clock for SoCs using DSPI IP. The bus clock factor's are taken from the data sheets of respective SoCs. Signed-off-by: Bhuvanchandra DV Acked-by: Stefan Agner Signed-off-by: Mark Brown --- drivers/spi/spi-fsl-dspi.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 39412c9097c6..559ed70fd229 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -121,18 +121,22 @@ enum dspi_trans_mode { struct fsl_dspi_devtype_data { enum dspi_trans_mode trans_mode; + u8 max_clock_factor; }; static const struct fsl_dspi_devtype_data vf610_data = { .trans_mode = DSPI_EOQ_MODE, + .max_clock_factor = 2, }; static const struct fsl_dspi_devtype_data ls1021a_v1_data = { .trans_mode = DSPI_TCFQ_MODE, + .max_clock_factor = 8, }; static const struct fsl_dspi_devtype_data ls2085a_data = { .trans_mode = DSPI_TCFQ_MODE, + .max_clock_factor = 8, }; struct fsl_dspi { @@ -726,6 +730,9 @@ static int dspi_probe(struct platform_device *pdev) } clk_prepare_enable(dspi->clk); + master->max_speed_hz = + clk_get_rate(dspi->clk) / dspi->devtype_data->max_clock_factor; + init_waitqueue_head(&dspi->waitq); platform_set_drvdata(pdev, master); -- cgit v1.2.3 From 321d178edb17d4619dbfa6216ac185c30c18d31a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 20 Nov 2015 10:27:18 +0000 Subject: drm/i915: Tidy aliasing_gtt_bind_vma() In commit 0a878716265e9af9f697264dc2e858fcc060d833 Author: Daniel Vetter Date: Thu Oct 15 14:23:01 2015 +0200 drm/i915: restore ggtt double-bind avoidance we wrote the ggtt_bind_vma() observing a number of cleanups we could do over the template of aliasing_gtt_bind_vma(). Now let's apply the cleanups we made there back to the original. The essence is to avoid redundant variables and assignements, and by doing so make the code easier to read. Signed-off-by: Chris Wilson Cc: Daniel Vetter Reviewed-by: Daniel Vetter Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1448015238-24639-1-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem_gtt.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 0715bb74d306..cbbd666b0d97 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -2613,32 +2613,31 @@ static int aliasing_gtt_bind_vma(struct i915_vma *vma, enum i915_cache_level cache_level, u32 flags) { - struct drm_device *dev = vma->vm->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj = vma->obj; - struct sg_table *pages = obj->pages; - u32 pte_flags = 0; + u32 pte_flags; int ret; ret = i915_get_ggtt_vma_pages(vma); if (ret) return ret; - pages = vma->ggtt_view.pages; /* Currently applicable only to VLV */ - if (obj->gt_ro) + pte_flags = 0; + if (vma->obj->gt_ro) pte_flags |= PTE_READ_ONLY; if (flags & GLOBAL_BIND) { - vma->vm->insert_entries(vma->vm, pages, + vma->vm->insert_entries(vma->vm, + vma->ggtt_view.pages, vma->node.start, cache_level, pte_flags); } if (flags & LOCAL_BIND) { - struct i915_hw_ppgtt *appgtt = dev_priv->mm.aliasing_ppgtt; - appgtt->base.insert_entries(&appgtt->base, pages, + struct i915_hw_ppgtt *appgtt = + to_i915(vma->vm->dev)->mm.aliasing_ppgtt; + appgtt->base.insert_entries(&appgtt->base, + vma->ggtt_view.pages, vma->node.start, cache_level, pte_flags); } -- cgit v1.2.3 From 307e44988018943586f27d554a1773f685b3342e Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Wed, 23 Mar 2016 14:33:28 +0100 Subject: drm/i915: Remove vblank wait from hsw_enable_ips, v2. intel_post_plane_update did an extra vblank wait that's no longer needed when enabling ips. Changes since v1: - Add comment explaining why vblank wait is performed. (Paulo) Signed-off-by: Maarten Lankhorst Reviewed-by: Paulo Zanoni Link: http://patchwork.freedesktop.org/patch/msgid/56F29B28.5070804@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 009b03b09a40..7c4ffcaf13c1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4412,8 +4412,11 @@ void hsw_enable_ips(struct intel_crtc *crtc) if (!crtc->config->ips_enabled) return; - /* We can only enable IPS after we enable a plane and wait for a vblank */ - intel_wait_for_vblank(dev, crtc->pipe); + /* + * We can only enable IPS after we enable a plane and wait for a vblank + * This function is called from post_plane_update, which is run after + * a vblank wait. + */ assert_plane_enabled(dev_priv, crtc->plane); if (IS_BROADWELL(dev)) { -- cgit v1.2.3 From db18b6a64ca3fb260858279b218b84d5c179330f Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 24 Mar 2016 12:41:40 +0200 Subject: drm/i915/bxt: Fix DSI HW state readout Currently the machine hangs during booting while accessing the BXT_MIPI_PORT_CTRL register during pipe HW state readout. After some experimentation I found that the hang is caused by the DSI PLL being disabled, or it being enabled but with an incorrect divider configuration. Enabling the PLL got rid of the boot problem, so fix this by checking the PLL enabled state/configuration before attempting to read out the HW state. The DSI_PLL_ENABLE register is in the always-on power well, while the BXT_DSI_PLL_CTL is in power well 0. This isn't exactly matched by the transcoder power domain, but what we really need is just a runtime PM reference, which is provided by any power domain. Ville also found this dependency specified in BSpec, so I added a reference to that too. v2: - Make sure we hold a power reference while accessing the PLL registers. v3: (Jani) - Simplify check in bxt_get_dsi_transcoder_state() - Add comment explaining why we check for valid dividers in bxt_dsi_pll_is_enabled() CC: Shashank Sharma CC: Uma Shankar CC: Jani Nikula Fixes: c6c794a2fc5e ("drm/i915/bxt: Initialize MIPI DSI for BXT") Signed-off-by: Imre Deak Reviewed-by: Jani Nikula Reviewed-by: Shashank Sharma Link: http://patchwork.freedesktop.org/patch/msgid/1458816100-31269-1-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 2 ++ drivers/gpu/drm/i915/intel_display.c | 11 ++++++++++ drivers/gpu/drm/i915/intel_dsi.c | 9 ++++++++ drivers/gpu/drm/i915/intel_dsi.h | 1 + drivers/gpu/drm/i915/intel_dsi_pll.c | 40 ++++++++++++++++++++++++++++++++++++ 5 files changed, 63 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index f3ba43c2ca22..c839ce952a50 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7811,9 +7811,11 @@ enum skl_disp_power_wells { #define BXT_DSIC_16X_BY2 (1 << 10) #define BXT_DSIC_16X_BY3 (2 << 10) #define BXT_DSIC_16X_BY4 (3 << 10) +#define BXT_DSIC_16X_MASK (3 << 10) #define BXT_DSIA_16X_BY2 (1 << 8) #define BXT_DSIA_16X_BY3 (2 << 8) #define BXT_DSIA_16X_BY4 (3 << 8) +#define BXT_DSIA_16X_MASK (3 << 8) #define BXT_DSI_FREQ_SEL_SHIFT 8 #define BXT_DSI_FREQ_SEL_MASK (0xF << BXT_DSI_FREQ_SEL_SHIFT) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 7c4ffcaf13c1..29aa64be1f03 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -36,6 +36,7 @@ #include "intel_drv.h" #include #include "i915_drv.h" +#include "intel_dsi.h" #include "i915_trace.h" #include #include @@ -9870,6 +9871,16 @@ static bool bxt_get_dsi_transcoder_state(struct intel_crtc *crtc, continue; *power_domain_mask |= BIT(power_domain); + /* + * The PLL needs to be enabled with a valid divider + * configuration, otherwise accessing DSI registers will hang + * the machine. See BSpec North Display Engine + * registers/MIPI[BXT]. We can break out here early, since we + * need the same DSI PLL to be enabled for both DSI ports. + */ + if (!intel_dsi_pll_is_enabled(dev_priv)) + break; + /* XXX: this works for video mode only */ tmp = I915_READ(BXT_MIPI_PORT_CTRL(port)); if (!(tmp & DPI_ENABLE)) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 96ea3f741a89..0de74e1b7ab3 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -684,6 +684,14 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) return false; + /* + * On Broxton the PLL needs to be enabled with a valid divider + * configuration, otherwise accessing DSI registers will hang the + * machine. See BSpec North Display Engine registers/MIPI[BXT]. + */ + if (IS_BROXTON(dev_priv) && !intel_dsi_pll_is_enabled(dev_priv)) + goto out_put_power; + /* XXX: this only works for one DSI output */ for_each_dsi_port(port, intel_dsi->ports) { i915_reg_t ctrl_reg = IS_BROXTON(dev) ? @@ -726,6 +734,7 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, break; } +out_put_power: intel_display_power_put(dev_priv, power_domain); return active; diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index e582ef8f3dac..ec58ead9ccd1 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h @@ -126,6 +126,7 @@ static inline struct intel_dsi *enc_to_intel_dsi(struct drm_encoder *encoder) return container_of(encoder, struct intel_dsi, base.base); } +bool intel_dsi_pll_is_enabled(struct drm_i915_private *dev_priv); extern void intel_enable_dsi_pll(struct intel_encoder *encoder); extern void intel_disable_dsi_pll(struct intel_encoder *encoder); extern u32 intel_dsi_get_pclk(struct intel_encoder *encoder, int pipe_bpp); diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c index e3e343c80221..4e53fcf6e087 100644 --- a/drivers/gpu/drm/i915/intel_dsi_pll.c +++ b/drivers/gpu/drm/i915/intel_dsi_pll.c @@ -192,6 +192,36 @@ static void vlv_disable_dsi_pll(struct intel_encoder *encoder) mutex_unlock(&dev_priv->sb_lock); } +static bool bxt_dsi_pll_is_enabled(struct drm_i915_private *dev_priv) +{ + bool enabled; + u32 val; + u32 mask; + + mask = BXT_DSI_PLL_DO_ENABLE | BXT_DSI_PLL_LOCKED; + val = I915_READ(BXT_DSI_PLL_ENABLE); + enabled = (val & mask) == mask; + + if (!enabled) + return false; + + /* + * Both dividers must be programmed with valid values even if only one + * of the PLL is used, see BSpec/Broxton Clocks. Check this here for + * paranoia, since BIOS is known to misconfigure PLLs in this way at + * times, and since accessing DSI registers with invalid dividers + * causes a system hang. + */ + val = I915_READ(BXT_DSI_PLL_CTL); + if (!(val & BXT_DSIA_16X_MASK) || !(val & BXT_DSIC_16X_MASK)) { + DRM_DEBUG_DRIVER("PLL is enabled with invalid divider settings (%08x)\n", + val); + enabled = false; + } + + return enabled; +} + static void bxt_disable_dsi_pll(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; @@ -486,6 +516,16 @@ static void bxt_enable_dsi_pll(struct intel_encoder *encoder) DRM_DEBUG_KMS("DSI PLL locked\n"); } +bool intel_dsi_pll_is_enabled(struct drm_i915_private *dev_priv) +{ + if (IS_BROXTON(dev_priv)) + return bxt_dsi_pll_is_enabled(dev_priv); + + MISSING_CASE(INTEL_DEVID(dev_priv)); + + return false; +} + void intel_enable_dsi_pll(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; -- cgit v1.2.3 From c3232b1883e033e291aa3146f431b7ec87c80ec5 Mon Sep 17 00:00:00 2001 From: Dave Gordon Date: Wed, 23 Mar 2016 18:19:53 +0000 Subject: drm/i915: introduce for_each_engine_id() Equivalent to the existing for_each_engine() macro, this will replace the latter wherever the third argument *is* actually wanted (in most places, it is not used). The third argument is renamed to emphasise that it is an engine id (type enum intel_engine_id). All the callers of the macro that actually need the third argument are updated to use this version, and the argument (generally 'i') is also updated to be 'id'. Other callers (where the third argument is unused) are untouched for now; they will be updated in the next patch. Signed-off-by: Dave Gordon Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 48 ++++++++++++++++-------------- drivers/gpu/drm/i915/i915_drv.h | 9 ++++++ drivers/gpu/drm/i915/i915_gpu_error.c | 6 ++-- drivers/gpu/drm/i915/i915_guc_submission.c | 8 ++--- drivers/gpu/drm/i915/i915_irq.c | 10 +++---- drivers/gpu/drm/i915/intel_mocs.c | 6 ++-- drivers/gpu/drm/i915/intel_ringbuffer.c | 21 +++++++------ 7 files changed, 62 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index e0ba3e38000f..77dce527a1cb 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -132,7 +132,7 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) struct intel_engine_cs *engine; struct i915_vma *vma; int pin_count = 0; - int i; + enum intel_engine_id id; seq_printf(m, "%pK: %s%s%s%s %8zdKiB %02x %02x [ ", &obj->base, @@ -143,9 +143,9 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) obj->base.size / 1024, obj->base.read_domains, obj->base.write_domain); - for_each_engine(engine, dev_priv, i) + for_each_engine_id(engine, dev_priv, id) seq_printf(m, "%x ", - i915_gem_request_get_seqno(obj->last_read_req[i])); + i915_gem_request_get_seqno(obj->last_read_req[id])); seq_printf(m, "] %x %x%s%s%s", i915_gem_request_get_seqno(obj->last_write_req), i915_gem_request_get_seqno(obj->last_fenced_req), @@ -1334,7 +1334,8 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused) u64 acthd[I915_NUM_ENGINES]; u32 seqno[I915_NUM_ENGINES]; u32 instdone[I915_NUM_INSTDONE_REG]; - int i, j; + enum intel_engine_id id; + int j; if (!i915.enable_hangcheck) { seq_printf(m, "Hangcheck disabled\n"); @@ -1343,9 +1344,9 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused) intel_runtime_pm_get(dev_priv); - for_each_engine(engine, dev_priv, i) { - seqno[i] = engine->get_seqno(engine, false); - acthd[i] = intel_ring_get_active_head(engine); + for_each_engine_id(engine, dev_priv, id) { + seqno[id] = engine->get_seqno(engine, false); + acthd[id] = intel_ring_get_active_head(engine); } i915_get_extra_instdone(dev, instdone); @@ -1359,13 +1360,13 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused) } else seq_printf(m, "Hangcheck inactive\n"); - for_each_engine(engine, dev_priv, i) { + for_each_engine_id(engine, dev_priv, id) { seq_printf(m, "%s:\n", engine->name); seq_printf(m, "\tseqno = %x [current %x]\n", - engine->hangcheck.seqno, seqno[i]); + engine->hangcheck.seqno, seqno[id]); seq_printf(m, "\tACTHD = 0x%08llx [current 0x%08llx]\n", (long long)engine->hangcheck.acthd, - (long long)acthd[i]); + (long long)acthd[id]); seq_printf(m, "\tscore = %d\n", engine->hangcheck.score); seq_printf(m, "\taction = %d\n", engine->hangcheck.action); @@ -1947,7 +1948,8 @@ static int i915_context_status(struct seq_file *m, void *unused) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *engine; struct intel_context *ctx; - int ret, i; + enum intel_engine_id id; + int ret; ret = mutex_lock_interruptible(&dev->struct_mutex); if (ret) @@ -1965,11 +1967,11 @@ static int i915_context_status(struct seq_file *m, void *unused) if (i915.enable_execlists) { seq_putc(m, '\n'); - for_each_engine(engine, dev_priv, i) { + for_each_engine_id(engine, dev_priv, id) { struct drm_i915_gem_object *ctx_obj = - ctx->engine[i].state; + ctx->engine[id].state; struct intel_ringbuffer *ringbuf = - ctx->engine[i].ringbuf; + ctx->engine[id].ringbuf; seq_printf(m, "%s: ", engine->name); if (ctx_obj) @@ -3134,7 +3136,8 @@ static int i915_semaphore_status(struct seq_file *m, void *unused) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *engine; int num_rings = hweight32(INTEL_INFO(dev)->ring_mask); - int i, j, ret; + enum intel_engine_id id; + int j, ret; if (!i915_semaphore_is_enabled(dev)) { seq_puts(m, "Semaphores are disabled\n"); @@ -3153,14 +3156,14 @@ static int i915_semaphore_status(struct seq_file *m, void *unused) page = i915_gem_object_get_page(dev_priv->semaphore_obj, 0); seqno = (uint64_t *)kmap_atomic(page); - for_each_engine(engine, dev_priv, i) { + for_each_engine_id(engine, dev_priv, id) { uint64_t offset; seq_printf(m, "%s\n", engine->name); seq_puts(m, " Last signal:"); for (j = 0; j < num_rings; j++) { - offset = i * I915_NUM_ENGINES + j; + offset = id * I915_NUM_ENGINES + j; seq_printf(m, "0x%08llx (0x%02llx) ", seqno[offset], offset * 8); } @@ -3168,7 +3171,7 @@ static int i915_semaphore_status(struct seq_file *m, void *unused) seq_puts(m, " Last wait: "); for (j = 0; j < num_rings; j++) { - offset = i + (j * I915_NUM_ENGINES); + offset = id + (j * I915_NUM_ENGINES); seq_printf(m, "0x%08llx (0x%02llx) ", seqno[offset], offset * 8); } @@ -3178,7 +3181,7 @@ static int i915_semaphore_status(struct seq_file *m, void *unused) kunmap_atomic(seqno); } else { seq_puts(m, " Last signal:"); - for_each_engine(engine, dev_priv, i) + for_each_engine(engine, dev_priv, id) for (j = 0; j < num_rings; j++) seq_printf(m, "0x%08x\n", I915_READ(engine->semaphore.mbox.signal[j])); @@ -3186,7 +3189,7 @@ static int i915_semaphore_status(struct seq_file *m, void *unused) } seq_puts(m, "\nSync seqno:\n"); - for_each_engine(engine, dev_priv, i) { + for_each_engine(engine, dev_priv, id) { for (j = 0; j < num_rings; j++) { seq_printf(m, " 0x%08x ", engine->semaphore.sync_seqno[j]); @@ -3236,6 +3239,7 @@ static int i915_wa_registers(struct seq_file *m, void *unused) struct drm_device *dev = node->minor->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct i915_workarounds *workarounds = &dev_priv->workarounds; + enum intel_engine_id id; ret = mutex_lock_interruptible(&dev->struct_mutex); if (ret) @@ -3244,9 +3248,9 @@ static int i915_wa_registers(struct seq_file *m, void *unused) intel_runtime_pm_get(dev_priv); seq_printf(m, "Workarounds applied: %d\n", workarounds->count); - for_each_engine(engine, dev_priv, i) + for_each_engine_id(engine, dev_priv, id) seq_printf(m, "HW whitelist count for %s: %d\n", - engine->name, workarounds->hw_whitelist_count[i]); + engine->name, workarounds->hw_whitelist_count[id]); for (i = 0; i < workarounds->count; ++i) { i915_reg_t addr; u32 mask, value, read; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 08b88c043431..8fe0592341b8 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1995,6 +1995,15 @@ static inline struct drm_i915_private *guc_to_i915(struct intel_guc *guc) for ((i__) = 0; (i__) < I915_NUM_ENGINES; (i__)++) \ for_each_if ((((ring__) = &(dev_priv__)->engine[(i__)]), intel_engine_initialized((ring__)))) +/* Iterator with engine_id */ +#define for_each_engine_id(engine__, dev_priv__, id__) \ + for ((engine__) = &(dev_priv__)->engine[0], (id__) = 0; \ + (engine__) < &(dev_priv__)->engine[I915_NUM_ENGINES]; \ + (engine__)++) \ + for_each_if (((id__) = (engine__)->id, \ + intel_engine_initialized(engine__))) + +/* Iterator over subset of engines selected by mask */ #define for_each_engine_masked(engine__, dev_priv__, mask__) \ for ((engine__) = &dev_priv->engine[0]; (engine__) < &dev_priv->engine[I915_NUM_ENGINES]; (engine__)++) \ for_each_if (intel_engine_flag((engine__)) & (mask__) && intel_engine_initialized((engine__))) diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 1f8ff06eed6b..54c208665b0d 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -846,7 +846,7 @@ static void gen8_record_semaphore_state(struct drm_i915_private *dev_priv, struct drm_i915_error_ring *ering) { struct intel_engine_cs *to; - int i; + enum intel_engine_id id; if (!i915_semaphore_is_enabled(dev_priv->dev)) return; @@ -856,7 +856,7 @@ static void gen8_record_semaphore_state(struct drm_i915_private *dev_priv, i915_error_ggtt_object_create(dev_priv, dev_priv->semaphore_obj); - for_each_engine(to, dev_priv, i) { + for_each_engine_id(to, dev_priv, id) { int idx; u16 signal_offset; u32 *tmp; @@ -864,7 +864,7 @@ static void gen8_record_semaphore_state(struct drm_i915_private *dev_priv, if (engine == to) continue; - signal_offset = (GEN8_SIGNAL_OFFSET(engine, i) & (PAGE_SIZE - 1)) + signal_offset = (GEN8_SIGNAL_OFFSET(engine, id) & (PAGE_SIZE - 1)) / 4; tmp = error->semaphore_obj->pages[0]; idx = intel_ring_sync_index(engine, to); diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index ae1f58d073f2..0611bdc13d2d 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -381,7 +381,7 @@ static void guc_init_ctx_desc(struct intel_guc *guc, struct intel_context *ctx = client->owner; struct guc_context_desc desc; struct sg_table *sg; - int i; + enum intel_engine_id id; memset(&desc, 0, sizeof(desc)); @@ -390,7 +390,7 @@ static void guc_init_ctx_desc(struct intel_guc *guc, desc.priority = client->priority; desc.db_id = client->doorbell_id; - for_each_engine(engine, dev_priv, i) { + for_each_engine_id(engine, dev_priv, id) { struct guc_execlist_context *lrc = &desc.lrc[engine->guc_id]; struct drm_i915_gem_object *obj; uint64_t ctx_desc; @@ -402,7 +402,7 @@ static void guc_init_ctx_desc(struct intel_guc *guc, * for now who owns a GuC client. But for future owner of GuC * client, need to make sure lrc is pinned prior to enter here. */ - obj = ctx->engine[i].state; + obj = ctx->engine[id].state; if (!obj) break; /* XXX: continue? */ @@ -415,7 +415,7 @@ static void guc_init_ctx_desc(struct intel_guc *guc, lrc->context_id = (client->ctx_index << GUC_ELC_CTXID_OFFSET) | (engine->guc_id << GUC_ELC_ENGINE_OFFSET); - obj = ctx->engine[i].ringbuf->obj; + obj = ctx->engine[id].ringbuf->obj; lrc->ring_begin = i915_gem_obj_ggtt_offset(obj); lrc->ring_end = lrc->ring_begin + obj->base.size - 1; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a55a7cc317f8..14a23b346631 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3073,7 +3073,7 @@ static void i915_hangcheck_elapsed(struct work_struct *work) gpu_error.hangcheck_work.work); struct drm_device *dev = dev_priv->dev; struct intel_engine_cs *engine; - int i; + enum intel_engine_id id; int busy_count = 0, rings_hung = 0; bool stuck[I915_NUM_ENGINES] = { 0 }; #define BUSY 1 @@ -3097,7 +3097,7 @@ static void i915_hangcheck_elapsed(struct work_struct *work) */ intel_uncore_arm_unclaimed_mmio_detection(dev_priv); - for_each_engine(engine, dev_priv, i) { + for_each_engine_id(engine, dev_priv, id) { u64 acthd; u32 seqno; bool busy = true; @@ -3157,7 +3157,7 @@ static void i915_hangcheck_elapsed(struct work_struct *work) break; case HANGCHECK_HUNG: engine->hangcheck.score += HUNG; - stuck[i] = true; + stuck[id] = true; break; } } @@ -3184,10 +3184,10 @@ static void i915_hangcheck_elapsed(struct work_struct *work) busy_count += busy; } - for_each_engine(engine, dev_priv, i) { + for_each_engine_id(engine, dev_priv, id) { if (engine->hangcheck.score >= HANGCHECK_SCORE_RING_HUNG) { DRM_INFO("%s on %s\n", - stuck[i] ? "stuck" : "no progress", + stuck[id] ? "stuck" : "no progress", engine->name); rings_hung |= intel_engine_flag(engine); } diff --git a/drivers/gpu/drm/i915/intel_mocs.c b/drivers/gpu/drm/i915/intel_mocs.c index 3c725dde16ed..7c7ac0aa192a 100644 --- a/drivers/gpu/drm/i915/intel_mocs.c +++ b/drivers/gpu/drm/i915/intel_mocs.c @@ -325,11 +325,11 @@ int intel_rcs_context_init_mocs(struct drm_i915_gem_request *req) if (get_mocs_settings(req->engine->dev, &t)) { struct drm_i915_private *dev_priv = req->i915; struct intel_engine_cs *engine; - enum intel_engine_id ring_id; + enum intel_engine_id id; /* Program the control registers */ - for_each_engine(engine, dev_priv, ring_id) { - ret = emit_mocs_control_table(req, &t, ring_id); + for_each_engine_id(engine, dev_priv, id) { + ret = emit_mocs_control_table(req, &t, id); if (ret) return ret; } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index ce59850f7e73..a492bcabd30d 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1280,7 +1280,8 @@ static int gen8_rcs_signal(struct drm_i915_gem_request *signaller_req, struct drm_device *dev = signaller->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *waiter; - int i, ret, num_rings; + enum intel_engine_id id; + int ret, num_rings; num_rings = hweight32(INTEL_INFO(dev)->ring_mask); num_dwords += (num_rings-1) * MBOX_UPDATE_DWORDS; @@ -1290,9 +1291,9 @@ static int gen8_rcs_signal(struct drm_i915_gem_request *signaller_req, if (ret) return ret; - for_each_engine(waiter, dev_priv, i) { + for_each_engine_id(waiter, dev_priv, id) { u32 seqno; - u64 gtt_offset = signaller->semaphore.signal_ggtt[i]; + u64 gtt_offset = signaller->semaphore.signal_ggtt[id]; if (gtt_offset == MI_SEMAPHORE_SYNC_INVALID) continue; @@ -1321,7 +1322,8 @@ static int gen8_xcs_signal(struct drm_i915_gem_request *signaller_req, struct drm_device *dev = signaller->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *waiter; - int i, ret, num_rings; + enum intel_engine_id id; + int ret, num_rings; num_rings = hweight32(INTEL_INFO(dev)->ring_mask); num_dwords += (num_rings-1) * MBOX_UPDATE_DWORDS; @@ -1331,9 +1333,9 @@ static int gen8_xcs_signal(struct drm_i915_gem_request *signaller_req, if (ret) return ret; - for_each_engine(waiter, dev_priv, i) { + for_each_engine_id(waiter, dev_priv, id) { u32 seqno; - u64 gtt_offset = signaller->semaphore.signal_ggtt[i]; + u64 gtt_offset = signaller->semaphore.signal_ggtt[id]; if (gtt_offset == MI_SEMAPHORE_SYNC_INVALID) continue; @@ -1359,7 +1361,8 @@ static int gen6_signal(struct drm_i915_gem_request *signaller_req, struct drm_device *dev = signaller->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *useless; - int i, ret, num_rings; + enum intel_engine_id id; + int ret, num_rings; #define MBOX_UPDATE_DWORDS 3 num_rings = hweight32(INTEL_INFO(dev)->ring_mask); @@ -1370,8 +1373,8 @@ static int gen6_signal(struct drm_i915_gem_request *signaller_req, if (ret) return ret; - for_each_engine(useless, dev_priv, i) { - i915_reg_t mbox_reg = signaller->semaphore.mbox.signal[i]; + for_each_engine_id(useless, dev_priv, id) { + i915_reg_t mbox_reg = signaller->semaphore.mbox.signal[id]; if (i915_mmio_reg_valid(mbox_reg)) { u32 seqno = i915_gem_request_get_seqno(signaller_req); -- cgit v1.2.3 From b4ac5afc6b8398b15d061e909bbad153aae41f15 Mon Sep 17 00:00:00 2001 From: Dave Gordon Date: Thu, 24 Mar 2016 11:20:38 +0000 Subject: drm/i915: replace for_each_engine() Having provided for_each_engine_id() for cases where the third (id) argument is useful, we can now replace all the remaining instances with a simpler version that takes only two parameters. In many cases, this also allows the elimination of the local variable used in the iterator (usually 'i'). v2: s/dev_priv/(dev_priv__)/ in body of for_each_engine_masked() [Chris Wilson] Signed-off-by: Dave Gordon Reviewed-by: Chris Wilson Signed-off-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1458757194-17783-2-git-send-email-david.s.gordon@intel.com --- drivers/gpu/drm/i915/i915_debugfs.c | 50 +++++++++++++----------------- drivers/gpu/drm/i915/i915_drv.h | 17 ++++++---- drivers/gpu/drm/i915/i915_gem.c | 50 +++++++++++++----------------- drivers/gpu/drm/i915/i915_gem_context.c | 6 ++-- drivers/gpu/drm/i915/i915_gem_debug.c | 3 +- drivers/gpu/drm/i915/i915_gem_gtt.c | 9 ++---- drivers/gpu/drm/i915/i915_guc_submission.c | 6 ++-- drivers/gpu/drm/i915/i915_irq.c | 14 +++------ drivers/gpu/drm/i915/intel_guc_loader.c | 8 ++--- drivers/gpu/drm/i915/intel_lrc.c | 3 +- drivers/gpu/drm/i915/intel_pm.c | 19 +++++------- 11 files changed, 82 insertions(+), 103 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 77dce527a1cb..d02f8ce0b1c8 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -398,11 +398,11 @@ static void print_batch_pool_stats(struct seq_file *m, struct drm_i915_gem_object *obj; struct file_stats stats; struct intel_engine_cs *engine; - int i, j; + int j; memset(&stats, 0, sizeof(stats)); - for_each_engine(engine, dev_priv, i) { + for_each_engine(engine, dev_priv) { for (j = 0; j < ARRAY_SIZE(engine->batch_pool.cache_list); j++) { list_for_each_entry(obj, &engine->batch_pool.cache_list[j], @@ -638,13 +638,13 @@ static int i915_gem_batch_pool_info(struct seq_file *m, void *data) struct drm_i915_gem_object *obj; struct intel_engine_cs *engine; int total = 0; - int ret, i, j; + int ret, j; ret = mutex_lock_interruptible(&dev->struct_mutex); if (ret) return ret; - for_each_engine(engine, dev_priv, i) { + for_each_engine(engine, dev_priv) { for (j = 0; j < ARRAY_SIZE(engine->batch_pool.cache_list); j++) { int count; @@ -682,14 +682,14 @@ static int i915_gem_request_info(struct seq_file *m, void *data) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *engine; struct drm_i915_gem_request *req; - int ret, any, i; + int ret, any; ret = mutex_lock_interruptible(&dev->struct_mutex); if (ret) return ret; any = 0; - for_each_engine(engine, dev_priv, i) { + for_each_engine(engine, dev_priv) { int count; count = 0; @@ -739,14 +739,14 @@ static int i915_gem_seqno_info(struct seq_file *m, void *data) struct drm_device *dev = node->minor->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *engine; - int ret, i; + int ret; ret = mutex_lock_interruptible(&dev->struct_mutex); if (ret) return ret; intel_runtime_pm_get(dev_priv); - for_each_engine(engine, dev_priv, i) + for_each_engine(engine, dev_priv) i915_ring_seqno_info(m, engine); intel_runtime_pm_put(dev_priv); @@ -933,7 +933,7 @@ static int i915_interrupt_info(struct seq_file *m, void *data) seq_printf(m, "Graphics Interrupt mask: %08x\n", I915_READ(GTIMR)); } - for_each_engine(engine, dev_priv, i) { + for_each_engine(engine, dev_priv) { if (INTEL_INFO(dev)->gen >= 6) { seq_printf(m, "Graphics Interrupt mask (%s): %08x\n", @@ -2044,7 +2044,7 @@ static int i915_dump_lrc(struct seq_file *m, void *unused) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *engine; struct intel_context *ctx; - int ret, i; + int ret; if (!i915.enable_execlists) { seq_printf(m, "Logical Ring Contexts are disabled\n"); @@ -2057,7 +2057,7 @@ static int i915_dump_lrc(struct seq_file *m, void *unused) list_for_each_entry(ctx, &dev_priv->context_list, link) if (ctx != dev_priv->kernel_context) - for_each_engine(engine, dev_priv, i) + for_each_engine(engine, dev_priv) i915_dump_lrc_obj(m, ctx, engine); mutex_unlock(&dev->struct_mutex); @@ -2077,8 +2077,7 @@ static int i915_execlists(struct seq_file *m, void *data) u32 status; u32 ctx_id; struct list_head *cursor; - int ring_id, i; - int ret; + int i, ret; if (!i915.enable_execlists) { seq_puts(m, "Logical Ring Contexts are disabled\n"); @@ -2091,7 +2090,7 @@ static int i915_execlists(struct seq_file *m, void *data) intel_runtime_pm_get(dev_priv); - for_each_engine(engine, dev_priv, ring_id) { + for_each_engine(engine, dev_priv) { struct drm_i915_gem_request *head_req = NULL; int count = 0; unsigned long flags; @@ -2250,12 +2249,12 @@ static void gen8_ppgtt_info(struct seq_file *m, struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *engine; struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; - int unused, i; + int i; if (!ppgtt) return; - for_each_engine(engine, dev_priv, unused) { + for_each_engine(engine, dev_priv) { seq_printf(m, "%s\n", engine->name); for (i = 0; i < 4; i++) { u64 pdp = I915_READ(GEN8_RING_PDP_UDW(engine, i)); @@ -2270,12 +2269,11 @@ static void gen6_ppgtt_info(struct seq_file *m, struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *engine; - int i; if (INTEL_INFO(dev)->gen == 6) seq_printf(m, "GFX_MODE: 0x%08x\n", I915_READ(GFX_MODE)); - for_each_engine(engine, dev_priv, i) { + for_each_engine(engine, dev_priv) { seq_printf(m, "%s\n", engine->name); if (INTEL_INFO(dev)->gen == 7) seq_printf(m, "GFX_MODE: 0x%08x\n", @@ -2342,9 +2340,8 @@ static int count_irq_waiters(struct drm_i915_private *i915) { struct intel_engine_cs *engine; int count = 0; - int i; - for_each_engine(engine, i915, i) + for_each_engine(engine, i915) count += engine->irq_refcount; return count; @@ -2455,7 +2452,6 @@ static void i915_guc_client_info(struct seq_file *m, { struct intel_engine_cs *engine; uint64_t tot = 0; - uint32_t i; seq_printf(m, "\tPriority %d, GuC ctx index: %u, PD offset 0x%x\n", client->priority, client->ctx_index, client->proc_desc_offset); @@ -2468,7 +2464,7 @@ static void i915_guc_client_info(struct seq_file *m, seq_printf(m, "\tFailed doorbell: %u\n", client->b_fail); seq_printf(m, "\tLast submission result: %d\n", client->retcode); - for_each_engine(engine, dev_priv, i) { + for_each_engine(engine, dev_priv) { seq_printf(m, "\tSubmissions: %llu %s\n", client->submissions[engine->guc_id], engine->name); @@ -2485,7 +2481,6 @@ static int i915_guc_info(struct seq_file *m, void *data) struct intel_guc guc; struct i915_guc_client client = {}; struct intel_engine_cs *engine; - enum intel_engine_id i; u64 total = 0; if (!HAS_GUC_SCHED(dev_priv->dev)) @@ -2508,7 +2503,7 @@ static int i915_guc_info(struct seq_file *m, void *data) seq_printf(m, "GuC last action error code: %d\n", guc.action_err); seq_printf(m, "\nGuC submissions:\n"); - for_each_engine(engine, dev_priv, i) { + for_each_engine(engine, dev_priv) { seq_printf(m, "\t%-24s: %10llu, last seqno 0x%08x\n", engine->name, guc.submissions[engine->guc_id], guc.last_seqno[engine->guc_id]); @@ -3181,7 +3176,7 @@ static int i915_semaphore_status(struct seq_file *m, void *unused) kunmap_atomic(seqno); } else { seq_puts(m, " Last signal:"); - for_each_engine(engine, dev_priv, id) + for_each_engine(engine, dev_priv) for (j = 0; j < num_rings; j++) seq_printf(m, "0x%08x\n", I915_READ(engine->semaphore.mbox.signal[j])); @@ -3189,11 +3184,10 @@ static int i915_semaphore_status(struct seq_file *m, void *unused) } seq_puts(m, "\nSync seqno:\n"); - for_each_engine(engine, dev_priv, id) { - for (j = 0; j < num_rings; j++) { + for_each_engine(engine, dev_priv) { + for (j = 0; j < num_rings; j++) seq_printf(m, " 0x%08x ", engine->semaphore.sync_seqno[j]); - } seq_putc(m, '\n'); } seq_putc(m, '\n'); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 8fe0592341b8..b93ef7017c93 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1990,10 +1990,12 @@ static inline struct drm_i915_private *guc_to_i915(struct intel_guc *guc) return container_of(guc, struct drm_i915_private, guc); } -/* Iterate over initialised rings */ -#define for_each_engine(ring__, dev_priv__, i__) \ - for ((i__) = 0; (i__) < I915_NUM_ENGINES; (i__)++) \ - for_each_if ((((ring__) = &(dev_priv__)->engine[(i__)]), intel_engine_initialized((ring__)))) +/* Simple iterator over all initialised engines */ +#define for_each_engine(engine__, dev_priv__) \ + for ((engine__) = &(dev_priv__)->engine[0]; \ + (engine__) < &(dev_priv__)->engine[I915_NUM_ENGINES]; \ + (engine__)++) \ + for_each_if (intel_engine_initialized(engine__)) /* Iterator with engine_id */ #define for_each_engine_id(engine__, dev_priv__, id__) \ @@ -2005,8 +2007,11 @@ static inline struct drm_i915_private *guc_to_i915(struct intel_guc *guc) /* Iterator over subset of engines selected by mask */ #define for_each_engine_masked(engine__, dev_priv__, mask__) \ - for ((engine__) = &dev_priv->engine[0]; (engine__) < &dev_priv->engine[I915_NUM_ENGINES]; (engine__)++) \ - for_each_if (intel_engine_flag((engine__)) & (mask__) && intel_engine_initialized((engine__))) + for ((engine__) = &(dev_priv__)->engine[0]; \ + (engine__) < &(dev_priv__)->engine[I915_NUM_ENGINES]; \ + (engine__)++) \ + for_each_if (((mask__) & intel_engine_flag(engine__)) && \ + intel_engine_initialized(engine__)) enum hdmi_force_audio { HDMI_AUDIO_OFF_DVI = -2, /* no aux data for HDMI-DVI converter */ diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 8588c83abb35..c7a997aeb33f 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2466,10 +2466,10 @@ i915_gem_init_seqno(struct drm_device *dev, u32 seqno) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *engine; - int ret, i, j; + int ret, j; /* Carefully retire all requests without writing to the rings */ - for_each_engine(engine, dev_priv, i) { + for_each_engine(engine, dev_priv) { ret = intel_engine_idle(engine); if (ret) return ret; @@ -2477,7 +2477,7 @@ i915_gem_init_seqno(struct drm_device *dev, u32 seqno) i915_gem_retire_requests(dev); /* Finally reset hw state */ - for_each_engine(engine, dev_priv, i) { + for_each_engine(engine, dev_priv) { intel_ring_init_seqno(engine, seqno); for (j = 0; j < ARRAY_SIZE(engine->semaphore.sync_seqno); j++) @@ -2884,17 +2884,16 @@ void i915_gem_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *engine; - int i; /* * Before we free the objects from the requests, we need to inspect * them for finding the guilty party. As the requests only borrow * their reference to the objects, the inspection must be done first. */ - for_each_engine(engine, dev_priv, i) + for_each_engine(engine, dev_priv) i915_gem_reset_engine_status(dev_priv, engine); - for_each_engine(engine, dev_priv, i) + for_each_engine(engine, dev_priv) i915_gem_reset_engine_cleanup(dev_priv, engine); i915_gem_context_reset(dev); @@ -2962,9 +2961,8 @@ i915_gem_retire_requests(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *engine; bool idle = true; - int i; - for_each_engine(engine, dev_priv, i) { + for_each_engine(engine, dev_priv) { i915_gem_retire_requests_ring(engine); idle &= list_empty(&engine->request_list); if (i915.enable_execlists) { @@ -3009,24 +3007,20 @@ i915_gem_idle_work_handler(struct work_struct *work) struct drm_i915_private *dev_priv = container_of(work, typeof(*dev_priv), mm.idle_work.work); struct drm_device *dev = dev_priv->dev; - struct intel_engine_cs *ring; - int i; + struct intel_engine_cs *engine; - for_each_engine(ring, dev_priv, i) - if (!list_empty(&ring->request_list)) + for_each_engine(engine, dev_priv) + if (!list_empty(&engine->request_list)) return; /* we probably should sync with hangcheck here, using cancel_work_sync. - * Also locking seems to be fubar here, ring->request_list is protected + * Also locking seems to be fubar here, engine->request_list is protected * by dev->struct_mutex. */ intel_mark_idle(dev); if (mutex_trylock(&dev->struct_mutex)) { - struct intel_engine_cs *engine; - int i; - - for_each_engine(engine, dev_priv, i) + for_each_engine(engine, dev_priv) i915_gem_batch_pool_fini(&engine->batch_pool); mutex_unlock(&dev->struct_mutex); @@ -3390,10 +3384,10 @@ int i915_gpu_idle(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *engine; - int ret, i; + int ret; /* Flush everything onto the inactive list. */ - for_each_engine(engine, dev_priv, i) { + for_each_engine(engine, dev_priv) { if (!i915.enable_execlists) { struct drm_i915_gem_request *req; @@ -4655,9 +4649,8 @@ i915_gem_stop_engines(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *engine; - int i; - for_each_engine(engine, dev_priv, i) + for_each_engine(engine, dev_priv) dev_priv->gt.stop_engine(engine); } @@ -4828,7 +4821,7 @@ i915_gem_init_hw(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *engine; - int ret, i, j; + int ret, j; if (INTEL_INFO(dev)->gen < 6 && !intel_enable_gtt()) return -EIO; @@ -4874,7 +4867,7 @@ i915_gem_init_hw(struct drm_device *dev) } /* Need to do basic initialisation of all rings first: */ - for_each_engine(engine, dev_priv, i) { + for_each_engine(engine, dev_priv) { ret = engine->init_hw(engine); if (ret) goto out; @@ -4899,7 +4892,7 @@ i915_gem_init_hw(struct drm_device *dev) goto out; /* Now it is safe to go back round and do everything else: */ - for_each_engine(engine, dev_priv, i) { + for_each_engine(engine, dev_priv) { struct drm_i915_gem_request *req; req = i915_gem_request_alloc(engine, NULL); @@ -4916,7 +4909,8 @@ i915_gem_init_hw(struct drm_device *dev) ret = i915_ppgtt_init_ring(req); if (ret && ret != -EIO) { - DRM_ERROR("PPGTT enable ring #%d failed %d\n", i, ret); + DRM_ERROR("PPGTT enable %s failed %d\n", + engine->name, ret); i915_gem_request_cancel(req); i915_gem_cleanup_engines(dev); goto out; @@ -4924,7 +4918,8 @@ i915_gem_init_hw(struct drm_device *dev) ret = i915_gem_context_enable(req); if (ret && ret != -EIO) { - DRM_ERROR("Context enable ring #%d failed %d\n", i, ret); + DRM_ERROR("Context enable %s failed %d\n", + engine->name, ret); i915_gem_request_cancel(req); i915_gem_cleanup_engines(dev); goto out; @@ -5005,9 +5000,8 @@ i915_gem_cleanup_engines(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *engine; - int i; - for_each_engine(engine, dev_priv, i) + for_each_engine(engine, dev_priv) dev_priv->gt.cleanup_engine(engine); if (i915.enable_execlists) diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 394e525e55f1..fe580cb9501a 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -517,7 +517,7 @@ mi_set_context(struct drm_i915_gem_request *req, u32 hw_flags) i915_semaphore_is_enabled(engine->dev) ? hweight32(INTEL_INFO(engine->dev)->ring_mask) - 1 : 0; - int len, i, ret; + int len, ret; /* w/a: If Flush TLB Invalidation Mode is enabled, driver must do a TLB * invalidation prior to MI_SET_CONTEXT. On GEN6 we don't set the value @@ -553,7 +553,7 @@ mi_set_context(struct drm_i915_gem_request *req, u32 hw_flags) intel_ring_emit(engine, MI_LOAD_REGISTER_IMM(num_rings)); - for_each_engine(signaller, to_i915(engine->dev), i) { + for_each_engine(signaller, to_i915(engine->dev)) { if (signaller == engine) continue; @@ -582,7 +582,7 @@ mi_set_context(struct drm_i915_gem_request *req, u32 hw_flags) intel_ring_emit(engine, MI_LOAD_REGISTER_IMM(num_rings)); - for_each_engine(signaller, to_i915(engine->dev), i) { + for_each_engine(signaller, to_i915(engine->dev)) { if (signaller == engine) continue; diff --git a/drivers/gpu/drm/i915/i915_gem_debug.c b/drivers/gpu/drm/i915/i915_gem_debug.c index ef9cd700f02f..a56516482394 100644 --- a/drivers/gpu/drm/i915/i915_gem_debug.c +++ b/drivers/gpu/drm/i915/i915_gem_debug.c @@ -38,12 +38,11 @@ i915_verify_lists(struct drm_device *dev) struct drm_i915_gem_object *obj; struct intel_engine_cs *engine; int err = 0; - int i; if (warned) return 0; - for_each_engine(engine, dev_priv, i) { + for_each_engine(engine, dev_priv) { list_for_each_entry(obj, &engine->active_list, engine_list[engine->id]) { if (obj->base.dev != dev || diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index cbbd666b0d97..7cfafdc80b17 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1737,9 +1737,8 @@ static void gen8_ppgtt_enable(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *engine; - int j; - for_each_engine(engine, dev_priv, j) { + for_each_engine(engine, dev_priv) { u32 four_level = USES_FULL_48BIT_PPGTT(dev) ? GEN8_GFX_PPGTT_48B : 0; I915_WRITE(RING_MODE_GEN7(engine), _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE | four_level)); @@ -1751,7 +1750,6 @@ static void gen7_ppgtt_enable(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *engine; uint32_t ecochk, ecobits; - int i; ecobits = I915_READ(GAC_ECO_BITS); I915_WRITE(GAC_ECO_BITS, ecobits | ECOBITS_PPGTT_CACHE64B); @@ -1765,7 +1763,7 @@ static void gen7_ppgtt_enable(struct drm_device *dev) } I915_WRITE(GAM_ECOCHK, ecochk); - for_each_engine(engine, dev_priv, i) { + for_each_engine(engine, dev_priv) { /* GFX_MODE is per-ring on gen7+ */ I915_WRITE(RING_MODE_GEN7(engine), _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE)); @@ -2287,12 +2285,11 @@ void i915_check_and_clear_faults(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *engine; - int i; if (INTEL_INFO(dev)->gen < 6) return; - for_each_engine(engine, dev_priv, i) { + for_each_engine(engine, dev_priv) { u32 fault_reg; fault_reg = I915_READ(RING_FAULT_REG(engine)); if (fault_reg & RING_FAULT_VALID) { diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 0611bdc13d2d..da86bdbba275 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -842,7 +842,7 @@ static void guc_create_ads(struct intel_guc *guc) struct guc_mmio_reg_state *reg_state; struct intel_engine_cs *engine; struct page *page; - u32 size, i; + u32 size; /* The ads obj includes the struct itself and buffers passed to GuC */ size = sizeof(struct guc_ads) + sizeof(struct guc_policies) + @@ -871,7 +871,7 @@ static void guc_create_ads(struct intel_guc *guc) engine = &dev_priv->engine[RCS]; ads->golden_context_lrca = engine->status_page.gfx_addr; - for_each_engine(engine, dev_priv, i) + for_each_engine(engine, dev_priv) ads->eng_state_size[engine->guc_id] = intel_lr_context_size(engine); /* GuC scheduling policies */ @@ -884,7 +884,7 @@ static void guc_create_ads(struct intel_guc *guc) /* MMIO reg state */ reg_state = (void *)policies + sizeof(struct guc_policies); - for_each_engine(engine, dev_priv, i) { + for_each_engine(engine, dev_priv) { reg_state->mmio_white_list[engine->guc_id].mmio_start = engine->mmio_base + GUC_MMIO_WHITE_LIST_START; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 14a23b346631..5aa42395241d 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1080,9 +1080,8 @@ static u32 vlv_wa_c0_ei(struct drm_i915_private *dev_priv, u32 pm_iir) static bool any_waiters(struct drm_i915_private *dev_priv) { struct intel_engine_cs *engine; - int i; - for_each_engine(engine, dev_priv, i) + for_each_engine(engine, dev_priv) if (engine->irq_refcount) return true; @@ -2450,7 +2449,6 @@ static void i915_error_wake_up(struct drm_i915_private *dev_priv, bool reset_completed) { struct intel_engine_cs *engine; - int i; /* * Notify all waiters for GPU completion events that reset state has @@ -2460,7 +2458,7 @@ static void i915_error_wake_up(struct drm_i915_private *dev_priv, */ /* Wake up __wait_seqno, potentially holding dev->struct_mutex. */ - for_each_engine(engine, dev_priv, i) + for_each_engine(engine, dev_priv) wake_up_all(&engine->irq_queue); /* Wake up intel_crtc_wait_for_pending_flips, holding crtc->mutex. */ @@ -2829,10 +2827,9 @@ semaphore_wait_to_signaller_ring(struct intel_engine_cs *engine, u32 ipehr, { struct drm_i915_private *dev_priv = engine->dev->dev_private; struct intel_engine_cs *signaller; - int i; if (INTEL_INFO(dev_priv->dev)->gen >= 8) { - for_each_engine(signaller, dev_priv, i) { + for_each_engine(signaller, dev_priv) { if (engine == signaller) continue; @@ -2842,7 +2839,7 @@ semaphore_wait_to_signaller_ring(struct intel_engine_cs *engine, u32 ipehr, } else { u32 sync_bits = ipehr & MI_SEMAPHORE_SYNC_MASK; - for_each_engine(signaller, dev_priv, i) { + for_each_engine(signaller, dev_priv) { if(engine == signaller) continue; @@ -2958,9 +2955,8 @@ static int semaphore_passed(struct intel_engine_cs *engine) static void semaphore_clear_deadlocks(struct drm_i915_private *dev_priv) { struct intel_engine_cs *engine; - int i; - for_each_engine(engine, dev_priv, i) + for_each_engine(engine, dev_priv) engine->hangcheck.deadlock = 0; } diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c index e1aff6263077..b4976f985369 100644 --- a/drivers/gpu/drm/i915/intel_guc_loader.c +++ b/drivers/gpu/drm/i915/intel_guc_loader.c @@ -82,12 +82,12 @@ const char *intel_guc_fw_status_repr(enum intel_guc_fw_status status) static void direct_interrupts_to_host(struct drm_i915_private *dev_priv) { struct intel_engine_cs *engine; - int i, irqs; + int irqs; /* tell all command streamers NOT to forward interrupts and vblank to GuC */ irqs = _MASKED_FIELD(GFX_FORWARD_VBLANK_MASK, GFX_FORWARD_VBLANK_NEVER); irqs |= _MASKED_BIT_DISABLE(GFX_INTERRUPT_STEERING); - for_each_engine(engine, dev_priv, i) + for_each_engine(engine, dev_priv) I915_WRITE(RING_MODE_GEN7(engine), irqs); /* route all GT interrupts to the host */ @@ -99,12 +99,12 @@ static void direct_interrupts_to_host(struct drm_i915_private *dev_priv) static void direct_interrupts_to_guc(struct drm_i915_private *dev_priv) { struct intel_engine_cs *engine; - int i, irqs; + int irqs; /* tell all command streamers to forward interrupts and vblank to GuC */ irqs = _MASKED_FIELD(GFX_FORWARD_VBLANK_MASK, GFX_FORWARD_VBLANK_ALWAYS); irqs |= _MASKED_BIT_ENABLE(GFX_INTERRUPT_STEERING); - for_each_engine(engine, dev_priv, i) + for_each_engine(engine, dev_priv) I915_WRITE(RING_MODE_GEN7(engine), irqs); /* route USER_INTERRUPT to Host, all others are sent to GuC. */ diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 40ef4eaf580f..5d4ca3b11ae2 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -2673,9 +2673,8 @@ void intel_lr_context_reset(struct drm_device *dev, { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *engine; - int i; - for_each_engine(engine, dev_priv, i) { + for_each_engine(engine, dev_priv) { struct drm_i915_gem_object *ctx_obj = ctx->engine[engine->id].state; struct intel_ringbuffer *ringbuf = diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 521cf4564329..6a04761ddc0f 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4817,7 +4817,6 @@ static void gen9_enable_rc6(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *engine; uint32_t rc6_mask = 0; - int unused; /* 1a: Software RC state - RC0 */ I915_WRITE(GEN6_RC_STATE, 0); @@ -4838,7 +4837,7 @@ static void gen9_enable_rc6(struct drm_device *dev) I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16); I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */ I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */ - for_each_engine(engine, dev_priv, unused) + for_each_engine(engine, dev_priv) I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10); if (HAS_GUC_UCODE(dev)) @@ -4887,7 +4886,6 @@ static void gen8_enable_rps(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *engine; uint32_t rc6_mask = 0; - int unused; /* 1a: Software RC state - RC0 */ I915_WRITE(GEN6_RC_STATE, 0); @@ -4906,7 +4904,7 @@ static void gen8_enable_rps(struct drm_device *dev) I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16); I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */ I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */ - for_each_engine(engine, dev_priv, unused) + for_each_engine(engine, dev_priv) I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10); I915_WRITE(GEN6_RC_SLEEP, 0); if (IS_BROADWELL(dev)) @@ -4971,7 +4969,7 @@ static void gen6_enable_rps(struct drm_device *dev) u32 rc6vids, pcu_mbox = 0, rc6_mask = 0; u32 gtfifodbg; int rc6_mode; - int i, ret; + int ret; WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); @@ -5003,7 +5001,7 @@ static void gen6_enable_rps(struct drm_device *dev) I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); - for_each_engine(engine, dev_priv, i) + for_each_engine(engine, dev_priv) I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10); I915_WRITE(GEN6_RC_SLEEP, 0); @@ -5497,7 +5495,6 @@ static void cherryview_enable_rps(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *engine; u32 gtfifodbg, val, rc6_mode = 0, pcbr; - int i; WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); @@ -5522,7 +5519,7 @@ static void cherryview_enable_rps(struct drm_device *dev) I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */ I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */ - for_each_engine(engine, dev_priv, i) + for_each_engine(engine, dev_priv) I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10); I915_WRITE(GEN6_RC_SLEEP, 0); @@ -5595,7 +5592,6 @@ static void valleyview_enable_rps(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *engine; u32 gtfifodbg, val, rc6_mode = 0; - int i; WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); @@ -5633,7 +5629,7 @@ static void valleyview_enable_rps(struct drm_device *dev) I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); - for_each_engine(engine, dev_priv, i) + for_each_engine(engine, dev_priv) I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10); I915_WRITE(GEN6_RC6_THRESHOLD, 0x557); @@ -6012,14 +6008,13 @@ bool i915_gpu_busy(void) struct drm_i915_private *dev_priv; struct intel_engine_cs *engine; bool ret = false; - int i; spin_lock_irq(&mchdev_lock); if (!i915_mch_dev) goto out_unlock; dev_priv = i915_mch_dev; - for_each_engine(engine, dev_priv, i) + for_each_engine(engine, dev_priv) ret |= !list_empty(&engine->request_list); out_unlock: -- cgit v1.2.3 From 9387bfd19b457085189d918ef117ffd63c4d67a0 Mon Sep 17 00:00:00 2001 From: Xing Zheng Date: Wed, 9 Mar 2016 10:43:31 +0800 Subject: clk: rockchip: add a COMPOSITE_FRACMUX_NOGATE type Because there are some frac clock mux nodes don't have a gate node on the RK3399. Signed-off-by: Xing Zheng Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h index 39c198bbcbee..f3da205073ee 100644 --- a/drivers/clk/rockchip/clk.h +++ b/drivers/clk/rockchip/clk.h @@ -428,6 +428,22 @@ struct rockchip_clk_branch { .child = ch, \ } +#define COMPOSITE_FRACMUX_NOGATE(_id, cname, pname, f, mo, df, ch) \ + { \ + .id = _id, \ + .branch_type = branch_fraction_divider, \ + .name = cname, \ + .parent_names = (const char *[]){ pname }, \ + .num_parents = 1, \ + .flags = f, \ + .muxdiv_offset = mo, \ + .div_shift = 16, \ + .div_width = 16, \ + .div_flags = df, \ + .gate_offset = -1, \ + .child = ch, \ + } + #define MUX(_id, cname, pnames, f, o, s, w, mf) \ { \ .id = _id, \ -- cgit v1.2.3 From 268aebaa2410152bf91ea1ede6b284ff8138822d Mon Sep 17 00:00:00 2001 From: Xing Zheng Date: Wed, 9 Mar 2016 10:37:03 +0800 Subject: clk: rockchip: allow varying mux parameters for cpuclk pll-sources Thers are only two parent PLLs that APLL and GPLL for core on the previous SoCs (RK3066/RK3188/RK3288/RK3368). Hence, we set fixed GPLL as alternate parent when core is switching freq. Since RK3399 big.LITTLE architecture, we need to select and adapt more PLLs (ALPLL/ABPLL/DPLL/GPLL) sources. Signed-off-by: Xing Zheng Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-cpu.c | 29 ++++++++++++++++++----------- drivers/clk/rockchip/clk-rk3036.c | 3 +++ drivers/clk/rockchip/clk-rk3188.c | 6 ++++++ drivers/clk/rockchip/clk-rk3228.c | 3 +++ drivers/clk/rockchip/clk-rk3288.c | 3 +++ drivers/clk/rockchip/clk-rk3368.c | 6 ++++++ drivers/clk/rockchip/clk.h | 6 ++++++ 7 files changed, 45 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/rockchip/clk-cpu.c b/drivers/clk/rockchip/clk-cpu.c index 4e73ed5cab58..4bb130cd0062 100644 --- a/drivers/clk/rockchip/clk-cpu.c +++ b/drivers/clk/rockchip/clk-cpu.c @@ -158,12 +158,16 @@ static int rockchip_cpuclk_pre_rate_change(struct rockchip_cpuclk *cpuclk, writel(HIWORD_UPDATE(alt_div, reg_data->div_core_mask, reg_data->div_core_shift) | - HIWORD_UPDATE(1, 1, reg_data->mux_core_shift), + HIWORD_UPDATE(reg_data->mux_core_alt, + reg_data->mux_core_mask, + reg_data->mux_core_shift), cpuclk->reg_base + reg_data->core_reg); } else { /* select alternate parent */ - writel(HIWORD_UPDATE(1, 1, reg_data->mux_core_shift), - cpuclk->reg_base + reg_data->core_reg); + writel(HIWORD_UPDATE(reg_data->mux_core_alt, + reg_data->mux_core_mask, + reg_data->mux_core_shift), + cpuclk->reg_base + reg_data->core_reg); } spin_unlock_irqrestore(cpuclk->lock, flags); @@ -198,7 +202,9 @@ static int rockchip_cpuclk_post_rate_change(struct rockchip_cpuclk *cpuclk, writel(HIWORD_UPDATE(0, reg_data->div_core_mask, reg_data->div_core_shift) | - HIWORD_UPDATE(0, 1, reg_data->mux_core_shift), + HIWORD_UPDATE(reg_data->mux_core_main, + reg_data->mux_core_mask, + reg_data->mux_core_shift), cpuclk->reg_base + reg_data->core_reg); if (ndata->old_rate > ndata->new_rate) @@ -252,7 +258,7 @@ struct clk *rockchip_clk_register_cpuclk(const char *name, return ERR_PTR(-ENOMEM); init.name = name; - init.parent_names = &parent_names[0]; + init.parent_names = &parent_names[reg_data->mux_core_main]; init.num_parents = 1; init.ops = &rockchip_cpuclk_ops; @@ -270,10 +276,10 @@ struct clk *rockchip_clk_register_cpuclk(const char *name, cpuclk->clk_nb.notifier_call = rockchip_cpuclk_notifier_cb; cpuclk->hw.init = &init; - cpuclk->alt_parent = __clk_lookup(parent_names[1]); + cpuclk->alt_parent = __clk_lookup(parent_names[reg_data->mux_core_alt]); if (!cpuclk->alt_parent) { - pr_err("%s: could not lookup alternate parent\n", - __func__); + pr_err("%s: could not lookup alternate parent: (%d)\n", + __func__, reg_data->mux_core_alt); ret = -EINVAL; goto free_cpuclk; } @@ -285,10 +291,11 @@ struct clk *rockchip_clk_register_cpuclk(const char *name, goto free_cpuclk; } - clk = __clk_lookup(parent_names[0]); + clk = __clk_lookup(parent_names[reg_data->mux_core_main]); if (!clk) { - pr_err("%s: could not lookup parent clock %s\n", - __func__, parent_names[0]); + pr_err("%s: could not lookup parent clock: (%d) %s\n", + __func__, reg_data->mux_core_main, + parent_names[reg_data->mux_core_main]); ret = -EINVAL; goto free_alt_parent; } diff --git a/drivers/clk/rockchip/clk-rk3036.c b/drivers/clk/rockchip/clk-rk3036.c index 7cdb2d61f3e0..f9cbba0eac36 100644 --- a/drivers/clk/rockchip/clk-rk3036.c +++ b/drivers/clk/rockchip/clk-rk3036.c @@ -113,7 +113,10 @@ static const struct rockchip_cpuclk_reg_data rk3036_cpuclk_data = { .core_reg = RK2928_CLKSEL_CON(0), .div_core_shift = 0, .div_core_mask = 0x1f, + .mux_core_alt = 1, + .mux_core_main = 0, .mux_core_shift = 7, + .mux_core_mask = 0x1, }; PNAME(mux_pll_p) = { "xin24m", "xin24m" }; diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c index 40bab3901491..e832403a0f9f 100644 --- a/drivers/clk/rockchip/clk-rk3188.c +++ b/drivers/clk/rockchip/clk-rk3188.c @@ -155,7 +155,10 @@ static const struct rockchip_cpuclk_reg_data rk3066_cpuclk_data = { .core_reg = RK2928_CLKSEL_CON(0), .div_core_shift = 0, .div_core_mask = 0x1f, + .mux_core_alt = 1, + .mux_core_main = 0, .mux_core_shift = 8, + .mux_core_mask = 0x1, }; #define RK3188_DIV_ACLK_CORE_MASK 0x7 @@ -191,7 +194,10 @@ static const struct rockchip_cpuclk_reg_data rk3188_cpuclk_data = { .core_reg = RK2928_CLKSEL_CON(0), .div_core_shift = 9, .div_core_mask = 0x1f, + .mux_core_alt = 1, + .mux_core_main = 0, .mux_core_shift = 8, + .mux_core_mask = 0x1, }; PNAME(mux_pll_p) = { "xin24m", "xin32k" }; diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c index 7702d2855e9c..4b4137e85125 100644 --- a/drivers/clk/rockchip/clk-rk3228.c +++ b/drivers/clk/rockchip/clk-rk3228.c @@ -111,7 +111,10 @@ static const struct rockchip_cpuclk_reg_data rk3228_cpuclk_data = { .core_reg = RK2928_CLKSEL_CON(0), .div_core_shift = 0, .div_core_mask = 0x1f, + .mux_core_alt = 1, + .mux_core_main = 0, .mux_core_shift = 6, + .mux_core_mask = 0x1, }; PNAME(mux_pll_p) = { "clk_24m", "xin24m" }; diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index 3cb72163a512..00faf3f9b179 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -165,7 +165,10 @@ static const struct rockchip_cpuclk_reg_data rk3288_cpuclk_data = { .core_reg = RK3288_CLKSEL_CON(0), .div_core_shift = 8, .div_core_mask = 0x1f, + .mux_core_alt = 1, + .mux_core_main = 0, .mux_core_shift = 15, + .mux_core_mask = 0x1, }; PNAME(mux_pll_p) = { "xin24m", "xin32k" }; diff --git a/drivers/clk/rockchip/clk-rk3368.c b/drivers/clk/rockchip/clk-rk3368.c index a2bb12200465..c26ff4a36dcd 100644 --- a/drivers/clk/rockchip/clk-rk3368.c +++ b/drivers/clk/rockchip/clk-rk3368.c @@ -165,14 +165,20 @@ static const struct rockchip_cpuclk_reg_data rk3368_cpuclkb_data = { .core_reg = RK3368_CLKSEL_CON(0), .div_core_shift = 0, .div_core_mask = 0x1f, + .mux_core_alt = 1, + .mux_core_main = 0, .mux_core_shift = 7, + .mux_core_mask = 0x1, }; static const struct rockchip_cpuclk_reg_data rk3368_cpuclkl_data = { .core_reg = RK3368_CLKSEL_CON(2), .div_core_shift = 0, + .mux_core_alt = 1, + .mux_core_main = 0, .div_core_mask = 0x1f, .mux_core_shift = 7, + .mux_core_mask = 0x1, }; #define RK3368_DIV_ACLKM_MASK 0x1f diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h index f3da205073ee..4133bfc8f827 100644 --- a/drivers/clk/rockchip/clk.h +++ b/drivers/clk/rockchip/clk.h @@ -217,14 +217,20 @@ struct rockchip_cpuclk_rate_table { * @core_reg: register offset of the core settings register * @div_core_shift: core divider offset used to divide the pll value * @div_core_mask: core divider mask + * @mux_core_alt: mux value to select alternate parent + * @mux_core_main: mux value to select main parent of core * @mux_core_shift: offset of the core multiplexer + * @mux_core_mask: core multiplexer mask */ struct rockchip_cpuclk_reg_data { int core_reg; u8 div_core_shift; u32 div_core_mask; int mux_core_reg; + u8 mux_core_alt; + u8 mux_core_main; u8 mux_core_shift; + u32 mux_core_mask; }; struct clk *rockchip_clk_register_cpuclk(const char *name, -- cgit v1.2.3 From ef1d9feeccc094f59b72bb11fe14ec886eb574d3 Mon Sep 17 00:00:00 2001 From: Xing Zheng Date: Wed, 9 Mar 2016 10:37:04 +0800 Subject: clk: rockchip: Add support for multiple clock providers There are need to support Multi-CRUs probability in future, but it is not supported on the current Rockchip Clock Framework. Therefore, this patch add support a provider as the parameter handler when we call the clock register functions for per CRU. Signed-off-by: Xing Zheng Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-pll.c | 30 ++++---- drivers/clk/rockchip/clk-rk3036.c | 17 +++-- drivers/clk/rockchip/clk-rk3188.c | 44 ++++++++---- drivers/clk/rockchip/clk-rk3228.c | 17 +++-- drivers/clk/rockchip/clk-rk3288.c | 19 +++-- drivers/clk/rockchip/clk-rk3368.c | 21 ++++-- drivers/clk/rockchip/clk.c | 148 +++++++++++++++++++++++--------------- drivers/clk/rockchip/clk.h | 51 +++++++++---- 8 files changed, 229 insertions(+), 118 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c index 5de797e34d54..27be66a2a358 100644 --- a/drivers/clk/rockchip/clk-pll.c +++ b/drivers/clk/rockchip/clk-pll.c @@ -46,6 +46,8 @@ struct rockchip_clk_pll { const struct rockchip_pll_rate_table *rate_table; unsigned int rate_count; spinlock_t *lock; + + struct rockchip_clk_provider *ctx; }; #define to_rockchip_clk_pll(_hw) container_of(_hw, struct rockchip_clk_pll, hw) @@ -90,7 +92,7 @@ static long rockchip_pll_round_rate(struct clk_hw *hw, */ static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll) { - struct regmap *grf = rockchip_clk_get_grf(); + struct regmap *grf = rockchip_clk_get_grf(pll->ctx); unsigned int val; int delay = 24000000, ret; @@ -251,7 +253,7 @@ static int rockchip_rk3036_pll_set_rate(struct clk_hw *hw, unsigned long drate, struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); const struct rockchip_pll_rate_table *rate; unsigned long old_rate = rockchip_rk3036_pll_recalc_rate(hw, prate); - struct regmap *grf = rockchip_clk_get_grf(); + struct regmap *grf = rockchip_clk_get_grf(pll->ctx); if (IS_ERR(grf)) { pr_debug("%s: grf regmap not available, aborting rate change\n", @@ -490,7 +492,7 @@ static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate, struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); const struct rockchip_pll_rate_table *rate; unsigned long old_rate = rockchip_rk3066_pll_recalc_rate(hw, prate); - struct regmap *grf = rockchip_clk_get_grf(); + struct regmap *grf = rockchip_clk_get_grf(pll->ctx); if (IS_ERR(grf)) { pr_debug("%s: grf regmap not available, aborting rate change\n", @@ -563,7 +565,7 @@ static void rockchip_rk3066_pll_init(struct clk_hw *hw) rate->no, cur.no, rate->nf, cur.nf, rate->nb, cur.nb); if (rate->nr != cur.nr || rate->no != cur.no || rate->nf != cur.nf || rate->nb != cur.nb) { - struct regmap *grf = rockchip_clk_get_grf(); + struct regmap *grf = rockchip_clk_get_grf(pll->ctx); if (IS_ERR(grf)) return; @@ -595,12 +597,13 @@ static const struct clk_ops rockchip_rk3066_pll_clk_ops = { * Common registering of pll clocks */ -struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, +struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, + enum rockchip_pll_type pll_type, const char *name, const char *const *parent_names, - u8 num_parents, void __iomem *base, int con_offset, - int grf_lock_offset, int lock_shift, int mode_offset, - int mode_shift, struct rockchip_pll_rate_table *rate_table, - u8 clk_pll_flags, spinlock_t *lock) + u8 num_parents, int con_offset, int grf_lock_offset, + int lock_shift, int mode_offset, int mode_shift, + struct rockchip_pll_rate_table *rate_table, + u8 clk_pll_flags) { const char *pll_parents[3]; struct clk_init_data init; @@ -624,11 +627,11 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, /* create the mux on top of the real pll */ pll->pll_mux_ops = &clk_mux_ops; pll_mux = &pll->pll_mux; - pll_mux->reg = base + mode_offset; + pll_mux->reg = ctx->reg_base + mode_offset; pll_mux->shift = mode_shift; pll_mux->mask = PLL_MODE_MASK; pll_mux->flags = 0; - pll_mux->lock = lock; + pll_mux->lock = &ctx->lock; pll_mux->hw.init = &init; if (pll_type == pll_rk3036 || pll_type == pll_rk3066) @@ -695,11 +698,12 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, pll->hw.init = &init; pll->type = pll_type; - pll->reg_base = base + con_offset; + pll->reg_base = ctx->reg_base + con_offset; pll->lock_offset = grf_lock_offset; pll->lock_shift = lock_shift; pll->flags = clk_pll_flags; - pll->lock = lock; + pll->lock = &ctx->lock; + pll->ctx = ctx; pll_clk = clk_register(NULL, &pll->hw); if (IS_ERR(pll_clk)) { diff --git a/drivers/clk/rockchip/clk-rk3036.c b/drivers/clk/rockchip/clk-rk3036.c index f9cbba0eac36..c7c8260e1c66 100644 --- a/drivers/clk/rockchip/clk-rk3036.c +++ b/drivers/clk/rockchip/clk-rk3036.c @@ -440,6 +440,7 @@ static const char *const rk3036_critical_clocks[] __initconst = { static void __init rk3036_clk_init(struct device_node *np) { + struct rockchip_clk_provider *ctx; void __iomem *reg_base; struct clk *clk; @@ -449,22 +450,26 @@ static void __init rk3036_clk_init(struct device_node *np) return; } - rockchip_clk_init(np, reg_base, CLK_NR_CLKS); + ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS); + if (IS_ERR(ctx)) { + pr_err("%s: rockchip clk init failed\n", __func__); + return; + } clk = clk_register_fixed_factor(NULL, "usb480m", "xin24m", 0, 20, 1); if (IS_ERR(clk)) pr_warn("%s: could not register clock usb480m: %ld\n", __func__, PTR_ERR(clk)); - rockchip_clk_register_plls(rk3036_pll_clks, + rockchip_clk_register_plls(ctx, rk3036_pll_clks, ARRAY_SIZE(rk3036_pll_clks), RK3036_GRF_SOC_STATUS0); - rockchip_clk_register_branches(rk3036_clk_branches, + rockchip_clk_register_branches(ctx, rk3036_clk_branches, ARRAY_SIZE(rk3036_clk_branches)); rockchip_clk_protect_critical(rk3036_critical_clocks, ARRAY_SIZE(rk3036_critical_clocks)); - rockchip_clk_register_armclk(ARMCLK, "armclk", + rockchip_clk_register_armclk(ctx, ARMCLK, "armclk", mux_armclk_p, ARRAY_SIZE(mux_armclk_p), &rk3036_cpuclk_data, rk3036_cpuclk_rates, ARRAY_SIZE(rk3036_cpuclk_rates)); @@ -472,6 +477,8 @@ static void __init rk3036_clk_init(struct device_node *np) rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0), ROCKCHIP_SOFTRST_HIWORD_MASK); - rockchip_register_restart_notifier(RK2928_GLB_SRST_FST, NULL); + rockchip_register_restart_notifier(ctx, RK2928_GLB_SRST_FST, NULL); + + rockchip_clk_of_add_provider(np, ctx); } CLK_OF_DECLARE(rk3036_cru, "rockchip,rk3036-cru", rk3036_clk_init); diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c index e832403a0f9f..0fcce2295b37 100644 --- a/drivers/clk/rockchip/clk-rk3188.c +++ b/drivers/clk/rockchip/clk-rk3188.c @@ -759,57 +759,74 @@ static const char *const rk3188_critical_clocks[] __initconst = { "hclk_cpubus" }; -static void __init rk3188_common_clk_init(struct device_node *np) +static struct rockchip_clk_provider *__init rk3188_common_clk_init(struct device_node *np) { + struct rockchip_clk_provider *ctx; void __iomem *reg_base; reg_base = of_iomap(np, 0); if (!reg_base) { pr_err("%s: could not map cru region\n", __func__); - return; + return ERR_PTR(-ENOMEM); } - rockchip_clk_init(np, reg_base, CLK_NR_CLKS); + ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS); + if (IS_ERR(ctx)) { + pr_err("%s: rockchip clk init failed\n", __func__); + return ERR_PTR(-ENOMEM); + } - rockchip_clk_register_branches(common_clk_branches, + rockchip_clk_register_branches(ctx, common_clk_branches, ARRAY_SIZE(common_clk_branches)); rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0), ROCKCHIP_SOFTRST_HIWORD_MASK); - rockchip_register_restart_notifier(RK2928_GLB_SRST_FST, NULL); + rockchip_register_restart_notifier(ctx, RK2928_GLB_SRST_FST, NULL); + + return ctx; } static void __init rk3066a_clk_init(struct device_node *np) { - rk3188_common_clk_init(np); - rockchip_clk_register_plls(rk3066_pll_clks, + struct rockchip_clk_provider *ctx; + + ctx = rk3188_common_clk_init(np); + if (IS_ERR(ctx)) + return; + + rockchip_clk_register_plls(ctx, rk3066_pll_clks, ARRAY_SIZE(rk3066_pll_clks), RK3066_GRF_SOC_STATUS); - rockchip_clk_register_branches(rk3066a_clk_branches, + rockchip_clk_register_branches(ctx, rk3066a_clk_branches, ARRAY_SIZE(rk3066a_clk_branches)); - rockchip_clk_register_armclk(ARMCLK, "armclk", + rockchip_clk_register_armclk(ctx, ARMCLK, "armclk", mux_armclk_p, ARRAY_SIZE(mux_armclk_p), &rk3066_cpuclk_data, rk3066_cpuclk_rates, ARRAY_SIZE(rk3066_cpuclk_rates)); rockchip_clk_protect_critical(rk3188_critical_clocks, ARRAY_SIZE(rk3188_critical_clocks)); + rockchip_clk_of_add_provider(np, ctx); } CLK_OF_DECLARE(rk3066a_cru, "rockchip,rk3066a-cru", rk3066a_clk_init); static void __init rk3188a_clk_init(struct device_node *np) { + struct rockchip_clk_provider *ctx; struct clk *clk1, *clk2; unsigned long rate; int ret; - rk3188_common_clk_init(np); - rockchip_clk_register_plls(rk3188_pll_clks, + ctx = rk3188_common_clk_init(np); + if (IS_ERR(ctx)) + return; + + rockchip_clk_register_plls(ctx, rk3188_pll_clks, ARRAY_SIZE(rk3188_pll_clks), RK3188_GRF_SOC_STATUS); - rockchip_clk_register_branches(rk3188_clk_branches, + rockchip_clk_register_branches(ctx, rk3188_clk_branches, ARRAY_SIZE(rk3188_clk_branches)); - rockchip_clk_register_armclk(ARMCLK, "armclk", + rockchip_clk_register_armclk(ctx, ARMCLK, "armclk", mux_armclk_p, ARRAY_SIZE(mux_armclk_p), &rk3188_cpuclk_data, rk3188_cpuclk_rates, ARRAY_SIZE(rk3188_cpuclk_rates)); @@ -833,6 +850,7 @@ static void __init rk3188a_clk_init(struct device_node *np) rockchip_clk_protect_critical(rk3188_critical_clocks, ARRAY_SIZE(rk3188_critical_clocks)); + rockchip_clk_of_add_provider(np, ctx); } CLK_OF_DECLARE(rk3188a_cru, "rockchip,rk3188a-cru", rk3188a_clk_init); diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c index 4b4137e85125..c112b2f95224 100644 --- a/drivers/clk/rockchip/clk-rk3228.c +++ b/drivers/clk/rockchip/clk-rk3228.c @@ -628,6 +628,7 @@ static const char *const rk3228_critical_clocks[] __initconst = { static void __init rk3228_clk_init(struct device_node *np) { + struct rockchip_clk_provider *ctx; void __iomem *reg_base; reg_base = of_iomap(np, 0); @@ -636,17 +637,21 @@ static void __init rk3228_clk_init(struct device_node *np) return; } - rockchip_clk_init(np, reg_base, CLK_NR_CLKS); + ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS); + if (IS_ERR(ctx)) { + pr_err("%s: rockchip clk init failed\n", __func__); + return; + } - rockchip_clk_register_plls(rk3228_pll_clks, + rockchip_clk_register_plls(ctx, rk3228_pll_clks, ARRAY_SIZE(rk3228_pll_clks), RK3228_GRF_SOC_STATUS0); - rockchip_clk_register_branches(rk3228_clk_branches, + rockchip_clk_register_branches(ctx, rk3228_clk_branches, ARRAY_SIZE(rk3228_clk_branches)); rockchip_clk_protect_critical(rk3228_critical_clocks, ARRAY_SIZE(rk3228_critical_clocks)); - rockchip_clk_register_armclk(ARMCLK, "armclk", + rockchip_clk_register_armclk(ctx, ARMCLK, "armclk", mux_armclk_p, ARRAY_SIZE(mux_armclk_p), &rk3228_cpuclk_data, rk3228_cpuclk_rates, ARRAY_SIZE(rk3228_cpuclk_rates)); @@ -654,6 +659,8 @@ static void __init rk3228_clk_init(struct device_node *np) rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0), ROCKCHIP_SOFTRST_HIWORD_MASK); - rockchip_register_restart_notifier(RK3228_GLB_SRST_FST, NULL); + rockchip_register_restart_notifier(ctx, RK3228_GLB_SRST_FST, NULL); + + rockchip_clk_of_add_provider(np, ctx); } CLK_OF_DECLARE(rk3228_cru, "rockchip,rk3228-cru", rk3228_clk_init); diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index 00faf3f9b179..d1031d1149ce 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -881,6 +881,7 @@ static struct syscore_ops rk3288_clk_syscore_ops = { static void __init rk3288_clk_init(struct device_node *np) { + struct rockchip_clk_provider *ctx; struct clk *clk; rk3288_cru_base = of_iomap(np, 0); @@ -889,7 +890,11 @@ static void __init rk3288_clk_init(struct device_node *np) return; } - rockchip_clk_init(np, rk3288_cru_base, CLK_NR_CLKS); + ctx = rockchip_clk_init(np, rk3288_cru_base, CLK_NR_CLKS); + if (IS_ERR(ctx)) { + pr_err("%s: rockchip clk init failed\n", __func__); + return; + } /* Watchdog pclk is controlled by RK3288_SGRF_SOC_CON0[1]. */ clk = clk_register_fixed_factor(NULL, "pclk_wdt", "pclk_pd_alive", 0, 1, 1); @@ -897,17 +902,17 @@ static void __init rk3288_clk_init(struct device_node *np) pr_warn("%s: could not register clock pclk_wdt: %ld\n", __func__, PTR_ERR(clk)); else - rockchip_clk_add_lookup(clk, PCLK_WDT); + rockchip_clk_add_lookup(ctx, clk, PCLK_WDT); - rockchip_clk_register_plls(rk3288_pll_clks, + rockchip_clk_register_plls(ctx, rk3288_pll_clks, ARRAY_SIZE(rk3288_pll_clks), RK3288_GRF_SOC_STATUS1); - rockchip_clk_register_branches(rk3288_clk_branches, + rockchip_clk_register_branches(ctx, rk3288_clk_branches, ARRAY_SIZE(rk3288_clk_branches)); rockchip_clk_protect_critical(rk3288_critical_clocks, ARRAY_SIZE(rk3288_critical_clocks)); - rockchip_clk_register_armclk(ARMCLK, "armclk", + rockchip_clk_register_armclk(ctx, ARMCLK, "armclk", mux_armclk_p, ARRAY_SIZE(mux_armclk_p), &rk3288_cpuclk_data, rk3288_cpuclk_rates, ARRAY_SIZE(rk3288_cpuclk_rates)); @@ -916,8 +921,10 @@ static void __init rk3288_clk_init(struct device_node *np) rk3288_cru_base + RK3288_SOFTRST_CON(0), ROCKCHIP_SOFTRST_HIWORD_MASK); - rockchip_register_restart_notifier(RK3288_GLB_SRST_FST, + rockchip_register_restart_notifier(ctx, RK3288_GLB_SRST_FST, rk3288_clk_shutdown); register_syscore_ops(&rk3288_clk_syscore_ops); + + rockchip_clk_of_add_provider(np, ctx); } CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init); diff --git a/drivers/clk/rockchip/clk-rk3368.c b/drivers/clk/rockchip/clk-rk3368.c index c26ff4a36dcd..3121414cfd63 100644 --- a/drivers/clk/rockchip/clk-rk3368.c +++ b/drivers/clk/rockchip/clk-rk3368.c @@ -862,6 +862,7 @@ static const char *const rk3368_critical_clocks[] __initconst = { static void __init rk3368_clk_init(struct device_node *np) { + struct rockchip_clk_provider *ctx; void __iomem *reg_base; struct clk *clk; @@ -871,7 +872,11 @@ static void __init rk3368_clk_init(struct device_node *np) return; } - rockchip_clk_init(np, reg_base, CLK_NR_CLKS); + ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS); + if (IS_ERR(ctx)) { + pr_err("%s: rockchip clk init failed\n", __func__); + return; + } /* Watchdog pclk is controlled by sgrf_soc_con3[7]. */ clk = clk_register_fixed_factor(NULL, "pclk_wdt", "pclk_pd_alive", 0, 1, 1); @@ -879,22 +884,22 @@ static void __init rk3368_clk_init(struct device_node *np) pr_warn("%s: could not register clock pclk_wdt: %ld\n", __func__, PTR_ERR(clk)); else - rockchip_clk_add_lookup(clk, PCLK_WDT); + rockchip_clk_add_lookup(ctx, clk, PCLK_WDT); - rockchip_clk_register_plls(rk3368_pll_clks, + rockchip_clk_register_plls(ctx, rk3368_pll_clks, ARRAY_SIZE(rk3368_pll_clks), RK3368_GRF_SOC_STATUS0); - rockchip_clk_register_branches(rk3368_clk_branches, + rockchip_clk_register_branches(ctx, rk3368_clk_branches, ARRAY_SIZE(rk3368_clk_branches)); rockchip_clk_protect_critical(rk3368_critical_clocks, ARRAY_SIZE(rk3368_critical_clocks)); - rockchip_clk_register_armclk(ARMCLKB, "armclkb", + rockchip_clk_register_armclk(ctx, ARMCLKB, "armclkb", mux_armclkb_p, ARRAY_SIZE(mux_armclkb_p), &rk3368_cpuclkb_data, rk3368_cpuclkb_rates, ARRAY_SIZE(rk3368_cpuclkb_rates)); - rockchip_clk_register_armclk(ARMCLKL, "armclkl", + rockchip_clk_register_armclk(ctx, ARMCLKL, "armclkl", mux_armclkl_p, ARRAY_SIZE(mux_armclkl_p), &rk3368_cpuclkl_data, rk3368_cpuclkl_rates, ARRAY_SIZE(rk3368_cpuclkl_rates)); @@ -902,6 +907,8 @@ static void __init rk3368_clk_init(struct device_node *np) rockchip_register_softrst(np, 15, reg_base + RK3368_SOFTRST_CON(0), ROCKCHIP_SOFTRST_HIWORD_MASK); - rockchip_register_restart_notifier(RK3368_GLB_SRST_FST, NULL); + rockchip_register_restart_notifier(ctx, RK3368_GLB_SRST_FST, NULL); + + rockchip_clk_of_add_provider(np, ctx); } CLK_OF_DECLARE(rk3368_cru, "rockchip,rk3368-cru", rk3368_clk_init); diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index ec06350c78c4..5618a8761dee 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c @@ -2,6 +2,9 @@ * Copyright (c) 2014 MundoReader S.L. * Author: Heiko Stuebner * + * Copyright (c) 2016 Rockchip Electronics Co. Ltd. + * Author: Xing Zheng + * * based on * * samsung/clk.c @@ -157,7 +160,8 @@ static int rockchip_clk_frac_notifier_cb(struct notifier_block *nb, return notifier_from_errno(ret); } -static struct clk *rockchip_clk_register_frac_branch(const char *name, +static struct clk *rockchip_clk_register_frac_branch( + struct rockchip_clk_provider *ctx, const char *name, const char *const *parent_names, u8 num_parents, void __iomem *base, int muxdiv_offset, u8 div_flags, int gate_offset, u8 gate_shift, u8 gate_flags, @@ -250,7 +254,7 @@ static struct clk *rockchip_clk_register_frac_branch(const char *name, if (IS_ERR(mux_clk)) return clk; - rockchip_clk_add_lookup(mux_clk, child->id); + rockchip_clk_add_lookup(ctx, mux_clk, child->id); /* notifier on the fraction divider to catch rate changes */ if (frac->mux_frac_idx >= 0) { @@ -314,66 +318,94 @@ static struct clk *rockchip_clk_register_factor_branch(const char *name, return clk; } -static DEFINE_SPINLOCK(clk_lock); -static struct clk **clk_table; -static void __iomem *reg_base; -static struct clk_onecell_data clk_data; -static struct device_node *cru_node; -static struct regmap *grf; - -void __init rockchip_clk_init(struct device_node *np, void __iomem *base, - unsigned long nr_clks) +struct rockchip_clk_provider * __init rockchip_clk_init(struct device_node *np, + void __iomem *base, unsigned long nr_clks) { - reg_base = base; - cru_node = np; - grf = ERR_PTR(-EPROBE_DEFER); + struct rockchip_clk_provider *ctx; + struct clk **clk_table; + int i; + + ctx = kzalloc(sizeof(struct rockchip_clk_provider), GFP_KERNEL); + if (!ctx) { + pr_err("%s: Could not allocate clock provider context\n", + __func__); + return ERR_PTR(-ENOMEM); + } clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL); - if (!clk_table) - pr_err("%s: could not allocate clock lookup table\n", __func__); + if (!clk_table) { + pr_err("%s: Could not allocate clock lookup table\n", + __func__); + goto err_free; + } + + for (i = 0; i < nr_clks; ++i) + clk_table[i] = ERR_PTR(-ENOENT); - clk_data.clks = clk_table; - clk_data.clk_num = nr_clks; - of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); + ctx->reg_base = base; + ctx->clk_data.clks = clk_table; + ctx->clk_data.clk_num = nr_clks; + ctx->cru_node = np; + ctx->grf = ERR_PTR(-EPROBE_DEFER); + spin_lock_init(&ctx->lock); + + return ctx; + +err_free: + kfree(ctx); + return ERR_PTR(-ENOMEM); +} + +void __init rockchip_clk_of_add_provider(struct device_node *np, + struct rockchip_clk_provider *ctx) +{ + if (np) { + if (of_clk_add_provider(np, of_clk_src_onecell_get, + &ctx->clk_data)) + pr_err("%s: could not register clk provider\n", __func__); + } } -struct regmap *rockchip_clk_get_grf(void) +struct regmap *rockchip_clk_get_grf(struct rockchip_clk_provider *ctx) { - if (IS_ERR(grf)) - grf = syscon_regmap_lookup_by_phandle(cru_node, "rockchip,grf"); - return grf; + if (IS_ERR(ctx->grf)) + ctx->grf = syscon_regmap_lookup_by_phandle(ctx->cru_node, "rockchip,grf"); + return ctx->grf; } -void rockchip_clk_add_lookup(struct clk *clk, unsigned int id) +void rockchip_clk_add_lookup(struct rockchip_clk_provider *ctx, + struct clk *clk, unsigned int id) { - if (clk_table && id) - clk_table[id] = clk; + if (ctx->clk_data.clks && id) + ctx->clk_data.clks[id] = clk; } -void __init rockchip_clk_register_plls(struct rockchip_pll_clock *list, +void __init rockchip_clk_register_plls(struct rockchip_clk_provider *ctx, + struct rockchip_pll_clock *list, unsigned int nr_pll, int grf_lock_offset) { struct clk *clk; int idx; for (idx = 0; idx < nr_pll; idx++, list++) { - clk = rockchip_clk_register_pll(list->type, list->name, + clk = rockchip_clk_register_pll(ctx, list->type, list->name, list->parent_names, list->num_parents, - reg_base, list->con_offset, grf_lock_offset, + list->con_offset, grf_lock_offset, list->lock_shift, list->mode_offset, list->mode_shift, list->rate_table, - list->pll_flags, &clk_lock); + list->pll_flags); if (IS_ERR(clk)) { pr_err("%s: failed to register clock %s\n", __func__, list->name); continue; } - rockchip_clk_add_lookup(clk, list->id); + rockchip_clk_add_lookup(ctx, clk, list->id); } } void __init rockchip_clk_register_branches( + struct rockchip_clk_provider *ctx, struct rockchip_clk_branch *list, unsigned int nr_clk) { @@ -389,56 +421,56 @@ void __init rockchip_clk_register_branches( case branch_mux: clk = clk_register_mux(NULL, list->name, list->parent_names, list->num_parents, - flags, reg_base + list->muxdiv_offset, + flags, ctx->reg_base + list->muxdiv_offset, list->mux_shift, list->mux_width, - list->mux_flags, &clk_lock); + list->mux_flags, &ctx->lock); break; case branch_divider: if (list->div_table) clk = clk_register_divider_table(NULL, list->name, list->parent_names[0], - flags, reg_base + list->muxdiv_offset, + flags, ctx->reg_base + list->muxdiv_offset, list->div_shift, list->div_width, list->div_flags, list->div_table, - &clk_lock); + &ctx->lock); else clk = clk_register_divider(NULL, list->name, list->parent_names[0], flags, - reg_base + list->muxdiv_offset, + ctx->reg_base + list->muxdiv_offset, list->div_shift, list->div_width, - list->div_flags, &clk_lock); + list->div_flags, &ctx->lock); break; case branch_fraction_divider: - clk = rockchip_clk_register_frac_branch(list->name, + clk = rockchip_clk_register_frac_branch(ctx, list->name, list->parent_names, list->num_parents, - reg_base, list->muxdiv_offset, list->div_flags, + ctx->reg_base, list->muxdiv_offset, list->div_flags, list->gate_offset, list->gate_shift, list->gate_flags, flags, list->child, - &clk_lock); + &ctx->lock); break; case branch_gate: flags |= CLK_SET_RATE_PARENT; clk = clk_register_gate(NULL, list->name, list->parent_names[0], flags, - reg_base + list->gate_offset, - list->gate_shift, list->gate_flags, &clk_lock); + ctx->reg_base + list->gate_offset, + list->gate_shift, list->gate_flags, &ctx->lock); break; case branch_composite: clk = rockchip_clk_register_branch(list->name, list->parent_names, list->num_parents, - reg_base, list->muxdiv_offset, list->mux_shift, + ctx->reg_base, list->muxdiv_offset, list->mux_shift, list->mux_width, list->mux_flags, list->div_shift, list->div_width, list->div_flags, list->div_table, list->gate_offset, list->gate_shift, - list->gate_flags, flags, &clk_lock); + list->gate_flags, flags, &ctx->lock); break; case branch_mmc: clk = rockchip_clk_register_mmc( list->name, list->parent_names, list->num_parents, - reg_base + list->muxdiv_offset, + ctx->reg_base + list->muxdiv_offset, list->div_shift ); break; @@ -446,16 +478,16 @@ void __init rockchip_clk_register_branches( clk = rockchip_clk_register_inverter( list->name, list->parent_names, list->num_parents, - reg_base + list->muxdiv_offset, - list->div_shift, list->div_flags, &clk_lock); + ctx->reg_base + list->muxdiv_offset, + list->div_shift, list->div_flags, &ctx->lock); break; case branch_factor: clk = rockchip_clk_register_factor_branch( list->name, list->parent_names, - list->num_parents, reg_base, + list->num_parents, ctx->reg_base, list->div_shift, list->div_width, list->gate_offset, list->gate_shift, - list->gate_flags, flags, &clk_lock); + list->gate_flags, flags, &ctx->lock); break; } @@ -472,11 +504,12 @@ void __init rockchip_clk_register_branches( continue; } - rockchip_clk_add_lookup(clk, list->id); + rockchip_clk_add_lookup(ctx, clk, list->id); } } -void __init rockchip_clk_register_armclk(unsigned int lookup_id, +void __init rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx, + unsigned int lookup_id, const char *name, const char *const *parent_names, u8 num_parents, const struct rockchip_cpuclk_reg_data *reg_data, @@ -486,15 +519,15 @@ void __init rockchip_clk_register_armclk(unsigned int lookup_id, struct clk *clk; clk = rockchip_clk_register_cpuclk(name, parent_names, num_parents, - reg_data, rates, nrates, reg_base, - &clk_lock); + reg_data, rates, nrates, ctx->reg_base, + &ctx->lock); if (IS_ERR(clk)) { pr_err("%s: failed to register clock %s: %ld\n", __func__, name, PTR_ERR(clk)); return; } - rockchip_clk_add_lookup(clk, lookup_id); + rockchip_clk_add_lookup(ctx, clk, lookup_id); } void __init rockchip_clk_protect_critical(const char *const clocks[], @@ -511,6 +544,7 @@ void __init rockchip_clk_protect_critical(const char *const clocks[], } } +static void __iomem *rst_base; static unsigned int reg_restart; static void (*cb_restart)(void); static int rockchip_restart_notify(struct notifier_block *this, @@ -519,7 +553,7 @@ static int rockchip_restart_notify(struct notifier_block *this, if (cb_restart) cb_restart(); - writel(0xfdb9, reg_base + reg_restart); + writel(0xfdb9, rst_base + reg_restart); return NOTIFY_DONE; } @@ -528,10 +562,12 @@ static struct notifier_block rockchip_restart_handler = { .priority = 128, }; -void __init rockchip_register_restart_notifier(unsigned int reg, void (*cb)(void)) +void __init rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx, + unsigned int reg, void (*cb)(void)) { int ret; + rst_base = ctx->reg_base; reg_restart = reg; cb_restart = cb; ret = register_restart_handler(&rockchip_restart_handler); diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h index 4133bfc8f827..e243d509da89 100644 --- a/drivers/clk/rockchip/clk.h +++ b/drivers/clk/rockchip/clk.h @@ -27,6 +27,7 @@ #define CLK_ROCKCHIP_CLK_H #include +#include struct clk; @@ -127,6 +128,22 @@ enum rockchip_pll_type { .nb = _nb, \ } +/** + * struct rockchip_clk_provider: information about clock provider + * @reg_base: virtual address for the register base. + * @clk_data: holds clock related data like clk* and number of clocks. + * @cru_node: device-node of the clock-provider + * @grf: regmap of the general-register-files syscon + * @lock: maintains exclusion between callbacks for a given clock-provider. + */ +struct rockchip_clk_provider { + void __iomem *reg_base; + struct clk_onecell_data clk_data; + struct device_node *cru_node; + struct regmap *grf; + spinlock_t lock; +}; + struct rockchip_pll_rate_table { unsigned long rate; unsigned int nr; @@ -194,12 +211,13 @@ struct rockchip_pll_clock { .rate_table = _rtable, \ } -struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, +struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, + enum rockchip_pll_type pll_type, const char *name, const char *const *parent_names, - u8 num_parents, void __iomem *base, int con_offset, - int grf_lock_offset, int lock_shift, int reg_mode, - int mode_shift, struct rockchip_pll_rate_table *rate_table, - u8 clk_pll_flags, spinlock_t *lock); + u8 num_parents, int con_offset, int grf_lock_offset, + int lock_shift, int mode_offset, int mode_shift, + struct rockchip_pll_rate_table *rate_table, + u8 clk_pll_flags); struct rockchip_cpuclk_clksel { int reg; @@ -558,21 +576,28 @@ struct rockchip_clk_branch { .gate_flags = gf, \ } -void rockchip_clk_init(struct device_node *np, void __iomem *base, - unsigned long nr_clks); -struct regmap *rockchip_clk_get_grf(void); -void rockchip_clk_add_lookup(struct clk *clk, unsigned int id); -void rockchip_clk_register_branches(struct rockchip_clk_branch *clk_list, +struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np, + void __iomem *base, unsigned long nr_clks); +void rockchip_clk_of_add_provider(struct device_node *np, + struct rockchip_clk_provider *ctx); +struct regmap *rockchip_clk_get_grf(struct rockchip_clk_provider *ctx); +void rockchip_clk_add_lookup(struct rockchip_clk_provider *ctx, + struct clk *clk, unsigned int id); +void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx, + struct rockchip_clk_branch *list, unsigned int nr_clk); -void rockchip_clk_register_plls(struct rockchip_pll_clock *pll_list, +void rockchip_clk_register_plls(struct rockchip_clk_provider *ctx, + struct rockchip_pll_clock *pll_list, unsigned int nr_pll, int grf_lock_offset); -void rockchip_clk_register_armclk(unsigned int lookup_id, const char *name, +void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx, + unsigned int lookup_id, const char *name, const char *const *parent_names, u8 num_parents, const struct rockchip_cpuclk_reg_data *reg_data, const struct rockchip_cpuclk_rate_table *rates, int nrates); void rockchip_clk_protect_critical(const char *const clocks[], int nclocks); -void rockchip_register_restart_notifier(unsigned int reg, void (*cb)(void)); +void rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx, + unsigned int reg, void (*cb)(void)); #define ROCKCHIP_SOFTRST_HIWORD_MASK BIT(0) -- cgit v1.2.3 From b40baccd236a9a91fbb077efb8dadb41fdfb55ab Mon Sep 17 00:00:00 2001 From: Xing Zheng Date: Thu, 10 Mar 2016 11:47:01 +0800 Subject: clk: rockchip: add new pll-type for rk3399 and similar socs The rk3399's pll and clock are similar with rk3036's, it different with base on the rk3066(rk3188, rk3288, rk3368 use it), there are different adjust foctors and control registers, so these should be independent and separate from the series of rk3066s. Signed-off-by: Xing Zheng Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-pll.c | 271 ++++++++++++++++++++++++++++++++++++++++- drivers/clk/rockchip/clk.h | 3 +- 2 files changed, 272 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c index 27be66a2a358..128a6b2fca7f 100644 --- a/drivers/clk/rockchip/clk-pll.c +++ b/drivers/clk/rockchip/clk-pll.c @@ -593,6 +593,267 @@ static const struct clk_ops rockchip_rk3066_pll_clk_ops = { .init = rockchip_rk3066_pll_init, }; +/** + * PLL used in RK3399 + */ + +#define RK3399_PLLCON(i) (i * 0x4) +#define RK3399_PLLCON0_FBDIV_MASK 0xfff +#define RK3399_PLLCON0_FBDIV_SHIFT 0 +#define RK3399_PLLCON1_REFDIV_MASK 0x3f +#define RK3399_PLLCON1_REFDIV_SHIFT 0 +#define RK3399_PLLCON1_POSTDIV1_MASK 0x7 +#define RK3399_PLLCON1_POSTDIV1_SHIFT 8 +#define RK3399_PLLCON1_POSTDIV2_MASK 0x7 +#define RK3399_PLLCON1_POSTDIV2_SHIFT 12 +#define RK3399_PLLCON2_FRAC_MASK 0xffffff +#define RK3399_PLLCON2_FRAC_SHIFT 0 +#define RK3399_PLLCON2_LOCK_STATUS BIT(31) +#define RK3399_PLLCON3_PWRDOWN BIT(0) +#define RK3399_PLLCON3_DSMPD_MASK 0x1 +#define RK3399_PLLCON3_DSMPD_SHIFT 3 + +static int rockchip_rk3399_pll_wait_lock(struct rockchip_clk_pll *pll) +{ + u32 pllcon; + int delay = 24000000; + + /* poll check the lock status in rk3399 xPLLCON2 */ + while (delay > 0) { + pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2)); + if (pllcon & RK3399_PLLCON2_LOCK_STATUS) + return 0; + + delay--; + } + + pr_err("%s: timeout waiting for pll to lock\n", __func__); + return -ETIMEDOUT; +} + +static void rockchip_rk3399_pll_get_params(struct rockchip_clk_pll *pll, + struct rockchip_pll_rate_table *rate) +{ + u32 pllcon; + + pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(0)); + rate->fbdiv = ((pllcon >> RK3399_PLLCON0_FBDIV_SHIFT) + & RK3399_PLLCON0_FBDIV_MASK); + + pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(1)); + rate->refdiv = ((pllcon >> RK3399_PLLCON1_REFDIV_SHIFT) + & RK3399_PLLCON1_REFDIV_MASK); + rate->postdiv1 = ((pllcon >> RK3399_PLLCON1_POSTDIV1_SHIFT) + & RK3399_PLLCON1_POSTDIV1_MASK); + rate->postdiv2 = ((pllcon >> RK3399_PLLCON1_POSTDIV2_SHIFT) + & RK3399_PLLCON1_POSTDIV2_MASK); + + pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2)); + rate->frac = ((pllcon >> RK3399_PLLCON2_FRAC_SHIFT) + & RK3399_PLLCON2_FRAC_MASK); + + pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(3)); + rate->dsmpd = ((pllcon >> RK3399_PLLCON3_DSMPD_SHIFT) + & RK3399_PLLCON3_DSMPD_MASK); +} + +static unsigned long rockchip_rk3399_pll_recalc_rate(struct clk_hw *hw, + unsigned long prate) +{ + struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); + struct rockchip_pll_rate_table cur; + u64 rate64 = prate; + + rockchip_rk3399_pll_get_params(pll, &cur); + + rate64 *= cur.fbdiv; + do_div(rate64, cur.refdiv); + + if (cur.dsmpd == 0) { + /* fractional mode */ + u64 frac_rate64 = prate * cur.frac; + + do_div(frac_rate64, cur.refdiv); + rate64 += frac_rate64 >> 24; + } + + do_div(rate64, cur.postdiv1); + do_div(rate64, cur.postdiv2); + + return (unsigned long)rate64; +} + +static int rockchip_rk3399_pll_set_params(struct rockchip_clk_pll *pll, + const struct rockchip_pll_rate_table *rate) +{ + const struct clk_ops *pll_mux_ops = pll->pll_mux_ops; + struct clk_mux *pll_mux = &pll->pll_mux; + struct rockchip_pll_rate_table cur; + u32 pllcon; + int rate_change_remuxed = 0; + int cur_parent; + int ret; + + pr_debug("%s: rate settings for %lu fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n", + __func__, rate->rate, rate->fbdiv, rate->postdiv1, rate->refdiv, + rate->postdiv2, rate->dsmpd, rate->frac); + + rockchip_rk3399_pll_get_params(pll, &cur); + cur.rate = 0; + + cur_parent = pll_mux_ops->get_parent(&pll_mux->hw); + if (cur_parent == PLL_MODE_NORM) { + pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW); + rate_change_remuxed = 1; + } + + /* update pll values */ + writel_relaxed(HIWORD_UPDATE(rate->fbdiv, RK3399_PLLCON0_FBDIV_MASK, + RK3399_PLLCON0_FBDIV_SHIFT), + pll->reg_base + RK3399_PLLCON(0)); + + writel_relaxed(HIWORD_UPDATE(rate->refdiv, RK3399_PLLCON1_REFDIV_MASK, + RK3399_PLLCON1_REFDIV_SHIFT) | + HIWORD_UPDATE(rate->postdiv1, RK3399_PLLCON1_POSTDIV1_MASK, + RK3399_PLLCON1_POSTDIV1_SHIFT) | + HIWORD_UPDATE(rate->postdiv2, RK3399_PLLCON1_POSTDIV2_MASK, + RK3399_PLLCON1_POSTDIV2_SHIFT), + pll->reg_base + RK3399_PLLCON(1)); + + /* xPLL CON2 is not HIWORD_MASK */ + pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2)); + pllcon &= ~(RK3399_PLLCON2_FRAC_MASK << RK3399_PLLCON2_FRAC_SHIFT); + pllcon |= rate->frac << RK3399_PLLCON2_FRAC_SHIFT; + writel_relaxed(pllcon, pll->reg_base + RK3399_PLLCON(2)); + + writel_relaxed(HIWORD_UPDATE(rate->dsmpd, RK3399_PLLCON3_DSMPD_MASK, + RK3399_PLLCON3_DSMPD_SHIFT), + pll->reg_base + RK3399_PLLCON(3)); + + /* wait for the pll to lock */ + ret = rockchip_rk3399_pll_wait_lock(pll); + if (ret) { + pr_warn("%s: pll update unsuccessful, trying to restore old params\n", + __func__); + rockchip_rk3399_pll_set_params(pll, &cur); + } + + if (rate_change_remuxed) + pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM); + + return ret; +} + +static int rockchip_rk3399_pll_set_rate(struct clk_hw *hw, unsigned long drate, + unsigned long prate) +{ + struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); + const struct rockchip_pll_rate_table *rate; + unsigned long old_rate = rockchip_rk3399_pll_recalc_rate(hw, prate); + + pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n", + __func__, __clk_get_name(hw->clk), old_rate, drate, prate); + + /* Get required rate settings from table */ + rate = rockchip_get_pll_settings(pll, drate); + if (!rate) { + pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__, + drate, __clk_get_name(hw->clk)); + return -EINVAL; + } + + return rockchip_rk3399_pll_set_params(pll, rate); +} + +static int rockchip_rk3399_pll_enable(struct clk_hw *hw) +{ + struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); + + writel(HIWORD_UPDATE(0, RK3399_PLLCON3_PWRDOWN, 0), + pll->reg_base + RK3399_PLLCON(3)); + + return 0; +} + +static void rockchip_rk3399_pll_disable(struct clk_hw *hw) +{ + struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); + + writel(HIWORD_UPDATE(RK3399_PLLCON3_PWRDOWN, + RK3399_PLLCON3_PWRDOWN, 0), + pll->reg_base + RK3399_PLLCON(3)); +} + +static int rockchip_rk3399_pll_is_enabled(struct clk_hw *hw) +{ + struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); + u32 pllcon = readl(pll->reg_base + RK3399_PLLCON(3)); + + return !(pllcon & RK3399_PLLCON3_PWRDOWN); +} + +static void rockchip_rk3399_pll_init(struct clk_hw *hw) +{ + struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); + const struct rockchip_pll_rate_table *rate; + struct rockchip_pll_rate_table cur; + unsigned long drate; + + if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE)) + return; + + drate = clk_hw_get_rate(hw); + rate = rockchip_get_pll_settings(pll, drate); + + /* when no rate setting for the current rate, rely on clk_set_rate */ + if (!rate) + return; + + rockchip_rk3399_pll_get_params(pll, &cur); + + pr_debug("%s: pll %s@%lu: Hz\n", __func__, __clk_get_name(hw->clk), + drate); + pr_debug("old - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n", + cur.fbdiv, cur.postdiv1, cur.refdiv, cur.postdiv2, + cur.dsmpd, cur.frac); + pr_debug("new - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n", + rate->fbdiv, rate->postdiv1, rate->refdiv, rate->postdiv2, + rate->dsmpd, rate->frac); + + if (rate->fbdiv != cur.fbdiv || rate->postdiv1 != cur.postdiv1 || + rate->refdiv != cur.refdiv || rate->postdiv2 != cur.postdiv2 || + rate->dsmpd != cur.dsmpd || rate->frac != cur.frac) { + struct clk *parent = clk_get_parent(hw->clk); + + if (!parent) { + pr_warn("%s: parent of %s not available\n", + __func__, __clk_get_name(hw->clk)); + return; + } + + pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n", + __func__, __clk_get_name(hw->clk)); + rockchip_rk3399_pll_set_params(pll, rate); + } +} + +static const struct clk_ops rockchip_rk3399_pll_clk_norate_ops = { + .recalc_rate = rockchip_rk3399_pll_recalc_rate, + .enable = rockchip_rk3399_pll_enable, + .disable = rockchip_rk3399_pll_disable, + .is_enabled = rockchip_rk3399_pll_is_enabled, +}; + +static const struct clk_ops rockchip_rk3399_pll_clk_ops = { + .recalc_rate = rockchip_rk3399_pll_recalc_rate, + .round_rate = rockchip_pll_round_rate, + .set_rate = rockchip_rk3399_pll_set_rate, + .enable = rockchip_rk3399_pll_enable, + .disable = rockchip_rk3399_pll_disable, + .is_enabled = rockchip_rk3399_pll_is_enabled, + .init = rockchip_rk3399_pll_init, +}; + /* * Common registering of pll clocks */ @@ -634,7 +895,9 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, pll_mux->lock = &ctx->lock; pll_mux->hw.init = &init; - if (pll_type == pll_rk3036 || pll_type == pll_rk3066) + if (pll_type == pll_rk3036 || + pll_type == pll_rk3066 || + pll_type == pll_rk3399) pll_mux->flags |= CLK_MUX_HIWORD_MASK; /* the actual muxing is xin24m, pll-output, xin32k */ @@ -691,6 +954,12 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, else init.ops = &rockchip_rk3066_pll_clk_ops; break; + case pll_rk3399: + if (!pll->rate_table) + init.ops = &rockchip_rk3399_pll_clk_norate_ops; + else + init.ops = &rockchip_rk3399_pll_clk_ops; + break; default: pr_warn("%s: Unknown pll type for pll clk %s\n", __func__, name); diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h index e243d509da89..4798786703b8 100644 --- a/drivers/clk/rockchip/clk.h +++ b/drivers/clk/rockchip/clk.h @@ -96,6 +96,7 @@ struct clk; enum rockchip_pll_type { pll_rk3036, pll_rk3066, + pll_rk3399, }; #define RK3036_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1, \ @@ -150,7 +151,7 @@ struct rockchip_pll_rate_table { unsigned int nf; unsigned int no; unsigned int nb; - /* for RK3036 */ + /* for RK3036/RK3399 */ unsigned int fbdiv; unsigned int postdiv1; unsigned int refdiv; -- cgit v1.2.3 From cb3abdd628abe8583c81b07d5bb8b6d1dbd12227 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Sun, 13 Mar 2016 00:25:00 +0800 Subject: clk: rockchip: remove mux_core_reg from rockchip_cpuclk_reg_data mux_core_reg isn't been used anywhere, let's remove it. Signed-off-by: Shawn Lin Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk.h | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h index 4798786703b8..b298f99dae97 100644 --- a/drivers/clk/rockchip/clk.h +++ b/drivers/clk/rockchip/clk.h @@ -245,7 +245,6 @@ struct rockchip_cpuclk_reg_data { int core_reg; u8 div_core_shift; u32 div_core_mask; - int mux_core_reg; u8 mux_core_alt; u8 mux_core_main; u8 mux_core_shift; -- cgit v1.2.3 From 2af2544d60f007277a98f66391a521ec377a6a67 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Sun, 13 Mar 2016 00:25:14 +0800 Subject: clk: rockchip: fix warning reported by kernel-doc ./scripts/kernel-doc -man -v drivers/clk/rockchip/clk.h > /dev/null drivers/clk/rockchip/clk.h:133: warning: missing initial short description on line: * struct rockchip_clk_provider: information about clock provider drivers/clk/rockchip/clk.h:133: info: Scanning doc for struct drivers/clk/rockchip/clk.h:164: warning: missing initial short description on line: * struct rockchip_pll_clock: information about pll clock drivers/clk/rockchip/clk.h:164: info: Scanning doc for struct drivers/clk/rockchip/clk.h:194: warning: No description found for parameter 'parent_names' drivers/clk/rockchip/clk.h:194: warning: No description found for parameter 'num_parents' drivers/clk/rockchip/clk.h:194: warning: Excess struct/union/enum/typedef member 'parent_name' description in 'rockchip_pll_clock' drivers/clk/rockchip/clk.h:235: warning: missing initial short description on line: * struct rockchip_cpuclk_reg_data: describes register offsets and masks of the cpuclock Signed-off-by: Shawn Lin Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h index b298f99dae97..cb6a63963693 100644 --- a/drivers/clk/rockchip/clk.h +++ b/drivers/clk/rockchip/clk.h @@ -130,7 +130,7 @@ enum rockchip_pll_type { } /** - * struct rockchip_clk_provider: information about clock provider + * struct rockchip_clk_provider - information about clock provider * @reg_base: virtual address for the register base. * @clk_data: holds clock related data like clk* and number of clocks. * @cru_node: device-node of the clock-provider @@ -161,10 +161,11 @@ struct rockchip_pll_rate_table { }; /** - * struct rockchip_pll_clock: information about pll clock + * struct rockchip_pll_clock - information about pll clock * @id: platform specific id of the clock. * @name: name of this pll clock. - * @parent_name: name of the parent clock. + * @parent_names: name of the parent clock. + * @num_parents: number of parents * @flags: optional flags for basic clock. * @con_offset: offset of the register for configuring the PLL. * @mode_offset: offset of the register for configuring the PLL-mode. @@ -232,7 +233,7 @@ struct rockchip_cpuclk_rate_table { }; /** - * struct rockchip_cpuclk_reg_data: describes register offsets and masks of the cpuclock + * struct rockchip_cpuclk_reg_data - describes register offsets and masks of the cpuclock * @core_reg: register offset of the core settings register * @div_core_shift: core divider offset used to divide the pll value * @div_core_mask: core divider mask -- cgit v1.2.3 From ff1ae209617cb31a5297bd103709d6b9e2db77d2 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Sun, 13 Mar 2016 00:25:53 +0800 Subject: clk: rockchip: remove redundant checking of device_node rockchip_clk_of_add_provider is used by sub-clk driver which already call of_iomap before calling it. If device_node does not exist, of_iomap returns NULL which will fail to init the sub-clk driver. So really it's redundant. Signed-off-by: Shawn Lin Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index 5618a8761dee..277f9270bf72 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c @@ -359,11 +359,9 @@ err_free: void __init rockchip_clk_of_add_provider(struct device_node *np, struct rockchip_clk_provider *ctx) { - if (np) { - if (of_clk_add_provider(np, of_clk_src_onecell_get, - &ctx->clk_data)) - pr_err("%s: could not register clk provider\n", __func__); - } + if (of_clk_add_provider(np, of_clk_src_onecell_get, + &ctx->clk_data)) + pr_err("%s: could not register clk provider\n", __func__); } struct regmap *rockchip_clk_get_grf(struct rockchip_clk_provider *ctx) -- cgit v1.2.3 From 1d003eb0805ac5b549e76202a1e95da33f62cb9a Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Sun, 13 Mar 2016 12:13:22 +0800 Subject: clk: rockchip: release io resource when failing to init clk We should call iounmap to relase reg_base since it's not going to be used any more if failing to init clk. Signed-off-by: Shawn Lin Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3036.c | 1 + drivers/clk/rockchip/clk-rk3188.c | 1 + drivers/clk/rockchip/clk-rk3228.c | 1 + drivers/clk/rockchip/clk-rk3288.c | 1 + drivers/clk/rockchip/clk-rk3368.c | 1 + 5 files changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/rockchip/clk-rk3036.c b/drivers/clk/rockchip/clk-rk3036.c index c7c8260e1c66..924f560dcf80 100644 --- a/drivers/clk/rockchip/clk-rk3036.c +++ b/drivers/clk/rockchip/clk-rk3036.c @@ -453,6 +453,7 @@ static void __init rk3036_clk_init(struct device_node *np) ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS); if (IS_ERR(ctx)) { pr_err("%s: rockchip clk init failed\n", __func__); + iounmap(reg_base); return; } diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c index 0fcce2295b37..d0e722a0e8cf 100644 --- a/drivers/clk/rockchip/clk-rk3188.c +++ b/drivers/clk/rockchip/clk-rk3188.c @@ -773,6 +773,7 @@ static struct rockchip_clk_provider *__init rk3188_common_clk_init(struct device ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS); if (IS_ERR(ctx)) { pr_err("%s: rockchip clk init failed\n", __func__); + iounmap(reg_base); return ERR_PTR(-ENOMEM); } diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c index c112b2f95224..016bdb0b793a 100644 --- a/drivers/clk/rockchip/clk-rk3228.c +++ b/drivers/clk/rockchip/clk-rk3228.c @@ -640,6 +640,7 @@ static void __init rk3228_clk_init(struct device_node *np) ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS); if (IS_ERR(ctx)) { pr_err("%s: rockchip clk init failed\n", __func__); + iounmap(reg_base); return; } diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index d1031d1149ce..39af05a589b3 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -893,6 +893,7 @@ static void __init rk3288_clk_init(struct device_node *np) ctx = rockchip_clk_init(np, rk3288_cru_base, CLK_NR_CLKS); if (IS_ERR(ctx)) { pr_err("%s: rockchip clk init failed\n", __func__); + iounmap(rk3288_cru_base); return; } diff --git a/drivers/clk/rockchip/clk-rk3368.c b/drivers/clk/rockchip/clk-rk3368.c index 3121414cfd63..6cb474c593e7 100644 --- a/drivers/clk/rockchip/clk-rk3368.c +++ b/drivers/clk/rockchip/clk-rk3368.c @@ -875,6 +875,7 @@ static void __init rk3368_clk_init(struct device_node *np) ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS); if (IS_ERR(ctx)) { pr_err("%s: rockchip clk init failed\n", __func__); + iounmap(reg_base); return; } -- cgit v1.2.3 From e6e45420f41fc613569e8bb6d15e0472dc0ea1ab Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 24 Mar 2016 14:18:03 +0100 Subject: iio: st_sensors: simplify buffer address handling The driver goes to some length to dynamically allocate an array to hold the channel addresses. However no ST sensor has more than three channels (x, y, z at most). Instead of kmalloc():ing and kfree():in the address array, just use a fixed array of three elements. Cc: Giuseppe Barba Signed-off-by: Linus Walleij Acked-by: Denis Ciocca Signed-off-by: Jonathan Cameron --- drivers/iio/common/st_sensors/st_sensors_buffer.c | 28 ++++++----------------- 1 file changed, 7 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/common/st_sensors/st_sensors_buffer.c b/drivers/iio/common/st_sensors/st_sensors_buffer.c index e18bc6782256..73764961feac 100644 --- a/drivers/iio/common/st_sensors/st_sensors_buffer.c +++ b/drivers/iio/common/st_sensors/st_sensors_buffer.c @@ -24,19 +24,13 @@ int st_sensors_get_buffer_element(struct iio_dev *indio_dev, u8 *buf) { - u8 *addr; + u8 addr[3]; /* no ST sensor has more than 3 channels */ int i, n = 0, len; struct st_sensor_data *sdata = iio_priv(indio_dev); unsigned int num_data_channels = sdata->num_data_channels; unsigned int byte_for_channel = indio_dev->channels[0].scan_type.storagebits >> 3; - addr = kmalloc(num_data_channels, GFP_KERNEL); - if (!addr) { - len = -ENOMEM; - goto st_sensors_get_buffer_element_error; - } - for (i = 0; i < num_data_channels; i++) { if (test_bit(i, indio_dev->active_scan_mask)) { addr[n] = indio_dev->channels[i].address; @@ -57,10 +51,8 @@ int st_sensors_get_buffer_element(struct iio_dev *indio_dev, u8 *buf) u8 *rx_array; rx_array = kmalloc(byte_for_channel * num_data_channels, GFP_KERNEL); - if (!rx_array) { - len = -ENOMEM; - goto st_sensors_free_memory; - } + if (!rx_array) + return -ENOMEM; len = sdata->tf->read_multiple_byte(&sdata->tb, sdata->dev, addr[0], @@ -68,7 +60,7 @@ int st_sensors_get_buffer_element(struct iio_dev *indio_dev, u8 *buf) rx_array, sdata->multiread_bit); if (len < 0) { kfree(rx_array); - goto st_sensors_free_memory; + return len; } for (i = 0; i < n * byte_for_channel; i++) { @@ -87,17 +79,11 @@ int st_sensors_get_buffer_element(struct iio_dev *indio_dev, u8 *buf) buf, sdata->multiread_bit); break; default: - len = -EINVAL; - goto st_sensors_free_memory; - } - if (len != byte_for_channel * n) { - len = -EIO; - goto st_sensors_free_memory; + return -EINVAL; } + if (len != byte_for_channel * n) + return -EIO; -st_sensors_free_memory: - kfree(addr); -st_sensors_get_buffer_element_error: return len; } EXPORT_SYMBOL(st_sensors_get_buffer_element); -- cgit v1.2.3 From 51fadb985786929af9377245042b412302d2c9a2 Mon Sep 17 00:00:00 2001 From: Alison Schofield Date: Sat, 26 Mar 2016 12:50:24 -0700 Subject: staging: iio: convert bare unsigned usage to unsigned int Use kernel preferred unsigned int declaration style. Patch created using: git ls-files drivers/staging/iio | \ xargs ./scripts/checkpatch.pl -f --fix-inplace --types=unspecified_int Hand edits restored columns in structure definitions. Signed-off-by: Alison Schofield Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/ad7280a.c | 40 +++++++++++------------ drivers/staging/iio/adc/ad7280a.h | 8 ++--- drivers/staging/iio/adc/ad7606.h | 28 ++++++++-------- drivers/staging/iio/adc/ad7606_core.c | 6 ++-- drivers/staging/iio/adc/ad7780.c | 2 +- drivers/staging/iio/impedance-analyzer/ad5933.c | 14 ++++---- drivers/staging/iio/meter/ade7758_ring.c | 4 +-- drivers/staging/iio/resolver/ad2s1210.h | 8 ++--- drivers/staging/iio/trigger/iio-trig-bfin-timer.c | 12 +++---- 9 files changed, 61 insertions(+), 61 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/adc/ad7280a.c b/drivers/staging/iio/adc/ad7280a.c index 62e5ecacf634..a06b46cb81ca 100644 --- a/drivers/staging/iio/adc/ad7280a.c +++ b/drivers/staging/iio/adc/ad7280a.c @@ -155,7 +155,7 @@ static void ad7280_crc8_build_table(unsigned char *crc_tab) } } -static unsigned char ad7280_calc_crc8(unsigned char *crc_tab, unsigned val) +static unsigned char ad7280_calc_crc8(unsigned char *crc_tab, unsigned int val) { unsigned char crc; @@ -165,7 +165,7 @@ static unsigned char ad7280_calc_crc8(unsigned char *crc_tab, unsigned val) return crc ^ (val & 0xFF); } -static int ad7280_check_crc(struct ad7280_state *st, unsigned val) +static int ad7280_check_crc(struct ad7280_state *st, unsigned int val) { unsigned char crc = ad7280_calc_crc8(st->crc_tab, val >> 10); @@ -191,7 +191,7 @@ static void ad7280_delay(struct ad7280_state *st) usleep_range(250, 500); } -static int __ad7280_read32(struct ad7280_state *st, unsigned *val) +static int __ad7280_read32(struct ad7280_state *st, unsigned int *val) { int ret; struct spi_transfer t = { @@ -211,10 +211,10 @@ static int __ad7280_read32(struct ad7280_state *st, unsigned *val) return 0; } -static int ad7280_write(struct ad7280_state *st, unsigned devaddr, - unsigned addr, bool all, unsigned val) +static int ad7280_write(struct ad7280_state *st, unsigned int devaddr, + unsigned int addr, bool all, unsigned int val) { - unsigned reg = devaddr << 27 | addr << 21 | + unsigned int reg = devaddr << 27 | addr << 21 | (val & 0xFF) << 13 | all << 12; reg |= ad7280_calc_crc8(st->crc_tab, reg >> 11) << 3 | 0x2; @@ -223,11 +223,11 @@ static int ad7280_write(struct ad7280_state *st, unsigned devaddr, return spi_write(st->spi, &st->buf[0], 4); } -static int ad7280_read(struct ad7280_state *st, unsigned devaddr, - unsigned addr) +static int ad7280_read(struct ad7280_state *st, unsigned int devaddr, + unsigned int addr) { int ret; - unsigned tmp; + unsigned int tmp; /* turns off the read operation on all parts */ ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, AD7280A_CONTROL_HB, 1, @@ -261,11 +261,11 @@ static int ad7280_read(struct ad7280_state *st, unsigned devaddr, return (tmp >> 13) & 0xFF; } -static int ad7280_read_channel(struct ad7280_state *st, unsigned devaddr, - unsigned addr) +static int ad7280_read_channel(struct ad7280_state *st, unsigned int devaddr, + unsigned int addr) { int ret; - unsigned tmp; + unsigned int tmp; ret = ad7280_write(st, devaddr, AD7280A_READ, 0, addr << 2); if (ret) @@ -299,11 +299,11 @@ static int ad7280_read_channel(struct ad7280_state *st, unsigned devaddr, return (tmp >> 11) & 0xFFF; } -static int ad7280_read_all_channels(struct ad7280_state *st, unsigned cnt, - unsigned *array) +static int ad7280_read_all_channels(struct ad7280_state *st, unsigned int cnt, + unsigned int *array) { int i, ret; - unsigned tmp, sum = 0; + unsigned int tmp, sum = 0; ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, AD7280A_READ, 1, AD7280A_CELL_VOLTAGE_1 << 2); @@ -338,7 +338,7 @@ static int ad7280_read_all_channels(struct ad7280_state *st, unsigned cnt, static int ad7280_chain_setup(struct ad7280_state *st) { - unsigned val, n; + unsigned int val, n; int ret; ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, AD7280A_CONTROL_LB, 1, @@ -401,7 +401,7 @@ static ssize_t ad7280_store_balance_sw(struct device *dev, struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); bool readin; int ret; - unsigned devaddr, ch; + unsigned int devaddr, ch; ret = strtobool(buf, &readin); if (ret) @@ -431,7 +431,7 @@ static ssize_t ad7280_show_balance_timer(struct device *dev, struct ad7280_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); int ret; - unsigned msecs; + unsigned int msecs; mutex_lock(&indio_dev->mlock); ret = ad7280_read(st, this_attr->address >> 8, @@ -602,7 +602,7 @@ static ssize_t ad7280_read_channel_config(struct device *dev, struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7280_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - unsigned val; + unsigned int val; switch ((u32)this_attr->address) { case AD7280A_CELL_OVERVOLTAGE: @@ -683,7 +683,7 @@ static irqreturn_t ad7280_event_handler(int irq, void *private) { struct iio_dev *indio_dev = private; struct ad7280_state *st = iio_priv(indio_dev); - unsigned *channels; + unsigned int *channels; int i, ret; channels = kcalloc(st->scan_cnt, sizeof(*channels), GFP_KERNEL); diff --git a/drivers/staging/iio/adc/ad7280a.h b/drivers/staging/iio/adc/ad7280a.h index 732347a9bce4..ccfb90d20e71 100644 --- a/drivers/staging/iio/adc/ad7280a.h +++ b/drivers/staging/iio/adc/ad7280a.h @@ -29,10 +29,10 @@ #define AD7280A_ALERT_REMOVE_AUX4_AUX5 BIT(1) struct ad7280_platform_data { - unsigned acquisition_time; - unsigned conversion_averaging; - unsigned chain_last_alert_ignore; - bool thermistor_term_en; + unsigned int acquisition_time; + unsigned int conversion_averaging; + unsigned int chain_last_alert_ignore; + bool thermistor_term_en; }; #endif /* IIO_ADC_AD7280_H_ */ diff --git a/drivers/staging/iio/adc/ad7606.h b/drivers/staging/iio/adc/ad7606.h index cca946924c58..39f50440d915 100644 --- a/drivers/staging/iio/adc/ad7606.h +++ b/drivers/staging/iio/adc/ad7606.h @@ -28,16 +28,16 @@ */ struct ad7606_platform_data { - unsigned default_os; - unsigned default_range; - unsigned gpio_convst; - unsigned gpio_reset; - unsigned gpio_range; - unsigned gpio_os0; - unsigned gpio_os1; - unsigned gpio_os2; - unsigned gpio_frstdata; - unsigned gpio_stby; + unsigned int default_os; + unsigned int default_range; + unsigned int gpio_convst; + unsigned int gpio_reset; + unsigned int gpio_range; + unsigned int gpio_os0; + unsigned int gpio_os1; + unsigned int gpio_os2; + unsigned int gpio_frstdata; + unsigned int gpio_stby; }; /** @@ -52,7 +52,7 @@ struct ad7606_chip_info { const char *name; u16 int_vref_mv; const struct iio_chan_spec *channels; - unsigned num_channels; + unsigned int num_channels; }; /** @@ -67,8 +67,8 @@ struct ad7606_state { struct work_struct poll_work; wait_queue_head_t wq_data_avail; const struct ad7606_bus_ops *bops; - unsigned range; - unsigned oversampling; + unsigned int range; + unsigned int oversampling; bool done; void __iomem *base_address; @@ -86,7 +86,7 @@ struct ad7606_bus_ops { }; struct iio_dev *ad7606_probe(struct device *dev, int irq, - void __iomem *base_address, unsigned id, + void __iomem *base_address, unsigned int id, const struct ad7606_bus_ops *bops); int ad7606_remove(struct iio_dev *indio_dev, int irq); int ad7606_reset(struct ad7606_state *st); diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/adc/ad7606_core.c index fe6caeee0843..6dbc811730ae 100644 --- a/drivers/staging/iio/adc/ad7606_core.c +++ b/drivers/staging/iio/adc/ad7606_core.c @@ -36,7 +36,7 @@ int ad7606_reset(struct ad7606_state *st) return -ENODEV; } -static int ad7606_scan_direct(struct iio_dev *indio_dev, unsigned ch) +static int ad7606_scan_direct(struct iio_dev *indio_dev, unsigned int ch) { struct ad7606_state *st = iio_priv(indio_dev); int ret; @@ -155,7 +155,7 @@ static ssize_t ad7606_show_oversampling_ratio(struct device *dev, return sprintf(buf, "%u\n", st->oversampling); } -static int ad7606_oversampling_get_index(unsigned val) +static int ad7606_oversampling_get_index(unsigned int val) { unsigned char supported[] = {0, 2, 4, 8, 16, 32, 64}; int i; @@ -446,7 +446,7 @@ static const struct iio_info ad7606_info_range = { struct iio_dev *ad7606_probe(struct device *dev, int irq, void __iomem *base_address, - unsigned id, + unsigned int id, const struct ad7606_bus_ops *bops) { struct ad7606_platform_data *pdata = dev->platform_data; diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c index 1439cfdbb09c..c9a0c2aa602f 100644 --- a/drivers/staging/iio/adc/ad7780.c +++ b/drivers/staging/iio/adc/ad7780.c @@ -63,7 +63,7 @@ static int ad7780_set_mode(struct ad_sigma_delta *sigma_delta, enum ad_sigma_delta_mode mode) { struct ad7780_state *st = ad_sigma_delta_to_ad7780(sigma_delta); - unsigned val; + unsigned int val; switch (mode) { case AD_SD_MODE_SINGLE: diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index d1218d896725..65947d38edd7 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c @@ -93,14 +93,14 @@ struct ad5933_state { unsigned long mclk_hz; unsigned char ctrl_hb; unsigned char ctrl_lb; - unsigned range_avail[4]; + unsigned int range_avail[4]; unsigned short vref_mv; unsigned short settling_cycles; unsigned short freq_points; - unsigned freq_start; - unsigned freq_inc; - unsigned state; - unsigned poll_time_jiffies; + unsigned int freq_start; + unsigned int freq_inc; + unsigned int state; + unsigned int poll_time_jiffies; }; static struct ad5933_platform_data ad5933_default_pdata = { @@ -214,7 +214,7 @@ static int ad5933_wait_busy(struct ad5933_state *st, unsigned char event) } static int ad5933_set_freq(struct ad5933_state *st, - unsigned reg, unsigned long freq) + unsigned int reg, unsigned long freq) { unsigned long long freqreg; union { @@ -274,7 +274,7 @@ static int ad5933_setup(struct ad5933_state *st) static void ad5933_calc_out_ranges(struct ad5933_state *st) { int i; - unsigned normalized_3v3[4] = {1980, 198, 383, 970}; + unsigned int normalized_3v3[4] = {1980, 198, 383, 970}; for (i = 0; i < 4; i++) st->range_avail[i] = normalized_3v3[i] * st->vref_mv / 3300; diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c index 9a24e0226f8b..a6b76d4b1c80 100644 --- a/drivers/staging/iio/meter/ade7758_ring.c +++ b/drivers/staging/iio/meter/ade7758_ring.c @@ -33,7 +33,7 @@ static int ade7758_spi_read_burst(struct iio_dev *indio_dev) return ret; } -static int ade7758_write_waveform_type(struct device *dev, unsigned type) +static int ade7758_write_waveform_type(struct device *dev, unsigned int type) { int ret; u8 reg; @@ -85,7 +85,7 @@ static irqreturn_t ade7758_trigger_handler(int irq, void *p) **/ static int ade7758_ring_preenable(struct iio_dev *indio_dev) { - unsigned channel; + unsigned int channel; if (bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength)) return -EINVAL; diff --git a/drivers/staging/iio/resolver/ad2s1210.h b/drivers/staging/iio/resolver/ad2s1210.h index c7158f6e61c2..e9b2147701fc 100644 --- a/drivers/staging/iio/resolver/ad2s1210.h +++ b/drivers/staging/iio/resolver/ad2s1210.h @@ -12,9 +12,9 @@ #define _AD2S1210_H struct ad2s1210_platform_data { - unsigned sample; - unsigned a[2]; - unsigned res[2]; - bool gpioin; + unsigned int sample; + unsigned int a[2]; + unsigned int res[2]; + bool gpioin; }; #endif /* _AD2S1210_H */ diff --git a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c index 035dd456d7d6..aeafad41f9c0 100644 --- a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c +++ b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c @@ -55,12 +55,12 @@ static struct bfin_timer iio_bfin_timer_code[MAX_BLACKFIN_GPTIMERS] = { }; struct bfin_tmr_state { - struct iio_trigger *trig; - struct bfin_timer *t; - unsigned timer_num; - bool output_enable; - unsigned int duty; - int irq; + struct iio_trigger *trig; + struct bfin_timer *t; + unsigned int timer_num; + bool output_enable; + unsigned int duty; + int irq; }; static int iio_bfin_tmr_set_state(struct iio_trigger *trig, bool state) -- cgit v1.2.3 From 7d1f1bf699efc9b0f0e92c910dc667a4511943f5 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 24 Mar 2016 15:35:42 +0200 Subject: spi: pxa2xx: handle error of pxa2xx_spi_dma_prepare() If by some reason pxa2xx_spi_dma_prepare() fails we have not to ignore its error. In such case we abort the transfer and return the error to upper level. Signed-off-by: Andy Shevchenko [Jarkko: Avoid leaking TX descriptors in case RX descriptor allocation fails. Noted by Robert Jarzmik . Unmap also buffers in case of failure.] Signed-off-by: Jarkko Nikula Acked-by: Robert Jarzmik Signed-off-by: Mark Brown --- drivers/spi/spi-pxa2xx-dma.c | 13 +++++++++++-- drivers/spi/spi-pxa2xx.c | 8 +++++++- 2 files changed, 18 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-pxa2xx-dma.c b/drivers/spi/spi-pxa2xx-dma.c index 365fc22c3572..b1883d228103 100644 --- a/drivers/spi/spi-pxa2xx-dma.c +++ b/drivers/spi/spi-pxa2xx-dma.c @@ -267,19 +267,22 @@ irqreturn_t pxa2xx_spi_dma_transfer(struct driver_data *drv_data) int pxa2xx_spi_dma_prepare(struct driver_data *drv_data, u32 dma_burst) { struct dma_async_tx_descriptor *tx_desc, *rx_desc; + int err = 0; tx_desc = pxa2xx_spi_dma_prepare_one(drv_data, DMA_MEM_TO_DEV); if (!tx_desc) { dev_err(&drv_data->pdev->dev, "failed to get DMA TX descriptor\n"); - return -EBUSY; + err = -EBUSY; + goto err_tx; } rx_desc = pxa2xx_spi_dma_prepare_one(drv_data, DMA_DEV_TO_MEM); if (!rx_desc) { dev_err(&drv_data->pdev->dev, "failed to get DMA RX descriptor\n"); - return -EBUSY; + err = -EBUSY; + goto err_rx; } /* We are ready when RX completes */ @@ -289,6 +292,12 @@ int pxa2xx_spi_dma_prepare(struct driver_data *drv_data, u32 dma_burst) dmaengine_submit(rx_desc); dmaengine_submit(tx_desc); return 0; + +err_rx: + dmaengine_terminate_async(drv_data->tx_chan); +err_tx: + pxa2xx_spi_unmap_dma_buffers(drv_data); + return err; } void pxa2xx_spi_dma_start(struct driver_data *drv_data) diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index 85e59a406a4c..47bdbd350a24 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -928,6 +928,7 @@ static void pump_transfers(unsigned long data) u32 dma_thresh = drv_data->cur_chip->dma_threshold; u32 dma_burst = drv_data->cur_chip->dma_burst_size; u32 change_mask = pxa2xx_spi_get_ssrc1_change_mask(drv_data); + int err; /* Get current state information */ message = drv_data->cur_msg; @@ -1047,7 +1048,12 @@ static void pump_transfers(unsigned long data) /* Ensure we have the correct interrupt handler */ drv_data->transfer_handler = pxa2xx_spi_dma_transfer; - pxa2xx_spi_dma_prepare(drv_data, dma_burst); + err = pxa2xx_spi_dma_prepare(drv_data, dma_burst); + if (err) { + message->status = err; + giveback(drv_data); + return; + } /* Clear status and start DMA engine */ cr1 = chip->cr1 | dma_thresh | drv_data->dma_cr1; -- cgit v1.2.3 From 68335ec76e45fb3a1b796b26c3ea49ce1231d8fb Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Thu, 24 Mar 2016 15:35:43 +0200 Subject: spi: pxa2xx: Remove rx_/tx_map_len members from struct driver_data spi-pxa2xx-dma.c DMA engine implementation stopped using PIO for unaligned trailing bytes in the commit 111e0a9dc71e ("spi/pxa2xx: Prevent DMA from transferring too many bytes"). This means there is no need to update tx/rx transfer buffer pointers after DMA completion. These buffer pointers will be set to new buffers when handling the next transfer. Because this buffer pointer update was only remaining use for rx_map_len and tx_map_len members in struct driver_data after removing the legacy PXA DMA implementation they can be removed now. Signed-off-by: Jarkko Nikula Acked-by: Robert Jarzmik Signed-off-by: Mark Brown --- drivers/spi/spi-pxa2xx-dma.c | 5 ----- drivers/spi/spi-pxa2xx.h | 2 -- 2 files changed, 7 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-pxa2xx-dma.c b/drivers/spi/spi-pxa2xx-dma.c index b1883d228103..624cb06bd2e1 100644 --- a/drivers/spi/spi-pxa2xx-dma.c +++ b/drivers/spi/spi-pxa2xx-dma.c @@ -33,12 +33,10 @@ static int pxa2xx_spi_map_dma_buffer(struct driver_data *drv_data, dmadev = drv_data->tx_chan->device->dev; sgt = &drv_data->tx_sgt; buf = drv_data->tx; - drv_data->tx_map_len = len; } else { dmadev = drv_data->rx_chan->device->dev; sgt = &drv_data->rx_sgt; buf = drv_data->rx; - drv_data->rx_map_len = len; } nents = DIV_ROUND_UP(len, SZ_2K); @@ -133,9 +131,6 @@ static void pxa2xx_spi_dma_transfer_complete(struct driver_data *drv_data, if (!error) { pxa2xx_spi_unmap_dma_buffers(drv_data); - drv_data->tx += drv_data->tx_map_len; - drv_data->rx += drv_data->rx_map_len; - msg->actual_length += drv_data->len; msg->state = pxa2xx_spi_next_transfer(drv_data); } else { diff --git a/drivers/spi/spi-pxa2xx.h b/drivers/spi/spi-pxa2xx.h index a1ef88948144..85017f9ca67c 100644 --- a/drivers/spi/spi-pxa2xx.h +++ b/drivers/spi/spi-pxa2xx.h @@ -69,8 +69,6 @@ struct driver_data { void *rx; void *rx_end; int dma_mapped; - size_t rx_map_len; - size_t tx_map_len; u8 n_bytes; int (*write)(struct driver_data *drv_data); int (*read)(struct driver_data *drv_data); -- cgit v1.2.3 From 8c3ad488fe0e4478b3b29b9501074c5fb1bfda0d Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Thu, 24 Mar 2016 15:35:44 +0200 Subject: spi: pxa2xx: Use dummy buffers provided by SPI core Dummy buffer is used for half duplex transfers that don't have TX or RX buffer set. Instead of own dummy buffer management here let the SPI core to handle it by setting the SPI_MASTER_MUST_RX and SPI_MASTER_MUST_TX flags. Then core makes sure both transfer buffers are set. Signed-off-by: Jarkko Nikula Signed-off-by: Mark Brown --- drivers/spi/spi-pxa2xx-dma.c | 10 +--------- drivers/spi/spi-pxa2xx.c | 1 + drivers/spi/spi-pxa2xx.h | 1 - 3 files changed, 2 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-pxa2xx-dma.c b/drivers/spi/spi-pxa2xx-dma.c index 624cb06bd2e1..a18a03d0afb7 100644 --- a/drivers/spi/spi-pxa2xx-dma.c +++ b/drivers/spi/spi-pxa2xx-dma.c @@ -53,11 +53,7 @@ static int pxa2xx_spi_map_dma_buffer(struct driver_data *drv_data, for_each_sg(sgt->sgl, sg, sgt->nents, i) { size_t bytes = min_t(size_t, len, SZ_2K); - if (buf) - sg_set_buf(sg, pbuf, bytes); - else - sg_set_buf(sg, drv_data->dummy, bytes); - + sg_set_buf(sg, pbuf, bytes); pbuf += bytes; len -= bytes; } @@ -312,10 +308,6 @@ int pxa2xx_spi_dma_setup(struct driver_data *drv_data) dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); - drv_data->dummy = devm_kzalloc(dev, SZ_2K, GFP_KERNEL); - if (!drv_data->dummy) - return -ENOMEM; - drv_data->tx_chan = dma_request_slave_channel_compat(mask, pdata->dma_filter, pdata->tx_param, dev, "tx"); if (!drv_data->tx_chan) diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index 47bdbd350a24..86c155aea0cf 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -1562,6 +1562,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev) master->unprepare_transfer_hardware = pxa2xx_spi_unprepare_transfer; master->fw_translate_cs = pxa2xx_spi_fw_translate_cs; master->auto_runtime_pm = true; + master->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX; drv_data->ssp_type = ssp->type; diff --git a/drivers/spi/spi-pxa2xx.h b/drivers/spi/spi-pxa2xx.h index 85017f9ca67c..e6b09000ff14 100644 --- a/drivers/spi/spi-pxa2xx.h +++ b/drivers/spi/spi-pxa2xx.h @@ -56,7 +56,6 @@ struct driver_data { struct sg_table tx_sgt; int rx_nents; int tx_nents; - void *dummy; atomic_t dma_running; /* Current message transfer state info */ -- cgit v1.2.3 From 115510053e5e5872f1f19a2220b04aab5542c5c4 Mon Sep 17 00:00:00 2001 From: Xing Zheng Date: Mon, 28 Mar 2016 17:51:37 +0800 Subject: clk: rockchip: add clock controller for the RK3399 Add the clock tree definition for the new RK3399 SoC. Signed-off-by: Xing Zheng Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/Makefile | 1 + drivers/clk/rockchip/clk-rk3399.c | 1540 +++++++++++++++++++++++++++++++++++++ drivers/clk/rockchip/clk.h | 22 +- 3 files changed, 1562 insertions(+), 1 deletion(-) create mode 100644 drivers/clk/rockchip/clk-rk3399.c (limited to 'drivers') diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile index 80b9a379beb4..f47a2fa962d2 100644 --- a/drivers/clk/rockchip/Makefile +++ b/drivers/clk/rockchip/Makefile @@ -15,3 +15,4 @@ obj-y += clk-rk3188.o obj-y += clk-rk3228.o obj-y += clk-rk3288.o obj-y += clk-rk3368.o +obj-y += clk-rk3399.o diff --git a/drivers/clk/rockchip/clk-rk3399.c b/drivers/clk/rockchip/clk-rk3399.c new file mode 100644 index 000000000000..356e13256242 --- /dev/null +++ b/drivers/clk/rockchip/clk-rk3399.c @@ -0,0 +1,1540 @@ +/* + * Copyright (c) 2016 Rockchip Electronics Co. Ltd. + * Author: Xing Zheng + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include "clk.h" + +enum rk3399_plls { + lpll, bpll, dpll, cpll, gpll, npll, vpll, +}; + +enum rk3399_pmu_plls { + ppll, +}; + +static struct rockchip_pll_rate_table rk3399_pll_rates[] = { + /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */ + RK3036_PLL_RATE(2208000000, 1, 92, 1, 1, 1, 0), + RK3036_PLL_RATE(2184000000, 1, 91, 1, 1, 1, 0), + RK3036_PLL_RATE(2160000000, 1, 90, 1, 1, 1, 0), + RK3036_PLL_RATE(2136000000, 1, 89, 1, 1, 1, 0), + RK3036_PLL_RATE(2112000000, 1, 88, 1, 1, 1, 0), + RK3036_PLL_RATE(2088000000, 1, 87, 1, 1, 1, 0), + RK3036_PLL_RATE(2064000000, 1, 86, 1, 1, 1, 0), + RK3036_PLL_RATE(2040000000, 1, 85, 1, 1, 1, 0), + RK3036_PLL_RATE(2016000000, 1, 84, 1, 1, 1, 0), + RK3036_PLL_RATE(1992000000, 1, 83, 1, 1, 1, 0), + RK3036_PLL_RATE(1968000000, 1, 82, 1, 1, 1, 0), + RK3036_PLL_RATE(1944000000, 1, 81, 1, 1, 1, 0), + RK3036_PLL_RATE(1920000000, 1, 80, 1, 1, 1, 0), + RK3036_PLL_RATE(1896000000, 1, 79, 1, 1, 1, 0), + RK3036_PLL_RATE(1872000000, 1, 78, 1, 1, 1, 0), + RK3036_PLL_RATE(1848000000, 1, 77, 1, 1, 1, 0), + RK3036_PLL_RATE(1824000000, 1, 76, 1, 1, 1, 0), + RK3036_PLL_RATE(1800000000, 1, 75, 1, 1, 1, 0), + RK3036_PLL_RATE(1776000000, 1, 74, 1, 1, 1, 0), + RK3036_PLL_RATE(1752000000, 1, 73, 1, 1, 1, 0), + RK3036_PLL_RATE(1728000000, 1, 72, 1, 1, 1, 0), + RK3036_PLL_RATE(1704000000, 1, 71, 1, 1, 1, 0), + RK3036_PLL_RATE(1680000000, 1, 70, 1, 1, 1, 0), + RK3036_PLL_RATE(1656000000, 1, 69, 1, 1, 1, 0), + RK3036_PLL_RATE(1632000000, 1, 68, 1, 1, 1, 0), + RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0), + RK3036_PLL_RATE(1584000000, 1, 66, 1, 1, 1, 0), + RK3036_PLL_RATE(1560000000, 1, 65, 1, 1, 1, 0), + RK3036_PLL_RATE(1536000000, 1, 64, 1, 1, 1, 0), + RK3036_PLL_RATE(1512000000, 1, 63, 1, 1, 1, 0), + RK3036_PLL_RATE(1488000000, 1, 62, 1, 1, 1, 0), + RK3036_PLL_RATE(1464000000, 1, 61, 1, 1, 1, 0), + RK3036_PLL_RATE(1440000000, 1, 60, 1, 1, 1, 0), + RK3036_PLL_RATE(1416000000, 1, 59, 1, 1, 1, 0), + RK3036_PLL_RATE(1392000000, 1, 58, 1, 1, 1, 0), + RK3036_PLL_RATE(1368000000, 1, 57, 1, 1, 1, 0), + RK3036_PLL_RATE(1344000000, 1, 56, 1, 1, 1, 0), + RK3036_PLL_RATE(1320000000, 1, 55, 1, 1, 1, 0), + RK3036_PLL_RATE(1296000000, 1, 54, 1, 1, 1, 0), + RK3036_PLL_RATE(1272000000, 1, 53, 1, 1, 1, 0), + RK3036_PLL_RATE(1248000000, 1, 52, 1, 1, 1, 0), + RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0), + RK3036_PLL_RATE(1188000000, 2, 99, 1, 1, 1, 0), + RK3036_PLL_RATE(1104000000, 1, 46, 1, 1, 1, 0), + RK3036_PLL_RATE(1100000000, 12, 550, 1, 1, 1, 0), + RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0), + RK3036_PLL_RATE(1000000000, 6, 500, 2, 1, 1, 0), + RK3036_PLL_RATE( 984000000, 1, 82, 2, 1, 1, 0), + RK3036_PLL_RATE( 960000000, 1, 80, 2, 1, 1, 0), + RK3036_PLL_RATE( 936000000, 1, 78, 2, 1, 1, 0), + RK3036_PLL_RATE( 912000000, 1, 76, 2, 1, 1, 0), + RK3036_PLL_RATE( 900000000, 4, 300, 2, 1, 1, 0), + RK3036_PLL_RATE( 888000000, 1, 74, 2, 1, 1, 0), + RK3036_PLL_RATE( 864000000, 1, 72, 2, 1, 1, 0), + RK3036_PLL_RATE( 840000000, 1, 70, 2, 1, 1, 0), + RK3036_PLL_RATE( 816000000, 1, 68, 2, 1, 1, 0), + RK3036_PLL_RATE( 800000000, 6, 400, 2, 1, 1, 0), + RK3036_PLL_RATE( 700000000, 6, 350, 2, 1, 1, 0), + RK3036_PLL_RATE( 696000000, 1, 58, 2, 1, 1, 0), + RK3036_PLL_RATE( 676000000, 3, 169, 2, 1, 1, 0), + RK3036_PLL_RATE( 600000000, 1, 75, 3, 1, 1, 0), + RK3036_PLL_RATE( 594000000, 2, 99, 2, 1, 1, 0), + RK3036_PLL_RATE( 504000000, 1, 63, 3, 1, 1, 0), + RK3036_PLL_RATE( 500000000, 6, 250, 2, 1, 1, 0), + RK3036_PLL_RATE( 408000000, 1, 68, 2, 2, 1, 0), + RK3036_PLL_RATE( 312000000, 1, 52, 2, 2, 1, 0), + RK3036_PLL_RATE( 216000000, 1, 72, 4, 2, 1, 0), + RK3036_PLL_RATE( 96000000, 1, 64, 4, 4, 1, 0), + { /* sentinel */ }, +}; + +/* CRU parents */ +PNAME(mux_pll_p) = { "xin24m", "xin32k" }; + +PNAME(mux_armclkl_p) = { "clk_core_l_lpll_src", + "clk_core_l_bpll_src", + "clk_core_l_dpll_src", + "clk_core_l_gpll_src" }; +PNAME(mux_armclkb_p) = { "clk_core_b_lpll_src", + "clk_core_b_bpll_src", + "clk_core_b_dpll_src", + "clk_core_b_gpll_src" }; +PNAME(mux_aclk_cci_p) = { "cpll_aclk_cci_src", + "gpll_aclk_cci_src", + "npll_aclk_cci_src", + "vpll_aclk_cci_src" }; +PNAME(mux_cci_trace_p) = { "cpll_cci_trace", "gpll_cci_trace" }; +PNAME(mux_cs_p) = { "cpll_cs", "gpll_cs", "npll_cs"}; +PNAME(mux_aclk_perihp_p) = { "cpll_aclk_perihp_src", "gpll_aclk_perihp_src" }; + +PNAME(mux_pll_src_cpll_gpll_p) = { "cpll", "gpll" }; +PNAME(mux_pll_src_cpll_gpll_npll_p) = { "cpll", "gpll", "npll" }; +PNAME(mux_pll_src_cpll_gpll_ppll_p) = { "cpll", "gpll", "ppll" }; +PNAME(mux_pll_src_cpll_gpll_upll_p) = { "cpll", "gpll", "upll" }; +PNAME(mux_pll_src_npll_cpll_gpll_p) = { "npll", "cpll", "gpll" }; +PNAME(mux_pll_src_cpll_gpll_npll_ppll_p) = { "cpll", "gpll", "npll", "ppll" }; +PNAME(mux_pll_src_cpll_gpll_npll_24m_p) = { "cpll", "gpll", "npll", "xin24m" }; +PNAME(mux_pll_src_cpll_gpll_npll_usbphy480m_p) = { "cpll", "gpll", "npll", "clk_usbphy_480m" }; +PNAME(mux_pll_src_ppll_cpll_gpll_npll_p) = { "ppll", "cpll", "gpll", "npll", "upll" }; +PNAME(mux_pll_src_cpll_gpll_npll_upll_24m_p) = { "cpll", "gpll", "npll", "upll", "xin24m" }; +PNAME(mux_pll_src_cpll_gpll_npll_ppll_upll_24m_p) = { "cpll", "gpll", "npll", "ppll", "upll", "xin24m" }; + +PNAME(mux_pll_src_vpll_cpll_gpll_p) = { "vpll", "cpll", "gpll" }; +PNAME(mux_pll_src_vpll_cpll_gpll_npll_p) = { "vpll", "cpll", "gpll", "npll" }; +PNAME(mux_pll_src_vpll_cpll_gpll_24m_p) = { "vpll", "cpll", "gpll", "xin24m" }; + +PNAME(mux_dclk_vop0_p) = { "dclk_vop0_div", "dclk_vop0_frac" }; +PNAME(mux_dclk_vop1_p) = { "dclk_vop1_div", "dclk_vop1_frac" }; + +PNAME(mux_clk_cif_p) = { "clk_cifout_div", "xin24m" }; + +PNAME(mux_pll_src_24m_usbphy480m_p) = { "xin24m", "clk_usbphy_480m" }; +PNAME(mux_pll_src_24m_pciephy_p) = { "xin24m", "clk_pciephy_ref100m" }; +PNAME(mux_pll_src_24m_32k_cpll_gpll_p) = { "xin24m", "xin32k", "cpll", "gpll" }; +PNAME(mux_pciecore_cru_phy_p) = { "clk_pcie_core_cru", "clk_pcie_core_phy" }; + +PNAME(mux_aclk_emmc_p) = { "cpll_aclk_emmc_src", "gpll_aclk_emmc_src" }; + +PNAME(mux_aclk_perilp0_p) = { "cpll_aclk_perilp0_src", "gpll_aclk_perilp0_src" }; + +PNAME(mux_fclk_cm0s_p) = { "cpll_fclk_cm0s_src", "gpll_fclk_cm0s_src" }; + +PNAME(mux_hclk_perilp1_p) = { "cpll_hclk_perilp1_src", "gpll_hclk_perilp1_src" }; + +PNAME(mux_clk_testout1_p) = { "clk_testout1_pll_src", "xin24m" }; +PNAME(mux_clk_testout2_p) = { "clk_testout2_pll_src", "xin24m" }; + +PNAME(mux_usbphy_480m_p) = { "clk_usbphy0_480m_src", "clk_usbphy1_480m_src" }; +PNAME(mux_aclk_gmac_p) = { "cpll_aclk_gmac_src", "gpll_aclk_gmac_src" }; +PNAME(mux_rmii_p) = { "clk_gmac", "clkin_gmac" }; +PNAME(mux_spdif_p) = { "clk_spdif_div", "clk_spdif_frac", + "clkin_i2s", "xin12m" }; +PNAME(mux_i2s0_p) = { "clk_i2s0_div", "clk_i2s0_frac", + "clkin_i2s", "xin12m" }; +PNAME(mux_i2s1_p) = { "clk_i2s1_div", "clk_i2s1_frac", + "clkin_i2s", "xin12m" }; +PNAME(mux_i2s2_p) = { "clk_i2s2_div", "clk_i2s2_frac", + "clkin_i2s", "xin12m" }; +PNAME(mux_i2sch_p) = { "clk_i2s0", "clk_i2s1", "clk_i2s2" }; +PNAME(mux_i2sout_p) = { "clk_i2sout_src", "xin12m" }; + +PNAME(mux_uart0_p) = { "clk_uart0_div", "clk_uart0_frac", "xin24m" }; +PNAME(mux_uart1_p) = { "clk_uart1_div", "clk_uart1_frac", "xin24m" }; +PNAME(mux_uart2_p) = { "clk_uart2_div", "clk_uart2_frac", "xin24m" }; +PNAME(mux_uart3_p) = { "clk_uart3_div", "clk_uart3_frac", "xin24m" }; + +/* PMU CRU parents */ +PNAME(mux_ppll_24m_p) = { "ppll", "xin24m" }; +PNAME(mux_24m_ppll_p) = { "xin24m", "ppll" }; +PNAME(mux_fclk_cm0s_pmu_ppll_p) = { "fclk_cm0s_pmu_ppll_src", "xin24m" }; +PNAME(mux_wifi_pmu_p) = { "clk_wifi_div", "clk_wifi_frac" }; +PNAME(mux_uart4_pmu_p) = { "clk_uart4_div", "clk_uart4_frac", "xin24m" }; +PNAME(mux_clk_testout2_2io_p) = { "clk_testout2", "clk_32k_suspend_pmu" }; + +static struct rockchip_pll_clock rk3399_pll_clks[] __initdata = { + [lpll] = PLL(pll_rk3399, PLL_APLLL, "lpll", mux_pll_p, 0, RK3399_PLL_CON(0), + RK3399_PLL_CON(3), 8, 31, 0, rk3399_pll_rates), + [bpll] = PLL(pll_rk3399, PLL_APLLB, "bpll", mux_pll_p, 0, RK3399_PLL_CON(8), + RK3399_PLL_CON(11), 8, 31, 0, rk3399_pll_rates), + [dpll] = PLL(pll_rk3399, PLL_DPLL, "dpll", mux_pll_p, 0, RK3399_PLL_CON(16), + RK3399_PLL_CON(19), 8, 31, 0, NULL), + [cpll] = PLL(pll_rk3399, PLL_CPLL, "cpll", mux_pll_p, 0, RK3399_PLL_CON(24), + RK3399_PLL_CON(27), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk3399_pll_rates), + [gpll] = PLL(pll_rk3399, PLL_GPLL, "gpll", mux_pll_p, 0, RK3399_PLL_CON(32), + RK3399_PLL_CON(35), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk3399_pll_rates), + [npll] = PLL(pll_rk3399, PLL_NPLL, "npll", mux_pll_p, 0, RK3399_PLL_CON(40), + RK3399_PLL_CON(43), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk3399_pll_rates), + [vpll] = PLL(pll_rk3399, PLL_VPLL, "vpll", mux_pll_p, 0, RK3399_PLL_CON(48), + RK3399_PLL_CON(51), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk3399_pll_rates), +}; + +static struct rockchip_pll_clock rk3399_pmu_pll_clks[] __initdata = { + [ppll] = PLL(pll_rk3399, PLL_PPLL, "ppll", mux_pll_p, 0, RK3399_PMU_PLL_CON(0), + RK3399_PMU_PLL_CON(3), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk3399_pll_rates), +}; + +#define MFLAGS CLK_MUX_HIWORD_MASK +#define DFLAGS CLK_DIVIDER_HIWORD_MASK +#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE) +#define IFLAGS ROCKCHIP_INVERTER_HIWORD_MASK + +static struct rockchip_clk_branch rk3399_spdif_fracmux __initdata = + MUX(0, "clk_spdif_mux", mux_spdif_p, CLK_SET_RATE_PARENT, + RK3399_CLKSEL_CON(32), 13, 2, MFLAGS); + +static struct rockchip_clk_branch rk3399_i2s0_fracmux __initdata = + MUX(0, "clk_i2s0_mux", mux_i2s0_p, CLK_SET_RATE_PARENT, + RK3399_CLKSEL_CON(28), 8, 2, MFLAGS); + +static struct rockchip_clk_branch rk3399_i2s1_fracmux __initdata = + MUX(0, "clk_i2s1_mux", mux_i2s1_p, CLK_SET_RATE_PARENT, + RK3399_CLKSEL_CON(29), 8, 2, MFLAGS); + +static struct rockchip_clk_branch rk3399_i2s2_fracmux __initdata = + MUX(0, "clk_i2s2_mux", mux_i2s2_p, CLK_SET_RATE_PARENT, + RK3399_CLKSEL_CON(30), 8, 2, MFLAGS); + +static struct rockchip_clk_branch rk3399_uart0_fracmux __initdata = + MUX(SCLK_UART0, "clk_uart0", mux_uart0_p, CLK_SET_RATE_PARENT, + RK3399_CLKSEL_CON(33), 8, 2, MFLAGS); + +static struct rockchip_clk_branch rk3399_uart1_fracmux __initdata = + MUX(SCLK_UART1, "clk_uart1", mux_uart1_p, CLK_SET_RATE_PARENT, + RK3399_CLKSEL_CON(34), 8, 2, MFLAGS); + +static struct rockchip_clk_branch rk3399_uart2_fracmux __initdata = + MUX(SCLK_UART2, "clk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT, + RK3399_CLKSEL_CON(35), 8, 2, MFLAGS); + +static struct rockchip_clk_branch rk3399_uart3_fracmux __initdata = + MUX(SCLK_UART3, "clk_uart3", mux_uart3_p, CLK_SET_RATE_PARENT, + RK3399_CLKSEL_CON(36), 8, 2, MFLAGS); + +static struct rockchip_clk_branch rk3399_uart4_pmu_fracmux __initdata = + MUX(SCLK_UART4_PMU, "clk_uart4_pmu", mux_uart4_pmu_p, CLK_SET_RATE_PARENT, + RK3399_PMU_CLKSEL_CON(5), 8, 2, MFLAGS); + +static struct rockchip_clk_branch rk3399_dclk_vop0_fracmux __initdata = + MUX(DCLK_VOP0, "dclk_vop0", mux_dclk_vop0_p, CLK_SET_RATE_PARENT, + RK3399_CLKSEL_CON(49), 11, 1, MFLAGS); + +static struct rockchip_clk_branch rk3399_dclk_vop1_fracmux __initdata = + MUX(DCLK_VOP1, "dclk_vop1", mux_dclk_vop1_p, CLK_SET_RATE_PARENT, + RK3399_CLKSEL_CON(50), 11, 1, MFLAGS); + +static struct rockchip_clk_branch rk3399_pmuclk_wifi_fracmux __initdata = + MUX(SCLK_WIFI_PMU, "clk_wifi_pmu", mux_wifi_pmu_p, CLK_SET_RATE_PARENT, + RK3399_PMU_CLKSEL_CON(1), 14, 1, MFLAGS); + +static const struct rockchip_cpuclk_reg_data rk3399_cpuclkl_data = { + .core_reg = RK3399_CLKSEL_CON(0), + .div_core_shift = 0, + .div_core_mask = 0x1f, + .mux_core_alt = 3, + .mux_core_main = 0, + .mux_core_shift = 6, + .mux_core_mask = 0x3, +}; + +static const struct rockchip_cpuclk_reg_data rk3399_cpuclkb_data = { + .core_reg = RK3399_CLKSEL_CON(2), + .div_core_shift = 0, + .div_core_mask = 0x1f, + .mux_core_alt = 3, + .mux_core_main = 1, + .mux_core_shift = 6, + .mux_core_mask = 0x3, +}; + +#define RK3399_DIV_ACLKM_MASK 0x1f +#define RK3399_DIV_ACLKM_SHIFT 8 +#define RK3399_DIV_ATCLK_MASK 0x1f +#define RK3399_DIV_ATCLK_SHIFT 0 +#define RK3399_DIV_PCLK_DBG_MASK 0x1f +#define RK3399_DIV_PCLK_DBG_SHIFT 8 + +#define RK3399_CLKSEL0(_offs, _aclkm) \ + { \ + .reg = RK3399_CLKSEL_CON(0 + _offs), \ + .val = HIWORD_UPDATE(_aclkm, RK3399_DIV_ACLKM_MASK, \ + RK3399_DIV_ACLKM_SHIFT), \ + } +#define RK3399_CLKSEL1(_offs, _atclk, _pdbg) \ + { \ + .reg = RK3399_CLKSEL_CON(1 + _offs), \ + .val = HIWORD_UPDATE(_atclk, RK3399_DIV_ATCLK_MASK, \ + RK3399_DIV_ATCLK_SHIFT) | \ + HIWORD_UPDATE(_pdbg, RK3399_DIV_PCLK_DBG_MASK, \ + RK3399_DIV_PCLK_DBG_SHIFT), \ + } + +/* cluster_l: aclkm in clksel0, rest in clksel1 */ +#define RK3399_CPUCLKL_RATE(_prate, _aclkm, _atclk, _pdbg) \ + { \ + .prate = _prate##U, \ + .divs = { \ + RK3399_CLKSEL0(0, _aclkm), \ + RK3399_CLKSEL1(0, _atclk, _pdbg), \ + }, \ + } + +/* cluster_b: aclkm in clksel2, rest in clksel3 */ +#define RK3399_CPUCLKB_RATE(_prate, _aclkm, _atclk, _pdbg) \ + { \ + .prate = _prate##U, \ + .divs = { \ + RK3399_CLKSEL0(2, _aclkm), \ + RK3399_CLKSEL1(2, _atclk, _pdbg), \ + }, \ + } + +static struct rockchip_cpuclk_rate_table rk3399_cpuclkl_rates[] __initdata = { + RK3399_CPUCLKL_RATE(1800000000, 1, 8, 8), + RK3399_CPUCLKL_RATE(1704000000, 1, 8, 8), + RK3399_CPUCLKL_RATE(1608000000, 1, 7, 7), + RK3399_CPUCLKL_RATE(1512000000, 1, 7, 7), + RK3399_CPUCLKL_RATE(1488000000, 1, 6, 6), + RK3399_CPUCLKL_RATE(1416000000, 1, 6, 6), + RK3399_CPUCLKL_RATE(1200000000, 1, 5, 5), + RK3399_CPUCLKL_RATE(1008000000, 1, 5, 5), + RK3399_CPUCLKL_RATE( 816000000, 1, 4, 4), + RK3399_CPUCLKL_RATE( 696000000, 1, 3, 3), + RK3399_CPUCLKL_RATE( 600000000, 1, 3, 3), + RK3399_CPUCLKL_RATE( 408000000, 1, 2, 2), + RK3399_CPUCLKL_RATE( 312000000, 1, 1, 1), +}; + +static struct rockchip_cpuclk_rate_table rk3399_cpuclkb_rates[] __initdata = { + RK3399_CPUCLKB_RATE(2208000000, 1, 11, 11), + RK3399_CPUCLKB_RATE(2184000000, 1, 11, 11), + RK3399_CPUCLKB_RATE(2088000000, 1, 10, 10), + RK3399_CPUCLKB_RATE(2040000000, 1, 10, 10), + RK3399_CPUCLKB_RATE(1992000000, 1, 9, 9), + RK3399_CPUCLKB_RATE(1896000000, 1, 9, 9), + RK3399_CPUCLKB_RATE(1800000000, 1, 8, 8), + RK3399_CPUCLKB_RATE(1704000000, 1, 8, 8), + RK3399_CPUCLKB_RATE(1608000000, 1, 7, 7), + RK3399_CPUCLKB_RATE(1512000000, 1, 7, 7), + RK3399_CPUCLKB_RATE(1488000000, 1, 6, 6), + RK3399_CPUCLKB_RATE(1416000000, 1, 6, 6), + RK3399_CPUCLKB_RATE(1200000000, 1, 5, 5), + RK3399_CPUCLKB_RATE(1008000000, 1, 5, 5), + RK3399_CPUCLKB_RATE( 816000000, 1, 4, 4), + RK3399_CPUCLKB_RATE( 696000000, 1, 3, 3), + RK3399_CPUCLKB_RATE( 600000000, 1, 3, 3), + RK3399_CPUCLKB_RATE( 408000000, 1, 2, 2), + RK3399_CPUCLKB_RATE( 312000000, 1, 1, 1), +}; + +static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { + /* + * CRU Clock-Architecture + */ + + /* usbphy */ + GATE(SCLK_USB2PHY0_REF, "clk_usb2phy0_ref", "xin24m", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(6), 5, GFLAGS), + GATE(SCLK_USB2PHY1_REF, "clk_usb2phy1_ref", "xin24m", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(6), 6, GFLAGS), + + GATE(0, "clk_usbphy0_480m_src", "clk_usbphy0_480m", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(13), 12, GFLAGS), + GATE(0, "clk_usbphy1_480m_src", "clk_usbphy1_480m", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(13), 12, GFLAGS), + MUX(0, "clk_usbphy_480m", mux_usbphy_480m_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(14), 6, 1, MFLAGS), + + MUX(0, "upll", mux_pll_src_24m_usbphy480m_p, 0, + RK3399_CLKSEL_CON(14), 15, 1, MFLAGS), + + COMPOSITE_NODIV(SCLK_HSICPHY, "clk_hsicphy", mux_pll_src_cpll_gpll_npll_usbphy480m_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(19), 0, 2, MFLAGS, + RK3399_CLKGATE_CON(6), 4, GFLAGS), + + COMPOSITE(ACLK_USB3, "aclk_usb3", mux_pll_src_cpll_gpll_npll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(39), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3399_CLKGATE_CON(12), 0, GFLAGS), + GATE(ACLK_USB3_NOC, "aclk_usb3_noc", "aclk_usb3", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(30), 0, GFLAGS), + GATE(ACLK_USB3OTG0, "aclk_usb3otg0", "aclk_usb3", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(30), 1, GFLAGS), + GATE(ACLK_USB3OTG1, "aclk_usb3otg1", "aclk_usb3", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(30), 2, GFLAGS), + GATE(ACLK_USB3_RKSOC_AXI_PERF, "aclk_usb3_rksoc_axi_perf", "aclk_usb3", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(30), 3, GFLAGS), + GATE(ACLK_USB3_GRF, "aclk_usb3_grf", "aclk_usb3", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(30), 4, GFLAGS), + + GATE(SCLK_USB3OTG0_REF, "clk_usb3otg0_ref", "xin24m", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(12), 1, GFLAGS), + GATE(SCLK_USB3OTG1_REF, "clk_usb3otg1_ref", "xin24m", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(12), 2, GFLAGS), + + COMPOSITE(SCLK_USB3OTG0_SUSPEND, "clk_usb3otg0_suspend", mux_pll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(40), 15, 1, MFLAGS, 0, 10, DFLAGS, + RK3399_CLKGATE_CON(12), 3, GFLAGS), + + COMPOSITE(SCLK_USB3OTG1_SUSPEND, "clk_usb3otg1_suspend", mux_pll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(41), 15, 1, MFLAGS, 0, 10, DFLAGS, + RK3399_CLKGATE_CON(12), 4, GFLAGS), + + COMPOSITE(SCLK_UPHY0_TCPDPHY_REF, "clk_uphy0_tcpdphy_ref", mux_pll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(64), 15, 1, MFLAGS, 8, 5, DFLAGS, + RK3399_CLKGATE_CON(13), 4, GFLAGS), + + COMPOSITE(SCLK_UPHY0_TCPDCORE, "clk_uphy0_tcpdcore", mux_pll_src_24m_32k_cpll_gpll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(64), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3399_CLKGATE_CON(13), 5, GFLAGS), + + COMPOSITE(SCLK_UPHY1_TCPDPHY_REF, "clk_uphy1_tcpdphy_ref", mux_pll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(65), 15, 1, MFLAGS, 8, 5, DFLAGS, + RK3399_CLKGATE_CON(13), 6, GFLAGS), + + COMPOSITE(SCLK_UPHY1_TCPDCORE, "clk_uphy1_tcpdcore", mux_pll_src_24m_32k_cpll_gpll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(65), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3399_CLKGATE_CON(13), 7, GFLAGS), + + /* little core */ + GATE(0, "clk_core_l_lpll_src", "lpll", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(0), 0, GFLAGS), + GATE(0, "clk_core_l_bpll_src", "bpll", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(0), 1, GFLAGS), + GATE(0, "clk_core_l_dpll_src", "dpll", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(0), 2, GFLAGS), + GATE(0, "clk_core_l_gpll_src", "gpll", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(0), 3, GFLAGS), + + COMPOSITE_NOMUX(0, "aclkm_core_l", "armclkl", CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(0), 8, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3399_CLKGATE_CON(0), 4, GFLAGS), + COMPOSITE_NOMUX(0, "atclk_core_l", "armclkl", CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(1), 0, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3399_CLKGATE_CON(0), 5, GFLAGS), + COMPOSITE_NOMUX(0, "pclk_dbg_core_l", "armclkl", CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(1), 8, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3399_CLKGATE_CON(0), 6, GFLAGS), + + GATE(ACLK_CORE_ADB400_CORE_L_2_CCI500, "aclk_core_adb400_core_l_2_cci500", "aclkm_core_l", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(14), 12, GFLAGS), + GATE(ACLK_PERF_CORE_L, "aclk_perf_core_l", "aclkm_core_l", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(14), 13, GFLAGS), + + GATE(0, "clk_dbg_pd_core_l", "armclkl", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(14), 9, GFLAGS), + GATE(ACLK_GIC_ADB400_GIC_2_CORE_L, "aclk_core_adb400_gic_2_core_l", "armclkl", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(14), 10, GFLAGS), + GATE(ACLK_GIC_ADB400_CORE_L_2_GIC, "aclk_core_adb400_core_l_2_gic", "armclkl", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(14), 11, GFLAGS), + GATE(SCLK_PVTM_CORE_L, "clk_pvtm_core_l", "xin24m", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(0), 7, GFLAGS), + + /* big core */ + GATE(0, "clk_core_b_lpll_src", "lpll", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(1), 0, GFLAGS), + GATE(0, "clk_core_b_bpll_src", "bpll", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(1), 1, GFLAGS), + GATE(0, "clk_core_b_dpll_src", "dpll", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(1), 2, GFLAGS), + GATE(0, "clk_core_b_gpll_src", "gpll", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(1), 3, GFLAGS), + + COMPOSITE_NOMUX(0, "aclkm_core_b", "armclkb", CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(2), 8, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3399_CLKGATE_CON(1), 4, GFLAGS), + COMPOSITE_NOMUX(0, "atclk_core_b", "armclkb", CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(3), 0, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3399_CLKGATE_CON(1), 5, GFLAGS), + COMPOSITE_NOMUX(0, "pclk_dbg_core_b", "armclkb", CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(3), 8, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3399_CLKGATE_CON(1), 6, GFLAGS), + + GATE(ACLK_CORE_ADB400_CORE_B_2_CCI500, "aclk_core_adb400_core_b_2_cci500", "aclkm_core_b", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(14), 5, GFLAGS), + GATE(ACLK_PERF_CORE_B, "aclk_perf_core_b", "aclkm_core_b", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(14), 6, GFLAGS), + + GATE(0, "clk_dbg_pd_core_b", "armclkb", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(14), 1, GFLAGS), + GATE(ACLK_GIC_ADB400_GIC_2_CORE_B, "aclk_core_adb400_gic_2_core_b", "armclkb", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(14), 3, GFLAGS), + GATE(ACLK_GIC_ADB400_CORE_B_2_GIC, "aclk_core_adb400_core_b_2_gic", "armclkb", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(14), 4, GFLAGS), + + DIV(0, "pclken_dbg_core_b", "pclk_dbg_core_b", CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(3), 13, 2, DFLAGS | CLK_DIVIDER_READ_ONLY), + + GATE(0, "pclk_dbg_cxcs_pd_core_b", "pclk_dbg_core_b", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(14), 2, GFLAGS), + + GATE(SCLK_PVTM_CORE_B, "clk_pvtm_core_b", "xin24m", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(1), 7, GFLAGS), + + /* gmac */ + GATE(0, "cpll_aclk_gmac_src", "cpll", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(6), 9, GFLAGS), + GATE(0, "gpll_aclk_gmac_src", "gpll", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(6), 8, GFLAGS), + COMPOSITE(0, "aclk_gmac_pre", mux_aclk_gmac_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(20), 7, 1, MFLAGS, 0, 5, DFLAGS, + RK3399_CLKGATE_CON(6), 10, GFLAGS), + + GATE(ACLK_GMAC, "aclk_gmac", "aclk_gmac_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(32), 0, GFLAGS), + GATE(ACLK_GMAC_NOC, "aclk_gmac_noc", "aclk_gmac_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(32), 1, GFLAGS), + GATE(ACLK_PERF_GMAC, "aclk_perf_gmac", "aclk_gmac_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(32), 4, GFLAGS), + + COMPOSITE_NOMUX(0, "pclk_gmac_pre", "aclk_gmac_pre", 0, + RK3399_CLKSEL_CON(19), 8, 3, DFLAGS, + RK3399_CLKGATE_CON(6), 11, GFLAGS), + GATE(PCLK_GMAC, "pclk_gmac", "pclk_gmac_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(32), 2, GFLAGS), + GATE(PCLK_GMAC_NOC, "pclk_gmac_noc", "pclk_gmac_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(32), 3, GFLAGS), + + COMPOSITE(SCLK_MAC, "clk_gmac", mux_pll_src_cpll_gpll_npll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(20), 14, 2, MFLAGS, 8, 5, DFLAGS, + RK3399_CLKGATE_CON(5), 5, GFLAGS), + + MUX(0, "clk_rmii_src", mux_rmii_p, CLK_SET_RATE_PARENT, + RK3399_CLKSEL_CON(19), 4, 1, MFLAGS), + GATE(SCLK_MACREF_OUT, "clk_mac_refout", "clk_rmii_src", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(5), 6, GFLAGS), + GATE(SCLK_MACREF, "clk_mac_ref", "clk_rmii_src", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(5), 7, GFLAGS), + GATE(SCLK_MAC_RX, "clk_rmii_rx", "clk_rmii_src", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(5), 8, GFLAGS), + GATE(SCLK_MAC_TX, "clk_rmii_tx", "clk_rmii_src", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(5), 9, GFLAGS), + + /* spdif */ + COMPOSITE(0, "clk_spdif_div", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(32), 7, 1, MFLAGS, 0, 7, DFLAGS, + RK3399_CLKGATE_CON(8), 13, GFLAGS), + COMPOSITE_FRACMUX(0, "clk_spdif_frac", "clk_spdif_div", CLK_SET_RATE_PARENT, + RK3399_CLKSEL_CON(99), 0, + RK3399_CLKGATE_CON(8), 14, GFLAGS, + &rk3399_spdif_fracmux), + GATE(SCLK_SPDIF_8CH, "clk_spdif", "clk_spdif_mux", CLK_SET_RATE_PARENT, + RK3399_CLKGATE_CON(8), 15, GFLAGS), + + COMPOSITE(SCLK_SPDIF_REC_DPTX, "clk_spdif_rec_dptx", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(32), 15, 1, MFLAGS, 0, 5, DFLAGS, + RK3399_CLKGATE_CON(10), 6, GFLAGS), + /* i2s */ + COMPOSITE(0, "clk_i2s0_div", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(28), 7, 1, MFLAGS, 0, 7, DFLAGS, + RK3399_CLKGATE_CON(8), 3, GFLAGS), + COMPOSITE_FRACMUX(0, "clk_i2s0_frac", "clk_i2s0_div", CLK_SET_RATE_PARENT, + RK3399_CLKSEL_CON(96), 0, + RK3399_CLKGATE_CON(8), 4, GFLAGS, + &rk3399_i2s0_fracmux), + GATE(SCLK_I2S0_8CH, "clk_i2s0", "clk_i2s0_mux", CLK_SET_RATE_PARENT, + RK3399_CLKGATE_CON(8), 5, GFLAGS), + + COMPOSITE(0, "clk_i2s1_div", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(29), 7, 1, MFLAGS, 0, 7, DFLAGS, + RK3399_CLKGATE_CON(8), 6, GFLAGS), + COMPOSITE_FRACMUX(0, "clk_i2s1_frac", "clk_i2s1_div", CLK_SET_RATE_PARENT, + RK3399_CLKSEL_CON(97), 0, + RK3399_CLKGATE_CON(8), 7, GFLAGS, + &rk3399_i2s1_fracmux), + GATE(SCLK_I2S1_8CH, "clk_i2s1", "clk_i2s1_mux", CLK_SET_RATE_PARENT, + RK3399_CLKGATE_CON(8), 8, GFLAGS), + + COMPOSITE(0, "clk_i2s2_div", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(30), 7, 1, MFLAGS, 0, 7, DFLAGS, + RK3399_CLKGATE_CON(8), 9, GFLAGS), + COMPOSITE_FRACMUX(0, "clk_i2s2_frac", "clk_i2s2_div", CLK_SET_RATE_PARENT, + RK3399_CLKSEL_CON(98), 0, + RK3399_CLKGATE_CON(8), 10, GFLAGS, + &rk3399_i2s2_fracmux), + GATE(SCLK_I2S2_8CH, "clk_i2s2", "clk_i2s2_mux", CLK_SET_RATE_PARENT, + RK3399_CLKGATE_CON(8), 11, GFLAGS), + + MUX(0, "clk_i2sout_src", mux_i2sch_p, CLK_SET_RATE_PARENT, + RK3399_CLKSEL_CON(31), 0, 2, MFLAGS), + COMPOSITE_NODIV(SCLK_I2S_8CH_OUT, "clk_i2sout", mux_i2sout_p, CLK_SET_RATE_PARENT, + RK3399_CLKSEL_CON(30), 8, 2, MFLAGS, + RK3399_CLKGATE_CON(8), 12, GFLAGS), + + /* uart */ + MUX(0, "clk_uart0_src", mux_pll_src_cpll_gpll_upll_p, 0, + RK3399_CLKSEL_CON(33), 12, 2, MFLAGS), + COMPOSITE_NOMUX(0, "clk_uart0_div", "clk_uart0_src", 0, + RK3399_CLKSEL_CON(33), 0, 7, DFLAGS, + RK3399_CLKGATE_CON(9), 0, GFLAGS), + COMPOSITE_FRACMUX(0, "clk_uart0_frac", "clk_uart0_div", CLK_SET_RATE_PARENT, + RK3399_CLKSEL_CON(100), 0, + RK3399_CLKGATE_CON(9), 1, GFLAGS, + &rk3399_uart0_fracmux), + + MUX(0, "clk_uart_src", mux_pll_src_cpll_gpll_p, 0, + RK3399_CLKSEL_CON(33), 15, 1, MFLAGS), + COMPOSITE_NOMUX(0, "clk_uart1_div", "clk_uart_src", 0, + RK3399_CLKSEL_CON(34), 0, 7, DFLAGS, + RK3399_CLKGATE_CON(9), 2, GFLAGS), + COMPOSITE_FRACMUX(0, "clk_uart1_frac", "clk_uart1_div", CLK_SET_RATE_PARENT, + RK3399_CLKSEL_CON(101), 0, + RK3399_CLKGATE_CON(9), 3, GFLAGS, + &rk3399_uart1_fracmux), + + COMPOSITE_NOMUX(0, "clk_uart2_div", "clk_uart_src", 0, + RK3399_CLKSEL_CON(35), 0, 7, DFLAGS, + RK3399_CLKGATE_CON(9), 4, GFLAGS), + COMPOSITE_FRACMUX(0, "clk_uart2_frac", "clk_uart2_div", CLK_SET_RATE_PARENT, + RK3399_CLKSEL_CON(102), 0, + RK3399_CLKGATE_CON(9), 5, GFLAGS, + &rk3399_uart2_fracmux), + + COMPOSITE_NOMUX(0, "clk_uart3_div", "clk_uart_src", 0, + RK3399_CLKSEL_CON(36), 0, 7, DFLAGS, + RK3399_CLKGATE_CON(9), 6, GFLAGS), + COMPOSITE_FRACMUX(0, "clk_uart3_frac", "clk_uart3_div", CLK_SET_RATE_PARENT, + RK3399_CLKSEL_CON(103), 0, + RK3399_CLKGATE_CON(9), 7, GFLAGS, + &rk3399_uart3_fracmux), + + COMPOSITE(0, "pclk_ddr", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(6), 15, 1, MFLAGS, 8, 5, DFLAGS, + RK3399_CLKGATE_CON(3), 4, GFLAGS), + + GATE(PCLK_CENTER_MAIN_NOC, "pclk_center_main_noc", "pclk_ddr", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(18), 10, GFLAGS), + GATE(PCLK_DDR_MON, "pclk_ddr_mon", "pclk_ddr", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(18), 12, GFLAGS), + GATE(PCLK_CIC, "pclk_cic", "pclk_ddr", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(18), 15, GFLAGS), + GATE(PCLK_DDR_SGRF, "pclk_ddr_sgrf", "pclk_ddr", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(19), 2, GFLAGS), + + GATE(SCLK_PVTM_DDR, "clk_pvtm_ddr", "xin24m", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(4), 11, GFLAGS), + GATE(SCLK_DFIMON0_TIMER, "clk_dfimon0_timer", "xin24m", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(3), 5, GFLAGS), + GATE(SCLK_DFIMON1_TIMER, "clk_dfimon1_timer", "xin24m", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(3), 6, GFLAGS), + + /* cci */ + GATE(0, "cpll_aclk_cci_src", "cpll", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(2), 0, GFLAGS), + GATE(0, "gpll_aclk_cci_src", "gpll", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(2), 1, GFLAGS), + GATE(0, "npll_aclk_cci_src", "npll", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(2), 2, GFLAGS), + GATE(0, "vpll_aclk_cci_src", "vpll", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(2), 3, GFLAGS), + + COMPOSITE(0, "aclk_cci_pre", mux_aclk_cci_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(5), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3399_CLKGATE_CON(2), 4, GFLAGS), + + GATE(ACLK_ADB400M_PD_CORE_L, "aclk_adb400m_pd_core_l", "aclk_cci_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(15), 0, GFLAGS), + GATE(ACLK_ADB400M_PD_CORE_B, "aclk_adb400m_pd_core_b", "aclk_cci_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(15), 1, GFLAGS), + GATE(ACLK_CCI, "aclk_cci", "aclk_cci_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(15), 2, GFLAGS), + GATE(ACLK_CCI_NOC0, "aclk_cci_noc0", "aclk_cci_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(15), 3, GFLAGS), + GATE(ACLK_CCI_NOC1, "aclk_cci_noc1", "aclk_cci_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(15), 4, GFLAGS), + GATE(ACLK_CCI_GRF, "aclk_cci_grf", "aclk_cci_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(15), 7, GFLAGS), + + GATE(0, "cpll_cci_trace", "cpll", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(2), 5, GFLAGS), + GATE(0, "gpll_cci_trace", "gpll", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(2), 6, GFLAGS), + COMPOSITE(SCLK_CCI_TRACE, "clk_cci_trace", mux_cci_trace_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(5), 15, 2, MFLAGS, 8, 5, DFLAGS, + RK3399_CLKGATE_CON(2), 7, GFLAGS), + + GATE(0, "cpll_cs", "cpll", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(2), 8, GFLAGS), + GATE(0, "gpll_cs", "gpll", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(2), 9, GFLAGS), + GATE(0, "npll_cs", "npll", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(2), 10, GFLAGS), + COMPOSITE_NOGATE(0, "clk_cs", mux_cs_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(4), 6, 2, MFLAGS, 0, 5, DFLAGS), + GATE(0, "clk_dbg_cxcs", "clk_cs", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(15), 5, GFLAGS), + GATE(0, "clk_dbg_noc", "clk_cs", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(15), 6, GFLAGS), + + /* vcodec */ + COMPOSITE(0, "aclk_vcodec_pre", mux_pll_src_cpll_gpll_npll_ppll_p, 0, + RK3399_CLKSEL_CON(7), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3399_CLKGATE_CON(4), 0, GFLAGS), + COMPOSITE_NOMUX(0, "hclk_vcodec_pre", "aclk_vcodec_pre", 0, + RK3399_CLKSEL_CON(7), 8, 5, DFLAGS, + RK3399_CLKGATE_CON(4), 1, GFLAGS), + GATE(HCLK_VCODEC, "hclk_vcodec", "hclk_vcodec_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(17), 2, GFLAGS), + GATE(0, "hclk_vcodec_noc", "hclk_vcodec_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(17), 3, GFLAGS), + + GATE(ACLK_VCODEC, "aclk_vcodec", "aclk_vcodec_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(17), 0, GFLAGS), + GATE(0, "aclk_vcodec_noc", "aclk_vcodec_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(17), 1, GFLAGS), + + /* vdu */ + COMPOSITE(SCLK_VDU_CORE, "clk_vdu_core", mux_pll_src_cpll_gpll_npll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(9), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3399_CLKGATE_CON(4), 4, GFLAGS), + COMPOSITE(SCLK_VDU_CA, "clk_vdu_ca", mux_pll_src_cpll_gpll_npll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(9), 14, 2, MFLAGS, 8, 5, DFLAGS, + RK3399_CLKGATE_CON(4), 5, GFLAGS), + + COMPOSITE(0, "aclk_vdu_pre", mux_pll_src_cpll_gpll_npll_ppll_p, 0, + RK3399_CLKSEL_CON(8), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3399_CLKGATE_CON(4), 2, GFLAGS), + COMPOSITE_NOMUX(0, "hclk_vdu_pre", "aclk_vdu_pre", 0, + RK3399_CLKSEL_CON(8), 8, 5, DFLAGS, + RK3399_CLKGATE_CON(4), 3, GFLAGS), + GATE(HCLK_VDU, "hclk_vdu", "hclk_vdu_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(17), 10, GFLAGS), + GATE(HCLK_VDU_NOC, "hclk_vdu_noc", "hclk_vdu_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(17), 11, GFLAGS), + + GATE(ACLK_VDU, "aclk_vdu", "aclk_vdu_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(17), 8, GFLAGS), + GATE(ACLK_VDU_NOC, "aclk_vdu_noc", "aclk_vdu_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(17), 9, GFLAGS), + + /* iep */ + COMPOSITE(0, "aclk_iep_pre", mux_pll_src_cpll_gpll_npll_ppll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(10), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3399_CLKGATE_CON(4), 6, GFLAGS), + COMPOSITE_NOMUX(0, "hclk_iep_pre", "aclk_iep_pre", 0, + RK3399_CLKSEL_CON(10), 8, 5, DFLAGS, + RK3399_CLKGATE_CON(4), 7, GFLAGS), + GATE(HCLK_IEP, "hclk_iep", "hclk_iep_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(16), 2, GFLAGS), + GATE(HCLK_IEP_NOC, "hclk_iep_noc", "hclk_iep_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(16), 3, GFLAGS), + + GATE(ACLK_IEP, "aclk_iep", "aclk_iep_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(16), 0, GFLAGS), + GATE(ACLK_IEP_NOC, "aclk_iep_noc", "aclk_iep_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(16), 1, GFLAGS), + + /* rga */ + COMPOSITE(0, "clk_rga_core", mux_pll_src_cpll_gpll_npll_ppll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(12), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3399_CLKGATE_CON(4), 10, GFLAGS), + + COMPOSITE(0, "aclk_rga_pre", mux_pll_src_cpll_gpll_npll_ppll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(11), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3399_CLKGATE_CON(4), 8, GFLAGS), + COMPOSITE_NOMUX(0, "hclk_rga_pre", "aclk_rga_pre", 0, + RK3399_CLKSEL_CON(11), 8, 5, DFLAGS, + RK3399_CLKGATE_CON(4), 9, GFLAGS), + GATE(HCLK_RGA, "hclk_rga", "hclk_rga_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(16), 10, GFLAGS), + GATE(HCLK_RGA_NOC, "hclk_rga_noc", "hclk_rga_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(16), 11, GFLAGS), + + GATE(ACLK_RGA, "aclk_rga", "aclk_rga_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(16), 8, GFLAGS), + GATE(ACLK_RGA_NOC, "aclk_rga_noc", "aclk_rga_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(16), 9, GFLAGS), + + /* center */ + COMPOSITE(0, "aclk_center", mux_pll_src_cpll_gpll_npll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(12), 14, 2, MFLAGS, 8, 5, DFLAGS, + RK3399_CLKGATE_CON(3), 7, GFLAGS), + GATE(ACLK_CENTER_MAIN_NOC, "aclk_center_main_noc", "aclk_center", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(19), 0, GFLAGS), + GATE(ACLK_CENTER_PERI_NOC, "aclk_center_peri_noc", "aclk_center", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(19), 1, GFLAGS), + + /* gpu */ + COMPOSITE(0, "aclk_gpu_pre", mux_pll_src_ppll_cpll_gpll_npll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(13), 5, 3, MFLAGS, 0, 5, DFLAGS, + RK3399_CLKGATE_CON(13), 0, GFLAGS), + GATE(ACLK_GPU, "aclk_gpu", "aclk_gpu_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(30), 8, GFLAGS), + GATE(ACLK_PERF_GPU, "aclk_perf_gpu", "aclk_gpu_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(30), 10, GFLAGS), + GATE(ACLK_GPU_GRF, "aclk_gpu_grf", "aclk_gpu_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(30), 11, GFLAGS), + GATE(SCLK_PVTM_GPU, "aclk_pvtm_gpu", "xin24m", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(13), 1, GFLAGS), + + /* perihp */ + GATE(0, "cpll_aclk_perihp_src", "gpll", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(5), 0, GFLAGS), + GATE(0, "gpll_aclk_perihp_src", "cpll", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(5), 1, GFLAGS), + COMPOSITE(ACLK_PERIHP, "aclk_perihp", mux_aclk_perihp_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(14), 7, 1, MFLAGS, 0, 5, DFLAGS, + RK3399_CLKGATE_CON(5), 2, GFLAGS), + COMPOSITE_NOMUX(HCLK_PERIHP, "hclk_perihp", "aclk_perihp", CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(14), 8, 2, DFLAGS, + RK3399_CLKGATE_CON(5), 3, GFLAGS), + COMPOSITE_NOMUX(PCLK_PERIHP, "pclk_perihp", "aclk_perihp", CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(14), 12, 2, DFLAGS, + RK3399_CLKGATE_CON(5), 4, GFLAGS), + + GATE(ACLK_PERF_PCIE, "aclk_perf_pcie", "aclk_perihp", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(20), 2, GFLAGS), + GATE(ACLK_PCIE, "aclk_pcie", "aclk_perihp", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(20), 10, GFLAGS), + GATE(0, "aclk_perihp_noc", "aclk_perihp", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(20), 12, GFLAGS), + + GATE(HCLK_HOST0, "hclk_host0", "hclk_perihp", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(20), 5, GFLAGS), + GATE(HCLK_HOST0_ARB, "hclk_host0_arb", "hclk_perihp", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(20), 6, GFLAGS), + GATE(HCLK_HOST1, "hclk_host1", "hclk_perihp", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(20), 7, GFLAGS), + GATE(HCLK_HOST1_ARB, "hclk_host1_arb", "hclk_perihp", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(20), 8, GFLAGS), + GATE(HCLK_HSIC, "hclk_hsic", "hclk_perihp", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(20), 9, GFLAGS), + GATE(0, "hclk_perihp_noc", "hclk_perihp", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(20), 13, GFLAGS), + GATE(0, "hclk_ahb1tom", "hclk_perihp", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(20), 15, GFLAGS), + + GATE(PCLK_PERIHP_GRF, "pclk_perihp_grf", "pclk_perihp", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(20), 4, GFLAGS), + GATE(PCLK_PCIE, "pclk_pcie", "pclk_perihp", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(20), 11, GFLAGS), + GATE(0, "pclk_perihp_noc", "pclk_perihp", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(20), 14, GFLAGS), + GATE(PCLK_HSICPHY, "pclk_hsicphy", "pclk_perihp", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(31), 8, GFLAGS), + + /* sdio & sdmmc */ + COMPOSITE(0, "hclk_sd", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(13), 15, 1, MFLAGS, 8, 5, DFLAGS, + RK3399_CLKGATE_CON(12), 13, GFLAGS), + GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_sd", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(33), 8, GFLAGS), + GATE(0, "hclk_sdmmc_noc", "hclk_sd", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(33), 9, GFLAGS), + + COMPOSITE(SCLK_SDIO, "clk_sdio", mux_pll_src_cpll_gpll_npll_ppll_upll_24m_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(15), 8, 3, MFLAGS, 0, 7, DFLAGS, + RK3399_CLKGATE_CON(6), 0, GFLAGS), + + COMPOSITE(SCLK_SDMMC, "clk_sdmmc", mux_pll_src_cpll_gpll_npll_ppll_upll_24m_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(16), 8, 3, MFLAGS, 0, 7, DFLAGS, + RK3399_CLKGATE_CON(6), 1, GFLAGS), + + MMC(SCLK_SDMMC_DRV, "emmc_drv", "clk_sdmmc", RK3399_SDMMC_CON0, 1), + MMC(SCLK_SDMMC_SAMPLE, "emmc_sample", "clk_sdmmc", RK3399_SDMMC_CON1, 1), + + MMC(SCLK_SDIO_DRV, "sdio_drv", "clk_sdio", RK3399_SDIO_CON0, 1), + MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "clk_sdio", RK3399_SDIO_CON1, 1), + + /* pcie */ + COMPOSITE(SCLK_PCIE_PM, "clk_pcie_pm", mux_pll_src_cpll_gpll_npll_24m_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(17), 8, 3, MFLAGS, 0, 7, DFLAGS, + RK3399_CLKGATE_CON(6), 2, GFLAGS), + + COMPOSITE_NOMUX(0, "clk_pciephy_ref100m", "npll", CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(18), 11, 5, DFLAGS, + RK3399_CLKGATE_CON(12), 6, GFLAGS), + MUX(SCLK_PCIEPHY_REF, "clk_pciephy_ref", mux_pll_src_24m_pciephy_p, CLK_SET_RATE_PARENT, + RK3399_CLKSEL_CON(18), 10, 1, MFLAGS), + + COMPOSITE(0, "clk_pcie_core_cru", mux_pll_src_cpll_gpll_npll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(18), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3399_CLKGATE_CON(6), 3, GFLAGS), + MUX(SCLK_PCIE_CORE, "clk_pcie_core", mux_pciecore_cru_phy_p, CLK_SET_RATE_PARENT, + RK3399_CLKSEL_CON(18), 7, 1, MFLAGS), + + /* emmc */ + COMPOSITE(SCLK_EMMC, "clk_emmc", mux_pll_src_cpll_gpll_npll_upll_24m_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(22), 8, 3, MFLAGS, 0, 7, DFLAGS, + RK3399_CLKGATE_CON(6), 14, GFLAGS), + + GATE(0, "cpll_aclk_emmc_src", "cpll", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(6), 12, GFLAGS), + GATE(0, "gpll_aclk_emmc_src", "gpll", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(6), 13, GFLAGS), + COMPOSITE_NOGATE(ACLK_EMMC, "aclk_emmc", mux_aclk_emmc_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(21), 7, 1, MFLAGS, 0, 5, DFLAGS), + GATE(ACLK_EMMC_CORE, "aclk_emmccore", "aclk_emmc", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(32), 8, GFLAGS), + GATE(ACLK_EMMC_NOC, "aclk_emmc_noc", "aclk_emmc", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(32), 9, GFLAGS), + GATE(ACLK_EMMC_GRF, "aclk_emmcgrf", "aclk_emmc", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(32), 10, GFLAGS), + + /* perilp0 */ + GATE(0, "cpll_aclk_perilp0_src", "cpll", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(7), 1, GFLAGS), + GATE(0, "gpll_aclk_perilp0_src", "gpll", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(7), 0, GFLAGS), + COMPOSITE(ACLK_PERILP0, "aclk_perilp0", mux_aclk_perilp0_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(23), 7, 1, MFLAGS, 0, 5, DFLAGS, + RK3399_CLKGATE_CON(7), 2, GFLAGS), + COMPOSITE_NOMUX(HCLK_PERILP0, "hclk_perilp0", "aclk_perilp0", CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(23), 8, 2, DFLAGS, + RK3399_CLKGATE_CON(7), 3, GFLAGS), + COMPOSITE_NOMUX(PCLK_PERILP0, "pclk_perilp0", "aclk_perilp0", 0, + RK3399_CLKSEL_CON(23), 12, 3, DFLAGS, + RK3399_CLKGATE_CON(7), 4, GFLAGS), + + /* aclk_perilp0 gates */ + GATE(ACLK_INTMEM, "aclk_intmem", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 0, GFLAGS), + GATE(ACLK_TZMA, "aclk_tzma", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 1, GFLAGS), + GATE(SCLK_INTMEM0, "clk_intmem0", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 2, GFLAGS), + GATE(SCLK_INTMEM1, "clk_intmem1", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 3, GFLAGS), + GATE(SCLK_INTMEM2, "clk_intmem2", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 4, GFLAGS), + GATE(SCLK_INTMEM3, "clk_intmem3", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 5, GFLAGS), + GATE(SCLK_INTMEM4, "clk_intmem4", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 6, GFLAGS), + GATE(SCLK_INTMEM5, "clk_intmem5", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 7, GFLAGS), + GATE(ACLK_DCF, "aclk_dcf", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 8, GFLAGS), + GATE(ACLK_DMAC0_PERILP, "aclk_dmac0_perilp", "aclk_perilp0", 0, RK3399_CLKGATE_CON(25), 5, GFLAGS), + GATE(ACLK_DMAC1_PERILP, "aclk_dmac1_perilp", "aclk_perilp0", 0, RK3399_CLKGATE_CON(25), 6, GFLAGS), + GATE(ACLK_PERILP0_NOC, "aclk_perilp0_noc", "aclk_perilp0", 0, RK3399_CLKGATE_CON(25), 7, GFLAGS), + + /* hclk_perilp0 gates */ + GATE(HCLK_ROM, "hclk_rom", "hclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(24), 4, GFLAGS), + GATE(HCLK_M_CRYPTO0, "hclk_m_crypto0", "hclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(24), 5, GFLAGS), + GATE(HCLK_S_CRYPTO0, "hclk_s_crypto0", "hclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(24), 6, GFLAGS), + GATE(HCLK_M_CRYPTO1, "hclk_m_crypto1", "hclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(24), 14, GFLAGS), + GATE(HCLK_S_CRYPTO1, "hclk_s_crypto1", "hclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(24), 15, GFLAGS), + GATE(HCLK_PERILP0_NOC, "hclk_perilp0_noc", "hclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(25), 8, GFLAGS), + + /* pclk_perilp0 gates */ + GATE(PCLK_DCF, "pclk_dcf", "pclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 9, GFLAGS), + + /* crypto */ + COMPOSITE(SCLK_CRYPTO0, "clk_crypto0", mux_pll_src_cpll_gpll_ppll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(24), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3399_CLKGATE_CON(7), 7, GFLAGS), + + COMPOSITE(SCLK_CRYPTO1, "clk_crypto1", mux_pll_src_cpll_gpll_ppll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(26), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3399_CLKGATE_CON(7), 8, GFLAGS), + + /* cm0s_perilp */ + GATE(0, "cpll_fclk_cm0s_src", "cpll", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(7), 6, GFLAGS), + GATE(0, "gpll_fclk_cm0s_src", "gpll", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(7), 5, GFLAGS), + COMPOSITE(FCLK_CM0S, "fclk_cm0s", mux_fclk_cm0s_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(24), 15, 1, MFLAGS, 8, 5, DFLAGS, + RK3399_CLKGATE_CON(7), 9, GFLAGS), + + /* fclk_cm0s gates */ + GATE(SCLK_M0_PERILP, "sclk_m0_perilp", "fclk_cm0s", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(24), 8, GFLAGS), + GATE(HCLK_M0_PERILP, "hclk_m0_perilp", "fclk_cm0s", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(24), 9, GFLAGS), + GATE(DCLK_M0_PERILP, "dclk_m0_perilp", "fclk_cm0s", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(24), 10, GFLAGS), + GATE(SCLK_M0_PERILP_DEC, "clk_m0_perilp_dec", "fclk_cm0s", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(24), 11, GFLAGS), + GATE(HCLK_M0_PERILP_NOC, "hclk_m0_perilp_noc", "fclk_cm0s", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(25), 11, GFLAGS), + + /* perilp1 */ + GATE(0, "cpll_hclk_perilp1_src", "cpll", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(8), 1, GFLAGS), + GATE(0, "gpll_hclk_perilp1_src", "gpll", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(8), 0, GFLAGS), + COMPOSITE_NOGATE(HCLK_PERILP1, "hclk_perilp1", mux_hclk_perilp1_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(25), 7, 1, MFLAGS, 0, 5, DFLAGS), + COMPOSITE_NOMUX(PCLK_PERILP1, "pclk_perilp1", "hclk_perilp1", CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(25), 8, 3, DFLAGS, + RK3399_CLKGATE_CON(8), 2, GFLAGS), + + /* hclk_perilp1 gates */ + GATE(0, "hclk_perilp1_noc", "hclk_perilp1", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(25), 9, GFLAGS), + GATE(0, "hclk_sdio_noc", "hclk_perilp1", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(25), 12, GFLAGS), + GATE(HCLK_I2S0_8CH, "hclk_i2s0", "hclk_perilp1", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(34), 0, GFLAGS), + GATE(HCLK_I2S1_8CH, "hclk_i2s1", "hclk_perilp1", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(34), 1, GFLAGS), + GATE(HCLK_I2S2_8CH, "hclk_i2s2", "hclk_perilp1", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(34), 2, GFLAGS), + GATE(HCLK_SPDIF, "hclk_spdif", "hclk_perilp1", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(34), 3, GFLAGS), + GATE(HCLK_SDIO, "hclk_sdio", "hclk_perilp1", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(34), 4, GFLAGS), + GATE(PCLK_SPI5, "pclk_spi5", "hclk_perilp1", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(34), 5, GFLAGS), + GATE(0, "hclk_sdioaudio_noc", "hclk_perilp1", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(34), 6, GFLAGS), + + /* pclk_perilp1 gates */ + GATE(PCLK_UART0, "pclk_uart0", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 0, GFLAGS), + GATE(PCLK_UART1, "pclk_uart1", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 1, GFLAGS), + GATE(PCLK_UART2, "pclk_uart2", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 2, GFLAGS), + GATE(PCLK_UART3, "pclk_uart3", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 3, GFLAGS), + GATE(PCLK_I2C7, "pclk_rki2c7", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 5, GFLAGS), + GATE(PCLK_I2C1, "pclk_rki2c1", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 6, GFLAGS), + GATE(PCLK_I2C5, "pclk_rki2c5", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 7, GFLAGS), + GATE(PCLK_I2C6, "pclk_rki2c6", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 8, GFLAGS), + GATE(PCLK_I2C2, "pclk_rki2c2", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 9, GFLAGS), + GATE(PCLK_I2C3, "pclk_rki2c3", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 10, GFLAGS), + GATE(PCLK_MAILBOX0, "pclk_mailbox0", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 11, GFLAGS), + GATE(PCLK_SARADC, "pclk_saradc", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 12, GFLAGS), + GATE(PCLK_TSADC, "pclk_tsadc", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 13, GFLAGS), + GATE(PCLK_EFUSE1024NS, "pclk_efuse1024ns", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 14, GFLAGS), + GATE(PCLK_EFUSE1024S, "pclk_efuse1024s", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 15, GFLAGS), + GATE(PCLK_SPI0, "pclk_spi0", "pclk_perilp1", 0, RK3399_CLKGATE_CON(23), 10, GFLAGS), + GATE(PCLK_SPI1, "pclk_spi1", "pclk_perilp1", 0, RK3399_CLKGATE_CON(23), 11, GFLAGS), + GATE(PCLK_SPI2, "pclk_spi2", "pclk_perilp1", 0, RK3399_CLKGATE_CON(23), 12, GFLAGS), + GATE(PCLK_SPI4, "pclk_spi4", "pclk_perilp1", 0, RK3399_CLKGATE_CON(23), 13, GFLAGS), + GATE(PCLK_PERIHP_GRF, "pclk_perilp_sgrf", "pclk_perilp1", 0, RK3399_CLKGATE_CON(24), 13, GFLAGS), + GATE(0, "pclk_perilp1_noc", "pclk_perilp1", 0, RK3399_CLKGATE_CON(25), 10, GFLAGS), + + /* saradc */ + COMPOSITE_NOMUX(SCLK_SARADC, "clk_saradc", "xin24m", 0, + RK3399_CLKSEL_CON(26), 8, 8, DFLAGS, + RK3399_CLKGATE_CON(9), 11, GFLAGS), + + /* tsadc */ + COMPOSITE(SCLK_TSADC, "clk_tsadc", mux_pll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(27), 15, 1, MFLAGS, 0, 10, DFLAGS, + RK3399_CLKGATE_CON(9), 10, GFLAGS), + + /* cif_testout */ + MUX(0, "clk_testout1_pll_src", mux_pll_src_cpll_gpll_npll_p, 0, + RK3399_CLKSEL_CON(38), 6, 2, MFLAGS), + COMPOSITE(0, "clk_testout1", mux_clk_testout1_p, 0, + RK3399_CLKSEL_CON(38), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3399_CLKGATE_CON(13), 14, GFLAGS), + + MUX(0, "clk_testout2_pll_src", mux_pll_src_cpll_gpll_npll_p, 0, + RK3399_CLKSEL_CON(38), 14, 2, MFLAGS), + COMPOSITE(0, "clk_testout2", mux_clk_testout2_p, 0, + RK3399_CLKSEL_CON(38), 13, 1, MFLAGS, 8, 5, DFLAGS, + RK3399_CLKGATE_CON(13), 15, GFLAGS), + + /* vio */ + COMPOSITE(ACLK_VIO, "aclk_vio", mux_pll_src_cpll_gpll_ppll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(42), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3399_CLKGATE_CON(11), 10, GFLAGS), + COMPOSITE_NOMUX(PCLK_VIO, "pclk_vio", "aclk_vio", 0, + RK3399_CLKSEL_CON(43), 0, 5, DFLAGS, + RK3399_CLKGATE_CON(11), 1, GFLAGS), + + GATE(ACLK_VIO_NOC, "aclk_vio_noc", "aclk_vio", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(29), 0, GFLAGS), + + GATE(PCLK_MIPI_DSI0, "pclk_mipi_dsi0", "pclk_vio", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(29), 1, GFLAGS), + GATE(PCLK_MIPI_DSI1, "pclk_mipi_dsi1", "pclk_vio", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(29), 2, GFLAGS), + GATE(PCLK_VIO_GRF, "pclk_vio_grf", "pclk_vio", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(29), 12, GFLAGS), + + /* hdcp */ + COMPOSITE(ACLK_HDCP, "aclk_hdcp", mux_pll_src_cpll_gpll_ppll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(42), 14, 2, MFLAGS, 8, 5, DFLAGS, + RK3399_CLKGATE_CON(11), 12, GFLAGS), + COMPOSITE_NOMUX(HCLK_HDCP, "hclk_hdcp", "aclk_hdcp", CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(43), 5, 5, DFLAGS, + RK3399_CLKGATE_CON(11), 3, GFLAGS), + COMPOSITE_NOMUX(PCLK_HDCP, "pclk_hdcp", "aclk_hdcp", CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(43), 10, 5, DFLAGS, + RK3399_CLKGATE_CON(11), 10, GFLAGS), + + GATE(ACLK_HDCP_NOC, "aclk_hdcp_noc", "aclk_hdcp", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(29), 4, GFLAGS), + GATE(ACLK_HDCP22, "aclk_hdcp22", "aclk_hdcp", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(29), 10, GFLAGS), + + GATE(HCLK_HDCP_NOC, "hclk_hdcp_noc", "hclk_hdcp", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(29), 5, GFLAGS), + GATE(HCLK_HDCP22, "hclk_hdcp22", "hclk_hdcp", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(29), 9, GFLAGS), + + GATE(PCLK_HDCP_NOC, "pclk_hdcp_noc", "pclk_hdcp", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(29), 3, GFLAGS), + GATE(PCLK_HDMI_CTRL, "pclk_hdmi_ctrl", "pclk_hdcp", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(29), 6, GFLAGS), + GATE(PCLK_DP_CTRL, "pclk_dp_ctrl", "pclk_hdcp", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(29), 7, GFLAGS), + GATE(PCLK_HDCP22, "pclk_hdcp22", "pclk_hdcp", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(29), 8, GFLAGS), + GATE(PCLK_GASKET, "pclk_gasket", "pclk_hdcp", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(29), 11, GFLAGS), + + /* edp */ + COMPOSITE(SCLK_DP_CORE, "clk_dp_core", mux_pll_src_npll_cpll_gpll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(46), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3399_CLKGATE_CON(11), 8, GFLAGS), + + COMPOSITE(PCLK_EDP, "pclk_edp", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(44), 15, 1, MFLAGS, 8, 5, DFLAGS, + RK3399_CLKGATE_CON(11), 11, GFLAGS), + GATE(PCLK_EDP_NOC, "pclk_edp_noc", "pclk_edp", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(32), 12, GFLAGS), + GATE(PCLK_EDP_CTRL, "pclk_edp_ctrl", "pclk_edp", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(32), 13, GFLAGS), + + /* hdmi */ + GATE(SCLK_HDMI_SFR, "clk_hdmi_sfr", "xin24m", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(11), 6, GFLAGS), + + COMPOSITE(SCLK_HDMI_CEC, "clk_hdmi_cec", mux_pll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(45), 15, 1, MFLAGS, 0, 10, DFLAGS, + RK3399_CLKGATE_CON(11), 7, GFLAGS), + + /* vop0 */ + COMPOSITE(ACLK_VOP0_PRE, "aclk_vop0_pre", mux_pll_src_vpll_cpll_gpll_npll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(47), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3399_CLKGATE_CON(10), 8, GFLAGS), + COMPOSITE_NOMUX(0, "hclk_vop0_pre", "aclk_vop0_pre", 0, + RK3399_CLKSEL_CON(47), 8, 5, DFLAGS, + RK3399_CLKGATE_CON(10), 9, GFLAGS), + + GATE(ACLK_VOP0, "aclk_vop0", "aclk_vop0_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(28), 3, GFLAGS), + GATE(ACLK_VOP0_NOC, "aclk_vop0_noc", "aclk_vop0_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(28), 1, GFLAGS), + + GATE(HCLK_VOP0, "hclk_vop0", "hclk_vop0_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(28), 2, GFLAGS), + GATE(HCLK_VOP0_NOC, "hclk_vop0_noc", "hclk_vop0_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(28), 0, GFLAGS), + + COMPOSITE(DCLK_VOP0_DIV, "dclk_vop0_div", mux_pll_src_vpll_cpll_gpll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(49), 8, 2, MFLAGS, 0, 8, DFLAGS, + RK3399_CLKGATE_CON(10), 12, GFLAGS), + + COMPOSITE_FRACMUX_NOGATE(0, "dclk_vop0_frac", "dclk_vop0_div", CLK_SET_RATE_PARENT, + RK3399_CLKSEL_CON(106), 0, + &rk3399_dclk_vop0_fracmux), + + COMPOSITE(SCLK_VOP0_PWM, "clk_vop0_pwm", mux_pll_src_vpll_cpll_gpll_24m_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(51), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3399_CLKGATE_CON(10), 14, GFLAGS), + + /* vop1 */ + COMPOSITE(ACLK_VOP1_PRE, "aclk_vop1_pre", mux_pll_src_vpll_cpll_gpll_npll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(48), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3399_CLKGATE_CON(10), 10, GFLAGS), + COMPOSITE_NOMUX(0, "hclk_vop1_pre", "aclk_vop1_pre", 0, + RK3399_CLKSEL_CON(48), 8, 5, DFLAGS, + RK3399_CLKGATE_CON(10), 11, GFLAGS), + + GATE(ACLK_VOP1, "aclk_vop1", "aclk_vop1_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(28), 7, GFLAGS), + GATE(ACLK_VOP1_NOC, "aclk_vop1_noc", "aclk_vop1_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(28), 5, GFLAGS), + + GATE(HCLK_VOP1, "hclk_vop1", "hclk_vop1_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(28), 6, GFLAGS), + GATE(HCLK_VOP1_NOC, "hclk_vop1_noc", "hclk_vop1_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(28), 4, GFLAGS), + + COMPOSITE(DCLK_VOP1_DIV, "dclk_vop1_div", mux_pll_src_vpll_cpll_gpll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(50), 8, 2, MFLAGS, 0, 8, DFLAGS, + RK3399_CLKGATE_CON(10), 13, GFLAGS), + + COMPOSITE_FRACMUX_NOGATE(0, "dclk_vop1_frac", "dclk_vop1_div", CLK_SET_RATE_PARENT, + RK3399_CLKSEL_CON(107), 0, + &rk3399_dclk_vop1_fracmux), + + COMPOSITE(SCLK_VOP1_PWM, "clk_vop1_pwm", mux_pll_src_vpll_cpll_gpll_24m_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(52), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3399_CLKGATE_CON(10), 15, GFLAGS), + + /* isp */ + COMPOSITE(0, "aclk_isp0", mux_pll_src_cpll_gpll_ppll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(53), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3399_CLKGATE_CON(12), 8, GFLAGS), + COMPOSITE_NOMUX(0, "hclk_isp0", "aclk_isp0", 0, + RK3399_CLKSEL_CON(53), 8, 5, DFLAGS, + RK3399_CLKGATE_CON(12), 9, GFLAGS), + + GATE(ACLK_ISP0_NOC, "aclk_isp0_noc", "aclk_isp0", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(27), 1, GFLAGS), + GATE(ACLK_ISP0_WRAPPER, "aclk_isp0_wrapper", "aclk_isp0", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(27), 5, GFLAGS), + GATE(HCLK_ISP1_WRAPPER, "hclk_isp1_wrapper", "aclk_isp0", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(27), 7, GFLAGS), + + GATE(HCLK_ISP0_NOC, "hclk_isp0_noc", "hclk_isp0", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(27), 0, GFLAGS), + GATE(HCLK_ISP0_WRAPPER, "hclk_isp0_wrapper", "hclk_isp0", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(27), 4, GFLAGS), + + COMPOSITE(SCLK_ISP0, "clk_isp0", mux_pll_src_cpll_gpll_npll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(55), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3399_CLKGATE_CON(11), 4, GFLAGS), + + COMPOSITE(ACLK_ISP1, "aclk_isp1", mux_pll_src_cpll_gpll_ppll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(54), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3399_CLKGATE_CON(12), 10, GFLAGS), + COMPOSITE_NOMUX(0, "hclk_isp1", "aclk_isp1", 0, + RK3399_CLKSEL_CON(54), 8, 5, DFLAGS, + RK3399_CLKGATE_CON(12), 11, GFLAGS), + + GATE(ACLK_ISP1_NOC, "aclk_isp1_noc", "aclk_isp1", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(27), 3, GFLAGS), + + GATE(HCLK_ISP1_NOC, "hclk_isp1_noc", "hclk_isp1", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(27), 2, GFLAGS), + GATE(ACLK_ISP1_WRAPPER, "aclk_isp1_wrapper", "hclk_isp1", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(27), 8, GFLAGS), + + COMPOSITE(SCLK_ISP1, "clk_isp1", mux_pll_src_cpll_gpll_npll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(55), 14, 2, MFLAGS, 8, 5, DFLAGS, + RK3399_CLKGATE_CON(11), 5, GFLAGS), + + /* + * We use pclkin_cifinv by default GRF_SOC_CON20[9] (GSC20_9) setting in system, + * so we ignore the mux and make clocks nodes as following, + * + * pclkin_cifinv --|-------\ + * |GSC20_9|-- pclkin_cifmux -- |G27_6| -- pclkin_isp1_wrapper + * pclkin_cif --|-------/ + */ + GATE(PCLK_ISP1_WRAPPER, "pclkin_isp1_wrapper", "pclkin_cif", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(27), 6, GFLAGS), + + /* cif */ + COMPOSITE(0, "clk_cifout_div", mux_pll_src_cpll_gpll_npll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(56), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3399_CLKGATE_CON(10), 7, GFLAGS), + MUX(SCLK_CIF_OUT, "clk_cifout", mux_clk_cif_p, CLK_SET_RATE_PARENT, + RK3399_CLKSEL_CON(56), 5, 1, MFLAGS), + + /* gic */ + COMPOSITE(ACLK_GIC_PRE, "aclk_gic_pre", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED, + RK3399_CLKSEL_CON(56), 15, 1, MFLAGS, 8, 5, DFLAGS, + RK3399_CLKGATE_CON(12), 12, GFLAGS), + + GATE(ACLK_GIC, "aclk_gic", "aclk_gic_pre", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(33), 0, GFLAGS), + GATE(ACLK_GIC_NOC, "aclk_gic_noc", "aclk_gic_pre", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(33), 1, GFLAGS), + GATE(ACLK_GIC_ADB400_CORE_L_2_GIC, "aclk_gic_adb400_core_l_2_gic", "aclk_gic_pre", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(33), 2, GFLAGS), + GATE(ACLK_GIC_ADB400_CORE_B_2_GIC, "aclk_gic_adb400_core_b_2_gic", "aclk_gic_pre", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(33), 3, GFLAGS), + GATE(ACLK_GIC_ADB400_GIC_2_CORE_L, "aclk_gic_adb400_gic_2_core_l", "aclk_gic_pre", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(33), 4, GFLAGS), + GATE(ACLK_GIC_ADB400_GIC_2_CORE_B, "aclk_gic_adb400_gic_2_core_b", "aclk_gic_pre", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(33), 5, GFLAGS), + + /* alive */ + /* pclk_alive_gpll_src is controlled by PMUGRF_SOC_CON0[6] */ + DIV(PCLK_ALIVE, "pclk_alive", "gpll", 0, + RK3399_CLKSEL_CON(57), 0, 5, DFLAGS), + + GATE(PCLK_USBPHY_MUX_G, "pclk_usbphy_mux_g", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 4, GFLAGS), + GATE(PCLK_UPHY0_TCPHY_G, "pclk_uphy0_tcphy_g", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 5, GFLAGS), + GATE(PCLK_UPHY0_TCPD_G, "pclk_uphy0_tcpd_g", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 6, GFLAGS), + GATE(PCLK_UPHY1_TCPHY_G, "pclk_uphy1_tcphy_g", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 8, GFLAGS), + GATE(PCLK_UPHY1_TCPD_G, "pclk_uphy1_tcpd_g", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 9, GFLAGS), + + GATE(PCLK_GRF, "pclk_grf", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(31), 1, GFLAGS), + GATE(PCLK_INTR_ARB, "pclk_intr_arb", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(31), 2, GFLAGS), + GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(31), 3, GFLAGS), + GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(31), 4, GFLAGS), + GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(31), 5, GFLAGS), + GATE(PCLK_TIMER0, "pclk_timer0", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(31), 6, GFLAGS), + GATE(PCLK_TIMER1, "pclk_timer1", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(31), 7, GFLAGS), + GATE(PCLK_PMU_INTR_ARB, "pclk_pmu_intr_arb", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(31), 9, GFLAGS), + GATE(PCLK_SGRF, "pclk_sgrf", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(31), 10, GFLAGS), + + GATE(SCLK_MIPIDPHY_REF, "clk_mipidphy_ref", "xin24m", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(11), 14, GFLAGS), + GATE(SCLK_DPHY_PLL, "clk_dphy_pll", "clk_mipidphy_ref", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 0, GFLAGS), + + GATE(SCLK_MIPIDPHY_CFG, "clk_mipidphy_cfg", "xin24m", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(11), 15, GFLAGS), + GATE(SCLK_DPHY_TX0_CFG, "clk_dphy_tx0_cfg", "clk_mipidphy_cfg", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 1, GFLAGS), + GATE(SCLK_DPHY_TX1RX1_CFG, "clk_dphy_tx1rx1_cfg", "clk_mipidphy_cfg", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 2, GFLAGS), + GATE(SCLK_DPHY_RX0_CFG, "clk_dphy_rx0_cfg", "clk_mipidphy_cfg", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 3, GFLAGS), + + /* testout */ + MUX(0, "clk_test_pre", mux_pll_src_cpll_gpll_p, CLK_SET_RATE_PARENT, + RK3399_CLKSEL_CON(58), 7, 1, MFLAGS), + COMPOSITE_FRAC(0, "clk_test_frac", "clk_test_pre", CLK_SET_RATE_PARENT, + RK3399_CLKSEL_CON(105), 0, + RK3399_CLKGATE_CON(13), 9, GFLAGS), + + DIV(0, "clk_test_24m", "xin24m", 0, + RK3399_CLKSEL_CON(57), 6, 10, DFLAGS), + + /* spi */ + COMPOSITE(SCLK_SPI0, "clk_spi0", mux_pll_src_cpll_gpll_p, 0, + RK3399_CLKSEL_CON(59), 7, 1, MFLAGS, 0, 7, DFLAGS, + RK3399_CLKGATE_CON(9), 12, GFLAGS), + + COMPOSITE(SCLK_SPI1, "clk_spi1", mux_pll_src_cpll_gpll_p, 0, + RK3399_CLKSEL_CON(59), 15, 1, MFLAGS, 8, 7, DFLAGS, + RK3399_CLKGATE_CON(9), 13, GFLAGS), + + COMPOSITE(SCLK_SPI2, "clk_spi2", mux_pll_src_cpll_gpll_p, 0, + RK3399_CLKSEL_CON(60), 7, 1, MFLAGS, 0, 7, DFLAGS, + RK3399_CLKGATE_CON(9), 14, GFLAGS), + + COMPOSITE(SCLK_SPI4, "clk_spi4", mux_pll_src_cpll_gpll_p, 0, + RK3399_CLKSEL_CON(60), 15, 1, MFLAGS, 8, 7, DFLAGS, + RK3399_CLKGATE_CON(9), 15, GFLAGS), + + COMPOSITE(SCLK_SPI5, "clk_spi5", mux_pll_src_cpll_gpll_p, 0, + RK3399_CLKSEL_CON(58), 15, 1, MFLAGS, 8, 7, DFLAGS, + RK3399_CLKGATE_CON(13), 13, GFLAGS), + + /* i2c */ + COMPOSITE(SCLK_I2C1, "clk_i2c1", mux_pll_src_cpll_gpll_p, 0, + RK3399_CLKSEL_CON(61), 7, 1, MFLAGS, 0, 7, DFLAGS, + RK3399_CLKGATE_CON(10), 0, GFLAGS), + + COMPOSITE(SCLK_I2C2, "clk_i2c2", mux_pll_src_cpll_gpll_p, 0, + RK3399_CLKSEL_CON(62), 7, 1, MFLAGS, 0, 7, DFLAGS, + RK3399_CLKGATE_CON(10), 2, GFLAGS), + + COMPOSITE(SCLK_I2C3, "clk_i2c3", mux_pll_src_cpll_gpll_p, 0, + RK3399_CLKSEL_CON(63), 7, 1, MFLAGS, 0, 7, DFLAGS, + RK3399_CLKGATE_CON(10), 4, GFLAGS), + + COMPOSITE(SCLK_I2C5, "clk_i2c5", mux_pll_src_cpll_gpll_p, 0, + RK3399_CLKSEL_CON(61), 15, 1, MFLAGS, 8, 7, DFLAGS, + RK3399_CLKGATE_CON(10), 1, GFLAGS), + + COMPOSITE(SCLK_I2C6, "clk_i2c6", mux_pll_src_cpll_gpll_p, 0, + RK3399_CLKSEL_CON(62), 15, 1, MFLAGS, 8, 7, DFLAGS, + RK3399_CLKGATE_CON(10), 3, GFLAGS), + + COMPOSITE(SCLK_I2C7, "clk_i2c7", mux_pll_src_cpll_gpll_p, 0, + RK3399_CLKSEL_CON(63), 15, 1, MFLAGS, 8, 7, DFLAGS, + RK3399_CLKGATE_CON(10), 5, GFLAGS), + + /* timer */ + GATE(SCLK_TIMER00, "clk_timer00", "xin24m", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(26), 0, GFLAGS), + GATE(SCLK_TIMER01, "clk_timer01", "xin24m", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(26), 1, GFLAGS), + GATE(SCLK_TIMER02, "clk_timer02", "xin24m", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(26), 2, GFLAGS), + GATE(SCLK_TIMER03, "clk_timer03", "xin24m", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(26), 3, GFLAGS), + GATE(SCLK_TIMER04, "clk_timer04", "xin24m", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(26), 4, GFLAGS), + GATE(SCLK_TIMER05, "clk_timer05", "xin24m", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(26), 5, GFLAGS), + GATE(SCLK_TIMER06, "clk_timer06", "xin24m", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(26), 6, GFLAGS), + GATE(SCLK_TIMER07, "clk_timer07", "xin24m", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(26), 7, GFLAGS), + GATE(SCLK_TIMER08, "clk_timer08", "xin24m", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(26), 8, GFLAGS), + GATE(SCLK_TIMER09, "clk_timer09", "xin24m", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(26), 9, GFLAGS), + GATE(SCLK_TIMER10, "clk_timer10", "xin24m", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(26), 10, GFLAGS), + GATE(SCLK_TIMER11, "clk_timer11", "xin24m", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(26), 11, GFLAGS), + + /* clk_test */ + /* clk_test_pre is controlled by CRU_MISC_CON[3] */ + COMPOSITE_NOMUX(0, "clk_test", "clk_test_pre", CLK_IGNORE_UNUSED, + RK3368_CLKSEL_CON(58), 0, 5, DFLAGS, + RK3368_CLKGATE_CON(13), 11, GFLAGS), +}; + +static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = { + /* + * PMU CRU Clock-Architecture + */ + + GATE(0, "fclk_cm0s_pmu_ppll_src", "ppll", CLK_IGNORE_UNUSED, + RK3399_PMU_CLKGATE_CON(0), 1, GFLAGS), + + COMPOSITE_NOGATE(FCLK_CM0S_SRC_PMU, "fclk_cm0s_src_pmu", mux_fclk_cm0s_pmu_ppll_p, CLK_IGNORE_UNUSED, + RK3399_PMU_CLKSEL_CON(0), 15, 1, MFLAGS, 8, 5, DFLAGS), + + COMPOSITE(SCLK_SPI3_PMU, "clk_spi3_pmu", mux_24m_ppll_p, CLK_IGNORE_UNUSED, + RK3399_PMU_CLKSEL_CON(1), 7, 1, MFLAGS, 0, 7, DFLAGS, + RK3399_PMU_CLKGATE_CON(0), 2, GFLAGS), + + COMPOSITE(0, "clk_wifi_div", mux_ppll_24m_p, CLK_IGNORE_UNUSED, + RK3399_PMU_CLKSEL_CON(1), 13, 1, MFLAGS, 8, 5, DFLAGS, + RK3399_PMU_CLKGATE_CON(0), 8, GFLAGS), + + COMPOSITE_FRACMUX_NOGATE(0, "clk_wifi_frac", "clk_wifi_div", CLK_SET_RATE_PARENT, + RK3399_PMU_CLKSEL_CON(7), 0, + &rk3399_pmuclk_wifi_fracmux), + + MUX(0, "clk_timer_src_pmu", mux_pll_p, CLK_IGNORE_UNUSED, + RK3399_PMU_CLKSEL_CON(1), 15, 1, MFLAGS), + + COMPOSITE_NOMUX(SCLK_I2C0_PMU, "clk_i2c0_pmu", "ppll", 0, + RK3399_PMU_CLKSEL_CON(2), 0, 7, DFLAGS, + RK3399_PMU_CLKGATE_CON(0), 9, GFLAGS), + + COMPOSITE_NOMUX(SCLK_I2C4_PMU, "clk_i2c4_pmu", "ppll", 0, + RK3399_PMU_CLKSEL_CON(3), 0, 7, DFLAGS, + RK3399_PMU_CLKGATE_CON(0), 11, GFLAGS), + + COMPOSITE_NOMUX(SCLK_I2C8_PMU, "clk_i2c8_pmu", "ppll", 0, + RK3399_PMU_CLKSEL_CON(2), 8, 7, DFLAGS, + RK3399_PMU_CLKGATE_CON(0), 10, GFLAGS), + + DIV(0, "clk_32k_suspend_pmu", "xin24m", CLK_IGNORE_UNUSED, + RK3399_PMU_CLKSEL_CON(4), 0, 10, DFLAGS), + MUX(0, "clk_testout_2io", mux_clk_testout2_2io_p, CLK_IGNORE_UNUSED, + RK3399_PMU_CLKSEL_CON(4), 15, 1, MFLAGS), + + COMPOSITE(0, "clk_uart4_div", mux_24m_ppll_p, CLK_IGNORE_UNUSED, + RK3399_PMU_CLKSEL_CON(5), 10, 1, MFLAGS, 0, 7, DFLAGS, + RK3399_PMU_CLKGATE_CON(0), 5, GFLAGS), + + COMPOSITE_FRACMUX(0, "clk_uart4_frac", "clk_uart4_div", CLK_SET_RATE_PARENT, + RK3399_PMU_CLKSEL_CON(6), 0, + RK3399_PMU_CLKGATE_CON(0), 6, GFLAGS, + &rk3399_uart4_pmu_fracmux), + + DIV(PCLK_SRC_PMU, "pclk_pmu_src", "ppll", CLK_IGNORE_UNUSED, + RK3399_PMU_CLKSEL_CON(0), 0, 5, DFLAGS), + + /* pmu clock gates */ + GATE(SCLK_TIMER12_PMU, "clk_timer0_pmu", "clk_timer_src_pmu", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(0), 3, GFLAGS), + GATE(SCLK_TIMER13_PMU, "clk_timer1_pmu", "clk_timer_src_pmu", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(0), 4, GFLAGS), + + GATE(SCLK_PVTM_PMU, "clk_pvtm_pmu", "xin24m", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(0), 7, GFLAGS), + + GATE(PCLK_PMU, "pclk_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), 0, GFLAGS), + GATE(PCLK_PMUGRF_PMU, "pclk_pmugrf_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), 1, GFLAGS), + GATE(PCLK_INTMEM1_PMU, "pclk_intmem1_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), 2, GFLAGS), + GATE(PCLK_GPIO0_PMU, "pclk_gpio0_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), 3, GFLAGS), + GATE(PCLK_GPIO1_PMU, "pclk_gpio1_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), 4, GFLAGS), + GATE(PCLK_SGRF_PMU, "pclk_sgrf_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), 5, GFLAGS), + GATE(PCLK_NOC_PMU, "pclk_noc_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), 6, GFLAGS), + GATE(PCLK_I2C0_PMU, "pclk_i2c0_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), 7, GFLAGS), + GATE(PCLK_I2C4_PMU, "pclk_i2c4_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), 8, GFLAGS), + GATE(PCLK_I2C8_PMU, "pclk_i2c8_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), 9, GFLAGS), + GATE(PCLK_RKPWM_PMU, "pclk_rkpwm_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), 10, GFLAGS), + GATE(PCLK_SPI3_PMU, "pclk_spi3_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), 11, GFLAGS), + GATE(PCLK_TIMER_PMU, "pclk_timer_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), 12, GFLAGS), + GATE(PCLK_MAILBOX_PMU, "pclk_mailbox_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), 13, GFLAGS), + GATE(PCLK_UART4_PMU, "pclk_uart4_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), 14, GFLAGS), + GATE(PCLK_WDT_M0_PMU, "pclk_wdt_m0_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), 15, GFLAGS), + + GATE(FCLK_CM0S_PMU, "fclk_cm0s_pmu", "fclk_cm0s_src_pmu", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(2), 0, GFLAGS), + GATE(SCLK_CM0S_PMU, "sclk_cm0s_pmu", "fclk_cm0s_src_pmu", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(2), 1, GFLAGS), + GATE(HCLK_CM0S_PMU, "hclk_cm0s_pmu", "fclk_cm0s_src_pmu", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(2), 2, GFLAGS), + GATE(DCLK_CM0S_PMU, "dclk_cm0s_pmu", "fclk_cm0s_src_pmu", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(2), 3, GFLAGS), + GATE(HCLK_NOC_PMU, "hclk_noc_pmu", "fclk_cm0s_src_pmu", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(2), 5, GFLAGS), +}; + +static const char *const rk3399_cru_critical_clocks[] __initconst = { + "aclk_cci_pre", + "pclk_perilp0", + "pclk_perilp0", + "hclk_perilp0", + "hclk_perilp0_noc", + "pclk_perilp1", + "pclk_perilp1_noc", + "pclk_perihp", + "pclk_perihp_noc", + "hclk_perihp", + "aclk_perihp", + "aclk_perihp_noc", + "aclk_perilp0", + "aclk_perilp0_noc", + "hclk_perilp1", + "hclk_perilp1_noc", + "aclk_dmac0_perilp", + "gpll_hclk_perilp1_src", + "gpll_aclk_perilp0_src", + "gpll_aclk_perihp_src", +}; + +static const char *const rk3399_pmucru_critical_clocks[] __initconst = { + "ppll", + "pclk_pmu_src", + "fclk_cm0s_src_pmu", + "clk_timer_src_pmu", +}; + +static void __init rk3399_clk_init(struct device_node *np) +{ + struct rockchip_clk_provider *ctx; + void __iomem *reg_base; + + reg_base = of_iomap(np, 0); + if (!reg_base) { + pr_err("%s: could not map cru region\n", __func__); + return; + } + + ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS); + if (IS_ERR(ctx)) { + pr_err("%s: rockchip clk init failed\n", __func__); + return; + } + + rockchip_clk_register_plls(ctx, rk3399_pll_clks, + ARRAY_SIZE(rk3399_pll_clks), -1); + + rockchip_clk_register_branches(ctx, rk3399_clk_branches, + ARRAY_SIZE(rk3399_clk_branches)); + + rockchip_clk_protect_critical(rk3399_cru_critical_clocks, + ARRAY_SIZE(rk3399_cru_critical_clocks)); + + rockchip_clk_register_armclk(ctx, ARMCLKL, "armclkl", + mux_armclkl_p, ARRAY_SIZE(mux_armclkl_p), + &rk3399_cpuclkl_data, rk3399_cpuclkl_rates, + ARRAY_SIZE(rk3399_cpuclkl_rates)); + + rockchip_clk_register_armclk(ctx, ARMCLKB, "armclkb", + mux_armclkb_p, ARRAY_SIZE(mux_armclkb_p), + &rk3399_cpuclkb_data, rk3399_cpuclkb_rates, + ARRAY_SIZE(rk3399_cpuclkb_rates)); + + rockchip_register_softrst(np, 21, reg_base + RK3399_SOFTRST_CON(0), + ROCKCHIP_SOFTRST_HIWORD_MASK); + + rockchip_register_restart_notifier(ctx, RK3399_GLB_SRST_FST, NULL); + + rockchip_clk_of_add_provider(np, ctx); +} +CLK_OF_DECLARE(rk3399_cru, "rockchip,rk3399-cru", rk3399_clk_init); + +static void __init rk3399_pmu_clk_init(struct device_node *np) +{ + struct rockchip_clk_provider *ctx; + void __iomem *reg_base; + + reg_base = of_iomap(np, 0); + if (!reg_base) { + pr_err("%s: could not map cru pmu region\n", __func__); + return; + } + + ctx = rockchip_clk_init(np, reg_base, CLKPMU_NR_CLKS); + if (IS_ERR(ctx)) { + pr_err("%s: rockchip pmu clk init failed\n", __func__); + return; + } + + rockchip_clk_register_plls(ctx, rk3399_pmu_pll_clks, + ARRAY_SIZE(rk3399_pmu_pll_clks), -1); + + rockchip_clk_register_branches(ctx, rk3399_clk_pmu_branches, + ARRAY_SIZE(rk3399_clk_pmu_branches)); + + rockchip_clk_protect_critical(rk3399_pmucru_critical_clocks, + ARRAY_SIZE(rk3399_pmucru_critical_clocks)); + + rockchip_register_softrst(np, 2, reg_base + RK3399_PMU_SOFTRST_CON(0), + ROCKCHIP_SOFTRST_HIWORD_MASK); + + rockchip_clk_of_add_provider(np, ctx); +} +CLK_OF_DECLARE(rk3399_cru_pmu, "rockchip,rk3399-pmucru", rk3399_pmu_clk_init); diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h index cb6a63963693..880349f6d3d7 100644 --- a/drivers/clk/rockchip/clk.h +++ b/drivers/clk/rockchip/clk.h @@ -34,7 +34,7 @@ struct clk; #define HIWORD_UPDATE(val, mask, shift) \ ((val) << (shift) | (mask) << ((shift) + 16)) -/* register positions shared by RK2928, RK3036, RK3066, RK3188 and RK3228 */ +/* register positions shared by RK2928, RK3036, RK3066, RK3188, RK3228, RK3399 */ #define RK2928_PLL_CON(x) ((x) * 0x4) #define RK2928_MODE_CON 0x40 #define RK2928_CLKSEL_CON(x) ((x) * 0x4 + 0x44) @@ -93,6 +93,26 @@ struct clk; #define RK3368_EMMC_CON0 0x418 #define RK3368_EMMC_CON1 0x41c +#define RK3399_PLL_CON(x) RK2928_PLL_CON(x) +#define RK3399_CLKSEL_CON(x) ((x) * 0x4 + 0x100) +#define RK3399_CLKGATE_CON(x) ((x) * 0x4 + 0x300) +#define RK3399_SOFTRST_CON(x) ((x) * 0x4 + 0x400) +#define RK3399_GLB_SRST_FST 0x500 +#define RK3399_GLB_SRST_SND 0x504 +#define RK3399_GLB_CNT_TH 0x508 +#define RK3399_MISC_CON 0x50c +#define RK3399_RST_CON 0x510 +#define RK3399_RST_ST 0x514 +#define RK3399_SDMMC_CON0 0x580 +#define RK3399_SDMMC_CON1 0x584 +#define RK3399_SDIO_CON0 0x588 +#define RK3399_SDIO_CON1 0x58c + +#define RK3399_PMU_PLL_CON(x) RK2928_PLL_CON(x) +#define RK3399_PMU_CLKSEL_CON(x) ((x) * 0x4 + 0x80) +#define RK3399_PMU_CLKGATE_CON(x) ((x) * 0x4 + 0x100) +#define RK3399_PMU_SOFTRST_CON(x) ((x) * 0x4 + 0x110) + enum rockchip_pll_type { pll_rk3036, pll_rk3066, -- cgit v1.2.3 From 3d1477309806459d39e13d8c3206ba35d183c34a Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Sat, 19 Mar 2016 18:02:55 +0530 Subject: staging: lustre: lnet: Replace sg++ with sg = sg_next(sg) With scatterlist chaining, simply incrementing the array does not work. sg_next macro was thus introduced to follow the chain links when necessary. So replace sg++ with sg_next. This change was made with the help of the following Coccinelle semantic patch: // @@ struct scatterlist *sg; @@ -sg++ +sg = sg_next(sg) // Signed-off-by: Amitoj Kaur Chawla Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c index 2323e8d3a318..cd3fde7c4fbd 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c @@ -704,7 +704,7 @@ kiblnd_setup_rd_iov(lnet_ni_t *ni, kib_tx_t *tx, kib_rdma_desc_t *rd, fragnob = min(fragnob, (int)PAGE_SIZE - page_offset); sg_set_page(sg, page, fragnob, page_offset); - sg++; + sg = sg_next(sg); if (offset + fragnob < iov->iov_len) { offset += fragnob; @@ -748,7 +748,7 @@ kiblnd_setup_rd_kiov(lnet_ni_t *ni, kib_tx_t *tx, kib_rdma_desc_t *rd, sg_set_page(sg, kiov->kiov_page, fragnob, kiov->kiov_offset + offset); - sg++; + sg = sg_next(sg); offset = 0; kiov++; -- cgit v1.2.3 From bde98b0603cf6ebdf2d5aea7f83f02f88aa35a7f Mon Sep 17 00:00:00 2001 From: James Nunez Date: Sat, 12 Mar 2016 13:00:31 -0500 Subject: staging: lustre: Correct missing newline for CERROR call in sfw_handle_server_rpc This is one of the fixes broken out of patch 10000 that was missed in the merger. With this fix the CERROR called in sfw_handle_server_rpc will print out correctly. Signed-off-by: James Nunez Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-4871 Reviewed-on: http://review.whamcloud.com/10000 Reviewed-by: Andreas Dilger Reviewed-by: John L. Hammond Reviewed-by: Cliff White Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/selftest/framework.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/selftest/framework.c b/drivers/staging/lustre/lnet/selftest/framework.c index 926c3970c498..0f32f0be4edc 100644 --- a/drivers/staging/lustre/lnet/selftest/framework.c +++ b/drivers/staging/lustre/lnet/selftest/framework.c @@ -1244,7 +1244,7 @@ sfw_handle_server_rpc(struct srpc_server_rpc *rpc) /* Remove timer to avoid racing with it or expiring active session */ if (sfw_del_session_timer()) { - CERROR("Dropping RPC (%s) from %s: racing with expiry timer.", + CERROR("dropping RPC %s from %s: racing with expiry timer\n", sv->sv_name, libcfs_id2str(rpc->srpc_peer)); spin_unlock(&sfw_data.fw_lock); return -EAGAIN; -- cgit v1.2.3 From ea25f451a063e1934402fab578d85ea8254d3dee Mon Sep 17 00:00:00 2001 From: Dmitry Eremin Date: Sat, 12 Mar 2016 13:00:32 -0500 Subject: staging: lustre: add missing buffer overflow fix for console.c Patch 9389 change a strncpy call into a strlcpy call. This was missed in the merger into the upstream client. Signed-off-by: Dmitry Eremin Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-4629 Reviewed-on: http://review.whamcloud.com/9389 Reviewed-by: Andreas Dilger Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/selftest/console.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/selftest/console.c b/drivers/staging/lustre/lnet/selftest/console.c index 1a923ea3a755..c009ad348a06 100644 --- a/drivers/staging/lustre/lnet/selftest/console.c +++ b/drivers/staging/lustre/lnet/selftest/console.c @@ -1749,7 +1749,7 @@ lstcon_session_new(char *name, int key, unsigned feats, if (strlen(name) > sizeof(console_session.ses_name) - 1) return -E2BIG; - strncpy(console_session.ses_name, name, + strlcpy(console_session.ses_name, name, sizeof(console_session.ses_name)); rc = lstcon_batch_add(LST_DEFAULT_BATCH); -- cgit v1.2.3 From 3eaf9fcc4b97dc3a475d2328c29cfd46615b3e55 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Sat, 12 Mar 2016 13:00:33 -0500 Subject: staging: lustre: handle error returned from wait_event_timeout seltest timer The function wait_event_timeout can fail and return an error. Handle this case in stt_timer_main(). Signed-off-by: James Simmons Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/selftest/timer.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/selftest/timer.c b/drivers/staging/lustre/lnet/selftest/timer.c index 8be52526ae5a..ef8a8a748cbe 100644 --- a/drivers/staging/lustre/lnet/selftest/timer.c +++ b/drivers/staging/lustre/lnet/selftest/timer.c @@ -170,20 +170,22 @@ stt_check_timers(unsigned long *last) static int stt_timer_main(void *arg) { + int rc = 0; + cfs_block_allsigs(); while (!stt_data.stt_shuttingdown) { stt_check_timers(&stt_data.stt_prev_slot); - wait_event_timeout(stt_data.stt_waitq, - stt_data.stt_shuttingdown, - cfs_time_seconds(STTIMER_SLOTTIME)); + rc = wait_event_timeout(stt_data.stt_waitq, + stt_data.stt_shuttingdown, + cfs_time_seconds(STTIMER_SLOTTIME)); } spin_lock(&stt_data.stt_lock); stt_data.stt_nthreads--; spin_unlock(&stt_data.stt_lock); - return 0; + return rc; } static int -- cgit v1.2.3 From 9b8fa4456cf3f6428958a71fdcc5fef64f3f0e11 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Sat, 12 Mar 2016 13:00:34 -0500 Subject: staging: lustre: remove excess blank lines in lnet selftest code Remove extra blank lines missed by checkpatch. Signed-off-by: James Simmons Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/selftest/brw_test.c | 2 -- drivers/staging/lustre/lnet/selftest/conrpc.c | 2 -- drivers/staging/lustre/lnet/selftest/console.c | 2 -- 3 files changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/selftest/brw_test.c b/drivers/staging/lustre/lnet/selftest/brw_test.c index eebc92412061..69812fc3c9ed 100644 --- a/drivers/staging/lustre/lnet/selftest/brw_test.c +++ b/drivers/staging/lustre/lnet/selftest/brw_test.c @@ -91,7 +91,6 @@ brw_client_init(sfw_test_instance_t *tsi) * but we have to keep it for compatibility */ len = npg * PAGE_CACHE_SIZE; - } else { test_bulk_req_v1_t *breq = &tsi->tsi_u.bulk_v1; @@ -279,7 +278,6 @@ brw_client_prep_rpc(sfw_test_unit_t *tsu, flags = breq->blk_flags; npg = breq->blk_npg; len = npg * PAGE_CACHE_SIZE; - } else { test_bulk_req_v1_t *breq = &tsi->tsi_u.bulk_v1; diff --git a/drivers/staging/lustre/lnet/selftest/conrpc.c b/drivers/staging/lustre/lnet/selftest/conrpc.c index bcd78888f9cc..d11869aa5db4 100644 --- a/drivers/staging/lustre/lnet/selftest/conrpc.c +++ b/drivers/staging/lustre/lnet/selftest/conrpc.c @@ -531,7 +531,6 @@ lstcon_rpc_trans_interpreter(lstcon_rpc_trans_t *trans, continue; error = readent(trans->tas_opc, msg, ent); - if (error) return error; } @@ -841,7 +840,6 @@ lstcon_testrpc_prep(lstcon_node_t *nd, int transop, unsigned feats, trq->tsr_ndest = 0; trq->tsr_loop = nmax * test->tes_dist * test->tes_concur; - } else { bulk = &(*crpc)->crp_rpc->crpc_bulk; diff --git a/drivers/staging/lustre/lnet/selftest/console.c b/drivers/staging/lustre/lnet/selftest/console.c index c009ad348a06..17d0d132d103 100644 --- a/drivers/staging/lustre/lnet/selftest/console.c +++ b/drivers/staging/lustre/lnet/selftest/console.c @@ -977,7 +977,6 @@ lstcon_batch_info(char *name, lstcon_test_batch_ent_t __user *ent_up, if (!test) { entp->u.tbe_batch.bae_ntest = bat->bat_ntest; entp->u.tbe_batch.bae_state = bat->bat_state; - } else { entp->u.tbe_test.tse_type = test->tes_type; entp->u.tbe_test.tse_loop = test->tes_loop; @@ -1423,7 +1422,6 @@ lstcon_test_batch_query(char *name, int testidx, int client, translist = &batch->bat_trans_list; ndlist = &batch->bat_cli_list; hdr = &batch->bat_hdr; - } else { /* query specified test only */ rc = lstcon_test_find(batch, testidx, &test); -- cgit v1.2.3 From 0b4427deebab7cf86917772f8e00061c63494cd3 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Sat, 12 Mar 2016 13:00:35 -0500 Subject: staging: lustre: realign some code in lnet selftest so its readable Two places to align the code so it is easier to read. Signed-off-by: James Simmons Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/selftest/console.c | 2 +- drivers/staging/lustre/lnet/selftest/ping_test.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/selftest/console.c b/drivers/staging/lustre/lnet/selftest/console.c index 17d0d132d103..6ec895208c26 100644 --- a/drivers/staging/lustre/lnet/selftest/console.c +++ b/drivers/staging/lustre/lnet/selftest/console.c @@ -733,7 +733,7 @@ lstcon_group_list(int index, int len, char __user *name_up) list_for_each_entry(grp, &console_session.ses_grp_list, grp_link) { if (!index--) { return copy_to_user(name_up, grp->grp_name, len) ? - -EFAULT : 0; + -EFAULT : 0; } } diff --git a/drivers/staging/lustre/lnet/selftest/ping_test.c b/drivers/staging/lustre/lnet/selftest/ping_test.c index 81a45045e186..438fca2e9b95 100644 --- a/drivers/staging/lustre/lnet/selftest/ping_test.c +++ b/drivers/staging/lustre/lnet/selftest/ping_test.c @@ -86,8 +86,8 @@ ping_client_fini(sfw_test_instance_t *tsi) } static int -ping_client_prep_rpc(sfw_test_unit_t *tsu, - lnet_process_id_t dest, srpc_client_rpc_t **rpc) +ping_client_prep_rpc(sfw_test_unit_t *tsu, lnet_process_id_t dest, + srpc_client_rpc_t **rpc) { srpc_ping_reqst_t *req; sfw_test_instance_t *tsi = tsu->tsu_instance; -- cgit v1.2.3 From dae0587ef0c8e6584837d3737fc5555eb2b36097 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Sat, 12 Mar 2016 13:00:36 -0500 Subject: staging: lustre: cleanup comment style for lnet selftest Apply a consistent style for comments in the lnet selftest code. Realign some of the comments to make it easier to read. This also fixes a few checkpatch issues as well. Signed-off-by: James Simmons Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/selftest/brw_test.c | 2 +- drivers/staging/lustre/lnet/selftest/conctl.c | 50 ++++++++++++------------ drivers/staging/lustre/lnet/selftest/conrpc.c | 17 ++++---- drivers/staging/lustre/lnet/selftest/console.c | 5 ++- drivers/staging/lustre/lnet/selftest/framework.c | 12 +++--- drivers/staging/lustre/lnet/selftest/ping_test.c | 2 +- drivers/staging/lustre/lnet/selftest/rpc.c | 8 ++-- drivers/staging/lustre/lnet/selftest/timer.c | 2 +- 8 files changed, 50 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/selftest/brw_test.c b/drivers/staging/lustre/lnet/selftest/brw_test.c index 69812fc3c9ed..b33c35694eb1 100644 --- a/drivers/staging/lustre/lnet/selftest/brw_test.c +++ b/drivers/staging/lustre/lnet/selftest/brw_test.c @@ -327,7 +327,7 @@ brw_client_done_rpc(sfw_test_unit_t *tsu, srpc_client_rpc_t *rpc) if (rpc->crpc_status) { CERROR("BRW RPC to %s failed with %d\n", libcfs_id2str(rpc->crpc_dest), rpc->crpc_status); - if (!tsi->tsi_stopping) /* rpc could have been aborted */ + if (!tsi->tsi_stopping) /* rpc could have been aborted */ atomic_inc(&sn->sn_brw_errors); return; } diff --git a/drivers/staging/lustre/lnet/selftest/conctl.c b/drivers/staging/lustre/lnet/selftest/conctl.c index 5c7cb72eac9a..6e2a81d8e730 100644 --- a/drivers/staging/lustre/lnet/selftest/conctl.c +++ b/drivers/staging/lustre/lnet/selftest/conctl.c @@ -51,9 +51,9 @@ lst_session_new_ioctl(lstio_session_new_args_t *args) char *name; int rc; - if (!args->lstio_ses_idp || /* address for output sid */ - !args->lstio_ses_key || /* no key is specified */ - !args->lstio_ses_namep || /* session name */ + if (!args->lstio_ses_idp || /* address for output sid */ + !args->lstio_ses_key || /* no key is specified */ + !args->lstio_ses_namep || /* session name */ args->lstio_ses_nmlen <= 0 || args->lstio_ses_nmlen > LST_NAME_SIZE) return -EINVAL; @@ -95,11 +95,11 @@ lst_session_info_ioctl(lstio_session_info_args_t *args) { /* no checking of key */ - if (!args->lstio_ses_idp || /* address for output sid */ - !args->lstio_ses_keyp || /* address for output key */ - !args->lstio_ses_featp || /* address for output features */ - !args->lstio_ses_ndinfo || /* address for output ndinfo */ - !args->lstio_ses_namep || /* address for output name */ + if (!args->lstio_ses_idp || /* address for output sid */ + !args->lstio_ses_keyp || /* address for output key */ + !args->lstio_ses_featp || /* address for output features */ + !args->lstio_ses_ndinfo || /* address for output ndinfo */ + !args->lstio_ses_namep || /* address for output name */ args->lstio_ses_nmlen <= 0 || args->lstio_ses_nmlen > LST_NAME_SIZE) return -EINVAL; @@ -125,7 +125,7 @@ lst_debug_ioctl(lstio_debug_args_t *args) if (!args->lstio_dbg_resultp) return -EINVAL; - if (args->lstio_dbg_namep && /* name of batch/group */ + if (args->lstio_dbg_namep && /* name of batch/group */ (args->lstio_dbg_nmlen <= 0 || args->lstio_dbg_nmlen > LST_NAME_SIZE)) return -EINVAL; @@ -326,7 +326,7 @@ lst_nodes_add_ioctl(lstio_group_nodes_args_t *args) if (args->lstio_grp_key != console_session.ses_key) return -EACCES; - if (!args->lstio_grp_idsp || /* array of ids */ + if (!args->lstio_grp_idsp || /* array of ids */ args->lstio_grp_count <= 0 || !args->lstio_grp_resultp || !args->lstio_grp_featp || @@ -394,13 +394,13 @@ lst_group_info_ioctl(lstio_group_info_args_t *args) args->lstio_grp_nmlen > LST_NAME_SIZE) return -EINVAL; - if (!args->lstio_grp_entp && /* output: group entry */ - !args->lstio_grp_dentsp) /* output: node entry */ + if (!args->lstio_grp_entp && /* output: group entry */ + !args->lstio_grp_dentsp) /* output: node entry */ return -EINVAL; - if (args->lstio_grp_dentsp) { /* have node entry */ - if (!args->lstio_grp_idxp || /* node index */ - !args->lstio_grp_ndentp) /* # of node entry */ + if (args->lstio_grp_dentsp) { /* have node entry */ + if (!args->lstio_grp_idxp || /* node index */ + !args->lstio_grp_ndentp) /* # of node entry */ return -EINVAL; if (copy_from_user(&ndent, args->lstio_grp_ndentp, @@ -612,18 +612,18 @@ lst_batch_info_ioctl(lstio_batch_info_args_t *args) if (args->lstio_bat_key != console_session.ses_key) return -EACCES; - if (!args->lstio_bat_namep || /* batch name */ + if (!args->lstio_bat_namep || /* batch name */ args->lstio_bat_nmlen <= 0 || args->lstio_bat_nmlen > LST_NAME_SIZE) return -EINVAL; - if (!args->lstio_bat_entp && /* output: batch entry */ - !args->lstio_bat_dentsp) /* output: node entry */ + if (!args->lstio_bat_entp && /* output: batch entry */ + !args->lstio_bat_dentsp) /* output: node entry */ return -EINVAL; - if (args->lstio_bat_dentsp) { /* have node entry */ - if (!args->lstio_bat_idxp || /* node index */ - !args->lstio_bat_ndentp) /* # of node entry */ + if (args->lstio_bat_dentsp) { /* have node entry */ + if (!args->lstio_bat_idxp || /* node index */ + !args->lstio_bat_ndentp) /* # of node entry */ return -EINVAL; if (copy_from_user(&index, args->lstio_bat_idxp, @@ -722,18 +722,18 @@ static int lst_test_add_ioctl(lstio_test_args_t *args) if (!args->lstio_tes_resultp || !args->lstio_tes_retp || - !args->lstio_tes_bat_name || /* no specified batch */ + !args->lstio_tes_bat_name || /* no specified batch */ args->lstio_tes_bat_nmlen <= 0 || args->lstio_tes_bat_nmlen > LST_NAME_SIZE || - !args->lstio_tes_sgrp_name || /* no source group */ + !args->lstio_tes_sgrp_name || /* no source group */ args->lstio_tes_sgrp_nmlen <= 0 || args->lstio_tes_sgrp_nmlen > LST_NAME_SIZE || - !args->lstio_tes_dgrp_name || /* no target group */ + !args->lstio_tes_dgrp_name || /* no target group */ args->lstio_tes_dgrp_nmlen <= 0 || args->lstio_tes_dgrp_nmlen > LST_NAME_SIZE) return -EINVAL; - if (!args->lstio_tes_loop || /* negative is infinite */ + if (!args->lstio_tes_loop || /* negative is infinite */ args->lstio_tes_concur <= 0 || args->lstio_tes_dist <= 0 || args->lstio_tes_span <= 0) diff --git a/drivers/staging/lustre/lnet/selftest/conrpc.c b/drivers/staging/lustre/lnet/selftest/conrpc.c index d11869aa5db4..3908c100ccb2 100644 --- a/drivers/staging/lustre/lnet/selftest/conrpc.c +++ b/drivers/staging/lustre/lnet/selftest/conrpc.c @@ -296,8 +296,8 @@ lstcon_rpc_trans_abort(lstcon_rpc_trans_t *trans, int error) spin_lock(&rpc->crpc_lock); - if (!crpc->crp_posted || /* not posted */ - crpc->crp_stamp) { /* rpc done or aborted already */ + if (!crpc->crp_posted || /* not posted */ + crpc->crp_stamp) { /* rpc done or aborted already */ if (!crpc->crp_stamp) { crpc->crp_stamp = cfs_time_current(); crpc->crp_status = -EINTR; @@ -562,10 +562,10 @@ lstcon_rpc_trans_destroy(lstcon_rpc_trans_t *trans) } /* - * rpcs can be still not callbacked (even LNetMDUnlink is called) - * because huge timeout for inaccessible network, don't make - * user wait for them, just abandon them, they will be recycled - * in callback + * rpcs can be still not callbacked (even LNetMDUnlink is + * called) because huge timeout for inaccessible network, + * don't make user wait for them, just abandon them, they + * will be recycled in callback */ LASSERT(crpc->crp_status); @@ -938,7 +938,7 @@ lstcon_sesnew_stat_reply(lstcon_rpc_trans_t *trans, if (!trans->tas_feats_updated) { spin_lock(&console_session.ses_rpc_lock); - if (!trans->tas_feats_updated) { /* recheck with lock */ + if (!trans->tas_feats_updated) { /* recheck with lock */ trans->tas_feats_updated = 1; trans->tas_features = reply->msg_ses_feats; } @@ -1178,7 +1178,8 @@ lstcon_rpc_pinger(void *arg) int count = 0; int rc; - /* RPC pinger is a special case of transaction, + /* + * RPC pinger is a special case of transaction, * it's called by timer at 8 seconds interval. */ mutex_lock(&console_session.ses_mutex); diff --git a/drivers/staging/lustre/lnet/selftest/console.c b/drivers/staging/lustre/lnet/selftest/console.c index 6ec895208c26..dcfc83d0ad41 100644 --- a/drivers/staging/lustre/lnet/selftest/console.c +++ b/drivers/staging/lustre/lnet/selftest/console.c @@ -277,7 +277,7 @@ lstcon_group_find(const char *name, lstcon_group_t **grpp) if (strncmp(grp->grp_name, name, LST_NAME_SIZE)) continue; - lstcon_group_addref(grp); /* +1 ref for caller */ + lstcon_group_addref(grp); /* +1 ref for caller */ *grpp = grp; return 0; } @@ -1446,7 +1446,8 @@ lstcon_test_batch_query(char *name, int testidx, int client, lstcon_rpc_trans_postwait(trans, timeout); - if (!testidx && /* query a batch, not a test */ + /* query a batch, not a test */ + if (!testidx && !lstcon_rpc_stat_failure(lstcon_trans_stat(), 0) && !lstcon_tsbqry_stat_run(lstcon_trans_stat(), 0)) { /* all RPCs finished, and no active test */ diff --git a/drivers/staging/lustre/lnet/selftest/framework.c b/drivers/staging/lustre/lnet/selftest/framework.c index 0f32f0be4edc..aa646a780f58 100644 --- a/drivers/staging/lustre/lnet/selftest/framework.c +++ b/drivers/staging/lustre/lnet/selftest/framework.c @@ -226,7 +226,7 @@ __must_hold(&sfw_data.fw_lock) } if (nactive) - return; /* wait for active batches to stop */ + return; /* wait for active batches to stop */ list_del_init(&sn->sn_list); spin_unlock(&sfw_data.fw_lock); @@ -693,7 +693,7 @@ sfw_unpack_addtest_req(srpc_msg_t *msg) LASSERT(req->tsr_is_client); if (msg->msg_magic == SRPC_MSG_MAGIC) - return; /* no flipping needed */ + return; /* no flipping needed */ LASSERT(msg->msg_magic == __swab32(SRPC_MSG_MAGIC)); @@ -789,7 +789,7 @@ sfw_add_test_instance(sfw_batch_t *tsb, struct srpc_server_rpc *rpc) int j; dests = page_address(bk->bk_iovs[i / SFW_ID_PER_PAGE].kiov_page); - LASSERT(dests); /* my pages are within KVM always */ + LASSERT(dests); /* my pages are within KVM always */ id = dests[i % SFW_ID_PER_PAGE]; if (msg->msg_magic != SRPC_MSG_MAGIC) sfw_unpack_id(id); @@ -844,8 +844,8 @@ sfw_test_unit_done(sfw_test_unit_t *tsu) spin_lock(&sfw_data.fw_lock); - if (!atomic_dec_and_test(&tsb->bat_nactive) ||/* tsb still active */ - sn == sfw_data.fw_session) { /* sn also active */ + if (!atomic_dec_and_test(&tsb->bat_nactive) || /* tsb still active */ + sn == sfw_data.fw_session) { /* sn also active */ spin_unlock(&sfw_data.fw_lock); return; } @@ -1273,7 +1273,7 @@ sfw_handle_server_rpc(struct srpc_server_rpc *rpc) } } else if (request->msg_ses_feats & ~LST_FEATS_MASK) { - /** + /* * NB: at this point, old version will ignore features and * create new session anyway, so console should be able * to handle this diff --git a/drivers/staging/lustre/lnet/selftest/ping_test.c b/drivers/staging/lustre/lnet/selftest/ping_test.c index 438fca2e9b95..c7c50be6dab4 100644 --- a/drivers/staging/lustre/lnet/selftest/ping_test.c +++ b/drivers/staging/lustre/lnet/selftest/ping_test.c @@ -129,7 +129,7 @@ ping_client_done_rpc(sfw_test_unit_t *tsu, srpc_client_rpc_t *rpc) LASSERT(sn); if (rpc->crpc_status) { - if (!tsi->tsi_stopping) /* rpc could have been aborted */ + if (!tsi->tsi_stopping) /* rpc could have been aborted */ atomic_inc(&sn->sn_ping_errors); CERROR("Unable to ping %s (%d): %d\n", libcfs_id2str(rpc->crpc_dest), diff --git a/drivers/staging/lustre/lnet/selftest/rpc.c b/drivers/staging/lustre/lnet/selftest/rpc.c index 69be7d6f48fa..ab8ba3724954 100644 --- a/drivers/staging/lustre/lnet/selftest/rpc.c +++ b/drivers/staging/lustre/lnet/selftest/rpc.c @@ -1332,8 +1332,8 @@ srpc_abort_rpc(srpc_client_rpc_t *rpc, int why) { LASSERT(why); - if (rpc->crpc_aborted || /* already aborted */ - rpc->crpc_closed) /* callback imminent */ + if (rpc->crpc_aborted || /* already aborted */ + rpc->crpc_closed) /* callback imminent */ return; CDEBUG(D_NET, "Aborting RPC: service %d, peer %s, state %s, why %d\n", @@ -1401,7 +1401,7 @@ srpc_send_reply(struct srpc_server_rpc *rpc) rpc->srpc_peer, rpc->srpc_self, &rpc->srpc_replymdh, ev); if (rc) - ev->ev_fired = 1; /* no more event expected */ + ev->ev_fired = 1; /* no more event expected */ return rc; } @@ -1509,7 +1509,7 @@ srpc_lnet_ev_handler(lnet_event_t *ev) scd->scd_buf_err = 0; } - if (!scd->scd_buf_err && /* adding buffer is enabled */ + if (!scd->scd_buf_err && /* adding buffer is enabled */ !scd->scd_buf_adjust && scd->scd_buf_nposted < scd->scd_buf_low) { scd->scd_buf_adjust = max(scd->scd_buf_total / 2, diff --git a/drivers/staging/lustre/lnet/selftest/timer.c b/drivers/staging/lustre/lnet/selftest/timer.c index ef8a8a748cbe..b6c4aae007af 100644 --- a/drivers/staging/lustre/lnet/selftest/timer.c +++ b/drivers/staging/lustre/lnet/selftest/timer.c @@ -49,7 +49,7 @@ * sorted by increasing expiry time. The number of slots is 2**7 (128), * to cover a time period of 1024 seconds into the future before wrapping. */ -#define STTIMER_MINPOLL 3 /* log2 min poll interval (8 s) */ +#define STTIMER_MINPOLL 3 /* log2 min poll interval (8 s) */ #define STTIMER_SLOTTIME (1 << STTIMER_MINPOLL) #define STTIMER_SLOTTIMEMASK (~(STTIMER_SLOTTIME - 1)) #define STTIMER_NSLOTS (1 << 7) -- cgit v1.2.3 From b899963f158056f19928ed5dc7314fac5b57db97 Mon Sep 17 00:00:00 2001 From: David Kershner Date: Fri, 11 Mar 2016 17:01:38 -0500 Subject: staging: unisys: visorbus: cleanup goto in setup_crash_devices_work_queue If visorbus has registered yet just reschedule and exit. The rest of the function doesn't need to reschedule so just move it up to the initial check. Signed-off-by: David Kershner Signed-off-by: Timothy Sell Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorbus/visorchipset.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/unisys/visorbus/visorchipset.c b/drivers/staging/unisys/visorbus/visorchipset.c index 5fbda7b218c7..3fd4bea6535d 100644 --- a/drivers/staging/unisys/visorbus/visorchipset.c +++ b/drivers/staging/unisys/visorbus/visorchipset.c @@ -1979,8 +1979,11 @@ setup_crash_devices_work_queue(struct work_struct *work) u16 local_crash_msg_count; /* make sure visorbus is registered for controlvm callbacks */ - if (visorchipset_visorbusregwait && !visorbusregistered) - goto cleanup; + if (visorchipset_visorbusregwait && !visorbusregistered) { + poll_jiffies = POLLJIFFIES_CONTROLVMCHANNEL_SLOW; + schedule_delayed_work(&periodic_controlvm_work, poll_jiffies); + return; + } POSTCODE_LINUX_2(CRASH_DEV_ENTRY_PC, POSTCODE_SEVERITY_INFO); @@ -2057,13 +2060,6 @@ setup_crash_devices_work_queue(struct work_struct *work) return; } POSTCODE_LINUX_2(CRASH_DEV_EXIT_PC, POSTCODE_SEVERITY_INFO); - return; - -cleanup: - - poll_jiffies = POLLJIFFIES_CONTROLVMCHANNEL_SLOW; - - schedule_delayed_work(&periodic_controlvm_work, poll_jiffies); } static void -- cgit v1.2.3 From dde29996cdb1514a457ffbfaaf8f795d66fe2a5a Mon Sep 17 00:00:00 2001 From: David Kershner Date: Fri, 11 Mar 2016 17:01:39 -0500 Subject: staging: unisys: visorbus: get rid of gotos in intialize_controlvm_payload_info Get rid of the gotos in initialize_controlvm_payload_info. The check in the error path if payload was valid was never called so get rid of that as well. Signed-off-by: David Kershner Signed-off-by: Timothy Sell Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorbus/visorchipset.c | 30 ++++++++------------------ 1 file changed, 9 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/unisys/visorbus/visorchipset.c b/drivers/staging/unisys/visorbus/visorchipset.c index 3fd4bea6535d..6ab659cbd6d5 100644 --- a/drivers/staging/unisys/visorbus/visorchipset.c +++ b/drivers/staging/unisys/visorbus/visorchipset.c @@ -1382,35 +1382,23 @@ initialize_controlvm_payload_info(u64 phys_addr, u64 offset, u32 bytes, struct visor_controlvm_payload_info *info) { u8 *payload = NULL; - int rc = CONTROLVM_RESP_SUCCESS; - if (!info) { - rc = -CONTROLVM_RESP_ERROR_PAYLOAD_INVALID; - goto cleanup; - } + if (!info) + return -CONTROLVM_RESP_ERROR_PAYLOAD_INVALID; + memset(info, 0, sizeof(struct visor_controlvm_payload_info)); - if ((offset == 0) || (bytes == 0)) { - rc = -CONTROLVM_RESP_ERROR_PAYLOAD_INVALID; - goto cleanup; - } + if ((offset == 0) || (bytes == 0)) + return -CONTROLVM_RESP_ERROR_PAYLOAD_INVALID; + payload = memremap(phys_addr + offset, bytes, MEMREMAP_WB); - if (!payload) { - rc = -CONTROLVM_RESP_ERROR_IOREMAP_FAILED; - goto cleanup; - } + if (!payload) + return -CONTROLVM_RESP_ERROR_IOREMAP_FAILED; info->offset = offset; info->bytes = bytes; info->ptr = payload; -cleanup: - if (rc < 0) { - if (payload) { - memunmap(payload); - payload = NULL; - } - } - return rc; + return CONTROLVM_RESP_SUCCESS; } static void -- cgit v1.2.3 From d79f56b59917fcd3e21190f281e07ebda628eb17 Mon Sep 17 00:00:00 2001 From: David Kershner Date: Fri, 11 Mar 2016 17:01:40 -0500 Subject: staging: unisys: visorbus: cleanup gotos in parser_init_byte_stream Clean up the goto in parser_init_byte_stream and make the goto section the error case. Signed-off-by: David Kershner Signed-off-by: Timothy Sell Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorbus/visorchipset.c | 39 +++++++++----------------- 1 file changed, 14 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/unisys/visorbus/visorchipset.c b/drivers/staging/unisys/visorbus/visorchipset.c index 6ab659cbd6d5..6598d6977263 100644 --- a/drivers/staging/unisys/visorbus/visorchipset.c +++ b/drivers/staging/unisys/visorbus/visorchipset.c @@ -359,8 +359,7 @@ static struct parser_context * parser_init_byte_stream(u64 addr, u32 bytes, bool local, bool *retry) { int allocbytes = sizeof(struct parser_context) + bytes; - struct parser_context *rc = NULL; - struct parser_context *ctx = NULL; + struct parser_context *ctx; if (retry) *retry = false; @@ -374,15 +373,13 @@ parser_init_byte_stream(u64 addr, u32 bytes, bool local, bool *retry) > MAX_CONTROLVM_PAYLOAD_BYTES) { if (retry) *retry = true; - rc = NULL; - goto cleanup; + return NULL; } ctx = kzalloc(allocbytes, GFP_KERNEL | __GFP_NORETRY); if (!ctx) { if (retry) *retry = true; - rc = NULL; - goto cleanup; + return NULL; } ctx->allocbytes = allocbytes; @@ -393,35 +390,27 @@ parser_init_byte_stream(u64 addr, u32 bytes, bool local, bool *retry) if (local) { void *p; - if (addr > virt_to_phys(high_memory - 1)) { - rc = NULL; - goto cleanup; - } + if (addr > virt_to_phys(high_memory - 1)) + goto err_finish_ctx; p = __va((unsigned long)(addr)); memcpy(ctx->data, p, bytes); } else { void *mapping = memremap(addr, bytes, MEMREMAP_WB); - if (!mapping) { - rc = NULL; - goto cleanup; - } + if (!mapping) + goto err_finish_ctx; memcpy(ctx->data, mapping, bytes); memunmap(mapping); } ctx->byte_stream = true; - rc = ctx; -cleanup: - if (rc) { - controlvm_payload_bytes_buffered += ctx->param_bytes; - } else { - if (ctx) { - parser_done(ctx); - ctx = NULL; - } - } - return rc; + controlvm_payload_bytes_buffered += ctx->param_bytes; + + return ctx; + +err_finish_ctx: + parser_done(ctx); + return NULL; } static uuid_le -- cgit v1.2.3 From 5233d1ebb6c99ca67521cdeb66dccd1256820d5f Mon Sep 17 00:00:00 2001 From: David Kershner Date: Fri, 11 Mar 2016 17:01:41 -0500 Subject: staging: unisys: visorbus: chipset_init rename goto Change the goto label "cleanup" to something more useful like out_respond. Signed-off-by: David Kershner Signed-off-by: Timothy Sell Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorbus/visorchipset.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/unisys/visorbus/visorchipset.c b/drivers/staging/unisys/visorbus/visorchipset.c index 6598d6977263..e278595d68e2 100644 --- a/drivers/staging/unisys/visorbus/visorchipset.c +++ b/drivers/staging/unisys/visorbus/visorchipset.c @@ -761,7 +761,7 @@ chipset_init(struct controlvm_message *inmsg) POSTCODE_LINUX_2(CHIPSET_INIT_ENTRY_PC, POSTCODE_SEVERITY_INFO); if (chipset_inited) { rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE; - goto cleanup; + goto out_respond; } chipset_inited = 1; POSTCODE_LINUX_2(CHIPSET_INIT_EXIT_PC, POSTCODE_SEVERITY_INFO); @@ -778,7 +778,7 @@ chipset_init(struct controlvm_message *inmsg) */ features |= ULTRA_CHIPSET_FEATURE_REPLY; -cleanup: +out_respond: if (inmsg->hdr.flags.response_expected) controlvm_respond_chipset_init(&inmsg->hdr, rc, features); } -- cgit v1.2.3 From 9fd04060abdfd1e2ec763ea0096cc91026c77cca Mon Sep 17 00:00:00 2001 From: David Kershner Date: Fri, 11 Mar 2016 17:01:42 -0500 Subject: staging: unisys: visorbus: Cleanup goto in bus_create Rename it to what it does instead of the default ambiguous cleanup. Signed-off-by: David Kershner Signed-off-by: Timothy Sell Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorbus/visorchipset.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/unisys/visorbus/visorchipset.c b/drivers/staging/unisys/visorbus/visorchipset.c index e278595d68e2..49d99229d241 100644 --- a/drivers/staging/unisys/visorbus/visorchipset.c +++ b/drivers/staging/unisys/visorbus/visorchipset.c @@ -1131,14 +1131,14 @@ bus_create(struct controlvm_message *inmsg) POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus_no, POSTCODE_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE; - goto cleanup; + goto out_bus_epilog; } bus_info = kzalloc(sizeof(*bus_info), GFP_KERNEL); if (!bus_info) { POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus_no, POSTCODE_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED; - goto cleanup; + goto out_bus_epilog; } INIT_LIST_HEAD(&bus_info->list_all); @@ -1158,7 +1158,7 @@ bus_create(struct controlvm_message *inmsg) rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED; kfree(bus_info); bus_info = NULL; - goto cleanup; + goto out_bus_epilog; } bus_info->visorchannel = visorchannel; if (uuid_le_cmp(cmd->create_bus.bus_inst_uuid, spar_siovm_uuid) == 0) { @@ -1168,7 +1168,7 @@ bus_create(struct controlvm_message *inmsg) POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC, bus_no, POSTCODE_SEVERITY_INFO); -cleanup: +out_bus_epilog: bus_epilog(bus_info, CONTROLVM_BUS_CREATE, &inmsg->hdr, rc, inmsg->hdr.flags.response_expected == 1); } -- cgit v1.2.3 From 368acb3f512b415d11bfc3801b4a3d1453cc455d Mon Sep 17 00:00:00 2001 From: David Kershner Date: Fri, 11 Mar 2016 17:01:43 -0500 Subject: staging: unisys: visorbus: Cleanup bus_epilog goto statements Cleaned up bus_epilogs vague gotos and in the process discovered some error paths that could unlock a non locked semaphore. Signed-off-by: David Kershner Signed-off-by: Timothy Sell Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorbus/visorchipset.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/unisys/visorbus/visorchipset.c b/drivers/staging/unisys/visorbus/visorchipset.c index 49d99229d241..b1c5e9e78679 100644 --- a/drivers/staging/unisys/visorbus/visorchipset.c +++ b/drivers/staging/unisys/visorbus/visorchipset.c @@ -962,25 +962,29 @@ bus_epilog(struct visor_device *bus_info, bool notified = false; struct controlvm_message_header *pmsg_hdr = NULL; + down(¬ifier_lock); + if (!bus_info) { /* relying on a valid passed in response code */ /* be lazy and re-use msg_hdr for this failure, is this ok?? */ pmsg_hdr = msg_hdr; - goto away; + goto out_respond_and_unlock; } if (bus_info->pending_msg_hdr) { /* only non-NULL if dev is still waiting on a response */ response = -CONTROLVM_RESP_ERROR_MESSAGE_ID_INVALID_FOR_CLIENT; pmsg_hdr = bus_info->pending_msg_hdr; - goto away; + goto out_respond_and_unlock; } if (need_response) { pmsg_hdr = kzalloc(sizeof(*pmsg_hdr), GFP_KERNEL); if (!pmsg_hdr) { - response = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED; - goto away; + POSTCODE_LINUX_4(MALLOC_FAILURE_PC, cmd, + bus_info->chipset_bus_no, + POSTCODE_SEVERITY_ERR); + goto out_unlock; } memcpy(pmsg_hdr, msg_hdr, @@ -988,7 +992,6 @@ bus_epilog(struct visor_device *bus_info, bus_info->pending_msg_hdr = pmsg_hdr; } - down(¬ifier_lock); if (response == CONTROLVM_RESP_SUCCESS) { switch (cmd) { case CONTROLVM_BUS_CREATE: @@ -1005,7 +1008,8 @@ bus_epilog(struct visor_device *bus_info, break; } } -away: + +out_respond_and_unlock: if (notified) /* The callback function just called above is responsible * for calling the appropriate visorchipset_busdev_responders @@ -1019,6 +1023,8 @@ away: * directly and kfree() there. */ bus_responder(cmd, pmsg_hdr, response); + +out_unlock: up(¬ifier_lock); } -- cgit v1.2.3 From c6af7a9cbcfa65b9322436836ad7cc323d2d5d6d Mon Sep 17 00:00:00 2001 From: David Kershner Date: Fri, 11 Mar 2016 17:01:44 -0500 Subject: staging: unisys: visorbus: fix my_create_device goto statements Don't use the abmiguous cleanup, make it more meaningful. Signed-off-by: David Kershner Signed-off-by: Timothy Sell Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorbus/visorchipset.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/unisys/visorbus/visorchipset.c b/drivers/staging/unisys/visorbus/visorchipset.c index b1c5e9e78679..17bedbc6761d 100644 --- a/drivers/staging/unisys/visorbus/visorchipset.c +++ b/drivers/staging/unisys/visorbus/visorchipset.c @@ -1255,14 +1255,14 @@ my_device_create(struct controlvm_message *inmsg) POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, POSTCODE_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_BUS_INVALID; - goto cleanup; + goto out_respond; } if (bus_info->state.created == 0) { POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, POSTCODE_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_BUS_INVALID; - goto cleanup; + goto out_respond; } dev_info = visorbus_get_device_by_id(bus_no, dev_no, NULL); @@ -1270,7 +1270,7 @@ my_device_create(struct controlvm_message *inmsg) POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, POSTCODE_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE; - goto cleanup; + goto out_respond; } dev_info = kzalloc(sizeof(*dev_info), GFP_KERNEL); @@ -1278,7 +1278,7 @@ my_device_create(struct controlvm_message *inmsg) POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, POSTCODE_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED; - goto cleanup; + goto out_respond; } dev_info->chipset_bus_no = bus_no; @@ -1303,7 +1303,7 @@ my_device_create(struct controlvm_message *inmsg) rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED; kfree(dev_info); dev_info = NULL; - goto cleanup; + goto out_respond; } dev_info->visorchannel = visorchannel; dev_info->channel_type_guid = cmd->create_device.data_type_uuid; @@ -1313,7 +1313,7 @@ my_device_create(struct controlvm_message *inmsg) POSTCODE_LINUX_4(DEVICE_CREATE_EXIT_PC, dev_no, bus_no, POSTCODE_SEVERITY_INFO); -cleanup: +out_respond: device_epilog(dev_info, segment_state_running, CONTROLVM_DEVICE_CREATE, &inmsg->hdr, rc, inmsg->hdr.flags.response_expected == 1, 1); -- cgit v1.2.3 From 4000622ec21ba5e93fdb74bc4168a9545a089ce7 Mon Sep 17 00:00:00 2001 From: David Kershner Date: Sat, 12 Mar 2016 21:27:08 -0500 Subject: staging: unisys: visorbus: Fix up visordriver_probe Fixup the visordriver_probe function. Rearrange the function to avoid needing gotos and removed unnecessary wmb(). Signed-off-by: David Kershner Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorbus/visorbus_main.c | 32 ++++++++++--------------- 1 file changed, 12 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c index 533bb5b3d284..6a12829151e0 100644 --- a/drivers/staging/unisys/visorbus/visorbus_main.c +++ b/drivers/staging/unisys/visorbus/visorbus_main.c @@ -752,36 +752,28 @@ dev_stop_periodic_work(struct visor_device *dev) static int visordriver_probe_device(struct device *xdev) { - int rc; + int res; struct visor_driver *drv; struct visor_device *dev; drv = to_visor_driver(xdev->driver); dev = to_visor_device(xdev); + + if (!drv->probe) + return -ENODEV; + down(&dev->visordriver_callback_lock); dev->being_removed = false; - /* - * ensure that the dev->being_removed flag is cleared before - * we start the probe - */ - wmb(); - get_device(&dev->device); - if (!drv->probe) { - up(&dev->visordriver_callback_lock); - rc = -ENODEV; - goto away; + + res = drv->probe(dev); + if (res >= 0) { + /* success: reference kept via unmatched get_device() */ + get_device(&dev->device); + fix_vbus_dev_info(dev); } - rc = drv->probe(dev); - if (rc < 0) - goto away; - fix_vbus_dev_info(dev); up(&dev->visordriver_callback_lock); - rc = 0; -away: - if (rc != 0) - put_device(&dev->device); - return rc; + return res; } /** This is called when device_unregister() is called for each child device -- cgit v1.2.3 From b750b05939778a8b43fc7e3c96a48f59d123451d Mon Sep 17 00:00:00 2001 From: Tim Sell Date: Sat, 12 Mar 2016 21:27:09 -0500 Subject: staging: unisys: visorbus: remove unused sysfs attribute devmajorminor/* The sysfs attribute directory at: /sys/bus/visorbus/devices/vbus:dev/devmajorminor/* or /sys/devices/visorbus/vbus:dev/devmajorminor/* previously provided a location where a visorbus function driver could publish information (for usermode use) about possibly-multiple major and minor device numbers for character devices created for a each visorbus device, using visorbus_registerdevnode(). This functionality is not currently used, so it has been removed by this cset. Signed-off-by: Tim Sell Signed-off-by: David Kershner Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/Documentation/overview.txt | 19 --- drivers/staging/unisys/include/visorbus.h | 3 - drivers/staging/unisys/visorbus/visorbus_main.c | 194 ---------------------- 3 files changed, 216 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/unisys/Documentation/overview.txt b/drivers/staging/unisys/Documentation/overview.txt index c2d8dd4a2e41..1146c1cf5c2a 100644 --- a/drivers/staging/unisys/Documentation/overview.txt +++ b/drivers/staging/unisys/Documentation/overview.txt @@ -137,12 +137,6 @@ called automatically by the visorbus driver at appropriate times: * The resume() function is the "book-end" to pause(), and is described above. -If/when a function driver creates a Linux device (that needs to be accessed -from usermode), it calls visorbus_registerdevnode(), passing the major and -minor number of the device. (Of course not all function drivers will need -to do this.) This simply creates the appropriate "devmajorminor" sysfs entry -described below, so that a hotplug script can use it to create a device node. - 2.1.3. sysfs Advertised Information ----------------------------------- @@ -197,19 +191,6 @@ The following files exist under /sys/devices/visorbus/vbus:dev: if the appropriate function driver has not been loaded yet. - devmajorminor - - if applicable, each file here identifies (via - ... its file contents) the - ":" needed for a device node to - enable access from usermode. There is exactly - one file here for each different device node - that can be accessed (from usermode). Note - that this info is provided by a particular - function driver, so these will not exist - until AFTER the appropriate function driver - controlling this device class is loaded. - channel properties of the device channel (all in ascii text format) diff --git a/drivers/staging/unisys/include/visorbus.h b/drivers/staging/unisys/include/visorbus.h index 2a64a9ce0208..9c47a138e748 100644 --- a/drivers/staging/unisys/include/visorbus.h +++ b/drivers/staging/unisys/include/visorbus.h @@ -136,7 +136,6 @@ struct visor_device { struct periodic_work *periodic_work; bool being_removed; bool responded_to_device_create; - struct kobject kobjdevmajorminor; /* visorbus/dev/devmajorminor/*/ struct { int major, minor; void *attr; /* private use by devmajorminor_attr.c you can @@ -174,8 +173,6 @@ int visorbus_write_channel(struct visor_device *dev, unsigned long nbytes); int visorbus_clear_channel(struct visor_device *dev, unsigned long offset, u8 ch, unsigned long nbytes); -int visorbus_registerdevnode(struct visor_device *dev, - const char *name, int major, int minor); void visorbus_enable_channel_interrupts(struct visor_device *dev); void visorbus_disable_channel_interrupts(struct visor_device *dev); #endif diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c index 6a12829151e0..813d29ea0c4e 100644 --- a/drivers/staging/unisys/visorbus/visorbus_main.c +++ b/drivers/staging/unisys/visorbus/visorbus_main.c @@ -243,180 +243,6 @@ visorbus_release_device(struct device *xdev) kfree(dev); } -/* Implement publishing of device node attributes under: - * - * /sys/bus/visorbus/dev/devmajorminor - * - */ - -#define to_devmajorminor_attr(_attr) \ - container_of(_attr, struct devmajorminor_attribute, attr) -#define to_visor_device_from_kobjdevmajorminor(obj) \ - container_of(obj, struct visor_device, kobjdevmajorminor) - -struct devmajorminor_attribute { - struct attribute attr; - int slot; - ssize_t (*show)(struct visor_device *, int slot, char *buf); - ssize_t (*store)(struct visor_device *, int slot, const char *buf, - size_t count); -}; - -static ssize_t DEVMAJORMINOR_ATTR(struct visor_device *dev, int slot, char *buf) -{ - int maxdevnodes = ARRAY_SIZE(dev->devnodes) / sizeof(dev->devnodes[0]); - - if (slot < 0 || slot >= maxdevnodes) - return 0; - return snprintf(buf, PAGE_SIZE, "%d:%d\n", - dev->devnodes[slot].major, dev->devnodes[slot].minor); -} - -static ssize_t -devmajorminor_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) -{ - struct devmajorminor_attribute *devmajorminor_attr = - to_devmajorminor_attr(attr); - struct visor_device *dev = to_visor_device_from_kobjdevmajorminor(kobj); - ssize_t ret = 0; - - if (devmajorminor_attr->show) - ret = devmajorminor_attr->show(dev, - devmajorminor_attr->slot, buf); - return ret; -} - -static ssize_t -devmajorminor_attr_store(struct kobject *kobj, - struct attribute *attr, const char *buf, size_t count) -{ - struct devmajorminor_attribute *devmajorminor_attr = - to_devmajorminor_attr(attr); - struct visor_device *dev = to_visor_device_from_kobjdevmajorminor(kobj); - ssize_t ret = 0; - - if (devmajorminor_attr->store) - ret = devmajorminor_attr->store(dev, - devmajorminor_attr->slot, - buf, count); - return ret; -} - -static int register_devmajorminor_attributes(struct visor_device *dev); - -static int -devmajorminor_create_file(struct visor_device *dev, const char *name, - int major, int minor) -{ - int maxdevnodes = ARRAY_SIZE(dev->devnodes) / sizeof(dev->devnodes[0]); - struct devmajorminor_attribute *myattr = NULL; - int x = -1, rc = 0, slot = -1; - - register_devmajorminor_attributes(dev); - for (slot = 0; slot < maxdevnodes; slot++) - if (!dev->devnodes[slot].attr) - break; - if (slot == maxdevnodes) { - rc = -ENOMEM; - goto away; - } - myattr = kzalloc(sizeof(*myattr), GFP_KERNEL); - if (!myattr) { - rc = -ENOMEM; - goto away; - } - myattr->show = DEVMAJORMINOR_ATTR; - myattr->store = NULL; - myattr->slot = slot; - myattr->attr.name = name; - myattr->attr.mode = S_IRUGO; - dev->devnodes[slot].attr = myattr; - dev->devnodes[slot].major = major; - dev->devnodes[slot].minor = minor; - x = sysfs_create_file(&dev->kobjdevmajorminor, &myattr->attr); - if (x < 0) { - rc = x; - goto away; - } - kobject_uevent(&dev->device.kobj, KOBJ_ONLINE); -away: - if (rc < 0) { - kfree(myattr); - myattr = NULL; - dev->devnodes[slot].attr = NULL; - } - return rc; -} - -static void -devmajorminor_remove_file(struct visor_device *dev, int slot) -{ - int maxdevnodes = ARRAY_SIZE(dev->devnodes) / sizeof(dev->devnodes[0]); - struct devmajorminor_attribute *myattr = NULL; - - if (slot < 0 || slot >= maxdevnodes) - return; - myattr = (struct devmajorminor_attribute *)(dev->devnodes[slot].attr); - if (!myattr) - return; - sysfs_remove_file(&dev->kobjdevmajorminor, &myattr->attr); - kobject_uevent(&dev->device.kobj, KOBJ_OFFLINE); - dev->devnodes[slot].attr = NULL; - kfree(myattr); -} - -static void -devmajorminor_remove_all_files(struct visor_device *dev) -{ - int i = 0; - int maxdevnodes = ARRAY_SIZE(dev->devnodes) / sizeof(dev->devnodes[0]); - - for (i = 0; i < maxdevnodes; i++) - devmajorminor_remove_file(dev, i); -} - -static const struct sysfs_ops devmajorminor_sysfs_ops = { - .show = devmajorminor_attr_show, - .store = devmajorminor_attr_store, -}; - -static struct kobj_type devmajorminor_kobj_type = { - .sysfs_ops = &devmajorminor_sysfs_ops -}; - -static int -register_devmajorminor_attributes(struct visor_device *dev) -{ - int rc = 0, x = 0; - - if (dev->kobjdevmajorminor.parent) - goto away; /* already registered */ - x = kobject_init_and_add(&dev->kobjdevmajorminor, - &devmajorminor_kobj_type, &dev->device.kobj, - "devmajorminor"); - if (x < 0) { - rc = x; - goto away; - } - - kobject_uevent(&dev->kobjdevmajorminor, KOBJ_ADD); - -away: - return rc; -} - -static void -unregister_devmajorminor_attributes(struct visor_device *dev) -{ - if (!dev->kobjdevmajorminor.parent) - return; /* already unregistered */ - devmajorminor_remove_all_files(dev); - - kobject_del(&dev->kobjdevmajorminor); - kobject_put(&dev->kobjdevmajorminor); - dev->kobjdevmajorminor.parent = NULL; -} - /* begin implementation of specific channel attributes to appear under * /sys/bus/visorbus/dev/channel */ @@ -801,7 +627,6 @@ visordriver_remove_device(struct device *xdev) } up(&dev->visordriver_callback_lock); dev_stop_periodic_work(dev); - devmajorminor_remove_all_files(dev); put_device(&dev->device); @@ -920,14 +745,6 @@ visorbus_clear_channel(struct visor_device *dev, unsigned long offset, u8 ch, } EXPORT_SYMBOL_GPL(visorbus_clear_channel); -int -visorbus_registerdevnode(struct visor_device *dev, - const char *name, int major, int minor) -{ - return devmajorminor_create_file(dev, name, major, minor); -} -EXPORT_SYMBOL_GPL(visorbus_registerdevnode); - /** We don't really have a real interrupt, so for now we just call the * interrupt function periodically... */ @@ -1018,19 +835,9 @@ create_visor_device(struct visor_device *dev) goto away; } - rc = register_devmajorminor_attributes(dev); - if (rc < 0) { - POSTCODE_LINUX_3(DEVICE_REGISTER_FAILURE_PC, chipset_dev_no, - DIAG_SEVERITY_ERR); - goto away_unregister; - } - list_add_tail(&dev->list_all, &list_all_device_instances); return 0; -away_unregister: - device_unregister(&dev->device); - away: put_device(&dev->device); return rc; @@ -1040,7 +847,6 @@ static void remove_visor_device(struct visor_device *dev) { list_del(&dev->list_all); - unregister_devmajorminor_attributes(dev); put_device(&dev->device); device_unregister(&dev->device); } -- cgit v1.2.3 From 78af1aef662eef4ffac6f453fdc46d3389274f34 Mon Sep 17 00:00:00 2001 From: David Kershner Date: Sat, 12 Mar 2016 21:27:10 -0500 Subject: staging: unisys: visorbus: fix up gotos in visorbus_init This patch fixes the gotos in visorbus_init Signed-off-by: David Kershner Signed-off-by: Timothy Sell Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorbus/visorbus_main.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c index 813d29ea0c4e..816a16dea763 100644 --- a/drivers/staging/unisys/visorbus/visorbus_main.c +++ b/drivers/staging/unisys/visorbus/visorbus_main.c @@ -1275,24 +1275,24 @@ struct channel_size_info { int visorbus_init(void) { - int rc = 0; + int err; - POSTCODE_LINUX_3(DRIVER_ENTRY_PC, rc, POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX_3(DRIVER_ENTRY_PC, 0, POSTCODE_SEVERITY_INFO); bus_device_info_init(&clientbus_driverinfo, "clientbus", "visorbus", VERSION, NULL); - rc = create_bus_type(); - if (rc < 0) { + err = create_bus_type(); + if (err < 0) { POSTCODE_LINUX_2(BUS_CREATE_ENTRY_PC, DIAG_SEVERITY_ERR); - goto away; + goto error; } periodic_dev_workqueue = create_singlethread_workqueue("visorbus_dev"); if (!periodic_dev_workqueue) { POSTCODE_LINUX_2(CREATE_WORKQUEUE_PC, DIAG_SEVERITY_ERR); - rc = -ENOMEM; - goto away; + err = -ENOMEM; + goto error; } /* This enables us to receive notifications when devices appear for @@ -1302,13 +1302,11 @@ visorbus_init(void) &chipset_responders, &chipset_driverinfo); - rc = 0; + return 0; -away: - if (rc) - POSTCODE_LINUX_3(CHIPSET_INIT_FAILURE_PC, rc, - POSTCODE_SEVERITY_ERR); - return rc; +error: + POSTCODE_LINUX_3(CHIPSET_INIT_FAILURE_PC, err, POSTCODE_SEVERITY_ERR); + return err; } void -- cgit v1.2.3 From 8e33f48c9585c82258c8bef1d93149ca27f8d91d Mon Sep 17 00:00:00 2001 From: David Kershner Date: Sat, 12 Mar 2016 21:27:11 -0500 Subject: staging: unisys: visorbus: Remove gotos in visorbus_match Gotos in visorbus_match are not needed. Signed-off-by: David Kershner Signed-off-by: Timothy Sell Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorbus/visorbus_main.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c index 816a16dea763..b31c44f8043f 100644 --- a/drivers/staging/unisys/visorbus/visorbus_main.c +++ b/drivers/staging/unisys/visorbus/visorbus_main.c @@ -182,7 +182,6 @@ static int visorbus_match(struct device *xdev, struct device_driver *xdrv) { uuid_le channel_type; - int rc = 0; int i; struct visor_device *dev; struct visor_driver *drv; @@ -190,26 +189,23 @@ visorbus_match(struct device *xdev, struct device_driver *xdrv) dev = to_visor_device(xdev); drv = to_visor_driver(xdrv); channel_type = visorchannel_get_uuid(dev->visorchannel); - if (visorbus_forcematch) { - rc = 1; - goto away; - } - if (visorbus_forcenomatch) - goto away; + if (visorbus_forcematch) + return 1; + if (visorbus_forcenomatch) + return 0; if (!drv->channel_types) - goto away; + return 0; + for (i = 0; (uuid_le_cmp(drv->channel_types[i].guid, NULL_UUID_LE) != 0) || (drv->channel_types[i].name); i++) if (uuid_le_cmp(drv->channel_types[i].guid, - channel_type) == 0) { - rc = i + 1; - goto away; - } -away: - return rc; + channel_type) == 0) + return i + 1; + + return 0; } /** This is called when device_unregister() is called for the bus device -- cgit v1.2.3 From 0b2acf34f3680c4b0857625af667dcd53d39028e Mon Sep 17 00:00:00 2001 From: David Kershner Date: Sat, 12 Mar 2016 21:27:12 -0500 Subject: staging: unisys: visorbus: rename create_visor_device gotos Away is ambiguous when specifying error vs success. Make return labels more meaningful by marking them as error paths. Signed-off-by: David Kershner Signed-off-by: Timothy Sell Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorbus/visorbus_main.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c index b31c44f8043f..54d77dd26be0 100644 --- a/drivers/staging/unisys/visorbus/visorbus_main.c +++ b/drivers/staging/unisys/visorbus/visorbus_main.c @@ -775,7 +775,7 @@ EXPORT_SYMBOL_GPL(visorbus_disable_channel_interrupts); static int create_visor_device(struct visor_device *dev) { - int rc; + int err; u32 chipset_bus_no = dev->chipset_bus_no; u32 chipset_dev_no = dev->chipset_dev_no; @@ -797,8 +797,8 @@ create_visor_device(struct visor_device *dev) if (!dev->periodic_work) { POSTCODE_LINUX_3(DEVICE_CREATE_FAILURE_PC, chipset_dev_no, DIAG_SEVERITY_ERR); - rc = -EINVAL; - goto away; + err = -EINVAL; + goto err_put; } /* bus_id must be a unique name with respect to this bus TYPE @@ -824,19 +824,19 @@ create_visor_device(struct visor_device *dev) * claim the device. The device will be linked onto * bus_type.klist_devices regardless (use bus_for_each_dev). */ - rc = device_add(&dev->device); - if (rc < 0) { + err = device_add(&dev->device); + if (err < 0) { POSTCODE_LINUX_3(DEVICE_ADD_PC, chipset_bus_no, DIAG_SEVERITY_ERR); - goto away; + goto err_put; } list_add_tail(&dev->list_all, &list_all_device_instances); - return 0; + return 0; /* success: reference kept via unmatched get_device() */ -away: +err_put: put_device(&dev->device); - return rc; + return err; } static void -- cgit v1.2.3 From 437ba274b5e5c813c2cede7051701ff3f0959022 Mon Sep 17 00:00:00 2001 From: Eva Rachel Retuya Date: Sat, 12 Mar 2016 16:19:20 +0800 Subject: staging: iio: tsl2x7x_core: adjust alignment to match open parenthesis Align the parameters to match open parenthesis. Issue detected using checkpatch. CHECK: Alignment should match open parenthesis Signed-off-by: Eva Rachel Retuya Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/light/tsl2x7x_core.c | 164 +++++++++++++++++-------------- 1 file changed, 92 insertions(+), 72 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/light/tsl2x7x_core.c b/drivers/staging/iio/light/tsl2x7x_core.c index 5f308bae41b9..4948791b2cd7 100644 --- a/drivers/staging/iio/light/tsl2x7x_core.c +++ b/drivers/staging/iio/light/tsl2x7x_core.c @@ -349,13 +349,13 @@ static int tsl2x7x_get_lux(struct iio_dev *indio_dev) if (chip->tsl2x7x_chip_status != TSL2X7X_CHIP_WORKING) { /* device is not enabled */ dev_err(&chip->client->dev, "%s: device is not enabled\n", - __func__); + __func__); ret = -EBUSY; goto out_unlock; } ret = tsl2x7x_i2c_read(chip->client, - (TSL2X7X_CMD_REG | TSL2X7X_STATUS), &buf[0]); + (TSL2X7X_CMD_REG | TSL2X7X_STATUS), &buf[0]); if (ret < 0) { dev_err(&chip->client->dev, "%s: Failed to read STATUS Reg\n", __func__); @@ -371,8 +371,8 @@ static int tsl2x7x_get_lux(struct iio_dev *indio_dev) for (i = 0; i < 4; i++) { ret = tsl2x7x_i2c_read(chip->client, - (TSL2X7X_CMD_REG | (TSL2X7X_ALS_CHAN0LO + i)), - &buf[i]); + (TSL2X7X_CMD_REG | + (TSL2X7X_ALS_CHAN0LO + i)), &buf[i]); if (ret < 0) { dev_err(&chip->client->dev, "failed to read. err=%x\n", ret); @@ -382,9 +382,9 @@ static int tsl2x7x_get_lux(struct iio_dev *indio_dev) /* clear any existing interrupt status */ ret = i2c_smbus_write_byte(chip->client, - (TSL2X7X_CMD_REG | - TSL2X7X_CMD_SPL_FN | - TSL2X7X_CMD_ALS_INT_CLR)); + (TSL2X7X_CMD_REG | + TSL2X7X_CMD_SPL_FN | + TSL2X7X_CMD_ALS_INT_CLR)); if (ret < 0) { dev_err(&chip->client->dev, "i2c_write_command failed - err = %d\n", ret); @@ -488,7 +488,7 @@ static int tsl2x7x_get_prox(struct iio_dev *indio_dev) } ret = tsl2x7x_i2c_read(chip->client, - (TSL2X7X_CMD_REG | TSL2X7X_STATUS), &status); + (TSL2X7X_CMD_REG | TSL2X7X_STATUS), &status); if (ret < 0) { dev_err(&chip->client->dev, "i2c err=%d\n", ret); goto prox_poll_err; @@ -515,8 +515,8 @@ static int tsl2x7x_get_prox(struct iio_dev *indio_dev) for (i = 0; i < 2; i++) { ret = tsl2x7x_i2c_read(chip->client, - (TSL2X7X_CMD_REG | - (TSL2X7X_PRX_LO + i)), &chdata[i]); + (TSL2X7X_CMD_REG | + (TSL2X7X_PRX_LO + i)), &chdata[i]); if (ret < 0) goto prox_poll_err; } @@ -542,19 +542,19 @@ static void tsl2x7x_defaults(struct tsl2X7X_chip *chip) { /* If Operational settings defined elsewhere.. */ if (chip->pdata && chip->pdata->platform_default_settings) - memcpy(&(chip->tsl2x7x_settings), - chip->pdata->platform_default_settings, - sizeof(tsl2x7x_default_settings)); + memcpy(&chip->tsl2x7x_settings, + chip->pdata->platform_default_settings, + sizeof(tsl2x7x_default_settings)); else - memcpy(&(chip->tsl2x7x_settings), - &tsl2x7x_default_settings, - sizeof(tsl2x7x_default_settings)); + memcpy(&chip->tsl2x7x_settings, + &tsl2x7x_default_settings, + sizeof(tsl2x7x_default_settings)); /* Load up the proper lux table. */ if (chip->pdata && chip->pdata->platform_lux_table[0].ratio != 0) memcpy(chip->tsl2x7x_device_lux, - chip->pdata->platform_lux_table, - sizeof(chip->pdata->platform_lux_table)); + chip->pdata->platform_lux_table, + sizeof(chip->pdata->platform_lux_table)); else memcpy(chip->tsl2x7x_device_lux, (struct tsl2x7x_lux *)tsl2x7x_default_lux_table_group[chip->id], @@ -576,7 +576,7 @@ static int tsl2x7x_als_calibrate(struct iio_dev *indio_dev) int lux_val; ret = i2c_smbus_write_byte(chip->client, - (TSL2X7X_CMD_REG | TSL2X7X_CNTRL)); + (TSL2X7X_CMD_REG | TSL2X7X_CNTRL)); if (ret < 0) { dev_err(&chip->client->dev, "failed to write CNTRL register, ret=%d\n", ret); @@ -592,7 +592,7 @@ static int tsl2x7x_als_calibrate(struct iio_dev *indio_dev) } ret = i2c_smbus_write_byte(chip->client, - (TSL2X7X_CMD_REG | TSL2X7X_CNTRL)); + (TSL2X7X_CMD_REG | TSL2X7X_CNTRL)); if (ret < 0) { dev_err(&chip->client->dev, "failed to write ctrl reg: ret=%d\n", ret); @@ -609,7 +609,7 @@ static int tsl2x7x_als_calibrate(struct iio_dev *indio_dev) lux_val = tsl2x7x_get_lux(indio_dev); if (lux_val < 0) { dev_err(&chip->client->dev, - "%s: failed to get lux\n", __func__); + "%s: failed to get lux\n", __func__); return lux_val; } @@ -620,7 +620,7 @@ static int tsl2x7x_als_calibrate(struct iio_dev *indio_dev) chip->tsl2x7x_settings.als_gain_trim = gain_trim_val; dev_info(&chip->client->dev, - "%s als_calibrate completed\n", chip->client->name); + "%s als_calibrate completed\n", chip->client->name); return (int) gain_trim_val; } @@ -699,7 +699,7 @@ static int tsl2x7x_chip_on(struct iio_dev *indio_dev) * Power on the device 1st. */ utmp = TSL2X7X_CNTL_PWR_ON; ret = i2c_smbus_write_byte_data(chip->client, - TSL2X7X_CMD_REG | TSL2X7X_CNTRL, utmp); + TSL2X7X_CMD_REG | TSL2X7X_CNTRL, utmp); if (ret < 0) { dev_err(&chip->client->dev, "%s: failed on CNTRL reg.\n", __func__); @@ -711,7 +711,8 @@ static int tsl2x7x_chip_on(struct iio_dev *indio_dev) for (i = 0, dev_reg = chip->tsl2x7x_config; i < TSL2X7X_MAX_CONFIG_REG; i++) { ret = i2c_smbus_write_byte_data(chip->client, - TSL2X7X_CMD_REG + i, *dev_reg++); + TSL2X7X_CMD_REG + i, + *dev_reg++); if (ret < 0) { dev_err(&chip->client->dev, "failed on write to reg %d.\n", i); @@ -727,7 +728,7 @@ static int tsl2x7x_chip_on(struct iio_dev *indio_dev) TSL2X7X_CNTL_ADC_ENBL | TSL2X7X_CNTL_PROX_DET_ENBL; ret = i2c_smbus_write_byte_data(chip->client, - TSL2X7X_CMD_REG | TSL2X7X_CNTRL, utmp); + TSL2X7X_CMD_REG | TSL2X7X_CNTRL, utmp); if (ret < 0) { dev_err(&chip->client->dev, "%s: failed on 2nd CTRL reg.\n", __func__); @@ -741,12 +742,13 @@ static int tsl2x7x_chip_on(struct iio_dev *indio_dev) reg_val = TSL2X7X_CNTL_PWR_ON | TSL2X7X_CNTL_ADC_ENBL; if ((chip->tsl2x7x_settings.interrupts_en == 0x20) || - (chip->tsl2x7x_settings.interrupts_en == 0x30)) + (chip->tsl2x7x_settings.interrupts_en == 0x30)) reg_val |= TSL2X7X_CNTL_PROX_DET_ENBL; reg_val |= chip->tsl2x7x_settings.interrupts_en; ret = i2c_smbus_write_byte_data(chip->client, - (TSL2X7X_CMD_REG | TSL2X7X_CNTRL), reg_val); + (TSL2X7X_CMD_REG | + TSL2X7X_CNTRL), reg_val); if (ret < 0) dev_err(&chip->client->dev, "%s: failed in tsl2x7x_IOCTL_INT_SET.\n", @@ -754,8 +756,9 @@ static int tsl2x7x_chip_on(struct iio_dev *indio_dev) /* Clear out any initial interrupts */ ret = i2c_smbus_write_byte(chip->client, - TSL2X7X_CMD_REG | TSL2X7X_CMD_SPL_FN | - TSL2X7X_CMD_PROXALS_INT_CLR); + TSL2X7X_CMD_REG | + TSL2X7X_CMD_SPL_FN | + TSL2X7X_CMD_PROXALS_INT_CLR); if (ret < 0) { dev_err(&chip->client->dev, "%s: Failed to clear Int status\n", @@ -776,7 +779,7 @@ static int tsl2x7x_chip_off(struct iio_dev *indio_dev) chip->tsl2x7x_chip_status = TSL2X7X_CHIP_SUSPENDED; ret = i2c_smbus_write_byte_data(chip->client, - TSL2X7X_CMD_REG | TSL2X7X_CNTRL, 0x00); + TSL2X7X_CMD_REG | TSL2X7X_CNTRL, 0x00); if (chip->pdata && chip->pdata->power_off) chip->pdata->power_off(chip->client); @@ -819,7 +822,7 @@ int tsl2x7x_invoke_change(struct iio_dev *indio_dev) static void tsl2x7x_prox_calculate(int *data, int length, - struct tsl2x7x_prox_stat *statP) + struct tsl2x7x_prox_stat *statP) { int i; int sample_sum; @@ -886,20 +889,21 @@ static void tsl2x7x_prox_cal(struct iio_dev *indio_dev) tsl2x7x_get_prox(indio_dev); prox_history[i] = chip->prox_data; dev_info(&chip->client->dev, "2 i=%d prox data= %d\n", - i, chip->prox_data); + i, chip->prox_data); } tsl2x7x_chip_off(indio_dev); calP = &prox_stat_data[PROX_STAT_CAL]; tsl2x7x_prox_calculate(prox_history, - chip->tsl2x7x_settings.prox_max_samples_cal, calP); + chip->tsl2x7x_settings.prox_max_samples_cal, + calP); chip->tsl2x7x_settings.prox_thres_high = (calP->max << 1) - calP->mean; dev_info(&chip->client->dev, " cal min=%d mean=%d max=%d\n", - calP->min, calP->mean, calP->max); + calP->min, calP->mean, calP->max); dev_info(&chip->client->dev, - "%s proximity threshold set to %d\n", - chip->client->name, chip->tsl2x7x_settings.prox_thres_high); + "%s proximity threshold set to %d\n", + chip->client->name, chip->tsl2x7x_settings.prox_thres_high); /* back to the way they were */ chip->tsl2x7x_settings.interrupts_en = tmp_irq_settings; @@ -908,7 +912,8 @@ static void tsl2x7x_prox_cal(struct iio_dev *indio_dev) } static ssize_t tsl2x7x_power_state_show(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev)); @@ -916,7 +921,8 @@ static ssize_t tsl2x7x_power_state_show(struct device *dev, } static ssize_t tsl2x7x_power_state_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t len) + struct device_attribute *attr, + const char *buf, size_t len) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); bool value; @@ -933,7 +939,8 @@ static ssize_t tsl2x7x_power_state_store(struct device *dev, } static ssize_t tsl2x7x_gain_available_show(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev)); @@ -950,13 +957,15 @@ static ssize_t tsl2x7x_gain_available_show(struct device *dev, } static ssize_t tsl2x7x_prox_gain_available_show(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { return snprintf(buf, PAGE_SIZE, "%s\n", "1 2 4 8"); } static ssize_t tsl2x7x_als_time_show(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev)); int y, z; @@ -970,7 +979,8 @@ static ssize_t tsl2x7x_als_time_show(struct device *dev, } static ssize_t tsl2x7x_als_time_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t len) + struct device_attribute *attr, + const char *buf, size_t len) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct tsl2X7X_chip *chip = iio_priv(indio_dev); @@ -986,7 +996,7 @@ static ssize_t tsl2x7x_als_time_store(struct device *dev, TSL2X7X_MAX_TIMER_CNT - (u8)result.fract; dev_info(&chip->client->dev, "%s: als time = %d", - __func__, chip->tsl2x7x_settings.als_time); + __func__, chip->tsl2x7x_settings.als_time); tsl2x7x_invoke_change(indio_dev); @@ -997,7 +1007,8 @@ static IIO_CONST_ATTR(in_illuminance0_integration_time_available, ".00272 - .696"); static ssize_t tsl2x7x_als_cal_target_show(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev)); @@ -1006,7 +1017,8 @@ static ssize_t tsl2x7x_als_cal_target_show(struct device *dev, } static ssize_t tsl2x7x_als_cal_target_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t len) + struct device_attribute *attr, + const char *buf, size_t len) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct tsl2X7X_chip *chip = iio_priv(indio_dev); @@ -1025,7 +1037,8 @@ static ssize_t tsl2x7x_als_cal_target_store(struct device *dev, /* persistence settings */ static ssize_t tsl2x7x_als_persistence_show(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev)); int y, z, filter_delay; @@ -1041,7 +1054,8 @@ static ssize_t tsl2x7x_als_persistence_show(struct device *dev, } static ssize_t tsl2x7x_als_persistence_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t len) + struct device_attribute *attr, + const char *buf, size_t len) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct tsl2X7X_chip *chip = iio_priv(indio_dev); @@ -1063,7 +1077,7 @@ static ssize_t tsl2x7x_als_persistence_store(struct device *dev, chip->tsl2x7x_settings.persistence |= (filter_delay & 0x0F); dev_info(&chip->client->dev, "%s: als persistence = %d", - __func__, filter_delay); + __func__, filter_delay); tsl2x7x_invoke_change(indio_dev); @@ -1071,7 +1085,8 @@ static ssize_t tsl2x7x_als_persistence_store(struct device *dev, } static ssize_t tsl2x7x_prox_persistence_show(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev)); int y, z, filter_delay; @@ -1087,7 +1102,8 @@ static ssize_t tsl2x7x_prox_persistence_show(struct device *dev, } static ssize_t tsl2x7x_prox_persistence_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t len) + struct device_attribute *attr, + const char *buf, size_t len) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct tsl2X7X_chip *chip = iio_priv(indio_dev); @@ -1109,7 +1125,7 @@ static ssize_t tsl2x7x_prox_persistence_store(struct device *dev, chip->tsl2x7x_settings.persistence |= ((filter_delay << 4) & 0xF0); dev_info(&chip->client->dev, "%s: prox persistence = %d", - __func__, filter_delay); + __func__, filter_delay); tsl2x7x_invoke_change(indio_dev); @@ -1117,7 +1133,8 @@ static ssize_t tsl2x7x_prox_persistence_store(struct device *dev, } static ssize_t tsl2x7x_do_calibrate(struct device *dev, - struct device_attribute *attr, const char *buf, size_t len) + struct device_attribute *attr, + const char *buf, size_t len) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); bool value; @@ -1134,7 +1151,8 @@ static ssize_t tsl2x7x_do_calibrate(struct device *dev, } static ssize_t tsl2x7x_luxtable_show(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev)); int i = 0; @@ -1159,7 +1177,8 @@ static ssize_t tsl2x7x_luxtable_show(struct device *dev, } static ssize_t tsl2x7x_luxtable_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t len) + struct device_attribute *attr, + const char *buf, size_t len) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct tsl2X7X_chip *chip = iio_priv(indio_dev); @@ -1175,7 +1194,7 @@ static ssize_t tsl2x7x_luxtable_store(struct device *dev, */ n = value[0]; if ((n % 3) || n < 6 || - n > ((ARRAY_SIZE(chip->tsl2x7x_device_lux) - 1) * 3)) { + n > ((ARRAY_SIZE(chip->tsl2x7x_device_lux) - 1) * 3)) { dev_info(dev, "LUX TABLE INPUT ERROR 1 Value[0]=%d\n", n); return -EINVAL; } @@ -1198,7 +1217,8 @@ static ssize_t tsl2x7x_luxtable_store(struct device *dev, } static ssize_t tsl2x7x_do_prox_calibrate(struct device *dev, - struct device_attribute *attr, const char *buf, size_t len) + struct device_attribute *attr, + const char *buf, size_t len) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); bool value; @@ -1391,10 +1411,10 @@ static int tsl2x7x_read_raw(struct iio_dev *indio_dev, } static int tsl2x7x_write_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int val, - int val2, - long mask) + struct iio_chan_spec const *chan, + int val, + int val2, + long mask) { struct tsl2X7X_chip *chip = iio_priv(indio_dev); @@ -1529,7 +1549,7 @@ static irqreturn_t tsl2x7x_event_handler(int irq, void *private) u8 value; value = i2c_smbus_read_byte_data(chip->client, - TSL2X7X_CMD_REG | TSL2X7X_STATUS); + TSL2X7X_CMD_REG | TSL2X7X_STATUS); /* What type of interrupt do we need to process */ if (value & TSL2X7X_STA_PRX_INTR) { @@ -1545,16 +1565,16 @@ static irqreturn_t tsl2x7x_event_handler(int irq, void *private) if (value & TSL2X7X_STA_ALS_INTR) { tsl2x7x_get_lux(indio_dev); /* freshen data for ABI */ iio_push_event(indio_dev, - IIO_UNMOD_EVENT_CODE(IIO_LIGHT, - 0, - IIO_EV_TYPE_THRESH, - IIO_EV_DIR_EITHER), - timestamp); + IIO_UNMOD_EVENT_CODE(IIO_LIGHT, + 0, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_EITHER), + timestamp); } /* Clear interrupt now that we have handled it. */ ret = i2c_smbus_write_byte(chip->client, - TSL2X7X_CMD_REG | TSL2X7X_CMD_SPL_FN | - TSL2X7X_CMD_PROXALS_INT_CLR); + TSL2X7X_CMD_REG | TSL2X7X_CMD_SPL_FN | + TSL2X7X_CMD_PROXALS_INT_CLR); if (ret < 0) dev_err(&chip->client->dev, "Failed to clear irq from event handler. err = %d\n", @@ -1857,7 +1877,7 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = { }; static int tsl2x7x_probe(struct i2c_client *clientp, - const struct i2c_device_id *id) + const struct i2c_device_id *id) { int ret; unsigned char device_id; @@ -1873,14 +1893,14 @@ static int tsl2x7x_probe(struct i2c_client *clientp, i2c_set_clientdata(clientp, indio_dev); ret = tsl2x7x_i2c_read(chip->client, - TSL2X7X_CHIPID, &device_id); + TSL2X7X_CHIPID, &device_id); if (ret < 0) return ret; if ((!tsl2x7x_device_id(&device_id, id->driver_data)) || - (tsl2x7x_device_id(&device_id, id->driver_data) == -EINVAL)) { + (tsl2x7x_device_id(&device_id, id->driver_data) == -EINVAL)) { dev_info(&chip->client->dev, - "%s: i2c device found does not match expected id\n", + "%s: i2c device found does not match expected id\n", __func__); return -EINVAL; } -- cgit v1.2.3 From 2cbc8b34ef9fd081a4ae90460b9e26756ddebfe4 Mon Sep 17 00:00:00 2001 From: Eva Rachel Retuya Date: Sat, 12 Mar 2016 16:19:21 +0800 Subject: staging: iio: tsl2x7x_core: use preferred comment style Adjust block comments by adding the necessary trailing */ on a separate line. Checkpatch found this issue. Signed-off-by: Eva Rachel Retuya Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/light/tsl2x7x_core.c | 38 +++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/light/tsl2x7x_core.c b/drivers/staging/iio/light/tsl2x7x_core.c index 4948791b2cd7..de069be7f8f5 100644 --- a/drivers/staging/iio/light/tsl2x7x_core.c +++ b/drivers/staging/iio/light/tsl2x7x_core.c @@ -187,9 +187,11 @@ struct tsl2X7X_chip { const struct tsl2x7x_chip_info *chip_info; const struct iio_info *info; s64 event_timestamp; - /* This structure is intentionally large to accommodate - * updates via sysfs. */ - /* Sized to 9 = max 8 segments + 1 termination segment */ + /* + * This structure is intentionally large to accommodate + * updates via sysfs. + * Sized to 9 = max 8 segments + 1 termination segment + */ struct tsl2x7x_lux tsl2x7x_device_lux[TSL2X7X_MAX_LUX_TABLE_SIZE]; }; @@ -695,8 +697,10 @@ static int tsl2x7x_chip_on(struct iio_dev *indio_dev) chip->als_saturation = als_count * 922; /* 90% of full scale */ chip->als_time_scale = (als_time + 25) / 50; - /* TSL2X7X Specific power-on / adc enable sequence - * Power on the device 1st. */ + /* + * TSL2X7X Specific power-on / adc enable sequence + * Power on the device 1st. + */ utmp = TSL2X7X_CNTL_PWR_ON; ret = i2c_smbus_write_byte_data(chip->client, TSL2X7X_CMD_REG | TSL2X7X_CNTRL, utmp); @@ -706,8 +710,10 @@ static int tsl2x7x_chip_on(struct iio_dev *indio_dev) return ret; } - /* Use the following shadow copy for our delay before enabling ADC. - * Write all the registers. */ + /* + * Use the following shadow copy for our delay before enabling ADC. + * Write all the registers. + */ for (i = 0, dev_reg = chip->tsl2x7x_config; i < TSL2X7X_MAX_CONFIG_REG; i++) { ret = i2c_smbus_write_byte_data(chip->client, @@ -722,8 +728,10 @@ static int tsl2x7x_chip_on(struct iio_dev *indio_dev) mdelay(3); /* Power-on settling time */ - /* NOW enable the ADC - * initialize the desired mode of operation */ + /* + * NOW enable the ADC + * initialize the desired mode of operation + */ utmp = TSL2X7X_CNTL_PWR_ON | TSL2X7X_CNTL_ADC_ENBL | TSL2X7X_CNTL_PROX_DET_ENBL; @@ -1164,8 +1172,10 @@ static ssize_t tsl2x7x_luxtable_show(struct device *dev, chip->tsl2x7x_device_lux[i].ch0, chip->tsl2x7x_device_lux[i].ch1); if (chip->tsl2x7x_device_lux[i].ratio == 0) { - /* We just printed the first "0" entry. - * Now get rid of the extra "," and break. */ + /* + * We just printed the first "0" entry. + * Now get rid of the extra "," and break. + */ offset--; break; } @@ -1912,8 +1922,10 @@ static int tsl2x7x_probe(struct i2c_client *clientp, return ret; } - /* ALS and PROX functions can be invoked via user space poll - * or H/W interrupt. If busy return last sample. */ + /* + * ALS and PROX functions can be invoked via user space poll + * or H/W interrupt. If busy return last sample. + */ mutex_init(&chip->als_mutex); mutex_init(&chip->prox_mutex); -- cgit v1.2.3 From 54a0cd3e5757e6cbec63911f234190287ebeca29 Mon Sep 17 00:00:00 2001 From: Eva Rachel Retuya Date: Sat, 12 Mar 2016 16:19:22 +0800 Subject: staging: iio: tsl2x7x_core: remove space after a cast Delete unneeded space after a cast as suggested by checkpatch. CHECK: No space is necessary after a cast. Signed-off-by: Eva Rachel Retuya Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/light/tsl2x7x_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/light/tsl2x7x_core.c b/drivers/staging/iio/light/tsl2x7x_core.c index de069be7f8f5..6291a71d9565 100644 --- a/drivers/staging/iio/light/tsl2x7x_core.c +++ b/drivers/staging/iio/light/tsl2x7x_core.c @@ -413,7 +413,7 @@ static int tsl2x7x_get_lux(struct iio_dev *indio_dev) /* calculate ratio */ ratio = (ch1 << 15) / ch0; /* convert to unscaled lux using the pointer to the table */ - p = (struct tsl2x7x_lux *) chip->tsl2x7x_device_lux; + p = (struct tsl2x7x_lux *)chip->tsl2x7x_device_lux; while (p->ratio != 0 && p->ratio < ratio) p++; @@ -624,7 +624,7 @@ static int tsl2x7x_als_calibrate(struct iio_dev *indio_dev) dev_info(&chip->client->dev, "%s als_calibrate completed\n", chip->client->name); - return (int) gain_trim_val; + return (int)gain_trim_val; } static int tsl2x7x_chip_on(struct iio_dev *indio_dev) -- cgit v1.2.3 From 95066a028b6bf9a1f4c6fcb69fab8474952bc858 Mon Sep 17 00:00:00 2001 From: Eva Rachel Retuya Date: Sat, 12 Mar 2016 16:19:23 +0800 Subject: staging: iio: tsl2x7x_core: add spaces around operators Address the checkpatch check by adding the necessary whitespace around operators: CHECK: spaces preferred around that '/' (ctx:VxV) Signed-off-by: Eva Rachel Retuya Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/light/tsl2x7x_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/light/tsl2x7x_core.c b/drivers/staging/iio/light/tsl2x7x_core.c index 6291a71d9565..a72bb2912622 100644 --- a/drivers/staging/iio/light/tsl2x7x_core.c +++ b/drivers/staging/iio/light/tsl2x7x_core.c @@ -854,7 +854,7 @@ void tsl2x7x_prox_calculate(int *data, int length, tmp = data[i] - statP->mean; sample_sum += tmp * tmp; } - statP->stddev = int_sqrt((long)sample_sum)/length; + statP->stddev = int_sqrt((long)sample_sum) / length; } /** @@ -1192,7 +1192,7 @@ static ssize_t tsl2x7x_luxtable_store(struct device *dev, { struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct tsl2X7X_chip *chip = iio_priv(indio_dev); - int value[ARRAY_SIZE(chip->tsl2x7x_device_lux)*3 + 1]; + int value[ARRAY_SIZE(chip->tsl2x7x_device_lux) * 3 + 1]; int n; get_options(buf, ARRAY_SIZE(value), value); -- cgit v1.2.3 From b026338289d65ef6fddfefcf5d1ba7932bc77c8a Mon Sep 17 00:00:00 2001 From: Eva Rachel Retuya Date: Sat, 12 Mar 2016 16:19:24 +0800 Subject: staging: iio: tsl2x7x_core: add blank line after struct declaration Add the missing blank line after struct declaration. Checkpatch found this issue. CHECK: Please use a blank line after function/struct/union/enum declarations Signed-off-by: Eva Rachel Retuya Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/light/tsl2x7x_core.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/iio/light/tsl2x7x_core.c b/drivers/staging/iio/light/tsl2x7x_core.c index a72bb2912622..d553c8e18fcc 100644 --- a/drivers/staging/iio/light/tsl2x7x_core.c +++ b/drivers/staging/iio/light/tsl2x7x_core.c @@ -1646,6 +1646,7 @@ static struct attribute *tsl2X7X_ALS_event_attrs[] = { &dev_attr_in_intensity0_thresh_period.attr, NULL, }; + static struct attribute *tsl2X7X_PRX_event_attrs[] = { &dev_attr_in_proximity0_thresh_period.attr, NULL, -- cgit v1.2.3 From 5e3d1d520ffccb956a5b00c8a858416747869058 Mon Sep 17 00:00:00 2001 From: Alison Schofield Date: Sun, 13 Mar 2016 23:11:30 -0700 Subject: staging: iio: meter: remove fixme comment on device remove This comment was in place in the original drafts of these drivers when the remove function did a whole lot of work: flushed queues, unregistered interrupts, uninitialized rings, unconfigured rings, and a few kfree's. The remove functions have since been reduced to unregistering and stopping the device. This is the inverse of what was done during probe and is correct. Time to remove the comment. Signed-off-by: Alison Schofield Acked-by: Daniel Baluta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/meter/ade7753.c | 1 - drivers/staging/iio/meter/ade7754.c | 1 - drivers/staging/iio/meter/ade7759.c | 1 - 3 files changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c index 69287108f793..b0bc99a958c5 100644 --- a/drivers/staging/iio/meter/ade7753.c +++ b/drivers/staging/iio/meter/ade7753.c @@ -528,7 +528,6 @@ static int ade7753_probe(struct spi_device *spi) return iio_device_register(indio_dev); } -/* fixme, confirm ordering in this function */ static int ade7753_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c index f4188e17d30b..fed11804d548 100644 --- a/drivers/staging/iio/meter/ade7754.c +++ b/drivers/staging/iio/meter/ade7754.c @@ -558,7 +558,6 @@ powerdown_on_error: return ret; } -/* fixme, confirm ordering in this function */ static int ade7754_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c index 684e612a88b9..c14892db7e4c 100644 --- a/drivers/staging/iio/meter/ade7759.c +++ b/drivers/staging/iio/meter/ade7759.c @@ -476,7 +476,6 @@ static int ade7759_probe(struct spi_device *spi) return iio_device_register(indio_dev); } -/* fixme, confirm ordering in this function */ static int ade7759_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); -- cgit v1.2.3 From 7b58e2402f965c97c191570e187fa107230d09b4 Mon Sep 17 00:00:00 2001 From: Alison Schofield Date: Sun, 13 Mar 2016 23:13:49 -0700 Subject: staging: iio: ad5933: use dev_get_platdata() Use dev_get_platdata() for retrieving the platform data instead of accessing dev->platform_data directly. Signed-off-by: Alison Schofield Acked-by: Daniel Baluta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/impedance-analyzer/ad5933.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index d1218d896725..428587433c4a 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c @@ -699,7 +699,7 @@ static int ad5933_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret, voltage_uv = 0; - struct ad5933_platform_data *pdata = client->dev.platform_data; + struct ad5933_platform_data *pdata = dev_get_platdata(&client->dev); struct ad5933_state *st; struct iio_dev *indio_dev; -- cgit v1.2.3 From e279ee89d349af16fc7b77f4d715cd2826ac8249 Mon Sep 17 00:00:00 2001 From: Alison Schofield Date: Sun, 13 Mar 2016 23:15:51 -0700 Subject: staging: iio: io-trig-bfin-timer: use dev_get_platdata() Use dev_get_platdata() for retrieving the platform data instead of accessing dev->platform_data directly. Move the assignment out of the declaration (avoid lines over 80 char and put it close to usage). Signed-off-by: Alison Schofield Acked-by: Daniel Baluta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/trigger/iio-trig-bfin-timer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c index 035dd456d7d6..8667334f3f41 100644 --- a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c +++ b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c @@ -178,7 +178,7 @@ static const struct iio_trigger_ops iio_bfin_tmr_trigger_ops = { static int iio_bfin_tmr_trigger_probe(struct platform_device *pdev) { - struct iio_bfin_timer_trigger_pdata *pdata = pdev->dev.platform_data; + struct iio_bfin_timer_trigger_pdata *pdata; struct bfin_tmr_state *st; unsigned int config; int ret; @@ -221,6 +221,7 @@ static int iio_bfin_tmr_trigger_probe(struct platform_device *pdev) config = PWM_OUT | PERIOD_CNT | IRQ_ENA; + pdata = dev_get_platdata(&pdev->dev); if (pdata && pdata->output_enable) { unsigned long long val; -- cgit v1.2.3 From f5d82ad9bca2df8204c9b47748cbf1c5f3eb691d Mon Sep 17 00:00:00 2001 From: Alison Schofield Date: Wed, 16 Mar 2016 23:59:19 -0700 Subject: staging: iio: ad5933: move contents of header file to source file The contents of the header file are used only by this single source file. Move content into .c and remove .h. Signed-off-by: Alison Schofield Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/impedance-analyzer/ad5933.c | 14 +++++++++++-- drivers/staging/iio/impedance-analyzer/ad5933.h | 28 ------------------------- 2 files changed, 12 insertions(+), 30 deletions(-) delete mode 100644 drivers/staging/iio/impedance-analyzer/ad5933.h (limited to 'drivers') diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index 428587433c4a..f2c305cfdfc3 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c @@ -24,8 +24,6 @@ #include #include -#include "ad5933.h" - /* AD5933/AD5934 Registers */ #define AD5933_REG_CONTROL_HB 0x80 /* R/W, 2 bytes */ #define AD5933_REG_CONTROL_LB 0x81 /* R/W, 2 bytes */ @@ -86,6 +84,18 @@ #define AD5933_POLL_TIME_ms 10 #define AD5933_INIT_EXCITATION_TIME_ms 100 +/** + * struct ad5933_platform_data - platform specific data + * @ext_clk_Hz: the external clock frequency in Hz, if not set + * the driver uses the internal clock (16.776 MHz) + * @vref_mv: the external reference voltage in millivolt + */ + +struct ad5933_platform_data { + unsigned long ext_clk_Hz; + unsigned short vref_mv; +}; + struct ad5933_state { struct i2c_client *client; struct regulator *reg; diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.h b/drivers/staging/iio/impedance-analyzer/ad5933.h deleted file mode 100644 index b140e42d67cf..000000000000 --- a/drivers/staging/iio/impedance-analyzer/ad5933.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * AD5933 AD5934 Impedance Converter, Network Analyzer - * - * Copyright 2011 Analog Devices Inc. - * - * Licensed under the GPL-2. - */ - -#ifndef IIO_ADC_AD5933_H_ -#define IIO_ADC_AD5933_H_ - -/* - * TODO: struct ad5933_platform_data needs to go into include/linux/iio - */ - -/** - * struct ad5933_platform_data - platform specific data - * @ext_clk_Hz: the external clock frequency in Hz, if not set - * the driver uses the internal clock (16.776 MHz) - * @vref_mv: the external reference voltage in millivolt - */ - -struct ad5933_platform_data { - unsigned long ext_clk_Hz; - unsigned short vref_mv; -}; - -#endif /* IIO_ADC_AD5933_H_ */ -- cgit v1.2.3 From 5359ada246eb651679b80cfaa036c1d1ebcd0896 Mon Sep 17 00:00:00 2001 From: Alison Schofield Date: Thu, 17 Mar 2016 00:00:20 -0700 Subject: staging: iio: ad5933: remove unused #includes Remove #includes no longer used in this module. Signed-off-by: Alison Schofield Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/impedance-analyzer/ad5933.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index f2c305cfdfc3..af3a19045363 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c @@ -12,12 +12,10 @@ #include #include #include -#include #include #include #include #include -#include #include #include -- cgit v1.2.3 From 0eea4ce3f4be3253206ca7bb84a458cea0c41e01 Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Mon, 21 Mar 2016 13:11:15 +0530 Subject: Staging: iio: ade7758_core: Fix open parentheses alignment issues. Fix open parentheses alignment issues. Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/meter/ade7758_core.c | 73 ++++++++++++-------------------- 1 file changed, 26 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c index 40f5afaa984b..d6e35c76ad09 100644 --- a/drivers/staging/iio/meter/ade7758_core.c +++ b/drivers/staging/iio/meter/ade7758_core.c @@ -24,9 +24,7 @@ #include "meter.h" #include "ade7758.h" -int ade7758_spi_write_reg_8(struct device *dev, - u8 reg_address, - u8 val) +int ade7758_spi_write_reg_8(struct device *dev, u8 reg_address, u8 val) { int ret; struct iio_dev *indio_dev = dev_to_iio_dev(dev); @@ -42,9 +40,8 @@ int ade7758_spi_write_reg_8(struct device *dev, return ret; } -static int ade7758_spi_write_reg_16(struct device *dev, - u8 reg_address, - u16 value) +static int ade7758_spi_write_reg_16(struct device *dev, u8 reg_address, + u16 value) { int ret; struct iio_dev *indio_dev = dev_to_iio_dev(dev); @@ -68,9 +65,8 @@ static int ade7758_spi_write_reg_16(struct device *dev, return ret; } -static int ade7758_spi_write_reg_24(struct device *dev, - u8 reg_address, - u32 value) +static int ade7758_spi_write_reg_24(struct device *dev, u8 reg_address, + u32 value) { int ret; struct iio_dev *indio_dev = dev_to_iio_dev(dev); @@ -95,9 +91,7 @@ static int ade7758_spi_write_reg_24(struct device *dev, return ret; } -int ade7758_spi_read_reg_8(struct device *dev, - u8 reg_address, - u8 *val) +int ade7758_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7758_state *st = iio_priv(indio_dev); @@ -124,7 +118,7 @@ int ade7758_spi_read_reg_8(struct device *dev, ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers)); if (ret) { dev_err(&st->us->dev, "problem when reading 8 bit register 0x%02X", - reg_address); + reg_address); goto error_ret; } *val = st->rx[0]; @@ -134,9 +128,8 @@ error_ret: return ret; } -static int ade7758_spi_read_reg_16(struct device *dev, - u8 reg_address, - u16 *val) +static int ade7758_spi_read_reg_16(struct device *dev, u8 reg_address, + u16 *val) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7758_state *st = iio_priv(indio_dev); @@ -165,7 +158,7 @@ static int ade7758_spi_read_reg_16(struct device *dev, ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers)); if (ret) { dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X", - reg_address); + reg_address); goto error_ret; } @@ -176,9 +169,8 @@ error_ret: return ret; } -static int ade7758_spi_read_reg_24(struct device *dev, - u8 reg_address, - u32 *val) +static int ade7758_spi_read_reg_24(struct device *dev, u8 reg_address, + u32 *val) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7758_state *st = iio_priv(indio_dev); @@ -207,7 +199,7 @@ static int ade7758_spi_read_reg_24(struct device *dev, ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers)); if (ret) { dev_err(&st->us->dev, "problem when reading 24 bit register 0x%02X", - reg_address); + reg_address); goto error_ret; } *val = (st->rx[0] << 16) | (st->rx[1] << 8) | st->rx[2]; @@ -218,8 +210,7 @@ error_ret: } static ssize_t ade7758_read_8bit(struct device *dev, - struct device_attribute *attr, - char *buf) + struct device_attribute *attr, char *buf) { int ret; u8 val = 0; @@ -233,8 +224,7 @@ static ssize_t ade7758_read_8bit(struct device *dev, } static ssize_t ade7758_read_16bit(struct device *dev, - struct device_attribute *attr, - char *buf) + struct device_attribute *attr, char *buf) { int ret; u16 val = 0; @@ -248,8 +238,7 @@ static ssize_t ade7758_read_16bit(struct device *dev, } static ssize_t ade7758_read_24bit(struct device *dev, - struct device_attribute *attr, - char *buf) + struct device_attribute *attr, char *buf) { int ret; u32 val = 0; @@ -263,9 +252,8 @@ static ssize_t ade7758_read_24bit(struct device *dev, } static ssize_t ade7758_write_8bit(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) + struct device_attribute *attr, + const char *buf, size_t len) { struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); int ret; @@ -281,9 +269,8 @@ error_ret: } static ssize_t ade7758_write_16bit(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) + struct device_attribute *attr, + const char *buf, size_t len) { struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); int ret; @@ -479,16 +466,13 @@ err_ret: } static ssize_t ade7758_read_frequency(struct device *dev, - struct device_attribute *attr, - char *buf) + struct device_attribute *attr, char *buf) { int ret; u8 t; int sps; - ret = ade7758_spi_read_reg_8(dev, - ADE7758_WAVMODE, - &t); + ret = ade7758_spi_read_reg_8(dev, ADE7758_WAVMODE, &t); if (ret) return ret; @@ -499,9 +483,8 @@ static ssize_t ade7758_read_frequency(struct device *dev, } static ssize_t ade7758_write_frequency(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) + struct device_attribute *attr, + const char *buf, size_t len) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); u16 val; @@ -532,18 +515,14 @@ static ssize_t ade7758_write_frequency(struct device *dev, goto out; } - ret = ade7758_spi_read_reg_8(dev, - ADE7758_WAVMODE, - ®); + ret = ade7758_spi_read_reg_8(dev, ADE7758_WAVMODE, ®); if (ret) goto out; reg &= ~(5 << 3); reg |= t << 5; - ret = ade7758_spi_write_reg_8(dev, - ADE7758_WAVMODE, - reg); + ret = ade7758_spi_write_reg_8(dev, ADE7758_WAVMODE, reg); out: mutex_unlock(&indio_dev->mlock); -- cgit v1.2.3 From 929d2691f202c1904db5a8a471636e030eaef570 Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Mon, 21 Mar 2016 13:13:46 +0530 Subject: Staging: iio: ade7758_core: Remove unnecessary blank line. Remove unnecessary blank line. Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/meter/ade7758_core.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c index d6e35c76ad09..310296573e52 100644 --- a/drivers/staging/iio/meter/ade7758_core.c +++ b/drivers/staging/iio/meter/ade7758_core.c @@ -149,7 +149,6 @@ static int ade7758_spi_read_reg_16(struct device *dev, u8 reg_address, }, }; - mutex_lock(&st->buf_lock); st->tx[0] = ADE7758_READ_REG(reg_address); st->tx[1] = 0; -- cgit v1.2.3 From 93636775b9b68f239cf6a100f9148c0936dbd02e Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Mon, 21 Mar 2016 13:15:13 +0530 Subject: Staging: iio: ade7758: Use a blank line after function/struct declarations. Use a blank line after function/struct declarations. Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/meter/ade7758.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/iio/meter/ade7758.h b/drivers/staging/iio/meter/ade7758.h index f6739e2c24b1..ff7c7641546c 100644 --- a/drivers/staging/iio/meter/ade7758.h +++ b/drivers/staging/iio/meter/ade7758.h @@ -129,6 +129,7 @@ struct ade7758_state { unsigned char tx_buf[8]; }; + #ifdef CONFIG_IIO_BUFFER /* At the moment triggers are only used for ring buffer * filling. This may change! @@ -157,6 +158,7 @@ int ade7758_spi_read_reg_8(struct device *dev, static inline void ade7758_remove_trigger(struct iio_dev *indio_dev) { } + static inline int ade7758_probe_trigger(struct iio_dev *indio_dev) { return 0; @@ -166,16 +168,20 @@ static int ade7758_configure_ring(struct iio_dev *indio_dev) { return 0; } + static inline void ade7758_unconfigure_ring(struct iio_dev *indio_dev) { } + static inline int ade7758_initialize_ring(struct iio_ring_buffer *ring) { return 0; } + static inline void ade7758_uninitialize_ring(struct iio_dev *indio_dev) { } + #endif /* CONFIG_IIO_BUFFER */ #endif -- cgit v1.2.3 From 04e1f7b9b0b24b0d2fb669ea8fdce429478da72f Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Mon, 21 Mar 2016 13:17:01 +0530 Subject: Staging: iio: ade7758: Fix open parentheses alignment issues. Fix open parentheses alignment issues. Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/meter/ade7758.h | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/meter/ade7758.h b/drivers/staging/iio/meter/ade7758.h index ff7c7641546c..1d04ec9524c8 100644 --- a/drivers/staging/iio/meter/ade7758.h +++ b/drivers/staging/iio/meter/ade7758.h @@ -139,19 +139,15 @@ void ade7758_remove_trigger(struct iio_dev *indio_dev); int ade7758_probe_trigger(struct iio_dev *indio_dev); ssize_t ade7758_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf); - + struct device_attribute *attr, char *buf); int ade7758_configure_ring(struct iio_dev *indio_dev); void ade7758_unconfigure_ring(struct iio_dev *indio_dev); int ade7758_set_irq(struct device *dev, bool enable); -int ade7758_spi_write_reg_8(struct device *dev, - u8 reg_address, u8 val); -int ade7758_spi_read_reg_8(struct device *dev, - u8 reg_address, u8 *val); +int ade7758_spi_write_reg_8(struct device *dev, u8 reg_address, u8 val); +int ade7758_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val); #else /* CONFIG_IIO_BUFFER */ -- cgit v1.2.3 From 7df7ee9be9801a7d0c73e9a4ef3e4912aef8b083 Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Mon, 21 Mar 2016 17:19:44 +0530 Subject: Staging: iio: ad5933: Remove unnecessary space after cast. Remove unnecessary space after cast. Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/impedance-analyzer/ad5933.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index af3a19045363..620b33a61a2d 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c @@ -315,10 +315,10 @@ static ssize_t ad5933_show_frequency(struct device *dev, freqreg = be32_to_cpu(dat.d32) & 0xFFFFFF; - freqreg = (u64) freqreg * (u64) (st->mclk_hz / 4); + freqreg = (u64)freqreg * (u64)(st->mclk_hz / 4); do_div(freqreg, 1 << 27); - return sprintf(buf, "%d\n", (int) freqreg); + return sprintf(buf, "%d\n", (int)freqreg); } static ssize_t ad5933_store_frequency(struct device *dev, @@ -366,7 +366,7 @@ static ssize_t ad5933_show(struct device *dev, int ret = 0, len = 0; mutex_lock(&indio_dev->mlock); - switch ((u32) this_attr->address) { + switch ((u32)this_attr->address) { case AD5933_OUT_RANGE: len = sprintf(buf, "%u\n", st->range_avail[(st->ctrl_hb >> 1) & 0x3]); @@ -417,7 +417,7 @@ static ssize_t ad5933_store(struct device *dev, } mutex_lock(&indio_dev->mlock); - switch ((u32) this_attr->address) { + switch ((u32)this_attr->address) { case AD5933_OUT_RANGE: for (i = 0; i < 4; i++) if (val == st->range_avail[i]) { -- cgit v1.2.3 From afb105549d4879018e45bbf77e76034237d8fc20 Mon Sep 17 00:00:00 2001 From: PrasannaKumar Muralidharan Date: Sat, 12 Mar 2016 14:03:09 +0530 Subject: Staging: most: Remove atomic_counter_t typedef Remove atomic_counter_t typedef, use int instead. Signed-off-by: PrasannaKumar Muralidharan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/hdm-dim2/dim2_hal.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.h b/drivers/staging/most/hdm-dim2/dim2_hal.h index fc73d4f97734..9f8e88028181 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.h +++ b/drivers/staging/most/hdm-dim2/dim2_hal.h @@ -42,14 +42,12 @@ struct dim_ch_state_t { u16 done_buffers; /* Number of completed buffers */ }; -typedef int atomic_counter_t; - struct int_ch_state { /* changed only in interrupt context */ - volatile atomic_counter_t request_counter; + volatile int request_counter; /* changed only in task context */ - volatile atomic_counter_t service_counter; + volatile int service_counter; u8 idx1; u8 idx2; -- cgit v1.2.3 From 514dd88df707a1094e937c20d5a0b1ec619e1f96 Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Sat, 12 Mar 2016 15:01:04 +0530 Subject: staging: slicoss: Add error check for pci_map_single Currently, DMA mapping failure is not detected, causing the hardware to attempt a DMA from an invalid address. This patch adds the corresponding error check for pci_map_single i.e. pci_dma_mapping_error. Problem found using the following Coccinelle semantic patch: // @@ expression e1; identifier x; @@ x= ( *dma_map_single(...) | *dma_map_page(...) ) ... when != dma_mapping_error(e1,x) @@ expression e1; identifier x; @@ x = ( *pci_map_single(...) | *pci_map_page(...) ) ... when != pci_dma_mapping_error(e1,x) // Signed-off-by: Amitoj Kaur Chawla Signed-off-by: Greg Kroah-Hartman --- drivers/staging/slicoss/slicoss.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index 6d50fc4fd02e..fa61e8e9964b 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -1855,6 +1855,11 @@ static void slic_xmit_build_request(struct adapter *adapter, ihcmd->u.slic_buffers.totlen = skb->len; phys_addr = pci_map_single(adapter->pcidev, skb->data, skb->len, PCI_DMA_TODEVICE); + if (pci_dma_mapping_error(adapter->pcidev, phys_addr)) { + kfree_skb(skb); + dev_err(&adapter->pcidev->dev, "DMA mapping error\n"); + return; + } ihcmd->u.slic_buffers.bufs[0].paddrl = SLIC_GET_ADDR_LOW(phys_addr); ihcmd->u.slic_buffers.bufs[0].paddrh = SLIC_GET_ADDR_HIGH(phys_addr); ihcmd->u.slic_buffers.bufs[0].length = skb->len; -- cgit v1.2.3 From c2598d468f3cccb1266a8ffe1a0d7268ff2d8eb4 Mon Sep 17 00:00:00 2001 From: Laura Garcia Liebana Date: Sat, 12 Mar 2016 16:03:50 +0100 Subject: staging: octeon: Use type int instead of int32_t Prefer the use of type int instead of int32_t. Checkpatch detected these issues. Signed-off-by: Laura Garcia Liebana Signed-off-by: Greg Kroah-Hartman --- drivers/staging/octeon/ethernet-tx.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/octeon/ethernet-tx.c b/drivers/staging/octeon/ethernet-tx.c index ffe9bd77a7bb..93f65589f72a 100644 --- a/drivers/staging/octeon/ethernet-tx.c +++ b/drivers/staging/octeon/ethernet-tx.c @@ -58,9 +58,9 @@ static DECLARE_TASKLET(cvm_oct_tx_cleanup_tasklet, cvm_oct_tx_do_cleanup, 0); /* Maximum number of SKBs to try to free per xmit packet. */ #define MAX_SKB_TO_FREE (MAX_OUT_QUEUE_DEPTH * 2) -static inline int32_t cvm_oct_adjust_skb_to_free(int32_t skb_to_free, int fau) +static inline int cvm_oct_adjust_skb_to_free(int skb_to_free, int fau) { - int32_t undo; + int undo; undo = skb_to_free > 0 ? MAX_SKB_TO_FREE : skb_to_free + MAX_SKB_TO_FREE; @@ -83,7 +83,7 @@ static void cvm_oct_kick_tx_poll_watchdog(void) static void cvm_oct_free_tx_skbs(struct net_device *dev) { - int32_t skb_to_free; + int skb_to_free; int qos, queues_per_port; int total_freed = 0; int total_remaining = 0; @@ -148,8 +148,8 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev) enum {QUEUE_CORE, QUEUE_HW, QUEUE_DROP} queue_type; struct octeon_ethernet *priv = netdev_priv(dev); struct sk_buff *to_free_list; - int32_t skb_to_free; - int32_t buffers_to_free; + int skb_to_free; + int buffers_to_free; u32 total_to_clean; unsigned long flags; #if REUSE_SKBUFFS_WITHOUT_FREE -- cgit v1.2.3 From ac05a587c8a7b6ae8c4acef5a6db7e6ccfbcfd3e Mon Sep 17 00:00:00 2001 From: Laura Garcia Liebana Date: Sat, 12 Mar 2016 16:35:30 +0100 Subject: staging: octeon: Fix alignment with open parenthesis Alignment should match open parenthesis. Checkpatch detected these issues. Signed-off-by: Laura Garcia Liebana Signed-off-by: Greg Kroah-Hartman --- drivers/staging/octeon/ethernet-rx.c | 7 ++++--- drivers/staging/octeon/ethernet-rx.h | 2 +- drivers/staging/octeon/ethernet-tx.c | 5 +++-- drivers/staging/octeon/ethernet.c | 4 ++-- 4 files changed, 10 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/octeon/ethernet-rx.c b/drivers/staging/octeon/ethernet-rx.c index b6993b0b8170..a10fe3af9a9c 100644 --- a/drivers/staging/octeon/ethernet-rx.c +++ b/drivers/staging/octeon/ethernet-rx.c @@ -172,12 +172,13 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) if (OCTEON_IS_MODEL(OCTEON_CN68XX)) { old_group_mask = cvmx_read_csr(CVMX_SSO_PPX_GRP_MSK(coreid)); cvmx_write_csr(CVMX_SSO_PPX_GRP_MSK(coreid), - 1ull << pow_receive_group); + 1ull << pow_receive_group); cvmx_read_csr(CVMX_SSO_PPX_GRP_MSK(coreid)); /* Flush */ } else { old_group_mask = cvmx_read_csr(CVMX_POW_PP_GRP_MSKX(coreid)); cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(coreid), - (old_group_mask & ~0xFFFFull) | 1 << pow_receive_group); + (old_group_mask & ~0xFFFFull) | + 1 << pow_receive_group); } if (USE_ASYNC_IOBDMA) { @@ -374,7 +375,7 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) * doesn't exist. */ printk_ratelimited("Port %d not controlled by Linux, packet dropped\n", - port); + port); dev_kfree_skb_irq(skb); } /* diff --git a/drivers/staging/octeon/ethernet-rx.h b/drivers/staging/octeon/ethernet-rx.h index a5973fd015fc..315a63d7094f 100644 --- a/drivers/staging/octeon/ethernet-rx.h +++ b/drivers/staging/octeon/ethernet-rx.h @@ -30,7 +30,7 @@ static inline void cvm_oct_rx_refill_pool(int fill_threshold) number_to_free); if (num_freed != number_to_free) { cvmx_fau_atomic_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE, - number_to_free - num_freed); + number_to_free - num_freed); } } } diff --git a/drivers/staging/octeon/ethernet-tx.c b/drivers/staging/octeon/ethernet-tx.c index 93f65589f72a..6b4c20872323 100644 --- a/drivers/staging/octeon/ethernet-tx.c +++ b/drivers/staging/octeon/ethernet-tx.c @@ -220,7 +220,8 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev) priv->fau + qos * 4, MAX_SKB_TO_FREE); } skb_to_free = cvm_oct_adjust_skb_to_free(skb_to_free, - priv->fau + qos * 4); + priv->fau + + qos * 4); spin_lock_irqsave(&priv->tx_free_list[qos].lock, flags); goto skip_xmit; } @@ -402,7 +403,7 @@ dont_put_skbuff_in_hw: } skb_to_free = cvm_oct_adjust_skb_to_free(skb_to_free, - priv->fau + qos * 4); + priv->fau + qos * 4); /* * If we're sending faster than the receive can free them then diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c index 271e1b8d8506..e9cd5f242921 100644 --- a/drivers/staging/octeon/ethernet.c +++ b/drivers/staging/octeon/ethernet.c @@ -635,7 +635,7 @@ static struct device_node *cvm_oct_of_get_child( } static struct device_node *cvm_oct_node_for_port(struct device_node *pip, - int interface, int port) + int interface, int port) { struct device_node *ni, *np; @@ -815,7 +815,7 @@ static int cvm_oct_probe(struct platform_device *pdev) free_netdev(dev); } else if (register_netdev(dev) < 0) { pr_err("Failed to register ethernet device for interface %d, port %d\n", - interface, priv->port); + interface, priv->port); free_netdev(dev); } else { cvm_oct_device[priv->port] = dev; -- cgit v1.2.3 From 9fc27699bd16707ae95218ba553bde144f5afbed Mon Sep 17 00:00:00 2001 From: Laura Garcia Liebana Date: Sat, 12 Mar 2016 16:20:04 +0100 Subject: staging: nvec: Remove space after a cast No space is required after a cast. Checkpatch detected this issue. Signed-off-by: Laura Garcia Liebana Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/nvec.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 9fda136b8e05..dc38ca815806 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -659,10 +659,11 @@ static irqreturn_t nvec_interrupt(int irq, void *dev) } else if (nvec->tx && nvec->tx->pos < nvec->tx->size) { to_send = nvec->tx->data[nvec->tx->pos++]; } else { - dev_err(nvec->dev, "tx buffer underflow on %p (%u > %u)\n", + dev_err(nvec->dev, + "tx buffer underflow on %p (%u > %u)\n", nvec->tx, - (uint) (nvec->tx ? nvec->tx->pos : 0), - (uint) (nvec->tx ? nvec->tx->size : 0)); + (uint)(nvec->tx ? nvec->tx->pos : 0), + (uint)(nvec->tx ? nvec->tx->size : 0)); nvec->state = 0; } break; -- cgit v1.2.3 From f05f33fae3c720bd555ceb15b46beb4c642b663a Mon Sep 17 00:00:00 2001 From: Laura Garcia Liebana Date: Sat, 12 Mar 2016 16:19:11 +0100 Subject: staging: nvec: Fix comparison to NULL Replace the use of comparison to NULL, use ! instead. Checkpatch detected these issues. Signed-off-by: Laura Garcia Liebana Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/nvec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index dc38ca815806..c1feccf8d94a 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -264,7 +264,7 @@ int nvec_write_async(struct nvec_chip *nvec, const unsigned char *data, msg = nvec_msg_alloc(nvec, NVEC_MSG_TX); - if (msg == NULL) + if (!msg) return -ENOMEM; msg->data[0] = size; @@ -620,7 +620,7 @@ static irqreturn_t nvec_interrupt(int irq, void *dev) } else { nvec->rx = nvec_msg_alloc(nvec, NVEC_MSG_RX); /* Should not happen in a normal world */ - if (unlikely(nvec->rx == NULL)) { + if (unlikely(!nvec->rx)) { nvec->state = 0; break; } -- cgit v1.2.3 From a3dac5a35cc54fa983e3de56ec010734c87315c4 Mon Sep 17 00:00:00 2001 From: Ben Marsh Date: Tue, 15 Mar 2016 19:37:54 +0100 Subject: Staging: nvec: removes a useless cast on a void pointer Remove an unnecessary cast on a void pointer in nvec_power.c Signed-off-by: Ben Marsh Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/nvec_power.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/nvec/nvec_power.c b/drivers/staging/nvec/nvec_power.c index b4a0545e8806..fcbb0fa03765 100644 --- a/drivers/staging/nvec/nvec_power.c +++ b/drivers/staging/nvec/nvec_power.c @@ -90,7 +90,7 @@ static int nvec_power_notifier(struct notifier_block *nb, { struct nvec_power *power = container_of(nb, struct nvec_power, notifier); - struct bat_response *res = (struct bat_response *)data; + struct bat_response *res = data; if (event_type != NVEC_SYS) return NOTIFY_DONE; @@ -126,7 +126,7 @@ static int nvec_power_bat_notifier(struct notifier_block *nb, { struct nvec_power *power = container_of(nb, struct nvec_power, notifier); - struct bat_response *res = (struct bat_response *)data; + struct bat_response *res = data; int status_changed = 0; if (event_type != NVEC_BAT) -- cgit v1.2.3 From 6422ea03f335bf7441150555de1ab048ac82ee99 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Tue, 15 Mar 2016 18:48:08 +0900 Subject: staging: wilc1000: removes function 'init_tcp_tracking()' This patch removes function 'init_tcp_tracking()'. The function is an unnecessary return. Signed-off-by: Leo Kim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index fd938fb43dd3..ca9054a5ff88 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -150,11 +150,6 @@ static u32 pending_base; static u32 tcp_session; static u32 pending_acks; -static inline int init_tcp_tracking(void) -{ - return 0; -} - static inline int add_tcp_session(u32 src_prt, u32 dst_prt, u32 seq) { if (tcp_session < 2 * MAX_TCP_SESSION) { @@ -1440,7 +1435,6 @@ int wilc_wlan_init(struct net_device *dev) ret = -EIO; goto _fail_; } - init_tcp_tracking(); return 1; -- cgit v1.2.3 From 9635d338303c3ed80e06c03b54ee171651438984 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Tue, 15 Mar 2016 18:48:09 +0900 Subject: staging: wilc1000: wilc_spi.c: removes debug print log This patches removes unnecessary debug print logs. Signed-off-by: Leo Kim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_spi.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c index d41b8b6790af..4268e2f29307 100644 --- a/drivers/staging/wilc1000/wilc_spi.c +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -196,9 +196,6 @@ static int wilc_spi_tx(struct wilc *wilc, u8 *b, u32 len) dev_err(&spi->dev, "can't write data with the following length: %d\n", len); - dev_err(&spi->dev, - "FAILED due to NULL buffer or ZERO length check the following length: %d\n", - len); ret = -EINVAL; } -- cgit v1.2.3 From 2dfad49a8f93ceae8a74bc403664fd13f801f8fe Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Tue, 15 Mar 2016 18:48:10 +0900 Subject: staging: wilc1000: removes duplicate vif variable setting This patches removes duplicate vif variable setting. This value has already been set previously. Signed-off-by: Leo Kim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index bfa754bb022d..8a1083133a1b 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -912,7 +912,6 @@ int wilc_mac_open(struct net_device *ndev) return -ENODEV; } - vif = netdev_priv(ndev); wilc = vif->wilc; priv = wiphy_priv(vif->ndev->ieee80211_ptr->wiphy); netdev_dbg(ndev, "MAC OPEN[%p]\n", ndev); -- cgit v1.2.3 From ba7504730b26b7eb49731a5ac7972c34f0513ac1 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Tue, 15 Mar 2016 18:48:11 +0900 Subject: staging: wilc1000: removes duplicate wilc variable setting This patches removes duplicate wilc variable setting. This value has already been set to wl variable previously. Replace wilc with wl as well. Signed-off-by: Leo Kim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 8a1083133a1b..1a5de2e911cb 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -896,7 +896,6 @@ static int mac_init_fn(struct net_device *ndev) int wilc_mac_open(struct net_device *ndev) { struct wilc_vif *vif; - struct wilc *wilc; unsigned char mac_add[ETH_ALEN] = {0}; int ret = 0; @@ -912,7 +911,6 @@ int wilc_mac_open(struct net_device *ndev) return -ENODEV; } - wilc = vif->wilc; priv = wiphy_priv(vif->ndev->ieee80211_ptr->wiphy); netdev_dbg(ndev, "MAC OPEN[%p]\n", ndev); @@ -932,13 +930,13 @@ int wilc_mac_open(struct net_device *ndev) wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif), 0); - } else if (!wilc_wlan_get_num_conn_ifcs(wilc)) { + } else if (!wilc_wlan_get_num_conn_ifcs(wl)) { wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif), - wilc->open_ifcs); + wl->open_ifcs); } else { - if (memcmp(wilc->vif[i ^ 1]->bssid, - wilc->vif[i ^ 1]->src_addr, 6)) + if (memcmp(wl->vif[i ^ 1]->bssid, + wl->vif[i ^ 1]->src_addr, 6)) wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif), 0); -- cgit v1.2.3 From 90fd4cc5d25d5baf5540c99c100e82ce06af63f0 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Tue, 15 Mar 2016 18:48:12 +0900 Subject: staging: wilc1000: changes an ambiguous debug messages This patches changes an ambiguous debug messages. The device types are both SDIO or SPI. Signed-off-by: Leo Kim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 1a5de2e911cb..e949f218885c 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -907,7 +907,7 @@ int wilc_mac_open(struct net_device *ndev) wl = vif->wilc; if (!wl || !wl->dev) { - netdev_err(ndev, "wilc1000: SPI device not ready\n"); + netdev_err(ndev, "device not ready\n"); return -ENODEV; } -- cgit v1.2.3 From 5c6021da1c3c46f3c2727626b4a3b9c96bf688ec Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Tue, 15 Mar 2016 18:48:13 +0900 Subject: staging: wilc1000: removes goto definitions from wilc_wlan_firmware_download This patch removes goto definitions from wilc_wlan_firmware_download function. Goto '_fail_1' feature is error return. It returns error type directly without result variable replacement as well. Signed-off-by: Leo Kim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index ca9054a5ff88..ea671a985089 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -946,10 +946,8 @@ int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer, blksz = BIT(12); dma_buffer = kmalloc(blksz, GFP_KERNEL); - if (!dma_buffer) { - ret = -EIO; - goto _fail_1; - } + if (!dma_buffer) + return -EIO; offset = 0; do { @@ -987,8 +985,6 @@ _fail_: kfree(dma_buffer); -_fail_1: - return (ret < 0) ? ret : 0; } -- cgit v1.2.3 From 88253ab8e637f210decc8d3ec910e5205cb75b34 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Tue, 15 Mar 2016 18:48:14 +0900 Subject: staging: wilc1000: removes an unnecessary if-condition This patch removes an unnecessary if-condition. Regardless of an if-condition is performed unconditionally '_end_' statement. Signed-off-by: Leo Kim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index ea671a985089..08937fe42b42 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -895,8 +895,6 @@ static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status) DATA_INT_CLR | ENABLE_RX_VMM); ret = wilc->hif_func->hif_block_rx_ext(wilc, 0, buffer, size); - if (!ret) - goto _end_; _end_: if (ret) { offset += size; -- cgit v1.2.3 From 613eaa39d68b928c52a8d93bec4573925f009b62 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Mon, 14 Mar 2016 09:40:27 +0900 Subject: staging: wilc1000: use completion instead of struct semaphore hif_sema_wait_response This patch replaces struct semaphore hif_sema_wait_response with struct completion hif_wait_response. In case of struct hif_sema_wait_response, it better to use completion than semaphore. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 0a922c7c7cbf..e73ee89cf6d4 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -232,7 +232,7 @@ static struct task_struct *hif_thread_handler; static struct message_queue hif_msg_q; static struct semaphore hif_sema_thread; static struct semaphore hif_sema_driver; -static struct semaphore hif_sema_wait_response; +static struct completion hif_wait_response; static struct semaphore hif_sema_deinit; static struct timer_list periodic_rssi; @@ -430,7 +430,7 @@ static s32 handle_get_mac_address(struct wilc_vif *vif, netdev_err(vif->ndev, "Failed to get mac address\n"); result = -EFAULT; } - up(&hif_sema_wait_response); + complete(&hif_wait_response); return result; } @@ -1938,7 +1938,7 @@ static s32 Handle_GetStatistics(struct wilc_vif *vif, wilc_enable_tcp_ack_filter(false); if (pstrStatistics != &vif->wilc->dummy_statistics) - up(&hif_sema_wait_response); + complete(&hif_wait_response); return 0; } @@ -2172,7 +2172,7 @@ static void Handle_DelAllSta(struct wilc_vif *vif, ERRORHANDLER: kfree(wid.val); - up(&hif_sema_wait_response); + complete(&hif_wait_response); } static void Handle_DelStation(struct wilc_vif *vif, @@ -2485,7 +2485,7 @@ static void handle_get_tx_pwr(struct wilc_vif *vif, u8 *tx_pwr) if (ret) netdev_err(vif->ndev, "Failed to get TX PWR\n"); - up(&hif_sema_wait_response); + complete(&hif_wait_response); } static int hostIFthread(void *pvArg) @@ -3007,7 +3007,7 @@ int wilc_get_mac_address(struct wilc_vif *vif, u8 *mac_addr) return -EFAULT; } - down(&hif_sema_wait_response); + wait_for_completion(&hif_wait_response); return result; } @@ -3272,7 +3272,7 @@ int wilc_get_statistics(struct wilc_vif *vif, struct rf_info *stats) } if (stats != &vif->wilc->dummy_statistics) - down(&hif_sema_wait_response); + wait_for_completion(&hif_wait_response); return result; } @@ -3382,7 +3382,7 @@ int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) scan_while_connected = false; - sema_init(&hif_sema_wait_response, 0); + init_completion(&hif_wait_response); hif_drv = kzalloc(sizeof(struct host_if_drv), GFP_KERNEL); if (!hif_drv) { @@ -3888,7 +3888,7 @@ int wilc_del_allstation(struct wilc_vif *vif, u8 mac_addr[][ETH_ALEN]) if (result) netdev_err(vif->ndev, "wilc_mq_send fail\n"); - down(&hif_sema_wait_response); + wait_for_completion(&hif_wait_response); return result; } @@ -4221,7 +4221,7 @@ int wilc_get_tx_power(struct wilc_vif *vif, u8 *tx_power) if (ret) netdev_err(vif->ndev, "Failed to get TX PWR\n"); - down(&hif_sema_wait_response); + wait_for_completion(&hif_wait_response); *tx_power = msg.body.tx_power.tx_pwr; return ret; -- cgit v1.2.3 From a5c3f8db438ab3627992124eae98fefcce53977f Mon Sep 17 00:00:00 2001 From: Anchal Jain Date: Sun, 13 Mar 2016 15:14:38 +0530 Subject: staging: wilc1000: else is not generally useful after a break or return Remove else after a break. Because else is generally not useful after a break or return. Signed-off-by: Anchal Jain Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 08937fe42b42..30e1c039e80a 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -621,13 +621,12 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) if ((reg & 0x1) == 0) { break; - } else { - counter++; - if (counter > 200) { - counter = 0; - ret = wilc->hif_func->hif_write_reg(wilc, WILC_HOST_TX_CTRL, 0); - break; - } + } + counter++; + if (counter > 200) { + counter = 0; + ret = wilc->hif_func->hif_write_reg(wilc, WILC_HOST_TX_CTRL, 0); + break; } } while (!wilc->quit); @@ -653,9 +652,8 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) if ((reg >> 2) & 0x1) { entries = ((reg >> 3) & 0x3f); break; - } else { - release_bus(wilc, RELEASE_ALLOW_SLEEP); } + release_bus(wilc, RELEASE_ALLOW_SLEEP); } while (--timeout); if (timeout <= 0) { ret = wilc->hif_func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x0); @@ -674,9 +672,8 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) if (!ret) break; break; - } else { - break; } + break; } while (1); if (!ret) -- cgit v1.2.3 From 1b7c69e84bcea7a8054b44e6671e7b9ad758c2d8 Mon Sep 17 00:00:00 2001 From: Anchal Jain Date: Mon, 14 Mar 2016 18:06:54 +0530 Subject: staging: wilc1000: Fix lines over 80 characters Break lines so that they do not exceed 80 characters. Problem found using checkpatch. Signed-off-by: Anchal Jain Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_mon.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/linux_mon.c b/drivers/staging/wilc1000/linux_mon.c index 7d9e5ded8ff4..6503316314f8 100644 --- a/drivers/staging/wilc1000/linux_mon.c +++ b/drivers/staging/wilc1000/linux_mon.c @@ -59,9 +59,10 @@ void WILC_WFI_monitor_rx(u8 *buff, u32 size) /* Get WILC header */ memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET); - - /* The packet offset field conain info about what type of managment frame */ - /* we are dealing with and ack status */ + /* + * The packet offset field contain info about what type of management + * the frame we are dealing with and ack status + */ pkt_offset = GET_PKT_OFFSET(header); if (pkt_offset & IS_MANAGMEMENT_CALLBACK) { @@ -105,7 +106,7 @@ void WILC_WFI_monitor_rx(u8 *buff, u32 size) hdr->hdr.it_version = 0; /* PKTHDR_RADIOTAP_VERSION; */ hdr->hdr.it_len = cpu_to_le16(sizeof(struct wilc_wfi_radiotap_hdr)); hdr->hdr.it_present = cpu_to_le32 - (1 << IEEE80211_RADIOTAP_RATE); /* | */ + (1 << IEEE80211_RADIOTAP_RATE); /* | */ hdr->rate = 5; /* txrate->bitrate / 5; */ } @@ -127,8 +128,10 @@ struct tx_complete_mon_data { static void mgmt_tx_complete(void *priv, int status) { struct tx_complete_mon_data *pv_data = priv; - - /* incase of fully hosting mode, the freeing will be done in response to the cfg packet */ + /* + * in case of fully hosting mode, the freeing will be done + * in response to the cfg packet + */ kfree(pv_data->buff); kfree(pv_data); @@ -255,7 +258,8 @@ static const struct net_device_ops wilc_wfi_netdev_ops = { * @date 12 JUL 2012 * @version 1.0 */ -struct net_device *WILC_WFI_init_mon_interface(const char *name, struct net_device *real_dev) +struct net_device *WILC_WFI_init_mon_interface(const char *name, + struct net_device *real_dev) { u32 ret = 0; struct WILC_WFI_mon_priv *priv; -- cgit v1.2.3 From e0c1496fcf6a1bbc9b827e763f58535585b249d5 Mon Sep 17 00:00:00 2001 From: Alison Schofield Date: Mon, 14 Mar 2016 10:34:14 -0700 Subject: staging: wilc1000: replace semaphore sem_inactive_time with a completion Semaphore sem_inactive_time is used to signal completion of its host interface message. Since the thread locking this semaphore will have to wait, completions are the preferred mechanism and will offer a performance improvement. Signed-off-by: Alison Schofield Reviewed-by: Arnd Bergmann Tested-by: Leo Kim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 7 ++++--- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index e73ee89cf6d4..2f14370b3ecc 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -2,6 +2,7 @@ #include #include #include +#include #include "host_interface.h" #include "coreconfigurator.h" #include "wilc_wlan.h" @@ -1979,7 +1980,7 @@ static s32 Handle_Get_InActiveTime(struct wilc_vif *vif, return -EFAULT; } - up(&hif_drv->sem_inactive_time); + complete(&hif_drv->comp_inactive_time); return result; } @@ -3220,7 +3221,7 @@ s32 wilc_get_inactive_time(struct wilc_vif *vif, const u8 *mac, if (result) netdev_err(vif->ndev, "Failed to send get host ch param\n"); - down(&hif_drv->sem_inactive_time); + wait_for_completion(&hif_drv->comp_inactive_time); *pu32InactiveTime = inactive_time; @@ -3407,7 +3408,7 @@ int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) sema_init(&hif_drv->sem_test_key_block, 0); sema_init(&hif_drv->sem_test_disconn_block, 0); sema_init(&hif_drv->sem_get_rssi, 0); - sema_init(&hif_drv->sem_inactive_time, 0); + init_completion(&hif_drv->comp_inactive_time); if (clients_count == 0) { result = wilc_mq_create(&hif_msg_q); diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 01f3222a4231..68852b3404d2 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -278,7 +278,7 @@ struct host_if_drv { struct semaphore sem_test_key_block; struct semaphore sem_test_disconn_block; struct semaphore sem_get_rssi; - struct semaphore sem_inactive_time; + struct completion comp_inactive_time; struct timer_list scan_timer; struct timer_list connect_timer; -- cgit v1.2.3 From 7c8a3dcac82f11681e3e6ad61fb2e5802a136c24 Mon Sep 17 00:00:00 2001 From: Alison Schofield Date: Mon, 14 Mar 2016 10:34:39 -0700 Subject: staging: wilc1000: replace semaphore sem_get_rssi with a completion Semaphore sem_get_rssi is used to signal completion of its host interface message. Since the thread locking this semaphore will have to wait, completions are the preferred mechanism and will offer a performance improvement. Signed-off-by: Alison Schofield Reviewed-by: Arnd Bergmann Tested-by: Leo Kim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 6 +++--- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 2f14370b3ecc..697491e8cfb2 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -1886,7 +1886,7 @@ static void Handle_GetRssi(struct wilc_vif *vif) result = -EFAULT; } - up(&vif->hif_drv->sem_get_rssi); + complete(&vif->hif_drv->comp_get_rssi); } static s32 Handle_GetStatistics(struct wilc_vif *vif, @@ -3244,7 +3244,7 @@ int wilc_get_rssi(struct wilc_vif *vif, s8 *rssi_level) return -EFAULT; } - down(&hif_drv->sem_get_rssi); + wait_for_completion(&hif_drv->comp_get_rssi); if (!rssi_level) { netdev_err(vif->ndev, "RSS pointer value is null\n"); @@ -3407,7 +3407,7 @@ int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) sema_init(&hif_drv->sem_test_key_block, 0); sema_init(&hif_drv->sem_test_disconn_block, 0); - sema_init(&hif_drv->sem_get_rssi, 0); + init_completion(&hif_drv->comp_get_rssi); init_completion(&hif_drv->comp_inactive_time); if (clients_count == 0) { diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 68852b3404d2..085adeeaa767 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -277,7 +277,7 @@ struct host_if_drv { struct mutex cfg_values_lock; struct semaphore sem_test_key_block; struct semaphore sem_test_disconn_block; - struct semaphore sem_get_rssi; + struct completion comp_get_rssi; struct completion comp_inactive_time; struct timer_list scan_timer; -- cgit v1.2.3 From 96adbd276e7194320f08fd7f00c4a1be2d910d11 Mon Sep 17 00:00:00 2001 From: Alison Schofield Date: Mon, 14 Mar 2016 10:35:05 -0700 Subject: staging: wilc1000: replace sem_test_disconn_block with a completion Semaphore sem_test_disconn_block is used to signal completion of its host interface message. Since the thread locking this semaphore will have to wait, completions are the preferred mechanism and will offer a performance improvement. Signed-off-by: Alison Schofield Reviewed-by: Arnd Bergmann Tested-by: Leo Kim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 6 +++--- drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 697491e8cfb2..ed7f011b3eca 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -1857,7 +1857,7 @@ static void Handle_Disconnect(struct wilc_vif *vif) } } - up(&hif_drv->sem_test_disconn_block); + complete(&hif_drv->comp_test_disconn_block); } void wilc_resolve_disconnect_aberration(struct wilc_vif *vif) @@ -3099,7 +3099,7 @@ int wilc_disconnect(struct wilc_vif *vif, u16 reason_code) if (result) netdev_err(vif->ndev, "Failed to send message: disconnect\n"); - down(&hif_drv->sem_test_disconn_block); + wait_for_completion(&hif_drv->comp_test_disconn_block); return result; } @@ -3406,7 +3406,7 @@ int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) } sema_init(&hif_drv->sem_test_key_block, 0); - sema_init(&hif_drv->sem_test_disconn_block, 0); + init_completion(&hif_drv->comp_test_disconn_block); init_completion(&hif_drv->comp_get_rssi); init_completion(&hif_drv->comp_inactive_time); diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 085adeeaa767..3ab94a7ba5e9 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -276,7 +276,7 @@ struct host_if_drv { struct mutex cfg_values_lock; struct semaphore sem_test_key_block; - struct semaphore sem_test_disconn_block; + struct completion comp_test_disconn_block; struct completion comp_get_rssi; struct completion comp_inactive_time; -- cgit v1.2.3 From 702962f33ba664d3a6ce2008d076dccd93c420a2 Mon Sep 17 00:00:00 2001 From: Alison Schofield Date: Mon, 14 Mar 2016 10:35:41 -0700 Subject: staging: wilc1000: replace sem_test_key_block with a completion Semaphore sem_test_key_block is used to signal completion of its host interface message. Since the thread locking this semaphore will have to wait, completions are the preferred mechanism and will offer a performance improvement. Signed-off-by: Alison Schofield Reviewed-by: Arnd Bergmann Tested-by: Leo Kim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 24 ++++++++++++------------ drivers/staging/wilc1000/host_interface.h | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index ed7f011b3eca..f50571ffcf32 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -1611,7 +1611,7 @@ static int Handle_Key(struct wilc_vif *vif, &wid, 1, wilc_get_vif_idx(vif)); } - up(&hif_drv->sem_test_key_block); + complete(&hif_drv->comp_test_key_block); break; case WPA_RX_GTK: @@ -1645,7 +1645,7 @@ static int Handle_Key(struct wilc_vif *vif, wilc_get_vif_idx(vif)); kfree(pu8keybuf); - up(&hif_drv->sem_test_key_block); + complete(&hif_drv->comp_test_key_block); } else if (pstrHostIFkeyAttr->action & ADDKEY) { pu8keybuf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL); if (pu8keybuf == NULL) { @@ -1674,7 +1674,7 @@ static int Handle_Key(struct wilc_vif *vif, wilc_get_vif_idx(vif)); kfree(pu8keybuf); - up(&hif_drv->sem_test_key_block); + complete(&hif_drv->comp_test_key_block); } _WPARxGtk_end_case_: kfree(pstrHostIFkeyAttr->attr.wpa.key); @@ -1712,7 +1712,7 @@ _WPARxGtk_end_case_: strWIDList, 2, wilc_get_vif_idx(vif)); kfree(pu8keybuf); - up(&hif_drv->sem_test_key_block); + complete(&hif_drv->comp_test_key_block); } else if (pstrHostIFkeyAttr->action & ADDKEY) { pu8keybuf = kmalloc(PTK_KEY_MSG_LEN, GFP_KERNEL); if (!pu8keybuf) { @@ -1735,7 +1735,7 @@ _WPARxGtk_end_case_: &wid, 1, wilc_get_vif_idx(vif)); kfree(pu8keybuf); - up(&hif_drv->sem_test_key_block); + complete(&hif_drv->comp_test_key_block); } _WPAPtk_end_case_: @@ -2731,7 +2731,7 @@ int wilc_remove_wep_key(struct wilc_vif *vif, u8 index) result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); if (result) netdev_err(vif->ndev, "Request to remove WEP key\n"); - down(&hif_drv->sem_test_key_block); + wait_for_completion(&hif_drv->comp_test_key_block); return result; } @@ -2759,7 +2759,7 @@ int wilc_set_wep_default_keyid(struct wilc_vif *vif, u8 index) result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); if (result) netdev_err(vif->ndev, "Default key index\n"); - down(&hif_drv->sem_test_key_block); + wait_for_completion(&hif_drv->comp_test_key_block); return result; } @@ -2792,7 +2792,7 @@ int wilc_add_wep_key_bss_sta(struct wilc_vif *vif, const u8 *key, u8 len, result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); if (result) netdev_err(vif->ndev, "STA - WEP Key\n"); - down(&hif_drv->sem_test_key_block); + wait_for_completion(&hif_drv->comp_test_key_block); return result; } @@ -2828,7 +2828,7 @@ int wilc_add_wep_key_bss_ap(struct wilc_vif *vif, const u8 *key, u8 len, if (result) netdev_err(vif->ndev, "AP - WEP Key\n"); - down(&hif_drv->sem_test_key_block); + wait_for_completion(&hif_drv->comp_test_key_block); return result; } @@ -2884,7 +2884,7 @@ int wilc_add_ptk(struct wilc_vif *vif, const u8 *ptk, u8 ptk_key_len, if (result) netdev_err(vif->ndev, "PTK Key\n"); - down(&hif_drv->sem_test_key_block); + wait_for_completion(&hif_drv->comp_test_key_block); return result; } @@ -2952,7 +2952,7 @@ int wilc_add_rx_gtk(struct wilc_vif *vif, const u8 *rx_gtk, u8 gtk_key_len, if (result) netdev_err(vif->ndev, "RX GTK\n"); - down(&hif_drv->sem_test_key_block); + wait_for_completion(&hif_drv->comp_test_key_block); return result; } @@ -3405,7 +3405,7 @@ int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) sema_init(&hif_sema_deinit, 1); } - sema_init(&hif_drv->sem_test_key_block, 0); + init_completion(&hif_drv->comp_test_key_block); init_completion(&hif_drv->comp_test_disconn_block); init_completion(&hif_drv->comp_get_rssi); init_completion(&hif_drv->comp_inactive_time); diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 3ab94a7ba5e9..8d2dd0db0bed 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -275,7 +275,7 @@ struct host_if_drv { struct cfg_param_attr cfg_values; struct mutex cfg_values_lock; - struct semaphore sem_test_key_block; + struct completion comp_test_key_block; struct completion comp_test_disconn_block; struct completion comp_get_rssi; struct completion comp_inactive_time; -- cgit v1.2.3 From d5e27e8b83b1da0cd64a6a090e273a199c2805fc Mon Sep 17 00:00:00 2001 From: "Roger H. Newell" Date: Sat, 19 Mar 2016 12:49:21 -0230 Subject: staging: wilc1000: Removed braces from single block statements This patch corrects warnings generated by checkpatch.pl by removing braces from single block statements. Signed-ff-by: Roger H. Newell Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 31 +++++++++-------------- drivers/staging/wilc1000/wilc_wlan_cfg.c | 3 +-- 2 files changed, 13 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 448a5c8c4514..70625f8a2e3c 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -558,11 +558,11 @@ static void CfgConnectResult(enum conn_event enuConnDisconnEvent, if (!pstrWFIDrv->p2p_connect) wlan_channel = INVALID_CHANNEL; - if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev)) { + if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev)) pstrDisconnectNotifInfo->reason = 3; - } else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev)) { + else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev)) pstrDisconnectNotifInfo->reason = 1; - } + cfg80211_disconnected(dev, pstrDisconnectNotifInfo->reason, pstrDisconnectNotifInfo->ie, pstrDisconnectNotifInfo->ie_len, false, GFP_KERNEL); @@ -739,18 +739,15 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len, sme->key_idx); } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) { - if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) { + if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) u8security = ENCRYPT_ENABLED | WPA2 | TKIP; - } else { + else u8security = ENCRYPT_ENABLED | WPA2 | AES; - } } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) { - if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) { + if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) u8security = ENCRYPT_ENABLED | WPA | TKIP; - } else { + else u8security = ENCRYPT_ENABLED | WPA | AES; - } - } else { s32Error = -ENOTSUPP; netdev_err(dev, "Not supported cipher\n"); @@ -762,11 +759,10 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) { for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) { - if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) { + if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) u8security = u8security | TKIP; - } else { + else u8security = u8security | AES; - } } } @@ -1355,9 +1351,8 @@ static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len) u8 channel_list_attr_index = 0; while (index < len) { - if (buf[index] == GO_INTENT_ATTR_ID) { + if (buf[index] == GO_INTENT_ATTR_ID) buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1); - } if (buf[index] == CHANLIST_ATTR_ID) channel_list_attr_index = index; @@ -1369,9 +1364,8 @@ static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len) if (channel_list_attr_index) { for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) { if (buf[i] == 0x51) { - for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) { + for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) buf[j] = wlan_channel; - } break; } } @@ -1409,9 +1403,8 @@ static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftyp if (channel_list_attr_index) { for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) { if (buf[i] == 0x51) { - for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) { + for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) buf[j] = wlan_channel; - } break; } } diff --git a/drivers/staging/wilc1000/wilc_wlan_cfg.c b/drivers/staging/wilc1000/wilc_wlan_cfg.c index b3425b9cec94..b9711caac0da 100644 --- a/drivers/staging/wilc1000/wilc_wlan_cfg.c +++ b/drivers/staging/wilc1000/wilc_wlan_cfg.c @@ -253,9 +253,8 @@ static int wilc_wlan_cfg_set_bin(u8 *frame, u32 offset, u16 id, u8 *b, u32 size) if ((b != NULL) && (size != 0)) { memcpy(&buf[4], b, size); - for (i = 0; i < size; i++) { + for (i = 0; i < size; i++) checksum += buf[i + 4]; - } } buf[size + 4] = checksum; -- cgit v1.2.3 From b59958ee900c81692da131873c0fc0b1599f164f Mon Sep 17 00:00:00 2001 From: "Roger H. Newell" Date: Sat, 19 Mar 2016 12:50:52 -0230 Subject: staging: wilc1000: Replaced comparison to NULL statements This patch corrects checks generated by checkpatch.pl by replacing comparison to null statements with equivalent statements in the form "x" or "!x" Signed-off-by: Roger H. Newell Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 2 +- drivers/staging/wilc1000/wilc_wlan_cfg.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index f50571ffcf32..4be8b3183b28 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -1648,7 +1648,7 @@ static int Handle_Key(struct wilc_vif *vif, complete(&hif_drv->comp_test_key_block); } else if (pstrHostIFkeyAttr->action & ADDKEY) { pu8keybuf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL); - if (pu8keybuf == NULL) { + if (!pu8keybuf) { ret = -ENOMEM; goto _WPARxGtk_end_case_; } diff --git a/drivers/staging/wilc1000/wilc_wlan_cfg.c b/drivers/staging/wilc1000/wilc_wlan_cfg.c index b9711caac0da..926fc16319b6 100644 --- a/drivers/staging/wilc1000/wilc_wlan_cfg.c +++ b/drivers/staging/wilc1000/wilc_wlan_cfg.c @@ -230,7 +230,7 @@ static int wilc_wlan_cfg_set_str(u8 *frame, u32 offset, u16 id, u8 *str, u32 siz buf[1] = (u8)(id >> 8); buf[2] = (u8)size; - if ((str != NULL) && (size != 0)) + if ((str) && (size != 0)) memcpy(&buf[3], str, size); return (size + 3); @@ -251,7 +251,7 @@ static int wilc_wlan_cfg_set_bin(u8 *frame, u32 offset, u16 id, u8 *b, u32 size) buf[2] = (u8)size; buf[3] = (u8)(size >> 8); - if ((b != NULL) && (size != 0)) { + if ((b) && (size != 0)) { memcpy(&buf[4], b, size); for (i = 0; i < size; i++) checksum += buf[i + 4]; -- cgit v1.2.3 From 4dadfb97b73f0fbcc0c6f5a6897c0942c05a9dd3 Mon Sep 17 00:00:00 2001 From: Juliana Rodrigues Date: Sun, 13 Mar 2016 15:07:30 -0300 Subject: staging: rtl8712: hal_init.c: fix comment block code style This patch fixes several warnings caused by malformed comments on hal_init.c and found by checkpatch.pl. Signed-off-by: Juliana Rodrigues Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/hal_init.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8712/hal_init.c b/drivers/staging/rtl8712/hal_init.c index 8008efe5686d..37fe0a4db602 100644 --- a/drivers/staging/rtl8712/hal_init.c +++ b/drivers/staging/rtl8712/hal_init.c @@ -297,7 +297,8 @@ static u8 rtl8712_dl_fw(struct _adapter *padapter) tmp8 = r8712_read8(padapter, 0x1025000A); if (tmp8 & BIT(4)) /* When boot from EEPROM, - & FW need more time to read EEPROM */ + * & FW need more time to read EEPROM + */ i = 60; else /* boot from EFUSE */ i = 30; @@ -332,7 +333,8 @@ uint rtl8712_hal_init(struct _adapter *padapter) r8712_read32(padapter, RCR)); val32 = r8712_read32(padapter, RCR); r8712_write32(padapter, RCR, (val32 | BIT(26))); /* Enable RX TCP - Checksum offload */ + * Checksum offload + */ netdev_info(padapter->pnetdev, "2 RCR=0x%x\n", r8712_read32(padapter, RCR)); val32 = r8712_read32(padapter, RCR); @@ -346,7 +348,8 @@ uint rtl8712_hal_init(struct _adapter *padapter) r8712_write8(padapter, 0x102500BD, r8712_read8(padapter, 0x102500BD) | BIT(7)); /* enable usb rx aggregation */ r8712_write8(padapter, 0x102500D9, 1); /* TH=1 => means that invalidate - * usb rx aggregation */ + * usb rx aggregation + */ r8712_write8(padapter, 0x1025FE5B, 0x04); /* 1.7ms/4 */ /* Fix the RX FIFO issue(USB error) */ r8712_write8(padapter, 0x1025fe5C, r8712_read8(padapter, 0x1025fe5C) @@ -367,7 +370,8 @@ uint rtl8712_hal_deinit(struct _adapter *padapter) r8712_write8(padapter, SYS_FUNC_EN + 1, 0x70); r8712_write8(padapter, PMC_FSM, 0x06); /* Enable Loader Data Keep */ r8712_write8(padapter, SYS_ISO_CTRL, 0xF9); /* Isolation signals from - * CORE, PLL */ + * CORE, PLL + */ r8712_write8(padapter, SYS_ISO_CTRL + 1, 0xe8); /* Enable EFUSE 1.2V */ r8712_write8(padapter, AFE_PLL_CTRL, 0x00); /* Disable AFE PLL. */ r8712_write8(padapter, LDOA15_CTRL, 0x54); /* Disable A15V */ -- cgit v1.2.3 From 7fcf92c0a4847b0d66fbc09446561752ec2d2575 Mon Sep 17 00:00:00 2001 From: Juliana Rodrigues Date: Sun, 13 Mar 2016 15:30:57 -0300 Subject: staging: rtl8712: rtl8712_cmd.c: fixed comparison to null This patch fixes multiple "comparison to NULL" checkpatch.pl issues: CHECK: Comparison to NULL could be written "!pcmd" + if (pcmd == NULL) Signed-off-by: Juliana Rodrigues Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/rtl8712_cmd.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8712/rtl8712_cmd.c b/drivers/staging/rtl8712/rtl8712_cmd.c index 50f400234593..13c018340ff2 100644 --- a/drivers/staging/rtl8712/rtl8712_cmd.c +++ b/drivers/staging/rtl8712/rtl8712_cmd.c @@ -135,7 +135,7 @@ static u8 read_macreg_hdl(struct _adapter *padapter, u8 *pbuf) /* invoke cmd->callback function */ pcmd_callback = cmd_callback[pcmd->cmdcode].callback; - if (pcmd_callback == NULL) + if (!pcmd_callback) r8712_free_cmd_obj(pcmd); else pcmd_callback(padapter, pcmd); @@ -149,7 +149,7 @@ static u8 write_macreg_hdl(struct _adapter *padapter, u8 *pbuf) /* invoke cmd->callback function */ pcmd_callback = cmd_callback[pcmd->cmdcode].callback; - if (pcmd_callback == NULL) + if (!pcmd_callback) r8712_free_cmd_obj(pcmd); else pcmd_callback(padapter, pcmd); @@ -165,7 +165,7 @@ static u8 read_bbreg_hdl(struct _adapter *padapter, u8 *pbuf) if (pcmd->rsp && pcmd->rspsz > 0) memcpy(pcmd->rsp, (u8 *)&val, pcmd->rspsz); pcmd_callback = cmd_callback[pcmd->cmdcode].callback; - if (pcmd_callback == NULL) + if (!pcmd_callback) r8712_free_cmd_obj(pcmd); else pcmd_callback(padapter, pcmd); @@ -178,7 +178,7 @@ static u8 write_bbreg_hdl(struct _adapter *padapter, u8 *pbuf) struct cmd_obj *pcmd = (struct cmd_obj *)pbuf; pcmd_callback = cmd_callback[pcmd->cmdcode].callback; - if (pcmd_callback == NULL) + if (!pcmd_callback) r8712_free_cmd_obj(pcmd); else pcmd_callback(padapter, pcmd); @@ -194,7 +194,7 @@ static u8 read_rfreg_hdl(struct _adapter *padapter, u8 *pbuf) if (pcmd->rsp && pcmd->rspsz > 0) memcpy(pcmd->rsp, (u8 *)&val, pcmd->rspsz); pcmd_callback = cmd_callback[pcmd->cmdcode].callback; - if (pcmd_callback == NULL) + if (!pcmd_callback) r8712_free_cmd_obj(pcmd); else pcmd_callback(padapter, pcmd); @@ -207,7 +207,7 @@ static u8 write_rfreg_hdl(struct _adapter *padapter, u8 *pbuf) struct cmd_obj *pcmd = (struct cmd_obj *)pbuf; pcmd_callback = cmd_callback[pcmd->cmdcode].callback; - if (pcmd_callback == NULL) + if (!pcmd_callback) r8712_free_cmd_obj(pcmd); else pcmd_callback(padapter, pcmd); @@ -227,7 +227,7 @@ static struct cmd_obj *cmd_hdl_filter(struct _adapter *padapter, { struct cmd_obj *pcmd_r; - if (pcmd == NULL) + if (!pcmd) return pcmd; pcmd_r = NULL; @@ -416,7 +416,7 @@ _next: /* free all cmd_obj resources */ do { pcmd = r8712_dequeue_cmd(&(pcmdpriv->cmd_queue)); - if (pcmd == NULL) + if (!pcmd) break; r8712_free_cmd_obj(pcmd); } while (1); @@ -431,7 +431,7 @@ void r8712_event_handle(struct _adapter *padapter, uint *peventbuf) void (*event_callback)(struct _adapter *dev, u8 *pbuf); struct evt_priv *pevt_priv = &(padapter->evtpriv); - if (peventbuf == NULL) + if (!peventbuf) goto _abort_event_; evt_sz = (u16)(le32_to_cpu(*peventbuf) & 0xffff); evt_seq = (u8)((le32_to_cpu(*peventbuf) >> 24) & 0x7f); -- cgit v1.2.3 From 5a9e10a11e6a76f726235a788265b7c6c5bd1bd7 Mon Sep 17 00:00:00 2001 From: Ben Marsh Date: Sat, 12 Mar 2016 10:33:00 +0100 Subject: Staging: rtl8188eu: removes an unnecessary cast on a void pointer. Patch to rtl8188e_rxdesc.c to remove an unnecessary cast on a void pointer. Signed-off-by: Ben Marsh Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c b/drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c index 53cf3baf46e0..4c78369673b6 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c @@ -64,7 +64,7 @@ static void process_link_qual(struct adapter *padapter, void rtl8188e_process_phy_info(struct adapter *padapter, void *prframe) { - struct recv_frame *precvframe = (struct recv_frame *)prframe; + struct recv_frame *precvframe = prframe; /* Check RSSI */ process_rssi(padapter, precvframe); -- cgit v1.2.3 From fb025382b4c2e394dd2b5ac4d173d42d2d9b5b69 Mon Sep 17 00:00:00 2001 From: Kyle Kuffermann Date: Sun, 13 Mar 2016 10:16:27 -0400 Subject: staging: rtl8188eu: Remove license paragraph with mailing address This fixes the issue reported by checkpatch.pl: "Do not include the paragraph about writing to the Free Software Foundation's mailing address from the sample GPL notice. The FSF has changed addresses in the past, and may do so again. Linux already includes a copy of the GPL." in all files for the rtl8188eu driver. Signed-off-by: Kyle Kuffermann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_ap.c | 5 ----- drivers/staging/rtl8188eu/core/rtw_cmd.c | 5 ----- drivers/staging/rtl8188eu/core/rtw_debug.c | 5 ----- drivers/staging/rtl8188eu/core/rtw_efuse.c | 5 ----- drivers/staging/rtl8188eu/core/rtw_ieee80211.c | 5 ----- drivers/staging/rtl8188eu/core/rtw_ioctl_set.c | 5 ----- drivers/staging/rtl8188eu/core/rtw_mlme.c | 5 ----- drivers/staging/rtl8188eu/core/rtw_mlme_ext.c | 5 ----- drivers/staging/rtl8188eu/core/rtw_pwrctrl.c | 5 ----- drivers/staging/rtl8188eu/core/rtw_recv.c | 5 ----- drivers/staging/rtl8188eu/core/rtw_rf.c | 5 ----- drivers/staging/rtl8188eu/core/rtw_security.c | 5 ----- drivers/staging/rtl8188eu/core/rtw_sreset.c | 5 ----- drivers/staging/rtl8188eu/core/rtw_sta_mgt.c | 5 ----- drivers/staging/rtl8188eu/core/rtw_wlan_util.c | 5 ----- drivers/staging/rtl8188eu/core/rtw_xmit.c | 5 ----- drivers/staging/rtl8188eu/hal/bb_cfg.c | 5 ----- drivers/staging/rtl8188eu/hal/fw.c | 4 ---- drivers/staging/rtl8188eu/hal/hal_com.c | 5 ----- drivers/staging/rtl8188eu/hal/hal_intf.c | 5 ----- drivers/staging/rtl8188eu/hal/mac_cfg.c | 5 ----- drivers/staging/rtl8188eu/hal/odm.c | 5 ----- drivers/staging/rtl8188eu/hal/odm_HWConfig.c | 5 ----- drivers/staging/rtl8188eu/hal/odm_RTL8188E.c | 5 ----- drivers/staging/rtl8188eu/hal/phy.c | 5 ----- drivers/staging/rtl8188eu/hal/pwrseq.c | 5 ----- drivers/staging/rtl8188eu/hal/pwrseqcmd.c | 4 ---- drivers/staging/rtl8188eu/hal/rf.c | 4 ---- drivers/staging/rtl8188eu/hal/rf_cfg.c | 5 ----- drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c | 5 ----- drivers/staging/rtl8188eu/hal/rtl8188e_dm.c | 5 ----- drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c | 5 ----- drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c | 5 ----- drivers/staging/rtl8188eu/hal/rtl8188e_xmit.c | 5 ----- drivers/staging/rtl8188eu/hal/rtl8188eu_led.c | 5 ----- drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c | 5 ----- drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c | 5 ----- drivers/staging/rtl8188eu/hal/usb_halinit.c | 5 ----- drivers/staging/rtl8188eu/include/Hal8188EPhyCfg.h | 5 ----- drivers/staging/rtl8188eu/include/Hal8188EPhyReg.h | 5 ----- drivers/staging/rtl8188eu/include/HalHWImg8188E_FW.h | 5 ----- drivers/staging/rtl8188eu/include/HalVerDef.h | 5 ----- drivers/staging/rtl8188eu/include/basic_types.h | 5 ----- drivers/staging/rtl8188eu/include/drv_types.h | 5 ----- drivers/staging/rtl8188eu/include/fw.h | 4 ---- drivers/staging/rtl8188eu/include/hal_com.h | 5 ----- drivers/staging/rtl8188eu/include/hal_intf.h | 5 ----- drivers/staging/rtl8188eu/include/ieee80211.h | 5 ----- drivers/staging/rtl8188eu/include/mlme_osdep.h | 5 ----- drivers/staging/rtl8188eu/include/mp_custom_oid.h | 5 ----- drivers/staging/rtl8188eu/include/odm.h | 5 ----- drivers/staging/rtl8188eu/include/odm_HWConfig.h | 4 ---- drivers/staging/rtl8188eu/include/odm_RTL8188E.h | 5 ----- drivers/staging/rtl8188eu/include/odm_RegDefine11N.h | 5 ----- drivers/staging/rtl8188eu/include/odm_debug.h | 5 ----- drivers/staging/rtl8188eu/include/odm_precomp.h | 5 ----- drivers/staging/rtl8188eu/include/odm_reg.h | 5 ----- drivers/staging/rtl8188eu/include/odm_types.h | 5 ----- drivers/staging/rtl8188eu/include/osdep_intf.h | 5 ----- drivers/staging/rtl8188eu/include/osdep_service.h | 5 ----- drivers/staging/rtl8188eu/include/pwrseq.h | 5 ----- drivers/staging/rtl8188eu/include/pwrseqcmd.h | 5 ----- drivers/staging/rtl8188eu/include/recv_osdep.h | 5 ----- drivers/staging/rtl8188eu/include/rtl8188e_cmd.h | 5 ----- drivers/staging/rtl8188eu/include/rtl8188e_dm.h | 5 ----- drivers/staging/rtl8188eu/include/rtl8188e_hal.h | 5 ----- drivers/staging/rtl8188eu/include/rtl8188e_led.h | 5 ----- drivers/staging/rtl8188eu/include/rtl8188e_recv.h | 5 ----- drivers/staging/rtl8188eu/include/rtl8188e_spec.h | 4 ---- drivers/staging/rtl8188eu/include/rtl8188e_xmit.h | 5 ----- drivers/staging/rtl8188eu/include/rtw_android.h | 5 ----- drivers/staging/rtl8188eu/include/rtw_ap.h | 5 ----- drivers/staging/rtl8188eu/include/rtw_cmd.h | 5 ----- drivers/staging/rtl8188eu/include/rtw_debug.h | 5 ----- drivers/staging/rtl8188eu/include/rtw_eeprom.h | 5 ----- drivers/staging/rtl8188eu/include/rtw_efuse.h | 5 ----- drivers/staging/rtl8188eu/include/rtw_event.h | 5 ----- drivers/staging/rtl8188eu/include/rtw_ht.h | 5 ----- drivers/staging/rtl8188eu/include/rtw_ioctl.h | 5 ----- drivers/staging/rtl8188eu/include/rtw_ioctl_rtl.h | 5 ----- drivers/staging/rtl8188eu/include/rtw_ioctl_set.h | 5 ----- drivers/staging/rtl8188eu/include/rtw_iol.h | 5 ----- drivers/staging/rtl8188eu/include/rtw_mlme.h | 5 ----- drivers/staging/rtl8188eu/include/rtw_mlme_ext.h | 5 ----- drivers/staging/rtl8188eu/include/rtw_mp_phy_regdef.h | 5 ----- drivers/staging/rtl8188eu/include/rtw_pwrctrl.h | 5 ----- drivers/staging/rtl8188eu/include/rtw_qos.h | 5 ----- drivers/staging/rtl8188eu/include/rtw_recv.h | 5 ----- drivers/staging/rtl8188eu/include/rtw_rf.h | 5 ----- drivers/staging/rtl8188eu/include/rtw_security.h | 5 ----- drivers/staging/rtl8188eu/include/rtw_sreset.h | 5 ----- drivers/staging/rtl8188eu/include/rtw_xmit.h | 5 ----- drivers/staging/rtl8188eu/include/sta_info.h | 5 ----- drivers/staging/rtl8188eu/include/usb_hal.h | 5 ----- drivers/staging/rtl8188eu/include/usb_ops_linux.h | 5 ----- drivers/staging/rtl8188eu/include/wifi.h | 5 ----- drivers/staging/rtl8188eu/include/wlan_bssdef.h | 5 ----- drivers/staging/rtl8188eu/include/xmit_osdep.h | 5 ----- drivers/staging/rtl8188eu/os_dep/ioctl_linux.c | 5 ----- drivers/staging/rtl8188eu/os_dep/mlme_linux.c | 5 ----- drivers/staging/rtl8188eu/os_dep/os_intfs.c | 5 ----- drivers/staging/rtl8188eu/os_dep/osdep_service.c | 5 ----- drivers/staging/rtl8188eu/os_dep/recv_linux.c | 5 ----- drivers/staging/rtl8188eu/os_dep/rtw_android.c | 5 ----- drivers/staging/rtl8188eu/os_dep/usb_intf.c | 5 ----- drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c | 4 ---- drivers/staging/rtl8188eu/os_dep/xmit_linux.c | 5 ----- 107 files changed, 528 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8188eu/core/rtw_ap.c b/drivers/staging/rtl8188eu/core/rtw_ap.c index 012860b34651..a5755358cc5d 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ap.c +++ b/drivers/staging/rtl8188eu/core/rtw_ap.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #define _RTW_AP_C_ diff --git a/drivers/staging/rtl8188eu/core/rtw_cmd.c b/drivers/staging/rtl8188eu/core/rtw_cmd.c index e5a6b7a70df7..f08d052f8e52 100644 --- a/drivers/staging/rtl8188eu/core/rtw_cmd.c +++ b/drivers/staging/rtl8188eu/core/rtw_cmd.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #define _RTW_CMD_C_ diff --git a/drivers/staging/rtl8188eu/core/rtw_debug.c b/drivers/staging/rtl8188eu/core/rtw_debug.c index 93e898d598fe..db5c952ac852 100644 --- a/drivers/staging/rtl8188eu/core/rtw_debug.c +++ b/drivers/staging/rtl8188eu/core/rtw_debug.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #define _RTW_DEBUG_C_ diff --git a/drivers/staging/rtl8188eu/core/rtw_efuse.c b/drivers/staging/rtl8188eu/core/rtw_efuse.c index 19f11d04d152..fbce1f7e68ca 100644 --- a/drivers/staging/rtl8188eu/core/rtw_efuse.c +++ b/drivers/staging/rtl8188eu/core/rtw_efuse.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #define _RTW_EFUSE_C_ diff --git a/drivers/staging/rtl8188eu/core/rtw_ieee80211.c b/drivers/staging/rtl8188eu/core/rtw_ieee80211.c index f4e4baf6054a..0b0d78fe83ed 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ieee80211.c +++ b/drivers/staging/rtl8188eu/core/rtw_ieee80211.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #define _IEEE80211_C diff --git a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c index cf60717a6c19..f85a6abec3a3 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c +++ b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #define _RTW_IOCTL_SET_C_ diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme.c b/drivers/staging/rtl8188eu/core/rtw_mlme.c index a645a620ebe2..472cd3f381cb 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #define _RTW_MLME_C_ diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c index 591a9127b573..da6ccc1a69cc 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #define _RTW_MLME_EXT_C_ diff --git a/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c b/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c index 5e1ef9fdcf47..59c6d8ab60f6 100644 --- a/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c +++ b/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #define _RTW_PWRCTRL_C_ diff --git a/drivers/staging/rtl8188eu/core/rtw_recv.c b/drivers/staging/rtl8188eu/core/rtw_recv.c index 5f53aa1cfd8a..977bb2532c3e 100644 --- a/drivers/staging/rtl8188eu/core/rtw_recv.c +++ b/drivers/staging/rtl8188eu/core/rtw_recv.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #define _RTW_RECV_C_ diff --git a/drivers/staging/rtl8188eu/core/rtw_rf.c b/drivers/staging/rtl8188eu/core/rtw_rf.c index 4ad2d8f63acf..3fc1a8fd367c 100644 --- a/drivers/staging/rtl8188eu/core/rtw_rf.c +++ b/drivers/staging/rtl8188eu/core/rtw_rf.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #define _RTW_RF_C_ diff --git a/drivers/staging/rtl8188eu/core/rtw_security.c b/drivers/staging/rtl8188eu/core/rtw_security.c index b781ccf45bc0..442a614a3726 100644 --- a/drivers/staging/rtl8188eu/core/rtw_security.c +++ b/drivers/staging/rtl8188eu/core/rtw_security.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #define _RTW_SECURITY_C_ diff --git a/drivers/staging/rtl8188eu/core/rtw_sreset.c b/drivers/staging/rtl8188eu/core/rtw_sreset.c index e725a4708775..13a5bf4730ab 100644 --- a/drivers/staging/rtl8188eu/core/rtw_sreset.c +++ b/drivers/staging/rtl8188eu/core/rtw_sreset.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #include diff --git a/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c b/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c index 78a9b9bf3b32..a71e25294add 100644 --- a/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c +++ b/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #define _RTW_STA_MGT_C_ diff --git a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c index 83096696cd5b..4410fe8d7c68 100644 --- a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c +++ b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #define _RTW_WLAN_UTIL_C_ diff --git a/drivers/staging/rtl8188eu/core/rtw_xmit.c b/drivers/staging/rtl8188eu/core/rtw_xmit.c index f2dd7a60f67c..e0a5567f5942 100644 --- a/drivers/staging/rtl8188eu/core/rtw_xmit.c +++ b/drivers/staging/rtl8188eu/core/rtw_xmit.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #define _RTW_XMIT_C_ diff --git a/drivers/staging/rtl8188eu/hal/bb_cfg.c b/drivers/staging/rtl8188eu/hal/bb_cfg.c index c2ad6a3b99da..cce1ea259b76 100644 --- a/drivers/staging/rtl8188eu/hal/bb_cfg.c +++ b/drivers/staging/rtl8188eu/hal/bb_cfg.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * -* You should have received a copy of the GNU General Public License along with -* this program; if not, write to the Free Software Foundation, Inc., -* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA -* -* ******************************************************************************/ #include "odm_precomp.h" diff --git a/drivers/staging/rtl8188eu/hal/fw.c b/drivers/staging/rtl8188eu/hal/fw.c index 656133c47426..03d091bad13a 100644 --- a/drivers/staging/rtl8188eu/hal/fw.c +++ b/drivers/staging/rtl8188eu/hal/fw.c @@ -11,10 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * diff --git a/drivers/staging/rtl8188eu/hal/hal_com.c b/drivers/staging/rtl8188eu/hal/hal_com.c index 3871cda2eec2..960cc406d238 100644 --- a/drivers/staging/rtl8188eu/hal/hal_com.c +++ b/drivers/staging/rtl8188eu/hal/hal_com.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #include #include diff --git a/drivers/staging/rtl8188eu/hal/hal_intf.c b/drivers/staging/rtl8188eu/hal/hal_intf.c index 85c17ef942f3..c49c86ccea76 100644 --- a/drivers/staging/rtl8188eu/hal/hal_intf.c +++ b/drivers/staging/rtl8188eu/hal/hal_intf.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #define _HAL_INTF_C_ diff --git a/drivers/staging/rtl8188eu/hal/mac_cfg.c b/drivers/staging/rtl8188eu/hal/mac_cfg.c index 0bc1b215219a..6ed5e15ce661 100644 --- a/drivers/staging/rtl8188eu/hal/mac_cfg.c +++ b/drivers/staging/rtl8188eu/hal/mac_cfg.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * -* You should have received a copy of the GNU General Public License along with -* this program; if not, write to the Free Software Foundation, Inc., -* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA -* -* ******************************************************************************/ #include "odm_precomp.h" diff --git a/drivers/staging/rtl8188eu/hal/odm.c b/drivers/staging/rtl8188eu/hal/odm.c index 8d2316b9e6e5..57a127501694 100644 --- a/drivers/staging/rtl8188eu/hal/odm.c +++ b/drivers/staging/rtl8188eu/hal/odm.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ /* include files */ diff --git a/drivers/staging/rtl8188eu/hal/odm_HWConfig.c b/drivers/staging/rtl8188eu/hal/odm_HWConfig.c index 28b9f7f591c0..0555e42a3787 100644 --- a/drivers/staging/rtl8188eu/hal/odm_HWConfig.c +++ b/drivers/staging/rtl8188eu/hal/odm_HWConfig.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ /* include files */ diff --git a/drivers/staging/rtl8188eu/hal/odm_RTL8188E.c b/drivers/staging/rtl8188eu/hal/odm_RTL8188E.c index c0242a095c19..dd9b902c8ae3 100644 --- a/drivers/staging/rtl8188eu/hal/odm_RTL8188E.c +++ b/drivers/staging/rtl8188eu/hal/odm_RTL8188E.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #include "odm_precomp.h" diff --git a/drivers/staging/rtl8188eu/hal/phy.c b/drivers/staging/rtl8188eu/hal/phy.c index ae42b4492c77..a83bbea9be93 100644 --- a/drivers/staging/rtl8188eu/hal/phy.c +++ b/drivers/staging/rtl8188eu/hal/phy.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #define _RTL8188E_PHYCFG_C_ diff --git a/drivers/staging/rtl8188eu/hal/pwrseq.c b/drivers/staging/rtl8188eu/hal/pwrseq.c index 20dce42cee1d..d92a34ea8d60 100644 --- a/drivers/staging/rtl8188eu/hal/pwrseq.c +++ b/drivers/staging/rtl8188eu/hal/pwrseq.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #include "pwrseq.h" diff --git a/drivers/staging/rtl8188eu/hal/pwrseqcmd.c b/drivers/staging/rtl8188eu/hal/pwrseqcmd.c index b76b0f5d6220..2867864bbfbe 100644 --- a/drivers/staging/rtl8188eu/hal/pwrseqcmd.c +++ b/drivers/staging/rtl8188eu/hal/pwrseqcmd.c @@ -11,10 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * ******************************************************************************/ #include diff --git a/drivers/staging/rtl8188eu/hal/rf.c b/drivers/staging/rtl8188eu/hal/rf.c index 38845d17d593..1596274eefc5 100644 --- a/drivers/staging/rtl8188eu/hal/rf.c +++ b/drivers/staging/rtl8188eu/hal/rf.c @@ -11,10 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * ******************************************************************************/ #include diff --git a/drivers/staging/rtl8188eu/hal/rf_cfg.c b/drivers/staging/rtl8188eu/hal/rf_cfg.c index 44945427cc34..453f9e729067 100644 --- a/drivers/staging/rtl8188eu/hal/rf_cfg.c +++ b/drivers/staging/rtl8188eu/hal/rf_cfg.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * -* You should have received a copy of the GNU General Public License along with -* this program; if not, write to the Free Software Foundation, Inc., -* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA -* -* ******************************************************************************/ #include "odm_precomp.h" diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c b/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c index 580876313e98..2422c0297a50 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #define _RTL8188E_CMD_C_ diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_dm.c b/drivers/staging/rtl8188eu/hal/rtl8188e_dm.c index f9919a94a77e..81f2931876f8 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_dm.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_dm.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ /* */ /* Description: */ diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c index 2592bc298f84..0b444fd3e550 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #define _HAL_INIT_C_ diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c b/drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c index 4c78369673b6..4ac6bcf9dada 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #define _RTL8188E_REDESC_C_ diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_xmit.c b/drivers/staging/rtl8188eu/hal/rtl8188e_xmit.c index a6ba53b488e3..460a20558bc0 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_xmit.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_xmit.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #define _RTL8188E_XMIT_C_ diff --git a/drivers/staging/rtl8188eu/hal/rtl8188eu_led.c b/drivers/staging/rtl8188eu/hal/rtl8188eu_led.c index 564cf53bff1b..d9e677ef8f84 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188eu_led.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188eu_led.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #include diff --git a/drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c b/drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c index d6d009aafcf0..255d6f215091 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #define _RTL8188EU_RECV_C_ #include diff --git a/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c b/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c index c96d80487a56..ec21d8c82eba 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #define _RTL8188E_XMIT_C_ #include diff --git a/drivers/staging/rtl8188eu/hal/usb_halinit.c b/drivers/staging/rtl8188eu/hal/usb_halinit.c index 07a61b8271f0..358762d3fb45 100644 --- a/drivers/staging/rtl8188eu/hal/usb_halinit.c +++ b/drivers/staging/rtl8188eu/hal/usb_halinit.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #define _HCI_HAL_INIT_C_ diff --git a/drivers/staging/rtl8188eu/include/Hal8188EPhyCfg.h b/drivers/staging/rtl8188eu/include/Hal8188EPhyCfg.h index 2670d6b6a79e..8990748a1919 100644 --- a/drivers/staging/rtl8188eu/include/Hal8188EPhyCfg.h +++ b/drivers/staging/rtl8188eu/include/Hal8188EPhyCfg.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __INC_HAL8188EPHYCFG_H__ #define __INC_HAL8188EPHYCFG_H__ diff --git a/drivers/staging/rtl8188eu/include/Hal8188EPhyReg.h b/drivers/staging/rtl8188eu/include/Hal8188EPhyReg.h index 9f2969bf8355..344c73d1081b 100644 --- a/drivers/staging/rtl8188eu/include/Hal8188EPhyReg.h +++ b/drivers/staging/rtl8188eu/include/Hal8188EPhyReg.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __INC_HAL8188EPHYREG_H__ #define __INC_HAL8188EPHYREG_H__ diff --git a/drivers/staging/rtl8188eu/include/HalHWImg8188E_FW.h b/drivers/staging/rtl8188eu/include/HalHWImg8188E_FW.h index 1bf9bc70a696..dbb55247b0c6 100644 --- a/drivers/staging/rtl8188eu/include/HalHWImg8188E_FW.h +++ b/drivers/staging/rtl8188eu/include/HalHWImg8188E_FW.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * -* You should have received a copy of the GNU General Public License along with -* this program; if not, write to the Free Software Foundation, Inc., -* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA -* -* ******************************************************************************/ #ifndef __INC_FW_8188E_HW_IMG_H diff --git a/drivers/staging/rtl8188eu/include/HalVerDef.h b/drivers/staging/rtl8188eu/include/HalVerDef.h index 6f2b2a436b04..d244efff3593 100644 --- a/drivers/staging/rtl8188eu/include/HalVerDef.h +++ b/drivers/staging/rtl8188eu/include/HalVerDef.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __HAL_VERSION_DEF_H__ #define __HAL_VERSION_DEF_H__ diff --git a/drivers/staging/rtl8188eu/include/basic_types.h b/drivers/staging/rtl8188eu/include/basic_types.h index 3fb691daa5af..2c1676d2ac6e 100644 --- a/drivers/staging/rtl8188eu/include/basic_types.h +++ b/drivers/staging/rtl8188eu/include/basic_types.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __BASIC_TYPES_H__ #define __BASIC_TYPES_H__ diff --git a/drivers/staging/rtl8188eu/include/drv_types.h b/drivers/staging/rtl8188eu/include/drv_types.h index dcb032b6c3a7..55506a7da1a4 100644 --- a/drivers/staging/rtl8188eu/include/drv_types.h +++ b/drivers/staging/rtl8188eu/include/drv_types.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ /*----------------------------------------------------------------------------- diff --git a/drivers/staging/rtl8188eu/include/fw.h b/drivers/staging/rtl8188eu/include/fw.h index 7884d8f65763..b016f32a8992 100644 --- a/drivers/staging/rtl8188eu/include/fw.h +++ b/drivers/staging/rtl8188eu/include/fw.h @@ -11,10 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * diff --git a/drivers/staging/rtl8188eu/include/hal_com.h b/drivers/staging/rtl8188eu/include/hal_com.h index 47715d949d54..aaf444733507 100644 --- a/drivers/staging/rtl8188eu/include/hal_com.h +++ b/drivers/staging/rtl8188eu/include/hal_com.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __HAL_COMMON_H__ #define __HAL_COMMON_H__ diff --git a/drivers/staging/rtl8188eu/include/hal_intf.h b/drivers/staging/rtl8188eu/include/hal_intf.h index 1b1c10292456..eaf939bd4103 100644 --- a/drivers/staging/rtl8188eu/include/hal_intf.h +++ b/drivers/staging/rtl8188eu/include/hal_intf.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __HAL_INTF_H__ #define __HAL_INTF_H__ diff --git a/drivers/staging/rtl8188eu/include/ieee80211.h b/drivers/staging/rtl8188eu/include/ieee80211.h index f8f5eb6b7976..d8284c84f09c 100644 --- a/drivers/staging/rtl8188eu/include/ieee80211.h +++ b/drivers/staging/rtl8188eu/include/ieee80211.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __IEEE80211_H #define __IEEE80211_H diff --git a/drivers/staging/rtl8188eu/include/mlme_osdep.h b/drivers/staging/rtl8188eu/include/mlme_osdep.h index ae1722c67032..5a35b0866db6 100644 --- a/drivers/staging/rtl8188eu/include/mlme_osdep.h +++ b/drivers/staging/rtl8188eu/include/mlme_osdep.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __MLME_OSDEP_H_ #define __MLME_OSDEP_H_ diff --git a/drivers/staging/rtl8188eu/include/mp_custom_oid.h b/drivers/staging/rtl8188eu/include/mp_custom_oid.h index 6fa52cf99c4e..1a06ee6ad460 100644 --- a/drivers/staging/rtl8188eu/include/mp_custom_oid.h +++ b/drivers/staging/rtl8188eu/include/mp_custom_oid.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __CUSTOM_OID_H #define __CUSTOM_OID_H diff --git a/drivers/staging/rtl8188eu/include/odm.h b/drivers/staging/rtl8188eu/include/odm.h index af781c7cd3a5..dbebf17f36d3 100644 --- a/drivers/staging/rtl8188eu/include/odm.h +++ b/drivers/staging/rtl8188eu/include/odm.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ diff --git a/drivers/staging/rtl8188eu/include/odm_HWConfig.h b/drivers/staging/rtl8188eu/include/odm_HWConfig.h index ef792bfd535e..da7325d599c6 100644 --- a/drivers/staging/rtl8188eu/include/odm_HWConfig.h +++ b/drivers/staging/rtl8188eu/include/odm_HWConfig.h @@ -11,10 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * ******************************************************************************/ diff --git a/drivers/staging/rtl8188eu/include/odm_RTL8188E.h b/drivers/staging/rtl8188eu/include/odm_RTL8188E.h index 14dce6c4b1bc..72b4db67ac33 100644 --- a/drivers/staging/rtl8188eu/include/odm_RTL8188E.h +++ b/drivers/staging/rtl8188eu/include/odm_RTL8188E.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __ODM_RTL8188E_H__ #define __ODM_RTL8188E_H__ diff --git a/drivers/staging/rtl8188eu/include/odm_RegDefine11N.h b/drivers/staging/rtl8188eu/include/odm_RegDefine11N.h index 5a61f902bc1b..c82c09013487 100644 --- a/drivers/staging/rtl8188eu/include/odm_RegDefine11N.h +++ b/drivers/staging/rtl8188eu/include/odm_RegDefine11N.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __ODM_REGDEFINE11N_H__ diff --git a/drivers/staging/rtl8188eu/include/odm_debug.h b/drivers/staging/rtl8188eu/include/odm_debug.h index e9390963d6ff..52e51f19f752 100644 --- a/drivers/staging/rtl8188eu/include/odm_debug.h +++ b/drivers/staging/rtl8188eu/include/odm_debug.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ diff --git a/drivers/staging/rtl8188eu/include/odm_precomp.h b/drivers/staging/rtl8188eu/include/odm_precomp.h index 0f236da09277..9e5fe1777e6c 100644 --- a/drivers/staging/rtl8188eu/include/odm_precomp.h +++ b/drivers/staging/rtl8188eu/include/odm_precomp.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __ODM_PRECOMP_H__ diff --git a/drivers/staging/rtl8188eu/include/odm_reg.h b/drivers/staging/rtl8188eu/include/odm_reg.h index 7f10b695cf9d..3405a44a19ed 100644 --- a/drivers/staging/rtl8188eu/include/odm_reg.h +++ b/drivers/staging/rtl8188eu/include/odm_reg.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ /* */ /* File Name: odm_reg.h */ diff --git a/drivers/staging/rtl8188eu/include/odm_types.h b/drivers/staging/rtl8188eu/include/odm_types.h index c1355b959c55..3474a9c72640 100644 --- a/drivers/staging/rtl8188eu/include/odm_types.h +++ b/drivers/staging/rtl8188eu/include/odm_types.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __ODM_TYPES_H__ #define __ODM_TYPES_H__ diff --git a/drivers/staging/rtl8188eu/include/osdep_intf.h b/drivers/staging/rtl8188eu/include/osdep_intf.h index 1521744d626c..54fca79827e3 100644 --- a/drivers/staging/rtl8188eu/include/osdep_intf.h +++ b/drivers/staging/rtl8188eu/include/osdep_intf.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __OSDEP_INTF_H_ diff --git a/drivers/staging/rtl8188eu/include/osdep_service.h b/drivers/staging/rtl8188eu/include/osdep_service.h index 22de53d6539a..5475956c5ee5 100644 --- a/drivers/staging/rtl8188eu/include/osdep_service.h +++ b/drivers/staging/rtl8188eu/include/osdep_service.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __OSDEP_SERVICE_H_ #define __OSDEP_SERVICE_H_ diff --git a/drivers/staging/rtl8188eu/include/pwrseq.h b/drivers/staging/rtl8188eu/include/pwrseq.h index 9dbf8435f147..afd61cf4cb15 100644 --- a/drivers/staging/rtl8188eu/include/pwrseq.h +++ b/drivers/staging/rtl8188eu/include/pwrseq.h @@ -12,11 +12,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __HAL8188EPWRSEQ_H__ diff --git a/drivers/staging/rtl8188eu/include/pwrseqcmd.h b/drivers/staging/rtl8188eu/include/pwrseqcmd.h index 468a3fb28e00..c4a919ea17ea 100644 --- a/drivers/staging/rtl8188eu/include/pwrseqcmd.h +++ b/drivers/staging/rtl8188eu/include/pwrseqcmd.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __HALPWRSEQCMD_H__ #define __HALPWRSEQCMD_H__ diff --git a/drivers/staging/rtl8188eu/include/recv_osdep.h b/drivers/staging/rtl8188eu/include/recv_osdep.h index fdeb603b6cc1..cad31587c30a 100644 --- a/drivers/staging/rtl8188eu/include/recv_osdep.h +++ b/drivers/staging/rtl8188eu/include/recv_osdep.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __RECV_OSDEP_H_ #define __RECV_OSDEP_H_ diff --git a/drivers/staging/rtl8188eu/include/rtl8188e_cmd.h b/drivers/staging/rtl8188eu/include/rtl8188e_cmd.h index f813ce0563f8..4d7d804658c2 100644 --- a/drivers/staging/rtl8188eu/include/rtl8188e_cmd.h +++ b/drivers/staging/rtl8188eu/include/rtl8188e_cmd.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __RTL8188E_CMD_H__ #define __RTL8188E_CMD_H__ diff --git a/drivers/staging/rtl8188eu/include/rtl8188e_dm.h b/drivers/staging/rtl8188eu/include/rtl8188e_dm.h index 5e0ac31ef464..4190112a50bf 100644 --- a/drivers/staging/rtl8188eu/include/rtl8188e_dm.h +++ b/drivers/staging/rtl8188eu/include/rtl8188e_dm.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __RTL8188E_DM_H__ #define __RTL8188E_DM_H__ diff --git a/drivers/staging/rtl8188eu/include/rtl8188e_hal.h b/drivers/staging/rtl8188eu/include/rtl8188e_hal.h index 9f5050e6f6ab..9dd5c293a54b 100644 --- a/drivers/staging/rtl8188eu/include/rtl8188e_hal.h +++ b/drivers/staging/rtl8188eu/include/rtl8188e_hal.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __RTL8188E_HAL_H__ #define __RTL8188E_HAL_H__ diff --git a/drivers/staging/rtl8188eu/include/rtl8188e_led.h b/drivers/staging/rtl8188eu/include/rtl8188e_led.h index c0147e73cd8c..fca6d8c81e90 100644 --- a/drivers/staging/rtl8188eu/include/rtl8188e_led.h +++ b/drivers/staging/rtl8188eu/include/rtl8188e_led.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __RTL8188E_LED_H__ #define __RTL8188E_LED_H__ diff --git a/drivers/staging/rtl8188eu/include/rtl8188e_recv.h b/drivers/staging/rtl8188eu/include/rtl8188e_recv.h index 5fed30d389a2..54048bc826e5 100644 --- a/drivers/staging/rtl8188eu/include/rtl8188e_recv.h +++ b/drivers/staging/rtl8188eu/include/rtl8188e_recv.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __RTL8188E_RECV_H__ #define __RTL8188E_RECV_H__ diff --git a/drivers/staging/rtl8188eu/include/rtl8188e_spec.h b/drivers/staging/rtl8188eu/include/rtl8188e_spec.h index beeee4a6b0bc..fb82f663b1f5 100644 --- a/drivers/staging/rtl8188eu/include/rtl8188e_spec.h +++ b/drivers/staging/rtl8188eu/include/rtl8188e_spec.h @@ -11,10 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * *******************************************************************************/ #ifndef __RTL8188E_SPEC_H__ #define __RTL8188E_SPEC_H__ diff --git a/drivers/staging/rtl8188eu/include/rtl8188e_xmit.h b/drivers/staging/rtl8188eu/include/rtl8188e_xmit.h index 0b96d42e290b..65a63df2077f 100644 --- a/drivers/staging/rtl8188eu/include/rtl8188e_xmit.h +++ b/drivers/staging/rtl8188eu/include/rtl8188e_xmit.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __RTL8188E_XMIT_H__ #define __RTL8188E_XMIT_H__ diff --git a/drivers/staging/rtl8188eu/include/rtw_android.h b/drivers/staging/rtl8188eu/include/rtw_android.h index e85bf1ff01f8..e81ee92b0ae2 100644 --- a/drivers/staging/rtl8188eu/include/rtw_android.h +++ b/drivers/staging/rtl8188eu/include/rtw_android.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __RTW_ANDROID_H__ diff --git a/drivers/staging/rtl8188eu/include/rtw_ap.h b/drivers/staging/rtl8188eu/include/rtw_ap.h index 6128ccce91ba..b820684bc3fe 100644 --- a/drivers/staging/rtl8188eu/include/rtw_ap.h +++ b/drivers/staging/rtl8188eu/include/rtw_ap.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __RTW_AP_H_ #define __RTW_AP_H_ diff --git a/drivers/staging/rtl8188eu/include/rtw_cmd.h b/drivers/staging/rtl8188eu/include/rtw_cmd.h index 9e9f5f4af8f1..08ca59217cb7 100644 --- a/drivers/staging/rtl8188eu/include/rtw_cmd.h +++ b/drivers/staging/rtl8188eu/include/rtw_cmd.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __RTW_CMD_H_ #define __RTW_CMD_H_ diff --git a/drivers/staging/rtl8188eu/include/rtw_debug.h b/drivers/staging/rtl8188eu/include/rtw_debug.h index 971bf457f32d..7ed4cada7efa 100644 --- a/drivers/staging/rtl8188eu/include/rtw_debug.h +++ b/drivers/staging/rtl8188eu/include/rtw_debug.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __RTW_DEBUG_H__ #define __RTW_DEBUG_H__ diff --git a/drivers/staging/rtl8188eu/include/rtw_eeprom.h b/drivers/staging/rtl8188eu/include/rtw_eeprom.h index 904fea1fad6c..5dd73841dd9e 100644 --- a/drivers/staging/rtl8188eu/include/rtw_eeprom.h +++ b/drivers/staging/rtl8188eu/include/rtw_eeprom.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __RTW_EEPROM_H__ #define __RTW_EEPROM_H__ diff --git a/drivers/staging/rtl8188eu/include/rtw_efuse.h b/drivers/staging/rtl8188eu/include/rtw_efuse.h index 5660eed7196b..9bfb10c302b5 100644 --- a/drivers/staging/rtl8188eu/include/rtw_efuse.h +++ b/drivers/staging/rtl8188eu/include/rtw_efuse.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __RTW_EFUSE_H__ #define __RTW_EFUSE_H__ diff --git a/drivers/staging/rtl8188eu/include/rtw_event.h b/drivers/staging/rtl8188eu/include/rtw_event.h index 52151dc4495a..5c34e567d341 100644 --- a/drivers/staging/rtl8188eu/include/rtw_event.h +++ b/drivers/staging/rtl8188eu/include/rtw_event.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef _RTW_EVENT_H_ #define _RTW_EVENT_H_ diff --git a/drivers/staging/rtl8188eu/include/rtw_ht.h b/drivers/staging/rtl8188eu/include/rtw_ht.h index beb210b37083..b45483fd069f 100644 --- a/drivers/staging/rtl8188eu/include/rtw_ht.h +++ b/drivers/staging/rtl8188eu/include/rtw_ht.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef _RTW_HT_H_ #define _RTW_HT_H_ diff --git a/drivers/staging/rtl8188eu/include/rtw_ioctl.h b/drivers/staging/rtl8188eu/include/rtw_ioctl.h index ee2cb54a7552..3a652df4b26c 100644 --- a/drivers/staging/rtl8188eu/include/rtw_ioctl.h +++ b/drivers/staging/rtl8188eu/include/rtw_ioctl.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef _RTW_IOCTL_H_ #define _RTW_IOCTL_H_ diff --git a/drivers/staging/rtl8188eu/include/rtw_ioctl_rtl.h b/drivers/staging/rtl8188eu/include/rtw_ioctl_rtl.h index 8fa3858cb776..da4949f94f4c 100644 --- a/drivers/staging/rtl8188eu/include/rtw_ioctl_rtl.h +++ b/drivers/staging/rtl8188eu/include/rtw_ioctl_rtl.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef _RTW_IOCTL_RTL_H_ #define _RTW_IOCTL_RTL_H_ diff --git a/drivers/staging/rtl8188eu/include/rtw_ioctl_set.h b/drivers/staging/rtl8188eu/include/rtw_ioctl_set.h index fa9d655eaab9..b6e14a8b7a11 100644 --- a/drivers/staging/rtl8188eu/include/rtw_ioctl_set.h +++ b/drivers/staging/rtl8188eu/include/rtw_ioctl_set.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __RTW_IOCTL_SET_H_ #define __RTW_IOCTL_SET_H_ diff --git a/drivers/staging/rtl8188eu/include/rtw_iol.h b/drivers/staging/rtl8188eu/include/rtw_iol.h index 68aae7f0b02f..1f324e68d2ae 100644 --- a/drivers/staging/rtl8188eu/include/rtw_iol.h +++ b/drivers/staging/rtl8188eu/include/rtw_iol.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __RTW_IOL_H_ #define __RTW_IOL_H_ diff --git a/drivers/staging/rtl8188eu/include/rtw_mlme.h b/drivers/staging/rtl8188eu/include/rtw_mlme.h index 4c992573e3ca..5d8bce0f58db 100644 --- a/drivers/staging/rtl8188eu/include/rtw_mlme.h +++ b/drivers/staging/rtl8188eu/include/rtw_mlme.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __RTW_MLME_H_ #define __RTW_MLME_H_ diff --git a/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h b/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h index 44711332b90c..27382ff24a84 100644 --- a/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __RTW_MLME_EXT_H_ #define __RTW_MLME_EXT_H_ diff --git a/drivers/staging/rtl8188eu/include/rtw_mp_phy_regdef.h b/drivers/staging/rtl8188eu/include/rtw_mp_phy_regdef.h index 30fd17f23bf1..02b300217185 100644 --- a/drivers/staging/rtl8188eu/include/rtw_mp_phy_regdef.h +++ b/drivers/staging/rtl8188eu/include/rtw_mp_phy_regdef.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ /***************************************************************************** * diff --git a/drivers/staging/rtl8188eu/include/rtw_pwrctrl.h b/drivers/staging/rtl8188eu/include/rtw_pwrctrl.h index a493d4c37ef1..9680e2eab62f 100644 --- a/drivers/staging/rtl8188eu/include/rtw_pwrctrl.h +++ b/drivers/staging/rtl8188eu/include/rtw_pwrctrl.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __RTW_PWRCTRL_H_ #define __RTW_PWRCTRL_H_ diff --git a/drivers/staging/rtl8188eu/include/rtw_qos.h b/drivers/staging/rtl8188eu/include/rtw_qos.h index bbee1ddc00bb..45a77f6f8427 100644 --- a/drivers/staging/rtl8188eu/include/rtw_qos.h +++ b/drivers/staging/rtl8188eu/include/rtw_qos.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef _RTW_QOS_H_ #define _RTW_QOS_H_ diff --git a/drivers/staging/rtl8188eu/include/rtw_recv.h b/drivers/staging/rtl8188eu/include/rtw_recv.h index eb1ac3d03123..b0373b6216d6 100644 --- a/drivers/staging/rtl8188eu/include/rtw_recv.h +++ b/drivers/staging/rtl8188eu/include/rtw_recv.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef _RTW_RECV_H_ #define _RTW_RECV_H_ diff --git a/drivers/staging/rtl8188eu/include/rtw_rf.h b/drivers/staging/rtl8188eu/include/rtw_rf.h index 35f61be12acd..66896af02042 100644 --- a/drivers/staging/rtl8188eu/include/rtw_rf.h +++ b/drivers/staging/rtl8188eu/include/rtw_rf.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __RTW_RF_H_ #define __RTW_RF_H_ diff --git a/drivers/staging/rtl8188eu/include/rtw_security.h b/drivers/staging/rtl8188eu/include/rtw_security.h index a1aebe6c8452..ca1247bce6e3 100644 --- a/drivers/staging/rtl8188eu/include/rtw_security.h +++ b/drivers/staging/rtl8188eu/include/rtw_security.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __RTW_SECURITY_H_ #define __RTW_SECURITY_H_ diff --git a/drivers/staging/rtl8188eu/include/rtw_sreset.h b/drivers/staging/rtl8188eu/include/rtw_sreset.h index 3a62ed010875..ce027dfdecc5 100644 --- a/drivers/staging/rtl8188eu/include/rtw_sreset.h +++ b/drivers/staging/rtl8188eu/include/rtw_sreset.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef _RTW_SRESET_C_ #define _RTW_SRESET_C_ diff --git a/drivers/staging/rtl8188eu/include/rtw_xmit.h b/drivers/staging/rtl8188eu/include/rtw_xmit.h index b7c20883d355..a0853bab3edb 100644 --- a/drivers/staging/rtl8188eu/include/rtw_xmit.h +++ b/drivers/staging/rtl8188eu/include/rtw_xmit.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef _RTW_XMIT_H_ #define _RTW_XMIT_H_ diff --git a/drivers/staging/rtl8188eu/include/sta_info.h b/drivers/staging/rtl8188eu/include/sta_info.h index d4e78326fc8d..42a035123365 100644 --- a/drivers/staging/rtl8188eu/include/sta_info.h +++ b/drivers/staging/rtl8188eu/include/sta_info.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __STA_INFO_H_ #define __STA_INFO_H_ diff --git a/drivers/staging/rtl8188eu/include/usb_hal.h b/drivers/staging/rtl8188eu/include/usb_hal.h index 8a65995d5e48..b1bf07a9013e 100644 --- a/drivers/staging/rtl8188eu/include/usb_hal.h +++ b/drivers/staging/rtl8188eu/include/usb_hal.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __USB_HAL_H__ #define __USB_HAL_H__ diff --git a/drivers/staging/rtl8188eu/include/usb_ops_linux.h b/drivers/staging/rtl8188eu/include/usb_ops_linux.h index 4fdc536cba79..220733314f8b 100644 --- a/drivers/staging/rtl8188eu/include/usb_ops_linux.h +++ b/drivers/staging/rtl8188eu/include/usb_ops_linux.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __USB_OPS_LINUX_H__ #define __USB_OPS_LINUX_H__ diff --git a/drivers/staging/rtl8188eu/include/wifi.h b/drivers/staging/rtl8188eu/include/wifi.h index 6cb5beca1672..e7c512183619 100644 --- a/drivers/staging/rtl8188eu/include/wifi.h +++ b/drivers/staging/rtl8188eu/include/wifi.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef _WIFI_H_ #define _WIFI_H_ diff --git a/drivers/staging/rtl8188eu/include/wlan_bssdef.h b/drivers/staging/rtl8188eu/include/wlan_bssdef.h index 85b99da49a2d..560966cd7dfe 100644 --- a/drivers/staging/rtl8188eu/include/wlan_bssdef.h +++ b/drivers/staging/rtl8188eu/include/wlan_bssdef.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __WLAN_BSSDEF_H__ #define __WLAN_BSSDEF_H__ diff --git a/drivers/staging/rtl8188eu/include/xmit_osdep.h b/drivers/staging/rtl8188eu/include/xmit_osdep.h index 13965f2489db..f96ca6af934d 100644 --- a/drivers/staging/rtl8188eu/include/xmit_osdep.h +++ b/drivers/staging/rtl8188eu/include/xmit_osdep.h @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #ifndef __XMIT_OSDEP_H_ #define __XMIT_OSDEP_H_ diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c index 911980495fb2..eeb1694d8bbe 100644 --- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #define _IOCTL_LINUX_C_ diff --git a/drivers/staging/rtl8188eu/os_dep/mlme_linux.c b/drivers/staging/rtl8188eu/os_dep/mlme_linux.c index 08bfa76f4975..bc756267c7fc 100644 --- a/drivers/staging/rtl8188eu/os_dep/mlme_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/mlme_linux.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ diff --git a/drivers/staging/rtl8188eu/os_dep/os_intfs.c b/drivers/staging/rtl8188eu/os_dep/os_intfs.c index 7986e678521a..ae2caff030f1 100644 --- a/drivers/staging/rtl8188eu/os_dep/os_intfs.c +++ b/drivers/staging/rtl8188eu/os_dep/os_intfs.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #define _OS_INTFS_C_ diff --git a/drivers/staging/rtl8188eu/os_dep/osdep_service.c b/drivers/staging/rtl8188eu/os_dep/osdep_service.c index f090bef59594..764250b4ba86 100644 --- a/drivers/staging/rtl8188eu/os_dep/osdep_service.c +++ b/drivers/staging/rtl8188eu/os_dep/osdep_service.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ diff --git a/drivers/staging/rtl8188eu/os_dep/recv_linux.c b/drivers/staging/rtl8188eu/os_dep/recv_linux.c index d4734baffc8a..0c44914ea3e6 100644 --- a/drivers/staging/rtl8188eu/os_dep/recv_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/recv_linux.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #include #include diff --git a/drivers/staging/rtl8188eu/os_dep/rtw_android.c b/drivers/staging/rtl8188eu/os_dep/rtw_android.c index 5f3337c281ee..41e1b1d15b81 100644 --- a/drivers/staging/rtl8188eu/os_dep/rtw_android.c +++ b/drivers/staging/rtl8188eu/os_dep/rtw_android.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #include diff --git a/drivers/staging/rtl8188eu/os_dep/usb_intf.c b/drivers/staging/rtl8188eu/os_dep/usb_intf.c index 794cc114348c..8fd608d6027a 100644 --- a/drivers/staging/rtl8188eu/os_dep/usb_intf.c +++ b/drivers/staging/rtl8188eu/os_dep/usb_intf.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #define pr_fmt(fmt) "R8188EU: " fmt diff --git a/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c b/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c index 0fea338d7313..ce1e1a135f1b 100644 --- a/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c @@ -11,10 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * ******************************************************************************/ #define _USB_OPS_LINUX_C_ diff --git a/drivers/staging/rtl8188eu/os_dep/xmit_linux.c b/drivers/staging/rtl8188eu/os_dep/xmit_linux.c index 1593e280e060..221e2750652e 100644 --- a/drivers/staging/rtl8188eu/os_dep/xmit_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/xmit_linux.c @@ -11,11 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * ******************************************************************************/ #define _XMIT_OSDEP_C_ -- cgit v1.2.3 From 17d4591d96d66806d0edd759897699ae50f0e4d4 Mon Sep 17 00:00:00 2001 From: Nicholas Sim Date: Fri, 18 Mar 2016 12:11:07 +0000 Subject: staging: rtl8188eu: remove return at end of void function call Remove unnecessary return statement from last line of void function call Signed-off-by: Nicholas Sim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_mlme_ext.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c index da6ccc1a69cc..86108d4bec0a 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c @@ -2100,7 +2100,6 @@ static void site_survey(struct adapter *padapter) issue_action_BSSCoexistPacket(padapter); issue_action_BSSCoexistPacket(padapter); } - return; } /* collect bss info from Beacon and Probe request/response frames. */ -- cgit v1.2.3 From 7f69e09aba50113c639a2ed1cbc0e033808b16f2 Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Sat, 19 Mar 2016 16:14:30 +0530 Subject: Staging: rtl8188eu: Hal8188ERateAdaptive: Use x instead of x != NULL. Use x instead of x != NULL. Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/hal/Hal8188ERateAdaptive.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8188eu/hal/Hal8188ERateAdaptive.c b/drivers/staging/rtl8188eu/hal/Hal8188ERateAdaptive.c index a108e8032327..201c15b07f9e 100644 --- a/drivers/staging/rtl8188eu/hal/Hal8188ERateAdaptive.c +++ b/drivers/staging/rtl8188eu/hal/Hal8188ERateAdaptive.c @@ -557,7 +557,7 @@ int ODM_RAInfo_Init(struct odm_dm_struct *dm_odm, u8 macid) u8 WirelessMode = 0xFF; /* invalid value */ u8 max_rate_idx = 0x13; /* MCS7 */ - if (dm_odm->pWirelessMode != NULL) + if (dm_odm->pWirelessMode) WirelessMode = *(dm_odm->pWirelessMode); if (WirelessMode != 0xFF) { -- cgit v1.2.3 From 79146cedc30aba94045114020608dbf951f4c1ff Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Sat, 19 Mar 2016 16:16:38 +0530 Subject: Staging: rtl8188eu: hal_intf: Use x instead of x != NULL. Use x instead of x != NULL. Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/hal/hal_intf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8188eu/hal/hal_intf.c b/drivers/staging/rtl8188eu/hal/hal_intf.c index c49c86ccea76..085f0fbd0c43 100644 --- a/drivers/staging/rtl8188eu/hal/hal_intf.c +++ b/drivers/staging/rtl8188eu/hal/hal_intf.c @@ -181,7 +181,7 @@ s32 rtw_hal_mgnt_xmit(struct adapter *adapt, struct xmit_frame *pmgntframe) s32 rtw_hal_init_xmit_priv(struct adapter *adapt) { - if (adapt->HalFunc.init_xmit_priv != NULL) + if (adapt->HalFunc.init_xmit_priv) return adapt->HalFunc.init_xmit_priv(adapt); return _FAIL; } -- cgit v1.2.3 From eec1c50002eafe1c48b550fff10bf3eca83f46ea Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Sat, 19 Mar 2016 16:18:47 +0530 Subject: Staging: rtl8188eu: rtl8188e_rxdesc: Use !x instead of x == NULL. Use !x instead of x == NULL. Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c b/drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c index 4ac6bcf9dada..f110c961df70 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c @@ -40,7 +40,7 @@ static void process_link_qual(struct adapter *padapter, struct rx_pkt_attrib *pattrib; struct signal_stat *signal_stat; - if (prframe == NULL || padapter == NULL) + if (!prframe || !padapter) return; pattrib = &prframe->attrib; -- cgit v1.2.3 From f3e80d80e9db08edc3de35996027a657b4a8c8de Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Sat, 19 Mar 2016 16:20:25 +0530 Subject: Staging: rtl8188eu: usb_halinit: Use !x instead of x == NULL. Use !x instead of x == NULL. Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/hal/usb_halinit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8188eu/hal/usb_halinit.c b/drivers/staging/rtl8188eu/hal/usb_halinit.c index 358762d3fb45..0c7456f39fb5 100644 --- a/drivers/staging/rtl8188eu/hal/usb_halinit.c +++ b/drivers/staging/rtl8188eu/hal/usb_halinit.c @@ -2078,7 +2078,7 @@ void rtl8188eu_set_hal_ops(struct adapter *adapt) adapt->HalData = kzalloc(sizeof(struct hal_data_8188e), GFP_KERNEL); - if (adapt->HalData == NULL) + if (!adapt->HalData) DBG_88E("cant not alloc memory for HAL DATA\n"); halfunc->hal_power_on = rtl8188eu_InitPowerOn; -- cgit v1.2.3 From 57d8dfed8586427880516536cf0abc3aa19cea78 Mon Sep 17 00:00:00 2001 From: Sam Horlbeck Olsen Date: Mon, 14 Mar 2016 02:09:58 -0500 Subject: staging: dgnc: Add whitespace around OR'd flags ("|") This patch fixes the checkpatch.pl message: CHECK: spaces preferred around that '|' (ctx:VxV) + writeb((UART_FCR_ENABLE_FIFO|UART_FCR_CLEAR_RCVR|UART_FCR_CLEAR_XMIT), ^ ^ As per the guidelines for coding style in the kernel, I have updated the digi international driver to include spaces around the OR'd flags; not only is this formatting issue caught by `checkpatch.pl`, in the next `if` block the correct formatting is used, leading to both incorrect and inconsistent code formatting. This patch puts the line in question at 82 characters---while this is over the recommended limit, there are no clear locations to break the line and it barely breaks the cutoff. Signed-off-by: Sam Horlbeck Olsen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_cls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/dgnc/dgnc_cls.c b/drivers/staging/dgnc/dgnc_cls.c index 0ff3139e52b6..5e46ac8dfac5 100644 --- a/drivers/staging/dgnc/dgnc_cls.c +++ b/drivers/staging/dgnc/dgnc_cls.c @@ -1168,7 +1168,7 @@ static void cls_uart_init(struct channel_t *ch) /* Clear out UART and FIFO */ readb(&ch->ch_cls_uart->txrx); - writeb((UART_FCR_ENABLE_FIFO|UART_FCR_CLEAR_RCVR|UART_FCR_CLEAR_XMIT), + writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT), &ch->ch_cls_uart->isr_fcr); udelay(10); -- cgit v1.2.3 From 3733d3f997b468481e609d47fa35badd47d0bf06 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 18 Mar 2016 13:32:12 -0700 Subject: staging: skein: threefish_block: Use ror64 Use the inline instead of direct code to improve readability and shorten the code a little. Done with perl: $ perl -p -i -e 's/\((\w+) \>\> (\d+)\) \| \(\1 \<\< \(64 \- \2\)\)/ror64(\1, \2)/g' drivers/staging/skein/threefish_block.c Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/skein/threefish_block.c | 2144 +++++++++++++++---------------- 1 file changed, 1072 insertions(+), 1072 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/skein/threefish_block.c b/drivers/staging/skein/threefish_block.c index e19ac4368651..a95563fad071 100644 --- a/drivers/staging/skein/threefish_block.c +++ b/drivers/staging/skein/threefish_block.c @@ -512,622 +512,622 @@ void threefish_decrypt_256(struct threefish_key *key_ctx, u64 *input, b2 -= k0 + t1; b3 -= k1 + 18; tmp = b3 ^ b0; - b3 = (tmp >> 32) | (tmp << (64 - 32)); + b3 = ror64(tmp, 32); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 32) | (tmp << (64 - 32)); + b1 = ror64(tmp, 32); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 58) | (tmp << (64 - 58)); + b1 = ror64(tmp, 58); b0 -= b1; tmp = b3 ^ b2; - b3 = (tmp >> 22) | (tmp << (64 - 22)); + b3 = ror64(tmp, 22); b2 -= b3; tmp = b3 ^ b0; - b3 = (tmp >> 46) | (tmp << (64 - 46)); + b3 = ror64(tmp, 46); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 12) | (tmp << (64 - 12)); + b1 = ror64(tmp, 12); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 25) | (tmp << (64 - 25)); + b1 = ror64(tmp, 25); b0 -= b1 + k2; b1 -= k3 + t2; tmp = b3 ^ b2; - b3 = (tmp >> 33) | (tmp << (64 - 33)); + b3 = ror64(tmp, 33); b2 -= b3 + k4 + t0; b3 -= k0 + 17; tmp = b3 ^ b0; - b3 = (tmp >> 5) | (tmp << (64 - 5)); + b3 = ror64(tmp, 5); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 37) | (tmp << (64 - 37)); + b1 = ror64(tmp, 37); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 23) | (tmp << (64 - 23)); + b1 = ror64(tmp, 23); b0 -= b1; tmp = b3 ^ b2; - b3 = (tmp >> 40) | (tmp << (64 - 40)); + b3 = ror64(tmp, 40); b2 -= b3; tmp = b3 ^ b0; - b3 = (tmp >> 52) | (tmp << (64 - 52)); + b3 = ror64(tmp, 52); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 57) | (tmp << (64 - 57)); + b1 = ror64(tmp, 57); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 14) | (tmp << (64 - 14)); + b1 = ror64(tmp, 14); b0 -= b1 + k1; b1 -= k2 + t1; tmp = b3 ^ b2; - b3 = (tmp >> 16) | (tmp << (64 - 16)); + b3 = ror64(tmp, 16); b2 -= b3 + k3 + t2; b3 -= k4 + 16; tmp = b3 ^ b0; - b3 = (tmp >> 32) | (tmp << (64 - 32)); + b3 = ror64(tmp, 32); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 32) | (tmp << (64 - 32)); + b1 = ror64(tmp, 32); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 58) | (tmp << (64 - 58)); + b1 = ror64(tmp, 58); b0 -= b1; tmp = b3 ^ b2; - b3 = (tmp >> 22) | (tmp << (64 - 22)); + b3 = ror64(tmp, 22); b2 -= b3; tmp = b3 ^ b0; - b3 = (tmp >> 46) | (tmp << (64 - 46)); + b3 = ror64(tmp, 46); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 12) | (tmp << (64 - 12)); + b1 = ror64(tmp, 12); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 25) | (tmp << (64 - 25)); + b1 = ror64(tmp, 25); b0 -= b1 + k0; b1 -= k1 + t0; tmp = b3 ^ b2; - b3 = (tmp >> 33) | (tmp << (64 - 33)); + b3 = ror64(tmp, 33); b2 -= b3 + k2 + t1; b3 -= k3 + 15; tmp = b3 ^ b0; - b3 = (tmp >> 5) | (tmp << (64 - 5)); + b3 = ror64(tmp, 5); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 37) | (tmp << (64 - 37)); + b1 = ror64(tmp, 37); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 23) | (tmp << (64 - 23)); + b1 = ror64(tmp, 23); b0 -= b1; tmp = b3 ^ b2; - b3 = (tmp >> 40) | (tmp << (64 - 40)); + b3 = ror64(tmp, 40); b2 -= b3; tmp = b3 ^ b0; - b3 = (tmp >> 52) | (tmp << (64 - 52)); + b3 = ror64(tmp, 52); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 57) | (tmp << (64 - 57)); + b1 = ror64(tmp, 57); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 14) | (tmp << (64 - 14)); + b1 = ror64(tmp, 14); b0 -= b1 + k4; b1 -= k0 + t2; tmp = b3 ^ b2; - b3 = (tmp >> 16) | (tmp << (64 - 16)); + b3 = ror64(tmp, 16); b2 -= b3 + k1 + t0; b3 -= k2 + 14; tmp = b3 ^ b0; - b3 = (tmp >> 32) | (tmp << (64 - 32)); + b3 = ror64(tmp, 32); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 32) | (tmp << (64 - 32)); + b1 = ror64(tmp, 32); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 58) | (tmp << (64 - 58)); + b1 = ror64(tmp, 58); b0 -= b1; tmp = b3 ^ b2; - b3 = (tmp >> 22) | (tmp << (64 - 22)); + b3 = ror64(tmp, 22); b2 -= b3; tmp = b3 ^ b0; - b3 = (tmp >> 46) | (tmp << (64 - 46)); + b3 = ror64(tmp, 46); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 12) | (tmp << (64 - 12)); + b1 = ror64(tmp, 12); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 25) | (tmp << (64 - 25)); + b1 = ror64(tmp, 25); b0 -= b1 + k3; b1 -= k4 + t1; tmp = b3 ^ b2; - b3 = (tmp >> 33) | (tmp << (64 - 33)); + b3 = ror64(tmp, 33); b2 -= b3 + k0 + t2; b3 -= k1 + 13; tmp = b3 ^ b0; - b3 = (tmp >> 5) | (tmp << (64 - 5)); + b3 = ror64(tmp, 5); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 37) | (tmp << (64 - 37)); + b1 = ror64(tmp, 37); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 23) | (tmp << (64 - 23)); + b1 = ror64(tmp, 23); b0 -= b1; tmp = b3 ^ b2; - b3 = (tmp >> 40) | (tmp << (64 - 40)); + b3 = ror64(tmp, 40); b2 -= b3; tmp = b3 ^ b0; - b3 = (tmp >> 52) | (tmp << (64 - 52)); + b3 = ror64(tmp, 52); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 57) | (tmp << (64 - 57)); + b1 = ror64(tmp, 57); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 14) | (tmp << (64 - 14)); + b1 = ror64(tmp, 14); b0 -= b1 + k2; b1 -= k3 + t0; tmp = b3 ^ b2; - b3 = (tmp >> 16) | (tmp << (64 - 16)); + b3 = ror64(tmp, 16); b2 -= b3 + k4 + t1; b3 -= k0 + 12; tmp = b3 ^ b0; - b3 = (tmp >> 32) | (tmp << (64 - 32)); + b3 = ror64(tmp, 32); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 32) | (tmp << (64 - 32)); + b1 = ror64(tmp, 32); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 58) | (tmp << (64 - 58)); + b1 = ror64(tmp, 58); b0 -= b1; tmp = b3 ^ b2; - b3 = (tmp >> 22) | (tmp << (64 - 22)); + b3 = ror64(tmp, 22); b2 -= b3; tmp = b3 ^ b0; - b3 = (tmp >> 46) | (tmp << (64 - 46)); + b3 = ror64(tmp, 46); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 12) | (tmp << (64 - 12)); + b1 = ror64(tmp, 12); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 25) | (tmp << (64 - 25)); + b1 = ror64(tmp, 25); b0 -= b1 + k1; b1 -= k2 + t2; tmp = b3 ^ b2; - b3 = (tmp >> 33) | (tmp << (64 - 33)); + b3 = ror64(tmp, 33); b2 -= b3 + k3 + t0; b3 -= k4 + 11; tmp = b3 ^ b0; - b3 = (tmp >> 5) | (tmp << (64 - 5)); + b3 = ror64(tmp, 5); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 37) | (tmp << (64 - 37)); + b1 = ror64(tmp, 37); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 23) | (tmp << (64 - 23)); + b1 = ror64(tmp, 23); b0 -= b1; tmp = b3 ^ b2; - b3 = (tmp >> 40) | (tmp << (64 - 40)); + b3 = ror64(tmp, 40); b2 -= b3; tmp = b3 ^ b0; - b3 = (tmp >> 52) | (tmp << (64 - 52)); + b3 = ror64(tmp, 52); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 57) | (tmp << (64 - 57)); + b1 = ror64(tmp, 57); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 14) | (tmp << (64 - 14)); + b1 = ror64(tmp, 14); b0 -= b1 + k0; b1 -= k1 + t1; tmp = b3 ^ b2; - b3 = (tmp >> 16) | (tmp << (64 - 16)); + b3 = ror64(tmp, 16); b2 -= b3 + k2 + t2; b3 -= k3 + 10; tmp = b3 ^ b0; - b3 = (tmp >> 32) | (tmp << (64 - 32)); + b3 = ror64(tmp, 32); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 32) | (tmp << (64 - 32)); + b1 = ror64(tmp, 32); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 58) | (tmp << (64 - 58)); + b1 = ror64(tmp, 58); b0 -= b1; tmp = b3 ^ b2; - b3 = (tmp >> 22) | (tmp << (64 - 22)); + b3 = ror64(tmp, 22); b2 -= b3; tmp = b3 ^ b0; - b3 = (tmp >> 46) | (tmp << (64 - 46)); + b3 = ror64(tmp, 46); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 12) | (tmp << (64 - 12)); + b1 = ror64(tmp, 12); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 25) | (tmp << (64 - 25)); + b1 = ror64(tmp, 25); b0 -= b1 + k4; b1 -= k0 + t0; tmp = b3 ^ b2; - b3 = (tmp >> 33) | (tmp << (64 - 33)); + b3 = ror64(tmp, 33); b2 -= b3 + k1 + t1; b3 -= k2 + 9; tmp = b3 ^ b0; - b3 = (tmp >> 5) | (tmp << (64 - 5)); + b3 = ror64(tmp, 5); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 37) | (tmp << (64 - 37)); + b1 = ror64(tmp, 37); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 23) | (tmp << (64 - 23)); + b1 = ror64(tmp, 23); b0 -= b1; tmp = b3 ^ b2; - b3 = (tmp >> 40) | (tmp << (64 - 40)); + b3 = ror64(tmp, 40); b2 -= b3; tmp = b3 ^ b0; - b3 = (tmp >> 52) | (tmp << (64 - 52)); + b3 = ror64(tmp, 52); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 57) | (tmp << (64 - 57)); + b1 = ror64(tmp, 57); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 14) | (tmp << (64 - 14)); + b1 = ror64(tmp, 14); b0 -= b1 + k3; b1 -= k4 + t2; tmp = b3 ^ b2; - b3 = (tmp >> 16) | (tmp << (64 - 16)); + b3 = ror64(tmp, 16); b2 -= b3 + k0 + t0; b3 -= k1 + 8; tmp = b3 ^ b0; - b3 = (tmp >> 32) | (tmp << (64 - 32)); + b3 = ror64(tmp, 32); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 32) | (tmp << (64 - 32)); + b1 = ror64(tmp, 32); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 58) | (tmp << (64 - 58)); + b1 = ror64(tmp, 58); b0 -= b1; tmp = b3 ^ b2; - b3 = (tmp >> 22) | (tmp << (64 - 22)); + b3 = ror64(tmp, 22); b2 -= b3; tmp = b3 ^ b0; - b3 = (tmp >> 46) | (tmp << (64 - 46)); + b3 = ror64(tmp, 46); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 12) | (tmp << (64 - 12)); + b1 = ror64(tmp, 12); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 25) | (tmp << (64 - 25)); + b1 = ror64(tmp, 25); b0 -= b1 + k2; b1 -= k3 + t1; tmp = b3 ^ b2; - b3 = (tmp >> 33) | (tmp << (64 - 33)); + b3 = ror64(tmp, 33); b2 -= b3 + k4 + t2; b3 -= k0 + 7; tmp = b3 ^ b0; - b3 = (tmp >> 5) | (tmp << (64 - 5)); + b3 = ror64(tmp, 5); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 37) | (tmp << (64 - 37)); + b1 = ror64(tmp, 37); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 23) | (tmp << (64 - 23)); + b1 = ror64(tmp, 23); b0 -= b1; tmp = b3 ^ b2; - b3 = (tmp >> 40) | (tmp << (64 - 40)); + b3 = ror64(tmp, 40); b2 -= b3; tmp = b3 ^ b0; - b3 = (tmp >> 52) | (tmp << (64 - 52)); + b3 = ror64(tmp, 52); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 57) | (tmp << (64 - 57)); + b1 = ror64(tmp, 57); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 14) | (tmp << (64 - 14)); + b1 = ror64(tmp, 14); b0 -= b1 + k1; b1 -= k2 + t0; tmp = b3 ^ b2; - b3 = (tmp >> 16) | (tmp << (64 - 16)); + b3 = ror64(tmp, 16); b2 -= b3 + k3 + t1; b3 -= k4 + 6; tmp = b3 ^ b0; - b3 = (tmp >> 32) | (tmp << (64 - 32)); + b3 = ror64(tmp, 32); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 32) | (tmp << (64 - 32)); + b1 = ror64(tmp, 32); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 58) | (tmp << (64 - 58)); + b1 = ror64(tmp, 58); b0 -= b1; tmp = b3 ^ b2; - b3 = (tmp >> 22) | (tmp << (64 - 22)); + b3 = ror64(tmp, 22); b2 -= b3; tmp = b3 ^ b0; - b3 = (tmp >> 46) | (tmp << (64 - 46)); + b3 = ror64(tmp, 46); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 12) | (tmp << (64 - 12)); + b1 = ror64(tmp, 12); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 25) | (tmp << (64 - 25)); + b1 = ror64(tmp, 25); b0 -= b1 + k0; b1 -= k1 + t2; tmp = b3 ^ b2; - b3 = (tmp >> 33) | (tmp << (64 - 33)); + b3 = ror64(tmp, 33); b2 -= b3 + k2 + t0; b3 -= k3 + 5; tmp = b3 ^ b0; - b3 = (tmp >> 5) | (tmp << (64 - 5)); + b3 = ror64(tmp, 5); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 37) | (tmp << (64 - 37)); + b1 = ror64(tmp, 37); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 23) | (tmp << (64 - 23)); + b1 = ror64(tmp, 23); b0 -= b1; tmp = b3 ^ b2; - b3 = (tmp >> 40) | (tmp << (64 - 40)); + b3 = ror64(tmp, 40); b2 -= b3; tmp = b3 ^ b0; - b3 = (tmp >> 52) | (tmp << (64 - 52)); + b3 = ror64(tmp, 52); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 57) | (tmp << (64 - 57)); + b1 = ror64(tmp, 57); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 14) | (tmp << (64 - 14)); + b1 = ror64(tmp, 14); b0 -= b1 + k4; b1 -= k0 + t1; tmp = b3 ^ b2; - b3 = (tmp >> 16) | (tmp << (64 - 16)); + b3 = ror64(tmp, 16); b2 -= b3 + k1 + t2; b3 -= k2 + 4; tmp = b3 ^ b0; - b3 = (tmp >> 32) | (tmp << (64 - 32)); + b3 = ror64(tmp, 32); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 32) | (tmp << (64 - 32)); + b1 = ror64(tmp, 32); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 58) | (tmp << (64 - 58)); + b1 = ror64(tmp, 58); b0 -= b1; tmp = b3 ^ b2; - b3 = (tmp >> 22) | (tmp << (64 - 22)); + b3 = ror64(tmp, 22); b2 -= b3; tmp = b3 ^ b0; - b3 = (tmp >> 46) | (tmp << (64 - 46)); + b3 = ror64(tmp, 46); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 12) | (tmp << (64 - 12)); + b1 = ror64(tmp, 12); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 25) | (tmp << (64 - 25)); + b1 = ror64(tmp, 25); b0 -= b1 + k3; b1 -= k4 + t0; tmp = b3 ^ b2; - b3 = (tmp >> 33) | (tmp << (64 - 33)); + b3 = ror64(tmp, 33); b2 -= b3 + k0 + t1; b3 -= k1 + 3; tmp = b3 ^ b0; - b3 = (tmp >> 5) | (tmp << (64 - 5)); + b3 = ror64(tmp, 5); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 37) | (tmp << (64 - 37)); + b1 = ror64(tmp, 37); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 23) | (tmp << (64 - 23)); + b1 = ror64(tmp, 23); b0 -= b1; tmp = b3 ^ b2; - b3 = (tmp >> 40) | (tmp << (64 - 40)); + b3 = ror64(tmp, 40); b2 -= b3; tmp = b3 ^ b0; - b3 = (tmp >> 52) | (tmp << (64 - 52)); + b3 = ror64(tmp, 52); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 57) | (tmp << (64 - 57)); + b1 = ror64(tmp, 57); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 14) | (tmp << (64 - 14)); + b1 = ror64(tmp, 14); b0 -= b1 + k2; b1 -= k3 + t2; tmp = b3 ^ b2; - b3 = (tmp >> 16) | (tmp << (64 - 16)); + b3 = ror64(tmp, 16); b2 -= b3 + k4 + t0; b3 -= k0 + 2; tmp = b3 ^ b0; - b3 = (tmp >> 32) | (tmp << (64 - 32)); + b3 = ror64(tmp, 32); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 32) | (tmp << (64 - 32)); + b1 = ror64(tmp, 32); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 58) | (tmp << (64 - 58)); + b1 = ror64(tmp, 58); b0 -= b1; tmp = b3 ^ b2; - b3 = (tmp >> 22) | (tmp << (64 - 22)); + b3 = ror64(tmp, 22); b2 -= b3; tmp = b3 ^ b0; - b3 = (tmp >> 46) | (tmp << (64 - 46)); + b3 = ror64(tmp, 46); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 12) | (tmp << (64 - 12)); + b1 = ror64(tmp, 12); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 25) | (tmp << (64 - 25)); + b1 = ror64(tmp, 25); b0 -= b1 + k1; b1 -= k2 + t1; tmp = b3 ^ b2; - b3 = (tmp >> 33) | (tmp << (64 - 33)); + b3 = ror64(tmp, 33); b2 -= b3 + k3 + t2; b3 -= k4 + 1; tmp = b3 ^ b0; - b3 = (tmp >> 5) | (tmp << (64 - 5)); + b3 = ror64(tmp, 5); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 37) | (tmp << (64 - 37)); + b1 = ror64(tmp, 37); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 23) | (tmp << (64 - 23)); + b1 = ror64(tmp, 23); b0 -= b1; tmp = b3 ^ b2; - b3 = (tmp >> 40) | (tmp << (64 - 40)); + b3 = ror64(tmp, 40); b2 -= b3; tmp = b3 ^ b0; - b3 = (tmp >> 52) | (tmp << (64 - 52)); + b3 = ror64(tmp, 52); b0 -= b3; tmp = b1 ^ b2; - b1 = (tmp >> 57) | (tmp << (64 - 57)); + b1 = ror64(tmp, 57); b2 -= b1; tmp = b1 ^ b0; - b1 = (tmp >> 14) | (tmp << (64 - 14)); + b1 = ror64(tmp, 14); b0 -= b1 + k0; b1 -= k1 + t0; tmp = b3 ^ b2; - b3 = (tmp >> 16) | (tmp << (64 - 16)); + b3 = ror64(tmp, 16); b2 -= b3 + k2 + t1; b3 -= k3; @@ -2125,1226 +2125,1226 @@ void threefish_decrypt_512(struct threefish_key *key_ctx, u64 *input, b7 -= k7 + 18; tmp = b3 ^ b4; - b3 = (tmp >> 22) | (tmp << (64 - 22)); + b3 = ror64(tmp, 22); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 56) | (tmp << (64 - 56)); + b5 = ror64(tmp, 56); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 35) | (tmp << (64 - 35)); + b7 = ror64(tmp, 35); b0 -= b7; tmp = b1 ^ b6; - b1 = (tmp >> 8) | (tmp << (64 - 8)); + b1 = ror64(tmp, 8); b6 -= b1; tmp = b7 ^ b2; - b7 = (tmp >> 43) | (tmp << (64 - 43)); + b7 = ror64(tmp, 43); b2 -= b7; tmp = b5 ^ b0; - b5 = (tmp >> 39) | (tmp << (64 - 39)); + b5 = ror64(tmp, 39); b0 -= b5; tmp = b3 ^ b6; - b3 = (tmp >> 29) | (tmp << (64 - 29)); + b3 = ror64(tmp, 29); b6 -= b3; tmp = b1 ^ b4; - b1 = (tmp >> 25) | (tmp << (64 - 25)); + b1 = ror64(tmp, 25); b4 -= b1; tmp = b3 ^ b0; - b3 = (tmp >> 17) | (tmp << (64 - 17)); + b3 = ror64(tmp, 17); b0 -= b3; tmp = b5 ^ b6; - b5 = (tmp >> 10) | (tmp << (64 - 10)); + b5 = ror64(tmp, 10); b6 -= b5; tmp = b7 ^ b4; - b7 = (tmp >> 50) | (tmp << (64 - 50)); + b7 = ror64(tmp, 50); b4 -= b7; tmp = b1 ^ b2; - b1 = (tmp >> 13) | (tmp << (64 - 13)); + b1 = ror64(tmp, 13); b2 -= b1; tmp = b7 ^ b6; - b7 = (tmp >> 24) | (tmp << (64 - 24)); + b7 = ror64(tmp, 24); b6 -= b7 + k5 + t0; b7 -= k6 + 17; tmp = b5 ^ b4; - b5 = (tmp >> 34) | (tmp << (64 - 34)); + b5 = ror64(tmp, 34); b4 -= b5 + k3; b5 -= k4 + t2; tmp = b3 ^ b2; - b3 = (tmp >> 30) | (tmp << (64 - 30)); + b3 = ror64(tmp, 30); b2 -= b3 + k1; b3 -= k2; tmp = b1 ^ b0; - b1 = (tmp >> 39) | (tmp << (64 - 39)); + b1 = ror64(tmp, 39); b0 -= b1 + k8; b1 -= k0; tmp = b3 ^ b4; - b3 = (tmp >> 56) | (tmp << (64 - 56)); + b3 = ror64(tmp, 56); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 54) | (tmp << (64 - 54)); + b5 = ror64(tmp, 54); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 9) | (tmp << (64 - 9)); + b7 = ror64(tmp, 9); b0 -= b7; tmp = b1 ^ b6; - b1 = (tmp >> 44) | (tmp << (64 - 44)); + b1 = ror64(tmp, 44); b6 -= b1; tmp = b7 ^ b2; - b7 = (tmp >> 39) | (tmp << (64 - 39)); + b7 = ror64(tmp, 39); b2 -= b7; tmp = b5 ^ b0; - b5 = (tmp >> 36) | (tmp << (64 - 36)); + b5 = ror64(tmp, 36); b0 -= b5; tmp = b3 ^ b6; - b3 = (tmp >> 49) | (tmp << (64 - 49)); + b3 = ror64(tmp, 49); b6 -= b3; tmp = b1 ^ b4; - b1 = (tmp >> 17) | (tmp << (64 - 17)); + b1 = ror64(tmp, 17); b4 -= b1; tmp = b3 ^ b0; - b3 = (tmp >> 42) | (tmp << (64 - 42)); + b3 = ror64(tmp, 42); b0 -= b3; tmp = b5 ^ b6; - b5 = (tmp >> 14) | (tmp << (64 - 14)); + b5 = ror64(tmp, 14); b6 -= b5; tmp = b7 ^ b4; - b7 = (tmp >> 27) | (tmp << (64 - 27)); + b7 = ror64(tmp, 27); b4 -= b7; tmp = b1 ^ b2; - b1 = (tmp >> 33) | (tmp << (64 - 33)); + b1 = ror64(tmp, 33); b2 -= b1; tmp = b7 ^ b6; - b7 = (tmp >> 37) | (tmp << (64 - 37)); + b7 = ror64(tmp, 37); b6 -= b7 + k4 + t2; b7 -= k5 + 16; tmp = b5 ^ b4; - b5 = (tmp >> 19) | (tmp << (64 - 19)); + b5 = ror64(tmp, 19); b4 -= b5 + k2; b5 -= k3 + t1; tmp = b3 ^ b2; - b3 = (tmp >> 36) | (tmp << (64 - 36)); + b3 = ror64(tmp, 36); b2 -= b3 + k0; b3 -= k1; tmp = b1 ^ b0; - b1 = (tmp >> 46) | (tmp << (64 - 46)); + b1 = ror64(tmp, 46); b0 -= b1 + k7; b1 -= k8; tmp = b3 ^ b4; - b3 = (tmp >> 22) | (tmp << (64 - 22)); + b3 = ror64(tmp, 22); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 56) | (tmp << (64 - 56)); + b5 = ror64(tmp, 56); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 35) | (tmp << (64 - 35)); + b7 = ror64(tmp, 35); b0 -= b7; tmp = b1 ^ b6; - b1 = (tmp >> 8) | (tmp << (64 - 8)); + b1 = ror64(tmp, 8); b6 -= b1; tmp = b7 ^ b2; - b7 = (tmp >> 43) | (tmp << (64 - 43)); + b7 = ror64(tmp, 43); b2 -= b7; tmp = b5 ^ b0; - b5 = (tmp >> 39) | (tmp << (64 - 39)); + b5 = ror64(tmp, 39); b0 -= b5; tmp = b3 ^ b6; - b3 = (tmp >> 29) | (tmp << (64 - 29)); + b3 = ror64(tmp, 29); b6 -= b3; tmp = b1 ^ b4; - b1 = (tmp >> 25) | (tmp << (64 - 25)); + b1 = ror64(tmp, 25); b4 -= b1; tmp = b3 ^ b0; - b3 = (tmp >> 17) | (tmp << (64 - 17)); + b3 = ror64(tmp, 17); b0 -= b3; tmp = b5 ^ b6; - b5 = (tmp >> 10) | (tmp << (64 - 10)); + b5 = ror64(tmp, 10); b6 -= b5; tmp = b7 ^ b4; - b7 = (tmp >> 50) | (tmp << (64 - 50)); + b7 = ror64(tmp, 50); b4 -= b7; tmp = b1 ^ b2; - b1 = (tmp >> 13) | (tmp << (64 - 13)); + b1 = ror64(tmp, 13); b2 -= b1; tmp = b7 ^ b6; - b7 = (tmp >> 24) | (tmp << (64 - 24)); + b7 = ror64(tmp, 24); b6 -= b7 + k3 + t1; b7 -= k4 + 15; tmp = b5 ^ b4; - b5 = (tmp >> 34) | (tmp << (64 - 34)); + b5 = ror64(tmp, 34); b4 -= b5 + k1; b5 -= k2 + t0; tmp = b3 ^ b2; - b3 = (tmp >> 30) | (tmp << (64 - 30)); + b3 = ror64(tmp, 30); b2 -= b3 + k8; b3 -= k0; tmp = b1 ^ b0; - b1 = (tmp >> 39) | (tmp << (64 - 39)); + b1 = ror64(tmp, 39); b0 -= b1 + k6; b1 -= k7; tmp = b3 ^ b4; - b3 = (tmp >> 56) | (tmp << (64 - 56)); + b3 = ror64(tmp, 56); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 54) | (tmp << (64 - 54)); + b5 = ror64(tmp, 54); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 9) | (tmp << (64 - 9)); + b7 = ror64(tmp, 9); b0 -= b7; tmp = b1 ^ b6; - b1 = (tmp >> 44) | (tmp << (64 - 44)); + b1 = ror64(tmp, 44); b6 -= b1; tmp = b7 ^ b2; - b7 = (tmp >> 39) | (tmp << (64 - 39)); + b7 = ror64(tmp, 39); b2 -= b7; tmp = b5 ^ b0; - b5 = (tmp >> 36) | (tmp << (64 - 36)); + b5 = ror64(tmp, 36); b0 -= b5; tmp = b3 ^ b6; - b3 = (tmp >> 49) | (tmp << (64 - 49)); + b3 = ror64(tmp, 49); b6 -= b3; tmp = b1 ^ b4; - b1 = (tmp >> 17) | (tmp << (64 - 17)); + b1 = ror64(tmp, 17); b4 -= b1; tmp = b3 ^ b0; - b3 = (tmp >> 42) | (tmp << (64 - 42)); + b3 = ror64(tmp, 42); b0 -= b3; tmp = b5 ^ b6; - b5 = (tmp >> 14) | (tmp << (64 - 14)); + b5 = ror64(tmp, 14); b6 -= b5; tmp = b7 ^ b4; - b7 = (tmp >> 27) | (tmp << (64 - 27)); + b7 = ror64(tmp, 27); b4 -= b7; tmp = b1 ^ b2; - b1 = (tmp >> 33) | (tmp << (64 - 33)); + b1 = ror64(tmp, 33); b2 -= b1; tmp = b7 ^ b6; - b7 = (tmp >> 37) | (tmp << (64 - 37)); + b7 = ror64(tmp, 37); b6 -= b7 + k2 + t0; b7 -= k3 + 14; tmp = b5 ^ b4; - b5 = (tmp >> 19) | (tmp << (64 - 19)); + b5 = ror64(tmp, 19); b4 -= b5 + k0; b5 -= k1 + t2; tmp = b3 ^ b2; - b3 = (tmp >> 36) | (tmp << (64 - 36)); + b3 = ror64(tmp, 36); b2 -= b3 + k7; b3 -= k8; tmp = b1 ^ b0; - b1 = (tmp >> 46) | (tmp << (64 - 46)); + b1 = ror64(tmp, 46); b0 -= b1 + k5; b1 -= k6; tmp = b3 ^ b4; - b3 = (tmp >> 22) | (tmp << (64 - 22)); + b3 = ror64(tmp, 22); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 56) | (tmp << (64 - 56)); + b5 = ror64(tmp, 56); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 35) | (tmp << (64 - 35)); + b7 = ror64(tmp, 35); b0 -= b7; tmp = b1 ^ b6; - b1 = (tmp >> 8) | (tmp << (64 - 8)); + b1 = ror64(tmp, 8); b6 -= b1; tmp = b7 ^ b2; - b7 = (tmp >> 43) | (tmp << (64 - 43)); + b7 = ror64(tmp, 43); b2 -= b7; tmp = b5 ^ b0; - b5 = (tmp >> 39) | (tmp << (64 - 39)); + b5 = ror64(tmp, 39); b0 -= b5; tmp = b3 ^ b6; - b3 = (tmp >> 29) | (tmp << (64 - 29)); + b3 = ror64(tmp, 29); b6 -= b3; tmp = b1 ^ b4; - b1 = (tmp >> 25) | (tmp << (64 - 25)); + b1 = ror64(tmp, 25); b4 -= b1; tmp = b3 ^ b0; - b3 = (tmp >> 17) | (tmp << (64 - 17)); + b3 = ror64(tmp, 17); b0 -= b3; tmp = b5 ^ b6; - b5 = (tmp >> 10) | (tmp << (64 - 10)); + b5 = ror64(tmp, 10); b6 -= b5; tmp = b7 ^ b4; - b7 = (tmp >> 50) | (tmp << (64 - 50)); + b7 = ror64(tmp, 50); b4 -= b7; tmp = b1 ^ b2; - b1 = (tmp >> 13) | (tmp << (64 - 13)); + b1 = ror64(tmp, 13); b2 -= b1; tmp = b7 ^ b6; - b7 = (tmp >> 24) | (tmp << (64 - 24)); + b7 = ror64(tmp, 24); b6 -= b7 + k1 + t2; b7 -= k2 + 13; tmp = b5 ^ b4; - b5 = (tmp >> 34) | (tmp << (64 - 34)); + b5 = ror64(tmp, 34); b4 -= b5 + k8; b5 -= k0 + t1; tmp = b3 ^ b2; - b3 = (tmp >> 30) | (tmp << (64 - 30)); + b3 = ror64(tmp, 30); b2 -= b3 + k6; b3 -= k7; tmp = b1 ^ b0; - b1 = (tmp >> 39) | (tmp << (64 - 39)); + b1 = ror64(tmp, 39); b0 -= b1 + k4; b1 -= k5; tmp = b3 ^ b4; - b3 = (tmp >> 56) | (tmp << (64 - 56)); + b3 = ror64(tmp, 56); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 54) | (tmp << (64 - 54)); + b5 = ror64(tmp, 54); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 9) | (tmp << (64 - 9)); + b7 = ror64(tmp, 9); b0 -= b7; tmp = b1 ^ b6; - b1 = (tmp >> 44) | (tmp << (64 - 44)); + b1 = ror64(tmp, 44); b6 -= b1; tmp = b7 ^ b2; - b7 = (tmp >> 39) | (tmp << (64 - 39)); + b7 = ror64(tmp, 39); b2 -= b7; tmp = b5 ^ b0; - b5 = (tmp >> 36) | (tmp << (64 - 36)); + b5 = ror64(tmp, 36); b0 -= b5; tmp = b3 ^ b6; - b3 = (tmp >> 49) | (tmp << (64 - 49)); + b3 = ror64(tmp, 49); b6 -= b3; tmp = b1 ^ b4; - b1 = (tmp >> 17) | (tmp << (64 - 17)); + b1 = ror64(tmp, 17); b4 -= b1; tmp = b3 ^ b0; - b3 = (tmp >> 42) | (tmp << (64 - 42)); + b3 = ror64(tmp, 42); b0 -= b3; tmp = b5 ^ b6; - b5 = (tmp >> 14) | (tmp << (64 - 14)); + b5 = ror64(tmp, 14); b6 -= b5; tmp = b7 ^ b4; - b7 = (tmp >> 27) | (tmp << (64 - 27)); + b7 = ror64(tmp, 27); b4 -= b7; tmp = b1 ^ b2; - b1 = (tmp >> 33) | (tmp << (64 - 33)); + b1 = ror64(tmp, 33); b2 -= b1; tmp = b7 ^ b6; - b7 = (tmp >> 37) | (tmp << (64 - 37)); + b7 = ror64(tmp, 37); b6 -= b7 + k0 + t1; b7 -= k1 + 12; tmp = b5 ^ b4; - b5 = (tmp >> 19) | (tmp << (64 - 19)); + b5 = ror64(tmp, 19); b4 -= b5 + k7; b5 -= k8 + t0; tmp = b3 ^ b2; - b3 = (tmp >> 36) | (tmp << (64 - 36)); + b3 = ror64(tmp, 36); b2 -= b3 + k5; b3 -= k6; tmp = b1 ^ b0; - b1 = (tmp >> 46) | (tmp << (64 - 46)); + b1 = ror64(tmp, 46); b0 -= b1 + k3; b1 -= k4; tmp = b3 ^ b4; - b3 = (tmp >> 22) | (tmp << (64 - 22)); + b3 = ror64(tmp, 22); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 56) | (tmp << (64 - 56)); + b5 = ror64(tmp, 56); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 35) | (tmp << (64 - 35)); + b7 = ror64(tmp, 35); b0 -= b7; tmp = b1 ^ b6; - b1 = (tmp >> 8) | (tmp << (64 - 8)); + b1 = ror64(tmp, 8); b6 -= b1; tmp = b7 ^ b2; - b7 = (tmp >> 43) | (tmp << (64 - 43)); + b7 = ror64(tmp, 43); b2 -= b7; tmp = b5 ^ b0; - b5 = (tmp >> 39) | (tmp << (64 - 39)); + b5 = ror64(tmp, 39); b0 -= b5; tmp = b3 ^ b6; - b3 = (tmp >> 29) | (tmp << (64 - 29)); + b3 = ror64(tmp, 29); b6 -= b3; tmp = b1 ^ b4; - b1 = (tmp >> 25) | (tmp << (64 - 25)); + b1 = ror64(tmp, 25); b4 -= b1; tmp = b3 ^ b0; - b3 = (tmp >> 17) | (tmp << (64 - 17)); + b3 = ror64(tmp, 17); b0 -= b3; tmp = b5 ^ b6; - b5 = (tmp >> 10) | (tmp << (64 - 10)); + b5 = ror64(tmp, 10); b6 -= b5; tmp = b7 ^ b4; - b7 = (tmp >> 50) | (tmp << (64 - 50)); + b7 = ror64(tmp, 50); b4 -= b7; tmp = b1 ^ b2; - b1 = (tmp >> 13) | (tmp << (64 - 13)); + b1 = ror64(tmp, 13); b2 -= b1; tmp = b7 ^ b6; - b7 = (tmp >> 24) | (tmp << (64 - 24)); + b7 = ror64(tmp, 24); b6 -= b7 + k8 + t0; b7 -= k0 + 11; tmp = b5 ^ b4; - b5 = (tmp >> 34) | (tmp << (64 - 34)); + b5 = ror64(tmp, 34); b4 -= b5 + k6; b5 -= k7 + t2; tmp = b3 ^ b2; - b3 = (tmp >> 30) | (tmp << (64 - 30)); + b3 = ror64(tmp, 30); b2 -= b3 + k4; b3 -= k5; tmp = b1 ^ b0; - b1 = (tmp >> 39) | (tmp << (64 - 39)); + b1 = ror64(tmp, 39); b0 -= b1 + k2; b1 -= k3; tmp = b3 ^ b4; - b3 = (tmp >> 56) | (tmp << (64 - 56)); + b3 = ror64(tmp, 56); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 54) | (tmp << (64 - 54)); + b5 = ror64(tmp, 54); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 9) | (tmp << (64 - 9)); + b7 = ror64(tmp, 9); b0 -= b7; tmp = b1 ^ b6; - b1 = (tmp >> 44) | (tmp << (64 - 44)); + b1 = ror64(tmp, 44); b6 -= b1; tmp = b7 ^ b2; - b7 = (tmp >> 39) | (tmp << (64 - 39)); + b7 = ror64(tmp, 39); b2 -= b7; tmp = b5 ^ b0; - b5 = (tmp >> 36) | (tmp << (64 - 36)); + b5 = ror64(tmp, 36); b0 -= b5; tmp = b3 ^ b6; - b3 = (tmp >> 49) | (tmp << (64 - 49)); + b3 = ror64(tmp, 49); b6 -= b3; tmp = b1 ^ b4; - b1 = (tmp >> 17) | (tmp << (64 - 17)); + b1 = ror64(tmp, 17); b4 -= b1; tmp = b3 ^ b0; - b3 = (tmp >> 42) | (tmp << (64 - 42)); + b3 = ror64(tmp, 42); b0 -= b3; tmp = b5 ^ b6; - b5 = (tmp >> 14) | (tmp << (64 - 14)); + b5 = ror64(tmp, 14); b6 -= b5; tmp = b7 ^ b4; - b7 = (tmp >> 27) | (tmp << (64 - 27)); + b7 = ror64(tmp, 27); b4 -= b7; tmp = b1 ^ b2; - b1 = (tmp >> 33) | (tmp << (64 - 33)); + b1 = ror64(tmp, 33); b2 -= b1; tmp = b7 ^ b6; - b7 = (tmp >> 37) | (tmp << (64 - 37)); + b7 = ror64(tmp, 37); b6 -= b7 + k7 + t2; b7 -= k8 + 10; tmp = b5 ^ b4; - b5 = (tmp >> 19) | (tmp << (64 - 19)); + b5 = ror64(tmp, 19); b4 -= b5 + k5; b5 -= k6 + t1; tmp = b3 ^ b2; - b3 = (tmp >> 36) | (tmp << (64 - 36)); + b3 = ror64(tmp, 36); b2 -= b3 + k3; b3 -= k4; tmp = b1 ^ b0; - b1 = (tmp >> 46) | (tmp << (64 - 46)); + b1 = ror64(tmp, 46); b0 -= b1 + k1; b1 -= k2; tmp = b3 ^ b4; - b3 = (tmp >> 22) | (tmp << (64 - 22)); + b3 = ror64(tmp, 22); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 56) | (tmp << (64 - 56)); + b5 = ror64(tmp, 56); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 35) | (tmp << (64 - 35)); + b7 = ror64(tmp, 35); b0 -= b7; tmp = b1 ^ b6; - b1 = (tmp >> 8) | (tmp << (64 - 8)); + b1 = ror64(tmp, 8); b6 -= b1; tmp = b7 ^ b2; - b7 = (tmp >> 43) | (tmp << (64 - 43)); + b7 = ror64(tmp, 43); b2 -= b7; tmp = b5 ^ b0; - b5 = (tmp >> 39) | (tmp << (64 - 39)); + b5 = ror64(tmp, 39); b0 -= b5; tmp = b3 ^ b6; - b3 = (tmp >> 29) | (tmp << (64 - 29)); + b3 = ror64(tmp, 29); b6 -= b3; tmp = b1 ^ b4; - b1 = (tmp >> 25) | (tmp << (64 - 25)); + b1 = ror64(tmp, 25); b4 -= b1; tmp = b3 ^ b0; - b3 = (tmp >> 17) | (tmp << (64 - 17)); + b3 = ror64(tmp, 17); b0 -= b3; tmp = b5 ^ b6; - b5 = (tmp >> 10) | (tmp << (64 - 10)); + b5 = ror64(tmp, 10); b6 -= b5; tmp = b7 ^ b4; - b7 = (tmp >> 50) | (tmp << (64 - 50)); + b7 = ror64(tmp, 50); b4 -= b7; tmp = b1 ^ b2; - b1 = (tmp >> 13) | (tmp << (64 - 13)); + b1 = ror64(tmp, 13); b2 -= b1; tmp = b7 ^ b6; - b7 = (tmp >> 24) | (tmp << (64 - 24)); + b7 = ror64(tmp, 24); b6 -= b7 + k6 + t1; b7 -= k7 + 9; tmp = b5 ^ b4; - b5 = (tmp >> 34) | (tmp << (64 - 34)); + b5 = ror64(tmp, 34); b4 -= b5 + k4; b5 -= k5 + t0; tmp = b3 ^ b2; - b3 = (tmp >> 30) | (tmp << (64 - 30)); + b3 = ror64(tmp, 30); b2 -= b3 + k2; b3 -= k3; tmp = b1 ^ b0; - b1 = (tmp >> 39) | (tmp << (64 - 39)); + b1 = ror64(tmp, 39); b0 -= b1 + k0; b1 -= k1; tmp = b3 ^ b4; - b3 = (tmp >> 56) | (tmp << (64 - 56)); + b3 = ror64(tmp, 56); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 54) | (tmp << (64 - 54)); + b5 = ror64(tmp, 54); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 9) | (tmp << (64 - 9)); + b7 = ror64(tmp, 9); b0 -= b7; tmp = b1 ^ b6; - b1 = (tmp >> 44) | (tmp << (64 - 44)); + b1 = ror64(tmp, 44); b6 -= b1; tmp = b7 ^ b2; - b7 = (tmp >> 39) | (tmp << (64 - 39)); + b7 = ror64(tmp, 39); b2 -= b7; tmp = b5 ^ b0; - b5 = (tmp >> 36) | (tmp << (64 - 36)); + b5 = ror64(tmp, 36); b0 -= b5; tmp = b3 ^ b6; - b3 = (tmp >> 49) | (tmp << (64 - 49)); + b3 = ror64(tmp, 49); b6 -= b3; tmp = b1 ^ b4; - b1 = (tmp >> 17) | (tmp << (64 - 17)); + b1 = ror64(tmp, 17); b4 -= b1; tmp = b3 ^ b0; - b3 = (tmp >> 42) | (tmp << (64 - 42)); + b3 = ror64(tmp, 42); b0 -= b3; tmp = b5 ^ b6; - b5 = (tmp >> 14) | (tmp << (64 - 14)); + b5 = ror64(tmp, 14); b6 -= b5; tmp = b7 ^ b4; - b7 = (tmp >> 27) | (tmp << (64 - 27)); + b7 = ror64(tmp, 27); b4 -= b7; tmp = b1 ^ b2; - b1 = (tmp >> 33) | (tmp << (64 - 33)); + b1 = ror64(tmp, 33); b2 -= b1; tmp = b7 ^ b6; - b7 = (tmp >> 37) | (tmp << (64 - 37)); + b7 = ror64(tmp, 37); b6 -= b7 + k5 + t0; b7 -= k6 + 8; tmp = b5 ^ b4; - b5 = (tmp >> 19) | (tmp << (64 - 19)); + b5 = ror64(tmp, 19); b4 -= b5 + k3; b5 -= k4 + t2; tmp = b3 ^ b2; - b3 = (tmp >> 36) | (tmp << (64 - 36)); + b3 = ror64(tmp, 36); b2 -= b3 + k1; b3 -= k2; tmp = b1 ^ b0; - b1 = (tmp >> 46) | (tmp << (64 - 46)); + b1 = ror64(tmp, 46); b0 -= b1 + k8; b1 -= k0; tmp = b3 ^ b4; - b3 = (tmp >> 22) | (tmp << (64 - 22)); + b3 = ror64(tmp, 22); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 56) | (tmp << (64 - 56)); + b5 = ror64(tmp, 56); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 35) | (tmp << (64 - 35)); + b7 = ror64(tmp, 35); b0 -= b7; tmp = b1 ^ b6; - b1 = (tmp >> 8) | (tmp << (64 - 8)); + b1 = ror64(tmp, 8); b6 -= b1; tmp = b7 ^ b2; - b7 = (tmp >> 43) | (tmp << (64 - 43)); + b7 = ror64(tmp, 43); b2 -= b7; tmp = b5 ^ b0; - b5 = (tmp >> 39) | (tmp << (64 - 39)); + b5 = ror64(tmp, 39); b0 -= b5; tmp = b3 ^ b6; - b3 = (tmp >> 29) | (tmp << (64 - 29)); + b3 = ror64(tmp, 29); b6 -= b3; tmp = b1 ^ b4; - b1 = (tmp >> 25) | (tmp << (64 - 25)); + b1 = ror64(tmp, 25); b4 -= b1; tmp = b3 ^ b0; - b3 = (tmp >> 17) | (tmp << (64 - 17)); + b3 = ror64(tmp, 17); b0 -= b3; tmp = b5 ^ b6; - b5 = (tmp >> 10) | (tmp << (64 - 10)); + b5 = ror64(tmp, 10); b6 -= b5; tmp = b7 ^ b4; - b7 = (tmp >> 50) | (tmp << (64 - 50)); + b7 = ror64(tmp, 50); b4 -= b7; tmp = b1 ^ b2; - b1 = (tmp >> 13) | (tmp << (64 - 13)); + b1 = ror64(tmp, 13); b2 -= b1; tmp = b7 ^ b6; - b7 = (tmp >> 24) | (tmp << (64 - 24)); + b7 = ror64(tmp, 24); b6 -= b7 + k4 + t2; b7 -= k5 + 7; tmp = b5 ^ b4; - b5 = (tmp >> 34) | (tmp << (64 - 34)); + b5 = ror64(tmp, 34); b4 -= b5 + k2; b5 -= k3 + t1; tmp = b3 ^ b2; - b3 = (tmp >> 30) | (tmp << (64 - 30)); + b3 = ror64(tmp, 30); b2 -= b3 + k0; b3 -= k1; tmp = b1 ^ b0; - b1 = (tmp >> 39) | (tmp << (64 - 39)); + b1 = ror64(tmp, 39); b0 -= b1 + k7; b1 -= k8; tmp = b3 ^ b4; - b3 = (tmp >> 56) | (tmp << (64 - 56)); + b3 = ror64(tmp, 56); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 54) | (tmp << (64 - 54)); + b5 = ror64(tmp, 54); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 9) | (tmp << (64 - 9)); + b7 = ror64(tmp, 9); b0 -= b7; tmp = b1 ^ b6; - b1 = (tmp >> 44) | (tmp << (64 - 44)); + b1 = ror64(tmp, 44); b6 -= b1; tmp = b7 ^ b2; - b7 = (tmp >> 39) | (tmp << (64 - 39)); + b7 = ror64(tmp, 39); b2 -= b7; tmp = b5 ^ b0; - b5 = (tmp >> 36) | (tmp << (64 - 36)); + b5 = ror64(tmp, 36); b0 -= b5; tmp = b3 ^ b6; - b3 = (tmp >> 49) | (tmp << (64 - 49)); + b3 = ror64(tmp, 49); b6 -= b3; tmp = b1 ^ b4; - b1 = (tmp >> 17) | (tmp << (64 - 17)); + b1 = ror64(tmp, 17); b4 -= b1; tmp = b3 ^ b0; - b3 = (tmp >> 42) | (tmp << (64 - 42)); + b3 = ror64(tmp, 42); b0 -= b3; tmp = b5 ^ b6; - b5 = (tmp >> 14) | (tmp << (64 - 14)); + b5 = ror64(tmp, 14); b6 -= b5; tmp = b7 ^ b4; - b7 = (tmp >> 27) | (tmp << (64 - 27)); + b7 = ror64(tmp, 27); b4 -= b7; tmp = b1 ^ b2; - b1 = (tmp >> 33) | (tmp << (64 - 33)); + b1 = ror64(tmp, 33); b2 -= b1; tmp = b7 ^ b6; - b7 = (tmp >> 37) | (tmp << (64 - 37)); + b7 = ror64(tmp, 37); b6 -= b7 + k3 + t1; b7 -= k4 + 6; tmp = b5 ^ b4; - b5 = (tmp >> 19) | (tmp << (64 - 19)); + b5 = ror64(tmp, 19); b4 -= b5 + k1; b5 -= k2 + t0; tmp = b3 ^ b2; - b3 = (tmp >> 36) | (tmp << (64 - 36)); + b3 = ror64(tmp, 36); b2 -= b3 + k8; b3 -= k0; tmp = b1 ^ b0; - b1 = (tmp >> 46) | (tmp << (64 - 46)); + b1 = ror64(tmp, 46); b0 -= b1 + k6; b1 -= k7; tmp = b3 ^ b4; - b3 = (tmp >> 22) | (tmp << (64 - 22)); + b3 = ror64(tmp, 22); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 56) | (tmp << (64 - 56)); + b5 = ror64(tmp, 56); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 35) | (tmp << (64 - 35)); + b7 = ror64(tmp, 35); b0 -= b7; tmp = b1 ^ b6; - b1 = (tmp >> 8) | (tmp << (64 - 8)); + b1 = ror64(tmp, 8); b6 -= b1; tmp = b7 ^ b2; - b7 = (tmp >> 43) | (tmp << (64 - 43)); + b7 = ror64(tmp, 43); b2 -= b7; tmp = b5 ^ b0; - b5 = (tmp >> 39) | (tmp << (64 - 39)); + b5 = ror64(tmp, 39); b0 -= b5; tmp = b3 ^ b6; - b3 = (tmp >> 29) | (tmp << (64 - 29)); + b3 = ror64(tmp, 29); b6 -= b3; tmp = b1 ^ b4; - b1 = (tmp >> 25) | (tmp << (64 - 25)); + b1 = ror64(tmp, 25); b4 -= b1; tmp = b3 ^ b0; - b3 = (tmp >> 17) | (tmp << (64 - 17)); + b3 = ror64(tmp, 17); b0 -= b3; tmp = b5 ^ b6; - b5 = (tmp >> 10) | (tmp << (64 - 10)); + b5 = ror64(tmp, 10); b6 -= b5; tmp = b7 ^ b4; - b7 = (tmp >> 50) | (tmp << (64 - 50)); + b7 = ror64(tmp, 50); b4 -= b7; tmp = b1 ^ b2; - b1 = (tmp >> 13) | (tmp << (64 - 13)); + b1 = ror64(tmp, 13); b2 -= b1; tmp = b7 ^ b6; - b7 = (tmp >> 24) | (tmp << (64 - 24)); + b7 = ror64(tmp, 24); b6 -= b7 + k2 + t0; b7 -= k3 + 5; tmp = b5 ^ b4; - b5 = (tmp >> 34) | (tmp << (64 - 34)); + b5 = ror64(tmp, 34); b4 -= b5 + k0; b5 -= k1 + t2; tmp = b3 ^ b2; - b3 = (tmp >> 30) | (tmp << (64 - 30)); + b3 = ror64(tmp, 30); b2 -= b3 + k7; b3 -= k8; tmp = b1 ^ b0; - b1 = (tmp >> 39) | (tmp << (64 - 39)); + b1 = ror64(tmp, 39); b0 -= b1 + k5; b1 -= k6; tmp = b3 ^ b4; - b3 = (tmp >> 56) | (tmp << (64 - 56)); + b3 = ror64(tmp, 56); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 54) | (tmp << (64 - 54)); + b5 = ror64(tmp, 54); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 9) | (tmp << (64 - 9)); + b7 = ror64(tmp, 9); b0 -= b7; tmp = b1 ^ b6; - b1 = (tmp >> 44) | (tmp << (64 - 44)); + b1 = ror64(tmp, 44); b6 -= b1; tmp = b7 ^ b2; - b7 = (tmp >> 39) | (tmp << (64 - 39)); + b7 = ror64(tmp, 39); b2 -= b7; tmp = b5 ^ b0; - b5 = (tmp >> 36) | (tmp << (64 - 36)); + b5 = ror64(tmp, 36); b0 -= b5; tmp = b3 ^ b6; - b3 = (tmp >> 49) | (tmp << (64 - 49)); + b3 = ror64(tmp, 49); b6 -= b3; tmp = b1 ^ b4; - b1 = (tmp >> 17) | (tmp << (64 - 17)); + b1 = ror64(tmp, 17); b4 -= b1; tmp = b3 ^ b0; - b3 = (tmp >> 42) | (tmp << (64 - 42)); + b3 = ror64(tmp, 42); b0 -= b3; tmp = b5 ^ b6; - b5 = (tmp >> 14) | (tmp << (64 - 14)); + b5 = ror64(tmp, 14); b6 -= b5; tmp = b7 ^ b4; - b7 = (tmp >> 27) | (tmp << (64 - 27)); + b7 = ror64(tmp, 27); b4 -= b7; tmp = b1 ^ b2; - b1 = (tmp >> 33) | (tmp << (64 - 33)); + b1 = ror64(tmp, 33); b2 -= b1; tmp = b7 ^ b6; - b7 = (tmp >> 37) | (tmp << (64 - 37)); + b7 = ror64(tmp, 37); b6 -= b7 + k1 + t2; b7 -= k2 + 4; tmp = b5 ^ b4; - b5 = (tmp >> 19) | (tmp << (64 - 19)); + b5 = ror64(tmp, 19); b4 -= b5 + k8; b5 -= k0 + t1; tmp = b3 ^ b2; - b3 = (tmp >> 36) | (tmp << (64 - 36)); + b3 = ror64(tmp, 36); b2 -= b3 + k6; b3 -= k7; tmp = b1 ^ b0; - b1 = (tmp >> 46) | (tmp << (64 - 46)); + b1 = ror64(tmp, 46); b0 -= b1 + k4; b1 -= k5; tmp = b3 ^ b4; - b3 = (tmp >> 22) | (tmp << (64 - 22)); + b3 = ror64(tmp, 22); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 56) | (tmp << (64 - 56)); + b5 = ror64(tmp, 56); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 35) | (tmp << (64 - 35)); + b7 = ror64(tmp, 35); b0 -= b7; tmp = b1 ^ b6; - b1 = (tmp >> 8) | (tmp << (64 - 8)); + b1 = ror64(tmp, 8); b6 -= b1; tmp = b7 ^ b2; - b7 = (tmp >> 43) | (tmp << (64 - 43)); + b7 = ror64(tmp, 43); b2 -= b7; tmp = b5 ^ b0; - b5 = (tmp >> 39) | (tmp << (64 - 39)); + b5 = ror64(tmp, 39); b0 -= b5; tmp = b3 ^ b6; - b3 = (tmp >> 29) | (tmp << (64 - 29)); + b3 = ror64(tmp, 29); b6 -= b3; tmp = b1 ^ b4; - b1 = (tmp >> 25) | (tmp << (64 - 25)); + b1 = ror64(tmp, 25); b4 -= b1; tmp = b3 ^ b0; - b3 = (tmp >> 17) | (tmp << (64 - 17)); + b3 = ror64(tmp, 17); b0 -= b3; tmp = b5 ^ b6; - b5 = (tmp >> 10) | (tmp << (64 - 10)); + b5 = ror64(tmp, 10); b6 -= b5; tmp = b7 ^ b4; - b7 = (tmp >> 50) | (tmp << (64 - 50)); + b7 = ror64(tmp, 50); b4 -= b7; tmp = b1 ^ b2; - b1 = (tmp >> 13) | (tmp << (64 - 13)); + b1 = ror64(tmp, 13); b2 -= b1; tmp = b7 ^ b6; - b7 = (tmp >> 24) | (tmp << (64 - 24)); + b7 = ror64(tmp, 24); b6 -= b7 + k0 + t1; b7 -= k1 + 3; tmp = b5 ^ b4; - b5 = (tmp >> 34) | (tmp << (64 - 34)); + b5 = ror64(tmp, 34); b4 -= b5 + k7; b5 -= k8 + t0; tmp = b3 ^ b2; - b3 = (tmp >> 30) | (tmp << (64 - 30)); + b3 = ror64(tmp, 30); b2 -= b3 + k5; b3 -= k6; tmp = b1 ^ b0; - b1 = (tmp >> 39) | (tmp << (64 - 39)); + b1 = ror64(tmp, 39); b0 -= b1 + k3; b1 -= k4; tmp = b3 ^ b4; - b3 = (tmp >> 56) | (tmp << (64 - 56)); + b3 = ror64(tmp, 56); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 54) | (tmp << (64 - 54)); + b5 = ror64(tmp, 54); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 9) | (tmp << (64 - 9)); + b7 = ror64(tmp, 9); b0 -= b7; tmp = b1 ^ b6; - b1 = (tmp >> 44) | (tmp << (64 - 44)); + b1 = ror64(tmp, 44); b6 -= b1; tmp = b7 ^ b2; - b7 = (tmp >> 39) | (tmp << (64 - 39)); + b7 = ror64(tmp, 39); b2 -= b7; tmp = b5 ^ b0; - b5 = (tmp >> 36) | (tmp << (64 - 36)); + b5 = ror64(tmp, 36); b0 -= b5; tmp = b3 ^ b6; - b3 = (tmp >> 49) | (tmp << (64 - 49)); + b3 = ror64(tmp, 49); b6 -= b3; tmp = b1 ^ b4; - b1 = (tmp >> 17) | (tmp << (64 - 17)); + b1 = ror64(tmp, 17); b4 -= b1; tmp = b3 ^ b0; - b3 = (tmp >> 42) | (tmp << (64 - 42)); + b3 = ror64(tmp, 42); b0 -= b3; tmp = b5 ^ b6; - b5 = (tmp >> 14) | (tmp << (64 - 14)); + b5 = ror64(tmp, 14); b6 -= b5; tmp = b7 ^ b4; - b7 = (tmp >> 27) | (tmp << (64 - 27)); + b7 = ror64(tmp, 27); b4 -= b7; tmp = b1 ^ b2; - b1 = (tmp >> 33) | (tmp << (64 - 33)); + b1 = ror64(tmp, 33); b2 -= b1; tmp = b7 ^ b6; - b7 = (tmp >> 37) | (tmp << (64 - 37)); + b7 = ror64(tmp, 37); b6 -= b7 + k8 + t0; b7 -= k0 + 2; tmp = b5 ^ b4; - b5 = (tmp >> 19) | (tmp << (64 - 19)); + b5 = ror64(tmp, 19); b4 -= b5 + k6; b5 -= k7 + t2; tmp = b3 ^ b2; - b3 = (tmp >> 36) | (tmp << (64 - 36)); + b3 = ror64(tmp, 36); b2 -= b3 + k4; b3 -= k5; tmp = b1 ^ b0; - b1 = (tmp >> 46) | (tmp << (64 - 46)); + b1 = ror64(tmp, 46); b0 -= b1 + k2; b1 -= k3; tmp = b3 ^ b4; - b3 = (tmp >> 22) | (tmp << (64 - 22)); + b3 = ror64(tmp, 22); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 56) | (tmp << (64 - 56)); + b5 = ror64(tmp, 56); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 35) | (tmp << (64 - 35)); + b7 = ror64(tmp, 35); b0 -= b7; tmp = b1 ^ b6; - b1 = (tmp >> 8) | (tmp << (64 - 8)); + b1 = ror64(tmp, 8); b6 -= b1; tmp = b7 ^ b2; - b7 = (tmp >> 43) | (tmp << (64 - 43)); + b7 = ror64(tmp, 43); b2 -= b7; tmp = b5 ^ b0; - b5 = (tmp >> 39) | (tmp << (64 - 39)); + b5 = ror64(tmp, 39); b0 -= b5; tmp = b3 ^ b6; - b3 = (tmp >> 29) | (tmp << (64 - 29)); + b3 = ror64(tmp, 29); b6 -= b3; tmp = b1 ^ b4; - b1 = (tmp >> 25) | (tmp << (64 - 25)); + b1 = ror64(tmp, 25); b4 -= b1; tmp = b3 ^ b0; - b3 = (tmp >> 17) | (tmp << (64 - 17)); + b3 = ror64(tmp, 17); b0 -= b3; tmp = b5 ^ b6; - b5 = (tmp >> 10) | (tmp << (64 - 10)); + b5 = ror64(tmp, 10); b6 -= b5; tmp = b7 ^ b4; - b7 = (tmp >> 50) | (tmp << (64 - 50)); + b7 = ror64(tmp, 50); b4 -= b7; tmp = b1 ^ b2; - b1 = (tmp >> 13) | (tmp << (64 - 13)); + b1 = ror64(tmp, 13); b2 -= b1; tmp = b7 ^ b6; - b7 = (tmp >> 24) | (tmp << (64 - 24)); + b7 = ror64(tmp, 24); b6 -= b7 + k7 + t2; b7 -= k8 + 1; tmp = b5 ^ b4; - b5 = (tmp >> 34) | (tmp << (64 - 34)); + b5 = ror64(tmp, 34); b4 -= b5 + k5; b5 -= k6 + t1; tmp = b3 ^ b2; - b3 = (tmp >> 30) | (tmp << (64 - 30)); + b3 = ror64(tmp, 30); b2 -= b3 + k3; b3 -= k4; tmp = b1 ^ b0; - b1 = (tmp >> 39) | (tmp << (64 - 39)); + b1 = ror64(tmp, 39); b0 -= b1 + k1; b1 -= k2; tmp = b3 ^ b4; - b3 = (tmp >> 56) | (tmp << (64 - 56)); + b3 = ror64(tmp, 56); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 54) | (tmp << (64 - 54)); + b5 = ror64(tmp, 54); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 9) | (tmp << (64 - 9)); + b7 = ror64(tmp, 9); b0 -= b7; tmp = b1 ^ b6; - b1 = (tmp >> 44) | (tmp << (64 - 44)); + b1 = ror64(tmp, 44); b6 -= b1; tmp = b7 ^ b2; - b7 = (tmp >> 39) | (tmp << (64 - 39)); + b7 = ror64(tmp, 39); b2 -= b7; tmp = b5 ^ b0; - b5 = (tmp >> 36) | (tmp << (64 - 36)); + b5 = ror64(tmp, 36); b0 -= b5; tmp = b3 ^ b6; - b3 = (tmp >> 49) | (tmp << (64 - 49)); + b3 = ror64(tmp, 49); b6 -= b3; tmp = b1 ^ b4; - b1 = (tmp >> 17) | (tmp << (64 - 17)); + b1 = ror64(tmp, 17); b4 -= b1; tmp = b3 ^ b0; - b3 = (tmp >> 42) | (tmp << (64 - 42)); + b3 = ror64(tmp, 42); b0 -= b3; tmp = b5 ^ b6; - b5 = (tmp >> 14) | (tmp << (64 - 14)); + b5 = ror64(tmp, 14); b6 -= b5; tmp = b7 ^ b4; - b7 = (tmp >> 27) | (tmp << (64 - 27)); + b7 = ror64(tmp, 27); b4 -= b7; tmp = b1 ^ b2; - b1 = (tmp >> 33) | (tmp << (64 - 33)); + b1 = ror64(tmp, 33); b2 -= b1; tmp = b7 ^ b6; - b7 = (tmp >> 37) | (tmp << (64 - 37)); + b7 = ror64(tmp, 37); b6 -= b7 + k6 + t1; b7 -= k7; tmp = b5 ^ b4; - b5 = (tmp >> 19) | (tmp << (64 - 19)); + b5 = ror64(tmp, 19); b4 -= b5 + k4; b5 -= k5 + t0; tmp = b3 ^ b2; - b3 = (tmp >> 36) | (tmp << (64 - 36)); + b3 = ror64(tmp, 36); b2 -= b3 + k2; b3 -= k3; tmp = b1 ^ b0; - b1 = (tmp >> 46) | (tmp << (64 - 46)); + b1 = ror64(tmp, 46); b0 -= b1 + k0; b1 -= k1; @@ -5521,2722 +5521,2722 @@ void threefish_decrypt_1024(struct threefish_key *key_ctx, u64 *input, b14 -= k0 + t0; b15 -= k1 + 20; tmp = b7 ^ b12; - b7 = (tmp >> 20) | (tmp << (64 - 20)); + b7 = ror64(tmp, 20); b12 -= b7; tmp = b3 ^ b10; - b3 = (tmp >> 37) | (tmp << (64 - 37)); + b3 = ror64(tmp, 37); b10 -= b3; tmp = b5 ^ b8; - b5 = (tmp >> 31) | (tmp << (64 - 31)); + b5 = ror64(tmp, 31); b8 -= b5; tmp = b1 ^ b14; - b1 = (tmp >> 23) | (tmp << (64 - 23)); + b1 = ror64(tmp, 23); b14 -= b1; tmp = b9 ^ b4; - b9 = (tmp >> 52) | (tmp << (64 - 52)); + b9 = ror64(tmp, 52); b4 -= b9; tmp = b13 ^ b6; - b13 = (tmp >> 35) | (tmp << (64 - 35)); + b13 = ror64(tmp, 35); b6 -= b13; tmp = b11 ^ b2; - b11 = (tmp >> 48) | (tmp << (64 - 48)); + b11 = ror64(tmp, 48); b2 -= b11; tmp = b15 ^ b0; - b15 = (tmp >> 9) | (tmp << (64 - 9)); + b15 = ror64(tmp, 9); b0 -= b15; tmp = b9 ^ b10; - b9 = (tmp >> 25) | (tmp << (64 - 25)); + b9 = ror64(tmp, 25); b10 -= b9; tmp = b11 ^ b8; - b11 = (tmp >> 44) | (tmp << (64 - 44)); + b11 = ror64(tmp, 44); b8 -= b11; tmp = b13 ^ b14; - b13 = (tmp >> 42) | (tmp << (64 - 42)); + b13 = ror64(tmp, 42); b14 -= b13; tmp = b15 ^ b12; - b15 = (tmp >> 19) | (tmp << (64 - 19)); + b15 = ror64(tmp, 19); b12 -= b15; tmp = b1 ^ b6; - b1 = (tmp >> 46) | (tmp << (64 - 46)); + b1 = ror64(tmp, 46); b6 -= b1; tmp = b3 ^ b4; - b3 = (tmp >> 47) | (tmp << (64 - 47)); + b3 = ror64(tmp, 47); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 44) | (tmp << (64 - 44)); + b5 = ror64(tmp, 44); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 31) | (tmp << (64 - 31)); + b7 = ror64(tmp, 31); b0 -= b7; tmp = b1 ^ b8; - b1 = (tmp >> 41) | (tmp << (64 - 41)); + b1 = ror64(tmp, 41); b8 -= b1; tmp = b5 ^ b14; - b5 = (tmp >> 42) | (tmp << (64 - 42)); + b5 = ror64(tmp, 42); b14 -= b5; tmp = b3 ^ b12; - b3 = (tmp >> 53) | (tmp << (64 - 53)); + b3 = ror64(tmp, 53); b12 -= b3; tmp = b7 ^ b10; - b7 = (tmp >> 4) | (tmp << (64 - 4)); + b7 = ror64(tmp, 4); b10 -= b7; tmp = b15 ^ b4; - b15 = (tmp >> 51) | (tmp << (64 - 51)); + b15 = ror64(tmp, 51); b4 -= b15; tmp = b11 ^ b6; - b11 = (tmp >> 56) | (tmp << (64 - 56)); + b11 = ror64(tmp, 56); b6 -= b11; tmp = b13 ^ b2; - b13 = (tmp >> 34) | (tmp << (64 - 34)); + b13 = ror64(tmp, 34); b2 -= b13; tmp = b9 ^ b0; - b9 = (tmp >> 16) | (tmp << (64 - 16)); + b9 = ror64(tmp, 16); b0 -= b9; tmp = b15 ^ b14; - b15 = (tmp >> 30) | (tmp << (64 - 30)); + b15 = ror64(tmp, 30); b14 -= b15 + k16 + t2; b15 -= k0 + 19; tmp = b13 ^ b12; - b13 = (tmp >> 44) | (tmp << (64 - 44)); + b13 = ror64(tmp, 44); b12 -= b13 + k14; b13 -= k15 + t1; tmp = b11 ^ b10; - b11 = (tmp >> 47) | (tmp << (64 - 47)); + b11 = ror64(tmp, 47); b10 -= b11 + k12; b11 -= k13; tmp = b9 ^ b8; - b9 = (tmp >> 12) | (tmp << (64 - 12)); + b9 = ror64(tmp, 12); b8 -= b9 + k10; b9 -= k11; tmp = b7 ^ b6; - b7 = (tmp >> 31) | (tmp << (64 - 31)); + b7 = ror64(tmp, 31); b6 -= b7 + k8; b7 -= k9; tmp = b5 ^ b4; - b5 = (tmp >> 37) | (tmp << (64 - 37)); + b5 = ror64(tmp, 37); b4 -= b5 + k6; b5 -= k7; tmp = b3 ^ b2; - b3 = (tmp >> 9) | (tmp << (64 - 9)); + b3 = ror64(tmp, 9); b2 -= b3 + k4; b3 -= k5; tmp = b1 ^ b0; - b1 = (tmp >> 41) | (tmp << (64 - 41)); + b1 = ror64(tmp, 41); b0 -= b1 + k2; b1 -= k3; tmp = b7 ^ b12; - b7 = (tmp >> 25) | (tmp << (64 - 25)); + b7 = ror64(tmp, 25); b12 -= b7; tmp = b3 ^ b10; - b3 = (tmp >> 16) | (tmp << (64 - 16)); + b3 = ror64(tmp, 16); b10 -= b3; tmp = b5 ^ b8; - b5 = (tmp >> 28) | (tmp << (64 - 28)); + b5 = ror64(tmp, 28); b8 -= b5; tmp = b1 ^ b14; - b1 = (tmp >> 47) | (tmp << (64 - 47)); + b1 = ror64(tmp, 47); b14 -= b1; tmp = b9 ^ b4; - b9 = (tmp >> 41) | (tmp << (64 - 41)); + b9 = ror64(tmp, 41); b4 -= b9; tmp = b13 ^ b6; - b13 = (tmp >> 48) | (tmp << (64 - 48)); + b13 = ror64(tmp, 48); b6 -= b13; tmp = b11 ^ b2; - b11 = (tmp >> 20) | (tmp << (64 - 20)); + b11 = ror64(tmp, 20); b2 -= b11; tmp = b15 ^ b0; - b15 = (tmp >> 5) | (tmp << (64 - 5)); + b15 = ror64(tmp, 5); b0 -= b15; tmp = b9 ^ b10; - b9 = (tmp >> 17) | (tmp << (64 - 17)); + b9 = ror64(tmp, 17); b10 -= b9; tmp = b11 ^ b8; - b11 = (tmp >> 59) | (tmp << (64 - 59)); + b11 = ror64(tmp, 59); b8 -= b11; tmp = b13 ^ b14; - b13 = (tmp >> 41) | (tmp << (64 - 41)); + b13 = ror64(tmp, 41); b14 -= b13; tmp = b15 ^ b12; - b15 = (tmp >> 34) | (tmp << (64 - 34)); + b15 = ror64(tmp, 34); b12 -= b15; tmp = b1 ^ b6; - b1 = (tmp >> 13) | (tmp << (64 - 13)); + b1 = ror64(tmp, 13); b6 -= b1; tmp = b3 ^ b4; - b3 = (tmp >> 51) | (tmp << (64 - 51)); + b3 = ror64(tmp, 51); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 4) | (tmp << (64 - 4)); + b5 = ror64(tmp, 4); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 33) | (tmp << (64 - 33)); + b7 = ror64(tmp, 33); b0 -= b7; tmp = b1 ^ b8; - b1 = (tmp >> 52) | (tmp << (64 - 52)); + b1 = ror64(tmp, 52); b8 -= b1; tmp = b5 ^ b14; - b5 = (tmp >> 23) | (tmp << (64 - 23)); + b5 = ror64(tmp, 23); b14 -= b5; tmp = b3 ^ b12; - b3 = (tmp >> 18) | (tmp << (64 - 18)); + b3 = ror64(tmp, 18); b12 -= b3; tmp = b7 ^ b10; - b7 = (tmp >> 49) | (tmp << (64 - 49)); + b7 = ror64(tmp, 49); b10 -= b7; tmp = b15 ^ b4; - b15 = (tmp >> 55) | (tmp << (64 - 55)); + b15 = ror64(tmp, 55); b4 -= b15; tmp = b11 ^ b6; - b11 = (tmp >> 10) | (tmp << (64 - 10)); + b11 = ror64(tmp, 10); b6 -= b11; tmp = b13 ^ b2; - b13 = (tmp >> 19) | (tmp << (64 - 19)); + b13 = ror64(tmp, 19); b2 -= b13; tmp = b9 ^ b0; - b9 = (tmp >> 38) | (tmp << (64 - 38)); + b9 = ror64(tmp, 38); b0 -= b9; tmp = b15 ^ b14; - b15 = (tmp >> 37) | (tmp << (64 - 37)); + b15 = ror64(tmp, 37); b14 -= b15 + k15 + t1; b15 -= k16 + 18; tmp = b13 ^ b12; - b13 = (tmp >> 22) | (tmp << (64 - 22)); + b13 = ror64(tmp, 22); b12 -= b13 + k13; b13 -= k14 + t0; tmp = b11 ^ b10; - b11 = (tmp >> 17) | (tmp << (64 - 17)); + b11 = ror64(tmp, 17); b10 -= b11 + k11; b11 -= k12; tmp = b9 ^ b8; - b9 = (tmp >> 8) | (tmp << (64 - 8)); + b9 = ror64(tmp, 8); b8 -= b9 + k9; b9 -= k10; tmp = b7 ^ b6; - b7 = (tmp >> 47) | (tmp << (64 - 47)); + b7 = ror64(tmp, 47); b6 -= b7 + k7; b7 -= k8; tmp = b5 ^ b4; - b5 = (tmp >> 8) | (tmp << (64 - 8)); + b5 = ror64(tmp, 8); b4 -= b5 + k5; b5 -= k6; tmp = b3 ^ b2; - b3 = (tmp >> 13) | (tmp << (64 - 13)); + b3 = ror64(tmp, 13); b2 -= b3 + k3; b3 -= k4; tmp = b1 ^ b0; - b1 = (tmp >> 24) | (tmp << (64 - 24)); + b1 = ror64(tmp, 24); b0 -= b1 + k1; b1 -= k2; tmp = b7 ^ b12; - b7 = (tmp >> 20) | (tmp << (64 - 20)); + b7 = ror64(tmp, 20); b12 -= b7; tmp = b3 ^ b10; - b3 = (tmp >> 37) | (tmp << (64 - 37)); + b3 = ror64(tmp, 37); b10 -= b3; tmp = b5 ^ b8; - b5 = (tmp >> 31) | (tmp << (64 - 31)); + b5 = ror64(tmp, 31); b8 -= b5; tmp = b1 ^ b14; - b1 = (tmp >> 23) | (tmp << (64 - 23)); + b1 = ror64(tmp, 23); b14 -= b1; tmp = b9 ^ b4; - b9 = (tmp >> 52) | (tmp << (64 - 52)); + b9 = ror64(tmp, 52); b4 -= b9; tmp = b13 ^ b6; - b13 = (tmp >> 35) | (tmp << (64 - 35)); + b13 = ror64(tmp, 35); b6 -= b13; tmp = b11 ^ b2; - b11 = (tmp >> 48) | (tmp << (64 - 48)); + b11 = ror64(tmp, 48); b2 -= b11; tmp = b15 ^ b0; - b15 = (tmp >> 9) | (tmp << (64 - 9)); + b15 = ror64(tmp, 9); b0 -= b15; tmp = b9 ^ b10; - b9 = (tmp >> 25) | (tmp << (64 - 25)); + b9 = ror64(tmp, 25); b10 -= b9; tmp = b11 ^ b8; - b11 = (tmp >> 44) | (tmp << (64 - 44)); + b11 = ror64(tmp, 44); b8 -= b11; tmp = b13 ^ b14; - b13 = (tmp >> 42) | (tmp << (64 - 42)); + b13 = ror64(tmp, 42); b14 -= b13; tmp = b15 ^ b12; - b15 = (tmp >> 19) | (tmp << (64 - 19)); + b15 = ror64(tmp, 19); b12 -= b15; tmp = b1 ^ b6; - b1 = (tmp >> 46) | (tmp << (64 - 46)); + b1 = ror64(tmp, 46); b6 -= b1; tmp = b3 ^ b4; - b3 = (tmp >> 47) | (tmp << (64 - 47)); + b3 = ror64(tmp, 47); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 44) | (tmp << (64 - 44)); + b5 = ror64(tmp, 44); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 31) | (tmp << (64 - 31)); + b7 = ror64(tmp, 31); b0 -= b7; tmp = b1 ^ b8; - b1 = (tmp >> 41) | (tmp << (64 - 41)); + b1 = ror64(tmp, 41); b8 -= b1; tmp = b5 ^ b14; - b5 = (tmp >> 42) | (tmp << (64 - 42)); + b5 = ror64(tmp, 42); b14 -= b5; tmp = b3 ^ b12; - b3 = (tmp >> 53) | (tmp << (64 - 53)); + b3 = ror64(tmp, 53); b12 -= b3; tmp = b7 ^ b10; - b7 = (tmp >> 4) | (tmp << (64 - 4)); + b7 = ror64(tmp, 4); b10 -= b7; tmp = b15 ^ b4; - b15 = (tmp >> 51) | (tmp << (64 - 51)); + b15 = ror64(tmp, 51); b4 -= b15; tmp = b11 ^ b6; - b11 = (tmp >> 56) | (tmp << (64 - 56)); + b11 = ror64(tmp, 56); b6 -= b11; tmp = b13 ^ b2; - b13 = (tmp >> 34) | (tmp << (64 - 34)); + b13 = ror64(tmp, 34); b2 -= b13; tmp = b9 ^ b0; - b9 = (tmp >> 16) | (tmp << (64 - 16)); + b9 = ror64(tmp, 16); b0 -= b9; tmp = b15 ^ b14; - b15 = (tmp >> 30) | (tmp << (64 - 30)); + b15 = ror64(tmp, 30); b14 -= b15 + k14 + t0; b15 -= k15 + 17; tmp = b13 ^ b12; - b13 = (tmp >> 44) | (tmp << (64 - 44)); + b13 = ror64(tmp, 44); b12 -= b13 + k12; b13 -= k13 + t2; tmp = b11 ^ b10; - b11 = (tmp >> 47) | (tmp << (64 - 47)); + b11 = ror64(tmp, 47); b10 -= b11 + k10; b11 -= k11; tmp = b9 ^ b8; - b9 = (tmp >> 12) | (tmp << (64 - 12)); + b9 = ror64(tmp, 12); b8 -= b9 + k8; b9 -= k9; tmp = b7 ^ b6; - b7 = (tmp >> 31) | (tmp << (64 - 31)); + b7 = ror64(tmp, 31); b6 -= b7 + k6; b7 -= k7; tmp = b5 ^ b4; - b5 = (tmp >> 37) | (tmp << (64 - 37)); + b5 = ror64(tmp, 37); b4 -= b5 + k4; b5 -= k5; tmp = b3 ^ b2; - b3 = (tmp >> 9) | (tmp << (64 - 9)); + b3 = ror64(tmp, 9); b2 -= b3 + k2; b3 -= k3; tmp = b1 ^ b0; - b1 = (tmp >> 41) | (tmp << (64 - 41)); + b1 = ror64(tmp, 41); b0 -= b1 + k0; b1 -= k1; tmp = b7 ^ b12; - b7 = (tmp >> 25) | (tmp << (64 - 25)); + b7 = ror64(tmp, 25); b12 -= b7; tmp = b3 ^ b10; - b3 = (tmp >> 16) | (tmp << (64 - 16)); + b3 = ror64(tmp, 16); b10 -= b3; tmp = b5 ^ b8; - b5 = (tmp >> 28) | (tmp << (64 - 28)); + b5 = ror64(tmp, 28); b8 -= b5; tmp = b1 ^ b14; - b1 = (tmp >> 47) | (tmp << (64 - 47)); + b1 = ror64(tmp, 47); b14 -= b1; tmp = b9 ^ b4; - b9 = (tmp >> 41) | (tmp << (64 - 41)); + b9 = ror64(tmp, 41); b4 -= b9; tmp = b13 ^ b6; - b13 = (tmp >> 48) | (tmp << (64 - 48)); + b13 = ror64(tmp, 48); b6 -= b13; tmp = b11 ^ b2; - b11 = (tmp >> 20) | (tmp << (64 - 20)); + b11 = ror64(tmp, 20); b2 -= b11; tmp = b15 ^ b0; - b15 = (tmp >> 5) | (tmp << (64 - 5)); + b15 = ror64(tmp, 5); b0 -= b15; tmp = b9 ^ b10; - b9 = (tmp >> 17) | (tmp << (64 - 17)); + b9 = ror64(tmp, 17); b10 -= b9; tmp = b11 ^ b8; - b11 = (tmp >> 59) | (tmp << (64 - 59)); + b11 = ror64(tmp, 59); b8 -= b11; tmp = b13 ^ b14; - b13 = (tmp >> 41) | (tmp << (64 - 41)); + b13 = ror64(tmp, 41); b14 -= b13; tmp = b15 ^ b12; - b15 = (tmp >> 34) | (tmp << (64 - 34)); + b15 = ror64(tmp, 34); b12 -= b15; tmp = b1 ^ b6; - b1 = (tmp >> 13) | (tmp << (64 - 13)); + b1 = ror64(tmp, 13); b6 -= b1; tmp = b3 ^ b4; - b3 = (tmp >> 51) | (tmp << (64 - 51)); + b3 = ror64(tmp, 51); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 4) | (tmp << (64 - 4)); + b5 = ror64(tmp, 4); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 33) | (tmp << (64 - 33)); + b7 = ror64(tmp, 33); b0 -= b7; tmp = b1 ^ b8; - b1 = (tmp >> 52) | (tmp << (64 - 52)); + b1 = ror64(tmp, 52); b8 -= b1; tmp = b5 ^ b14; - b5 = (tmp >> 23) | (tmp << (64 - 23)); + b5 = ror64(tmp, 23); b14 -= b5; tmp = b3 ^ b12; - b3 = (tmp >> 18) | (tmp << (64 - 18)); + b3 = ror64(tmp, 18); b12 -= b3; tmp = b7 ^ b10; - b7 = (tmp >> 49) | (tmp << (64 - 49)); + b7 = ror64(tmp, 49); b10 -= b7; tmp = b15 ^ b4; - b15 = (tmp >> 55) | (tmp << (64 - 55)); + b15 = ror64(tmp, 55); b4 -= b15; tmp = b11 ^ b6; - b11 = (tmp >> 10) | (tmp << (64 - 10)); + b11 = ror64(tmp, 10); b6 -= b11; tmp = b13 ^ b2; - b13 = (tmp >> 19) | (tmp << (64 - 19)); + b13 = ror64(tmp, 19); b2 -= b13; tmp = b9 ^ b0; - b9 = (tmp >> 38) | (tmp << (64 - 38)); + b9 = ror64(tmp, 38); b0 -= b9; tmp = b15 ^ b14; - b15 = (tmp >> 37) | (tmp << (64 - 37)); + b15 = ror64(tmp, 37); b14 -= b15 + k13 + t2; b15 -= k14 + 16; tmp = b13 ^ b12; - b13 = (tmp >> 22) | (tmp << (64 - 22)); + b13 = ror64(tmp, 22); b12 -= b13 + k11; b13 -= k12 + t1; tmp = b11 ^ b10; - b11 = (tmp >> 17) | (tmp << (64 - 17)); + b11 = ror64(tmp, 17); b10 -= b11 + k9; b11 -= k10; tmp = b9 ^ b8; - b9 = (tmp >> 8) | (tmp << (64 - 8)); + b9 = ror64(tmp, 8); b8 -= b9 + k7; b9 -= k8; tmp = b7 ^ b6; - b7 = (tmp >> 47) | (tmp << (64 - 47)); + b7 = ror64(tmp, 47); b6 -= b7 + k5; b7 -= k6; tmp = b5 ^ b4; - b5 = (tmp >> 8) | (tmp << (64 - 8)); + b5 = ror64(tmp, 8); b4 -= b5 + k3; b5 -= k4; tmp = b3 ^ b2; - b3 = (tmp >> 13) | (tmp << (64 - 13)); + b3 = ror64(tmp, 13); b2 -= b3 + k1; b3 -= k2; tmp = b1 ^ b0; - b1 = (tmp >> 24) | (tmp << (64 - 24)); + b1 = ror64(tmp, 24); b0 -= b1 + k16; b1 -= k0; tmp = b7 ^ b12; - b7 = (tmp >> 20) | (tmp << (64 - 20)); + b7 = ror64(tmp, 20); b12 -= b7; tmp = b3 ^ b10; - b3 = (tmp >> 37) | (tmp << (64 - 37)); + b3 = ror64(tmp, 37); b10 -= b3; tmp = b5 ^ b8; - b5 = (tmp >> 31) | (tmp << (64 - 31)); + b5 = ror64(tmp, 31); b8 -= b5; tmp = b1 ^ b14; - b1 = (tmp >> 23) | (tmp << (64 - 23)); + b1 = ror64(tmp, 23); b14 -= b1; tmp = b9 ^ b4; - b9 = (tmp >> 52) | (tmp << (64 - 52)); + b9 = ror64(tmp, 52); b4 -= b9; tmp = b13 ^ b6; - b13 = (tmp >> 35) | (tmp << (64 - 35)); + b13 = ror64(tmp, 35); b6 -= b13; tmp = b11 ^ b2; - b11 = (tmp >> 48) | (tmp << (64 - 48)); + b11 = ror64(tmp, 48); b2 -= b11; tmp = b15 ^ b0; - b15 = (tmp >> 9) | (tmp << (64 - 9)); + b15 = ror64(tmp, 9); b0 -= b15; tmp = b9 ^ b10; - b9 = (tmp >> 25) | (tmp << (64 - 25)); + b9 = ror64(tmp, 25); b10 -= b9; tmp = b11 ^ b8; - b11 = (tmp >> 44) | (tmp << (64 - 44)); + b11 = ror64(tmp, 44); b8 -= b11; tmp = b13 ^ b14; - b13 = (tmp >> 42) | (tmp << (64 - 42)); + b13 = ror64(tmp, 42); b14 -= b13; tmp = b15 ^ b12; - b15 = (tmp >> 19) | (tmp << (64 - 19)); + b15 = ror64(tmp, 19); b12 -= b15; tmp = b1 ^ b6; - b1 = (tmp >> 46) | (tmp << (64 - 46)); + b1 = ror64(tmp, 46); b6 -= b1; tmp = b3 ^ b4; - b3 = (tmp >> 47) | (tmp << (64 - 47)); + b3 = ror64(tmp, 47); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 44) | (tmp << (64 - 44)); + b5 = ror64(tmp, 44); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 31) | (tmp << (64 - 31)); + b7 = ror64(tmp, 31); b0 -= b7; tmp = b1 ^ b8; - b1 = (tmp >> 41) | (tmp << (64 - 41)); + b1 = ror64(tmp, 41); b8 -= b1; tmp = b5 ^ b14; - b5 = (tmp >> 42) | (tmp << (64 - 42)); + b5 = ror64(tmp, 42); b14 -= b5; tmp = b3 ^ b12; - b3 = (tmp >> 53) | (tmp << (64 - 53)); + b3 = ror64(tmp, 53); b12 -= b3; tmp = b7 ^ b10; - b7 = (tmp >> 4) | (tmp << (64 - 4)); + b7 = ror64(tmp, 4); b10 -= b7; tmp = b15 ^ b4; - b15 = (tmp >> 51) | (tmp << (64 - 51)); + b15 = ror64(tmp, 51); b4 -= b15; tmp = b11 ^ b6; - b11 = (tmp >> 56) | (tmp << (64 - 56)); + b11 = ror64(tmp, 56); b6 -= b11; tmp = b13 ^ b2; - b13 = (tmp >> 34) | (tmp << (64 - 34)); + b13 = ror64(tmp, 34); b2 -= b13; tmp = b9 ^ b0; - b9 = (tmp >> 16) | (tmp << (64 - 16)); + b9 = ror64(tmp, 16); b0 -= b9; tmp = b15 ^ b14; - b15 = (tmp >> 30) | (tmp << (64 - 30)); + b15 = ror64(tmp, 30); b14 -= b15 + k12 + t1; b15 -= k13 + 15; tmp = b13 ^ b12; - b13 = (tmp >> 44) | (tmp << (64 - 44)); + b13 = ror64(tmp, 44); b12 -= b13 + k10; b13 -= k11 + t0; tmp = b11 ^ b10; - b11 = (tmp >> 47) | (tmp << (64 - 47)); + b11 = ror64(tmp, 47); b10 -= b11 + k8; b11 -= k9; tmp = b9 ^ b8; - b9 = (tmp >> 12) | (tmp << (64 - 12)); + b9 = ror64(tmp, 12); b8 -= b9 + k6; b9 -= k7; tmp = b7 ^ b6; - b7 = (tmp >> 31) | (tmp << (64 - 31)); + b7 = ror64(tmp, 31); b6 -= b7 + k4; b7 -= k5; tmp = b5 ^ b4; - b5 = (tmp >> 37) | (tmp << (64 - 37)); + b5 = ror64(tmp, 37); b4 -= b5 + k2; b5 -= k3; tmp = b3 ^ b2; - b3 = (tmp >> 9) | (tmp << (64 - 9)); + b3 = ror64(tmp, 9); b2 -= b3 + k0; b3 -= k1; tmp = b1 ^ b0; - b1 = (tmp >> 41) | (tmp << (64 - 41)); + b1 = ror64(tmp, 41); b0 -= b1 + k15; b1 -= k16; tmp = b7 ^ b12; - b7 = (tmp >> 25) | (tmp << (64 - 25)); + b7 = ror64(tmp, 25); b12 -= b7; tmp = b3 ^ b10; - b3 = (tmp >> 16) | (tmp << (64 - 16)); + b3 = ror64(tmp, 16); b10 -= b3; tmp = b5 ^ b8; - b5 = (tmp >> 28) | (tmp << (64 - 28)); + b5 = ror64(tmp, 28); b8 -= b5; tmp = b1 ^ b14; - b1 = (tmp >> 47) | (tmp << (64 - 47)); + b1 = ror64(tmp, 47); b14 -= b1; tmp = b9 ^ b4; - b9 = (tmp >> 41) | (tmp << (64 - 41)); + b9 = ror64(tmp, 41); b4 -= b9; tmp = b13 ^ b6; - b13 = (tmp >> 48) | (tmp << (64 - 48)); + b13 = ror64(tmp, 48); b6 -= b13; tmp = b11 ^ b2; - b11 = (tmp >> 20) | (tmp << (64 - 20)); + b11 = ror64(tmp, 20); b2 -= b11; tmp = b15 ^ b0; - b15 = (tmp >> 5) | (tmp << (64 - 5)); + b15 = ror64(tmp, 5); b0 -= b15; tmp = b9 ^ b10; - b9 = (tmp >> 17) | (tmp << (64 - 17)); + b9 = ror64(tmp, 17); b10 -= b9; tmp = b11 ^ b8; - b11 = (tmp >> 59) | (tmp << (64 - 59)); + b11 = ror64(tmp, 59); b8 -= b11; tmp = b13 ^ b14; - b13 = (tmp >> 41) | (tmp << (64 - 41)); + b13 = ror64(tmp, 41); b14 -= b13; tmp = b15 ^ b12; - b15 = (tmp >> 34) | (tmp << (64 - 34)); + b15 = ror64(tmp, 34); b12 -= b15; tmp = b1 ^ b6; - b1 = (tmp >> 13) | (tmp << (64 - 13)); + b1 = ror64(tmp, 13); b6 -= b1; tmp = b3 ^ b4; - b3 = (tmp >> 51) | (tmp << (64 - 51)); + b3 = ror64(tmp, 51); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 4) | (tmp << (64 - 4)); + b5 = ror64(tmp, 4); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 33) | (tmp << (64 - 33)); + b7 = ror64(tmp, 33); b0 -= b7; tmp = b1 ^ b8; - b1 = (tmp >> 52) | (tmp << (64 - 52)); + b1 = ror64(tmp, 52); b8 -= b1; tmp = b5 ^ b14; - b5 = (tmp >> 23) | (tmp << (64 - 23)); + b5 = ror64(tmp, 23); b14 -= b5; tmp = b3 ^ b12; - b3 = (tmp >> 18) | (tmp << (64 - 18)); + b3 = ror64(tmp, 18); b12 -= b3; tmp = b7 ^ b10; - b7 = (tmp >> 49) | (tmp << (64 - 49)); + b7 = ror64(tmp, 49); b10 -= b7; tmp = b15 ^ b4; - b15 = (tmp >> 55) | (tmp << (64 - 55)); + b15 = ror64(tmp, 55); b4 -= b15; tmp = b11 ^ b6; - b11 = (tmp >> 10) | (tmp << (64 - 10)); + b11 = ror64(tmp, 10); b6 -= b11; tmp = b13 ^ b2; - b13 = (tmp >> 19) | (tmp << (64 - 19)); + b13 = ror64(tmp, 19); b2 -= b13; tmp = b9 ^ b0; - b9 = (tmp >> 38) | (tmp << (64 - 38)); + b9 = ror64(tmp, 38); b0 -= b9; tmp = b15 ^ b14; - b15 = (tmp >> 37) | (tmp << (64 - 37)); + b15 = ror64(tmp, 37); b14 -= b15 + k11 + t0; b15 -= k12 + 14; tmp = b13 ^ b12; - b13 = (tmp >> 22) | (tmp << (64 - 22)); + b13 = ror64(tmp, 22); b12 -= b13 + k9; b13 -= k10 + t2; tmp = b11 ^ b10; - b11 = (tmp >> 17) | (tmp << (64 - 17)); + b11 = ror64(tmp, 17); b10 -= b11 + k7; b11 -= k8; tmp = b9 ^ b8; - b9 = (tmp >> 8) | (tmp << (64 - 8)); + b9 = ror64(tmp, 8); b8 -= b9 + k5; b9 -= k6; tmp = b7 ^ b6; - b7 = (tmp >> 47) | (tmp << (64 - 47)); + b7 = ror64(tmp, 47); b6 -= b7 + k3; b7 -= k4; tmp = b5 ^ b4; - b5 = (tmp >> 8) | (tmp << (64 - 8)); + b5 = ror64(tmp, 8); b4 -= b5 + k1; b5 -= k2; tmp = b3 ^ b2; - b3 = (tmp >> 13) | (tmp << (64 - 13)); + b3 = ror64(tmp, 13); b2 -= b3 + k16; b3 -= k0; tmp = b1 ^ b0; - b1 = (tmp >> 24) | (tmp << (64 - 24)); + b1 = ror64(tmp, 24); b0 -= b1 + k14; b1 -= k15; tmp = b7 ^ b12; - b7 = (tmp >> 20) | (tmp << (64 - 20)); + b7 = ror64(tmp, 20); b12 -= b7; tmp = b3 ^ b10; - b3 = (tmp >> 37) | (tmp << (64 - 37)); + b3 = ror64(tmp, 37); b10 -= b3; tmp = b5 ^ b8; - b5 = (tmp >> 31) | (tmp << (64 - 31)); + b5 = ror64(tmp, 31); b8 -= b5; tmp = b1 ^ b14; - b1 = (tmp >> 23) | (tmp << (64 - 23)); + b1 = ror64(tmp, 23); b14 -= b1; tmp = b9 ^ b4; - b9 = (tmp >> 52) | (tmp << (64 - 52)); + b9 = ror64(tmp, 52); b4 -= b9; tmp = b13 ^ b6; - b13 = (tmp >> 35) | (tmp << (64 - 35)); + b13 = ror64(tmp, 35); b6 -= b13; tmp = b11 ^ b2; - b11 = (tmp >> 48) | (tmp << (64 - 48)); + b11 = ror64(tmp, 48); b2 -= b11; tmp = b15 ^ b0; - b15 = (tmp >> 9) | (tmp << (64 - 9)); + b15 = ror64(tmp, 9); b0 -= b15; tmp = b9 ^ b10; - b9 = (tmp >> 25) | (tmp << (64 - 25)); + b9 = ror64(tmp, 25); b10 -= b9; tmp = b11 ^ b8; - b11 = (tmp >> 44) | (tmp << (64 - 44)); + b11 = ror64(tmp, 44); b8 -= b11; tmp = b13 ^ b14; - b13 = (tmp >> 42) | (tmp << (64 - 42)); + b13 = ror64(tmp, 42); b14 -= b13; tmp = b15 ^ b12; - b15 = (tmp >> 19) | (tmp << (64 - 19)); + b15 = ror64(tmp, 19); b12 -= b15; tmp = b1 ^ b6; - b1 = (tmp >> 46) | (tmp << (64 - 46)); + b1 = ror64(tmp, 46); b6 -= b1; tmp = b3 ^ b4; - b3 = (tmp >> 47) | (tmp << (64 - 47)); + b3 = ror64(tmp, 47); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 44) | (tmp << (64 - 44)); + b5 = ror64(tmp, 44); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 31) | (tmp << (64 - 31)); + b7 = ror64(tmp, 31); b0 -= b7; tmp = b1 ^ b8; - b1 = (tmp >> 41) | (tmp << (64 - 41)); + b1 = ror64(tmp, 41); b8 -= b1; tmp = b5 ^ b14; - b5 = (tmp >> 42) | (tmp << (64 - 42)); + b5 = ror64(tmp, 42); b14 -= b5; tmp = b3 ^ b12; - b3 = (tmp >> 53) | (tmp << (64 - 53)); + b3 = ror64(tmp, 53); b12 -= b3; tmp = b7 ^ b10; - b7 = (tmp >> 4) | (tmp << (64 - 4)); + b7 = ror64(tmp, 4); b10 -= b7; tmp = b15 ^ b4; - b15 = (tmp >> 51) | (tmp << (64 - 51)); + b15 = ror64(tmp, 51); b4 -= b15; tmp = b11 ^ b6; - b11 = (tmp >> 56) | (tmp << (64 - 56)); + b11 = ror64(tmp, 56); b6 -= b11; tmp = b13 ^ b2; - b13 = (tmp >> 34) | (tmp << (64 - 34)); + b13 = ror64(tmp, 34); b2 -= b13; tmp = b9 ^ b0; - b9 = (tmp >> 16) | (tmp << (64 - 16)); + b9 = ror64(tmp, 16); b0 -= b9; tmp = b15 ^ b14; - b15 = (tmp >> 30) | (tmp << (64 - 30)); + b15 = ror64(tmp, 30); b14 -= b15 + k10 + t2; b15 -= k11 + 13; tmp = b13 ^ b12; - b13 = (tmp >> 44) | (tmp << (64 - 44)); + b13 = ror64(tmp, 44); b12 -= b13 + k8; b13 -= k9 + t1; tmp = b11 ^ b10; - b11 = (tmp >> 47) | (tmp << (64 - 47)); + b11 = ror64(tmp, 47); b10 -= b11 + k6; b11 -= k7; tmp = b9 ^ b8; - b9 = (tmp >> 12) | (tmp << (64 - 12)); + b9 = ror64(tmp, 12); b8 -= b9 + k4; b9 -= k5; tmp = b7 ^ b6; - b7 = (tmp >> 31) | (tmp << (64 - 31)); + b7 = ror64(tmp, 31); b6 -= b7 + k2; b7 -= k3; tmp = b5 ^ b4; - b5 = (tmp >> 37) | (tmp << (64 - 37)); + b5 = ror64(tmp, 37); b4 -= b5 + k0; b5 -= k1; tmp = b3 ^ b2; - b3 = (tmp >> 9) | (tmp << (64 - 9)); + b3 = ror64(tmp, 9); b2 -= b3 + k15; b3 -= k16; tmp = b1 ^ b0; - b1 = (tmp >> 41) | (tmp << (64 - 41)); + b1 = ror64(tmp, 41); b0 -= b1 + k13; b1 -= k14; tmp = b7 ^ b12; - b7 = (tmp >> 25) | (tmp << (64 - 25)); + b7 = ror64(tmp, 25); b12 -= b7; tmp = b3 ^ b10; - b3 = (tmp >> 16) | (tmp << (64 - 16)); + b3 = ror64(tmp, 16); b10 -= b3; tmp = b5 ^ b8; - b5 = (tmp >> 28) | (tmp << (64 - 28)); + b5 = ror64(tmp, 28); b8 -= b5; tmp = b1 ^ b14; - b1 = (tmp >> 47) | (tmp << (64 - 47)); + b1 = ror64(tmp, 47); b14 -= b1; tmp = b9 ^ b4; - b9 = (tmp >> 41) | (tmp << (64 - 41)); + b9 = ror64(tmp, 41); b4 -= b9; tmp = b13 ^ b6; - b13 = (tmp >> 48) | (tmp << (64 - 48)); + b13 = ror64(tmp, 48); b6 -= b13; tmp = b11 ^ b2; - b11 = (tmp >> 20) | (tmp << (64 - 20)); + b11 = ror64(tmp, 20); b2 -= b11; tmp = b15 ^ b0; - b15 = (tmp >> 5) | (tmp << (64 - 5)); + b15 = ror64(tmp, 5); b0 -= b15; tmp = b9 ^ b10; - b9 = (tmp >> 17) | (tmp << (64 - 17)); + b9 = ror64(tmp, 17); b10 -= b9; tmp = b11 ^ b8; - b11 = (tmp >> 59) | (tmp << (64 - 59)); + b11 = ror64(tmp, 59); b8 -= b11; tmp = b13 ^ b14; - b13 = (tmp >> 41) | (tmp << (64 - 41)); + b13 = ror64(tmp, 41); b14 -= b13; tmp = b15 ^ b12; - b15 = (tmp >> 34) | (tmp << (64 - 34)); + b15 = ror64(tmp, 34); b12 -= b15; tmp = b1 ^ b6; - b1 = (tmp >> 13) | (tmp << (64 - 13)); + b1 = ror64(tmp, 13); b6 -= b1; tmp = b3 ^ b4; - b3 = (tmp >> 51) | (tmp << (64 - 51)); + b3 = ror64(tmp, 51); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 4) | (tmp << (64 - 4)); + b5 = ror64(tmp, 4); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 33) | (tmp << (64 - 33)); + b7 = ror64(tmp, 33); b0 -= b7; tmp = b1 ^ b8; - b1 = (tmp >> 52) | (tmp << (64 - 52)); + b1 = ror64(tmp, 52); b8 -= b1; tmp = b5 ^ b14; - b5 = (tmp >> 23) | (tmp << (64 - 23)); + b5 = ror64(tmp, 23); b14 -= b5; tmp = b3 ^ b12; - b3 = (tmp >> 18) | (tmp << (64 - 18)); + b3 = ror64(tmp, 18); b12 -= b3; tmp = b7 ^ b10; - b7 = (tmp >> 49) | (tmp << (64 - 49)); + b7 = ror64(tmp, 49); b10 -= b7; tmp = b15 ^ b4; - b15 = (tmp >> 55) | (tmp << (64 - 55)); + b15 = ror64(tmp, 55); b4 -= b15; tmp = b11 ^ b6; - b11 = (tmp >> 10) | (tmp << (64 - 10)); + b11 = ror64(tmp, 10); b6 -= b11; tmp = b13 ^ b2; - b13 = (tmp >> 19) | (tmp << (64 - 19)); + b13 = ror64(tmp, 19); b2 -= b13; tmp = b9 ^ b0; - b9 = (tmp >> 38) | (tmp << (64 - 38)); + b9 = ror64(tmp, 38); b0 -= b9; tmp = b15 ^ b14; - b15 = (tmp >> 37) | (tmp << (64 - 37)); + b15 = ror64(tmp, 37); b14 -= b15 + k9 + t1; b15 -= k10 + 12; tmp = b13 ^ b12; - b13 = (tmp >> 22) | (tmp << (64 - 22)); + b13 = ror64(tmp, 22); b12 -= b13 + k7; b13 -= k8 + t0; tmp = b11 ^ b10; - b11 = (tmp >> 17) | (tmp << (64 - 17)); + b11 = ror64(tmp, 17); b10 -= b11 + k5; b11 -= k6; tmp = b9 ^ b8; - b9 = (tmp >> 8) | (tmp << (64 - 8)); + b9 = ror64(tmp, 8); b8 -= b9 + k3; b9 -= k4; tmp = b7 ^ b6; - b7 = (tmp >> 47) | (tmp << (64 - 47)); + b7 = ror64(tmp, 47); b6 -= b7 + k1; b7 -= k2; tmp = b5 ^ b4; - b5 = (tmp >> 8) | (tmp << (64 - 8)); + b5 = ror64(tmp, 8); b4 -= b5 + k16; b5 -= k0; tmp = b3 ^ b2; - b3 = (tmp >> 13) | (tmp << (64 - 13)); + b3 = ror64(tmp, 13); b2 -= b3 + k14; b3 -= k15; tmp = b1 ^ b0; - b1 = (tmp >> 24) | (tmp << (64 - 24)); + b1 = ror64(tmp, 24); b0 -= b1 + k12; b1 -= k13; tmp = b7 ^ b12; - b7 = (tmp >> 20) | (tmp << (64 - 20)); + b7 = ror64(tmp, 20); b12 -= b7; tmp = b3 ^ b10; - b3 = (tmp >> 37) | (tmp << (64 - 37)); + b3 = ror64(tmp, 37); b10 -= b3; tmp = b5 ^ b8; - b5 = (tmp >> 31) | (tmp << (64 - 31)); + b5 = ror64(tmp, 31); b8 -= b5; tmp = b1 ^ b14; - b1 = (tmp >> 23) | (tmp << (64 - 23)); + b1 = ror64(tmp, 23); b14 -= b1; tmp = b9 ^ b4; - b9 = (tmp >> 52) | (tmp << (64 - 52)); + b9 = ror64(tmp, 52); b4 -= b9; tmp = b13 ^ b6; - b13 = (tmp >> 35) | (tmp << (64 - 35)); + b13 = ror64(tmp, 35); b6 -= b13; tmp = b11 ^ b2; - b11 = (tmp >> 48) | (tmp << (64 - 48)); + b11 = ror64(tmp, 48); b2 -= b11; tmp = b15 ^ b0; - b15 = (tmp >> 9) | (tmp << (64 - 9)); + b15 = ror64(tmp, 9); b0 -= b15; tmp = b9 ^ b10; - b9 = (tmp >> 25) | (tmp << (64 - 25)); + b9 = ror64(tmp, 25); b10 -= b9; tmp = b11 ^ b8; - b11 = (tmp >> 44) | (tmp << (64 - 44)); + b11 = ror64(tmp, 44); b8 -= b11; tmp = b13 ^ b14; - b13 = (tmp >> 42) | (tmp << (64 - 42)); + b13 = ror64(tmp, 42); b14 -= b13; tmp = b15 ^ b12; - b15 = (tmp >> 19) | (tmp << (64 - 19)); + b15 = ror64(tmp, 19); b12 -= b15; tmp = b1 ^ b6; - b1 = (tmp >> 46) | (tmp << (64 - 46)); + b1 = ror64(tmp, 46); b6 -= b1; tmp = b3 ^ b4; - b3 = (tmp >> 47) | (tmp << (64 - 47)); + b3 = ror64(tmp, 47); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 44) | (tmp << (64 - 44)); + b5 = ror64(tmp, 44); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 31) | (tmp << (64 - 31)); + b7 = ror64(tmp, 31); b0 -= b7; tmp = b1 ^ b8; - b1 = (tmp >> 41) | (tmp << (64 - 41)); + b1 = ror64(tmp, 41); b8 -= b1; tmp = b5 ^ b14; - b5 = (tmp >> 42) | (tmp << (64 - 42)); + b5 = ror64(tmp, 42); b14 -= b5; tmp = b3 ^ b12; - b3 = (tmp >> 53) | (tmp << (64 - 53)); + b3 = ror64(tmp, 53); b12 -= b3; tmp = b7 ^ b10; - b7 = (tmp >> 4) | (tmp << (64 - 4)); + b7 = ror64(tmp, 4); b10 -= b7; tmp = b15 ^ b4; - b15 = (tmp >> 51) | (tmp << (64 - 51)); + b15 = ror64(tmp, 51); b4 -= b15; tmp = b11 ^ b6; - b11 = (tmp >> 56) | (tmp << (64 - 56)); + b11 = ror64(tmp, 56); b6 -= b11; tmp = b13 ^ b2; - b13 = (tmp >> 34) | (tmp << (64 - 34)); + b13 = ror64(tmp, 34); b2 -= b13; tmp = b9 ^ b0; - b9 = (tmp >> 16) | (tmp << (64 - 16)); + b9 = ror64(tmp, 16); b0 -= b9; tmp = b15 ^ b14; - b15 = (tmp >> 30) | (tmp << (64 - 30)); + b15 = ror64(tmp, 30); b14 -= b15 + k8 + t0; b15 -= k9 + 11; tmp = b13 ^ b12; - b13 = (tmp >> 44) | (tmp << (64 - 44)); + b13 = ror64(tmp, 44); b12 -= b13 + k6; b13 -= k7 + t2; tmp = b11 ^ b10; - b11 = (tmp >> 47) | (tmp << (64 - 47)); + b11 = ror64(tmp, 47); b10 -= b11 + k4; b11 -= k5; tmp = b9 ^ b8; - b9 = (tmp >> 12) | (tmp << (64 - 12)); + b9 = ror64(tmp, 12); b8 -= b9 + k2; b9 -= k3; tmp = b7 ^ b6; - b7 = (tmp >> 31) | (tmp << (64 - 31)); + b7 = ror64(tmp, 31); b6 -= b7 + k0; b7 -= k1; tmp = b5 ^ b4; - b5 = (tmp >> 37) | (tmp << (64 - 37)); + b5 = ror64(tmp, 37); b4 -= b5 + k15; b5 -= k16; tmp = b3 ^ b2; - b3 = (tmp >> 9) | (tmp << (64 - 9)); + b3 = ror64(tmp, 9); b2 -= b3 + k13; b3 -= k14; tmp = b1 ^ b0; - b1 = (tmp >> 41) | (tmp << (64 - 41)); + b1 = ror64(tmp, 41); b0 -= b1 + k11; b1 -= k12; tmp = b7 ^ b12; - b7 = (tmp >> 25) | (tmp << (64 - 25)); + b7 = ror64(tmp, 25); b12 -= b7; tmp = b3 ^ b10; - b3 = (tmp >> 16) | (tmp << (64 - 16)); + b3 = ror64(tmp, 16); b10 -= b3; tmp = b5 ^ b8; - b5 = (tmp >> 28) | (tmp << (64 - 28)); + b5 = ror64(tmp, 28); b8 -= b5; tmp = b1 ^ b14; - b1 = (tmp >> 47) | (tmp << (64 - 47)); + b1 = ror64(tmp, 47); b14 -= b1; tmp = b9 ^ b4; - b9 = (tmp >> 41) | (tmp << (64 - 41)); + b9 = ror64(tmp, 41); b4 -= b9; tmp = b13 ^ b6; - b13 = (tmp >> 48) | (tmp << (64 - 48)); + b13 = ror64(tmp, 48); b6 -= b13; tmp = b11 ^ b2; - b11 = (tmp >> 20) | (tmp << (64 - 20)); + b11 = ror64(tmp, 20); b2 -= b11; tmp = b15 ^ b0; - b15 = (tmp >> 5) | (tmp << (64 - 5)); + b15 = ror64(tmp, 5); b0 -= b15; tmp = b9 ^ b10; - b9 = (tmp >> 17) | (tmp << (64 - 17)); + b9 = ror64(tmp, 17); b10 -= b9; tmp = b11 ^ b8; - b11 = (tmp >> 59) | (tmp << (64 - 59)); + b11 = ror64(tmp, 59); b8 -= b11; tmp = b13 ^ b14; - b13 = (tmp >> 41) | (tmp << (64 - 41)); + b13 = ror64(tmp, 41); b14 -= b13; tmp = b15 ^ b12; - b15 = (tmp >> 34) | (tmp << (64 - 34)); + b15 = ror64(tmp, 34); b12 -= b15; tmp = b1 ^ b6; - b1 = (tmp >> 13) | (tmp << (64 - 13)); + b1 = ror64(tmp, 13); b6 -= b1; tmp = b3 ^ b4; - b3 = (tmp >> 51) | (tmp << (64 - 51)); + b3 = ror64(tmp, 51); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 4) | (tmp << (64 - 4)); + b5 = ror64(tmp, 4); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 33) | (tmp << (64 - 33)); + b7 = ror64(tmp, 33); b0 -= b7; tmp = b1 ^ b8; - b1 = (tmp >> 52) | (tmp << (64 - 52)); + b1 = ror64(tmp, 52); b8 -= b1; tmp = b5 ^ b14; - b5 = (tmp >> 23) | (tmp << (64 - 23)); + b5 = ror64(tmp, 23); b14 -= b5; tmp = b3 ^ b12; - b3 = (tmp >> 18) | (tmp << (64 - 18)); + b3 = ror64(tmp, 18); b12 -= b3; tmp = b7 ^ b10; - b7 = (tmp >> 49) | (tmp << (64 - 49)); + b7 = ror64(tmp, 49); b10 -= b7; tmp = b15 ^ b4; - b15 = (tmp >> 55) | (tmp << (64 - 55)); + b15 = ror64(tmp, 55); b4 -= b15; tmp = b11 ^ b6; - b11 = (tmp >> 10) | (tmp << (64 - 10)); + b11 = ror64(tmp, 10); b6 -= b11; tmp = b13 ^ b2; - b13 = (tmp >> 19) | (tmp << (64 - 19)); + b13 = ror64(tmp, 19); b2 -= b13; tmp = b9 ^ b0; - b9 = (tmp >> 38) | (tmp << (64 - 38)); + b9 = ror64(tmp, 38); b0 -= b9; tmp = b15 ^ b14; - b15 = (tmp >> 37) | (tmp << (64 - 37)); + b15 = ror64(tmp, 37); b14 -= b15 + k7 + t2; b15 -= k8 + 10; tmp = b13 ^ b12; - b13 = (tmp >> 22) | (tmp << (64 - 22)); + b13 = ror64(tmp, 22); b12 -= b13 + k5; b13 -= k6 + t1; tmp = b11 ^ b10; - b11 = (tmp >> 17) | (tmp << (64 - 17)); + b11 = ror64(tmp, 17); b10 -= b11 + k3; b11 -= k4; tmp = b9 ^ b8; - b9 = (tmp >> 8) | (tmp << (64 - 8)); + b9 = ror64(tmp, 8); b8 -= b9 + k1; b9 -= k2; tmp = b7 ^ b6; - b7 = (tmp >> 47) | (tmp << (64 - 47)); + b7 = ror64(tmp, 47); b6 -= b7 + k16; b7 -= k0; tmp = b5 ^ b4; - b5 = (tmp >> 8) | (tmp << (64 - 8)); + b5 = ror64(tmp, 8); b4 -= b5 + k14; b5 -= k15; tmp = b3 ^ b2; - b3 = (tmp >> 13) | (tmp << (64 - 13)); + b3 = ror64(tmp, 13); b2 -= b3 + k12; b3 -= k13; tmp = b1 ^ b0; - b1 = (tmp >> 24) | (tmp << (64 - 24)); + b1 = ror64(tmp, 24); b0 -= b1 + k10; b1 -= k11; tmp = b7 ^ b12; - b7 = (tmp >> 20) | (tmp << (64 - 20)); + b7 = ror64(tmp, 20); b12 -= b7; tmp = b3 ^ b10; - b3 = (tmp >> 37) | (tmp << (64 - 37)); + b3 = ror64(tmp, 37); b10 -= b3; tmp = b5 ^ b8; - b5 = (tmp >> 31) | (tmp << (64 - 31)); + b5 = ror64(tmp, 31); b8 -= b5; tmp = b1 ^ b14; - b1 = (tmp >> 23) | (tmp << (64 - 23)); + b1 = ror64(tmp, 23); b14 -= b1; tmp = b9 ^ b4; - b9 = (tmp >> 52) | (tmp << (64 - 52)); + b9 = ror64(tmp, 52); b4 -= b9; tmp = b13 ^ b6; - b13 = (tmp >> 35) | (tmp << (64 - 35)); + b13 = ror64(tmp, 35); b6 -= b13; tmp = b11 ^ b2; - b11 = (tmp >> 48) | (tmp << (64 - 48)); + b11 = ror64(tmp, 48); b2 -= b11; tmp = b15 ^ b0; - b15 = (tmp >> 9) | (tmp << (64 - 9)); + b15 = ror64(tmp, 9); b0 -= b15; tmp = b9 ^ b10; - b9 = (tmp >> 25) | (tmp << (64 - 25)); + b9 = ror64(tmp, 25); b10 -= b9; tmp = b11 ^ b8; - b11 = (tmp >> 44) | (tmp << (64 - 44)); + b11 = ror64(tmp, 44); b8 -= b11; tmp = b13 ^ b14; - b13 = (tmp >> 42) | (tmp << (64 - 42)); + b13 = ror64(tmp, 42); b14 -= b13; tmp = b15 ^ b12; - b15 = (tmp >> 19) | (tmp << (64 - 19)); + b15 = ror64(tmp, 19); b12 -= b15; tmp = b1 ^ b6; - b1 = (tmp >> 46) | (tmp << (64 - 46)); + b1 = ror64(tmp, 46); b6 -= b1; tmp = b3 ^ b4; - b3 = (tmp >> 47) | (tmp << (64 - 47)); + b3 = ror64(tmp, 47); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 44) | (tmp << (64 - 44)); + b5 = ror64(tmp, 44); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 31) | (tmp << (64 - 31)); + b7 = ror64(tmp, 31); b0 -= b7; tmp = b1 ^ b8; - b1 = (tmp >> 41) | (tmp << (64 - 41)); + b1 = ror64(tmp, 41); b8 -= b1; tmp = b5 ^ b14; - b5 = (tmp >> 42) | (tmp << (64 - 42)); + b5 = ror64(tmp, 42); b14 -= b5; tmp = b3 ^ b12; - b3 = (tmp >> 53) | (tmp << (64 - 53)); + b3 = ror64(tmp, 53); b12 -= b3; tmp = b7 ^ b10; - b7 = (tmp >> 4) | (tmp << (64 - 4)); + b7 = ror64(tmp, 4); b10 -= b7; tmp = b15 ^ b4; - b15 = (tmp >> 51) | (tmp << (64 - 51)); + b15 = ror64(tmp, 51); b4 -= b15; tmp = b11 ^ b6; - b11 = (tmp >> 56) | (tmp << (64 - 56)); + b11 = ror64(tmp, 56); b6 -= b11; tmp = b13 ^ b2; - b13 = (tmp >> 34) | (tmp << (64 - 34)); + b13 = ror64(tmp, 34); b2 -= b13; tmp = b9 ^ b0; - b9 = (tmp >> 16) | (tmp << (64 - 16)); + b9 = ror64(tmp, 16); b0 -= b9; tmp = b15 ^ b14; - b15 = (tmp >> 30) | (tmp << (64 - 30)); + b15 = ror64(tmp, 30); b14 -= b15 + k6 + t1; b15 -= k7 + 9; tmp = b13 ^ b12; - b13 = (tmp >> 44) | (tmp << (64 - 44)); + b13 = ror64(tmp, 44); b12 -= b13 + k4; b13 -= k5 + t0; tmp = b11 ^ b10; - b11 = (tmp >> 47) | (tmp << (64 - 47)); + b11 = ror64(tmp, 47); b10 -= b11 + k2; b11 -= k3; tmp = b9 ^ b8; - b9 = (tmp >> 12) | (tmp << (64 - 12)); + b9 = ror64(tmp, 12); b8 -= b9 + k0; b9 -= k1; tmp = b7 ^ b6; - b7 = (tmp >> 31) | (tmp << (64 - 31)); + b7 = ror64(tmp, 31); b6 -= b7 + k15; b7 -= k16; tmp = b5 ^ b4; - b5 = (tmp >> 37) | (tmp << (64 - 37)); + b5 = ror64(tmp, 37); b4 -= b5 + k13; b5 -= k14; tmp = b3 ^ b2; - b3 = (tmp >> 9) | (tmp << (64 - 9)); + b3 = ror64(tmp, 9); b2 -= b3 + k11; b3 -= k12; tmp = b1 ^ b0; - b1 = (tmp >> 41) | (tmp << (64 - 41)); + b1 = ror64(tmp, 41); b0 -= b1 + k9; b1 -= k10; tmp = b7 ^ b12; - b7 = (tmp >> 25) | (tmp << (64 - 25)); + b7 = ror64(tmp, 25); b12 -= b7; tmp = b3 ^ b10; - b3 = (tmp >> 16) | (tmp << (64 - 16)); + b3 = ror64(tmp, 16); b10 -= b3; tmp = b5 ^ b8; - b5 = (tmp >> 28) | (tmp << (64 - 28)); + b5 = ror64(tmp, 28); b8 -= b5; tmp = b1 ^ b14; - b1 = (tmp >> 47) | (tmp << (64 - 47)); + b1 = ror64(tmp, 47); b14 -= b1; tmp = b9 ^ b4; - b9 = (tmp >> 41) | (tmp << (64 - 41)); + b9 = ror64(tmp, 41); b4 -= b9; tmp = b13 ^ b6; - b13 = (tmp >> 48) | (tmp << (64 - 48)); + b13 = ror64(tmp, 48); b6 -= b13; tmp = b11 ^ b2; - b11 = (tmp >> 20) | (tmp << (64 - 20)); + b11 = ror64(tmp, 20); b2 -= b11; tmp = b15 ^ b0; - b15 = (tmp >> 5) | (tmp << (64 - 5)); + b15 = ror64(tmp, 5); b0 -= b15; tmp = b9 ^ b10; - b9 = (tmp >> 17) | (tmp << (64 - 17)); + b9 = ror64(tmp, 17); b10 -= b9; tmp = b11 ^ b8; - b11 = (tmp >> 59) | (tmp << (64 - 59)); + b11 = ror64(tmp, 59); b8 -= b11; tmp = b13 ^ b14; - b13 = (tmp >> 41) | (tmp << (64 - 41)); + b13 = ror64(tmp, 41); b14 -= b13; tmp = b15 ^ b12; - b15 = (tmp >> 34) | (tmp << (64 - 34)); + b15 = ror64(tmp, 34); b12 -= b15; tmp = b1 ^ b6; - b1 = (tmp >> 13) | (tmp << (64 - 13)); + b1 = ror64(tmp, 13); b6 -= b1; tmp = b3 ^ b4; - b3 = (tmp >> 51) | (tmp << (64 - 51)); + b3 = ror64(tmp, 51); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 4) | (tmp << (64 - 4)); + b5 = ror64(tmp, 4); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 33) | (tmp << (64 - 33)); + b7 = ror64(tmp, 33); b0 -= b7; tmp = b1 ^ b8; - b1 = (tmp >> 52) | (tmp << (64 - 52)); + b1 = ror64(tmp, 52); b8 -= b1; tmp = b5 ^ b14; - b5 = (tmp >> 23) | (tmp << (64 - 23)); + b5 = ror64(tmp, 23); b14 -= b5; tmp = b3 ^ b12; - b3 = (tmp >> 18) | (tmp << (64 - 18)); + b3 = ror64(tmp, 18); b12 -= b3; tmp = b7 ^ b10; - b7 = (tmp >> 49) | (tmp << (64 - 49)); + b7 = ror64(tmp, 49); b10 -= b7; tmp = b15 ^ b4; - b15 = (tmp >> 55) | (tmp << (64 - 55)); + b15 = ror64(tmp, 55); b4 -= b15; tmp = b11 ^ b6; - b11 = (tmp >> 10) | (tmp << (64 - 10)); + b11 = ror64(tmp, 10); b6 -= b11; tmp = b13 ^ b2; - b13 = (tmp >> 19) | (tmp << (64 - 19)); + b13 = ror64(tmp, 19); b2 -= b13; tmp = b9 ^ b0; - b9 = (tmp >> 38) | (tmp << (64 - 38)); + b9 = ror64(tmp, 38); b0 -= b9; tmp = b15 ^ b14; - b15 = (tmp >> 37) | (tmp << (64 - 37)); + b15 = ror64(tmp, 37); b14 -= b15 + k5 + t0; b15 -= k6 + 8; tmp = b13 ^ b12; - b13 = (tmp >> 22) | (tmp << (64 - 22)); + b13 = ror64(tmp, 22); b12 -= b13 + k3; b13 -= k4 + t2; tmp = b11 ^ b10; - b11 = (tmp >> 17) | (tmp << (64 - 17)); + b11 = ror64(tmp, 17); b10 -= b11 + k1; b11 -= k2; tmp = b9 ^ b8; - b9 = (tmp >> 8) | (tmp << (64 - 8)); + b9 = ror64(tmp, 8); b8 -= b9 + k16; b9 -= k0; tmp = b7 ^ b6; - b7 = (tmp >> 47) | (tmp << (64 - 47)); + b7 = ror64(tmp, 47); b6 -= b7 + k14; b7 -= k15; tmp = b5 ^ b4; - b5 = (tmp >> 8) | (tmp << (64 - 8)); + b5 = ror64(tmp, 8); b4 -= b5 + k12; b5 -= k13; tmp = b3 ^ b2; - b3 = (tmp >> 13) | (tmp << (64 - 13)); + b3 = ror64(tmp, 13); b2 -= b3 + k10; b3 -= k11; tmp = b1 ^ b0; - b1 = (tmp >> 24) | (tmp << (64 - 24)); + b1 = ror64(tmp, 24); b0 -= b1 + k8; b1 -= k9; tmp = b7 ^ b12; - b7 = (tmp >> 20) | (tmp << (64 - 20)); + b7 = ror64(tmp, 20); b12 -= b7; tmp = b3 ^ b10; - b3 = (tmp >> 37) | (tmp << (64 - 37)); + b3 = ror64(tmp, 37); b10 -= b3; tmp = b5 ^ b8; - b5 = (tmp >> 31) | (tmp << (64 - 31)); + b5 = ror64(tmp, 31); b8 -= b5; tmp = b1 ^ b14; - b1 = (tmp >> 23) | (tmp << (64 - 23)); + b1 = ror64(tmp, 23); b14 -= b1; tmp = b9 ^ b4; - b9 = (tmp >> 52) | (tmp << (64 - 52)); + b9 = ror64(tmp, 52); b4 -= b9; tmp = b13 ^ b6; - b13 = (tmp >> 35) | (tmp << (64 - 35)); + b13 = ror64(tmp, 35); b6 -= b13; tmp = b11 ^ b2; - b11 = (tmp >> 48) | (tmp << (64 - 48)); + b11 = ror64(tmp, 48); b2 -= b11; tmp = b15 ^ b0; - b15 = (tmp >> 9) | (tmp << (64 - 9)); + b15 = ror64(tmp, 9); b0 -= b15; tmp = b9 ^ b10; - b9 = (tmp >> 25) | (tmp << (64 - 25)); + b9 = ror64(tmp, 25); b10 -= b9; tmp = b11 ^ b8; - b11 = (tmp >> 44) | (tmp << (64 - 44)); + b11 = ror64(tmp, 44); b8 -= b11; tmp = b13 ^ b14; - b13 = (tmp >> 42) | (tmp << (64 - 42)); + b13 = ror64(tmp, 42); b14 -= b13; tmp = b15 ^ b12; - b15 = (tmp >> 19) | (tmp << (64 - 19)); + b15 = ror64(tmp, 19); b12 -= b15; tmp = b1 ^ b6; - b1 = (tmp >> 46) | (tmp << (64 - 46)); + b1 = ror64(tmp, 46); b6 -= b1; tmp = b3 ^ b4; - b3 = (tmp >> 47) | (tmp << (64 - 47)); + b3 = ror64(tmp, 47); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 44) | (tmp << (64 - 44)); + b5 = ror64(tmp, 44); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 31) | (tmp << (64 - 31)); + b7 = ror64(tmp, 31); b0 -= b7; tmp = b1 ^ b8; - b1 = (tmp >> 41) | (tmp << (64 - 41)); + b1 = ror64(tmp, 41); b8 -= b1; tmp = b5 ^ b14; - b5 = (tmp >> 42) | (tmp << (64 - 42)); + b5 = ror64(tmp, 42); b14 -= b5; tmp = b3 ^ b12; - b3 = (tmp >> 53) | (tmp << (64 - 53)); + b3 = ror64(tmp, 53); b12 -= b3; tmp = b7 ^ b10; - b7 = (tmp >> 4) | (tmp << (64 - 4)); + b7 = ror64(tmp, 4); b10 -= b7; tmp = b15 ^ b4; - b15 = (tmp >> 51) | (tmp << (64 - 51)); + b15 = ror64(tmp, 51); b4 -= b15; tmp = b11 ^ b6; - b11 = (tmp >> 56) | (tmp << (64 - 56)); + b11 = ror64(tmp, 56); b6 -= b11; tmp = b13 ^ b2; - b13 = (tmp >> 34) | (tmp << (64 - 34)); + b13 = ror64(tmp, 34); b2 -= b13; tmp = b9 ^ b0; - b9 = (tmp >> 16) | (tmp << (64 - 16)); + b9 = ror64(tmp, 16); b0 -= b9; tmp = b15 ^ b14; - b15 = (tmp >> 30) | (tmp << (64 - 30)); + b15 = ror64(tmp, 30); b14 -= b15 + k4 + t2; b15 -= k5 + 7; tmp = b13 ^ b12; - b13 = (tmp >> 44) | (tmp << (64 - 44)); + b13 = ror64(tmp, 44); b12 -= b13 + k2; b13 -= k3 + t1; tmp = b11 ^ b10; - b11 = (tmp >> 47) | (tmp << (64 - 47)); + b11 = ror64(tmp, 47); b10 -= b11 + k0; b11 -= k1; tmp = b9 ^ b8; - b9 = (tmp >> 12) | (tmp << (64 - 12)); + b9 = ror64(tmp, 12); b8 -= b9 + k15; b9 -= k16; tmp = b7 ^ b6; - b7 = (tmp >> 31) | (tmp << (64 - 31)); + b7 = ror64(tmp, 31); b6 -= b7 + k13; b7 -= k14; tmp = b5 ^ b4; - b5 = (tmp >> 37) | (tmp << (64 - 37)); + b5 = ror64(tmp, 37); b4 -= b5 + k11; b5 -= k12; tmp = b3 ^ b2; - b3 = (tmp >> 9) | (tmp << (64 - 9)); + b3 = ror64(tmp, 9); b2 -= b3 + k9; b3 -= k10; tmp = b1 ^ b0; - b1 = (tmp >> 41) | (tmp << (64 - 41)); + b1 = ror64(tmp, 41); b0 -= b1 + k7; b1 -= k8; tmp = b7 ^ b12; - b7 = (tmp >> 25) | (tmp << (64 - 25)); + b7 = ror64(tmp, 25); b12 -= b7; tmp = b3 ^ b10; - b3 = (tmp >> 16) | (tmp << (64 - 16)); + b3 = ror64(tmp, 16); b10 -= b3; tmp = b5 ^ b8; - b5 = (tmp >> 28) | (tmp << (64 - 28)); + b5 = ror64(tmp, 28); b8 -= b5; tmp = b1 ^ b14; - b1 = (tmp >> 47) | (tmp << (64 - 47)); + b1 = ror64(tmp, 47); b14 -= b1; tmp = b9 ^ b4; - b9 = (tmp >> 41) | (tmp << (64 - 41)); + b9 = ror64(tmp, 41); b4 -= b9; tmp = b13 ^ b6; - b13 = (tmp >> 48) | (tmp << (64 - 48)); + b13 = ror64(tmp, 48); b6 -= b13; tmp = b11 ^ b2; - b11 = (tmp >> 20) | (tmp << (64 - 20)); + b11 = ror64(tmp, 20); b2 -= b11; tmp = b15 ^ b0; - b15 = (tmp >> 5) | (tmp << (64 - 5)); + b15 = ror64(tmp, 5); b0 -= b15; tmp = b9 ^ b10; - b9 = (tmp >> 17) | (tmp << (64 - 17)); + b9 = ror64(tmp, 17); b10 -= b9; tmp = b11 ^ b8; - b11 = (tmp >> 59) | (tmp << (64 - 59)); + b11 = ror64(tmp, 59); b8 -= b11; tmp = b13 ^ b14; - b13 = (tmp >> 41) | (tmp << (64 - 41)); + b13 = ror64(tmp, 41); b14 -= b13; tmp = b15 ^ b12; - b15 = (tmp >> 34) | (tmp << (64 - 34)); + b15 = ror64(tmp, 34); b12 -= b15; tmp = b1 ^ b6; - b1 = (tmp >> 13) | (tmp << (64 - 13)); + b1 = ror64(tmp, 13); b6 -= b1; tmp = b3 ^ b4; - b3 = (tmp >> 51) | (tmp << (64 - 51)); + b3 = ror64(tmp, 51); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 4) | (tmp << (64 - 4)); + b5 = ror64(tmp, 4); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 33) | (tmp << (64 - 33)); + b7 = ror64(tmp, 33); b0 -= b7; tmp = b1 ^ b8; - b1 = (tmp >> 52) | (tmp << (64 - 52)); + b1 = ror64(tmp, 52); b8 -= b1; tmp = b5 ^ b14; - b5 = (tmp >> 23) | (tmp << (64 - 23)); + b5 = ror64(tmp, 23); b14 -= b5; tmp = b3 ^ b12; - b3 = (tmp >> 18) | (tmp << (64 - 18)); + b3 = ror64(tmp, 18); b12 -= b3; tmp = b7 ^ b10; - b7 = (tmp >> 49) | (tmp << (64 - 49)); + b7 = ror64(tmp, 49); b10 -= b7; tmp = b15 ^ b4; - b15 = (tmp >> 55) | (tmp << (64 - 55)); + b15 = ror64(tmp, 55); b4 -= b15; tmp = b11 ^ b6; - b11 = (tmp >> 10) | (tmp << (64 - 10)); + b11 = ror64(tmp, 10); b6 -= b11; tmp = b13 ^ b2; - b13 = (tmp >> 19) | (tmp << (64 - 19)); + b13 = ror64(tmp, 19); b2 -= b13; tmp = b9 ^ b0; - b9 = (tmp >> 38) | (tmp << (64 - 38)); + b9 = ror64(tmp, 38); b0 -= b9; tmp = b15 ^ b14; - b15 = (tmp >> 37) | (tmp << (64 - 37)); + b15 = ror64(tmp, 37); b14 -= b15 + k3 + t1; b15 -= k4 + 6; tmp = b13 ^ b12; - b13 = (tmp >> 22) | (tmp << (64 - 22)); + b13 = ror64(tmp, 22); b12 -= b13 + k1; b13 -= k2 + t0; tmp = b11 ^ b10; - b11 = (tmp >> 17) | (tmp << (64 - 17)); + b11 = ror64(tmp, 17); b10 -= b11 + k16; b11 -= k0; tmp = b9 ^ b8; - b9 = (tmp >> 8) | (tmp << (64 - 8)); + b9 = ror64(tmp, 8); b8 -= b9 + k14; b9 -= k15; tmp = b7 ^ b6; - b7 = (tmp >> 47) | (tmp << (64 - 47)); + b7 = ror64(tmp, 47); b6 -= b7 + k12; b7 -= k13; tmp = b5 ^ b4; - b5 = (tmp >> 8) | (tmp << (64 - 8)); + b5 = ror64(tmp, 8); b4 -= b5 + k10; b5 -= k11; tmp = b3 ^ b2; - b3 = (tmp >> 13) | (tmp << (64 - 13)); + b3 = ror64(tmp, 13); b2 -= b3 + k8; b3 -= k9; tmp = b1 ^ b0; - b1 = (tmp >> 24) | (tmp << (64 - 24)); + b1 = ror64(tmp, 24); b0 -= b1 + k6; b1 -= k7; tmp = b7 ^ b12; - b7 = (tmp >> 20) | (tmp << (64 - 20)); + b7 = ror64(tmp, 20); b12 -= b7; tmp = b3 ^ b10; - b3 = (tmp >> 37) | (tmp << (64 - 37)); + b3 = ror64(tmp, 37); b10 -= b3; tmp = b5 ^ b8; - b5 = (tmp >> 31) | (tmp << (64 - 31)); + b5 = ror64(tmp, 31); b8 -= b5; tmp = b1 ^ b14; - b1 = (tmp >> 23) | (tmp << (64 - 23)); + b1 = ror64(tmp, 23); b14 -= b1; tmp = b9 ^ b4; - b9 = (tmp >> 52) | (tmp << (64 - 52)); + b9 = ror64(tmp, 52); b4 -= b9; tmp = b13 ^ b6; - b13 = (tmp >> 35) | (tmp << (64 - 35)); + b13 = ror64(tmp, 35); b6 -= b13; tmp = b11 ^ b2; - b11 = (tmp >> 48) | (tmp << (64 - 48)); + b11 = ror64(tmp, 48); b2 -= b11; tmp = b15 ^ b0; - b15 = (tmp >> 9) | (tmp << (64 - 9)); + b15 = ror64(tmp, 9); b0 -= b15; tmp = b9 ^ b10; - b9 = (tmp >> 25) | (tmp << (64 - 25)); + b9 = ror64(tmp, 25); b10 -= b9; tmp = b11 ^ b8; - b11 = (tmp >> 44) | (tmp << (64 - 44)); + b11 = ror64(tmp, 44); b8 -= b11; tmp = b13 ^ b14; - b13 = (tmp >> 42) | (tmp << (64 - 42)); + b13 = ror64(tmp, 42); b14 -= b13; tmp = b15 ^ b12; - b15 = (tmp >> 19) | (tmp << (64 - 19)); + b15 = ror64(tmp, 19); b12 -= b15; tmp = b1 ^ b6; - b1 = (tmp >> 46) | (tmp << (64 - 46)); + b1 = ror64(tmp, 46); b6 -= b1; tmp = b3 ^ b4; - b3 = (tmp >> 47) | (tmp << (64 - 47)); + b3 = ror64(tmp, 47); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 44) | (tmp << (64 - 44)); + b5 = ror64(tmp, 44); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 31) | (tmp << (64 - 31)); + b7 = ror64(tmp, 31); b0 -= b7; tmp = b1 ^ b8; - b1 = (tmp >> 41) | (tmp << (64 - 41)); + b1 = ror64(tmp, 41); b8 -= b1; tmp = b5 ^ b14; - b5 = (tmp >> 42) | (tmp << (64 - 42)); + b5 = ror64(tmp, 42); b14 -= b5; tmp = b3 ^ b12; - b3 = (tmp >> 53) | (tmp << (64 - 53)); + b3 = ror64(tmp, 53); b12 -= b3; tmp = b7 ^ b10; - b7 = (tmp >> 4) | (tmp << (64 - 4)); + b7 = ror64(tmp, 4); b10 -= b7; tmp = b15 ^ b4; - b15 = (tmp >> 51) | (tmp << (64 - 51)); + b15 = ror64(tmp, 51); b4 -= b15; tmp = b11 ^ b6; - b11 = (tmp >> 56) | (tmp << (64 - 56)); + b11 = ror64(tmp, 56); b6 -= b11; tmp = b13 ^ b2; - b13 = (tmp >> 34) | (tmp << (64 - 34)); + b13 = ror64(tmp, 34); b2 -= b13; tmp = b9 ^ b0; - b9 = (tmp >> 16) | (tmp << (64 - 16)); + b9 = ror64(tmp, 16); b0 -= b9; tmp = b15 ^ b14; - b15 = (tmp >> 30) | (tmp << (64 - 30)); + b15 = ror64(tmp, 30); b14 -= b15 + k2 + t0; b15 -= k3 + 5; tmp = b13 ^ b12; - b13 = (tmp >> 44) | (tmp << (64 - 44)); + b13 = ror64(tmp, 44); b12 -= b13 + k0; b13 -= k1 + t2; tmp = b11 ^ b10; - b11 = (tmp >> 47) | (tmp << (64 - 47)); + b11 = ror64(tmp, 47); b10 -= b11 + k15; b11 -= k16; tmp = b9 ^ b8; - b9 = (tmp >> 12) | (tmp << (64 - 12)); + b9 = ror64(tmp, 12); b8 -= b9 + k13; b9 -= k14; tmp = b7 ^ b6; - b7 = (tmp >> 31) | (tmp << (64 - 31)); + b7 = ror64(tmp, 31); b6 -= b7 + k11; b7 -= k12; tmp = b5 ^ b4; - b5 = (tmp >> 37) | (tmp << (64 - 37)); + b5 = ror64(tmp, 37); b4 -= b5 + k9; b5 -= k10; tmp = b3 ^ b2; - b3 = (tmp >> 9) | (tmp << (64 - 9)); + b3 = ror64(tmp, 9); b2 -= b3 + k7; b3 -= k8; tmp = b1 ^ b0; - b1 = (tmp >> 41) | (tmp << (64 - 41)); + b1 = ror64(tmp, 41); b0 -= b1 + k5; b1 -= k6; tmp = b7 ^ b12; - b7 = (tmp >> 25) | (tmp << (64 - 25)); + b7 = ror64(tmp, 25); b12 -= b7; tmp = b3 ^ b10; - b3 = (tmp >> 16) | (tmp << (64 - 16)); + b3 = ror64(tmp, 16); b10 -= b3; tmp = b5 ^ b8; - b5 = (tmp >> 28) | (tmp << (64 - 28)); + b5 = ror64(tmp, 28); b8 -= b5; tmp = b1 ^ b14; - b1 = (tmp >> 47) | (tmp << (64 - 47)); + b1 = ror64(tmp, 47); b14 -= b1; tmp = b9 ^ b4; - b9 = (tmp >> 41) | (tmp << (64 - 41)); + b9 = ror64(tmp, 41); b4 -= b9; tmp = b13 ^ b6; - b13 = (tmp >> 48) | (tmp << (64 - 48)); + b13 = ror64(tmp, 48); b6 -= b13; tmp = b11 ^ b2; - b11 = (tmp >> 20) | (tmp << (64 - 20)); + b11 = ror64(tmp, 20); b2 -= b11; tmp = b15 ^ b0; - b15 = (tmp >> 5) | (tmp << (64 - 5)); + b15 = ror64(tmp, 5); b0 -= b15; tmp = b9 ^ b10; - b9 = (tmp >> 17) | (tmp << (64 - 17)); + b9 = ror64(tmp, 17); b10 -= b9; tmp = b11 ^ b8; - b11 = (tmp >> 59) | (tmp << (64 - 59)); + b11 = ror64(tmp, 59); b8 -= b11; tmp = b13 ^ b14; - b13 = (tmp >> 41) | (tmp << (64 - 41)); + b13 = ror64(tmp, 41); b14 -= b13; tmp = b15 ^ b12; - b15 = (tmp >> 34) | (tmp << (64 - 34)); + b15 = ror64(tmp, 34); b12 -= b15; tmp = b1 ^ b6; - b1 = (tmp >> 13) | (tmp << (64 - 13)); + b1 = ror64(tmp, 13); b6 -= b1; tmp = b3 ^ b4; - b3 = (tmp >> 51) | (tmp << (64 - 51)); + b3 = ror64(tmp, 51); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 4) | (tmp << (64 - 4)); + b5 = ror64(tmp, 4); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 33) | (tmp << (64 - 33)); + b7 = ror64(tmp, 33); b0 -= b7; tmp = b1 ^ b8; - b1 = (tmp >> 52) | (tmp << (64 - 52)); + b1 = ror64(tmp, 52); b8 -= b1; tmp = b5 ^ b14; - b5 = (tmp >> 23) | (tmp << (64 - 23)); + b5 = ror64(tmp, 23); b14 -= b5; tmp = b3 ^ b12; - b3 = (tmp >> 18) | (tmp << (64 - 18)); + b3 = ror64(tmp, 18); b12 -= b3; tmp = b7 ^ b10; - b7 = (tmp >> 49) | (tmp << (64 - 49)); + b7 = ror64(tmp, 49); b10 -= b7; tmp = b15 ^ b4; - b15 = (tmp >> 55) | (tmp << (64 - 55)); + b15 = ror64(tmp, 55); b4 -= b15; tmp = b11 ^ b6; - b11 = (tmp >> 10) | (tmp << (64 - 10)); + b11 = ror64(tmp, 10); b6 -= b11; tmp = b13 ^ b2; - b13 = (tmp >> 19) | (tmp << (64 - 19)); + b13 = ror64(tmp, 19); b2 -= b13; tmp = b9 ^ b0; - b9 = (tmp >> 38) | (tmp << (64 - 38)); + b9 = ror64(tmp, 38); b0 -= b9; tmp = b15 ^ b14; - b15 = (tmp >> 37) | (tmp << (64 - 37)); + b15 = ror64(tmp, 37); b14 -= b15 + k1 + t2; b15 -= k2 + 4; tmp = b13 ^ b12; - b13 = (tmp >> 22) | (tmp << (64 - 22)); + b13 = ror64(tmp, 22); b12 -= b13 + k16; b13 -= k0 + t1; tmp = b11 ^ b10; - b11 = (tmp >> 17) | (tmp << (64 - 17)); + b11 = ror64(tmp, 17); b10 -= b11 + k14; b11 -= k15; tmp = b9 ^ b8; - b9 = (tmp >> 8) | (tmp << (64 - 8)); + b9 = ror64(tmp, 8); b8 -= b9 + k12; b9 -= k13; tmp = b7 ^ b6; - b7 = (tmp >> 47) | (tmp << (64 - 47)); + b7 = ror64(tmp, 47); b6 -= b7 + k10; b7 -= k11; tmp = b5 ^ b4; - b5 = (tmp >> 8) | (tmp << (64 - 8)); + b5 = ror64(tmp, 8); b4 -= b5 + k8; b5 -= k9; tmp = b3 ^ b2; - b3 = (tmp >> 13) | (tmp << (64 - 13)); + b3 = ror64(tmp, 13); b2 -= b3 + k6; b3 -= k7; tmp = b1 ^ b0; - b1 = (tmp >> 24) | (tmp << (64 - 24)); + b1 = ror64(tmp, 24); b0 -= b1 + k4; b1 -= k5; tmp = b7 ^ b12; - b7 = (tmp >> 20) | (tmp << (64 - 20)); + b7 = ror64(tmp, 20); b12 -= b7; tmp = b3 ^ b10; - b3 = (tmp >> 37) | (tmp << (64 - 37)); + b3 = ror64(tmp, 37); b10 -= b3; tmp = b5 ^ b8; - b5 = (tmp >> 31) | (tmp << (64 - 31)); + b5 = ror64(tmp, 31); b8 -= b5; tmp = b1 ^ b14; - b1 = (tmp >> 23) | (tmp << (64 - 23)); + b1 = ror64(tmp, 23); b14 -= b1; tmp = b9 ^ b4; - b9 = (tmp >> 52) | (tmp << (64 - 52)); + b9 = ror64(tmp, 52); b4 -= b9; tmp = b13 ^ b6; - b13 = (tmp >> 35) | (tmp << (64 - 35)); + b13 = ror64(tmp, 35); b6 -= b13; tmp = b11 ^ b2; - b11 = (tmp >> 48) | (tmp << (64 - 48)); + b11 = ror64(tmp, 48); b2 -= b11; tmp = b15 ^ b0; - b15 = (tmp >> 9) | (tmp << (64 - 9)); + b15 = ror64(tmp, 9); b0 -= b15; tmp = b9 ^ b10; - b9 = (tmp >> 25) | (tmp << (64 - 25)); + b9 = ror64(tmp, 25); b10 -= b9; tmp = b11 ^ b8; - b11 = (tmp >> 44) | (tmp << (64 - 44)); + b11 = ror64(tmp, 44); b8 -= b11; tmp = b13 ^ b14; - b13 = (tmp >> 42) | (tmp << (64 - 42)); + b13 = ror64(tmp, 42); b14 -= b13; tmp = b15 ^ b12; - b15 = (tmp >> 19) | (tmp << (64 - 19)); + b15 = ror64(tmp, 19); b12 -= b15; tmp = b1 ^ b6; - b1 = (tmp >> 46) | (tmp << (64 - 46)); + b1 = ror64(tmp, 46); b6 -= b1; tmp = b3 ^ b4; - b3 = (tmp >> 47) | (tmp << (64 - 47)); + b3 = ror64(tmp, 47); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 44) | (tmp << (64 - 44)); + b5 = ror64(tmp, 44); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 31) | (tmp << (64 - 31)); + b7 = ror64(tmp, 31); b0 -= b7; tmp = b1 ^ b8; - b1 = (tmp >> 41) | (tmp << (64 - 41)); + b1 = ror64(tmp, 41); b8 -= b1; tmp = b5 ^ b14; - b5 = (tmp >> 42) | (tmp << (64 - 42)); + b5 = ror64(tmp, 42); b14 -= b5; tmp = b3 ^ b12; - b3 = (tmp >> 53) | (tmp << (64 - 53)); + b3 = ror64(tmp, 53); b12 -= b3; tmp = b7 ^ b10; - b7 = (tmp >> 4) | (tmp << (64 - 4)); + b7 = ror64(tmp, 4); b10 -= b7; tmp = b15 ^ b4; - b15 = (tmp >> 51) | (tmp << (64 - 51)); + b15 = ror64(tmp, 51); b4 -= b15; tmp = b11 ^ b6; - b11 = (tmp >> 56) | (tmp << (64 - 56)); + b11 = ror64(tmp, 56); b6 -= b11; tmp = b13 ^ b2; - b13 = (tmp >> 34) | (tmp << (64 - 34)); + b13 = ror64(tmp, 34); b2 -= b13; tmp = b9 ^ b0; - b9 = (tmp >> 16) | (tmp << (64 - 16)); + b9 = ror64(tmp, 16); b0 -= b9; tmp = b15 ^ b14; - b15 = (tmp >> 30) | (tmp << (64 - 30)); + b15 = ror64(tmp, 30); b14 -= b15 + k0 + t1; b15 -= k1 + 3; tmp = b13 ^ b12; - b13 = (tmp >> 44) | (tmp << (64 - 44)); + b13 = ror64(tmp, 44); b12 -= b13 + k15; b13 -= k16 + t0; tmp = b11 ^ b10; - b11 = (tmp >> 47) | (tmp << (64 - 47)); + b11 = ror64(tmp, 47); b10 -= b11 + k13; b11 -= k14; tmp = b9 ^ b8; - b9 = (tmp >> 12) | (tmp << (64 - 12)); + b9 = ror64(tmp, 12); b8 -= b9 + k11; b9 -= k12; tmp = b7 ^ b6; - b7 = (tmp >> 31) | (tmp << (64 - 31)); + b7 = ror64(tmp, 31); b6 -= b7 + k9; b7 -= k10; tmp = b5 ^ b4; - b5 = (tmp >> 37) | (tmp << (64 - 37)); + b5 = ror64(tmp, 37); b4 -= b5 + k7; b5 -= k8; tmp = b3 ^ b2; - b3 = (tmp >> 9) | (tmp << (64 - 9)); + b3 = ror64(tmp, 9); b2 -= b3 + k5; b3 -= k6; tmp = b1 ^ b0; - b1 = (tmp >> 41) | (tmp << (64 - 41)); + b1 = ror64(tmp, 41); b0 -= b1 + k3; b1 -= k4; tmp = b7 ^ b12; - b7 = (tmp >> 25) | (tmp << (64 - 25)); + b7 = ror64(tmp, 25); b12 -= b7; tmp = b3 ^ b10; - b3 = (tmp >> 16) | (tmp << (64 - 16)); + b3 = ror64(tmp, 16); b10 -= b3; tmp = b5 ^ b8; - b5 = (tmp >> 28) | (tmp << (64 - 28)); + b5 = ror64(tmp, 28); b8 -= b5; tmp = b1 ^ b14; - b1 = (tmp >> 47) | (tmp << (64 - 47)); + b1 = ror64(tmp, 47); b14 -= b1; tmp = b9 ^ b4; - b9 = (tmp >> 41) | (tmp << (64 - 41)); + b9 = ror64(tmp, 41); b4 -= b9; tmp = b13 ^ b6; - b13 = (tmp >> 48) | (tmp << (64 - 48)); + b13 = ror64(tmp, 48); b6 -= b13; tmp = b11 ^ b2; - b11 = (tmp >> 20) | (tmp << (64 - 20)); + b11 = ror64(tmp, 20); b2 -= b11; tmp = b15 ^ b0; - b15 = (tmp >> 5) | (tmp << (64 - 5)); + b15 = ror64(tmp, 5); b0 -= b15; tmp = b9 ^ b10; - b9 = (tmp >> 17) | (tmp << (64 - 17)); + b9 = ror64(tmp, 17); b10 -= b9; tmp = b11 ^ b8; - b11 = (tmp >> 59) | (tmp << (64 - 59)); + b11 = ror64(tmp, 59); b8 -= b11; tmp = b13 ^ b14; - b13 = (tmp >> 41) | (tmp << (64 - 41)); + b13 = ror64(tmp, 41); b14 -= b13; tmp = b15 ^ b12; - b15 = (tmp >> 34) | (tmp << (64 - 34)); + b15 = ror64(tmp, 34); b12 -= b15; tmp = b1 ^ b6; - b1 = (tmp >> 13) | (tmp << (64 - 13)); + b1 = ror64(tmp, 13); b6 -= b1; tmp = b3 ^ b4; - b3 = (tmp >> 51) | (tmp << (64 - 51)); + b3 = ror64(tmp, 51); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 4) | (tmp << (64 - 4)); + b5 = ror64(tmp, 4); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 33) | (tmp << (64 - 33)); + b7 = ror64(tmp, 33); b0 -= b7; tmp = b1 ^ b8; - b1 = (tmp >> 52) | (tmp << (64 - 52)); + b1 = ror64(tmp, 52); b8 -= b1; tmp = b5 ^ b14; - b5 = (tmp >> 23) | (tmp << (64 - 23)); + b5 = ror64(tmp, 23); b14 -= b5; tmp = b3 ^ b12; - b3 = (tmp >> 18) | (tmp << (64 - 18)); + b3 = ror64(tmp, 18); b12 -= b3; tmp = b7 ^ b10; - b7 = (tmp >> 49) | (tmp << (64 - 49)); + b7 = ror64(tmp, 49); b10 -= b7; tmp = b15 ^ b4; - b15 = (tmp >> 55) | (tmp << (64 - 55)); + b15 = ror64(tmp, 55); b4 -= b15; tmp = b11 ^ b6; - b11 = (tmp >> 10) | (tmp << (64 - 10)); + b11 = ror64(tmp, 10); b6 -= b11; tmp = b13 ^ b2; - b13 = (tmp >> 19) | (tmp << (64 - 19)); + b13 = ror64(tmp, 19); b2 -= b13; tmp = b9 ^ b0; - b9 = (tmp >> 38) | (tmp << (64 - 38)); + b9 = ror64(tmp, 38); b0 -= b9; tmp = b15 ^ b14; - b15 = (tmp >> 37) | (tmp << (64 - 37)); + b15 = ror64(tmp, 37); b14 -= b15 + k16 + t0; b15 -= k0 + 2; tmp = b13 ^ b12; - b13 = (tmp >> 22) | (tmp << (64 - 22)); + b13 = ror64(tmp, 22); b12 -= b13 + k14; b13 -= k15 + t2; tmp = b11 ^ b10; - b11 = (tmp >> 17) | (tmp << (64 - 17)); + b11 = ror64(tmp, 17); b10 -= b11 + k12; b11 -= k13; tmp = b9 ^ b8; - b9 = (tmp >> 8) | (tmp << (64 - 8)); + b9 = ror64(tmp, 8); b8 -= b9 + k10; b9 -= k11; tmp = b7 ^ b6; - b7 = (tmp >> 47) | (tmp << (64 - 47)); + b7 = ror64(tmp, 47); b6 -= b7 + k8; b7 -= k9; tmp = b5 ^ b4; - b5 = (tmp >> 8) | (tmp << (64 - 8)); + b5 = ror64(tmp, 8); b4 -= b5 + k6; b5 -= k7; tmp = b3 ^ b2; - b3 = (tmp >> 13) | (tmp << (64 - 13)); + b3 = ror64(tmp, 13); b2 -= b3 + k4; b3 -= k5; tmp = b1 ^ b0; - b1 = (tmp >> 24) | (tmp << (64 - 24)); + b1 = ror64(tmp, 24); b0 -= b1 + k2; b1 -= k3; tmp = b7 ^ b12; - b7 = (tmp >> 20) | (tmp << (64 - 20)); + b7 = ror64(tmp, 20); b12 -= b7; tmp = b3 ^ b10; - b3 = (tmp >> 37) | (tmp << (64 - 37)); + b3 = ror64(tmp, 37); b10 -= b3; tmp = b5 ^ b8; - b5 = (tmp >> 31) | (tmp << (64 - 31)); + b5 = ror64(tmp, 31); b8 -= b5; tmp = b1 ^ b14; - b1 = (tmp >> 23) | (tmp << (64 - 23)); + b1 = ror64(tmp, 23); b14 -= b1; tmp = b9 ^ b4; - b9 = (tmp >> 52) | (tmp << (64 - 52)); + b9 = ror64(tmp, 52); b4 -= b9; tmp = b13 ^ b6; - b13 = (tmp >> 35) | (tmp << (64 - 35)); + b13 = ror64(tmp, 35); b6 -= b13; tmp = b11 ^ b2; - b11 = (tmp >> 48) | (tmp << (64 - 48)); + b11 = ror64(tmp, 48); b2 -= b11; tmp = b15 ^ b0; - b15 = (tmp >> 9) | (tmp << (64 - 9)); + b15 = ror64(tmp, 9); b0 -= b15; tmp = b9 ^ b10; - b9 = (tmp >> 25) | (tmp << (64 - 25)); + b9 = ror64(tmp, 25); b10 -= b9; tmp = b11 ^ b8; - b11 = (tmp >> 44) | (tmp << (64 - 44)); + b11 = ror64(tmp, 44); b8 -= b11; tmp = b13 ^ b14; - b13 = (tmp >> 42) | (tmp << (64 - 42)); + b13 = ror64(tmp, 42); b14 -= b13; tmp = b15 ^ b12; - b15 = (tmp >> 19) | (tmp << (64 - 19)); + b15 = ror64(tmp, 19); b12 -= b15; tmp = b1 ^ b6; - b1 = (tmp >> 46) | (tmp << (64 - 46)); + b1 = ror64(tmp, 46); b6 -= b1; tmp = b3 ^ b4; - b3 = (tmp >> 47) | (tmp << (64 - 47)); + b3 = ror64(tmp, 47); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 44) | (tmp << (64 - 44)); + b5 = ror64(tmp, 44); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 31) | (tmp << (64 - 31)); + b7 = ror64(tmp, 31); b0 -= b7; tmp = b1 ^ b8; - b1 = (tmp >> 41) | (tmp << (64 - 41)); + b1 = ror64(tmp, 41); b8 -= b1; tmp = b5 ^ b14; - b5 = (tmp >> 42) | (tmp << (64 - 42)); + b5 = ror64(tmp, 42); b14 -= b5; tmp = b3 ^ b12; - b3 = (tmp >> 53) | (tmp << (64 - 53)); + b3 = ror64(tmp, 53); b12 -= b3; tmp = b7 ^ b10; - b7 = (tmp >> 4) | (tmp << (64 - 4)); + b7 = ror64(tmp, 4); b10 -= b7; tmp = b15 ^ b4; - b15 = (tmp >> 51) | (tmp << (64 - 51)); + b15 = ror64(tmp, 51); b4 -= b15; tmp = b11 ^ b6; - b11 = (tmp >> 56) | (tmp << (64 - 56)); + b11 = ror64(tmp, 56); b6 -= b11; tmp = b13 ^ b2; - b13 = (tmp >> 34) | (tmp << (64 - 34)); + b13 = ror64(tmp, 34); b2 -= b13; tmp = b9 ^ b0; - b9 = (tmp >> 16) | (tmp << (64 - 16)); + b9 = ror64(tmp, 16); b0 -= b9; tmp = b15 ^ b14; - b15 = (tmp >> 30) | (tmp << (64 - 30)); + b15 = ror64(tmp, 30); b14 -= b15 + k15 + t2; b15 -= k16 + 1; tmp = b13 ^ b12; - b13 = (tmp >> 44) | (tmp << (64 - 44)); + b13 = ror64(tmp, 44); b12 -= b13 + k13; b13 -= k14 + t1; tmp = b11 ^ b10; - b11 = (tmp >> 47) | (tmp << (64 - 47)); + b11 = ror64(tmp, 47); b10 -= b11 + k11; b11 -= k12; tmp = b9 ^ b8; - b9 = (tmp >> 12) | (tmp << (64 - 12)); + b9 = ror64(tmp, 12); b8 -= b9 + k9; b9 -= k10; tmp = b7 ^ b6; - b7 = (tmp >> 31) | (tmp << (64 - 31)); + b7 = ror64(tmp, 31); b6 -= b7 + k7; b7 -= k8; tmp = b5 ^ b4; - b5 = (tmp >> 37) | (tmp << (64 - 37)); + b5 = ror64(tmp, 37); b4 -= b5 + k5; b5 -= k6; tmp = b3 ^ b2; - b3 = (tmp >> 9) | (tmp << (64 - 9)); + b3 = ror64(tmp, 9); b2 -= b3 + k3; b3 -= k4; tmp = b1 ^ b0; - b1 = (tmp >> 41) | (tmp << (64 - 41)); + b1 = ror64(tmp, 41); b0 -= b1 + k1; b1 -= k2; tmp = b7 ^ b12; - b7 = (tmp >> 25) | (tmp << (64 - 25)); + b7 = ror64(tmp, 25); b12 -= b7; tmp = b3 ^ b10; - b3 = (tmp >> 16) | (tmp << (64 - 16)); + b3 = ror64(tmp, 16); b10 -= b3; tmp = b5 ^ b8; - b5 = (tmp >> 28) | (tmp << (64 - 28)); + b5 = ror64(tmp, 28); b8 -= b5; tmp = b1 ^ b14; - b1 = (tmp >> 47) | (tmp << (64 - 47)); + b1 = ror64(tmp, 47); b14 -= b1; tmp = b9 ^ b4; - b9 = (tmp >> 41) | (tmp << (64 - 41)); + b9 = ror64(tmp, 41); b4 -= b9; tmp = b13 ^ b6; - b13 = (tmp >> 48) | (tmp << (64 - 48)); + b13 = ror64(tmp, 48); b6 -= b13; tmp = b11 ^ b2; - b11 = (tmp >> 20) | (tmp << (64 - 20)); + b11 = ror64(tmp, 20); b2 -= b11; tmp = b15 ^ b0; - b15 = (tmp >> 5) | (tmp << (64 - 5)); + b15 = ror64(tmp, 5); b0 -= b15; tmp = b9 ^ b10; - b9 = (tmp >> 17) | (tmp << (64 - 17)); + b9 = ror64(tmp, 17); b10 -= b9; tmp = b11 ^ b8; - b11 = (tmp >> 59) | (tmp << (64 - 59)); + b11 = ror64(tmp, 59); b8 -= b11; tmp = b13 ^ b14; - b13 = (tmp >> 41) | (tmp << (64 - 41)); + b13 = ror64(tmp, 41); b14 -= b13; tmp = b15 ^ b12; - b15 = (tmp >> 34) | (tmp << (64 - 34)); + b15 = ror64(tmp, 34); b12 -= b15; tmp = b1 ^ b6; - b1 = (tmp >> 13) | (tmp << (64 - 13)); + b1 = ror64(tmp, 13); b6 -= b1; tmp = b3 ^ b4; - b3 = (tmp >> 51) | (tmp << (64 - 51)); + b3 = ror64(tmp, 51); b4 -= b3; tmp = b5 ^ b2; - b5 = (tmp >> 4) | (tmp << (64 - 4)); + b5 = ror64(tmp, 4); b2 -= b5; tmp = b7 ^ b0; - b7 = (tmp >> 33) | (tmp << (64 - 33)); + b7 = ror64(tmp, 33); b0 -= b7; tmp = b1 ^ b8; - b1 = (tmp >> 52) | (tmp << (64 - 52)); + b1 = ror64(tmp, 52); b8 -= b1; tmp = b5 ^ b14; - b5 = (tmp >> 23) | (tmp << (64 - 23)); + b5 = ror64(tmp, 23); b14 -= b5; tmp = b3 ^ b12; - b3 = (tmp >> 18) | (tmp << (64 - 18)); + b3 = ror64(tmp, 18); b12 -= b3; tmp = b7 ^ b10; - b7 = (tmp >> 49) | (tmp << (64 - 49)); + b7 = ror64(tmp, 49); b10 -= b7; tmp = b15 ^ b4; - b15 = (tmp >> 55) | (tmp << (64 - 55)); + b15 = ror64(tmp, 55); b4 -= b15; tmp = b11 ^ b6; - b11 = (tmp >> 10) | (tmp << (64 - 10)); + b11 = ror64(tmp, 10); b6 -= b11; tmp = b13 ^ b2; - b13 = (tmp >> 19) | (tmp << (64 - 19)); + b13 = ror64(tmp, 19); b2 -= b13; tmp = b9 ^ b0; - b9 = (tmp >> 38) | (tmp << (64 - 38)); + b9 = ror64(tmp, 38); b0 -= b9; tmp = b15 ^ b14; - b15 = (tmp >> 37) | (tmp << (64 - 37)); + b15 = ror64(tmp, 37); b14 -= b15 + k14 + t1; b15 -= k15; tmp = b13 ^ b12; - b13 = (tmp >> 22) | (tmp << (64 - 22)); + b13 = ror64(tmp, 22); b12 -= b13 + k12; b13 -= k13 + t0; tmp = b11 ^ b10; - b11 = (tmp >> 17) | (tmp << (64 - 17)); + b11 = ror64(tmp, 17); b10 -= b11 + k10; b11 -= k11; tmp = b9 ^ b8; - b9 = (tmp >> 8) | (tmp << (64 - 8)); + b9 = ror64(tmp, 8); b8 -= b9 + k8; b9 -= k9; tmp = b7 ^ b6; - b7 = (tmp >> 47) | (tmp << (64 - 47)); + b7 = ror64(tmp, 47); b6 -= b7 + k6; b7 -= k7; tmp = b5 ^ b4; - b5 = (tmp >> 8) | (tmp << (64 - 8)); + b5 = ror64(tmp, 8); b4 -= b5 + k4; b5 -= k5; tmp = b3 ^ b2; - b3 = (tmp >> 13) | (tmp << (64 - 13)); + b3 = ror64(tmp, 13); b2 -= b3 + k2; b3 -= k3; tmp = b1 ^ b0; - b1 = (tmp >> 24) | (tmp << (64 - 24)); + b1 = ror64(tmp, 24); b0 -= b1 + k0; b1 -= k1; -- cgit v1.2.3 From de40f2ab975977375e4620448a2967b69cc3c9cb Mon Sep 17 00:00:00 2001 From: Dilek Uzulmez Date: Sun, 13 Mar 2016 23:31:08 +0200 Subject: Staging: rts5208: Add space around '+' Add space around operator '+'. Problem found using checkpatch.pl CHECK: spaces preferred around that '+' (ctx:VxV) Signed-off-by: Dilek Uzulmez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts5208/ms.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rts5208/ms.c b/drivers/staging/rts5208/ms.c index a780185a3754..3e75db751c41 100644 --- a/drivers/staging/rts5208/ms.c +++ b/drivers/staging/rts5208/ms.c @@ -2691,7 +2691,7 @@ static int ms_build_l2p_tbl(struct rtsx_chip *chip, int seg_no) } if ((log_blk < ms_start_idx[seg_no]) || - (log_blk >= ms_start_idx[seg_no+1])) { + (log_blk >= ms_start_idx[seg_no + 1])) { if (!(chip->card_wp & MS_CARD)) { retval = ms_erase_block(chip, phy_blk); if (retval != STATUS_SUCCESS) @@ -3836,7 +3836,7 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rtsx_chip *chip, start_page = (u8)(start_sector & ms_card->page_off); for (seg_no = 0; seg_no < ARRAY_SIZE(ms_start_idx) - 1; seg_no++) { - if (log_blk < ms_start_idx[seg_no+1]) + if (log_blk < ms_start_idx[seg_no + 1]) break; } @@ -4264,7 +4264,7 @@ int mg_set_leaf_id(struct scsi_cmnd *srb, struct rtsx_chip *chip) memset(buf1, 0, 32); rtsx_stor_get_xfer_buf(buf2, min_t(int, 12, scsi_bufflen(srb)), srb); for (i = 0; i < 8; i++) - buf1[8+i] = buf2[4+i]; + buf1[8 + i] = buf2[4 + i]; retval = ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, 32, WAIT_INT, buf1, 32); @@ -4399,10 +4399,10 @@ int mg_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip) rtsx_stor_get_xfer_buf(buf, bufflen, srb); for (i = 0; i < 8; i++) - buf[i] = buf[4+i]; + buf[i] = buf[4 + i]; for (i = 0; i < 24; i++) - buf[8+i] = 0; + buf[8 + i] = 0; retval = ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, 32, WAIT_INT, buf, 32); @@ -4511,10 +4511,10 @@ int mg_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip) rtsx_stor_get_xfer_buf(buf, bufflen, srb); for (i = 0; i < 8; i++) - buf[i] = buf[4+i]; + buf[i] = buf[4 + i]; for (i = 0; i < 24; i++) - buf[8+i] = 0; + buf[8 + i] = 0; retval = ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, 32, WAIT_INT, buf, 32); -- cgit v1.2.3 From 8aba6c6e9821a83937cccbc7f2292e06e605d340 Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Sun, 13 Mar 2016 15:48:15 +0530 Subject: Staging: gs_fpgaboot: Fix alignment to match open parenthesis. Fix alignment to match open parenthesis. Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gs_fpgaboot/gs_fpgaboot.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c index 7b7c9786c162..de1a9a69993a 100644 --- a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c +++ b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c @@ -201,7 +201,7 @@ static int gs_download_image(struct fpgaimage *fimage, enum wbus bus_bytes) #endif /* DEBUG_FPGA */ if (!xl_supported_prog_bus_width(bus_bytes)) { pr_err("unsupported program bus width %d\n", - bus_bytes); + bus_bytes); return -1; } @@ -277,7 +277,7 @@ static int gs_set_download_method(struct fpgaimage *fimage) static int init_driver(void) { firmware_pdev = platform_device_register_simple("fpgaboot", -1, - NULL, 0); + NULL, 0); return PTR_ERR_OR_ZERO(firmware_pdev); } -- cgit v1.2.3 From e58463b3415f242bbfad816810eb24454f5a0bb1 Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Sun, 13 Mar 2016 15:50:03 +0530 Subject: Staging: gs_fpgaboot: Remove unnecessary blank lines. Remove unnecessary blank lines. Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gs_fpgaboot/gs_fpgaboot.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c index de1a9a69993a..1af0745fa26a 100644 --- a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c +++ b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c @@ -93,7 +93,6 @@ static int readlength_bitstream(char *bitdata, int *lendata, int *offset) return 0; } - /* * read first 13 bytes to check bitstream magic number */ @@ -331,7 +330,6 @@ err_out1: kfree(fimage); return -1; - } static int __init gs_fpgaboot_init(void) -- cgit v1.2.3 From c5471a6fa66cffdf5c868a9fbec2e06c6fa057c5 Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Sun, 13 Mar 2016 15:52:15 +0530 Subject: Staging: gs_fpgaboot: Add space around '+'. Add space around '+'. Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gs_fpgaboot/gs_fpgaboot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c index 1af0745fa26a..a221f261c3d3 100644 --- a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c +++ b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c @@ -221,7 +221,7 @@ static int gs_download_image(struct fpgaimage *fimage, enum wbus bus_bytes) pr_info("device init done\n"); for (i = 0; i < size; i += bus_bytes) - xl_shift_bytes_out(bus_bytes, bitdata+i); + xl_shift_bytes_out(bus_bytes, bitdata + i); pr_info("program done\n"); -- cgit v1.2.3 From c70aa60bdc12347120b0f3277de2ec6c26988a2e Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Sun, 13 Mar 2016 16:41:23 +0530 Subject: Staging: gs_fpgaboot: Replace 'int32_t' with 'int'. Replace 'int32_t' with 'int'. Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gs_fpgaboot/gs_fpgaboot.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/gs_fpgaboot/gs_fpgaboot.h b/drivers/staging/gs_fpgaboot/gs_fpgaboot.h index f41f4cc798cc..8cc32555dbf3 100644 --- a/drivers/staging/gs_fpgaboot/gs_fpgaboot.h +++ b/drivers/staging/gs_fpgaboot/gs_fpgaboot.h @@ -51,6 +51,6 @@ struct fpgaimage { char part[MAX_STR]; char date[MAX_STR]; char time[MAX_STR]; - int32_t lendata; + int lendata; char *fpgadata; }; -- cgit v1.2.3 From abe341744574c3fd076e40f053a6fb2f6e549abc Mon Sep 17 00:00:00 2001 From: Dilek Uzulmez Date: Sun, 13 Mar 2016 23:58:08 +0200 Subject: Staging: emxx_udc: Add space around '-' Add space around operator '-'. Problem found using checkpatch.pl CHECK: spaces preferred around that '-' (ctx:VxV) Signed-off-by: Dilek Uzulmez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/emxx_udc/emxx_udc.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/emxx_udc/emxx_udc.c b/drivers/staging/emxx_udc/emxx_udc.c index e8cacaecf9ad..58e189b7f184 100644 --- a/drivers/staging/emxx_udc/emxx_udc.c +++ b/drivers/staging/emxx_udc/emxx_udc.c @@ -418,9 +418,9 @@ static void _nbu2ss_ep_dma_abort(struct nbu2ss_udc *udc, struct nbu2ss_ep *ep) { struct fc_regs *preg = udc->p_regs; - _nbu2ss_bitclr(&preg->EP_DCR[ep->epnum-1].EP_DCR1, DCR1_EPn_REQEN); + _nbu2ss_bitclr(&preg->EP_DCR[ep->epnum - 1].EP_DCR1, DCR1_EPn_REQEN); mdelay(DMA_DISABLE_TIME); /* DCR1_EPn_REQEN Clear */ - _nbu2ss_bitclr(&preg->EP_REGS[ep->epnum-1].EP_DMA_CTRL, EPn_DMA_EN); + _nbu2ss_bitclr(&preg->EP_REGS[ep->epnum - 1].EP_DMA_CTRL, EPn_DMA_EN); } /*-------------------------------------------------------------------------*/ @@ -909,7 +909,7 @@ static int _nbu2ss_epn_out_pio( /* Copy of every four bytes */ for (i = 0; i < iWordLength; i++) { pBuf32->dw = - _nbu2ss_readl(&preg->EP_REGS[ep->epnum-1].EP_READ); + _nbu2ss_readl(&preg->EP_REGS[ep->epnum - 1].EP_READ); pBuf32++; } result = iWordLength * sizeof(u32); @@ -919,7 +919,7 @@ static int _nbu2ss_epn_out_pio( if (data > 0) { /*---------------------------------------------------------*/ /* Copy of fraction byte */ - Temp32.dw = _nbu2ss_readl(&preg->EP_REGS[ep->epnum-1].EP_READ); + Temp32.dw = _nbu2ss_readl(&preg->EP_REGS[ep->epnum - 1].EP_READ); for (i = 0 ; i < data ; i++) pBuf32->byte.DATA[i] = Temp32.byte.DATA[i]; result += data; @@ -1128,7 +1128,7 @@ static int _nbu2ss_epn_in_pio( if (iWordLength > 0) { for (i = 0; i < iWordLength; i++) { _nbu2ss_writel( - &preg->EP_REGS[ep->epnum-1].EP_WRITE + &preg->EP_REGS[ep->epnum - 1].EP_WRITE , pBuf32->dw ); @@ -1290,7 +1290,7 @@ static void _nbu2ss_restert_transfer(struct nbu2ss_ep *ep) if (ep->epnum > 0) { length = _nbu2ss_readl( - &ep->udc->p_regs->EP_REGS[ep->epnum-1].EP_LEN_DCNT); + &ep->udc->p_regs->EP_REGS[ep->epnum - 1].EP_LEN_DCNT); length &= EPn_LDATA; if (length < ep->ep.maxpacket) @@ -1463,7 +1463,7 @@ static int _nbu2ss_get_ep_stall(struct nbu2ss_udc *udc, u8 ep_adrs) bit_data = EP0_STL; } else { - data = _nbu2ss_readl(&preg->EP_REGS[epnum-1].EP_CONTROL); + data = _nbu2ss_readl(&preg->EP_REGS[epnum - 1].EP_CONTROL); if ((data & EPn_EN) == 0) return -1; @@ -1558,7 +1558,7 @@ static void _nbu2ss_epn_set_stall( ; limit_cnt++) { regdata = _nbu2ss_readl( - &preg->EP_REGS[ep->epnum-1].EP_STATUS); + &preg->EP_REGS[ep->epnum - 1].EP_STATUS); if ((regdata & EPn_IN_DATA) == 0) break; @@ -1983,7 +1983,7 @@ static inline void _nbu2ss_epn_in_int( if (req->zero && ((req->req.actual % ep->ep.maxpacket) == 0)) { status = - _nbu2ss_readl(&preg->EP_REGS[ep->epnum-1].EP_STATUS); + _nbu2ss_readl(&preg->EP_REGS[ep->epnum - 1].EP_STATUS); if ((status & EPn_IN_FULL) == 0) { /*-----------------------------------------*/ @@ -2894,7 +2894,7 @@ static int nbu2ss_ep_fifo_status(struct usb_ep *_ep) data = _nbu2ss_readl(&preg->EP0_LENGTH) & EP0_LDATA; } else { - data = _nbu2ss_readl(&preg->EP_REGS[ep->epnum-1].EP_LEN_DCNT) + data = _nbu2ss_readl(&preg->EP_REGS[ep->epnum - 1].EP_LEN_DCNT) & EPn_LDATA; } -- cgit v1.2.3 From b6d3b4577e49fa8d9a37912ea36ae8449d630b0b Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Fri, 18 Mar 2016 13:56:00 +0530 Subject: Staging: emxx_udc: emxx_udc: Add space around operator. Add space around operator.This patch is found by checkpatch.pl script. Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/emxx_udc/emxx_udc.h | 40 ++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/emxx_udc/emxx_udc.h b/drivers/staging/emxx_udc/emxx_udc.h index 4a2cc38de7b3..39769e3a801c 100644 --- a/drivers/staging/emxx_udc/emxx_udc.h +++ b/drivers/staging/emxx_udc/emxx_udc.h @@ -97,7 +97,7 @@ #define BIT30 0x40000000 #define BIT31 0x80000000 -#define TEST_FORCE_ENABLE (BIT18+BIT16) +#define TEST_FORCE_ENABLE (BIT18 + BIT16) #define INT_SEL BIT10 #define CONSTFS BIT09 @@ -125,15 +125,15 @@ /*------- (0x0008) USB Address Register */ #define USB_ADDR 0x007F0000 #define SOF_STATUS BIT15 -#define UFRAME (BIT14+BIT13+BIT12) +#define UFRAME (BIT14 + BIT13 + BIT12) #define FRAME 0x000007FF #define USB_ADRS_SHIFT 16 /*------- (0x000C) UTMI Characteristic 1 Register */ -#define SQUSET (BIT07+BIT06+BIT05+BIT04) +#define SQUSET (BIT07 + BIT06 + BIT05 + BIT04) -#define USB_SQUSET (BIT06+BIT05+BIT04) +#define USB_SQUSET (BIT06 + BIT05 + BIT04) /*------- (0x0010) TEST Control Register */ #define FORCEHS BIT02 @@ -196,7 +196,7 @@ #define RSUM_EN BIT01 #define USB_INT_EN_BIT \ - (EP0_EN|SPEED_MODE_EN|USB_RST_EN|SPND_EN|RSUM_EN) + (EP0_EN | SPEED_MODE_EN | USB_RST_EN | SPND_EN | RSUM_EN) /*------- (0x0028) EP0 Control Register */ #define EP0_STGSEL BIT18 @@ -205,9 +205,9 @@ #define EP0_PIDCLR BIT09 #define EP0_BCLR BIT08 #define EP0_DEND BIT07 -#define EP0_DW (BIT06+BIT05) +#define EP0_DW (BIT06 + BIT05) #define EP0_DW4 0 -#define EP0_DW3 (BIT06+BIT05) +#define EP0_DW3 (BIT06 + BIT05) #define EP0_DW2 BIT06 #define EP0_DW1 BIT05 @@ -238,7 +238,7 @@ #define STG_START_INT BIT01 #define SETUP_INT BIT00 -#define EP0_STATUS_RW_BIT (BIT16|BIT15|BIT11|0xFF) +#define EP0_STATUS_RW_BIT (BIT16 | BIT15 | BIT11 | 0xFF) /*------- (0x0030) EP0 Interrupt Enable Register */ #define EP0_PERR_NAK_EN BIT16 @@ -256,7 +256,7 @@ #define SETUP_EN BIT00 #define EP0_INT_EN_BIT \ - (EP0_OUT_OR_EN|EP0_OUT_EN|EP0_IN_EN|STG_END_EN|SETUP_EN) + (EP0_OUT_OR_EN | EP0_OUT_EN | EP0_IN_EN | STG_END_EN | SETUP_EN) /*------- (0x0034) EP0 Length Register */ #define EP0_LDATA 0x0000007F @@ -270,7 +270,7 @@ #define EPn_BUF_SINGLE BIT30 #define EPn_DIR0 BIT26 -#define EPn_MODE (BIT25+BIT24) +#define EPn_MODE (BIT25 + BIT24) #define EPn_BULK 0 #define EPn_INTERRUPT BIT24 #define EPn_ISO BIT25 @@ -283,9 +283,9 @@ #define EPn_BCLR BIT09 #define EPn_CBCLR BIT08 #define EPn_DEND BIT07 -#define EPn_DW (BIT06+BIT05) +#define EPn_DW (BIT06 + BIT05) #define EPn_DW4 0 -#define EPn_DW3 (BIT06+BIT05) +#define EPn_DW3 (BIT06 + BIT05) #define EPn_DW2 BIT06 #define EPn_DW1 BIT05 @@ -324,7 +324,7 @@ #define EPn_IN_EMPTY BIT00 /* R */ #define EPn_INT_EN \ - (EPn_OUT_END_INT|EPn_OUT_INT|EPn_IN_END_INT|EPn_IN_INT) + (EPn_OUT_END_INT | EPn_OUT_INT | EPn_IN_END_INT | EPn_IN_INT) /*------- (0x0048:) EPn Interrupt Enable Register */ #define EPn_OUT_END_EN BIT23 /* RW */ @@ -368,7 +368,7 @@ #define ARBITER_CTR BIT31 /* RW */ #define MCYCLE_RST BIT12 /* RW */ -#define ENDIAN_CTR (BIT09+BIT08) /* RW */ +#define ENDIAN_CTR (BIT09 + BIT08) /* RW */ #define ENDIAN_BYTE_SWAP BIT09 #define ENDIAN_HALF_WORD_SWAP ENDIAN_CTR @@ -376,7 +376,7 @@ #define HTRANS_MODE BIT04 /* RW */ #define WBURST_TYPE BIT02 /* RW */ -#define BURST_TYPE (BIT01+BIT00) /* RW */ +#define BURST_TYPE (BIT01 + BIT00) /* RW */ #define BURST_MAX_16 0 #define BURST_MAX_8 BIT00 #define BURST_MAX_4 BIT01 @@ -412,7 +412,7 @@ #define EPC_RST BIT00 /* RW */ /*------- (0x1014) USBF_EPTEST Register */ -#define LINESTATE (BIT09+BIT08) /* R */ +#define LINESTATE (BIT09 + BIT08) /* R */ #define DM_LEVEL BIT09 /* R */ #define DP_LEVEL BIT08 /* R */ @@ -485,7 +485,7 @@ struct fc_regs { struct ep_regs EP_REGS[REG_EP_NUM]; /* Endpoint Register */ - u8 Reserved220[0x1000-0x220]; /* (0x0220:0x0FFF) Reserved */ + u8 Reserved220[0x1000 - 0x220]; /* (0x0220:0x0FFF) Reserved */ u32 AHBSCTR; /* (0x1000) AHBSCTR */ u32 AHBMCTR; /* (0x1004) AHBMCTR */ @@ -494,16 +494,16 @@ struct fc_regs { u32 EPCTR; /* (0x1010) EPCTR */ u32 USBF_EPTEST; /* (0x1014) USBF_EPTEST */ - u8 Reserved1018[0x20-0x18]; /* (0x1018:0x101F) Reserved */ + u8 Reserved1018[0x20 - 0x18]; /* (0x1018:0x101F) Reserved */ u32 USBSSVER; /* (0x1020) USBSSVER */ u32 USBSSCONF; /* (0x1024) USBSSCONF */ - u8 Reserved1028[0x110-0x28]; /* (0x1028:0x110F) Reserved */ + u8 Reserved1028[0x110 - 0x28]; /* (0x1028:0x110F) Reserved */ struct ep_dcr EP_DCR[REG_EP_NUM]; /* */ - u8 Reserved1200[0x1000-0x200]; /* Reserved */ + u8 Reserved1200[0x1000 - 0x200]; /* Reserved */ } __aligned(32); #define EP0_PACKETSIZE 64 -- cgit v1.2.3 From 364076730cd046ab347f5883cf9193f33adea1da Mon Sep 17 00:00:00 2001 From: Heena Sirwani Date: Mon, 14 Mar 2016 17:23:00 +0530 Subject: staging: media: omap4iss: Match alignment with open parenthesis. The following patch fixes the following checkpatch.pl warning: CHECK: Alignment should match open parenthesis Signed-off-by: Heena Sirwani Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/omap4iss/iss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c index c5a5138b3d3b..6ceb4eb00493 100644 --- a/drivers/staging/media/omap4iss/iss.c +++ b/drivers/staging/media/omap4iss/iss.c @@ -1065,7 +1065,7 @@ static int iss_register_entities(struct iss_device *iss) } ret = media_create_pad_link(&sensor->entity, 0, input, pad, - flags); + flags); if (ret < 0) goto done; } -- cgit v1.2.3 From 8cd977c3166e448684aba578df6e00dad83d990c Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Fri, 18 Mar 2016 14:56:31 +0530 Subject: Staging: fbtft: fbtft_device: No space is necessary after cast. No space is necessary after cast. Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/fbtft/fbtft_device.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/fbtft/fbtft_device.c b/drivers/staging/fbtft/fbtft_device.c index 241d7c6bebde..e4a355aefb25 100644 --- a/drivers/staging/fbtft/fbtft_device.c +++ b/drivers/staging/fbtft/fbtft_device.c @@ -1254,7 +1254,7 @@ static int write_gpio16_wr_slow(struct fbtft_par *par, void *buf, size_t len) "%s(len=%d): ", __func__, len); while (len) { - data = *(u16 *) buf; + data = *(u16 *)buf; /* Start writing by pulling down /WR */ gpio_set_value(par->gpio.wr, 0); @@ -1283,7 +1283,7 @@ static int write_gpio16_wr_slow(struct fbtft_par *par, void *buf, size_t len) gpio_set_value(par->gpio.wr, 1); #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO - prev_data = *(u16 *) buf; + prev_data = *(u16 *)buf; #endif buf += 2; len -= 2; @@ -1436,7 +1436,7 @@ static int __init fbtft_device_init(void) } strncpy(fbtft_device_param_gpios[i].name, p_name, FBTFT_GPIO_NAME_SIZE - 1); - fbtft_device_param_gpios[i++].gpio = (int) val; + fbtft_device_param_gpios[i++].gpio = (int)val; if (i == MAX_GPIOS) { pr_err("gpios parameter: exceeded max array size: %d\n", MAX_GPIOS); -- cgit v1.2.3 From 8d771ea8bf27ae02bf185bd32c67f4d314865945 Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Fri, 18 Mar 2016 14:59:34 +0530 Subject: Staging: fbtft: fbtft-io: No space is necessary after cast. No space is necessary after cast.This patch is found by checkpatch.pl script. Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/fbtft/fbtft-io.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/fbtft/fbtft-io.c b/drivers/staging/fbtft/fbtft-io.c index a6f091fb975c..4dcea2e0b3ae 100644 --- a/drivers/staging/fbtft/fbtft-io.c +++ b/drivers/staging/fbtft/fbtft-io.c @@ -141,7 +141,7 @@ int fbtft_write_gpio8_wr(struct fbtft_par *par, void *buf, size_t len) "%s(len=%d): ", __func__, len); while (len--) { - data = *(u8 *) buf; + data = *(u8 *)buf; /* Start writing by pulling down /WR */ gpio_set_value(par->gpio.wr, 0); @@ -170,7 +170,7 @@ int fbtft_write_gpio8_wr(struct fbtft_par *par, void *buf, size_t len) gpio_set_value(par->gpio.wr, 1); #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO - prev_data = *(u8 *) buf; + prev_data = *(u8 *)buf; #endif buf++; } @@ -191,7 +191,7 @@ int fbtft_write_gpio16_wr(struct fbtft_par *par, void *buf, size_t len) "%s(len=%d): ", __func__, len); while (len) { - data = *(u16 *) buf; + data = *(u16 *)buf; /* Start writing by pulling down /WR */ gpio_set_value(par->gpio.wr, 0); @@ -220,7 +220,7 @@ int fbtft_write_gpio16_wr(struct fbtft_par *par, void *buf, size_t len) gpio_set_value(par->gpio.wr, 1); #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO - prev_data = *(u16 *) buf; + prev_data = *(u16 *)buf; #endif buf += 2; len -= 2; -- cgit v1.2.3 From 60abe3510e55cbd74a1ed163fed75a25cae8d45c Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Fri, 18 Mar 2016 15:02:41 +0530 Subject: Staging: fbtft: fb_agm1264k-fl: No space is necessary after cast. No space is necessary after cast.This problem is found by checkpatch.pl script. Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/fbtft/fb_agm1264k-fl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/fbtft/fb_agm1264k-fl.c b/drivers/staging/fbtft/fb_agm1264k-fl.c index ba9fc444b848..82b46cd27ca7 100644 --- a/drivers/staging/fbtft/fb_agm1264k-fl.c +++ b/drivers/staging/fbtft/fb_agm1264k-fl.c @@ -414,7 +414,7 @@ static int write(struct fbtft_par *par, void *buf, size_t len) while (len--) { u8 i, data; - data = *(u8 *) buf++; + data = *(u8 *)buf++; /* set data bus */ for (i = 0; i < 8; ++i) -- cgit v1.2.3 From f3fe438db281cc2d115843d27c7e196bf7404d3c Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Sun, 20 Mar 2016 16:47:28 +0530 Subject: Staging: i4l: pcbit: layer2: Add parentheses to complex macro. Add parentheses to complex macro. Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/i4l/pcbit/layer2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/i4l/pcbit/layer2.h b/drivers/staging/i4l/pcbit/layer2.h index be1327bc162a..6b9063e388cd 100644 --- a/drivers/staging/i4l/pcbit/layer2.h +++ b/drivers/staging/i4l/pcbit/layer2.h @@ -109,7 +109,7 @@ #define SCHED_READ 0x01 #define SCHED_WRITE 0x02 -#define SET_RUN_TIMEOUT 2 * HZ /* 2 seconds */ +#define SET_RUN_TIMEOUT (2 * HZ) /* 2 seconds */ struct frame_buf { ulong msg; -- cgit v1.2.3 From f2cef3f2db6647975bb7e8a83fcdfc52146b55c0 Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Sun, 20 Mar 2016 16:49:02 +0530 Subject: Staging: i4l: pcbit: edss1: Use !x instead of x == NULL. Use !x instead of x == NULL. Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/i4l/pcbit/edss1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/i4l/pcbit/edss1.c b/drivers/staging/i4l/pcbit/edss1.c index b2262ba6f0c9..e72c16420712 100644 --- a/drivers/staging/i4l/pcbit/edss1.c +++ b/drivers/staging/i4l/pcbit/edss1.c @@ -254,7 +254,7 @@ static void pcbit_fsm_timer(unsigned long data) dev = chan2dev(chan); - if (dev == NULL) { + if (!dev) { printk(KERN_WARNING "pcbit: timer for unknown device\n"); return; } -- cgit v1.2.3 From 3e735d1e3a9a045cbd2610ff33e9fd355d09e632 Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Sun, 20 Mar 2016 16:50:49 +0530 Subject: Staging: i4l: pcbit: drv: Do not initialise statics to 0. Do not initialise statics to 0. Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/i4l/pcbit/drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/i4l/pcbit/drv.c b/drivers/staging/i4l/pcbit/drv.c index 4172e22ae7ed..c79ee84b56db 100644 --- a/drivers/staging/i4l/pcbit/drv.c +++ b/drivers/staging/i4l/pcbit/drv.c @@ -699,8 +699,8 @@ void pcbit_l3_receive(struct pcbit_dev *dev, ulong msg, */ static char statbuf[STATBUF_LEN]; -static int stat_st = 0; -static int stat_end = 0; +static int stat_st; +static int stat_end; static int pcbit_stat(u_char __user *buf, int len, int driver, int channel) { -- cgit v1.2.3 From 8c9a093e1cec027bec070134fd56d9ae98b080a8 Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Sun, 20 Mar 2016 16:52:35 +0530 Subject: Staging: i4l: pcbit: capi: Add parentheses to complex macro. Add parentheses to complex macro. Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/i4l/pcbit/capi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/i4l/pcbit/capi.h b/drivers/staging/i4l/pcbit/capi.h index 635f63476944..6f6f4dd0714e 100644 --- a/drivers/staging/i4l/pcbit/capi.h +++ b/drivers/staging/i4l/pcbit/capi.h @@ -17,7 +17,7 @@ #define REQ_DISPLAY 0x04 #define REQ_USER_TO_USER 0x08 -#define AppInfoMask REQ_CAUSE | REQ_DISPLAY | REQ_USER_TO_USER +#define AppInfoMask (REQ_CAUSE | REQ_DISPLAY | REQ_USER_TO_USER) /* Connection Setup */ extern int capi_conn_req(const char *calledPN, struct sk_buff **buf, -- cgit v1.2.3 From 5c722af4c454c881349fec4f8ee3a4ee0a2a77ed Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Fri, 18 Mar 2016 08:45:08 +0530 Subject: Staging: i4l: pcbit: drv: Remove unnecessary semicolon. Remove unnecessary semicolon.This issue is detected by coccinelle script. Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/i4l/pcbit/drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/i4l/pcbit/drv.c b/drivers/staging/i4l/pcbit/drv.c index c79ee84b56db..c5270e229efb 100644 --- a/drivers/staging/i4l/pcbit/drv.c +++ b/drivers/staging/i4l/pcbit/drv.c @@ -284,7 +284,7 @@ static int pcbit_command(isdn_ctrl *ctl) default: printk(KERN_DEBUG "pcbit_command: unknown command\n"); break; - }; + } return 0; } @@ -968,7 +968,7 @@ static int pcbit_ioctl(isdn_ctrl *ctl) default: printk("error: unknown ioctl\n"); break; - }; + } return 0; } -- cgit v1.2.3 From bb94df96f7a260ff0d4384719fd8cac477e4c31d Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Mon, 21 Mar 2016 18:06:03 +0530 Subject: Staging: lustre: lib-move: Remove unnecessary space after cast. Remove unnecessary space after cast. Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/lnet/lib-move.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 0009a8de77d5..44e2bd6dba63 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -407,7 +407,7 @@ lnet_copy_kiov2iov(unsigned int niov, struct kvec *iov, unsigned int iovoffset, LASSERT(niov > 0); LASSERT(nkiov > 0); this_nob = min(iov->iov_len - iovoffset, - (__kernel_size_t) kiov->kiov_len - kiovoffset); + (__kernel_size_t)kiov->kiov_len - kiovoffset); this_nob = min(this_nob, nob); if (!addr) @@ -477,7 +477,7 @@ lnet_copy_iov2kiov(unsigned int nkiov, lnet_kiov_t *kiov, do { LASSERT(nkiov > 0); LASSERT(niov > 0); - this_nob = min((__kernel_size_t) kiov->kiov_len - kiovoffset, + this_nob = min((__kernel_size_t)kiov->kiov_len - kiovoffset, iov->iov_len - iovoffset); this_nob = min(this_nob, nob); @@ -996,7 +996,7 @@ lnet_return_tx_credits_locked(lnet_msg_t *msg) LASSERT(msg2->msg_txpeer->lp_ni == ni); LASSERT(msg2->msg_tx_delayed); - (void) lnet_post_send_locked(msg2, 1); + (void)lnet_post_send_locked(msg2, 1); } } @@ -1019,7 +1019,7 @@ lnet_return_tx_credits_locked(lnet_msg_t *msg) LASSERT(msg2->msg_txpeer == txpeer); LASSERT(msg2->msg_tx_delayed); - (void) lnet_post_send_locked(msg2, 1); + (void)lnet_post_send_locked(msg2, 1); } } @@ -1142,7 +1142,7 @@ routing_off: lnet_msg_t, msg_list); list_del(&msg2->msg_list); - (void) lnet_post_routed_recv_locked(msg2, 1); + (void)lnet_post_routed_recv_locked(msg2, 1); } } if (rxpeer) { -- cgit v1.2.3 From 4f296211583ade450f25a14be0a669a309ea6303 Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Mon, 21 Mar 2016 19:15:24 +0530 Subject: Staging: lustre: socklnd_lib: Remove return statement from void function. Remove return statement from void function. Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c index 3e1f24e77f64..acebc6fe0dbe 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c @@ -675,7 +675,6 @@ ksocknal_lib_set_callback(struct socket *sock, ksock_conn_t *conn) sock->sk->sk_user_data = conn; sock->sk->sk_data_ready = ksocknal_data_ready; sock->sk->sk_write_space = ksocknal_write_space; - return; } void @@ -695,8 +694,6 @@ ksocknal_lib_reset_callback(struct socket *sock, ksock_conn_t *conn) * sk_user_data is NULL. */ sock->sk->sk_user_data = NULL; - - return ; } int -- cgit v1.2.3 From 4ec4595272240b21365b6563c24b1e22570c3880 Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Mon, 21 Mar 2016 19:16:48 +0530 Subject: Staging: lustre: socklnd: Remove return statement from void function. Remove return statement from void function. Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c index cca7b2f7f1a7..406c0e7a57b9 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c @@ -2582,7 +2582,6 @@ ksocknal_debug_peerhash(lnet_ni_t *ni) } read_unlock(&ksocknal_data.ksnd_global_lock); - return; } void -- cgit v1.2.3 From 9899cb68c6c23d58b27035c237b2d425f4c6133c Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Mon, 21 Mar 2016 19:51:12 +0530 Subject: Staging: lustre: rpc: Use sizeof type *pointer instead of sizeof type. Use sizeof type *pointer instead of sizeof type. Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/selftest/rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/selftest/rpc.c b/drivers/staging/lustre/lnet/selftest/rpc.c index ab8ba3724954..5d8908d258df 100644 --- a/drivers/staging/lustre/lnet/selftest/rpc.c +++ b/drivers/staging/lustre/lnet/selftest/rpc.c @@ -256,7 +256,7 @@ srpc_service_init(struct srpc_service *svc) svc->sv_shuttingdown = 0; svc->sv_cpt_data = cfs_percpt_alloc(lnet_cpt_table(), - sizeof(struct srpc_service_cd)); + sizeof(*svc->sv_cpt_data)); if (!svc->sv_cpt_data) return -ENOMEM; -- cgit v1.2.3 From 017168b5fd913df50a80b65b9c086066f1484a13 Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Mon, 21 Mar 2016 19:52:44 +0530 Subject: Staging: lustre: o2iblnd: Use sizeof type *pointer instead of sizeof type. Use sizeof type *pointer instead of sizeof type. Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c index 0d32e6541a3f..89f939092af4 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c @@ -1968,7 +1968,7 @@ static int kiblnd_net_init_pools(kib_net_t *net, __u32 *cpts, int ncpts) */ net->ibn_fmr_ps = cfs_percpt_alloc(lnet_cpt_table(), - sizeof(kib_fmr_poolset_t)); + sizeof(*net->ibn_fmr_ps)); if (!net->ibn_fmr_ps) { CERROR("Failed to allocate FMR pool array\n"); rc = -ENOMEM; @@ -1992,7 +1992,7 @@ static int kiblnd_net_init_pools(kib_net_t *net, __u32 *cpts, int ncpts) create_tx_pool: net->ibn_tx_ps = cfs_percpt_alloc(lnet_cpt_table(), - sizeof(kib_tx_poolset_t)); + sizeof(*net->ibn_tx_ps)); if (!net->ibn_tx_ps) { CERROR("Failed to allocate tx pool array\n"); rc = -ENOMEM; -- cgit v1.2.3 From a6634f83402c5c8baf636998143f956feecfa770 Mon Sep 17 00:00:00 2001 From: Alison Schofield Date: Mon, 21 Mar 2016 15:39:53 -0700 Subject: staging: iio: use kernel preferred block commenting style Use * on subsequent lines and trailing */ on a separate line in block comments. Signed-off-by: Alison Schofield Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/ad7192.c | 20 ++++++++++---------- drivers/staging/iio/impedance-analyzer/ad5933.c | 5 +++-- drivers/staging/iio/meter/ade7753.c | 3 ++- drivers/staging/iio/meter/ade7754.c | 3 ++- drivers/staging/iio/meter/ade7758_core.c | 3 ++- drivers/staging/iio/meter/ade7759.c | 3 ++- drivers/staging/iio/meter/ade7854.c | 3 ++- 7 files changed, 23 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index f843f19cf675..f91468e20b84 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c @@ -35,10 +35,10 @@ #define AD7192_REG_DATA 3 /* Data Register (RO, 24/32-bit) */ #define AD7192_REG_ID 4 /* ID Register (RO, 8-bit) */ #define AD7192_REG_GPOCON 5 /* GPOCON Register (RO, 8-bit) */ -#define AD7192_REG_OFFSET 6 /* Offset Register (RW, 16-bit - * (AD7792)/24-bit (AD7192)) */ -#define AD7192_REG_FULLSALE 7 /* Full-Scale Register - * (RW, 16-bit (AD7792)/24-bit (AD7192)) */ +#define AD7192_REG_OFFSET 6 /* Offset Register (RW, 16-bit */ + /* (AD7792)/24-bit (AD7192)) */ +#define AD7192_REG_FULLSALE 7 /* Full-Scale Register */ + /* (RW, 16-bit (AD7792)/24-bit (AD7192)) */ /* Communications Register Bit Designations (AD7192_REG_COMM) */ #define AD7192_COMM_WEN BIT(7) /* Write Enable */ @@ -80,13 +80,13 @@ #define AD7192_MODE_CAL_SYS_FULL 7 /* System Full-Scale Calibration */ /* Mode Register: AD7192_MODE_CLKSRC options */ -#define AD7192_CLK_EXT_MCLK1_2 0 /* External 4.92 MHz Clock connected - * from MCLK1 to MCLK2 */ +#define AD7192_CLK_EXT_MCLK1_2 0 /* External 4.92 MHz Clock connected*/ + /* from MCLK1 to MCLK2 */ #define AD7192_CLK_EXT_MCLK2 1 /* External Clock applied to MCLK2 */ -#define AD7192_CLK_INT 2 /* Internal 4.92 MHz Clock not - * available at the MCLK2 pin */ -#define AD7192_CLK_INT_CO 3 /* Internal 4.92 MHz Clock available - * at the MCLK2 pin */ +#define AD7192_CLK_INT 2 /* Internal 4.92 MHz Clock not */ + /* available at the MCLK2 pin */ +#define AD7192_CLK_INT_CO 3 /* Internal 4.92 MHz Clock available*/ + /* at the MCLK2 pin */ /* Configuration Register Bit Designations (AD7192_REG_CONF) */ diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index 620b33a61a2d..e6fdb3d54e25 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c @@ -691,8 +691,9 @@ static void ad5933_work(struct work_struct *work) } if (status & AD5933_STAT_SWEEP_DONE) { - /* last sample received - power down do nothing until - * the ring enable is toggled */ + /* last sample received - power down do + * nothing until the ring enable is toggled + */ ad5933_cmd(st, AD5933_CTRL_POWER_DOWN); } else { /* we just received a valid datum, move on to the next */ diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c index b0bc99a958c5..4b5f05fdadcd 100644 --- a/drivers/staging/iio/meter/ade7753.c +++ b/drivers/staging/iio/meter/ade7753.c @@ -333,7 +333,8 @@ static int ade7753_set_irq(struct device *dev, bool enable) if (enable) irqen |= BIT(3); /* Enables an interrupt when a data is - present in the waveform register */ + * present in the waveform register + */ else irqen &= ~BIT(3); diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c index fed11804d548..c46bef641613 100644 --- a/drivers/staging/iio/meter/ade7754.c +++ b/drivers/staging/iio/meter/ade7754.c @@ -351,7 +351,8 @@ static int ade7754_set_irq(struct device *dev, bool enable) if (enable) irqen |= BIT(14); /* Enables an interrupt when a data is - present in the waveform register */ + * present in the waveform register + */ else irqen &= ~BIT(14); diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c index 310296573e52..ebb8a1993303 100644 --- a/drivers/staging/iio/meter/ade7758_core.c +++ b/drivers/staging/iio/meter/ade7758_core.c @@ -413,7 +413,8 @@ int ade7758_set_irq(struct device *dev, bool enable) if (enable) irqen |= BIT(16); /* Enables an interrupt when a data is - present in the waveform register */ + * present in the waveform register + */ else irqen &= ~BIT(16); diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c index c14892db7e4c..80144d40d9ca 100644 --- a/drivers/staging/iio/meter/ade7759.c +++ b/drivers/staging/iio/meter/ade7759.c @@ -289,7 +289,8 @@ static int ade7759_set_irq(struct device *dev, bool enable) if (enable) irqen |= BIT(3); /* Enables an interrupt when a data is - present in the waveform register */ + * present in the waveform register + */ else irqen &= ~BIT(3); diff --git a/drivers/staging/iio/meter/ade7854.c b/drivers/staging/iio/meter/ade7854.c index 9e439af7100d..75e8685e6df2 100644 --- a/drivers/staging/iio/meter/ade7854.c +++ b/drivers/staging/iio/meter/ade7854.c @@ -421,7 +421,8 @@ static int ade7854_set_irq(struct device *dev, bool enable) if (enable) irqen |= BIT(17); /* 1: interrupt enabled when all periodical - (at 8 kHz rate) DSP computations finish. */ + * (at 8 kHz rate) DSP computations finish. + */ else irqen &= ~BIT(17); -- cgit v1.2.3 From 968b4e6bd3b00c3c05715f916e27439ff71c737d Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Sat, 19 Mar 2016 11:44:05 +0530 Subject: Staging: netlogic: Remove & from function name. Remove & from function name,when function name passed as an argument to another function. Function name is used as pointer without &. Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/netlogic/xlr_net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/netlogic/xlr_net.c b/drivers/staging/netlogic/xlr_net.c index aa1cdf602cf6..99445d0fcf9c 100644 --- a/drivers/staging/netlogic/xlr_net.c +++ b/drivers/staging/netlogic/xlr_net.c @@ -850,7 +850,7 @@ static int xlr_mii_probe(struct xlr_net_priv *priv) /* Attach MAC to PHY */ phydev = phy_connect(priv->ndev, phydev_name(phydev), - &xlr_gmac_link_adjust, priv->nd->phy_interface); + xlr_gmac_link_adjust, priv->nd->phy_interface); if (IS_ERR(phydev)) { pr_err("could not attach PHY\n"); -- cgit v1.2.3 From 6c1c9f9d5a079f3139d4dd34836da6eb49cbd5d4 Mon Sep 17 00:00:00 2001 From: Ben Marsh Date: Mon, 14 Mar 2016 17:40:20 +0100 Subject: Staging: rtl8192u: remove extra blank lines. This patch removes blank lines in r8192U_wx.c that were flagged by checkpatch.pl Signed-off-by: Ben Marsh Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/r8192U_wx.c | 22 ---------------------- 1 file changed, 22 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192u/r8192U_wx.c b/drivers/staging/rtl8192u/r8192U_wx.c index f828e6441f2d..837704de3ea4 100644 --- a/drivers/staging/rtl8192u/r8192U_wx.c +++ b/drivers/staging/rtl8192u/r8192U_wx.c @@ -30,7 +30,6 @@ static const u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000, 6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000}; - #ifndef ENETDOWN #define ENETDOWN 1 #endif @@ -44,7 +43,6 @@ static int r8192_wx_get_freq(struct net_device *dev, return ieee80211_wx_get_freq(priv->ieee80211, a, wrqu, b); } - static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a, union iwreq_data *wrqu, char *b) { @@ -53,8 +51,6 @@ static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a, return ieee80211_wx_get_mode(priv->ieee80211, a, wrqu, b); } - - static int r8192_wx_get_rate(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) @@ -64,8 +60,6 @@ static int r8192_wx_get_rate(struct net_device *dev, return ieee80211_wx_get_rate(priv->ieee80211, info, wrqu, extra); } - - static int r8192_wx_set_rate(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) @@ -82,7 +76,6 @@ static int r8192_wx_set_rate(struct net_device *dev, return ret; } - static int r8192_wx_set_rts(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) @@ -148,7 +141,6 @@ static int r8192_wx_force_reset(struct net_device *dev, } - static int r8192_wx_set_rawtx(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) @@ -301,7 +293,6 @@ static int rtl8180_wx_get_range(struct net_device *dev, /* range->min_r_time; */ /* Minimal retry lifetime */ /* range->max_r_time; */ /* Maximal retry lifetime */ - for (i = 0, val = 0; i < 14; i++) { /* Include only legal frequencies for some countries */ @@ -326,7 +317,6 @@ static int rtl8180_wx_get_range(struct net_device *dev, return 0; } - static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a, union iwreq_data *wrqu, char *b) { @@ -396,9 +386,6 @@ static int r8192_wx_set_essid(struct net_device *dev, return ret; } - - - static int r8192_wx_get_essid(struct net_device *dev, struct iw_request_info *a, union iwreq_data *wrqu, char *b) @@ -415,7 +402,6 @@ static int r8192_wx_get_essid(struct net_device *dev, return ret; } - static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a, union iwreq_data *wrqu, char *b) { @@ -439,7 +425,6 @@ static int r8192_wx_get_name(struct net_device *dev, return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra); } - static int r8192_wx_set_frag(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) @@ -493,7 +478,6 @@ static int r8192_wx_set_wap(struct net_device *dev, } - static int r8192_wx_get_wap(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) @@ -503,7 +487,6 @@ static int r8192_wx_get_wap(struct net_device *dev, return ieee80211_wx_get_wap(priv->ieee80211, info, wrqu, extra); } - static int r8192_wx_get_enc(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *key) @@ -695,7 +678,6 @@ static int r8192_wx_get_retry(struct net_device *dev, wrqu->retry.value = priv->retry_data; } - return 0; } @@ -711,7 +693,6 @@ static int r8192_wx_get_sens(struct net_device *dev, return 0; } - static int r8192_wx_set_sens(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) @@ -862,7 +843,6 @@ static int dummy(struct net_device *dev, struct iw_request_info *a, return -1; } - static iw_handler r8192_wx_handlers[] = { NULL, /* SIOCSIWCOMMIT */ r8192_wx_get_name, /* SIOCGIWNAME */ @@ -949,7 +929,6 @@ static const struct iw_priv_args r8192_private_args[] = { }; - static iw_handler r8192_private_handler[] = { r8192_wx_set_crcmon, r8192_wx_set_scan_type, @@ -985,7 +964,6 @@ struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev) return wstats; } - struct iw_handler_def r8192_wx_handlers_def = { .standard = r8192_wx_handlers, .num_standard = ARRAY_SIZE(r8192_wx_handlers), -- cgit v1.2.3 From 46347b3e096c649adcbe902798eb31c47ad5637c Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Fri, 18 Mar 2016 09:15:45 +0530 Subject: Staging: rtl8192u: Remove unnecessary semicolon. Remove unnecessary semicolon.This issue is found by coccinelle script. Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/r8190_rtl8256.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192u/r8190_rtl8256.c b/drivers/staging/rtl8192u/r8190_rtl8256.c index 5c3bb3be2720..d733fb2ade91 100644 --- a/drivers/staging/rtl8192u/r8190_rtl8256.c +++ b/drivers/staging/rtl8192u/r8190_rtl8256.c @@ -194,7 +194,7 @@ void phy_RF8256_Config_ParaFile(struct net_device *dev) break; } - /*----Restore RFENV control type----*/; + /*----Restore RFENV control type----*/ switch (eRFPath) { case RF90_PATH_A: case RF90_PATH_C: -- cgit v1.2.3 From 58493d8e405e6ebe530d04f97bfe32724608c89e Mon Sep 17 00:00:00 2001 From: Nik Nyby Date: Sun, 20 Mar 2016 15:46:35 -0400 Subject: staging: rtl8192u: fix typo in debug message This fixes a mis-spelled word in a few debug statements. Signed-off-by: Nik Nyby Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c | 2 +- drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c index f18fc0b6775b..051c2be842d0 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c @@ -746,7 +746,7 @@ static void RxReorderIndicatePacket(struct ieee80211_device *ieee, // Indicate packets if(index>REORDER_WIN_SIZE){ - IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): Rx Reorer buffer full!! \n"); + IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): Rx Reorder buffer full!! \n"); kfree(prxbIndicateArray); return; } diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c index 148d0d45547b..6033502eff3d 100644 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c +++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c @@ -75,7 +75,7 @@ static void RxPktPendingTimeout(unsigned long data) // Indicate packets if(index > REORDER_WIN_SIZE){ - IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): Rx Reorer buffer full!! \n"); + IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): Rx Reorder buffer full!! \n"); spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags); return; } -- cgit v1.2.3 From 13c1cce614d339ab369b9c2b10bc2a2d49ad3f6b Mon Sep 17 00:00:00 2001 From: Edward Lipinsky Date: Sat, 12 Mar 2016 11:45:44 -0800 Subject: staging: rtl8723au: Fix line longer than 80 columns. This patch fixes the checkpatch.pl warning: WARNING: line over 80 characters Signed-off-by: Edward Lipinsky Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_ap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8723au/core/rtw_ap.c b/drivers/staging/rtl8723au/core/rtw_ap.c index f68e2770255d..aad686da3cf0 100644 --- a/drivers/staging/rtl8723au/core/rtw_ap.c +++ b/drivers/staging/rtl8723au/core/rtw_ap.c @@ -1719,7 +1719,8 @@ void stop_ap_mode23a(struct rtw_adapter *padapter) } spin_unlock_bh(&pacl_node_q->lock); - DBG_8723A("%s, free acl_node_queue, num =%d\n", __func__, pacl_list->num); + DBG_8723A("%s, free acl_node_queue, num =%d\n", + __func__, pacl_list->num); rtw_sta_flush23a(padapter); -- cgit v1.2.3 From 299ccc8a07b79199b79bcfb3f701866f10b42063 Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Fri, 18 Mar 2016 09:26:02 +0530 Subject: Staging: rtl8723au: rtl8723a_rf6052: Remove unnecessary semicolon. Remove unnecessary semicolon. Coccinelle sementic patch as follows: @r_case@ position p; @@ switch (...) { case ...: ...;@p } @r_default@ position p; @@ switch (...) { default: ...;@p } @r1@ statement S; position p1; position p != {r_case.p, r_default.p}; identifier label; @@ ( label:; | S@p1;@p ) Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/rtl8723a_rf6052.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_rf6052.c b/drivers/staging/rtl8723au/hal/rtl8723a_rf6052.c index ce0d8d894787..24c0ff3d82bc 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_rf6052.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_rf6052.c @@ -465,7 +465,7 @@ static int phy_RF6052_Config_ParaFile(struct rtw_adapter *Adapter) break; } - /*----Restore RFENV control type----*/; + /*----Restore RFENV control type----*/ switch (eRFPath) { case RF_PATH_A: PHY_SetBBReg(Adapter, pPhyReg->rfintfs, -- cgit v1.2.3 From 9555ece315c7809f32ca5bdb8eb19d8160b91517 Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Sat, 19 Mar 2016 10:47:47 +0530 Subject: Staging: rtl8723au: Remove unnecessary return statement. Remove unnecessary return statement. Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c b/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c index e81301fcb01d..1ea0af499ce9 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c @@ -1175,8 +1175,6 @@ int InitLLTTable23a(struct rtw_adapter *padapter, u32 boundary) /* Let last entry point to the start entry of ring buffer */ status = _LLTWrite(padapter, Last_Entry_Of_TxPktBuf, txpktbuf_bndy); - if (status != _SUCCESS) - return status; return status; } -- cgit v1.2.3 From d08073d92463820bcebf8594279c635a793f6772 Mon Sep 17 00:00:00 2001 From: Bhaktipriya Shridhar Date: Fri, 18 Mar 2016 23:26:18 +0530 Subject: staging: rtl8712: rtl871x_ioctl_set: Remove unused macro Removed Unused macro IS_MAC_ADDRESS_BROADCAST. Grep'd to find occurences. Signed-off-by: Bhaktipriya Shridhar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/rtl871x_ioctl_set.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_set.c b/drivers/staging/rtl8712/rtl871x_ioctl_set.c index f772675ae9cd..56760cda8e89 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_set.c +++ b/drivers/staging/rtl8712/rtl871x_ioctl_set.c @@ -34,12 +34,6 @@ #include "usb_osintf.h" #include "usb_ops.h" -#define IS_MAC_ADDRESS_BROADCAST(addr) \ -( \ - ((addr[0] == 0xff) && (addr[1] == 0xff) && \ - (addr[2] == 0xff) && (addr[3] == 0xff) && \ - (addr[4] == 0xff) && (addr[5] == 0xff)) ? true : false \ -) static u8 validate_ssid(struct ndis_802_11_ssid *ssid) { -- cgit v1.2.3 From b7af4e6cc7f8f1b69e20ebd25cb633e30de4799e Mon Sep 17 00:00:00 2001 From: Bhaktipriya Shridhar Date: Mon, 21 Mar 2016 01:23:17 +0530 Subject: staging: rtl8712: os_intfs: Change form of NULL comparisons Change null comparisons of the form x == NULL to !x. This was done using Coccinelle. @@ expression e; @@ - e == NULL + !e Signed-off-by: Bhaktipriya Shridhar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/os_intfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8712/os_intfs.c b/drivers/staging/rtl8712/os_intfs.c index ab19112eae13..57211f7e68a5 100644 --- a/drivers/staging/rtl8712/os_intfs.c +++ b/drivers/staging/rtl8712/os_intfs.c @@ -389,7 +389,7 @@ static int netdev_open(struct net_device *pnetdev) padapter->bup = true; if (rtl871x_hal_init(padapter) != _SUCCESS) goto netdev_open_error; - if (r8712_initmac == NULL) + if (!r8712_initmac) /* Use the mac address stored in the Efuse */ memcpy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr, ETH_ALEN); @@ -413,7 +413,7 @@ static int netdev_open(struct net_device *pnetdev) } if (start_drv_threads(padapter) != _SUCCESS) goto netdev_open_error; - if (padapter->dvobjpriv.inirp_init == NULL) + if (!padapter->dvobjpriv.inirp_init) goto netdev_open_error; else padapter->dvobjpriv.inirp_init(padapter); -- cgit v1.2.3 From ddf6451ff98c5139c63639db826df540173db2d5 Mon Sep 17 00:00:00 2001 From: Bhaktipriya Shridhar Date: Mon, 21 Mar 2016 02:08:36 +0530 Subject: staging: rtl8712: usb_ops_linux: Clean up tests if NULL returned on failure Some functions like kmalloc/kzalloc return NULL on failure. When NULL represents failure, !x is commonly used. This was done using Coccinelle: @@ expression *e; identifier l1; @@ e = \(kmalloc\|kzalloc\|kcalloc\|devm_kzalloc\)(...); ... - e == NULL + !e Signed-off-by: Bhaktipriya Shridhar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/usb_ops_linux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8712/usb_ops_linux.c b/drivers/staging/rtl8712/usb_ops_linux.c index 454cdf6c7fa1..6f12345709c2 100644 --- a/drivers/staging/rtl8712/usb_ops_linux.c +++ b/drivers/staging/rtl8712/usb_ops_linux.c @@ -504,7 +504,7 @@ int r8712_usbctrl_vendorreq(struct intf_priv *pintfpriv, u8 request, u16 value, u8 *palloc_buf, *pIo_buf; palloc_buf = kmalloc((u32)len + 16, GFP_ATOMIC); - if (palloc_buf == NULL) + if (!palloc_buf) return -ENOMEM; pIo_buf = palloc_buf + 16 - ((addr_t)(palloc_buf) & 0x0f); if (requesttype == 0x01) { -- cgit v1.2.3 From 670e3fef68b82a0d43200fcbb3588c7ffa46ca08 Mon Sep 17 00:00:00 2001 From: Bhaktipriya Shridhar Date: Mon, 21 Mar 2016 02:09:17 +0530 Subject: staging: rtl8712: rtl871x_mlme: Clean up tests if NULL returned on failure Some functions like kmalloc/kzalloc return NULL on failure. When NULL represents failure, !x is commonly used. This was done using Coccinelle: @@ expression *e; identifier l1; @@ e = \(kmalloc\|kzalloc\|kcalloc\|devm_kzalloc\)(...); ... - e == NULL + !e Signed-off-by: Bhaktipriya Shridhar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/rtl871x_mlme.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8712/rtl871x_mlme.c b/drivers/staging/rtl8712/rtl871x_mlme.c index 62d4ae85af15..f8b1c8960192 100644 --- a/drivers/staging/rtl8712/rtl871x_mlme.c +++ b/drivers/staging/rtl8712/rtl871x_mlme.c @@ -1205,7 +1205,7 @@ sint r8712_set_auth(struct _adapter *adapter, return _FAIL; psetauthparm = kzalloc(sizeof(*psetauthparm), GFP_ATOMIC); - if (psetauthparm == NULL) { + if (!psetauthparm) { kfree(pcmd); return _FAIL; } @@ -1234,7 +1234,7 @@ sint r8712_set_key(struct _adapter *adapter, if (!pcmd) return _FAIL; psetkeyparm = kzalloc(sizeof(*psetkeyparm), GFP_ATOMIC); - if (psetkeyparm == NULL) { + if (!psetkeyparm) { ret = _FAIL; goto err_free_cmd; } -- cgit v1.2.3 From b1d055005519985784f9a613df81b8dd928c0090 Mon Sep 17 00:00:00 2001 From: Bhaktipriya Shridhar Date: Mon, 21 Mar 2016 02:09:49 +0530 Subject: staging: rtl8712: rtl871x_cmd: Clean up tests if NULL returned on failure Some functions like kmalloc/kzalloc return NULL on failure. When NULL represents failure, !x is commonly used. This was done using Coccinelle: @@ expression *e; identifier l1; @@ e = \(kmalloc\|kzalloc\|kcalloc\|devm_kzalloc\)(...); ... - e == NULL + !e Signed-off-by: Bhaktipriya Shridhar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/rtl871x_cmd.c | 80 +++++++++++++++++------------------ 1 file changed, 40 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8712/rtl871x_cmd.c b/drivers/staging/rtl8712/rtl871x_cmd.c index 86136cc73672..aed03cfbb1ba 100644 --- a/drivers/staging/rtl8712/rtl871x_cmd.c +++ b/drivers/staging/rtl8712/rtl871x_cmd.c @@ -225,10 +225,10 @@ u8 r8712_sitesurvey_cmd(struct _adapter *padapter, struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (ph2c == NULL) + if (!ph2c) return _FAIL; psurveyPara = kmalloc(sizeof(*psurveyPara), GFP_ATOMIC); - if (psurveyPara == NULL) { + if (!psurveyPara) { kfree(ph2c); return _FAIL; } @@ -258,10 +258,10 @@ u8 r8712_setdatarate_cmd(struct _adapter *padapter, u8 *rateset) struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (ph2c == NULL) + if (!ph2c) return _FAIL; pbsetdataratepara = kmalloc(sizeof(*pbsetdataratepara), GFP_ATOMIC); - if (pbsetdataratepara == NULL) { + if (!pbsetdataratepara) { kfree(ph2c); return _FAIL; } @@ -280,10 +280,10 @@ u8 r8712_set_chplan_cmd(struct _adapter *padapter, int chplan) struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (ph2c == NULL) + if (!ph2c) return _FAIL; psetchplanpara = kmalloc(sizeof(*psetchplanpara), GFP_ATOMIC); - if (psetchplanpara == NULL) { + if (!psetchplanpara) { kfree(ph2c); return _FAIL; } @@ -301,10 +301,10 @@ u8 r8712_setbasicrate_cmd(struct _adapter *padapter, u8 *rateset) struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (ph2c == NULL) + if (!ph2c) return _FAIL; pssetbasicratepara = kmalloc(sizeof(*pssetbasicratepara), GFP_ATOMIC); - if (pssetbasicratepara == NULL) { + if (!pssetbasicratepara) { kfree(ph2c); return _FAIL; } @@ -322,10 +322,10 @@ u8 r8712_setfwdig_cmd(struct _adapter *padapter, u8 type) struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (ph2c == NULL) + if (!ph2c) return _FAIL; pwriteptmparm = kmalloc(sizeof(*pwriteptmparm), GFP_ATOMIC); - if (pwriteptmparm == NULL) { + if (!pwriteptmparm) { kfree(ph2c); return _FAIL; } @@ -342,10 +342,10 @@ u8 r8712_setfwra_cmd(struct _adapter *padapter, u8 type) struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (ph2c == NULL) + if (!ph2c) return _FAIL; pwriteptmparm = kmalloc(sizeof(*pwriteptmparm), GFP_ATOMIC); - if (pwriteptmparm == NULL) { + if (!pwriteptmparm) { kfree(ph2c); return _FAIL; } @@ -362,10 +362,10 @@ u8 r8712_setrfreg_cmd(struct _adapter *padapter, u8 offset, u32 val) struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (ph2c == NULL) + if (!ph2c) return _FAIL; pwriterfparm = kmalloc(sizeof(*pwriterfparm), GFP_ATOMIC); - if (pwriterfparm == NULL) { + if (!pwriterfparm) { kfree(ph2c); return _FAIL; } @@ -383,10 +383,10 @@ u8 r8712_getrfreg_cmd(struct _adapter *padapter, u8 offset, u8 *pval) struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (ph2c == NULL) + if (!ph2c) return _FAIL; prdrfparm = kmalloc(sizeof(*prdrfparm), GFP_ATOMIC); - if (prdrfparm == NULL) { + if (!prdrfparm) { kfree(ph2c); return _FAIL; } @@ -427,7 +427,7 @@ u8 r8712_createbss_cmd(struct _adapter *padapter) padapter->ledpriv.LedControlHandler(padapter, LED_CTL_START_TO_LINK); pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC); - if (pcmd == NULL) + if (!pcmd) return _FAIL; INIT_LIST_HEAD(&pcmd->list); pcmd->cmdcode = _CreateBss_CMD_; @@ -457,7 +457,7 @@ u8 r8712_joinbss_cmd(struct _adapter *padapter, struct wlan_network *pnetwork) padapter->ledpriv.LedControlHandler(padapter, LED_CTL_START_TO_LINK); pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC); - if (pcmd == NULL) + if (!pcmd) return _FAIL; /* for hidden ap to set fw_state here */ @@ -587,10 +587,10 @@ u8 r8712_disassoc_cmd(struct _adapter *padapter) /* for sta_mode */ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; pdisconnect_cmd = kmalloc(sizeof(*pdisconnect_cmd), GFP_ATOMIC); - if (pdisconnect_cmd == NULL) + if (!pdisconnect_cmd) return _FAIL; pdisconnect = kmalloc(sizeof(*pdisconnect), GFP_ATOMIC); - if (pdisconnect == NULL) { + if (!pdisconnect) { kfree(pdisconnect_cmd); return _FAIL; } @@ -609,10 +609,10 @@ u8 r8712_setopmode_cmd(struct _adapter *padapter, struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (ph2c == NULL) + if (!ph2c) return _FAIL; psetop = kmalloc(sizeof(*psetop), GFP_ATOMIC); - if (psetop == NULL) { + if (!psetop) { kfree(ph2c); return _FAIL; } @@ -633,15 +633,15 @@ u8 r8712_setstakey_cmd(struct _adapter *padapter, u8 *psta, u8 unicast_key) struct sta_info *sta = (struct sta_info *)psta; ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (ph2c == NULL) + if (!ph2c) return _FAIL; psetstakey_para = kmalloc(sizeof(*psetstakey_para), GFP_ATOMIC); - if (psetstakey_para == NULL) { + if (!psetstakey_para) { kfree(ph2c); return _FAIL; } psetstakey_rsp = kmalloc(sizeof(*psetstakey_rsp), GFP_ATOMIC); - if (psetstakey_rsp == NULL) { + if (!psetstakey_rsp) { kfree(ph2c); kfree(psetstakey_para); return _FAIL; @@ -673,10 +673,10 @@ u8 r8712_setrfintfs_cmd(struct _adapter *padapter, u8 mode) struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (ph2c == NULL) + if (!ph2c) return _FAIL; psetrfintfsparm = kmalloc(sizeof(*psetrfintfsparm), GFP_ATOMIC); - if (psetrfintfsparm == NULL) { + if (!psetrfintfsparm) { kfree(ph2c); return _FAIL; } @@ -695,10 +695,10 @@ u8 r8712_setrttbl_cmd(struct _adapter *padapter, struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (ph2c == NULL) + if (!ph2c) return _FAIL; psetrttblparm = kmalloc(sizeof(*psetrttblparm), GFP_ATOMIC); - if (psetrttblparm == NULL) { + if (!psetrttblparm) { kfree(ph2c); return _FAIL; } @@ -716,10 +716,10 @@ u8 r8712_setMacAddr_cmd(struct _adapter *padapter, u8 *mac_addr) struct SetMacAddr_param *psetMacAddr_para; ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (ph2c == NULL) + if (!ph2c) return _FAIL; psetMacAddr_para = kmalloc(sizeof(*psetMacAddr_para), GFP_ATOMIC); - if (psetMacAddr_para == NULL) { + if (!psetMacAddr_para) { kfree(ph2c); return _FAIL; } @@ -738,15 +738,15 @@ u8 r8712_setassocsta_cmd(struct _adapter *padapter, u8 *mac_addr) struct set_assocsta_rsp *psetassocsta_rsp = NULL; ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (ph2c == NULL) + if (!ph2c) return _FAIL; psetassocsta_para = kmalloc(sizeof(*psetassocsta_para), GFP_ATOMIC); - if (psetassocsta_para == NULL) { + if (!psetassocsta_para) { kfree(ph2c); return _FAIL; } psetassocsta_rsp = kmalloc(sizeof(*psetassocsta_rsp), GFP_ATOMIC); - if (psetassocsta_rsp == NULL) { + if (!psetassocsta_rsp) { kfree(ph2c); kfree(psetassocsta_para); return _FAIL; @@ -766,10 +766,10 @@ u8 r8712_addbareq_cmd(struct _adapter *padapter, u8 tid) struct addBaReq_parm *paddbareq_parm; ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (ph2c == NULL) + if (!ph2c) return _FAIL; paddbareq_parm = kmalloc(sizeof(*paddbareq_parm), GFP_ATOMIC); - if (paddbareq_parm == NULL) { + if (!paddbareq_parm) { kfree(ph2c); return _FAIL; } @@ -787,10 +787,10 @@ u8 r8712_wdg_wk_cmd(struct _adapter *padapter) struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (ph2c == NULL) + if (!ph2c) return _FAIL; pdrvintcmd_param = kmalloc(sizeof(*pdrvintcmd_param), GFP_ATOMIC); - if (pdrvintcmd_param == NULL) { + if (!pdrvintcmd_param) { kfree(ph2c); return _FAIL; } @@ -961,10 +961,10 @@ u8 r8712_disconnectCtrlEx_cmd(struct _adapter *adapter, u32 enableDrvCtrl, struct cmd_priv *pcmdpriv = &adapter->cmdpriv; ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (ph2c == NULL) + if (!ph2c) return _FAIL; param = kzalloc(sizeof(*param), GFP_ATOMIC); - if (param == NULL) { + if (!param) { kfree(ph2c); return _FAIL; } -- cgit v1.2.3 From 0b90c305c93e4e94e80d7f10091867e28f275d37 Mon Sep 17 00:00:00 2001 From: Bhaktipriya Shridhar Date: Mon, 21 Mar 2016 02:10:21 +0530 Subject: staging: rtl8712: rtl871x_ioctl_linux: Clean up tests if NULL returned on failure Some functions like kmalloc/kzalloc return NULL on failure. When NULL represents failure, !x is commonly used. This was done using Coccinelle: @@ expression *e; identifier l1; @@ e = \(kmalloc\|kzalloc\|kcalloc\|devm_kzalloc\)(...); ... - e == NULL + !e Signed-off-by: Bhaktipriya Shridhar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/rtl871x_ioctl_linux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c index 1b9e24900477..6c02e9b29e2d 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c +++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c @@ -399,7 +399,7 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, if (wep_key_len > 0) { wep_key_len = wep_key_len <= 5 ? 5 : 13; pwep = kzalloc(sizeof(*pwep), GFP_ATOMIC); - if (pwep == NULL) + if (!pwep) return -ENOMEM; pwep->KeyLength = wep_key_len; pwep->Length = wep_key_len + @@ -1793,7 +1793,7 @@ static int r871x_wx_set_enc_ext(struct net_device *dev, param_len = sizeof(struct ieee_param) + pext->key_len; param = kzalloc(param_len, GFP_ATOMIC); - if (param == NULL) + if (!param) return -ENOMEM; param->cmd = IEEE_CMD_SET_ENCRYPTION; eth_broadcast_addr(param->sta_addr); -- cgit v1.2.3 From b2def44cf0616f600636e36f8376061804b83e62 Mon Sep 17 00:00:00 2001 From: Parth Sane Date: Tue, 22 Mar 2016 05:11:00 +0530 Subject: staging: rtl8712: Fixed FSF address warning in basic_types.h Fixed checkpatch warning after removing FSF address paragraph as per guidelines. Signed-off-by: Parth Sane Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/basic_types.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8712/basic_types.h b/drivers/staging/rtl8712/basic_types.h index 7561bed5dd44..f5c0231891b1 100644 --- a/drivers/staging/rtl8712/basic_types.h +++ b/drivers/staging/rtl8712/basic_types.h @@ -11,10 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * Modifications for inclusion into the Linux staging tree are * Copyright(c) 2010 Larry Finger. All rights reserved. * -- cgit v1.2.3 From 501ef12a74a51ffa1a1fe9057565c450be564050 Mon Sep 17 00:00:00 2001 From: Parth Sane Date: Tue, 22 Mar 2016 05:11:01 +0530 Subject: staging: rtl8712: Fixed FSF address warning in drv_types.h Fixed checkpatch warning after removing FSF address block as per guidelines. Signed-off-by: Parth Sane Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/drv_types.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8712/drv_types.h b/drivers/staging/rtl8712/drv_types.h index 29e47e1501c5..ae79047ac6dc 100644 --- a/drivers/staging/rtl8712/drv_types.h +++ b/drivers/staging/rtl8712/drv_types.h @@ -11,10 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * Modifications for inclusion into the Linux staging tree are * Copyright(c) 2010 Larry Finger. All rights reserved. * -- cgit v1.2.3 From c7838db04dc9a6921d3e3771c2deefe9dfe7c1a9 Mon Sep 17 00:00:00 2001 From: Parth Sane Date: Tue, 22 Mar 2016 05:11:02 +0530 Subject: staging: rtl8712: Fixed FSF address warning in ethernet.h Fixed checkpatch warning after removing FSF address block as per guidelines. Signed-off-by: Parth Sane Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/ethernet.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8712/ethernet.h b/drivers/staging/rtl8712/ethernet.h index fad173f4097e..039da36fad3d 100644 --- a/drivers/staging/rtl8712/ethernet.h +++ b/drivers/staging/rtl8712/ethernet.h @@ -11,10 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * Modifications for inclusion into the Linux staging tree are * Copyright(c) 2010 Larry Finger. All rights reserved. * -- cgit v1.2.3 From e8aad70c97ba280152463f6cb4f5e6ee2dd8e230 Mon Sep 17 00:00:00 2001 From: Parth Sane Date: Tue, 22 Mar 2016 05:11:03 +0530 Subject: staging: rtl8712: Fixed FSF address warning in hal_init.c Fixed checkpatch warning after removing FSF address block as per guidelines. Signed-off-by: Parth Sane Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/hal_init.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8712/hal_init.c b/drivers/staging/rtl8712/hal_init.c index 37fe0a4db602..0c76fbc3e702 100644 --- a/drivers/staging/rtl8712/hal_init.c +++ b/drivers/staging/rtl8712/hal_init.c @@ -13,10 +13,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * Modifications for inclusion into the Linux staging tree are * Copyright(c) 2010 Larry Finger. All rights reserved. * -- cgit v1.2.3 From 5ab2ce4305eb3c3b2dff7834993b1f6fb0c409be Mon Sep 17 00:00:00 2001 From: Parth Sane Date: Tue, 22 Mar 2016 05:11:04 +0530 Subject: staging: rtl8712: Fixed FSF address warning in ieee80211.c Fixed checkpatch warning after removing FSF address block as per guidelines. Signed-off-by: Parth Sane Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/ieee80211.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8712/ieee80211.c b/drivers/staging/rtl8712/ieee80211.c index d13b4d53c256..8918654b44ed 100644 --- a/drivers/staging/rtl8712/ieee80211.c +++ b/drivers/staging/rtl8712/ieee80211.c @@ -13,10 +13,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * Modifications for inclusion into the Linux staging tree are * Copyright(c) 2010 Larry Finger. All rights reserved. * -- cgit v1.2.3 From b5e12ec38331256c3055591031ee96454c868209 Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Mon, 21 Mar 2016 19:49:51 +0530 Subject: Staging: rtl8188eu: rtw_efuse: Use sizeof type *pointer instead of sizeof type. Use sizeof type *pointer instead of sizeof type. Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_efuse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8188eu/core/rtw_efuse.c b/drivers/staging/rtl8188eu/core/rtw_efuse.c index fbce1f7e68ca..c17870cddb5b 100644 --- a/drivers/staging/rtl8188eu/core/rtw_efuse.c +++ b/drivers/staging/rtl8188eu/core/rtw_efuse.c @@ -102,7 +102,7 @@ efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 _size_byte, u8 *pbuf) if (!efuseTbl) return; - eFuseWord = (u16 **)rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16)); + eFuseWord = (u16 **)rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(*eFuseWord)); if (!eFuseWord) { DBG_88E("%s: alloc eFuseWord fail!\n", __func__); goto eFuseWord_failed; -- cgit v1.2.3 From 78822dc3c371ba7a909de72525ee176f78ea236c Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Mon, 14 Mar 2016 22:45:13 +0200 Subject: Staging: wlan-ng: defined oui_rfc1042[] and oui_8021h[] arrays as const arrays This patch defines oui_rfc1042[] and oui_8021h[] arrays from p80211conv.c as const arrays since these are not changed anywhere in code. Signed-off-by: Claudiu Beznea Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/p80211conv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wlan-ng/p80211conv.c b/drivers/staging/wlan-ng/p80211conv.c index 0a8f3960d465..bdb50a51483b 100644 --- a/drivers/staging/wlan-ng/p80211conv.c +++ b/drivers/staging/wlan-ng/p80211conv.c @@ -75,8 +75,8 @@ #include "p80211ioctl.h" #include "p80211req.h" -static u8 oui_rfc1042[] = { 0x00, 0x00, 0x00 }; -static u8 oui_8021h[] = { 0x00, 0x00, 0xf8 }; +static const u8 oui_rfc1042[] = { 0x00, 0x00, 0x00 }; +static const u8 oui_8021h[] = { 0x00, 0x00, 0xf8 }; /*---------------------------------------------------------------- * p80211pb_ether_to_80211 -- cgit v1.2.3 From f3dbe30655a651cd846303ecc7d5c5176c00a023 Mon Sep 17 00:00:00 2001 From: Sandhya Bankar Date: Mon, 21 Mar 2016 20:46:15 +0530 Subject: Staging: wlan-ng: Use x instead of x != NULL. Use x instead of x != NULL.This issue is detected by checkpatch.pl script. Signed-off-by: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/p80211netdev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c index 88255ce2871b..fdfc82152312 100644 --- a/drivers/staging/wlan-ng/p80211netdev.c +++ b/drivers/staging/wlan-ng/p80211netdev.c @@ -156,7 +156,7 @@ static int p80211knetdev_open(netdevice_t *netdev) return -ENODEV; /* Tell the MSD to open */ - if (wlandev->open != NULL) { + if (wlandev->open) { result = wlandev->open(wlandev); if (result == 0) { netif_start_queue(wlandev->netdev); @@ -186,7 +186,7 @@ static int p80211knetdev_stop(netdevice_t *netdev) int result = 0; wlandevice_t *wlandev = netdev->ml_priv; - if (wlandev->close != NULL) + if (wlandev->close) result = wlandev->close(wlandev); netif_stop_queue(wlandev->netdev); -- cgit v1.2.3 From f6b1160eb27f990cc1c48b67a5f83cb63115284e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 17 Mar 2016 10:10:40 -0700 Subject: staging: comedi: dt282x: tidy up register bit defines Arnd Bergmann pointed out that gcc-6 warns about passing negative signed integer into swab16() due to the macro expansion of 'outw'. It appears that the register map constants are causing the warnings. Actually, it might just be the (1 << 15) ones... Convert all the constants as suggested by checkpatch.pl: CHECK: Prefer using the BIT macro The BIT() macro will make all the constants explicitly 'unsigned', which helps to avoid the warning. Fix the, unsused, DT2821_CHANCSR_PRESLA() macro. The "Present List Address" (PRESLA) bits in the CHANCSR register are read only. This define was meant to extract the bits from the read value. Signed-off-by: H Hartley Sweeten Reported-by: Arnd Bergmann Reviewed-by: Ian Abbott Tested-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt282x.c | 65 +++++++++++++++++---------------- 1 file changed, 33 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index 40bf00984fa5..06a87a10a2d0 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -69,48 +69,49 @@ * Register map */ #define DT2821_ADCSR_REG 0x00 -#define DT2821_ADCSR_ADERR (1 << 15) -#define DT2821_ADCSR_ADCLK (1 << 9) -#define DT2821_ADCSR_MUXBUSY (1 << 8) -#define DT2821_ADCSR_ADDONE (1 << 7) -#define DT2821_ADCSR_IADDONE (1 << 6) +#define DT2821_ADCSR_ADERR BIT(15) +#define DT2821_ADCSR_ADCLK BIT(9) +#define DT2821_ADCSR_MUXBUSY BIT(8) +#define DT2821_ADCSR_ADDONE BIT(7) +#define DT2821_ADCSR_IADDONE BIT(6) #define DT2821_ADCSR_GS(x) (((x) & 0x3) << 4) #define DT2821_ADCSR_CHAN(x) (((x) & 0xf) << 0) #define DT2821_CHANCSR_REG 0x02 -#define DT2821_CHANCSR_LLE (1 << 15) -#define DT2821_CHANCSR_PRESLA(x) (((x) & 0xf) >> 8) +#define DT2821_CHANCSR_LLE BIT(15) +#define DT2821_CHANCSR_TO_PRESLA(x) (((x) >> 8) & 0xf) #define DT2821_CHANCSR_NUMB(x) ((((x) - 1) & 0xf) << 0) #define DT2821_ADDAT_REG 0x04 #define DT2821_DACSR_REG 0x06 -#define DT2821_DACSR_DAERR (1 << 15) +#define DT2821_DACSR_DAERR BIT(15) #define DT2821_DACSR_YSEL(x) ((x) << 9) -#define DT2821_DACSR_SSEL (1 << 8) -#define DT2821_DACSR_DACRDY (1 << 7) -#define DT2821_DACSR_IDARDY (1 << 6) -#define DT2821_DACSR_DACLK (1 << 5) -#define DT2821_DACSR_HBOE (1 << 1) -#define DT2821_DACSR_LBOE (1 << 0) +#define DT2821_DACSR_SSEL BIT(8) +#define DT2821_DACSR_DACRDY BIT(7) +#define DT2821_DACSR_IDARDY BIT(6) +#define DT2821_DACSR_DACLK BIT(5) +#define DT2821_DACSR_HBOE BIT(1) +#define DT2821_DACSR_LBOE BIT(0) #define DT2821_DADAT_REG 0x08 #define DT2821_DIODAT_REG 0x0a #define DT2821_SUPCSR_REG 0x0c -#define DT2821_SUPCSR_DMAD (1 << 15) -#define DT2821_SUPCSR_ERRINTEN (1 << 14) -#define DT2821_SUPCSR_CLRDMADNE (1 << 13) -#define DT2821_SUPCSR_DDMA (1 << 12) -#define DT2821_SUPCSR_DS_PIO (0 << 10) -#define DT2821_SUPCSR_DS_AD_CLK (1 << 10) -#define DT2821_SUPCSR_DS_DA_CLK (2 << 10) -#define DT2821_SUPCSR_DS_AD_TRIG (3 << 10) -#define DT2821_SUPCSR_BUFFB (1 << 9) -#define DT2821_SUPCSR_SCDN (1 << 8) -#define DT2821_SUPCSR_DACON (1 << 7) -#define DT2821_SUPCSR_ADCINIT (1 << 6) -#define DT2821_SUPCSR_DACINIT (1 << 5) -#define DT2821_SUPCSR_PRLD (1 << 4) -#define DT2821_SUPCSR_STRIG (1 << 3) -#define DT2821_SUPCSR_XTRIG (1 << 2) -#define DT2821_SUPCSR_XCLK (1 << 1) -#define DT2821_SUPCSR_BDINIT (1 << 0) +#define DT2821_SUPCSR_DMAD BIT(15) +#define DT2821_SUPCSR_ERRINTEN BIT(14) +#define DT2821_SUPCSR_CLRDMADNE BIT(13) +#define DT2821_SUPCSR_DDMA BIT(12) +#define DT2821_SUPCSR_DS(x) (((x) & 0x3) << 10) +#define DT2821_SUPCSR_DS_PIO DT2821_SUPCSR_DS(0) +#define DT2821_SUPCSR_DS_AD_CLK DT2821_SUPCSR_DS(1) +#define DT2821_SUPCSR_DS_DA_CLK DT2821_SUPCSR_DS(2) +#define DT2821_SUPCSR_DS_AD_TRIG DT2821_SUPCSR_DS(3) +#define DT2821_SUPCSR_BUFFB BIT(9) +#define DT2821_SUPCSR_SCDN BIT(8) +#define DT2821_SUPCSR_DACON BIT(7) +#define DT2821_SUPCSR_ADCINIT BIT(6) +#define DT2821_SUPCSR_DACINIT BIT(5) +#define DT2821_SUPCSR_PRLD BIT(4) +#define DT2821_SUPCSR_STRIG BIT(3) +#define DT2821_SUPCSR_XTRIG BIT(2) +#define DT2821_SUPCSR_XCLK BIT(1) +#define DT2821_SUPCSR_BDINIT BIT(0) #define DT2821_TMRCTR_REG 0x0e static const struct comedi_lrange range_dt282x_ai_lo_bipolar = { -- cgit v1.2.3 From 938cae7ab3b046af9669aa7454fab0546231ba48 Mon Sep 17 00:00:00 2001 From: Leslie Klein Date: Sun, 20 Mar 2016 20:26:12 -0400 Subject: Staging: comedi: comedi_buf: Replace 'unsigned' with 'unsigned int' Fix checkpatch warning: Prefer 'unsigned int' to bare use of 'unsigned' in file comedi_buf.c Signed-off-by: Leslie Klein Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_buf.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c index 90c28016c6c1..c7d7682b1412 100644 --- a/drivers/staging/comedi/comedi_buf.c +++ b/drivers/staging/comedi/comedi_buf.c @@ -80,14 +80,14 @@ static void __comedi_buf_free(struct comedi_device *dev, static void __comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, - unsigned n_pages) + unsigned int n_pages) { struct comedi_async *async = s->async; struct page **pages = NULL; struct comedi_buf_map *bm; struct comedi_buf_page *buf; unsigned long flags; - unsigned i; + unsigned int i; if (!IS_ENABLED(CONFIG_HAS_DMA) && s->async_dma_dir != DMA_NONE) { dev_err(dev->class_dev, @@ -208,7 +208,7 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, /* allocate new buffer */ if (new_size) { - unsigned n_pages = new_size >> PAGE_SHIFT; + unsigned int n_pages = new_size >> PAGE_SHIFT; __comedi_buf_alloc(dev, s, n_pages); @@ -302,7 +302,7 @@ static unsigned int comedi_buf_munge(struct comedi_subdevice *s, { struct comedi_async *async = s->async; unsigned int count = 0; - const unsigned num_sample_bytes = comedi_bytes_per_sample(s); + const unsigned int num_sample_bytes = comedi_bytes_per_sample(s); if (!s->munge || (async->cmd.flags & CMDF_RAWDATA)) { async->munge_count += num_bytes; @@ -395,7 +395,7 @@ EXPORT_SYMBOL_GPL(comedi_buf_write_free); unsigned int comedi_buf_read_n_available(struct comedi_subdevice *s) { struct comedi_async *async = s->async; - unsigned num_bytes; + unsigned int num_bytes; if (!async) return 0; -- cgit v1.2.3 From d4d47895a906779b5e8df157f703f906d22305b5 Mon Sep 17 00:00:00 2001 From: Leslie Klein Date: Mon, 21 Mar 2016 09:18:35 -0400 Subject: Staging: comedi: comedi_fops: Replace 'unsigned' with 'unsigned int' Fix checkpatch warning: Prefer 'unsigned int' to bare use of 'unsigned' in file comedi_fops.c Signed-off-by: Leslie Klein Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 48 ++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 7c7b477b0f28..4bdea202c46c 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -186,7 +186,7 @@ static bool comedi_clear_board_dev(struct comedi_device *dev) return cleared; } -static struct comedi_device *comedi_clear_board_minor(unsigned minor) +static struct comedi_device *comedi_clear_board_minor(unsigned int minor) { struct comedi_device *dev; @@ -210,7 +210,7 @@ static void comedi_free_board_dev(struct comedi_device *dev) } static struct comedi_subdevice -*comedi_subdevice_from_minor(const struct comedi_device *dev, unsigned minor) +*comedi_subdevice_from_minor(const struct comedi_device *dev, unsigned int minor) { struct comedi_subdevice *s; unsigned int i = minor - COMEDI_NUM_BOARD_MINORS; @@ -223,7 +223,7 @@ static struct comedi_subdevice return s; } -static struct comedi_device *comedi_dev_get_from_board_minor(unsigned minor) +static struct comedi_device *comedi_dev_get_from_board_minor(unsigned int minor) { struct comedi_device *dev; @@ -233,7 +233,7 @@ static struct comedi_device *comedi_dev_get_from_board_minor(unsigned minor) return dev; } -static struct comedi_device *comedi_dev_get_from_subdevice_minor(unsigned minor) +static struct comedi_device *comedi_dev_get_from_subdevice_minor(unsigned int minor) { struct comedi_device *dev; struct comedi_subdevice *s; @@ -258,7 +258,7 @@ static struct comedi_device *comedi_dev_get_from_subdevice_minor(unsigned minor) * reference incremented. Return NULL if no COMEDI device exists with the * specified minor device number. */ -struct comedi_device *comedi_dev_get_from_minor(unsigned minor) +struct comedi_device *comedi_dev_get_from_minor(unsigned int minor) { if (minor < COMEDI_NUM_BOARD_MINORS) return comedi_dev_get_from_board_minor(minor); @@ -342,7 +342,7 @@ static struct comedi_subdevice *comedi_file_write_subdevice(struct file *file) } static int resize_async_buffer(struct comedi_device *dev, - struct comedi_subdevice *s, unsigned new_size) + struct comedi_subdevice *s, unsigned int new_size) { struct comedi_async *async = s->async; int retval; @@ -616,19 +616,19 @@ static struct attribute *comedi_dev_attrs[] = { ATTRIBUTE_GROUPS(comedi_dev); static void __comedi_clear_subdevice_runflags(struct comedi_subdevice *s, - unsigned bits) + unsigned int bits) { s->runflags &= ~bits; } static void __comedi_set_subdevice_runflags(struct comedi_subdevice *s, - unsigned bits) + unsigned int bits) { s->runflags |= bits; } static void comedi_update_subdevice_runflags(struct comedi_subdevice *s, - unsigned mask, unsigned bits) + unsigned int mask, unsigned int bits) { unsigned long flags; @@ -638,15 +638,15 @@ static void comedi_update_subdevice_runflags(struct comedi_subdevice *s, spin_unlock_irqrestore(&s->spin_lock, flags); } -static unsigned __comedi_get_subdevice_runflags(struct comedi_subdevice *s) +static unsigned int __comedi_get_subdevice_runflags(struct comedi_subdevice *s) { return s->runflags; } -static unsigned comedi_get_subdevice_runflags(struct comedi_subdevice *s) +static unsigned int comedi_get_subdevice_runflags(struct comedi_subdevice *s) { unsigned long flags; - unsigned runflags; + unsigned int runflags; spin_lock_irqsave(&s->spin_lock, flags); runflags = __comedi_get_subdevice_runflags(s); @@ -654,12 +654,12 @@ static unsigned comedi_get_subdevice_runflags(struct comedi_subdevice *s) return runflags; } -static bool comedi_is_runflags_running(unsigned runflags) +static bool comedi_is_runflags_running(unsigned int runflags) { return runflags & COMEDI_SRF_RUNNING; } -static bool comedi_is_runflags_in_error(unsigned runflags) +static bool comedi_is_runflags_in_error(unsigned int runflags) { return runflags & COMEDI_SRF_ERROR; } @@ -673,7 +673,7 @@ static bool comedi_is_runflags_in_error(unsigned runflags) */ bool comedi_is_subdevice_running(struct comedi_subdevice *s) { - unsigned runflags = comedi_get_subdevice_runflags(s); + unsigned int runflags = comedi_get_subdevice_runflags(s); return comedi_is_runflags_running(runflags); } @@ -681,14 +681,14 @@ EXPORT_SYMBOL_GPL(comedi_is_subdevice_running); static bool __comedi_is_subdevice_running(struct comedi_subdevice *s) { - unsigned runflags = __comedi_get_subdevice_runflags(s); + unsigned int runflags = __comedi_get_subdevice_runflags(s); return comedi_is_runflags_running(runflags); } bool comedi_can_auto_free_spriv(struct comedi_subdevice *s) { - unsigned runflags = __comedi_get_subdevice_runflags(s); + unsigned int runflags = __comedi_get_subdevice_runflags(s); return runflags & COMEDI_SRF_FREE_SPRIV; } @@ -2038,7 +2038,7 @@ static int do_setwsubd_ioctl(struct comedi_device *dev, unsigned long arg, static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - unsigned minor = iminor(file_inode(file)); + unsigned int minor = iminor(file_inode(file)); struct comedi_file *cfp = file->private_data; struct comedi_device *dev = cfp->dev; int rc; @@ -2342,7 +2342,7 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, add_wait_queue(&async->wait_head, &wait); while (count == 0 && !retval) { - unsigned runflags; + unsigned int runflags; unsigned int wp, n1, n2; set_current_state(TASK_INTERRUPTIBLE); @@ -2485,7 +2485,7 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, n = min_t(size_t, m, nbytes); if (n == 0) { - unsigned runflags = comedi_get_subdevice_runflags(s); + unsigned int runflags = comedi_get_subdevice_runflags(s); if (!comedi_is_runflags_running(runflags)) { if (comedi_is_runflags_in_error(runflags)) @@ -2573,7 +2573,7 @@ out: static int comedi_open(struct inode *inode, struct file *file) { - const unsigned minor = iminor(inode); + const unsigned int minor = iminor(inode); struct comedi_file *cfp; struct comedi_device *dev = comedi_dev_get_from_minor(minor); int rc; @@ -2733,7 +2733,7 @@ struct comedi_device *comedi_alloc_board_minor(struct device *hardware_device) { struct comedi_device *dev; struct device *csdev; - unsigned i; + unsigned int i; dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) @@ -2791,7 +2791,7 @@ int comedi_alloc_subdevice_minor(struct comedi_subdevice *s) { struct comedi_device *dev = s->device; struct device *csdev; - unsigned i; + unsigned int i; mutex_lock(&comedi_subdevice_minor_table_lock); for (i = 0; i < COMEDI_NUM_SUBDEVICE_MINORS; ++i) { @@ -2841,7 +2841,7 @@ void comedi_free_subdevice_minor(struct comedi_subdevice *s) static void comedi_cleanup_board_minors(void) { struct comedi_device *dev; - unsigned i; + unsigned int i; for (i = 0; i < COMEDI_NUM_BOARD_MINORS; i++) { dev = comedi_clear_board_minor(i); -- cgit v1.2.3 From 6c5f37dfbbc9b2121b39be3a7a61b93dbba3ed08 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Mon, 14 Mar 2016 21:55:20 +0200 Subject: Staging: vt6655: defined byVT3253InitTab_RFMD[] and byVT3253B0_RFMD[] as const arrays. This patch changes byVT3253InitTab_RFMD[] and byVT3253B0_RFMD[] arrays in const arrays since these are not changed anywhere in the code. Signed-off-by: Claudiu Beznea Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/baseband.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c index 1e6c0c4a0307..94a7e64baf5f 100644 --- a/drivers/staging/vt6655/baseband.c +++ b/drivers/staging/vt6655/baseband.c @@ -66,7 +66,7 @@ /*--------------------- Static Variables --------------------------*/ #define CB_VT3253_INIT_FOR_RFMD 446 -static unsigned char byVT3253InitTab_RFMD[CB_VT3253_INIT_FOR_RFMD][2] = { +static const unsigned char byVT3253InitTab_RFMD[CB_VT3253_INIT_FOR_RFMD][2] = { {0x00, 0x30}, {0x01, 0x00}, {0x02, 0x00}, @@ -516,7 +516,7 @@ static unsigned char byVT3253InitTab_RFMD[CB_VT3253_INIT_FOR_RFMD][2] = { }; #define CB_VT3253B0_INIT_FOR_RFMD 256 -static unsigned char byVT3253B0_RFMD[CB_VT3253B0_INIT_FOR_RFMD][2] = { +static const unsigned char byVT3253B0_RFMD[CB_VT3253B0_INIT_FOR_RFMD][2] = { {0x00, 0x31}, {0x01, 0x00}, {0x02, 0x00}, -- cgit v1.2.3 From 779bee40b907de23771bb8eaf334b81be53018b1 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Tue, 15 Mar 2016 21:34:59 +0100 Subject: Staging: speakup: Clear hi font bit from attributes Previously, speakup would see the hi-font bit in attributes. Since this bit has nothing to do with attributes, we need to clear it. Signed-off-by: Samuel Thibault Signed-off-by: Greg Kroah-Hartman --- drivers/staging/speakup/main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c index a22fb07512a1..97ca4ecca8a9 100644 --- a/drivers/staging/speakup/main.c +++ b/drivers/staging/speakup/main.c @@ -263,7 +263,7 @@ static struct notifier_block vt_notifier_block = { static unsigned char get_attributes(struct vc_data *vc, u16 *pos) { pos = screen_pos(vc, pos - (u16 *)vc->vc_origin, 1); - return (u_char) (scr_readw(pos) >> 8); + return (scr_readw(pos) & ~vc->vc_hi_font_mask) >> 8; } static void speakup_date(struct vc_data *vc) @@ -473,8 +473,10 @@ static u16 get_char(struct vc_data *vc, u16 *pos, u_char *attribs) w = scr_readw(pos); c = w & 0xff; - if (w & vc->vc_hi_font_mask) + if (w & vc->vc_hi_font_mask) { + w &= ~vc->vc_hi_font_mask; c |= 0x100; + } ch = inverse_translate(vc, c, 0); *attribs = (w & 0xff00) >> 8; -- cgit v1.2.3 From 5150d01ea99230576060e864f7a6f15e29b8dc4d Mon Sep 17 00:00:00 2001 From: Kathryn Hampton Date: Tue, 15 Mar 2016 18:16:24 -0700 Subject: staging: vt6655: fix style violations for lines over 80 characters This patch addresses line length errors reported by checkpatch.pl that could be fixed with simple line breaks. Signed-off-by: Kathryn Hampton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/baseband.c | 20 ++++++--- drivers/staging/vt6655/baseband.h | 6 ++- drivers/staging/vt6655/card.c | 95 ++++++++++++++++++++++++++------------- drivers/staging/vt6655/card.h | 9 ++-- drivers/staging/vt6655/desc.h | 3 +- drivers/staging/vt6655/mac.c | 15 ++++--- drivers/staging/vt6655/srom.c | 9 ++-- 7 files changed, 106 insertions(+), 51 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c index 94a7e64baf5f..654d072bdc28 100644 --- a/drivers/staging/vt6655/baseband.c +++ b/drivers/staging/vt6655/baseband.c @@ -36,8 +36,10 @@ * Revision History: * 06-10-2003 Bryan YC Fan: Re-write codes to support VT3253 spec. * 08-07-2003 Bryan YC Fan: Add MAXIM2827/2825 and RFMD2959 support. - * 08-26-2003 Kyle Hsu : Modify BBuGetFrameTime() and BBvCalculateParameter(). - * cancel the setting of MAC_REG_SOFTPWRCTL on BBbVT3253Init(). + * 08-26-2003 Kyle Hsu : Modify BBuGetFrameTime() and + * BBvCalculateParameter(). + * cancel the setting of MAC_REG_SOFTPWRCTL on + * BBbVT3253Init(). * Add the comments. * 09-01-2003 Bryan YC Fan: RF & BB tables updated. * Modified BBvLoopbackOn & BBvLoopbackOff(). @@ -777,7 +779,8 @@ static const unsigned char byVT3253B0_RFMD[CB_VT3253B0_INIT_FOR_RFMD][2] = { #define CB_VT3253B0_AGC_FOR_RFMD2959 195 /* For RFMD2959 */ -static unsigned char byVT3253B0_AGC4_RFMD2959[CB_VT3253B0_AGC_FOR_RFMD2959][2] = { +static +unsigned char byVT3253B0_AGC4_RFMD2959[CB_VT3253B0_AGC_FOR_RFMD2959][2] = { {0xF0, 0x00}, {0xF1, 0x3E}, {0xF0, 0x80}, @@ -977,7 +980,8 @@ static unsigned char byVT3253B0_AGC4_RFMD2959[CB_VT3253B0_AGC_FOR_RFMD2959][2] = #define CB_VT3253B0_INIT_FOR_AIROHA2230 256 /* For AIROHA */ -static unsigned char byVT3253B0_AIROHA2230[CB_VT3253B0_INIT_FOR_AIROHA2230][2] = { +static +unsigned char byVT3253B0_AIROHA2230[CB_VT3253B0_INIT_FOR_AIROHA2230][2] = { {0x00, 0x31}, {0x01, 0x00}, {0x02, 0x00}, @@ -2160,9 +2164,13 @@ bool BBbVT3253Init(struct vnt_private *priv) /* {{ RobertYu:20050223, request by JerryChung */ - /* Init ANT B select,TX Config CR09 = 0x61->0x45, 0x45->0x41(VC1/VC2 define, make the ANT_A, ANT_B inverted) */ + /* Init ANT B select,TX Config CR09 = 0x61->0x45, + * 0x45->0x41(VC1/VC2 define, make the ANT_A, ANT_B inverted) + */ /*bResult &= BBbWriteEmbedded(dwIoBase,0x09,0x41);*/ - /* Init ANT B select,RX Config CR10 = 0x28->0x2A, 0x2A->0x28(VC1/VC2 define, make the ANT_A, ANT_B inverted) */ + /* Init ANT B select,RX Config CR10 = 0x28->0x2A, + * 0x2A->0x28(VC1/VC2 define, make the ANT_A, ANT_B inverted) + */ /*bResult &= BBbWriteEmbedded(dwIoBase,0x0a,0x28);*/ /* Select VC1/VC2, CR215 = 0x02->0x06 */ bResult &= BBbWriteEmbedded(priv, 0xd7, 0x06); diff --git a/drivers/staging/vt6655/baseband.h b/drivers/staging/vt6655/baseband.h index 43a4fb1f3570..b4e8c43180ec 100644 --- a/drivers/staging/vt6655/baseband.h +++ b/drivers/staging/vt6655/baseband.h @@ -77,8 +77,10 @@ BBuGetFrameTime( void vnt_get_phy_field(struct vnt_private *, u32 frame_length, u16 tx_rate, u8 pkt_type, struct vnt_phy_field *); -bool BBbReadEmbedded(struct vnt_private *, unsigned char byBBAddr, unsigned char *pbyData); -bool BBbWriteEmbedded(struct vnt_private *, unsigned char byBBAddr, unsigned char byData); +bool BBbReadEmbedded(struct vnt_private *, unsigned char byBBAddr, + unsigned char *pbyData); +bool BBbWriteEmbedded(struct vnt_private *, unsigned char byBBAddr, + unsigned char byData); void BBvSetShortSlotTime(struct vnt_private *); void BBvSetVGAGainOffset(struct vnt_private *, unsigned char byData); diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index 3d338122b590..afb1e8bde975 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -336,7 +336,8 @@ bool CARDbSetPhyParameter(struct vnt_private *priv, u8 bb_type) } if (priv->byCWMaxMin != byCWMaxMin) { priv->byCWMaxMin = byCWMaxMin; - VNSvOutPortB(priv->PortOffset + MAC_REG_CWMAXMIN0, priv->byCWMaxMin); + VNSvOutPortB(priv->PortOffset + MAC_REG_CWMAXMIN0, + priv->byCWMaxMin); } priv->byPacketType = CARDbyGetPktType(priv); @@ -373,9 +374,12 @@ bool CARDbUpdateTSF(struct vnt_private *priv, unsigned char byRxRate, qwTSFOffset = CARDqGetTSFOffset(byRxRate, qwBSSTimestamp, local_tsf); /* adjust TSF, HW's TSF add TSF Offset reg */ - VNSvOutPortD(priv->PortOffset + MAC_REG_TSFOFST, (u32)qwTSFOffset); - VNSvOutPortD(priv->PortOffset + MAC_REG_TSFOFST + 4, (u32)(qwTSFOffset >> 32)); - MACvRegBitsOn(priv->PortOffset, MAC_REG_TFTCTL, TFTCTL_TSFSYNCEN); + VNSvOutPortD(priv->PortOffset + MAC_REG_TSFOFST, + (u32)qwTSFOffset); + VNSvOutPortD(priv->PortOffset + MAC_REG_TSFOFST + 4, + (u32)(qwTSFOffset >> 32)); + MACvRegBitsOn(priv->PortOffset, MAC_REG_TFTCTL, + TFTCTL_TSFSYNCEN); } return true; } @@ -407,7 +411,8 @@ bool CARDbSetBeaconPeriod(struct vnt_private *priv, priv->wBeaconInterval = wBeaconInterval; /* Set NextTBTT */ VNSvOutPortD(priv->PortOffset + MAC_REG_NEXTTBTT, (u32)qwNextTBTT); - VNSvOutPortD(priv->PortOffset + MAC_REG_NEXTTBTT + 4, (u32)(qwNextTBTT >> 32)); + VNSvOutPortD(priv->PortOffset + MAC_REG_NEXTTBTT + 4, + (u32)(qwNextTBTT >> 32)); MACvRegBitsOn(priv->PortOffset, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN); return true; @@ -433,15 +438,19 @@ bool CARDbRadioPowerOff(struct vnt_private *priv) switch (priv->byRFType) { case RF_RFMD2959: - MACvWordRegBitsOff(priv->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_TXPEINV); - MACvWordRegBitsOn(priv->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE1); + MACvWordRegBitsOff(priv->PortOffset, MAC_REG_SOFTPWRCTL, + SOFTPWRCTL_TXPEINV); + MACvWordRegBitsOn(priv->PortOffset, MAC_REG_SOFTPWRCTL, + SOFTPWRCTL_SWPE1); break; case RF_AIROHA: case RF_AL2230S: case RF_AIROHA7230: - MACvWordRegBitsOff(priv->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE2); - MACvWordRegBitsOff(priv->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); + MACvWordRegBitsOff(priv->PortOffset, MAC_REG_SOFTPWRCTL, + SOFTPWRCTL_SWPE2); + MACvWordRegBitsOff(priv->PortOffset, MAC_REG_SOFTPWRCTL, + SOFTPWRCTL_SWPE3); break; } @@ -451,7 +460,8 @@ bool CARDbRadioPowerOff(struct vnt_private *priv) priv->bRadioOff = true; pr_debug("chester power off\n"); - MACvRegBitsOn(priv->PortOffset, MAC_REG_GPIOCTL0, LED_ACTSET); /* LED issue */ + MACvRegBitsOn(priv->PortOffset, MAC_REG_GPIOCTL0, + LED_ACTSET); /* LED issue */ return bResult; } @@ -488,21 +498,24 @@ bool CARDbRadioPowerOn(struct vnt_private *priv) switch (priv->byRFType) { case RF_RFMD2959: - MACvWordRegBitsOn(priv->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_TXPEINV); - MACvWordRegBitsOff(priv->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE1); + MACvWordRegBitsOn(priv->PortOffset, MAC_REG_SOFTPWRCTL, + SOFTPWRCTL_TXPEINV); + MACvWordRegBitsOff(priv->PortOffset, MAC_REG_SOFTPWRCTL, + SOFTPWRCTL_SWPE1); break; case RF_AIROHA: case RF_AL2230S: case RF_AIROHA7230: - MACvWordRegBitsOn(priv->PortOffset, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE2 | - SOFTPWRCTL_SWPE3)); + MACvWordRegBitsOn(priv->PortOffset, MAC_REG_SOFTPWRCTL, + (SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3)); break; } priv->bRadioOff = false; pr_debug("chester power on\n"); - MACvRegBitsOff(priv->PortOffset, MAC_REG_GPIOCTL0, LED_ACTSET); /* LED issue */ + MACvRegBitsOff(priv->PortOffset, MAC_REG_GPIOCTL0, + LED_ACTSET); /* LED issue */ return bResult; } @@ -717,55 +730,72 @@ void CARDvSetRSPINF(struct vnt_private *priv, u8 bb_type) bb_type, &byTxRate, &byRsvTime); - VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_6, MAKEWORD(byTxRate, byRsvTime)); + VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_6, + MAKEWORD(byTxRate, byRsvTime)); /* RSPINF_a_9 */ s_vCalculateOFDMRParameter(RATE_9M, bb_type, &byTxRate, &byRsvTime); - VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_9, MAKEWORD(byTxRate, byRsvTime)); + VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_9, + MAKEWORD(byTxRate, byRsvTime)); /* RSPINF_a_12 */ s_vCalculateOFDMRParameter(RATE_12M, bb_type, &byTxRate, &byRsvTime); - VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_12, MAKEWORD(byTxRate, byRsvTime)); + VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_12, + MAKEWORD(byTxRate, byRsvTime)); /* RSPINF_a_18 */ s_vCalculateOFDMRParameter(RATE_18M, bb_type, &byTxRate, &byRsvTime); - VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_18, MAKEWORD(byTxRate, byRsvTime)); + VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_18, + MAKEWORD(byTxRate, byRsvTime)); /* RSPINF_a_24 */ s_vCalculateOFDMRParameter(RATE_24M, bb_type, &byTxRate, &byRsvTime); - VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_24, MAKEWORD(byTxRate, byRsvTime)); + VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_24, + MAKEWORD(byTxRate, byRsvTime)); /* RSPINF_a_36 */ - s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv, RATE_36M), + s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate( + (void *)priv, + RATE_36M), bb_type, &byTxRate, &byRsvTime); - VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_36, MAKEWORD(byTxRate, byRsvTime)); + VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_36, + MAKEWORD(byTxRate, byRsvTime)); /* RSPINF_a_48 */ - s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv, RATE_48M), + s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate( + (void *)priv, + RATE_48M), bb_type, &byTxRate, &byRsvTime); - VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_48, MAKEWORD(byTxRate, byRsvTime)); + VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_48, + MAKEWORD(byTxRate, byRsvTime)); /* RSPINF_a_54 */ - s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv, RATE_54M), + s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate( + (void *)priv, + RATE_54M), bb_type, &byTxRate, &byRsvTime); - VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_54, MAKEWORD(byTxRate, byRsvTime)); + VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_54, + MAKEWORD(byTxRate, byRsvTime)); /* RSPINF_a_72 */ - s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv, RATE_54M), + s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate( + (void *)priv, + RATE_54M), bb_type, &byTxRate, &byRsvTime); - VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_72, MAKEWORD(byTxRate, byRsvTime)); + VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_72, + MAKEWORD(byTxRate, byRsvTime)); /* Set to Page0 */ MACvSelectPage0(priv->PortOffset); @@ -830,7 +860,8 @@ unsigned char CARDbyGetPktType(struct vnt_private *priv) * * Return Value: none */ -void CARDvSetLoopbackMode(struct vnt_private *priv, unsigned short wLoopbackMode) +void CARDvSetLoopbackMode(struct vnt_private *priv, + unsigned short wLoopbackMode) { switch (wLoopbackMode) { case CARD_LB_NONE: @@ -965,7 +996,8 @@ u64 CARDqGetNextTBTT(u64 qwTSF, unsigned short wBeaconInterval) * * Return Value: none */ -void CARDvSetFirstNextTBTT(struct vnt_private *priv, unsigned short wBeaconInterval) +void CARDvSetFirstNextTBTT(struct vnt_private *priv, + unsigned short wBeaconInterval) { void __iomem *dwIoBase = priv->PortOffset; u64 qwNextTBTT = 0; @@ -993,7 +1025,8 @@ void CARDvSetFirstNextTBTT(struct vnt_private *priv, unsigned short wBeaconInter * * Return Value: none */ -void CARDvUpdateNextTBTT(struct vnt_private *priv, u64 qwTSF, unsigned short wBeaconInterval) +void CARDvUpdateNextTBTT(struct vnt_private *priv, u64 qwTSF, + unsigned short wBeaconInterval) { void __iomem *dwIoBase = priv->PortOffset; diff --git a/drivers/staging/vt6655/card.h b/drivers/staging/vt6655/card.h index 16cca49e680a..0203c7fd91a2 100644 --- a/drivers/staging/vt6655/card.h +++ b/drivers/staging/vt6655/card.h @@ -38,7 +38,8 @@ * LOBYTE is MAC LB mode, HIBYTE is MII LB mode */ #define CARD_LB_NONE MAKEWORD(MAC_LB_NONE, 0) -#define CARD_LB_MAC MAKEWORD(MAC_LB_INTERNAL, 0) /* PHY must ISO, avoid MAC loopback packet go out */ +/* PHY must ISO, avoid MAC loopback packet go out */ +#define CARD_LB_MAC MAKEWORD(MAC_LB_INTERNAL, 0) #define CARD_LB_PHY MAKEWORD(MAC_LB_EXT, 0) #define DEFAULT_MSDU_LIFETIME 512 /* ms */ @@ -71,8 +72,10 @@ void CARDvUpdateBasicTopRate(struct vnt_private *); bool CARDbIsOFDMinBasicRate(struct vnt_private *); void CARDvSetLoopbackMode(struct vnt_private *, unsigned short wLoopbackMode); bool CARDbSoftwareReset(struct vnt_private *); -void CARDvSetFirstNextTBTT(struct vnt_private *, unsigned short wBeaconInterval); -void CARDvUpdateNextTBTT(struct vnt_private *, u64 qwTSF, unsigned short wBeaconInterval); +void CARDvSetFirstNextTBTT(struct vnt_private *, + unsigned short wBeaconInterval); +void CARDvUpdateNextTBTT(struct vnt_private *, u64 qwTSF, + unsigned short wBeaconInterval); bool CARDbGetCurrentTSF(struct vnt_private *, u64 *pqwCurrTSF); u64 CARDqGetNextTBTT(u64 qwTSF, unsigned short wBeaconInterval); u64 CARDqGetTSFOffset(unsigned char byRxRate, u64 qwTSF1, u64 qwTSF2); diff --git a/drivers/staging/vt6655/desc.h b/drivers/staging/vt6655/desc.h index 9fbc7172484e..2d7f6ae89164 100644 --- a/drivers/staging/vt6655/desc.h +++ b/drivers/staging/vt6655/desc.h @@ -157,7 +157,8 @@ /* TD_INFO flags control bit */ #define TD_FLAGS_NETIF_SKB 0x01 /* check if need release skb */ -#define TD_FLAGS_PRIV_SKB 0x02 /* check if called from private skb (hostap) */ +/* check if called from private skb (hostap) */ +#define TD_FLAGS_PRIV_SKB 0x02 #define TD_FLAGS_PS_RETRY 0x04 /* check if PS STA frame re-transmit */ /* diff --git a/drivers/staging/vt6655/mac.c b/drivers/staging/vt6655/mac.c index 45196c6e9e12..8e13f7f41415 100644 --- a/drivers/staging/vt6655/mac.c +++ b/drivers/staging/vt6655/mac.c @@ -47,7 +47,8 @@ * * Revision History: * 08-22-2003 Kyle Hsu : Porting MAC functions from sim53 - * 09-03-2003 Bryan YC Fan : Add MACvClearBusSusInd()& MACvEnableBusSusEn() + * 09-03-2003 Bryan YC Fan : Add MACvClearBusSusInd()& + * MACvEnableBusSusEn() * 09-18-2003 Jerry Chen : Add MACvSetKeyEntry & MACvDisableKeyEntry * */ @@ -138,7 +139,8 @@ bool MACbIsIntDisable(struct vnt_private *priv) * Return Value: none * */ -void MACvSetShortRetryLimit(struct vnt_private *priv, unsigned char byRetryLimit) +void MACvSetShortRetryLimit(struct vnt_private *priv, + unsigned char byRetryLimit) { void __iomem *io_base = priv->PortOffset; /* set SRT */ @@ -160,7 +162,8 @@ void MACvSetShortRetryLimit(struct vnt_private *priv, unsigned char byRetryLimit * Return Value: none * */ -void MACvSetLongRetryLimit(struct vnt_private *priv, unsigned char byRetryLimit) +void MACvSetLongRetryLimit(struct vnt_private *priv, + unsigned char byRetryLimit) { void __iomem *io_base = priv->PortOffset; /* set LRT */ @@ -304,7 +307,8 @@ bool MACbSoftwareReset(struct vnt_private *priv) /* * Description: - * save some important register's value, then do reset, then restore register's value + * save some important register's value, then do reset, then restore + * register's value * * Parameters: * In: @@ -738,7 +742,8 @@ void MACvTimer0MicroSDelay(struct vnt_private *priv, unsigned int uDelay) * Return Value: none * */ -void MACvOneShotTimer1MicroSec(struct vnt_private *priv, unsigned int uDelayTime) +void MACvOneShotTimer1MicroSec(struct vnt_private *priv, + unsigned int uDelayTime) { void __iomem *io_base = priv->PortOffset; diff --git a/drivers/staging/vt6655/srom.c b/drivers/staging/vt6655/srom.c index 9ec49e653b61..ee992772066f 100644 --- a/drivers/staging/vt6655/srom.c +++ b/drivers/staging/vt6655/srom.c @@ -72,7 +72,8 @@ * Return Value: data read * */ -unsigned char SROMbyReadEmbedded(void __iomem *dwIoBase, unsigned char byContntOffset) +unsigned char SROMbyReadEmbedded(void __iomem *dwIoBase, + unsigned char byContntOffset) { unsigned short wDelay, wNoACK; unsigned char byWait; @@ -124,7 +125,8 @@ void SROMvReadAllContents(void __iomem *dwIoBase, unsigned char *pbyEepromRegs) /* ii = Rom Address */ for (ii = 0; ii < EEP_MAX_CONTEXT_SIZE; ii++) { - *pbyEepromRegs = SROMbyReadEmbedded(dwIoBase, (unsigned char)ii); + *pbyEepromRegs = SROMbyReadEmbedded(dwIoBase, + (unsigned char)ii); pbyEepromRegs++; } } @@ -141,7 +143,8 @@ void SROMvReadAllContents(void __iomem *dwIoBase, unsigned char *pbyEepromRegs) * Return Value: none * */ -void SROMvReadEtherAddress(void __iomem *dwIoBase, unsigned char *pbyEtherAddress) +void SROMvReadEtherAddress(void __iomem *dwIoBase, + unsigned char *pbyEtherAddress) { unsigned char ii; -- cgit v1.2.3 From 896802a8e208997faff6e38d711cd9b13c7a2e23 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Tue, 22 Mar 2016 08:39:24 +0900 Subject: staging: wilc1000: use mutex instead of struct semaphore hif_sema_deinit This patch replaces struct semaphore hif_sema_deinit with struct mutex hif_deinit_lock. It is better to use mutex because mutex gives better performance than semaphore. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 4be8b3183b28..b1ffa91dfe52 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -234,7 +234,7 @@ static struct message_queue hif_msg_q; static struct semaphore hif_sema_thread; static struct semaphore hif_sema_driver; static struct completion hif_wait_response; -static struct semaphore hif_sema_deinit; +static struct mutex hif_deinit_lock; static struct timer_list periodic_rssi; u8 wilc_multicast_mac_addr_list[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN]; @@ -3402,7 +3402,7 @@ int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) if (clients_count == 0) { sema_init(&hif_sema_thread, 0); sema_init(&hif_sema_driver, 0); - sema_init(&hif_sema_deinit, 1); + mutex_init(&hif_deinit_lock); } init_completion(&hif_drv->comp_test_key_block); @@ -3470,7 +3470,7 @@ int wilc_deinit(struct wilc_vif *vif) return -EFAULT; } - down(&hif_sema_deinit); + mutex_lock(&hif_deinit_lock); terminated_handle = hif_drv; @@ -3512,7 +3512,7 @@ int wilc_deinit(struct wilc_vif *vif) clients_count--; terminated_handle = NULL; - up(&hif_sema_deinit); + mutex_unlock(&hif_deinit_lock); return result; } @@ -3559,25 +3559,25 @@ void wilc_gnrl_async_info_received(struct wilc *wilc, u8 *pu8Buffer, struct host_if_drv *hif_drv = NULL; struct wilc_vif *vif; - down(&hif_sema_deinit); + mutex_lock(&hif_deinit_lock); id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24)); vif = wilc_get_vif_from_idx(wilc, id); if (!vif) { - up(&hif_sema_deinit); + mutex_unlock(&hif_deinit_lock); return; } hif_drv = vif->hif_drv; if (!hif_drv || hif_drv == terminated_handle) { - up(&hif_sema_deinit); + mutex_unlock(&hif_deinit_lock); return; } if (!hif_drv->usr_conn_req.conn_result) { netdev_err(vif->ndev, "there is no current Connect Request\n"); - up(&hif_sema_deinit); + mutex_unlock(&hif_deinit_lock); return; } @@ -3594,7 +3594,7 @@ void wilc_gnrl_async_info_received(struct wilc *wilc, u8 *pu8Buffer, if (result) netdev_err(vif->ndev, "synchronous info (%d)\n", result); - up(&hif_sema_deinit); + mutex_unlock(&hif_deinit_lock); } void wilc_scan_complete_received(struct wilc *wilc, u8 *pu8Buffer, -- cgit v1.2.3 From 094c0741dec38c73793f674293dcd2026d1e77d7 Mon Sep 17 00:00:00 2001 From: Bhaktipriya Shridhar Date: Tue, 22 Mar 2016 10:28:51 +0530 Subject: staging: comedi: amplc_pci230: Convert macro GAT_CONFIG to static inline function Convert macro GAT_CONFIG to static inline function as static inline functions are preferred over macros. This change is possible since the arguments at all call sites have the same type. This was done using Coccinelle: @r@ expression e; @@ - #define GAT_CONFIG(chan, src) e + static inline unsigned int pci230_gat_config(unsigned int chan, + unsigned int src) +{ + return ((chan & 3) << 3) | (src & 7); +} @r1@ expression dev,reg,chan,src; @@ -GAT_CONFIG(chan, src) +pci230_gat_config(chan, src) Also, the comment describing the macro has been removed manually. Signed-off-by: Bhaktipriya Shridhar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci230.c | 38 ++++++++++++++++----------- 1 file changed, 22 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index 907c39cc89d7..cf5ac8aad236 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -379,8 +379,12 @@ #define GAT_GND 1 /* GND (i.e. disabled) */ #define GAT_EXT 2 /* external gate input (PPCn on PCI230) */ #define GAT_NOUTNM2 3 /* inverted output of channel-2 modulo total */ -/* Macro to construct gate input configuration register value. */ -#define GAT_CONFIG(chan, src) ((((chan) & 3) << 3) | ((src) & 7)) + +static inline unsigned int pci230_gat_config(unsigned int chan, + unsigned int src) +{ + return ((chan & 3) << 3) | (src & 7); +} /* * Summary of CLK_OUTNM1 and GAT_NOUTNM2 connections for PCI230 and PCI260: @@ -1263,7 +1267,8 @@ static void pci230_ao_start(struct comedi_device *dev, irqflags); } /* Set CT1 gate high to start counting. */ - outb(GAT_CONFIG(1, GAT_VCC), dev->iobase + PCI230_ZGAT_SCE); + outb(pci230_gat_config(1, GAT_VCC), + dev->iobase + PCI230_ZGAT_SCE); break; case TRIG_INT: async->inttrig = pci230_ao_inttrig_scan_begin; @@ -1351,7 +1356,8 @@ static int pci230_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) * cmd->scan_begin_arg is sampling period in ns. * Gate it off for now. */ - outb(GAT_CONFIG(1, GAT_GND), dev->iobase + PCI230_ZGAT_SCE); + outb(pci230_gat_config(1, GAT_GND), + dev->iobase + PCI230_ZGAT_SCE); pci230_ct_setup_ns_mode(dev, 1, I8254_MODE3, cmd->scan_begin_arg, cmd->flags); @@ -1792,9 +1798,9 @@ static int pci230_ai_inttrig_scan_begin(struct comedi_device *dev, spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags); if (devpriv->ai_cmd_started) { /* Trigger scan by waggling CT0 gate source. */ - zgat = GAT_CONFIG(0, GAT_GND); + zgat = pci230_gat_config(0, GAT_GND); outb(zgat, dev->iobase + PCI230_ZGAT_SCE); - zgat = GAT_CONFIG(0, GAT_VCC); + zgat = pci230_gat_config(0, GAT_VCC); outb(zgat, dev->iobase + PCI230_ZGAT_SCE); } spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags); @@ -1926,20 +1932,20 @@ static void pci230_ai_start(struct comedi_device *dev, * Conversion timer CT2 needs to be gated by * inverted output of monostable CT2. */ - zgat = GAT_CONFIG(2, GAT_NOUTNM2); + zgat = pci230_gat_config(2, GAT_NOUTNM2); } else { /* * Conversion timer CT2 needs to be gated on * continuously. */ - zgat = GAT_CONFIG(2, GAT_VCC); + zgat = pci230_gat_config(2, GAT_VCC); } outb(zgat, dev->iobase + PCI230_ZGAT_SCE); if (cmd->scan_begin_src != TRIG_FOLLOW) { /* Set monostable CT0 trigger source. */ switch (cmd->scan_begin_src) { default: - zgat = GAT_CONFIG(0, GAT_VCC); + zgat = pci230_gat_config(0, GAT_VCC); break; case TRIG_EXT: /* @@ -1950,21 +1956,21 @@ static void pci230_ai_start(struct comedi_device *dev, * input in order to use it as an external scan * trigger. */ - zgat = GAT_CONFIG(0, GAT_EXT); + zgat = pci230_gat_config(0, GAT_EXT); break; case TRIG_TIMER: /* * Monostable CT0 triggered by rising edge on * inverted output of CT1 (falling edge on CT1). */ - zgat = GAT_CONFIG(0, GAT_NOUTNM2); + zgat = pci230_gat_config(0, GAT_NOUTNM2); break; case TRIG_INT: /* * Monostable CT0 is triggered by inttrig * function waggling the CT0 gate source. */ - zgat = GAT_CONFIG(0, GAT_VCC); + zgat = pci230_gat_config(0, GAT_VCC); break; } outb(zgat, dev->iobase + PCI230_ZGAT_SCE); @@ -1974,7 +1980,7 @@ static void pci230_ai_start(struct comedi_device *dev, * Scan period timer CT1 needs to be * gated on to start counting. */ - zgat = GAT_CONFIG(1, GAT_VCC); + zgat = pci230_gat_config(1, GAT_VCC); outb(zgat, dev->iobase + PCI230_ZGAT_SCE); break; case TRIG_INT: @@ -2216,7 +2222,7 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) * Note, counter/timer output 2 can be monitored on the * connector: PCI230 pin 21, PCI260 pin 18. */ - zgat = GAT_CONFIG(2, GAT_GND); + zgat = pci230_gat_config(2, GAT_GND); outb(zgat, dev->iobase + PCI230_ZGAT_SCE); /* Set counter/timer 2 to the specified conversion period. */ pci230_ct_setup_ns_mode(dev, 2, I8254_MODE3, cmd->convert_arg, @@ -2234,7 +2240,7 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) * monostable to stop it triggering. The trigger * source will be changed later. */ - zgat = GAT_CONFIG(0, GAT_VCC); + zgat = pci230_gat_config(0, GAT_VCC); outb(zgat, dev->iobase + PCI230_ZGAT_SCE); pci230_ct_setup_ns_mode(dev, 0, I8254_MODE1, ((uint64_t)cmd->convert_arg * @@ -2247,7 +2253,7 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) * * Set up CT1 but gate it off for now. */ - zgat = GAT_CONFIG(1, GAT_GND); + zgat = pci230_gat_config(1, GAT_GND); outb(zgat, dev->iobase + PCI230_ZGAT_SCE); pci230_ct_setup_ns_mode(dev, 1, I8254_MODE3, cmd->scan_begin_arg, -- cgit v1.2.3 From a5948d917c5201fb8c4503d82fb6fc09da7ae726 Mon Sep 17 00:00:00 2001 From: Svetlana Orlik Date: Tue, 22 Mar 2016 07:51:36 +0300 Subject: Staging: iio: ad9832: Replace 'unsigned' with 'unsigned int' Replace 'unsigned' with 'unsigned int' to avoid checkpatch.pl warning. Signed-off-by: Svetlana Orlik Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/frequency/ad9832.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/iio/frequency/ad9832.c b/drivers/staging/iio/frequency/ad9832.c index 18b27a1984b2..358400b22d33 100644 --- a/drivers/staging/iio/frequency/ad9832.c +++ b/drivers/staging/iio/frequency/ad9832.c @@ -31,7 +31,7 @@ static unsigned long ad9832_calc_freqreg(unsigned long mclk, unsigned long fout) } static int ad9832_write_frequency(struct ad9832_state *st, - unsigned addr, unsigned long fout) + unsigned int addr, unsigned long fout) { unsigned long regval; -- cgit v1.2.3 From 3261c31c7c2bfbca6db3a7a934ba9341bf65b16d Mon Sep 17 00:00:00 2001 From: Svetlana Orlik Date: Tue, 22 Mar 2016 11:43:08 +0300 Subject: staging: iio: accel: adis16240: Replace 'unsigned' with 'unsigned int' Replace 'unsigned' with 'unsigned int' to avoid checkpatch warning. Signed-off-by: Svetlana Orlik Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/accel/adis16240_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c index 1b5b685a8691..a425e1894863 100644 --- a/drivers/staging/iio/accel/adis16240_core.c +++ b/drivers/staging/iio/accel/adis16240_core.c @@ -29,13 +29,13 @@ static ssize_t adis16240_spi_read_signed(struct device *dev, struct device_attribute *attr, char *buf, - unsigned bits) + unsigned int bits) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct adis *st = iio_priv(indio_dev); int ret; s16 val = 0; - unsigned shift = 16 - bits; + unsigned int shift = 16 - bits; struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); ret = adis_read_reg_16(st, -- cgit v1.2.3 From 81da8a8913e768d8ce0de9edb5699f3879c1dd51 Mon Sep 17 00:00:00 2001 From: Svetlana Orlik Date: Tue, 22 Mar 2016 18:07:22 +0300 Subject: staging: iio: accel: adis16204: Fix 'line over 80 characters' warning Many of the comments in the same lines with #define caused checkpatch warning 'line over 80 characters'. Move all such comments to line before #define. This style is already used in some other .h files in accel: Add blank lines after #define to improve readability. Signed-off-by: Svetlana Orlik Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/accel/adis16204.h | 159 +++++++++++++++++++++++++--------- 1 file changed, 118 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/accel/adis16204.h b/drivers/staging/iio/accel/adis16204.h index 0b23f0b5c52f..cfc4038ffdfb 100644 --- a/drivers/staging/iio/accel/adis16204.h +++ b/drivers/staging/iio/accel/adis16204.h @@ -3,53 +3,130 @@ #define ADIS16204_STARTUP_DELAY 220 /* ms */ -#define ADIS16204_FLASH_CNT 0x00 /* Flash memory write count */ -#define ADIS16204_SUPPLY_OUT 0x02 /* Output, power supply */ -#define ADIS16204_XACCL_OUT 0x04 /* Output, x-axis accelerometer */ -#define ADIS16204_YACCL_OUT 0x06 /* Output, y-axis accelerometer */ -#define ADIS16204_AUX_ADC 0x08 /* Output, auxiliary ADC input */ -#define ADIS16204_TEMP_OUT 0x0A /* Output, temperature */ -#define ADIS16204_X_PEAK_OUT 0x0C /* Twos complement */ -#define ADIS16204_Y_PEAK_OUT 0x0E /* Twos complement */ -#define ADIS16204_XACCL_NULL 0x10 /* Calibration, x-axis acceleration offset null */ -#define ADIS16204_YACCL_NULL 0x12 /* Calibration, y-axis acceleration offset null */ -#define ADIS16204_XACCL_SCALE 0x14 /* X-axis scale factor calibration register */ -#define ADIS16204_YACCL_SCALE 0x16 /* Y-axis scale factor calibration register */ -#define ADIS16204_XY_RSS_OUT 0x18 /* XY combined acceleration (RSS) */ -#define ADIS16204_XY_PEAK_OUT 0x1A /* Peak, XY combined output (RSS) */ -#define ADIS16204_CAP_BUF_1 0x1C /* Capture buffer output register 1 */ -#define ADIS16204_CAP_BUF_2 0x1E /* Capture buffer output register 2 */ -#define ADIS16204_ALM_MAG1 0x20 /* Alarm 1 amplitude threshold */ -#define ADIS16204_ALM_MAG2 0x22 /* Alarm 2 amplitude threshold */ -#define ADIS16204_ALM_CTRL 0x28 /* Alarm control */ -#define ADIS16204_CAPT_PNTR 0x2A /* Capture register address pointer */ -#define ADIS16204_AUX_DAC 0x30 /* Auxiliary DAC data */ -#define ADIS16204_GPIO_CTRL 0x32 /* General-purpose digital input/output control */ -#define ADIS16204_MSC_CTRL 0x34 /* Miscellaneous control */ -#define ADIS16204_SMPL_PRD 0x36 /* Internal sample period (rate) control */ -#define ADIS16204_AVG_CNT 0x38 /* Operation, filter configuration */ -#define ADIS16204_SLP_CNT 0x3A /* Operation, sleep mode control */ -#define ADIS16204_DIAG_STAT 0x3C /* Diagnostics, system status register */ -#define ADIS16204_GLOB_CMD 0x3E /* Operation, system command register */ +/* Flash memory write count */ +#define ADIS16204_FLASH_CNT 0x00 + +/* Output, power supply */ +#define ADIS16204_SUPPLY_OUT 0x02 + +/* Output, x-axis accelerometer */ +#define ADIS16204_XACCL_OUT 0x04 + +/* Output, y-axis accelerometer */ +#define ADIS16204_YACCL_OUT 0x06 + +/* Output, auxiliary ADC input */ +#define ADIS16204_AUX_ADC 0x08 + +/* Output, temperature */ +#define ADIS16204_TEMP_OUT 0x0A + +/* Twos complement */ +#define ADIS16204_X_PEAK_OUT 0x0C +#define ADIS16204_Y_PEAK_OUT 0x0E + +/* Calibration, x-axis acceleration offset null */ +#define ADIS16204_XACCL_NULL 0x10 + +/* Calibration, y-axis acceleration offset null */ +#define ADIS16204_YACCL_NULL 0x12 + +/* X-axis scale factor calibration register */ +#define ADIS16204_XACCL_SCALE 0x14 + +/* Y-axis scale factor calibration register */ +#define ADIS16204_YACCL_SCALE 0x16 + +/* XY combined acceleration (RSS) */ +#define ADIS16204_XY_RSS_OUT 0x18 + +/* Peak, XY combined output (RSS) */ +#define ADIS16204_XY_PEAK_OUT 0x1A + +/* Capture buffer output register 1 */ +#define ADIS16204_CAP_BUF_1 0x1C + +/* Capture buffer output register 2 */ +#define ADIS16204_CAP_BUF_2 0x1E + +/* Alarm 1 amplitude threshold */ +#define ADIS16204_ALM_MAG1 0x20 + +/* Alarm 2 amplitude threshold */ +#define ADIS16204_ALM_MAG2 0x22 + +/* Alarm control */ +#define ADIS16204_ALM_CTRL 0x28 + +/* Capture register address pointer */ +#define ADIS16204_CAPT_PNTR 0x2A + +/* Auxiliary DAC data */ +#define ADIS16204_AUX_DAC 0x30 + +/* General-purpose digital input/output control */ +#define ADIS16204_GPIO_CTRL 0x32 + +/* Miscellaneous control */ +#define ADIS16204_MSC_CTRL 0x34 + +/* Internal sample period (rate) control */ +#define ADIS16204_SMPL_PRD 0x36 + +/* Operation, filter configuration */ +#define ADIS16204_AVG_CNT 0x38 + +/* Operation, sleep mode control */ +#define ADIS16204_SLP_CNT 0x3A + +/* Diagnostics, system status register */ +#define ADIS16204_DIAG_STAT 0x3C + +/* Operation, system command register */ +#define ADIS16204_GLOB_CMD 0x3E /* MSC_CTRL */ -#define ADIS16204_MSC_CTRL_PWRUP_SELF_TEST BIT(10) /* Self-test at power-on: 1 = disabled, 0 = enabled */ -#define ADIS16204_MSC_CTRL_SELF_TEST_EN BIT(8) /* Self-test enable */ -#define ADIS16204_MSC_CTRL_DATA_RDY_EN BIT(2) /* Data-ready enable: 1 = enabled, 0 = disabled */ -#define ADIS16204_MSC_CTRL_ACTIVE_HIGH BIT(1) /* Data-ready polarity: 1 = active high, 0 = active low */ -#define ADIS16204_MSC_CTRL_DATA_RDY_DIO2 BIT(0) /* Data-ready line selection: 1 = DIO2, 0 = DIO1 */ + +/* Self-test at power-on: 1 = disabled, 0 = enabled */ +#define ADIS16204_MSC_CTRL_PWRUP_SELF_TEST BIT(10) + +/* Self-test enable */ +#define ADIS16204_MSC_CTRL_SELF_TEST_EN BIT(8) + +/* Data-ready enable: 1 = enabled, 0 = disabled */ +#define ADIS16204_MSC_CTRL_DATA_RDY_EN BIT(2) + +/* Data-ready polarity: 1 = active high, 0 = active low */ +#define ADIS16204_MSC_CTRL_ACTIVE_HIGH BIT(1) + +/* Data-ready line selection: 1 = DIO2, 0 = DIO1 */ +#define ADIS16204_MSC_CTRL_DATA_RDY_DIO2 BIT(0) /* DIAG_STAT */ -#define ADIS16204_DIAG_STAT_ALARM2 BIT(9) /* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */ -#define ADIS16204_DIAG_STAT_ALARM1 BIT(8) /* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */ -#define ADIS16204_DIAG_STAT_SELFTEST_FAIL_BIT 5 /* Self-test diagnostic error flag: 1 = error condition, - 0 = normal operation */ -#define ADIS16204_DIAG_STAT_SPI_FAIL_BIT 3 /* SPI communications failure */ -#define ADIS16204_DIAG_STAT_FLASH_UPT_BIT 2 /* Flash update failure */ -#define ADIS16204_DIAG_STAT_POWER_HIGH_BIT 1 /* Power supply above 3.625 V */ -#define ADIS16204_DIAG_STAT_POWER_LOW_BIT 0 /* Power supply below 2.975 V */ + +/* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */ +#define ADIS16204_DIAG_STAT_ALARM2 BIT(9) + +/* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */ +#define ADIS16204_DIAG_STAT_ALARM1 BIT(8) + +/* Self-test diagnostic error flag: 1 = error condition, 0 = normal operation */ +#define ADIS16204_DIAG_STAT_SELFTEST_FAIL_BIT 5 + +/* SPI communications failure */ +#define ADIS16204_DIAG_STAT_SPI_FAIL_BIT 3 + +/* Flash update failure */ +#define ADIS16204_DIAG_STAT_FLASH_UPT_BIT 2 + +/* Power supply above 3.625 V */ +#define ADIS16204_DIAG_STAT_POWER_HIGH_BIT 1 + +/* Power supply below 2.975 V */ +#define ADIS16204_DIAG_STAT_POWER_LOW_BIT 0 /* GLOB_CMD */ + #define ADIS16204_GLOB_CMD_SW_RESET BIT(7) #define ADIS16204_GLOB_CMD_CLEAR_STAT BIT(4) #define ADIS16204_GLOB_CMD_FACTORY_CAL BIT(1) -- cgit v1.2.3 From a48b2362dd8bcdb3d8c65c7e5eca942bda7762b5 Mon Sep 17 00:00:00 2001 From: Svetlana Orlik Date: Tue, 22 Mar 2016 18:08:03 +0300 Subject: staging: iio: accel: adis16203: Fix 'line over 80 characters' warning Many of the comments in the same lines with #define caused checkpatch warning 'line over 80 characters'. Move all such comments to line before #define. This style is already used in some other .h files in accel: Add blank lines after #define to improve readability. Signed-off-by: Svetlana Orlik Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/accel/adis16203.h | 132 +++++++++++++++++++++++++--------- 1 file changed, 99 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/accel/adis16203.h b/drivers/staging/iio/accel/adis16203.h index 6426e38bf006..b483e4e6475b 100644 --- a/drivers/staging/iio/accel/adis16203.h +++ b/drivers/staging/iio/accel/adis16203.h @@ -3,45 +3,111 @@ #define ADIS16203_STARTUP_DELAY 220 /* ms */ -#define ADIS16203_FLASH_CNT 0x00 /* Flash memory write count */ -#define ADIS16203_SUPPLY_OUT 0x02 /* Output, power supply */ -#define ADIS16203_AUX_ADC 0x08 /* Output, auxiliary ADC input */ -#define ADIS16203_TEMP_OUT 0x0A /* Output, temperature */ -#define ADIS16203_XINCL_OUT 0x0C /* Output, x-axis inclination */ -#define ADIS16203_YINCL_OUT 0x0E /* Output, y-axis inclination */ -#define ADIS16203_INCL_NULL 0x18 /* Incline null calibration */ -#define ADIS16203_ALM_MAG1 0x20 /* Alarm 1 amplitude threshold */ -#define ADIS16203_ALM_MAG2 0x22 /* Alarm 2 amplitude threshold */ -#define ADIS16203_ALM_SMPL1 0x24 /* Alarm 1, sample period */ -#define ADIS16203_ALM_SMPL2 0x26 /* Alarm 2, sample period */ -#define ADIS16203_ALM_CTRL 0x28 /* Alarm control */ -#define ADIS16203_AUX_DAC 0x30 /* Auxiliary DAC data */ -#define ADIS16203_GPIO_CTRL 0x32 /* General-purpose digital input/output control */ -#define ADIS16203_MSC_CTRL 0x34 /* Miscellaneous control */ -#define ADIS16203_SMPL_PRD 0x36 /* Internal sample period (rate) control */ -#define ADIS16203_AVG_CNT 0x38 /* Operation, filter configuration */ -#define ADIS16203_SLP_CNT 0x3A /* Operation, sleep mode control */ -#define ADIS16203_DIAG_STAT 0x3C /* Diagnostics, system status register */ -#define ADIS16203_GLOB_CMD 0x3E /* Operation, system command register */ +/* Flash memory write count */ +#define ADIS16203_FLASH_CNT 0x00 + +/* Output, power supply */ +#define ADIS16203_SUPPLY_OUT 0x02 + +/* Output, auxiliary ADC input */ +#define ADIS16203_AUX_ADC 0x08 + +/* Output, temperature */ +#define ADIS16203_TEMP_OUT 0x0A + +/* Output, x-axis inclination */ +#define ADIS16203_XINCL_OUT 0x0C + +/* Output, y-axis inclination */ +#define ADIS16203_YINCL_OUT 0x0E + +/* Incline null calibration */ +#define ADIS16203_INCL_NULL 0x18 + +/* Alarm 1 amplitude threshold */ +#define ADIS16203_ALM_MAG1 0x20 + +/* Alarm 2 amplitude threshold */ +#define ADIS16203_ALM_MAG2 0x22 + +/* Alarm 1, sample period */ +#define ADIS16203_ALM_SMPL1 0x24 + +/* Alarm 2, sample period */ +#define ADIS16203_ALM_SMPL2 0x26 + +/* Alarm control */ +#define ADIS16203_ALM_CTRL 0x28 + +/* Auxiliary DAC data */ +#define ADIS16203_AUX_DAC 0x30 + +/* General-purpose digital input/output control */ +#define ADIS16203_GPIO_CTRL 0x32 + +/* Miscellaneous control */ +#define ADIS16203_MSC_CTRL 0x34 + +/* Internal sample period (rate) control */ +#define ADIS16203_SMPL_PRD 0x36 + +/* Operation, filter configuration */ +#define ADIS16203_AVG_CNT 0x38 + +/* Operation, sleep mode control */ +#define ADIS16203_SLP_CNT 0x3A + +/* Diagnostics, system status register */ +#define ADIS16203_DIAG_STAT 0x3C + +/* Operation, system command register */ +#define ADIS16203_GLOB_CMD 0x3E /* MSC_CTRL */ -#define ADIS16203_MSC_CTRL_PWRUP_SELF_TEST BIT(10) /* Self-test at power-on: 1 = disabled, 0 = enabled */ -#define ADIS16203_MSC_CTRL_REVERSE_ROT_EN BIT(9) /* Reverses rotation of both inclination outputs */ -#define ADIS16203_MSC_CTRL_SELF_TEST_EN BIT(8) /* Self-test enable */ -#define ADIS16203_MSC_CTRL_DATA_RDY_EN BIT(2) /* Data-ready enable: 1 = enabled, 0 = disabled */ -#define ADIS16203_MSC_CTRL_ACTIVE_HIGH BIT(1) /* Data-ready polarity: 1 = active high, 0 = active low */ -#define ADIS16203_MSC_CTRL_DATA_RDY_DIO1 BIT(0) /* Data-ready line selection: 1 = DIO1, 0 = DIO0 */ + +/* Self-test at power-on: 1 = disabled, 0 = enabled */ +#define ADIS16203_MSC_CTRL_PWRUP_SELF_TEST BIT(10) + +/* Reverses rotation of both inclination outputs */ +#define ADIS16203_MSC_CTRL_REVERSE_ROT_EN BIT(9) + +/* Self-test enable */ +#define ADIS16203_MSC_CTRL_SELF_TEST_EN BIT(8) + +/* Data-ready enable: 1 = enabled, 0 = disabled */ +#define ADIS16203_MSC_CTRL_DATA_RDY_EN BIT(2) + +/* Data-ready polarity: 1 = active high, 0 = active low */ +#define ADIS16203_MSC_CTRL_ACTIVE_HIGH BIT(1) + +/* Data-ready line selection: 1 = DIO1, 0 = DIO0 */ +#define ADIS16203_MSC_CTRL_DATA_RDY_DIO1 BIT(0) /* DIAG_STAT */ -#define ADIS16203_DIAG_STAT_ALARM2 BIT(9) /* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */ -#define ADIS16203_DIAG_STAT_ALARM1 BIT(8) /* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */ -#define ADIS16203_DIAG_STAT_SELFTEST_FAIL_BIT 5 /* Self-test diagnostic error flag */ -#define ADIS16203_DIAG_STAT_SPI_FAIL_BIT 3 /* SPI communications failure */ -#define ADIS16203_DIAG_STAT_FLASH_UPT_BIT 2 /* Flash update failure */ -#define ADIS16203_DIAG_STAT_POWER_HIGH_BIT 1 /* Power supply above 3.625 V */ -#define ADIS16203_DIAG_STAT_POWER_LOW_BIT 0 /* Power supply below 3.15 V */ + +/* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */ +#define ADIS16203_DIAG_STAT_ALARM2 BIT(9) + +/* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */ +#define ADIS16203_DIAG_STAT_ALARM1 BIT(8) + +/* Self-test diagnostic error flag */ +#define ADIS16203_DIAG_STAT_SELFTEST_FAIL_BIT 5 + +/* SPI communications failure */ +#define ADIS16203_DIAG_STAT_SPI_FAIL_BIT 3 + +/* Flash update failure */ +#define ADIS16203_DIAG_STAT_FLASH_UPT_BIT 2 + +/* Power supply above 3.625 V */ +#define ADIS16203_DIAG_STAT_POWER_HIGH_BIT 1 + +/* Power supply below 3.15 V */ +#define ADIS16203_DIAG_STAT_POWER_LOW_BIT 0 /* GLOB_CMD */ + #define ADIS16203_GLOB_CMD_SW_RESET BIT(7) #define ADIS16203_GLOB_CMD_CLEAR_STAT BIT(4) #define ADIS16203_GLOB_CMD_FACTORY_CAL BIT(1) -- cgit v1.2.3 From 0f5c42116ee7c6f9495222bf53370d19003b946b Mon Sep 17 00:00:00 2001 From: Svetlana Orlik Date: Tue, 22 Mar 2016 18:08:38 +0300 Subject: staging: iio: accel: adis16201: Fix 'line over 80 characters' warning Many of the comments in the same lines with #define caused checkpatch warning 'line over 80 characters'. Move all such comments to line before #define. This style is already used in some other .h files in accel: Add blank lines after #define to improve readability. Signed-off-by: Svetlana Orlik Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/accel/adis16201.h | 156 +++++++++++++++++++++++++--------- 1 file changed, 117 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/accel/adis16201.h b/drivers/staging/iio/accel/adis16201.h index e6b8c9af6e22..64844adcaacd 100644 --- a/drivers/staging/iio/accel/adis16201.h +++ b/drivers/staging/iio/accel/adis16201.h @@ -3,51 +3,129 @@ #define ADIS16201_STARTUP_DELAY 220 /* ms */ -#define ADIS16201_FLASH_CNT 0x00 /* Flash memory write count */ -#define ADIS16201_SUPPLY_OUT 0x02 /* Output, power supply */ -#define ADIS16201_XACCL_OUT 0x04 /* Output, x-axis accelerometer */ -#define ADIS16201_YACCL_OUT 0x06 /* Output, y-axis accelerometer */ -#define ADIS16201_AUX_ADC 0x08 /* Output, auxiliary ADC input */ -#define ADIS16201_TEMP_OUT 0x0A /* Output, temperature */ -#define ADIS16201_XINCL_OUT 0x0C /* Output, x-axis inclination */ -#define ADIS16201_YINCL_OUT 0x0E /* Output, y-axis inclination */ -#define ADIS16201_XACCL_OFFS 0x10 /* Calibration, x-axis acceleration offset */ -#define ADIS16201_YACCL_OFFS 0x12 /* Calibration, y-axis acceleration offset */ -#define ADIS16201_XACCL_SCALE 0x14 /* x-axis acceleration scale factor */ -#define ADIS16201_YACCL_SCALE 0x16 /* y-axis acceleration scale factor */ -#define ADIS16201_XINCL_OFFS 0x18 /* Calibration, x-axis inclination offset */ -#define ADIS16201_YINCL_OFFS 0x1A /* Calibration, y-axis inclination offset */ -#define ADIS16201_XINCL_SCALE 0x1C /* x-axis inclination scale factor */ -#define ADIS16201_YINCL_SCALE 0x1E /* y-axis inclination scale factor */ -#define ADIS16201_ALM_MAG1 0x20 /* Alarm 1 amplitude threshold */ -#define ADIS16201_ALM_MAG2 0x22 /* Alarm 2 amplitude threshold */ -#define ADIS16201_ALM_SMPL1 0x24 /* Alarm 1, sample period */ -#define ADIS16201_ALM_SMPL2 0x26 /* Alarm 2, sample period */ -#define ADIS16201_ALM_CTRL 0x28 /* Alarm control */ -#define ADIS16201_AUX_DAC 0x30 /* Auxiliary DAC data */ -#define ADIS16201_GPIO_CTRL 0x32 /* General-purpose digital input/output control */ -#define ADIS16201_MSC_CTRL 0x34 /* Miscellaneous control */ -#define ADIS16201_SMPL_PRD 0x36 /* Internal sample period (rate) control */ -#define ADIS16201_AVG_CNT 0x38 /* Operation, filter configuration */ -#define ADIS16201_SLP_CNT 0x3A /* Operation, sleep mode control */ -#define ADIS16201_DIAG_STAT 0x3C /* Diagnostics, system status register */ -#define ADIS16201_GLOB_CMD 0x3E /* Operation, system command register */ +/* Flash memory write count */ +#define ADIS16201_FLASH_CNT 0x00 + +/* Output, power supply */ +#define ADIS16201_SUPPLY_OUT 0x02 + +/* Output, x-axis accelerometer */ +#define ADIS16201_XACCL_OUT 0x04 + +/* Output, y-axis accelerometer */ +#define ADIS16201_YACCL_OUT 0x06 + +/* Output, auxiliary ADC input */ +#define ADIS16201_AUX_ADC 0x08 + +/* Output, temperature */ +#define ADIS16201_TEMP_OUT 0x0A + +/* Output, x-axis inclination */ +#define ADIS16201_XINCL_OUT 0x0C + +/* Output, y-axis inclination */ +#define ADIS16201_YINCL_OUT 0x0E + +/* Calibration, x-axis acceleration offset */ +#define ADIS16201_XACCL_OFFS 0x10 + +/* Calibration, y-axis acceleration offset */ +#define ADIS16201_YACCL_OFFS 0x12 + +/* x-axis acceleration scale factor */ +#define ADIS16201_XACCL_SCALE 0x14 + +/* y-axis acceleration scale factor */ +#define ADIS16201_YACCL_SCALE 0x16 + +/* Calibration, x-axis inclination offset */ +#define ADIS16201_XINCL_OFFS 0x18 + +/* Calibration, y-axis inclination offset */ +#define ADIS16201_YINCL_OFFS 0x1A + +/* x-axis inclination scale factor */ +#define ADIS16201_XINCL_SCALE 0x1C + +/* y-axis inclination scale factor */ +#define ADIS16201_YINCL_SCALE 0x1E + +/* Alarm 1 amplitude threshold */ +#define ADIS16201_ALM_MAG1 0x20 + +/* Alarm 2 amplitude threshold */ +#define ADIS16201_ALM_MAG2 0x22 + +/* Alarm 1, sample period */ +#define ADIS16201_ALM_SMPL1 0x24 + +/* Alarm 2, sample period */ +#define ADIS16201_ALM_SMPL2 0x26 + +/* Alarm control */ +#define ADIS16201_ALM_CTRL 0x28 + +/* Auxiliary DAC data */ +#define ADIS16201_AUX_DAC 0x30 + +/* General-purpose digital input/output control */ +#define ADIS16201_GPIO_CTRL 0x32 + +/* Miscellaneous control */ +#define ADIS16201_MSC_CTRL 0x34 + +/* Internal sample period (rate) control */ +#define ADIS16201_SMPL_PRD 0x36 + +/* Operation, filter configuration */ +#define ADIS16201_AVG_CNT 0x38 + +/* Operation, sleep mode control */ +#define ADIS16201_SLP_CNT 0x3A + +/* Diagnostics, system status register */ +#define ADIS16201_DIAG_STAT 0x3C + +/* Operation, system command register */ +#define ADIS16201_GLOB_CMD 0x3E /* MSC_CTRL */ -#define ADIS16201_MSC_CTRL_SELF_TEST_EN BIT(8) /* Self-test enable */ -#define ADIS16201_MSC_CTRL_DATA_RDY_EN BIT(2) /* Data-ready enable: 1 = enabled, 0 = disabled */ -#define ADIS16201_MSC_CTRL_ACTIVE_HIGH BIT(1) /* Data-ready polarity: 1 = active high, 0 = active low */ -#define ADIS16201_MSC_CTRL_DATA_RDY_DIO1 BIT(0) /* Data-ready line selection: 1 = DIO1, 0 = DIO0 */ + +/* Self-test enable */ +#define ADIS16201_MSC_CTRL_SELF_TEST_EN BIT(8) + +/* Data-ready enable: 1 = enabled, 0 = disabled */ +#define ADIS16201_MSC_CTRL_DATA_RDY_EN BIT(2) + +/* Data-ready polarity: 1 = active high, 0 = active low */ +#define ADIS16201_MSC_CTRL_ACTIVE_HIGH BIT(1) + +/* Data-ready line selection: 1 = DIO1, 0 = DIO0 */ +#define ADIS16201_MSC_CTRL_DATA_RDY_DIO1 BIT(0) /* DIAG_STAT */ -#define ADIS16201_DIAG_STAT_ALARM2 BIT(9) /* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */ -#define ADIS16201_DIAG_STAT_ALARM1 BIT(8) /* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */ -#define ADIS16201_DIAG_STAT_SPI_FAIL_BIT 3 /* SPI communications failure */ -#define ADIS16201_DIAG_STAT_FLASH_UPT_BIT 2 /* Flash update failure */ -#define ADIS16201_DIAG_STAT_POWER_HIGH_BIT 1 /* Power supply above 3.625 V */ -#define ADIS16201_DIAG_STAT_POWER_LOW_BIT 0 /* Power supply below 3.15 V */ + +/* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */ +#define ADIS16201_DIAG_STAT_ALARM2 BIT(9) + +/* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */ +#define ADIS16201_DIAG_STAT_ALARM1 BIT(8) + +/* SPI communications failure */ +#define ADIS16201_DIAG_STAT_SPI_FAIL_BIT 3 + +/* Flash update failure */ +#define ADIS16201_DIAG_STAT_FLASH_UPT_BIT 2 + +/* Power supply above 3.625 V */ +#define ADIS16201_DIAG_STAT_POWER_HIGH_BIT 1 + +/* Power supply below 3.15 V */ +#define ADIS16201_DIAG_STAT_POWER_LOW_BIT 0 /* GLOB_CMD */ + #define ADIS16201_GLOB_CMD_SW_RESET BIT(7) #define ADIS16201_GLOB_CMD_FACTORY_CAL BIT(1) -- cgit v1.2.3 From 328bdff8ec599ff1b86e52f5d99d31e55c4fbb0b Mon Sep 17 00:00:00 2001 From: Svetlana Orlik Date: Tue, 22 Mar 2016 18:09:21 +0300 Subject: staging: iio: accel: adis16209: Improve readability Lines with #define interlaced with comment lines making a mess. Separate groups of #define-comment with blank lines. Separate section title comments with blank lines. Signed-off-by: Svetlana Orlik Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/accel/adis16209.h | 39 +++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/iio/accel/adis16209.h b/drivers/staging/iio/accel/adis16209.h index 813698d18ec8..315f1c0c46e8 100644 --- a/drivers/staging/iio/accel/adis16209.h +++ b/drivers/staging/iio/accel/adis16209.h @@ -5,88 +5,127 @@ /* Flash memory write count */ #define ADIS16209_FLASH_CNT 0x00 + /* Output, power supply */ #define ADIS16209_SUPPLY_OUT 0x02 + /* Output, x-axis accelerometer */ #define ADIS16209_XACCL_OUT 0x04 + /* Output, y-axis accelerometer */ #define ADIS16209_YACCL_OUT 0x06 + /* Output, auxiliary ADC input */ #define ADIS16209_AUX_ADC 0x08 + /* Output, temperature */ #define ADIS16209_TEMP_OUT 0x0A + /* Output, x-axis inclination */ #define ADIS16209_XINCL_OUT 0x0C + /* Output, y-axis inclination */ #define ADIS16209_YINCL_OUT 0x0E + /* Output, +/-180 vertical rotational position */ #define ADIS16209_ROT_OUT 0x10 + /* Calibration, x-axis acceleration offset null */ #define ADIS16209_XACCL_NULL 0x12 + /* Calibration, y-axis acceleration offset null */ #define ADIS16209_YACCL_NULL 0x14 + /* Calibration, x-axis inclination offset null */ #define ADIS16209_XINCL_NULL 0x16 + /* Calibration, y-axis inclination offset null */ #define ADIS16209_YINCL_NULL 0x18 + /* Calibration, vertical rotation offset null */ #define ADIS16209_ROT_NULL 0x1A + /* Alarm 1 amplitude threshold */ #define ADIS16209_ALM_MAG1 0x20 + /* Alarm 2 amplitude threshold */ #define ADIS16209_ALM_MAG2 0x22 + /* Alarm 1, sample period */ #define ADIS16209_ALM_SMPL1 0x24 + /* Alarm 2, sample period */ #define ADIS16209_ALM_SMPL2 0x26 + /* Alarm control */ #define ADIS16209_ALM_CTRL 0x28 + /* Auxiliary DAC data */ #define ADIS16209_AUX_DAC 0x30 + /* General-purpose digital input/output control */ #define ADIS16209_GPIO_CTRL 0x32 + /* Miscellaneous control */ #define ADIS16209_MSC_CTRL 0x34 + /* Internal sample period (rate) control */ #define ADIS16209_SMPL_PRD 0x36 + /* Operation, filter configuration */ #define ADIS16209_AVG_CNT 0x38 + /* Operation, sleep mode control */ #define ADIS16209_SLP_CNT 0x3A + /* Diagnostics, system status register */ #define ADIS16209_DIAG_STAT 0x3C + /* Operation, system command register */ #define ADIS16209_GLOB_CMD 0x3E /* MSC_CTRL */ + /* Self-test at power-on: 1 = disabled, 0 = enabled */ #define ADIS16209_MSC_CTRL_PWRUP_SELF_TEST BIT(10) + /* Self-test enable */ #define ADIS16209_MSC_CTRL_SELF_TEST_EN BIT(8) + /* Data-ready enable: 1 = enabled, 0 = disabled */ #define ADIS16209_MSC_CTRL_DATA_RDY_EN BIT(2) + /* Data-ready polarity: 1 = active high, 0 = active low */ #define ADIS16209_MSC_CTRL_ACTIVE_HIGH BIT(1) + /* Data-ready line selection: 1 = DIO2, 0 = DIO1 */ #define ADIS16209_MSC_CTRL_DATA_RDY_DIO2 BIT(0) /* DIAG_STAT */ + /* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */ #define ADIS16209_DIAG_STAT_ALARM2 BIT(9) + /* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */ #define ADIS16209_DIAG_STAT_ALARM1 BIT(8) + /* Self-test diagnostic error flag: 1 = error condition, 0 = normal operation */ #define ADIS16209_DIAG_STAT_SELFTEST_FAIL_BIT 5 + /* SPI communications failure */ #define ADIS16209_DIAG_STAT_SPI_FAIL_BIT 3 + /* Flash update failure */ #define ADIS16209_DIAG_STAT_FLASH_UPT_BIT 2 + /* Power supply above 3.625 V */ #define ADIS16209_DIAG_STAT_POWER_HIGH_BIT 1 + /* Power supply below 3.15 V */ #define ADIS16209_DIAG_STAT_POWER_LOW_BIT 0 /* GLOB_CMD */ + #define ADIS16209_GLOB_CMD_SW_RESET BIT(7) #define ADIS16209_GLOB_CMD_CLEAR_STAT BIT(4) #define ADIS16209_GLOB_CMD_FACTORY_CAL BIT(1) -- cgit v1.2.3 From 7da6ec4870801c7be8cafb861a87697dd842a1d4 Mon Sep 17 00:00:00 2001 From: Svetlana Orlik Date: Tue, 22 Mar 2016 18:09:53 +0300 Subject: staging: iio: accel: adis16220: Improve readability Lines with #define interlaced with comment lines making a mess. Separate groups of #define-comment with blank lines. Separate section title comments with blank lines. Signed-off-by: Svetlana Orlik Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/accel/adis16220.h | 48 +++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/iio/accel/adis16220.h b/drivers/staging/iio/accel/adis16220.h index eab86331124f..31a1268bbfad 100644 --- a/drivers/staging/iio/accel/adis16220.h +++ b/drivers/staging/iio/accel/adis16220.h @@ -7,111 +7,159 @@ /* Flash memory write count */ #define ADIS16220_FLASH_CNT 0x00 + /* Control, acceleration offset adjustment control */ #define ADIS16220_ACCL_NULL 0x02 + /* Control, AIN1 offset adjustment control */ #define ADIS16220_AIN1_NULL 0x04 + /* Control, AIN2 offset adjustment control */ #define ADIS16220_AIN2_NULL 0x06 + /* Output, power supply during capture */ #define ADIS16220_CAPT_SUPPLY 0x0A + /* Output, temperature during capture */ #define ADIS16220_CAPT_TEMP 0x0C + /* Output, peak acceleration during capture */ #define ADIS16220_CAPT_PEAKA 0x0E + /* Output, peak AIN1 level during capture */ #define ADIS16220_CAPT_PEAK1 0x10 + /* Output, peak AIN2 level during capture */ #define ADIS16220_CAPT_PEAK2 0x12 + /* Output, capture buffer for acceleration */ #define ADIS16220_CAPT_BUFA 0x14 + /* Output, capture buffer for AIN1 */ #define ADIS16220_CAPT_BUF1 0x16 + /* Output, capture buffer for AIN2 */ #define ADIS16220_CAPT_BUF2 0x18 + /* Control, capture buffer address pointer */ #define ADIS16220_CAPT_PNTR 0x1A + /* Control, capture control register */ #define ADIS16220_CAPT_CTRL 0x1C + /* Control, capture period (automatic mode) */ #define ADIS16220_CAPT_PRD 0x1E + /* Control, Alarm A, acceleration peak threshold */ #define ADIS16220_ALM_MAGA 0x20 + /* Control, Alarm 1, AIN1 peak threshold */ #define ADIS16220_ALM_MAG1 0x22 + /* Control, Alarm 2, AIN2 peak threshold */ #define ADIS16220_ALM_MAG2 0x24 + /* Control, Alarm S, peak threshold */ #define ADIS16220_ALM_MAGS 0x26 + /* Control, alarm configuration register */ #define ADIS16220_ALM_CTRL 0x28 + /* Control, general I/O configuration */ #define ADIS16220_GPIO_CTRL 0x32 + /* Control, self-test control, AIN configuration */ #define ADIS16220_MSC_CTRL 0x34 + /* Control, digital I/O configuration */ #define ADIS16220_DIO_CTRL 0x36 + /* Control, filter configuration */ #define ADIS16220_AVG_CNT 0x38 + /* Status, system status */ #define ADIS16220_DIAG_STAT 0x3C + /* Control, system commands */ #define ADIS16220_GLOB_CMD 0x3E + /* Status, self-test response */ #define ADIS16220_ST_DELTA 0x40 + /* Lot Identification Code 1 */ #define ADIS16220_LOT_ID1 0x52 + /* Lot Identification Code 2 */ #define ADIS16220_LOT_ID2 0x54 + /* Product identifier; convert to decimal = 16220 */ #define ADIS16220_PROD_ID 0x56 + /* Serial number */ #define ADIS16220_SERIAL_NUM 0x58 #define ADIS16220_CAPTURE_SIZE 2048 /* MSC_CTRL */ + #define ADIS16220_MSC_CTRL_SELF_TEST_EN BIT(8) #define ADIS16220_MSC_CTRL_POWER_SUP_COM_AIN1 BIT(1) #define ADIS16220_MSC_CTRL_POWER_SUP_COM_AIN2 BIT(0) /* DIO_CTRL */ + #define ADIS16220_MSC_CTRL_DIO2_BUSY_IND (BIT(5) | BIT(4)) #define ADIS16220_MSC_CTRL_DIO1_BUSY_IND (BIT(3) | BIT(2)) #define ADIS16220_MSC_CTRL_DIO2_ACT_HIGH BIT(1) #define ADIS16220_MSC_CTRL_DIO1_ACT_HIGH BIT(0) /* DIAG_STAT */ + /* AIN2 sample > ALM_MAG2 */ #define ADIS16220_DIAG_STAT_ALM_MAG2 BIT(14) + /* AIN1 sample > ALM_MAG1 */ #define ADIS16220_DIAG_STAT_ALM_MAG1 BIT(13) + /* Acceleration sample > ALM_MAGA */ #define ADIS16220_DIAG_STAT_ALM_MAGA BIT(12) + /* Error condition programmed into ALM_MAGS[11:0] and ALM_CTRL[5:4] is true */ #define ADIS16220_DIAG_STAT_ALM_MAGS BIT(11) + /* |Peak value in AIN2 data capture| > ALM_MAG2 */ #define ADIS16220_DIAG_STAT_PEAK_AIN2 BIT(10) + /* |Peak value in AIN1 data capture| > ALM_MAG1 */ #define ADIS16220_DIAG_STAT_PEAK_AIN1 BIT(9) + /* |Peak value in acceleration data capture| > ALM_MAGA */ #define ADIS16220_DIAG_STAT_PEAK_ACCEL BIT(8) + /* Data ready, capture complete */ #define ADIS16220_DIAG_STAT_DATA_RDY BIT(7) + #define ADIS16220_DIAG_STAT_FLASH_CHK BIT(6) + #define ADIS16220_DIAG_STAT_SELF_TEST BIT(5) + /* Capture period violation/interruption */ #define ADIS16220_DIAG_STAT_VIOLATION_BIT 4 + /* SPI communications failure */ #define ADIS16220_DIAG_STAT_SPI_FAIL_BIT 3 + /* Flash update failure */ #define ADIS16220_DIAG_STAT_FLASH_UPT_BIT 2 + /* Power supply above 3.625 V */ #define ADIS16220_DIAG_STAT_POWER_HIGH_BIT 1 + /* Power supply below 3.15 V */ #define ADIS16220_DIAG_STAT_POWER_LOW_BIT 0 /* GLOB_CMD */ + #define ADIS16220_GLOB_CMD_SW_RESET BIT(7) #define ADIS16220_GLOB_CMD_SELF_TEST BIT(2) #define ADIS16220_GLOB_CMD_PWR_DOWN BIT(1) -- cgit v1.2.3 From b075286912ac435f72d864b2a6dae7ec25eece5d Mon Sep 17 00:00:00 2001 From: Svetlana Orlik Date: Tue, 22 Mar 2016 18:10:32 +0300 Subject: staging: iio: accel: adis16240: Improve readability Lines with #define interlaced with comment lines making a mess. Separate groups of #define-comment with blank lines. Separate section title comments with blank lines. Signed-off-by: Svetlana Orlik Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/accel/adis16240.h | 50 +++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/iio/accel/adis16240.h b/drivers/staging/iio/accel/adis16240.h index 66b5ad2f42c5..b2cb37b95913 100644 --- a/drivers/staging/iio/accel/adis16240.h +++ b/drivers/staging/iio/accel/adis16240.h @@ -5,110 +5,160 @@ /* Flash memory write count */ #define ADIS16240_FLASH_CNT 0x00 + /* Output, power supply */ #define ADIS16240_SUPPLY_OUT 0x02 + /* Output, x-axis accelerometer */ #define ADIS16240_XACCL_OUT 0x04 + /* Output, y-axis accelerometer */ #define ADIS16240_YACCL_OUT 0x06 + /* Output, z-axis accelerometer */ #define ADIS16240_ZACCL_OUT 0x08 + /* Output, auxiliary ADC input */ #define ADIS16240_AUX_ADC 0x0A + /* Output, temperature */ #define ADIS16240_TEMP_OUT 0x0C + /* Output, x-axis acceleration peak */ #define ADIS16240_XPEAK_OUT 0x0E + /* Output, y-axis acceleration peak */ #define ADIS16240_YPEAK_OUT 0x10 + /* Output, z-axis acceleration peak */ #define ADIS16240_ZPEAK_OUT 0x12 + /* Output, sum-of-squares acceleration peak */ #define ADIS16240_XYZPEAK_OUT 0x14 + /* Output, Capture Buffer 1, X and Y acceleration */ #define ADIS16240_CAPT_BUF1 0x16 + /* Output, Capture Buffer 2, Z acceleration */ #define ADIS16240_CAPT_BUF2 0x18 + /* Diagnostic, error flags */ #define ADIS16240_DIAG_STAT 0x1A + /* Diagnostic, event counter */ #define ADIS16240_EVNT_CNTR 0x1C + /* Diagnostic, check sum value from firmware test */ #define ADIS16240_CHK_SUM 0x1E + /* Calibration, x-axis acceleration offset adjustment */ #define ADIS16240_XACCL_OFF 0x20 + /* Calibration, y-axis acceleration offset adjustment */ #define ADIS16240_YACCL_OFF 0x22 + /* Calibration, z-axis acceleration offset adjustment */ #define ADIS16240_ZACCL_OFF 0x24 + /* Clock, hour and minute */ #define ADIS16240_CLK_TIME 0x2E + /* Clock, month and day */ #define ADIS16240_CLK_DATE 0x30 + /* Clock, year */ #define ADIS16240_CLK_YEAR 0x32 + /* Wake-up setting, hour and minute */ #define ADIS16240_WAKE_TIME 0x34 + /* Wake-up setting, month and day */ #define ADIS16240_WAKE_DATE 0x36 + /* Alarm 1 amplitude threshold */ #define ADIS16240_ALM_MAG1 0x38 + /* Alarm 2 amplitude threshold */ #define ADIS16240_ALM_MAG2 0x3A + /* Alarm control */ #define ADIS16240_ALM_CTRL 0x3C + /* Capture, external trigger control */ #define ADIS16240_XTRIG_CTRL 0x3E + /* Capture, address pointer */ #define ADIS16240_CAPT_PNTR 0x40 + /* Capture, configuration and control */ #define ADIS16240_CAPT_CTRL 0x42 + /* General-purpose digital input/output control */ #define ADIS16240_GPIO_CTRL 0x44 + /* Miscellaneous control */ #define ADIS16240_MSC_CTRL 0x46 + /* Internal sample period (rate) control */ #define ADIS16240_SMPL_PRD 0x48 + /* System command */ #define ADIS16240_GLOB_CMD 0x4A /* MSC_CTRL */ + /* Enables sum-of-squares output (XYZPEAK_OUT) */ #define ADIS16240_MSC_CTRL_XYZPEAK_OUT_EN BIT(15) + /* Enables peak tracking output (XPEAK_OUT, YPEAK_OUT, and ZPEAK_OUT) */ #define ADIS16240_MSC_CTRL_X_Y_ZPEAK_OUT_EN BIT(14) + /* Self-test enable: 1 = apply electrostatic force, 0 = disabled */ #define ADIS16240_MSC_CTRL_SELF_TEST_EN BIT(8) + /* Data-ready enable: 1 = enabled, 0 = disabled */ #define ADIS16240_MSC_CTRL_DATA_RDY_EN BIT(2) + /* Data-ready polarity: 1 = active high, 0 = active low */ #define ADIS16240_MSC_CTRL_ACTIVE_HIGH BIT(1) + /* Data-ready line selection: 1 = DIO2, 0 = DIO1 */ #define ADIS16240_MSC_CTRL_DATA_RDY_DIO2 BIT(0) /* DIAG_STAT */ + /* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */ #define ADIS16240_DIAG_STAT_ALARM2 BIT(9) + /* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */ #define ADIS16240_DIAG_STAT_ALARM1 BIT(8) + /* Capture buffer full: 1 = capture buffer is full */ #define ADIS16240_DIAG_STAT_CPT_BUF_FUL BIT(7) + /* Flash test, checksum flag: 1 = mismatch, 0 = match */ #define ADIS16240_DIAG_STAT_CHKSUM BIT(6) + /* Power-on, self-test flag: 1 = failure, 0 = pass */ #define ADIS16240_DIAG_STAT_PWRON_FAIL_BIT 5 + /* Power-on self-test: 1 = in-progress, 0 = complete */ #define ADIS16240_DIAG_STAT_PWRON_BUSY BIT(4) + /* SPI communications failure */ #define ADIS16240_DIAG_STAT_SPI_FAIL_BIT 3 + /* Flash update failure */ #define ADIS16240_DIAG_STAT_FLASH_UPT_BIT 2 + /* Power supply above 3.625 V */ #define ADIS16240_DIAG_STAT_POWER_HIGH_BIT 1 + /* Power supply below 3.15 V */ #define ADIS16240_DIAG_STAT_POWER_LOW_BIT 0 /* GLOB_CMD */ + #define ADIS16240_GLOB_CMD_RESUME BIT(8) #define ADIS16240_GLOB_CMD_SW_RESET BIT(7) #define ADIS16240_GLOB_CMD_STANDBY BIT(2) -- cgit v1.2.3 From 992aa7b59f62411cb2e5d4192f8598c0f87f12a6 Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Tue, 22 Mar 2016 18:20:46 +0900 Subject: staging: dgnc: fix camelcase of SerialDriver and PrintDriver fix the checkpatch.pl warning about CamelCase. Signed-off-by: Daeseok Youn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_driver.h | 4 +- drivers/staging/dgnc/dgnc_tty.c | 118 ++++++++++++++++++------------------- 2 files changed, 61 insertions(+), 61 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dgnc/dgnc_driver.h b/drivers/staging/dgnc/dgnc_driver.h index e4be81b66041..953c891d4064 100644 --- a/drivers/staging/dgnc/dgnc_driver.h +++ b/drivers/staging/dgnc/dgnc_driver.h @@ -202,9 +202,9 @@ struct dgnc_board { * to our channels. */ - struct tty_driver SerialDriver; + struct tty_driver serial_driver; char SerialName[200]; - struct tty_driver PrintDriver; + struct tty_driver print_driver; char PrintName[200]; bool dgnc_Major_Serial_Registered; diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index bcd2bdfb9c8f..081ac75abc88 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -178,20 +178,20 @@ int dgnc_tty_register(struct dgnc_board *brd) { int rc = 0; - brd->SerialDriver.magic = TTY_DRIVER_MAGIC; + brd->serial_driver.magic = TTY_DRIVER_MAGIC; snprintf(brd->SerialName, MAXTTYNAMELEN, "tty_dgnc_%d_", brd->boardnum); - brd->SerialDriver.name = brd->SerialName; - brd->SerialDriver.name_base = 0; - brd->SerialDriver.major = 0; - brd->SerialDriver.minor_start = 0; - brd->SerialDriver.num = brd->maxports; - brd->SerialDriver.type = TTY_DRIVER_TYPE_SERIAL; - brd->SerialDriver.subtype = SERIAL_TYPE_NORMAL; - brd->SerialDriver.init_termios = DgncDefaultTermios; - brd->SerialDriver.driver_name = DRVSTR; - brd->SerialDriver.flags = (TTY_DRIVER_REAL_RAW | + brd->serial_driver.name = brd->SerialName; + brd->serial_driver.name_base = 0; + brd->serial_driver.major = 0; + brd->serial_driver.minor_start = 0; + brd->serial_driver.num = brd->maxports; + brd->serial_driver.type = TTY_DRIVER_TYPE_SERIAL; + brd->serial_driver.subtype = SERIAL_TYPE_NORMAL; + brd->serial_driver.init_termios = DgncDefaultTermios; + brd->serial_driver.driver_name = DRVSTR; + brd->serial_driver.flags = (TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_HARDWARE_BREAK); @@ -199,28 +199,28 @@ int dgnc_tty_register(struct dgnc_board *brd) * The kernel wants space to store pointers to * tty_struct's and termios's. */ - brd->SerialDriver.ttys = kcalloc(brd->maxports, - sizeof(*brd->SerialDriver.ttys), + brd->serial_driver.ttys = kcalloc(brd->maxports, + sizeof(*brd->serial_driver.ttys), GFP_KERNEL); - if (!brd->SerialDriver.ttys) + if (!brd->serial_driver.ttys) return -ENOMEM; - kref_init(&brd->SerialDriver.kref); - brd->SerialDriver.termios = kcalloc(brd->maxports, - sizeof(*brd->SerialDriver.termios), + kref_init(&brd->serial_driver.kref); + brd->serial_driver.termios = kcalloc(brd->maxports, + sizeof(*brd->serial_driver.termios), GFP_KERNEL); - if (!brd->SerialDriver.termios) + if (!brd->serial_driver.termios) return -ENOMEM; /* * Entry points for driver. Called by the kernel from * tty_io.c and n_tty.c. */ - tty_set_operations(&brd->SerialDriver, &dgnc_tty_ops); + tty_set_operations(&brd->serial_driver, &dgnc_tty_ops); if (!brd->dgnc_Major_Serial_Registered) { /* Register tty devices */ - rc = tty_register_driver(&brd->SerialDriver); + rc = tty_register_driver(&brd->serial_driver); if (rc < 0) { dev_dbg(&brd->pdev->dev, "Can't register tty device (%d)\n", rc); @@ -234,19 +234,19 @@ int dgnc_tty_register(struct dgnc_board *brd) * again, separately so we don't get the LD confused about what major * we are when we get into the dgnc_tty_open() routine. */ - brd->PrintDriver.magic = TTY_DRIVER_MAGIC; + brd->print_driver.magic = TTY_DRIVER_MAGIC; snprintf(brd->PrintName, MAXTTYNAMELEN, "pr_dgnc_%d_", brd->boardnum); - brd->PrintDriver.name = brd->PrintName; - brd->PrintDriver.name_base = 0; - brd->PrintDriver.major = brd->SerialDriver.major; - brd->PrintDriver.minor_start = 0x80; - brd->PrintDriver.num = brd->maxports; - brd->PrintDriver.type = TTY_DRIVER_TYPE_SERIAL; - brd->PrintDriver.subtype = SERIAL_TYPE_NORMAL; - brd->PrintDriver.init_termios = DgncDefaultTermios; - brd->PrintDriver.driver_name = DRVSTR; - brd->PrintDriver.flags = (TTY_DRIVER_REAL_RAW | + brd->print_driver.name = brd->PrintName; + brd->print_driver.name_base = 0; + brd->print_driver.major = brd->serial_driver.major; + brd->print_driver.minor_start = 0x80; + brd->print_driver.num = brd->maxports; + brd->print_driver.type = TTY_DRIVER_TYPE_SERIAL; + brd->print_driver.subtype = SERIAL_TYPE_NORMAL; + brd->print_driver.init_termios = DgncDefaultTermios; + brd->print_driver.driver_name = DRVSTR; + brd->print_driver.flags = (TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_HARDWARE_BREAK); @@ -255,27 +255,27 @@ int dgnc_tty_register(struct dgnc_board *brd) * tty_struct's and termios's. Must be separated from * the Serial Driver so we don't get confused */ - brd->PrintDriver.ttys = kcalloc(brd->maxports, - sizeof(*brd->PrintDriver.ttys), + brd->print_driver.ttys = kcalloc(brd->maxports, + sizeof(*brd->print_driver.ttys), GFP_KERNEL); - if (!brd->PrintDriver.ttys) + if (!brd->print_driver.ttys) return -ENOMEM; - kref_init(&brd->PrintDriver.kref); - brd->PrintDriver.termios = kcalloc(brd->maxports, - sizeof(*brd->PrintDriver.termios), + kref_init(&brd->print_driver.kref); + brd->print_driver.termios = kcalloc(brd->maxports, + sizeof(*brd->print_driver.termios), GFP_KERNEL); - if (!brd->PrintDriver.termios) + if (!brd->print_driver.termios) return -ENOMEM; /* * Entry points for driver. Called by the kernel from * tty_io.c and n_tty.c. */ - tty_set_operations(&brd->PrintDriver, &dgnc_tty_ops); + tty_set_operations(&brd->print_driver, &dgnc_tty_ops); if (!brd->dgnc_Major_TransparentPrint_Registered) { /* Register Transparent Print devices */ - rc = tty_register_driver(&brd->PrintDriver); + rc = tty_register_driver(&brd->print_driver); if (rc < 0) { dev_dbg(&brd->pdev->dev, "Can't register Transparent Print device(%d)\n", @@ -285,9 +285,9 @@ int dgnc_tty_register(struct dgnc_board *brd) brd->dgnc_Major_TransparentPrint_Registered = true; } - dgnc_BoardsByMajor[brd->SerialDriver.major] = brd; - brd->dgnc_Serial_Major = brd->SerialDriver.major; - brd->dgnc_TransparentPrint_Major = brd->PrintDriver.major; + dgnc_BoardsByMajor[brd->serial_driver.major] = brd; + brd->dgnc_Serial_Major = brd->serial_driver.major; + brd->dgnc_TransparentPrint_Major = brd->print_driver.major; return rc; } @@ -364,12 +364,12 @@ int dgnc_tty_init(struct dgnc_board *brd) { struct device *classp; - classp = tty_register_device(&brd->SerialDriver, i, + classp = tty_register_device(&brd->serial_driver, i, &ch->ch_bd->pdev->dev); ch->ch_tun.un_sysfs = classp; dgnc_create_tty_sysfs(&ch->ch_tun, classp); - classp = tty_register_device(&brd->PrintDriver, i, + classp = tty_register_device(&brd->print_driver, i, &ch->ch_bd->pdev->dev); ch->ch_pun.un_sysfs = classp; dgnc_create_tty_sysfs(&ch->ch_pun, classp); @@ -408,39 +408,39 @@ void dgnc_tty_uninit(struct dgnc_board *brd) int i = 0; if (brd->dgnc_Major_Serial_Registered) { - dgnc_BoardsByMajor[brd->SerialDriver.major] = NULL; + dgnc_BoardsByMajor[brd->serial_driver.major] = NULL; brd->dgnc_Serial_Major = 0; for (i = 0; i < brd->nasync; i++) { if (brd->channels[i]) dgnc_remove_tty_sysfs(brd->channels[i]-> ch_tun.un_sysfs); - tty_unregister_device(&brd->SerialDriver, i); + tty_unregister_device(&brd->serial_driver, i); } - tty_unregister_driver(&brd->SerialDriver); + tty_unregister_driver(&brd->serial_driver); brd->dgnc_Major_Serial_Registered = false; } if (brd->dgnc_Major_TransparentPrint_Registered) { - dgnc_BoardsByMajor[brd->PrintDriver.major] = NULL; + dgnc_BoardsByMajor[brd->print_driver.major] = NULL; brd->dgnc_TransparentPrint_Major = 0; for (i = 0; i < brd->nasync; i++) { if (brd->channels[i]) dgnc_remove_tty_sysfs(brd->channels[i]-> ch_pun.un_sysfs); - tty_unregister_device(&brd->PrintDriver, i); + tty_unregister_device(&brd->print_driver, i); } - tty_unregister_driver(&brd->PrintDriver); + tty_unregister_driver(&brd->print_driver); brd->dgnc_Major_TransparentPrint_Registered = false; } - kfree(brd->SerialDriver.ttys); - brd->SerialDriver.ttys = NULL; - kfree(brd->SerialDriver.termios); - brd->SerialDriver.termios = NULL; - kfree(brd->PrintDriver.ttys); - brd->PrintDriver.ttys = NULL; - kfree(brd->PrintDriver.termios); - brd->PrintDriver.termios = NULL; + kfree(brd->serial_driver.ttys); + brd->serial_driver.ttys = NULL; + kfree(brd->serial_driver.termios); + brd->serial_driver.termios = NULL; + kfree(brd->print_driver.ttys); + brd->print_driver.ttys = NULL; + kfree(brd->print_driver.termios); + brd->print_driver.termios = NULL; } /* -- cgit v1.2.3 From add0f9fefe481cfe719fc8302764e3613de9a054 Mon Sep 17 00:00:00 2001 From: Anchal Jain Date: Tue, 22 Mar 2016 18:01:42 +0530 Subject: staging: wilc1000: Remove camel case in variable names. Remove a problem detect by checkpatch.pl CHECK: Avoid CamelCase: Signed-off-by: Anchal Jain Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_mon.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/linux_mon.c b/drivers/staging/wilc1000/linux_mon.c index 6503316314f8..242f82f4d24f 100644 --- a/drivers/staging/wilc1000/linux_mon.c +++ b/drivers/staging/wilc1000/linux_mon.c @@ -24,7 +24,7 @@ struct wilc_wfi_radiotap_cb_hdr { static struct net_device *wilc_wfi_mon; /* global monitor netdev */ -static u8 srcAdd[6]; +static u8 srcadd[6]; static u8 bssid[6]; static u8 broadcast[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; /** @@ -228,11 +228,11 @@ static netdev_tx_t WILC_WFI_mon_xmit(struct sk_buff *skb, skb->dev = mon_priv->real_ndev; /* Identify if Ethernet or MAC header (data or mgmt) */ - memcpy(srcAdd, &skb->data[10], 6); + memcpy(srcadd, &skb->data[10], 6); memcpy(bssid, &skb->data[16], 6); /* if source address and bssid fields are equal>>Mac header */ /*send it to mgmt frames handler */ - if (!(memcmp(srcAdd, bssid, 6))) { + if (!(memcmp(srcadd, bssid, 6))) { ret = mon_mgmt_tx(mon_priv->real_ndev, skb->data, skb->len); if (ret) netdev_err(dev, "fail to mgmt tx\n"); -- cgit v1.2.3 From 06884afcf2ab18d314d94456fbf1ac3c860e99bb Mon Sep 17 00:00:00 2001 From: Parth Sane Date: Tue, 22 Mar 2016 18:25:37 +0530 Subject: staging: vt6656: Fixed multiple logical comparisions warnings Using comparison to false and true is error prone. Fixed multiple warnings as per checkpatch guidelines. Signed-off-by: Parth Sane Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/wcmd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/wcmd.c b/drivers/staging/vt6656/wcmd.c index 4846a898d39b..95faaeb7432a 100644 --- a/drivers/staging/vt6656/wcmd.c +++ b/drivers/staging/vt6656/wcmd.c @@ -97,7 +97,7 @@ void vnt_run_command(struct work_struct *work) if (test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags)) return; - if (priv->cmd_running != true) + if (!priv->cmd_running) return; switch (priv->command_state) { @@ -143,13 +143,13 @@ void vnt_run_command(struct work_struct *work) if (priv->rx_antenna_sel == 0) { priv->rx_antenna_sel = 1; - if (priv->tx_rx_ant_inv == true) + if (priv->tx_rx_ant_inv) vnt_set_antenna_mode(priv, ANT_RXA); else vnt_set_antenna_mode(priv, ANT_RXB); } else { priv->rx_antenna_sel = 0; - if (priv->tx_rx_ant_inv == true) + if (priv->tx_rx_ant_inv) vnt_set_antenna_mode(priv, ANT_RXB); else vnt_set_antenna_mode(priv, ANT_RXA); @@ -174,7 +174,7 @@ int vnt_schedule_command(struct vnt_private *priv, enum vnt_cmd command) ADD_ONE_WITH_WRAP_AROUND(priv->cmd_enqueue_idx, CMD_Q_SIZE); priv->free_cmd_queue--; - if (priv->cmd_running == false) + if (!priv->cmd_running) vnt_cmd_complete(priv); return true; -- cgit v1.2.3 From 4d97b691475060ea6e1345ea7a7c2cba4658a631 Mon Sep 17 00:00:00 2001 From: Bhaktipriya Shridhar Date: Tue, 22 Mar 2016 20:29:13 +0530 Subject: staging: rtl8712: mlme_linux: Clean up tests if NULL returned on failure Some functions like kzalloc return NULL on failure. When NULL represents failure, !x is commonly used. This was done using Coccinelle: @@ expression *e; identifier l1; @@ e = \(kmalloc\|kzalloc\|kcalloc\|devm_kzalloc\)(...); ... - e == NULL + !e Signed-off-by: Bhaktipriya Shridhar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/mlme_linux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8712/mlme_linux.c b/drivers/staging/rtl8712/mlme_linux.c index e4e4bdee78be..af7c4a47738a 100644 --- a/drivers/staging/rtl8712/mlme_linux.c +++ b/drivers/staging/rtl8712/mlme_linux.c @@ -153,7 +153,7 @@ void r8712_report_sec_ie(struct _adapter *adapter, u8 authmode, u8 *sec_ie) buff = NULL; if (authmode == _WPA_IE_ID_) { buff = kzalloc(IW_CUSTOM_MAX, GFP_ATOMIC); - if (buff == NULL) + if (!buff) return; p = buff; p += sprintf(p, "ASSOCINFO(ReqIEs="); -- cgit v1.2.3 From 12f037ece36267c7e7c6e0e65bc1abdd4019fb5d Mon Sep 17 00:00:00 2001 From: Bhaktipriya Shridhar Date: Tue, 22 Mar 2016 20:28:28 +0530 Subject: staging: rtl8188eu: rtw_cmd: Clean up tests if NULL returned on failure Some functions like kmalloc/kzalloc return NULL on failure. When NULL represents failure, !x is commonly used. This was done using Coccinelle: @@ expression *e; identifier l1; @@ e = \(kmalloc\|kzalloc\|kcalloc\|devm_kzalloc\)(...); ... - e == NULL + !e Signed-off-by: Bhaktipriya Shridhar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_cmd.c | 44 ++++++++++++++++---------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8188eu/core/rtw_cmd.c b/drivers/staging/rtl8188eu/core/rtw_cmd.c index f08d052f8e52..77485235c615 100644 --- a/drivers/staging/rtl8188eu/core/rtw_cmd.c +++ b/drivers/staging/rtl8188eu/core/rtw_cmd.c @@ -258,11 +258,11 @@ u8 rtw_sitesurvey_cmd(struct adapter *padapter, struct ndis_802_11_ssid *ssid, rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SCAN, 1); ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); - if (ph2c == NULL) + if (!ph2c) return _FAIL; psurveyPara = kzalloc(sizeof(struct sitesurvey_parm), GFP_ATOMIC); - if (psurveyPara == NULL) { + if (!psurveyPara) { kfree(ph2c); return _FAIL; } @@ -345,7 +345,7 @@ u8 rtw_createbss_cmd(struct adapter *padapter) RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, (" createbss for SSid:%s\n", pmlmepriv->assoc_ssid.Ssid)); pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); - if (pcmd == NULL) { + if (!pcmd) { res = _FAIL; goto exit; } @@ -516,7 +516,7 @@ u8 rtw_disassoc_cmd(struct adapter *padapter, u32 deauth_timeout_ms, bool enqueu /* prepare cmd parameter */ param = kzalloc(sizeof(*param), GFP_KERNEL); - if (param == NULL) { + if (!param) { res = _FAIL; goto exit; } @@ -525,7 +525,7 @@ u8 rtw_disassoc_cmd(struct adapter *padapter, u32 deauth_timeout_ms, bool enqueu if (enqueue) { /* need enqueue, prepare cmd_obj and enqueue */ cmdobj = kzalloc(sizeof(*cmdobj), GFP_KERNEL); - if (cmdobj == NULL) { + if (!cmdobj) { res = _FAIL; kfree(param); goto exit; @@ -624,20 +624,20 @@ u8 rtw_clearstakey_cmd(struct adapter *padapter, u8 *psta, u8 entry, u8 enqueue) clear_cam_entry(padapter, entry); } else { ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); - if (ph2c == NULL) { + if (!ph2c) { res = _FAIL; goto exit; } psetstakey_para = kzalloc(sizeof(struct set_stakey_parm), GFP_ATOMIC); - if (psetstakey_para == NULL) { + if (!psetstakey_para) { kfree(ph2c); res = _FAIL; goto exit; } psetstakey_rsp = kzalloc(sizeof(struct set_stakey_rsp), GFP_ATOMIC); - if (psetstakey_rsp == NULL) { + if (!psetstakey_rsp) { kfree(ph2c); kfree(psetstakey_para); res = _FAIL; @@ -671,13 +671,13 @@ u8 rtw_addbareq_cmd(struct adapter *padapter, u8 tid, u8 *addr) ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); - if (ph2c == NULL) { + if (!ph2c) { res = _FAIL; goto exit; } paddbareq_parm = kzalloc(sizeof(struct addBaReq_parm), GFP_KERNEL); - if (paddbareq_parm == NULL) { + if (!paddbareq_parm) { kfree(ph2c); res = _FAIL; goto exit; @@ -708,13 +708,13 @@ u8 rtw_dynamic_chk_wk_cmd(struct adapter *padapter) ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); - if (ph2c == NULL) { + if (!ph2c) { res = _FAIL; goto exit; } pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_ATOMIC); - if (pdrvextra_cmd_parm == NULL) { + if (!pdrvextra_cmd_parm) { kfree(ph2c); res = _FAIL; goto exit; @@ -752,7 +752,7 @@ u8 rtw_set_chplan_cmd(struct adapter *padapter, u8 chplan, u8 enqueue) /* prepare cmd parameter */ setChannelPlan_param = kzalloc(sizeof(struct SetChannelPlan_param), GFP_KERNEL); - if (setChannelPlan_param == NULL) { + if (!setChannelPlan_param) { res = _FAIL; goto exit; } @@ -761,7 +761,7 @@ u8 rtw_set_chplan_cmd(struct adapter *padapter, u8 chplan, u8 enqueue) if (enqueue) { /* need enqueue, prepare cmd_obj and enqueue */ pcmdobj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); - if (pcmdobj == NULL) { + if (!pcmdobj) { kfree(setChannelPlan_param); res = _FAIL; goto exit; @@ -920,13 +920,13 @@ u8 rtw_lps_ctrl_wk_cmd(struct adapter *padapter, u8 lps_ctrl_type, u8 enqueue) if (enqueue) { ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); - if (ph2c == NULL) { + if (!ph2c) { res = _FAIL; goto exit; } pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_ATOMIC); - if (pdrvextra_cmd_parm == NULL) { + if (!pdrvextra_cmd_parm) { kfree(ph2c); res = _FAIL; goto exit; @@ -963,13 +963,13 @@ u8 rtw_rpt_timer_cfg_cmd(struct adapter *padapter, u16 min_time) u8 res = _SUCCESS; ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); - if (ph2c == NULL) { + if (!ph2c) { res = _FAIL; goto exit; } pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_ATOMIC); - if (pdrvextra_cmd_parm == NULL) { + if (!pdrvextra_cmd_parm) { kfree(ph2c); res = _FAIL; goto exit; @@ -1005,13 +1005,13 @@ u8 rtw_antenna_select_cmd(struct adapter *padapter, u8 antenna, u8 enqueue) if (enqueue) { ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); - if (ph2c == NULL) { + if (!ph2c) { res = _FAIL; goto exit; } pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_KERNEL); - if (pdrvextra_cmd_parm == NULL) { + if (!pdrvextra_cmd_parm) { kfree(ph2c); res = _FAIL; goto exit; @@ -1103,13 +1103,13 @@ u8 rtw_chk_hi_queue_cmd(struct adapter *padapter) u8 res = _SUCCESS; ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); - if (ph2c == NULL) { + if (!ph2c) { res = _FAIL; goto exit; } pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_KERNEL); - if (pdrvextra_cmd_parm == NULL) { + if (!pdrvextra_cmd_parm) { kfree(ph2c); res = _FAIL; goto exit; -- cgit v1.2.3 From a703f4726583318b24f76bb6bc61d46a5319f248 Mon Sep 17 00:00:00 2001 From: Bhaktipriya Shridhar Date: Tue, 22 Mar 2016 20:27:39 +0530 Subject: staging: rtl8188eu: rtw_mlme_ext: Clean up tests if NULL returned on failure Some functions like kzalloc return NULL on failure. When NULL represents failure, !x is commonly used. This was done using Coccinelle: @@ expression *e; identifier l1; @@ e = \(kmalloc\|kzalloc\|kcalloc\|devm_kzalloc\)(...); ... - e == NULL + !e Signed-off-by: Bhaktipriya Shridhar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_mlme_ext.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c index 86108d4bec0a..439c035fbb7b 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c @@ -4289,12 +4289,12 @@ void report_survey_event(struct adapter *padapter, pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); - if (pcmd_obj == NULL) + if (!pcmd_obj) return; cmdsz = sizeof(struct survey_event) + sizeof(struct C2HEvent_Header); pevtcmd = kzalloc(cmdsz, GFP_ATOMIC); - if (pevtcmd == NULL) { + if (!pevtcmd) { kfree(pcmd_obj); return; } @@ -4341,12 +4341,12 @@ void report_surveydone_event(struct adapter *padapter) struct cmd_priv *pcmdpriv = &padapter->cmdpriv; pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); - if (pcmd_obj == NULL) + if (!pcmd_obj) return; cmdsz = sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header); pevtcmd = kzalloc(cmdsz, GFP_KERNEL); - if (pevtcmd == NULL) { + if (!pevtcmd) { kfree(pcmd_obj); return; } @@ -4387,12 +4387,12 @@ void report_join_res(struct adapter *padapter, int res) struct cmd_priv *pcmdpriv = &padapter->cmdpriv; pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); - if (pcmd_obj == NULL) + if (!pcmd_obj) return; cmdsz = sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header); pevtcmd = kzalloc(cmdsz, GFP_ATOMIC); - if (pevtcmd == NULL) { + if (!pevtcmd) { kfree(pcmd_obj); return; } @@ -4440,12 +4440,12 @@ void report_del_sta_event(struct adapter *padapter, unsigned char *MacAddr, unsi struct cmd_priv *pcmdpriv = &padapter->cmdpriv; pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); - if (pcmd_obj == NULL) + if (!pcmd_obj) return; cmdsz = sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header); pevtcmd = kzalloc(cmdsz, GFP_KERNEL); - if (pevtcmd == NULL) { + if (!pevtcmd) { kfree(pcmd_obj); return; } @@ -4495,12 +4495,12 @@ void report_add_sta_event(struct adapter *padapter, unsigned char *MacAddr, int struct cmd_priv *pcmdpriv = &padapter->cmdpriv; pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); - if (pcmd_obj == NULL) + if (!pcmd_obj) return; cmdsz = sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header); pevtcmd = kzalloc(cmdsz, GFP_KERNEL); - if (pevtcmd == NULL) { + if (!pevtcmd) { kfree(pcmd_obj); return; } @@ -4911,11 +4911,11 @@ void survey_timer_hdl(unsigned long data) } ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); - if (ph2c == NULL) + if (!ph2c) goto exit_survey_timer_hdl; psurveyPara = kzalloc(sizeof(struct sitesurvey_parm), GFP_ATOMIC); - if (psurveyPara == NULL) { + if (!psurveyPara) { kfree(ph2c); goto exit_survey_timer_hdl; } @@ -5479,7 +5479,7 @@ u8 set_tx_beacon_cmd(struct adapter *padapter) ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); - if (ph2c == NULL) { + if (!ph2c) { res = _FAIL; goto exit; } -- cgit v1.2.3 From 6e9aeda3fa6fb1462cfc3d188ecfa734b1af6b21 Mon Sep 17 00:00:00 2001 From: Bhaktipriya Shridhar Date: Tue, 22 Mar 2016 20:26:33 +0530 Subject: staging: rtl8188eu: core: rtw_mlme: Clean up tests if NULL returned on failure Some functions like kmalloc/kzalloc return NULL on failure. When NULL represents failure, !x is commonly used. This was done using Coccinelle: @@ expression *e; identifier l1; @@ e = \(kmalloc\|kzalloc\|kcalloc\|devm_kzalloc\)(...); ... - e == NULL + !e Signed-off-by: Bhaktipriya Shridhar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_mlme.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme.c b/drivers/staging/rtl8188eu/core/rtw_mlme.c index 472cd3f381cb..1456499b84bf 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme.c @@ -1579,13 +1579,13 @@ int rtw_set_auth(struct adapter *adapter, struct security_priv *psecuritypriv) int res = _SUCCESS; pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); - if (pcmd == NULL) { + if (!pcmd) { res = _FAIL; /* try again */ goto exit; } psetauthparm = kzalloc(sizeof(struct setauth_parm), GFP_KERNEL); - if (psetauthparm == NULL) { + if (!psetauthparm) { kfree(pcmd); res = _FAIL; goto exit; @@ -1616,11 +1616,11 @@ int rtw_set_key(struct adapter *adapter, struct security_priv *psecuritypriv, in int res = _SUCCESS; pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); - if (pcmd == NULL) + if (!pcmd) return _FAIL; /* try again */ psetkeyparm = kzalloc(sizeof(struct setkey_parm), GFP_KERNEL); - if (psetkeyparm == NULL) { + if (!psetkeyparm) { res = _FAIL; goto err_free_cmd; } -- cgit v1.2.3 From 574502caed4c11c7bbb6b4532a8bb544f626f2dc Mon Sep 17 00:00:00 2001 From: Bhaktipriya Shridhar Date: Tue, 22 Mar 2016 20:25:55 +0530 Subject: staging: rtl8188eu: os_dep: usb_intf: Clean up tests if NULL returned on failure Some functions like kmalloc/kzalloc return NULL on failure. When NULL represents failure, !x is commonly used. This was done using Coccinelle: @@ expression *e; identifier l1; @@ e = \(kmalloc\|kzalloc\|kcalloc\|devm_kzalloc\)(...); ... - e == NULL + !e Signed-off-by: Bhaktipriya Shridhar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/os_dep/usb_intf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8188eu/os_dep/usb_intf.c b/drivers/staging/rtl8188eu/os_dep/usb_intf.c index 8fd608d6027a..11d51a30170f 100644 --- a/drivers/staging/rtl8188eu/os_dep/usb_intf.c +++ b/drivers/staging/rtl8188eu/os_dep/usb_intf.c @@ -60,7 +60,7 @@ static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf) struct usb_device *pusbd; pdvobjpriv = kzalloc(sizeof(*pdvobjpriv), GFP_KERNEL); - if (pdvobjpriv == NULL) + if (!pdvobjpriv) return NULL; pdvobjpriv->pusbintf = usb_intf; -- cgit v1.2.3 From 4ada295da12e9d0647801577cef37cfc48d41b38 Mon Sep 17 00:00:00 2001 From: Bhaktipriya Shridhar Date: Tue, 22 Mar 2016 20:19:49 +0530 Subject: staging: rtl8188eu: os_dep: ioctl_linux: Clean up tests if NULL returned on failure Some functions like kmalloc/kzalloc return NULL on failure. When NULL represents failure, !x is commonly used. This was done using Coccinelle: @@ expression *e; identifier l1; @@ e = \(kmalloc\|kzalloc\|kcalloc\|devm_kzalloc\)(...); ... - e == NULL + !e Signed-off-by: Bhaktipriya Shridhar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/os_dep/ioctl_linux.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c index eeb1694d8bbe..5672f014cc46 100644 --- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c @@ -2115,13 +2115,13 @@ static u8 set_pairwise_key(struct adapter *padapter, struct sta_info *psta) u8 res = _SUCCESS; ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); - if (ph2c == NULL) { + if (!ph2c) { res = _FAIL; goto exit; } psetstakey_para = kzalloc(sizeof(struct set_stakey_parm), GFP_KERNEL); - if (psetstakey_para == NULL) { + if (!psetstakey_para) { kfree(ph2c); res = _FAIL; goto exit; @@ -2153,12 +2153,12 @@ static int set_group_key(struct adapter *padapter, u8 *key, u8 alg, int keyid) DBG_88E("%s\n", __func__); pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); - if (pcmd == NULL) { + if (!pcmd) { res = _FAIL; goto exit; } psetkeyparm = kzalloc(sizeof(struct setkey_parm), GFP_KERNEL); - if (psetkeyparm == NULL) { + if (!psetkeyparm) { kfree(pcmd); res = _FAIL; goto exit; -- cgit v1.2.3 From f90272f432f7515044d9e13a6fa2c8bf1ac14838 Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Tue, 22 Mar 2016 22:22:41 +0530 Subject: staging: media: omap1: Replace clk_get with devm_clk_get devm_clk_get allocated resources get released when a driver detaches. Replace clk_get with devm_clk_get and remove corresponding data releasing function clk_put from probe and remove functions of a platform device. Also remove an unnecessary label. This change was made with the help of the following Coccinelle semantic patch: @platform@ identifier p, probefn, removefn; @@ struct platform_driver p = { .probe = probefn, .remove = removefn, }; @prb@ identifier platform.probefn, pdev; expression e; @@ probefn(struct platform_device *pdev, ...) { ... e = - clk_get + devm_clk_get (...); ... ?- clk_put(...); ... } @remove depends on prb@ identifier platform.removefn; @@ removefn(...) { ... ?- clk_put(...); ... } Signed-off-by: Amitoj Kaur Chawla Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/omap1/omap1_camera.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/media/omap1/omap1_camera.c b/drivers/staging/media/omap1/omap1_camera.c index bd721e35474a..bd001804ed47 100644 --- a/drivers/staging/media/omap1/omap1_camera.c +++ b/drivers/staging/media/omap1/omap1_camera.c @@ -1576,17 +1576,14 @@ static int omap1_cam_probe(struct platform_device *pdev) goto exit; } - clk = clk_get(&pdev->dev, "armper_ck"); - if (IS_ERR(clk)) { - err = PTR_ERR(clk); - goto exit; - } + clk = devm_clk_get(&pdev->dev, "armper_ck"); + if (IS_ERR(clk)) + return PTR_ERR(clk); pcdev = kzalloc(sizeof(*pcdev) + resource_size(res), GFP_KERNEL); if (!pcdev) { dev_err(&pdev->dev, "Could not allocate pcdev\n"); - err = -ENOMEM; - goto exit_put_clk; + return -ENOMEM; } pcdev->res = res; @@ -1685,8 +1682,6 @@ exit_release: release_mem_region(res->start, resource_size(res)); exit_kfree: kfree(pcdev); -exit_put_clk: - clk_put(clk); exit: return err; } @@ -1709,8 +1704,6 @@ static int omap1_cam_remove(struct platform_device *pdev) res = pcdev->res; release_mem_region(res->start, resource_size(res)); - clk_put(pcdev->clk); - kfree(pcdev); dev_info(&pdev->dev, "OMAP1 Camera Interface driver unloaded\n"); -- cgit v1.2.3 From ba99a0f19ae04820104c1cba11027ec69495879c Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Tue, 22 Mar 2016 22:22:48 +0530 Subject: staging: media: omap1: Replace kzalloc with devm_kzalloc Replace kzalloc with devm_kzalloc and consequently remove kfrees in probe and remove functions of a platform device. As a result of this change, remove unnecessary out of memory message and an unnecessary label. Signed-off-by: Amitoj Kaur Chawla Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/omap1/omap1_camera.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/media/omap1/omap1_camera.c b/drivers/staging/media/omap1/omap1_camera.c index bd001804ed47..8cc4a0a5a835 100644 --- a/drivers/staging/media/omap1/omap1_camera.c +++ b/drivers/staging/media/omap1/omap1_camera.c @@ -1580,11 +1580,10 @@ static int omap1_cam_probe(struct platform_device *pdev) if (IS_ERR(clk)) return PTR_ERR(clk); - pcdev = kzalloc(sizeof(*pcdev) + resource_size(res), GFP_KERNEL); - if (!pcdev) { - dev_err(&pdev->dev, "Could not allocate pcdev\n"); + pcdev = devm_kzalloc(&pdev->dev, sizeof(*pcdev) + resource_size(res), + GFP_KERNEL); + if (!pcdev) return -ENOMEM; - } pcdev->res = res; pcdev->clk = clk; @@ -1620,10 +1619,8 @@ static int omap1_cam_probe(struct platform_device *pdev) /* * Request the region. */ - if (!request_mem_region(res->start, resource_size(res), DRIVER_NAME)) { - err = -EBUSY; - goto exit_kfree; - } + if (!request_mem_region(res->start, resource_size(res), DRIVER_NAME)) + return -EBUSY; base = ioremap(res->start, resource_size(res)); if (!base) { @@ -1680,8 +1677,6 @@ exit_iounmap: iounmap(base); exit_release: release_mem_region(res->start, resource_size(res)); -exit_kfree: - kfree(pcdev); exit: return err; } @@ -1704,8 +1699,6 @@ static int omap1_cam_remove(struct platform_device *pdev) res = pcdev->res; release_mem_region(res->start, resource_size(res)); - kfree(pcdev); - dev_info(&pdev->dev, "OMAP1 Camera Interface driver unloaded\n"); return 0; -- cgit v1.2.3 From 76e543382bd4f488f2a1ca726b7494e6c5f4cc89 Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Tue, 22 Mar 2016 22:22:56 +0530 Subject: staging: media: omap1: Switch to devm_ioremap_resource Replace calls to request_mem_region and ioremap with a direct call to devm_ioremap_resource instead and modify error handling. Move the call to platform_get_resource adjacent to the call to devm_ioremap_resource to make the connection between them more clear. Also remove unnecessary labels, variable initialisations and release_mem_region iounmap from probe and remove functions. Signed-off-by: Amitoj Kaur Chawla Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/omap1/omap1_camera.c | 31 ++++++------------------------ 1 file changed, 6 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/media/omap1/omap1_camera.c b/drivers/staging/media/omap1/omap1_camera.c index 8cc4a0a5a835..c4450b42a4c4 100644 --- a/drivers/staging/media/omap1/omap1_camera.c +++ b/drivers/staging/media/omap1/omap1_camera.c @@ -1569,9 +1569,8 @@ static int omap1_cam_probe(struct platform_device *pdev) unsigned int irq; int err = 0; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq = platform_get_irq(pdev, 0); - if (!res || (int)irq <= 0) { + if ((int)irq <= 0) { err = -ENODEV; goto exit; } @@ -1585,7 +1584,6 @@ static int omap1_cam_probe(struct platform_device *pdev) if (!pcdev) return -ENOMEM; - pcdev->res = res; pcdev->clk = clk; pcdev->pdata = pdev->dev.platform_data; @@ -1616,17 +1614,11 @@ static int omap1_cam_probe(struct platform_device *pdev) INIT_LIST_HEAD(&pcdev->capture); spin_lock_init(&pcdev->lock); - /* - * Request the region. - */ - if (!request_mem_region(res->start, resource_size(res), DRIVER_NAME)) - return -EBUSY; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); - base = ioremap(res->start, resource_size(res)); - if (!base) { - err = -ENOMEM; - goto exit_release; - } pcdev->irq = irq; pcdev->base = base; @@ -1636,8 +1628,7 @@ static int omap1_cam_probe(struct platform_device *pdev) dma_isr, (void *)pcdev, &pcdev->dma_ch); if (err < 0) { dev_err(&pdev->dev, "Can't request DMA for OMAP1 Camera\n"); - err = -EBUSY; - goto exit_iounmap; + return -EBUSY; } dev_dbg(&pdev->dev, "got DMA channel %d\n", pcdev->dma_ch); @@ -1673,10 +1664,6 @@ exit_free_irq: free_irq(pcdev->irq, pcdev); exit_free_dma: omap_free_dma(pcdev->dma_ch); -exit_iounmap: - iounmap(base); -exit_release: - release_mem_region(res->start, resource_size(res)); exit: return err; } @@ -1686,7 +1673,6 @@ static int omap1_cam_remove(struct platform_device *pdev) struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev); struct omap1_cam_dev *pcdev = container_of(soc_host, struct omap1_cam_dev, soc_host); - struct resource *res; free_irq(pcdev->irq, pcdev); @@ -1694,11 +1680,6 @@ static int omap1_cam_remove(struct platform_device *pdev) soc_camera_host_unregister(soc_host); - iounmap(pcdev->base); - - res = pcdev->res; - release_mem_region(res->start, resource_size(res)); - dev_info(&pdev->dev, "OMAP1 Camera Interface driver unloaded\n"); return 0; -- cgit v1.2.3 From 62d727c4a99a97e5cc73294d86ccf4b7250bfc3b Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Tue, 22 Mar 2016 22:23:02 +0530 Subject: staging: media: omap1: Replace request_irq with devm_request_irq Replace request_irq with devm_request_irq to get the interrupt for device which is automatically freed on exit. Remove corresponding free_irq from probe and remove functions of a platform device. Also, remove an unnecessary label. Signed-off-by: Amitoj Kaur Chawla Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/omap1/omap1_camera.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/media/omap1/omap1_camera.c b/drivers/staging/media/omap1/omap1_camera.c index c4450b42a4c4..54b8dd2d2bba 100644 --- a/drivers/staging/media/omap1/omap1_camera.c +++ b/drivers/staging/media/omap1/omap1_camera.c @@ -1640,7 +1640,8 @@ static int omap1_cam_probe(struct platform_device *pdev) /* setup DMA autoinitialization */ omap_dma_link_lch(pcdev->dma_ch, pcdev->dma_ch); - err = request_irq(pcdev->irq, cam_isr, 0, DRIVER_NAME, pcdev); + err = devm_request_irq(&pdev->dev, pcdev->irq, cam_isr, 0, DRIVER_NAME, + pcdev); if (err) { dev_err(&pdev->dev, "Camera interrupt register failed\n"); goto exit_free_dma; @@ -1654,14 +1655,12 @@ static int omap1_cam_probe(struct platform_device *pdev) err = soc_camera_host_register(&pcdev->soc_host); if (err) - goto exit_free_irq; + return err; dev_info(&pdev->dev, "OMAP1 Camera Interface driver loaded\n"); return 0; -exit_free_irq: - free_irq(pcdev->irq, pcdev); exit_free_dma: omap_free_dma(pcdev->dma_ch); exit: @@ -1674,8 +1673,6 @@ static int omap1_cam_remove(struct platform_device *pdev) struct omap1_cam_dev *pcdev = container_of(soc_host, struct omap1_cam_dev, soc_host); - free_irq(pcdev->irq, pcdev); - omap_free_dma(pcdev->dma_ch); soc_camera_host_unregister(soc_host); -- cgit v1.2.3 From 7e221b6088eda47589480bcb29f4aaba44da49c7 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Thu, 24 Mar 2016 11:24:02 -0400 Subject: staging: lustre: lnet: revert commit 4671a0266 Commit 4671a0266 change the parameter of the second parameter of cfs_precpt_alloc() from a sizeof type to sizeof type *pointer. This was incorrect in this case and it caused a crash when the LNet layer was brought up in my testing. The reason is cfs_precpt_alloc() creates an array of items where the arrays size is equal to the number of CPTs that exist. Changing to type *pointer only had cfs_precpt_alloc() create an array of pointers instead of an array of actual data structures. This patch reverse this change and adds comments to explain what cfs_precpt_alloc() is actually doing to avoid potential issues like this again. Changelog: v1) Simple revert of the original patch v2) Added in comments to explain why cfs_precpt_alloc() has the arguments it uses. Signed-off-by: James Simmons Cc: Sandhya Bankar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c index 89f939092af4..e89c2a1bfa13 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c @@ -1965,10 +1965,13 @@ static int kiblnd_net_init_pools(kib_net_t *net, __u32 *cpts, int ncpts) /* * premapping can fail if ibd_nmr > 1, so we always create * FMR pool and map-on-demand if premapping failed + * + * cfs_precpt_alloc is creating an array of struct kib_fmr_poolset + * The number of struct kib_fmr_poolsets create is equal to the + * number of CPTs that exist, i.e net->ibn_fmr_ps[cpt]. */ - net->ibn_fmr_ps = cfs_percpt_alloc(lnet_cpt_table(), - sizeof(*net->ibn_fmr_ps)); + sizeof(kib_fmr_poolset_t)); if (!net->ibn_fmr_ps) { CERROR("Failed to allocate FMR pool array\n"); rc = -ENOMEM; @@ -1991,8 +1994,13 @@ static int kiblnd_net_init_pools(kib_net_t *net, __u32 *cpts, int ncpts) LASSERT(i == ncpts); create_tx_pool: + /* + * cfs_precpt_alloc is creating an array of struct kib_tx_poolset + * The number of struct kib_tx_poolsets create is equal to the + * number of CPTs that exist, i.e net->ibn_tx_ps[cpt]. + */ net->ibn_tx_ps = cfs_percpt_alloc(lnet_cpt_table(), - sizeof(*net->ibn_tx_ps)); + sizeof(kib_tx_poolset_t)); if (!net->ibn_tx_ps) { CERROR("Failed to allocate tx pool array\n"); rc = -ENOMEM; -- cgit v1.2.3 From ae664e824e3e4a85dbe857815d269f209d998e36 Mon Sep 17 00:00:00 2001 From: Liang Zhen Date: Tue, 22 Mar 2016 19:03:48 -0400 Subject: staging: lustre: libcfs: replace LNET_MAX_IOCTL_BUF_LEN with something bigger The size of LNET_MAX_IOCTL_BUF_LEN restricts the size of libcfs ioctl to the maximum needs of the LNet layer. Since libcfs also handles things like debugging we might need to let user land pass more data to or from the kernel than what is possible Signed-off-by: Liang Zhen Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5435 Reviewed-on: http://review.whamcloud.com/11313 Reviewed-by: Bobi Jam Reviewed-by: Johann Lombardi Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h | 3 +++ drivers/staging/lustre/lnet/libcfs/module.c | 5 +---- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h index 5ca99bd6f4e9..c71d1250ff96 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h @@ -49,6 +49,9 @@ struct libcfs_ioctl_hdr { __u32 ioc_version; }; +/** max size to copy from userspace */ +#define LIBCFS_IOC_DATA_MAX (128 * 1024) + struct libcfs_ioctl_data { struct libcfs_ioctl_hdr ioc_hdr; diff --git a/drivers/staging/lustre/lnet/libcfs/module.c b/drivers/staging/lustre/lnet/libcfs/module.c index cdc640bfdba8..f9f9d59052f8 100644 --- a/drivers/staging/lustre/lnet/libcfs/module.c +++ b/drivers/staging/lustre/lnet/libcfs/module.c @@ -54,9 +54,6 @@ # define DEBUG_SUBSYSTEM S_LNET -#define LNET_MAX_IOCTL_BUF_LEN (sizeof(struct lnet_ioctl_net_config) + \ - sizeof(struct lnet_ioctl_config_data)) - #include "../../include/linux/libcfs/libcfs.h" #include @@ -186,7 +183,7 @@ static int libcfs_ioctl(struct cfs_psdev_file *pfile, unsigned long cmd, * do a check here to restrict the size of the memory * to allocate to guard against DoS attacks. */ - if (buf_len > LNET_MAX_IOCTL_BUF_LEN) { + if (buf_len > LIBCFS_IOC_DATA_MAX) { CERROR("LNET: user buffer exceeds kernel buffer\n"); return -EINVAL; } -- cgit v1.2.3 From 74bfc129826a0e2e44821a5aea6ecda43fff5f87 Mon Sep 17 00:00:00 2001 From: Liang Zhen Date: Tue, 22 Mar 2016 19:03:49 -0400 Subject: staging: lustre: libcfs: use break in switch options for libcfs_ioctl_handle Instead of just returning for each switch condition use a break. Signed-off-by: Liang Zhen Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5435 Reviewed-on: http://review.whamcloud.com/11313 Reviewed-by: Bobi Jam Reviewed-by: Johann Lombardi Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/libcfs/module.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/libcfs/module.c b/drivers/staging/lustre/lnet/libcfs/module.c index f9f9d59052f8..3fe281064067 100644 --- a/drivers/staging/lustre/lnet/libcfs/module.c +++ b/drivers/staging/lustre/lnet/libcfs/module.c @@ -116,7 +116,7 @@ static int libcfs_ioctl_handle(struct cfs_psdev_file *pfile, unsigned long cmd, void __user *arg, struct libcfs_ioctl_hdr *hdr) { struct libcfs_ioctl_data *data = NULL; - int err = -EINVAL; + int err = 0; /* * The libcfs_ioctl_data_adjust() function performs adjustment @@ -134,7 +134,7 @@ static int libcfs_ioctl_handle(struct cfs_psdev_file *pfile, unsigned long cmd, switch (cmd) { case IOC_LIBCFS_CLEAR_DEBUG: libcfs_debug_clear_buffer(); - return 0; + break; /* * case IOC_LIBCFS_PANIC: * Handled in arch/cfs_module.c @@ -144,7 +144,7 @@ static int libcfs_ioctl_handle(struct cfs_psdev_file *pfile, unsigned long cmd, data->ioc_inlbuf1[data->ioc_inllen1 - 1] != '\0') return -EINVAL; libcfs_debug_mark_buffer(data->ioc_inlbuf1); - return 0; + break; default: { struct libcfs_ioctl_handler *hand; @@ -161,8 +161,7 @@ static int libcfs_ioctl_handle(struct cfs_psdev_file *pfile, unsigned long cmd, } } up_read(&ioctl_list_sem); - break; - } + break; } } return err; -- cgit v1.2.3 From e4efb34a3fc335ea7c837a10f5c03fe446e176d0 Mon Sep 17 00:00:00 2001 From: Liang Zhen Date: Tue, 22 Mar 2016 19:03:50 -0400 Subject: staging: lustre: libcfs: merge code from libcfs_ioctl into libcfs_ioctl_getdata This is apart of the cleanup of libcfs_ioctl* code. In this part some of the code in libcfs_ioctl is migrated into libcfs_ioctl_getdata_len() which is renamed libcfs_ioctl_getdata() Signed-off-by: Liang Zhen Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5435 Reviewed-on: http://review.whamcloud.com/11313 Reviewed-by: Bobi Jam Reviewed-by: Johann Lombardi Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- .../lustre/include/linux/libcfs/libcfs_ioctl.h | 4 ++-- .../lustre/lnet/libcfs/linux/linux-module.c | 23 ++++++++++++++---- drivers/staging/lustre/lnet/libcfs/module.c | 28 +++------------------- 3 files changed, 23 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h index c71d1250ff96..9c1deae4e226 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h @@ -225,8 +225,8 @@ static inline bool libcfs_ioctl_is_invalid(struct libcfs_ioctl_data *data) int libcfs_register_ioctl(struct libcfs_ioctl_handler *hand); int libcfs_deregister_ioctl(struct libcfs_ioctl_handler *hand); -int libcfs_ioctl_getdata_len(const struct libcfs_ioctl_hdr __user *arg, - __u32 *buf_len); +int libcfs_ioctl_getdata(struct libcfs_ioctl_hdr **hdr_pp, + const struct libcfs_ioctl_hdr __user *uparam); int libcfs_ioctl_popdata(void __user *arg, void *buf, int size); int libcfs_ioctl_data_adjust(struct libcfs_ioctl_data *data); diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c index ebc60ac9bb7a..a326ac63c752 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c @@ -57,12 +57,13 @@ int libcfs_ioctl_data_adjust(struct libcfs_ioctl_data *data) return 0; } -int libcfs_ioctl_getdata_len(const struct libcfs_ioctl_hdr __user *arg, - __u32 *len) +int libcfs_ioctl_getdata(struct libcfs_ioctl_hdr **hdr_pp, + const struct libcfs_ioctl_hdr __user *uhdr) { struct libcfs_ioctl_hdr hdr; + int err = 0; - if (copy_from_user(&hdr, arg, sizeof(hdr))) + if (copy_from_user(&hdr, uhdr, sizeof(uhdr))) return -EFAULT; if (hdr.ioc_version != LIBCFS_IOCTL_VERSION && @@ -72,9 +73,21 @@ int libcfs_ioctl_getdata_len(const struct libcfs_ioctl_hdr __user *arg, return -EINVAL; } - *len = hdr.ioc_len; + if (hdr.ioc_len > LIBCFS_IOC_DATA_MAX) { + CERROR("libcfs ioctl: user buffer is too large %d/%d\n", + hdr.ioc_len, LIBCFS_IOC_DATA_MAX); + return -EINVAL; + } - return 0; + LIBCFS_ALLOC(*hdr_pp, hdr.ioc_len); + if (!*hdr_pp) + return -ENOMEM; + + if (copy_from_user(*hdr_pp, uhdr, hdr.ioc_len)) { + LIBCFS_FREE(*hdr_pp, hdr.ioc_len); + err = -EFAULT; + } + return err; } int libcfs_ioctl_popdata(void __user *arg, void *data, int size) diff --git a/drivers/staging/lustre/lnet/libcfs/module.c b/drivers/staging/lustre/lnet/libcfs/module.c index 3fe281064067..5a20e5325f05 100644 --- a/drivers/staging/lustre/lnet/libcfs/module.c +++ b/drivers/staging/lustre/lnet/libcfs/module.c @@ -172,36 +172,14 @@ static int libcfs_ioctl(struct cfs_psdev_file *pfile, unsigned long cmd, { struct libcfs_ioctl_hdr *hdr; int err = 0; - __u32 buf_len; - err = libcfs_ioctl_getdata_len(arg, &buf_len); + /* 'cmd' and permissions get checked in our arch-specific caller */ + err = libcfs_ioctl_getdata(&hdr, arg); if (err) return err; - /* - * do a check here to restrict the size of the memory - * to allocate to guard against DoS attacks. - */ - if (buf_len > LIBCFS_IOC_DATA_MAX) { - CERROR("LNET: user buffer exceeds kernel buffer\n"); - return -EINVAL; - } - - LIBCFS_ALLOC_GFP(hdr, buf_len, GFP_KERNEL); - if (!hdr) - return -ENOMEM; - - /* 'cmd' and permissions get checked in our arch-specific caller */ - if (copy_from_user(hdr, arg, buf_len)) { - CERROR("LNET ioctl: data error\n"); - err = -EFAULT; - goto out; - } - err = libcfs_ioctl_handle(pfile, cmd, arg, hdr); - -out: - LIBCFS_FREE(hdr, buf_len); + LIBCFS_FREE(hdr, hdr->ioc_len); return err; } -- cgit v1.2.3 From db469aa868657ccf4944fb8a8bc13b54002b356e Mon Sep 17 00:00:00 2001 From: Liang Zhen Date: Tue, 22 Mar 2016 19:03:51 -0400 Subject: staging: lustre: libcfs: merge libcfs_ioctl_handle into libcfs_ioctl This is apart of the cleanup of libcfs_ioctl* code. In this part we turn libcfs_ioctl_handle into libcfs_ioctl since libcfs_ioctl is now a skeleton function. Signed-off-by: Liang Zhen Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5435 Reviewed-on: http://review.whamcloud.com/11313 Reviewed-by: Bobi Jam Reviewed-by: Johann Lombardi Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/libcfs/module.c | 37 ++++++++++++----------------- 1 file changed, 15 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/libcfs/module.c b/drivers/staging/lustre/lnet/libcfs/module.c index 5a20e5325f05..8beb954c152c 100644 --- a/drivers/staging/lustre/lnet/libcfs/module.c +++ b/drivers/staging/lustre/lnet/libcfs/module.c @@ -112,11 +112,17 @@ int libcfs_deregister_ioctl(struct libcfs_ioctl_handler *hand) } EXPORT_SYMBOL(libcfs_deregister_ioctl); -static int libcfs_ioctl_handle(struct cfs_psdev_file *pfile, unsigned long cmd, - void __user *arg, struct libcfs_ioctl_hdr *hdr) +static int libcfs_ioctl(struct cfs_psdev_file *pfile, unsigned long cmd, + void __user *arg) { struct libcfs_ioctl_data *data = NULL; - int err = 0; + struct libcfs_ioctl_hdr *hdr; + int err; + + /* 'cmd' and permissions get checked in our arch-specific caller */ + err = libcfs_ioctl_getdata(&hdr, arg); + if (err) + return err; /* * The libcfs_ioctl_data_adjust() function performs adjustment @@ -128,7 +134,7 @@ static int libcfs_ioctl_handle(struct cfs_psdev_file *pfile, unsigned long cmd, data = container_of(hdr, struct libcfs_ioctl_data, ioc_hdr); err = libcfs_ioctl_data_adjust(data); if (err) - return err; + goto out; } switch (cmd) { @@ -141,8 +147,10 @@ static int libcfs_ioctl_handle(struct cfs_psdev_file *pfile, unsigned long cmd, */ case IOC_LIBCFS_MARK_DEBUG: if (!data->ioc_inlbuf1 || - data->ioc_inlbuf1[data->ioc_inllen1 - 1] != '\0') - return -EINVAL; + data->ioc_inlbuf1[data->ioc_inllen1 - 1] != '\0') { + err = -EINVAL; + goto out; + } libcfs_debug_mark_buffer(data->ioc_inlbuf1); break; @@ -163,22 +171,7 @@ static int libcfs_ioctl_handle(struct cfs_psdev_file *pfile, unsigned long cmd, up_read(&ioctl_list_sem); break; } } - - return err; -} - -static int libcfs_ioctl(struct cfs_psdev_file *pfile, unsigned long cmd, - void __user *arg) -{ - struct libcfs_ioctl_hdr *hdr; - int err = 0; - - /* 'cmd' and permissions get checked in our arch-specific caller */ - err = libcfs_ioctl_getdata(&hdr, arg); - if (err) - return err; - - err = libcfs_ioctl_handle(pfile, cmd, arg, hdr); +out: LIBCFS_FREE(hdr, hdr->ioc_len); return err; } -- cgit v1.2.3 From ea1bffa45b1c4c0f33590850aa1cad9bc298b816 Mon Sep 17 00:00:00 2001 From: Liang Zhen Date: Tue, 22 Mar 2016 19:03:52 -0400 Subject: staging: lustre: libcfs: add debugging info for libcfs_ioctl Added some lustre debugging to track down potential future bugs. Signed-off-by: Liang Zhen Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5435 Reviewed-on: http://review.whamcloud.com/11313 Reviewed-by: Bobi Jam Reviewed-by: Johann Lombardi Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/libcfs/module.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/libcfs/module.c b/drivers/staging/lustre/lnet/libcfs/module.c index 8beb954c152c..b7575af84f95 100644 --- a/drivers/staging/lustre/lnet/libcfs/module.c +++ b/drivers/staging/lustre/lnet/libcfs/module.c @@ -121,8 +121,11 @@ static int libcfs_ioctl(struct cfs_psdev_file *pfile, unsigned long cmd, /* 'cmd' and permissions get checked in our arch-specific caller */ err = libcfs_ioctl_getdata(&hdr, arg); - if (err) + if (err) { + CDEBUG_LIMIT(D_ERROR, + "libcfs ioctl: data header error %d\n", err); return err; + } /* * The libcfs_ioctl_data_adjust() function performs adjustment @@ -137,6 +140,7 @@ static int libcfs_ioctl(struct cfs_psdev_file *pfile, unsigned long cmd, goto out; } + CDEBUG(D_IOCTL, "libcfs ioctl cmd %lu\n", cmd); switch (cmd) { case IOC_LIBCFS_CLEAR_DEBUG: libcfs_debug_clear_buffer(); -- cgit v1.2.3 From 0d674c10b04f2698c07953476393ead13980fa7f Mon Sep 17 00:00:00 2001 From: Liang Zhen Date: Tue, 22 Mar 2016 19:03:53 -0400 Subject: staging: lustre: libcfs: move comment in libcfs_ioctl Move the comment about libcfs_ioctl_data_adjust to the section where libcfs_ioctl_data_adjust is actually called. Signed-off-by: Liang Zhen Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5435 Reviewed-on: http://review.whamcloud.com/11313 Reviewed-by: Bobi Jam Reviewed-by: Johann Lombardi Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/libcfs/module.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/libcfs/module.c b/drivers/staging/lustre/lnet/libcfs/module.c index b7575af84f95..4c3fe8796545 100644 --- a/drivers/staging/lustre/lnet/libcfs/module.c +++ b/drivers/staging/lustre/lnet/libcfs/module.c @@ -127,13 +127,13 @@ static int libcfs_ioctl(struct cfs_psdev_file *pfile, unsigned long cmd, return err; } - /* - * The libcfs_ioctl_data_adjust() function performs adjustment - * operations on the libcfs_ioctl_data structure to make - * it usable by the code. This doesn't need to be called - * for new data structures added. - */ if (hdr->ioc_version == LIBCFS_IOCTL_VERSION) { + /* + * The libcfs_ioctl_data_adjust() function performs adjustment + * operations on the libcfs_ioctl_data structure to make + * it usable by the code. This doesn't need to be called + * for new data structures added. + */ data = container_of(hdr, struct libcfs_ioctl_data, ioc_hdr); err = libcfs_ioctl_data_adjust(data); if (err) -- cgit v1.2.3 From 4e31dad14dfec5746bdaa593db0cf0d8a6736b1c Mon Sep 17 00:00:00 2001 From: Liang Zhen Date: Tue, 22 Mar 2016 19:03:54 -0400 Subject: staging: lustre: libcfs: test if data is NULL Make sure data is not NULL otherwise we get an oops when using the IOC_LIBCFS_MARK_DEBUG ioctl. Signed-off-by: Liang Zhen Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5435 Reviewed-on: http://review.whamcloud.com/11313 Reviewed-by: Bobi Jam Reviewed-by: Johann Lombardi Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/libcfs/module.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/libcfs/module.c b/drivers/staging/lustre/lnet/libcfs/module.c index 4c3fe8796545..cce6ce35bd80 100644 --- a/drivers/staging/lustre/lnet/libcfs/module.c +++ b/drivers/staging/lustre/lnet/libcfs/module.c @@ -150,7 +150,7 @@ static int libcfs_ioctl(struct cfs_psdev_file *pfile, unsigned long cmd, * Handled in arch/cfs_module.c */ case IOC_LIBCFS_MARK_DEBUG: - if (!data->ioc_inlbuf1 || + if (!data || !data->ioc_inlbuf1 || data->ioc_inlbuf1[data->ioc_inllen1 - 1] != '\0') { err = -EINVAL; goto out; -- cgit v1.2.3 From 77f716360939767016e2ceab17f8234d0cabc61b Mon Sep 17 00:00:00 2001 From: Liang Zhen Date: Tue, 22 Mar 2016 19:03:55 -0400 Subject: staging: lustre: libcfs: invert test condition for libcfs_ioctl Invert the test of error returned by the handle_ioctl pointer. This reduces the code by one indentation level. Signed-off-by: Liang Zhen Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5435 Reviewed-on: http://review.whamcloud.com/11313 Reviewed-by: Bobi Jam Reviewed-by: Johann Lombardi Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/libcfs/module.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/libcfs/module.c b/drivers/staging/lustre/lnet/libcfs/module.c index cce6ce35bd80..97fc905ad78a 100644 --- a/drivers/staging/lustre/lnet/libcfs/module.c +++ b/drivers/staging/lustre/lnet/libcfs/module.c @@ -165,12 +165,13 @@ static int libcfs_ioctl(struct cfs_psdev_file *pfile, unsigned long cmd, down_read(&ioctl_list_sem); list_for_each_entry(hand, &ioctl_list, item) { err = hand->handle_ioctl(cmd, hdr); - if (err != -EINVAL) { - if (err == 0) - err = libcfs_ioctl_popdata(arg, - hdr, hdr->ioc_len); - break; - } + if (err == -EINVAL) + continue; + + if (!err) + err = libcfs_ioctl_popdata(arg, hdr, + hdr->ioc_len); + break; } up_read(&ioctl_list_sem); break; } -- cgit v1.2.3 From 6d0aeaa36178382898a15836c8c6542d92527a8c Mon Sep 17 00:00:00 2001 From: Liang Zhen Date: Tue, 22 Mar 2016 19:03:56 -0400 Subject: staging: lustre: libcfs: update error messages in linux-module.c The error message are for libcfs layer not LNet. Signed-off-by: Liang Zhen Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5435 Reviewed-on: http://review.whamcloud.com/11313 Reviewed-by: Bobi Jam Reviewed-by: Johann Lombardi Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/libcfs/linux/linux-module.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c index a326ac63c752..35e2fcf238e1 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c @@ -43,7 +43,7 @@ int libcfs_ioctl_data_adjust(struct libcfs_ioctl_data *data) { if (libcfs_ioctl_is_invalid(data)) { - CERROR("LNET: ioctl not correctly formatted\n"); + CERROR("libcfs ioctl: parameter not correctly formatted\n"); return -EINVAL; } @@ -68,7 +68,7 @@ int libcfs_ioctl_getdata(struct libcfs_ioctl_hdr **hdr_pp, if (hdr.ioc_version != LIBCFS_IOCTL_VERSION && hdr.ioc_version != LIBCFS_IOCTL_VERSION2) { - CERROR("LNET: version mismatch expected %#x, got %#x\n", + CERROR("libcfs ioctl: version mismatch expected %#x, got %#x\n", LIBCFS_IOCTL_VERSION, hdr.ioc_version); return -EINVAL; } -- cgit v1.2.3 From ed2f549dc0f687f5d454cb20754340e83e5b9c4f Mon Sep 17 00:00:00 2001 From: Liang Zhen Date: Tue, 22 Mar 2016 19:03:57 -0400 Subject: staging: lustre: libcfs: test if userland data is to small Ensure that user land data is at least the smallest size. Signed-off-by: Liang Zhen Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5435 Reviewed-on: http://review.whamcloud.com/11313 Reviewed-by: Bobi Jam Reviewed-by: Johann Lombardi Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/libcfs/linux/linux-module.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c index 35e2fcf238e1..ae058956f209 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c @@ -73,6 +73,11 @@ int libcfs_ioctl_getdata(struct libcfs_ioctl_hdr **hdr_pp, return -EINVAL; } + if (hdr.ioc_len < sizeof(struct libcfs_ioctl_data)) { + CERROR("libcfs ioctl: user buffer too small for ioctl\n"); + return -EINVAL; + } + if (hdr.ioc_len > LIBCFS_IOC_DATA_MAX) { CERROR("libcfs ioctl: user buffer is too large %d/%d\n", hdr.ioc_len, LIBCFS_IOC_DATA_MAX); -- cgit v1.2.3 From da4e5898375a100e6c1be984ceee84fb5911b6f6 Mon Sep 17 00:00:00 2001 From: Liang Zhen Date: Tue, 22 Mar 2016 19:03:58 -0400 Subject: staging: lustre: lnet: make sure lnet data not greater than LIBCFS_IOC_DATA_MAX Fail to compile if largest LNet user land data structures passed to kernel are larger than LIBCFS_IOC_DATA_MAX Signed-off-by: Liang Zhen Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5435 Reviewed-on: http://review.whamcloud.com/11313 Reviewed-by: Bobi Jam Reviewed-by: Johann Lombardi Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/lnet/api-ni.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 8764755544c9..f825784b79e1 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1864,6 +1864,10 @@ LNetCtl(unsigned int cmd, void *arg) int rc; unsigned long secs_passed; + BUILD_BUG_ON(LIBCFS_IOC_DATA_MAX < + sizeof(struct lnet_ioctl_net_config) + + sizeof(struct lnet_ioctl_config_data)); + switch (cmd) { case IOC_LIBCFS_GET_NI: rc = LNetGetId(data->ioc_count, &id); -- cgit v1.2.3 From a0d5fce76d69f574df1577d20dc3b25f99031167 Mon Sep 17 00:00:00 2001 From: Liang Zhen Date: Tue, 22 Mar 2016 19:03:59 -0400 Subject: staging: lustre: simple cleanup in obd_ioctl_popdata Code simplification for obd_ioctl_popdata. Signed-off-by: Liang Zhen Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5435 Reviewed-on: http://review.whamcloud.com/11313 Reviewed-by: Bobi Jam Reviewed-by: Johann Lombardi Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/obdclass/linux/linux-module.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c b/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c index 8eddf206f1ed..2cd4522462d9 100644 --- a/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c +++ b/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c @@ -158,9 +158,7 @@ int obd_ioctl_popdata(void __user *arg, void *data, int len) { int err; - err = copy_to_user(arg, data, len); - if (err) - err = -EFAULT; + err = copy_to_user(arg, data, len) ? -EFAULT : 0; return err; } EXPORT_SYMBOL(obd_ioctl_popdata); -- cgit v1.2.3 From 7401a6b067bcea2469cb0d6bdae34d8dcafc2a0d Mon Sep 17 00:00:00 2001 From: James Simmons Date: Tue, 22 Mar 2016 19:04:00 -0400 Subject: staging: lustre: libcfs: change variable name Change arg to uparam name for libcfs_ioctl(). Signed-off-by: Liang Zhen Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5435 Reviewed-on: http://review.whamcloud.com/11313 Reviewed-by: Bobi Jam Reviewed-by: Johann Lombardi Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/libcfs/module.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/libcfs/module.c b/drivers/staging/lustre/lnet/libcfs/module.c index 97fc905ad78a..839145e80d98 100644 --- a/drivers/staging/lustre/lnet/libcfs/module.c +++ b/drivers/staging/lustre/lnet/libcfs/module.c @@ -113,14 +113,14 @@ int libcfs_deregister_ioctl(struct libcfs_ioctl_handler *hand) EXPORT_SYMBOL(libcfs_deregister_ioctl); static int libcfs_ioctl(struct cfs_psdev_file *pfile, unsigned long cmd, - void __user *arg) + void __user *uparam) { struct libcfs_ioctl_data *data = NULL; struct libcfs_ioctl_hdr *hdr; int err; /* 'cmd' and permissions get checked in our arch-specific caller */ - err = libcfs_ioctl_getdata(&hdr, arg); + err = libcfs_ioctl_getdata(&hdr, uparam); if (err) { CDEBUG_LIMIT(D_ERROR, "libcfs ioctl: data header error %d\n", err); @@ -169,7 +169,7 @@ static int libcfs_ioctl(struct cfs_psdev_file *pfile, unsigned long cmd, continue; if (!err) - err = libcfs_ioctl_popdata(arg, hdr, + err = libcfs_ioctl_popdata(uparam, hdr, hdr->ioc_len); break; } -- cgit v1.2.3 From 4801919d0825fa35a7290c3625464f460083f9d9 Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Tue, 22 Mar 2016 19:04:01 -0400 Subject: staging: lustre: libcfs: remove libcfsutil.h in comment The header libcfsutil.h has been long gone in the upstream client. Replace libcfsutil.h reference to the current user land header instead. Signed-off-by: John L. Hammond Signed-off-by: James Simmons Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6245 Reviewed-on: http://review.whamcloud.com/14180 Reviewed-by: Dmitry Eremin Reviewed-by: frank zago Reviewed-by: James Simmons Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h index 9c1deae4e226..01bf8d6dedc6 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h @@ -34,7 +34,7 @@ * libcfs/include/libcfs/libcfs_ioctl.h * * Low-level ioctl data structures. Kernel ioctl functions declared here, - * and user space functions are in libcfsutil_ioctl.h. + * and user space functions are in libcfs/util/ioctl.h. * */ -- cgit v1.2.3 From 7b54d08b01e61d35d57cb5cdbaf6cd02babcdf17 Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Tue, 22 Mar 2016 19:04:02 -0400 Subject: staging: lustre: libcfs: move libcfs_ioctl_handler stuff to libcfs.h Move all the libcfs_ioctl_handler code from libcfs_ioctl.h to libcfs.h. The header libcfs_ioctl.h is a uapi header so their is no reason to keep kernel internals in that header. Signed-off-by: John L. Hammond Signed-off-by: James Simmons Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6245 Reviewed-on: http://review.whamcloud.com/14180 Reviewed-by: Dmitry Eremin Reviewed-by: frank zago Reviewed-by: James Simmons Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/include/linux/libcfs/libcfs.h | 14 ++++++++++++++ drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h | 13 ------------- 2 files changed, 14 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs.h b/drivers/staging/lustre/include/linux/libcfs/libcfs.h index 40af75c4201a..0ce52deac625 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs.h @@ -119,6 +119,20 @@ void cfs_get_random_bytes(void *buf, int size); #include "libcfs_fail.h" #include "libcfs_crypto.h" +struct libcfs_ioctl_handler { + struct list_head item; + int (*handle_ioctl)(unsigned int cmd, struct libcfs_ioctl_hdr *hdr); +}; + +#define DECLARE_IOCTL_HANDLER(ident, func) \ + struct libcfs_ioctl_handler ident = { \ + .item = LIST_HEAD_INIT(ident.item), \ + .handle_ioctl = func \ + } + +int libcfs_register_ioctl(struct libcfs_ioctl_handler *hand); +int libcfs_deregister_ioctl(struct libcfs_ioctl_handler *hand); + /* container_of depends on "likely" which is defined in libcfs_private.h */ static inline void *__container_of(void *ptr, unsigned long shift) { diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h index 01bf8d6dedc6..d167d2eaa84d 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h @@ -91,17 +91,6 @@ do { \ data.ioc_len = sizeof(data); \ } while (0) -struct libcfs_ioctl_handler { - struct list_head item; - int (*handle_ioctl)(unsigned int cmd, struct libcfs_ioctl_hdr *hdr); -}; - -#define DECLARE_IOCTL_HANDLER(ident, func) \ - struct libcfs_ioctl_handler ident = { \ - /* .item = */ LIST_HEAD_INIT(ident.item), \ - /* .handle_ioctl = */ func \ - } - /* FIXME check conflict with lustre_lib.h */ #define LIBCFS_IOC_DEBUG_MASK _IOWR('f', 250, long) @@ -223,8 +212,6 @@ static inline bool libcfs_ioctl_is_invalid(struct libcfs_ioctl_data *data) return 0; } -int libcfs_register_ioctl(struct libcfs_ioctl_handler *hand); -int libcfs_deregister_ioctl(struct libcfs_ioctl_handler *hand); int libcfs_ioctl_getdata(struct libcfs_ioctl_hdr **hdr_pp, const struct libcfs_ioctl_hdr __user *uparam); int libcfs_ioctl_popdata(void __user *arg, void *buf, int size); -- cgit v1.2.3 From 5206726ad8e286a09e73ae4a542de47f96d62f27 Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Tue, 22 Mar 2016 19:04:03 -0400 Subject: staging: lustre: libcfs: remove libcfs_ioctl_popdata wrapper Lets just use copy_to_user() directly instead of having a wrapper function. Signed-off-by: John L. Hammond Signed-off-by: James Simmons Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6245 Reviewed-on: http://review.whamcloud.com/14180 Reviewed-by: Dmitry Eremin Reviewed-by: frank zago Reviewed-by: James Simmons Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h | 1 - drivers/staging/lustre/lnet/libcfs/linux/linux-module.c | 7 ------- drivers/staging/lustre/lnet/libcfs/module.c | 7 ++++--- 3 files changed, 4 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h index d167d2eaa84d..45d1165a6ed4 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h @@ -214,7 +214,6 @@ static inline bool libcfs_ioctl_is_invalid(struct libcfs_ioctl_data *data) int libcfs_ioctl_getdata(struct libcfs_ioctl_hdr **hdr_pp, const struct libcfs_ioctl_hdr __user *uparam); -int libcfs_ioctl_popdata(void __user *arg, void *buf, int size); int libcfs_ioctl_data_adjust(struct libcfs_ioctl_data *data); #endif /* __LIBCFS_IOCTL_H__ */ diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c index ae058956f209..890a4588049d 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c @@ -95,13 +95,6 @@ int libcfs_ioctl_getdata(struct libcfs_ioctl_hdr **hdr_pp, return err; } -int libcfs_ioctl_popdata(void __user *arg, void *data, int size) -{ - if (copy_to_user(arg, data, size)) - return -EFAULT; - return 0; -} - static int libcfs_psdev_open(struct inode *inode, struct file *file) { diff --git a/drivers/staging/lustre/lnet/libcfs/module.c b/drivers/staging/lustre/lnet/libcfs/module.c index 839145e80d98..74b92369ac02 100644 --- a/drivers/staging/lustre/lnet/libcfs/module.c +++ b/drivers/staging/lustre/lnet/libcfs/module.c @@ -168,9 +168,10 @@ static int libcfs_ioctl(struct cfs_psdev_file *pfile, unsigned long cmd, if (err == -EINVAL) continue; - if (!err) - err = libcfs_ioctl_popdata(uparam, hdr, - hdr->ioc_len); + if (!err) { + if (copy_to_user(uparam, hdr, hdr->ioc_len)) + err = -EFAULT; + } break; } up_read(&ioctl_list_sem); -- cgit v1.2.3 From 68cf5b83659ecee9ad8a14d8ce74e9c5df6d0956 Mon Sep 17 00:00:00 2001 From: Parinay Kondekar Date: Tue, 22 Mar 2016 19:04:04 -0400 Subject: staging:lustre: remove last bits of the IOC_LIBCFS_PANIC ioctl A few pieces still exist for the IOC_LIBCFS_PANIC ioctl. Remove these last bits to prevent old tools from using them. The latest lustre utilities no longer use this ioctl. Signed-off-by: Parinay Kondekar Signed-off-by: James Simmons Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5844 Reviewed-on: http://review.whamcloud.com/17492 Reviewed-by: Andreas Dilger Reviewed-by: Dmitry Eremin Reviewed-by: John L. Hammond Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h | 2 +- drivers/staging/lustre/lnet/libcfs/linux/linux-module.c | 9 --------- drivers/staging/lustre/lnet/libcfs/module.c | 5 +---- 3 files changed, 2 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h index 45d1165a6ed4..d158cd12a19e 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h @@ -97,7 +97,7 @@ do { \ #define IOC_LIBCFS_TYPE 'e' #define IOC_LIBCFS_MIN_NR 30 /* libcfs ioctls */ -#define IOC_LIBCFS_PANIC _IOWR('e', 30, long) +/* IOC_LIBCFS_PANIC obsolete in 2.8.0, was _IOWR('e', 30, IOCTL_LIBCFS_TYPE) */ #define IOC_LIBCFS_CLEAR_DEBUG _IOWR('e', 31, long) #define IOC_LIBCFS_MARK_DEBUG _IOWR('e', 32, long) #define IOC_LIBCFS_MEMHOG _IOWR('e', 36, long) diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c index 890a4588049d..d801d8770cf7 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c @@ -141,15 +141,6 @@ static long libcfs_ioctl(struct file *file, return -EINVAL; } - /* Handle platform-dependent IOC requests */ - switch (cmd) { - case IOC_LIBCFS_PANIC: - if (!capable(CFS_CAP_SYS_BOOT)) - return -EPERM; - panic("debugctl-invoked panic"); - return 0; - } - if (libcfs_psdev_ops.p_ioctl) rc = libcfs_psdev_ops.p_ioctl(&pfile, cmd, (void __user *)arg); else diff --git a/drivers/staging/lustre/lnet/libcfs/module.c b/drivers/staging/lustre/lnet/libcfs/module.c index 74b92369ac02..3a88e6447d3b 100644 --- a/drivers/staging/lustre/lnet/libcfs/module.c +++ b/drivers/staging/lustre/lnet/libcfs/module.c @@ -145,10 +145,7 @@ static int libcfs_ioctl(struct cfs_psdev_file *pfile, unsigned long cmd, case IOC_LIBCFS_CLEAR_DEBUG: libcfs_debug_clear_buffer(); break; - /* - * case IOC_LIBCFS_PANIC: - * Handled in arch/cfs_module.c - */ + case IOC_LIBCFS_MARK_DEBUG: if (!data || !data->ioc_inlbuf1 || data->ioc_inlbuf1[data->ioc_inllen1 - 1] != '\0') { -- cgit v1.2.3 From c878547fdfa4f8023930cd43b75023f3061f9aa6 Mon Sep 17 00:00:00 2001 From: Parinay Kondekar Date: Tue, 22 Mar 2016 19:04:05 -0400 Subject: staging:lustre: remove the IOC_LIBCFS_MEMHOG ioctl The IOC_LIBCFS_MEMHOG is not needed so remove the last bits. Signed-off-by: Parinay Kondekar Signed-off-by: James Simmons Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5844 Reviewed-on: http://review.whamcloud.com/17492 Reviewed-by: Andreas Dilger Reviewed-by: Dmitry Eremin Reviewed-by: John L. Hammond Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h index d158cd12a19e..2e4e31b2cc41 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h @@ -100,7 +100,7 @@ do { \ /* IOC_LIBCFS_PANIC obsolete in 2.8.0, was _IOWR('e', 30, IOCTL_LIBCFS_TYPE) */ #define IOC_LIBCFS_CLEAR_DEBUG _IOWR('e', 31, long) #define IOC_LIBCFS_MARK_DEBUG _IOWR('e', 32, long) -#define IOC_LIBCFS_MEMHOG _IOWR('e', 36, long) +/* IOC_LIBCFS_MEMHOG obsolete in 2.8.0, was _IOWR('e', 36, IOCTL_LIBCFS_TYPE) */ /* lnet ioctls */ #define IOC_LIBCFS_GET_NI _IOWR('e', 50, long) #define IOC_LIBCFS_FAIL_NID _IOWR('e', 51, long) -- cgit v1.2.3 From 4678d183caf1b8a68860ca07fad95d9c6de14cc3 Mon Sep 17 00:00:00 2001 From: Parinay Kondekar Date: Tue, 22 Mar 2016 19:04:06 -0400 Subject: staging:lustre: remove libcfs_psdev_[open|release] With struct libcfs_device_userstate gone we can remove the remaining code of libcfs_psdev_ops.p_[open|close] as well as the libcfs_psdev_[open|release] functions. Signed-off-by: Parinay Kondekar Signed-off-by: James Simmons Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5844 Reviewed-on: http://review.whamcloud.com/17492 Reviewed-by: Andreas Dilger Reviewed-by: Dmitry Eremin Reviewed-by: John L. Hammond Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- .../staging/lustre/include/linux/libcfs/libcfs.h | 2 -- .../lustre/lnet/libcfs/linux/linux-module.c | 32 +--------------------- drivers/staging/lustre/lnet/libcfs/module.c | 16 ----------- 3 files changed, 1 insertion(+), 49 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs.h b/drivers/staging/lustre/include/linux/libcfs/libcfs.h index 0ce52deac625..5d228e5b438e 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs.h @@ -73,8 +73,6 @@ struct cfs_psdev_file { }; struct cfs_psdev_ops { - int (*p_open)(unsigned long, void *); - int (*p_close)(unsigned long, void *); int (*p_read)(struct cfs_psdev_file *, char *, unsigned long); int (*p_write)(struct cfs_psdev_file *, char *, unsigned long); int (*p_ioctl)(struct cfs_psdev_file *, unsigned long, void __user *); diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c index d801d8770cf7..633d76bec63c 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c @@ -95,35 +95,6 @@ int libcfs_ioctl_getdata(struct libcfs_ioctl_hdr **hdr_pp, return err; } -static int -libcfs_psdev_open(struct inode *inode, struct file *file) -{ - int rc = 0; - - if (!inode) - return -EINVAL; - if (libcfs_psdev_ops.p_open) - rc = libcfs_psdev_ops.p_open(0, NULL); - else - return -EPERM; - return rc; -} - -/* called when closing /dev/device */ -static int -libcfs_psdev_release(struct inode *inode, struct file *file) -{ - int rc = 0; - - if (!inode) - return -EINVAL; - if (libcfs_psdev_ops.p_close) - rc = libcfs_psdev_ops.p_close(0, NULL); - else - rc = -EPERM; - return rc; -} - static long libcfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -149,9 +120,8 @@ static long libcfs_ioctl(struct file *file, } static const struct file_operations libcfs_fops = { + .owner = THIS_MODULE, .unlocked_ioctl = libcfs_ioctl, - .open = libcfs_psdev_open, - .release = libcfs_psdev_release, }; struct miscdevice libcfs_dev = { diff --git a/drivers/staging/lustre/lnet/libcfs/module.c b/drivers/staging/lustre/lnet/libcfs/module.c index 3a88e6447d3b..4d38aafb0b18 100644 --- a/drivers/staging/lustre/lnet/libcfs/module.c +++ b/drivers/staging/lustre/lnet/libcfs/module.c @@ -65,20 +65,6 @@ static struct dentry *lnet_debugfs_root; -/* called when opening /dev/device */ -static int libcfs_psdev_open(unsigned long flags, void *args) -{ - try_module_get(THIS_MODULE); - return 0; -} - -/* called when closing /dev/device */ -static int libcfs_psdev_release(unsigned long flags, void *args) -{ - module_put(THIS_MODULE); - return 0; -} - static DECLARE_RWSEM(ioctl_list_sem); static LIST_HEAD(ioctl_list); @@ -180,8 +166,6 @@ out: } struct cfs_psdev_ops libcfs_psdev_ops = { - libcfs_psdev_open, - libcfs_psdev_release, NULL, NULL, libcfs_ioctl -- cgit v1.2.3 From ae272a48a16b53f77215749a68777c6c89ec9925 Mon Sep 17 00:00:00 2001 From: Parinay Kondekar Date: Tue, 22 Mar 2016 19:04:07 -0400 Subject: staging:lustre: call libcfs_ioctl directly No reason to go through the cfs_psdev_ops abstract to call libcfs_ioctl. Just call libcfs_ioctl directly. Signed-off-by: Parinay Kondekar Signed-off-by: James Simmons Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5844 Reviewed-on: http://review.whamcloud.com/17492 Reviewed-by: Andreas Dilger Reviewed-by: Dmitry Eremin Reviewed-by: John L. Hammond Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/include/linux/libcfs/libcfs.h | 3 ++- drivers/staging/lustre/lnet/libcfs/linux/linux-module.c | 13 ++++--------- drivers/staging/lustre/lnet/libcfs/module.c | 5 ++--- 3 files changed, 8 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs.h b/drivers/staging/lustre/include/linux/libcfs/libcfs.h index 5d228e5b438e..592ad31fbfac 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs.h @@ -75,7 +75,6 @@ struct cfs_psdev_file { struct cfs_psdev_ops { int (*p_read)(struct cfs_psdev_file *, char *, unsigned long); int (*p_write)(struct cfs_psdev_file *, char *, unsigned long); - int (*p_ioctl)(struct cfs_psdev_file *, unsigned long, void __user *); }; /* @@ -131,6 +130,8 @@ struct libcfs_ioctl_handler { int libcfs_register_ioctl(struct libcfs_ioctl_handler *hand); int libcfs_deregister_ioctl(struct libcfs_ioctl_handler *hand); +int libcfs_ioctl(struct cfs_psdev_file *pfile, unsigned long cmd, void *arg); + /* container_of depends on "likely" which is defined in libcfs_private.h */ static inline void *__container_of(void *ptr, unsigned long shift) { diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c index 633d76bec63c..6f35a80e20a1 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c @@ -95,11 +95,10 @@ int libcfs_ioctl_getdata(struct libcfs_ioctl_hdr **hdr_pp, return err; } -static long libcfs_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) +static long +libcfs_psdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct cfs_psdev_file pfile; - int rc = 0; if (!capable(CAP_SYS_ADMIN)) return -EACCES; @@ -112,16 +111,12 @@ static long libcfs_ioctl(struct file *file, return -EINVAL; } - if (libcfs_psdev_ops.p_ioctl) - rc = libcfs_psdev_ops.p_ioctl(&pfile, cmd, (void __user *)arg); - else - rc = -EPERM; - return rc; + return libcfs_ioctl(&pfile, cmd, (void __user *)arg); } static const struct file_operations libcfs_fops = { .owner = THIS_MODULE, - .unlocked_ioctl = libcfs_ioctl, + .unlocked_ioctl = libcfs_psdev_ioctl, }; struct miscdevice libcfs_dev = { diff --git a/drivers/staging/lustre/lnet/libcfs/module.c b/drivers/staging/lustre/lnet/libcfs/module.c index 4d38aafb0b18..4af455733a3b 100644 --- a/drivers/staging/lustre/lnet/libcfs/module.c +++ b/drivers/staging/lustre/lnet/libcfs/module.c @@ -98,8 +98,8 @@ int libcfs_deregister_ioctl(struct libcfs_ioctl_handler *hand) } EXPORT_SYMBOL(libcfs_deregister_ioctl); -static int libcfs_ioctl(struct cfs_psdev_file *pfile, unsigned long cmd, - void __user *uparam) +int libcfs_ioctl(struct cfs_psdev_file *pfile, unsigned long cmd, + void __user *uparam) { struct libcfs_ioctl_data *data = NULL; struct libcfs_ioctl_hdr *hdr; @@ -168,7 +168,6 @@ out: struct cfs_psdev_ops libcfs_psdev_ops = { NULL, NULL, - libcfs_ioctl }; int lprocfs_call_handler(void *data, int write, loff_t *ppos, -- cgit v1.2.3 From 89010fbc22162708c39447129580c4a47b03260e Mon Sep 17 00:00:00 2001 From: Parinay Kondekar Date: Tue, 22 Mar 2016 19:04:08 -0400 Subject: staging:lustre: remove libcfs pseudo device abstraction With the libcfs ioctl cleanup we no longer need the libcfs pseudo device abstraction. Signed-off-by: Parinay Kondekar Signed-off-by: James Simmons Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5844 Reviewed-on: http://review.whamcloud.com/17492 Reviewed-by: Andreas Dilger Reviewed-by: Dmitry Eremin Reviewed-by: John L. Hammond Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- .../staging/lustre/include/linux/libcfs/libcfs.h | 22 +--------------------- .../lustre/lnet/libcfs/linux/linux-module.c | 4 +--- drivers/staging/lustre/lnet/libcfs/module.c | 8 +------- 3 files changed, 3 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs.h b/drivers/staging/lustre/include/linux/libcfs/libcfs.h index 592ad31fbfac..1cd18790d22e 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs.h @@ -59,24 +59,6 @@ #define LNET_ACCEPTOR_MIN_RESERVED_PORT 512 #define LNET_ACCEPTOR_MAX_RESERVED_PORT 1023 -/* - * libcfs pseudo device operations - * - * It's just draft now. - */ - -struct cfs_psdev_file { - unsigned long off; - void *private_data; - unsigned long reserved1; - unsigned long reserved2; -}; - -struct cfs_psdev_ops { - int (*p_read)(struct cfs_psdev_file *, char *, unsigned long); - int (*p_write)(struct cfs_psdev_file *, char *, unsigned long); -}; - /* * Drop into debugger, if possible. Implementation is provided by platform. */ @@ -130,7 +112,7 @@ struct libcfs_ioctl_handler { int libcfs_register_ioctl(struct libcfs_ioctl_handler *hand); int libcfs_deregister_ioctl(struct libcfs_ioctl_handler *hand); -int libcfs_ioctl(struct cfs_psdev_file *pfile, unsigned long cmd, void *arg); +int libcfs_ioctl(unsigned long cmd, void *arg); /* container_of depends on "likely" which is defined in libcfs_private.h */ static inline void *__container_of(void *ptr, unsigned long shift) @@ -156,8 +138,6 @@ extern struct miscdevice libcfs_dev; extern char lnet_upcall[1024]; extern char lnet_debug_log_upcall[1024]; -extern struct cfs_psdev_ops libcfs_psdev_ops; - extern struct cfs_wi_sched *cfs_sched_rehash; struct lnet_debugfs_symlink_def { diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c index 6f35a80e20a1..7634551afed3 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c @@ -98,8 +98,6 @@ int libcfs_ioctl_getdata(struct libcfs_ioctl_hdr **hdr_pp, static long libcfs_psdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - struct cfs_psdev_file pfile; - if (!capable(CAP_SYS_ADMIN)) return -EACCES; @@ -111,7 +109,7 @@ libcfs_psdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) return -EINVAL; } - return libcfs_ioctl(&pfile, cmd, (void __user *)arg); + return libcfs_ioctl(cmd, (void __user *)arg); } static const struct file_operations libcfs_fops = { diff --git a/drivers/staging/lustre/lnet/libcfs/module.c b/drivers/staging/lustre/lnet/libcfs/module.c index 4af455733a3b..49c2d03dc9de 100644 --- a/drivers/staging/lustre/lnet/libcfs/module.c +++ b/drivers/staging/lustre/lnet/libcfs/module.c @@ -98,8 +98,7 @@ int libcfs_deregister_ioctl(struct libcfs_ioctl_handler *hand) } EXPORT_SYMBOL(libcfs_deregister_ioctl); -int libcfs_ioctl(struct cfs_psdev_file *pfile, unsigned long cmd, - void __user *uparam) +int libcfs_ioctl(unsigned long cmd, void __user *uparam) { struct libcfs_ioctl_data *data = NULL; struct libcfs_ioctl_hdr *hdr; @@ -165,11 +164,6 @@ out: return err; } -struct cfs_psdev_ops libcfs_psdev_ops = { - NULL, - NULL, -}; - int lprocfs_call_handler(void *data, int write, loff_t *ppos, void __user *buffer, size_t *lenp, int (*handler)(void *data, int write, loff_t pos, -- cgit v1.2.3 From b02e9d87a76501f2782436c3d5c8d2dde63023dc Mon Sep 17 00:00:00 2001 From: James Simmons Date: Tue, 22 Mar 2016 19:04:09 -0400 Subject: staging: lustre: libcfs: removal all userland only macros from libcfs_ioctl.h All the macros in libcfs_ioctl.h that is needed by user land have been moved into the lustre utilities software stack. Signed-off-by: James Simmons Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6245 Reviewed-on: http://review.whamcloud.com/17643 Reviewed-by: Bob Glossman Reviewed-by: John L. Hammond Reviewed-by: Dmitry Eremin Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h index 2e4e31b2cc41..e109a4b0f45a 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h @@ -76,21 +76,12 @@ struct libcfs_ioctl_data { char ioc_bulk[0]; }; -#define ioc_priority ioc_u32[0] - struct libcfs_debug_ioctl_data { struct libcfs_ioctl_hdr hdr; unsigned int subs; unsigned int debug; }; -#define LIBCFS_IOC_INIT(data) \ -do { \ - memset(&data, 0, sizeof(data)); \ - data.ioc_version = LIBCFS_IOCTL_VERSION; \ - data.ioc_len = sizeof(data); \ -} while (0) - /* FIXME check conflict with lustre_lib.h */ #define LIBCFS_IOC_DEBUG_MASK _IOWR('f', 250, long) -- cgit v1.2.3 From cfec4b5c66fa3412b712a6409c2c3d4192faea45 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Tue, 22 Mar 2016 19:04:10 -0400 Subject: staging: lustre: libcfs: migrate inline functions to source file Move large inline functions out of libcfs_ioctl.h to the source file linux-module.c belonging to libcfs. This code is only used by the core of libcfs and such inline functions don't belong in a uapi header file. Signed-off-by: James Simmons Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6245 Reviewed-on: http://review.whamcloud.com/17643 Reviewed-by: Bob Glossman Reviewed-by: John L. Hammond Reviewed-by: Dmitry Eremin Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- .../lustre/include/linux/libcfs/libcfs_ioctl.h | 65 ---------------------- .../lustre/lnet/libcfs/linux/linux-module.c | 65 ++++++++++++++++++++++ 2 files changed, 65 insertions(+), 65 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h index e109a4b0f45a..3af13e43169f 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h @@ -138,71 +138,6 @@ struct libcfs_debug_ioctl_data { #define IOC_LIBCFS_GET_LNET_STATS _IOWR(IOC_LIBCFS_TYPE, 91, IOCTL_CONFIG_SIZE) #define IOC_LIBCFS_MAX_NR 91 -static inline int libcfs_ioctl_packlen(struct libcfs_ioctl_data *data) -{ - int len = sizeof(*data); - - len += cfs_size_round(data->ioc_inllen1); - len += cfs_size_round(data->ioc_inllen2); - return len; -} - -static inline bool libcfs_ioctl_is_invalid(struct libcfs_ioctl_data *data) -{ - if (data->ioc_hdr.ioc_len > (1 << 30)) { - CERROR("LIBCFS ioctl: ioc_len larger than 1<<30\n"); - return 1; - } - if (data->ioc_inllen1 > (1<<30)) { - CERROR("LIBCFS ioctl: ioc_inllen1 larger than 1<<30\n"); - return 1; - } - if (data->ioc_inllen2 > (1<<30)) { - CERROR("LIBCFS ioctl: ioc_inllen2 larger than 1<<30\n"); - return 1; - } - if (data->ioc_inlbuf1 && !data->ioc_inllen1) { - CERROR("LIBCFS ioctl: inlbuf1 pointer but 0 length\n"); - return 1; - } - if (data->ioc_inlbuf2 && !data->ioc_inllen2) { - CERROR("LIBCFS ioctl: inlbuf2 pointer but 0 length\n"); - return 1; - } - if (data->ioc_pbuf1 && !data->ioc_plen1) { - CERROR("LIBCFS ioctl: pbuf1 pointer but 0 length\n"); - return 1; - } - if (data->ioc_pbuf2 && !data->ioc_plen2) { - CERROR("LIBCFS ioctl: pbuf2 pointer but 0 length\n"); - return 1; - } - if (data->ioc_plen1 && !data->ioc_pbuf1) { - CERROR("LIBCFS ioctl: plen1 nonzero but no pbuf1 pointer\n"); - return 1; - } - if (data->ioc_plen2 && !data->ioc_pbuf2) { - CERROR("LIBCFS ioctl: plen2 nonzero but no pbuf2 pointer\n"); - return 1; - } - if ((__u32)libcfs_ioctl_packlen(data) != data->ioc_hdr.ioc_len) { - CERROR("LIBCFS ioctl: packlen != ioc_len\n"); - return 1; - } - if (data->ioc_inllen1 && - data->ioc_bulk[data->ioc_inllen1 - 1] != '\0') { - CERROR("LIBCFS ioctl: inlbuf1 not 0 terminated\n"); - return 1; - } - if (data->ioc_inllen2 && - data->ioc_bulk[cfs_size_round(data->ioc_inllen1) + - data->ioc_inllen2 - 1] != '\0') { - CERROR("LIBCFS ioctl: inlbuf2 not 0 terminated\n"); - return 1; - } - return 0; -} - int libcfs_ioctl_getdata(struct libcfs_ioctl_hdr **hdr_pp, const struct libcfs_ioctl_hdr __user *uparam); int libcfs_ioctl_data_adjust(struct libcfs_ioctl_data *data); diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c index 7634551afed3..af19f3cabd2c 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c @@ -40,6 +40,71 @@ #define LNET_MINOR 240 +static inline int libcfs_ioctl_packlen(struct libcfs_ioctl_data *data) +{ + int len = sizeof(*data); + + len += cfs_size_round(data->ioc_inllen1); + len += cfs_size_round(data->ioc_inllen2); + return len; +} + +static inline bool libcfs_ioctl_is_invalid(struct libcfs_ioctl_data *data) +{ + if (data->ioc_hdr.ioc_len > (1 << 30)) { + CERROR("LIBCFS ioctl: ioc_len larger than 1<<30\n"); + return 1; + } + if (data->ioc_inllen1 > (1<<30)) { + CERROR("LIBCFS ioctl: ioc_inllen1 larger than 1<<30\n"); + return 1; + } + if (data->ioc_inllen2 > (1<<30)) { + CERROR("LIBCFS ioctl: ioc_inllen2 larger than 1<<30\n"); + return 1; + } + if (data->ioc_inlbuf1 && !data->ioc_inllen1) { + CERROR("LIBCFS ioctl: inlbuf1 pointer but 0 length\n"); + return 1; + } + if (data->ioc_inlbuf2 && !data->ioc_inllen2) { + CERROR("LIBCFS ioctl: inlbuf2 pointer but 0 length\n"); + return 1; + } + if (data->ioc_pbuf1 && !data->ioc_plen1) { + CERROR("LIBCFS ioctl: pbuf1 pointer but 0 length\n"); + return 1; + } + if (data->ioc_pbuf2 && !data->ioc_plen2) { + CERROR("LIBCFS ioctl: pbuf2 pointer but 0 length\n"); + return 1; + } + if (data->ioc_plen1 && !data->ioc_pbuf1) { + CERROR("LIBCFS ioctl: plen1 nonzero but no pbuf1 pointer\n"); + return 1; + } + if (data->ioc_plen2 && !data->ioc_pbuf2) { + CERROR("LIBCFS ioctl: plen2 nonzero but no pbuf2 pointer\n"); + return 1; + } + if ((__u32)libcfs_ioctl_packlen(data) != data->ioc_hdr.ioc_len) { + CERROR("LIBCFS ioctl: packlen != ioc_len\n"); + return 1; + } + if (data->ioc_inllen1 && + data->ioc_bulk[data->ioc_inllen1 - 1] != '\0') { + CERROR("LIBCFS ioctl: inlbuf1 not 0 terminated\n"); + return 1; + } + if (data->ioc_inllen2 && + data->ioc_bulk[cfs_size_round(data->ioc_inllen1) + + data->ioc_inllen2 - 1] != '\0') { + CERROR("LIBCFS ioctl: inlbuf2 not 0 terminated\n"); + return 1; + } + return 0; +} + int libcfs_ioctl_data_adjust(struct libcfs_ioctl_data *data) { if (libcfs_ioctl_is_invalid(data)) { -- cgit v1.2.3 From 659bd8d9792a354ba755dab623dc9909cd03206e Mon Sep 17 00:00:00 2001 From: James Simmons Date: Tue, 22 Mar 2016 19:04:11 -0400 Subject: staging: lustre: libcfs: move function declarations from libcfs_ioctl.h Move the function declartions that are used only by kernel space to libcfs.h This makes libcfs_ioctl.h a offical uapi header now. Move large inline functions out of libcfs_ioctl.h to the source file linux-module.c belonging to libcfs. This code is only used by the core of libcfs and such inline functions don't belong in a uapi header file. Signed-off-by: James Simmons Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6245 Reviewed-on: http://review.whamcloud.com/17643 Reviewed-by: Bob Glossman Reviewed-by: John L. Hammond Reviewed-by: Dmitry Eremin Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/include/linux/libcfs/libcfs.h | 3 +++ drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h | 4 ---- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs.h b/drivers/staging/lustre/include/linux/libcfs/libcfs.h index 1cd18790d22e..6a8e0d0d61bf 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs.h @@ -112,6 +112,9 @@ struct libcfs_ioctl_handler { int libcfs_register_ioctl(struct libcfs_ioctl_handler *hand); int libcfs_deregister_ioctl(struct libcfs_ioctl_handler *hand); +int libcfs_ioctl_getdata(struct libcfs_ioctl_hdr **hdr_pp, + const struct libcfs_ioctl_hdr __user *uparam); +int libcfs_ioctl_data_adjust(struct libcfs_ioctl_data *data); int libcfs_ioctl(unsigned long cmd, void *arg); /* container_of depends on "likely" which is defined in libcfs_private.h */ diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h index 3af13e43169f..c379d29992d1 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h @@ -138,8 +138,4 @@ struct libcfs_debug_ioctl_data { #define IOC_LIBCFS_GET_LNET_STATS _IOWR(IOC_LIBCFS_TYPE, 91, IOCTL_CONFIG_SIZE) #define IOC_LIBCFS_MAX_NR 91 -int libcfs_ioctl_getdata(struct libcfs_ioctl_hdr **hdr_pp, - const struct libcfs_ioctl_hdr __user *uparam); -int libcfs_ioctl_data_adjust(struct libcfs_ioctl_data *data); - #endif /* __LIBCFS_IOCTL_H__ */ -- cgit v1.2.3 From da71485102ff8d4b3481dedddcb5a79164f1e4bb Mon Sep 17 00:00:00 2001 From: James Simmons Date: Tue, 22 Mar 2016 19:04:12 -0400 Subject: staging: lustre: libcfs: make libcfs_ioctl.h readable Fix up all thw whitescapes and line up the IOCTL defines so it is readable. Signed-off-by: James Simmons Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6245 Reviewed-on: http://review.whamcloud.com/17643 Reviewed-by: Bob Glossman Reviewed-by: John L. Hammond Reviewed-by: Dmitry Eremin Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- .../lustre/include/linux/libcfs/libcfs_ioctl.h | 57 +++++++++++----------- 1 file changed, 29 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h index c379d29992d1..48372c4cc9a3 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h @@ -82,41 +82,42 @@ struct libcfs_debug_ioctl_data { unsigned int debug; }; -/* FIXME check conflict with lustre_lib.h */ -#define LIBCFS_IOC_DEBUG_MASK _IOWR('f', 250, long) +/* 'f' ioctls are defined in lustre_ioctl.h and lustre_user.h except for: */ +#define LIBCFS_IOC_DEBUG_MASK _IOWR('f', 250, long) +#define IOCTL_LIBCFS_TYPE long -#define IOC_LIBCFS_TYPE 'e' -#define IOC_LIBCFS_MIN_NR 30 +#define IOC_LIBCFS_TYPE ('e') +#define IOC_LIBCFS_MIN_NR 30 /* libcfs ioctls */ /* IOC_LIBCFS_PANIC obsolete in 2.8.0, was _IOWR('e', 30, IOCTL_LIBCFS_TYPE) */ -#define IOC_LIBCFS_CLEAR_DEBUG _IOWR('e', 31, long) -#define IOC_LIBCFS_MARK_DEBUG _IOWR('e', 32, long) +#define IOC_LIBCFS_CLEAR_DEBUG _IOWR('e', 31, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_MARK_DEBUG _IOWR('e', 32, IOCTL_LIBCFS_TYPE) /* IOC_LIBCFS_MEMHOG obsolete in 2.8.0, was _IOWR('e', 36, IOCTL_LIBCFS_TYPE) */ /* lnet ioctls */ -#define IOC_LIBCFS_GET_NI _IOWR('e', 50, long) -#define IOC_LIBCFS_FAIL_NID _IOWR('e', 51, long) -#define IOC_LIBCFS_NOTIFY_ROUTER _IOWR('e', 55, long) -#define IOC_LIBCFS_UNCONFIGURE _IOWR('e', 56, long) -/* #define IOC_LIBCFS_PORTALS_COMPATIBILITY _IOWR('e', 57, long) */ -#define IOC_LIBCFS_LNET_DIST _IOWR('e', 58, long) -#define IOC_LIBCFS_CONFIGURE _IOWR('e', 59, long) -#define IOC_LIBCFS_TESTPROTOCOMPAT _IOWR('e', 60, long) -#define IOC_LIBCFS_PING _IOWR('e', 61, long) -/* #define IOC_LIBCFS_DEBUG_PEER _IOWR('e', 62, long) */ -#define IOC_LIBCFS_LNETST _IOWR('e', 63, long) -#define IOC_LIBCFS_LNET_FAULT _IOWR('e', 64, long) +#define IOC_LIBCFS_GET_NI _IOWR('e', 50, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_FAIL_NID _IOWR('e', 51, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_NOTIFY_ROUTER _IOWR('e', 55, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_UNCONFIGURE _IOWR('e', 56, IOCTL_LIBCFS_TYPE) +/* IOC_LIBCFS_PORTALS_COMPATIBILITY _IOWR('e', 57, IOCTL_LIBCFS_TYPE) */ +#define IOC_LIBCFS_LNET_DIST _IOWR('e', 58, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_CONFIGURE _IOWR('e', 59, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_TESTPROTOCOMPAT _IOWR('e', 60, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_PING _IOWR('e', 61, IOCTL_LIBCFS_TYPE) +/* IOC_LIBCFS_DEBUG_PEER _IOWR('e', 62, IOCTL_LIBCFS_TYPE) */ +#define IOC_LIBCFS_LNETST _IOWR('e', 63, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_LNET_FAULT _IOWR('e', 64, IOCTL_LIBCFS_TYPE) /* lnd ioctls */ -#define IOC_LIBCFS_REGISTER_MYNID _IOWR('e', 70, long) -#define IOC_LIBCFS_CLOSE_CONNECTION _IOWR('e', 71, long) -#define IOC_LIBCFS_PUSH_CONNECTION _IOWR('e', 72, long) -#define IOC_LIBCFS_GET_CONN _IOWR('e', 73, long) -#define IOC_LIBCFS_DEL_PEER _IOWR('e', 74, long) -#define IOC_LIBCFS_ADD_PEER _IOWR('e', 75, long) -#define IOC_LIBCFS_GET_PEER _IOWR('e', 76, long) +#define IOC_LIBCFS_REGISTER_MYNID _IOWR('e', 70, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_CLOSE_CONNECTION _IOWR('e', 71, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_PUSH_CONNECTION _IOWR('e', 72, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_GET_CONN _IOWR('e', 73, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_DEL_PEER _IOWR('e', 74, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_ADD_PEER _IOWR('e', 75, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_GET_PEER _IOWR('e', 76, IOCTL_LIBCFS_TYPE) /* ioctl 77 is free for use */ -#define IOC_LIBCFS_ADD_INTERFACE _IOWR('e', 78, long) -#define IOC_LIBCFS_DEL_INTERFACE _IOWR('e', 79, long) -#define IOC_LIBCFS_GET_INTERFACE _IOWR('e', 80, long) +#define IOC_LIBCFS_ADD_INTERFACE _IOWR('e', 78, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_DEL_INTERFACE _IOWR('e', 79, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_GET_INTERFACE _IOWR('e', 80, IOCTL_LIBCFS_TYPE) /* * DLC Specific IOCTL numbers. -- cgit v1.2.3 From 92c18e1335cf757d9881864b58e725482b38a398 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Tue, 22 Mar 2016 19:04:13 -0400 Subject: staging: lustre: libcfs: add uapi headers to libcfs_ioctl.h Need a few uapi headers to make libcfs_ioctl.h compilable in userland. Signed-off-by: James Simmons Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6245 Reviewed-on: http://review.whamcloud.com/17643 Reviewed-by: Bob Glossman Reviewed-by: John L. Hammond Reviewed-by: Dmitry Eremin Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h index 48372c4cc9a3..4b9102bd95d5 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h @@ -41,6 +41,9 @@ #ifndef __LIBCFS_IOCTL_H__ #define __LIBCFS_IOCTL_H__ +#include +#include + #define LIBCFS_IOCTL_VERSION 0x0001000a #define LIBCFS_IOCTL_VERSION2 0x0001000b -- cgit v1.2.3 From 460a222d9e1c5c0b2f1e037aeab0408a733031dc Mon Sep 17 00:00:00 2001 From: James Simmons Date: Tue, 22 Mar 2016 19:04:14 -0400 Subject: staging: lustre: libcfs: return proper bool values Return real bool values for libcfs_ioctl_is_invalid(). Signed-off-by: James Simmons Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6245 Reviewed-on: http://review.whamcloud.com/17643 Reviewed-by: Bob Glossman Reviewed-by: John L. Hammond Reviewed-by: Dmitry Eremin Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- .../lustre/lnet/libcfs/linux/linux-module.c | 26 +++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c index af19f3cabd2c..d5b7d3a210da 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c @@ -53,56 +53,56 @@ static inline bool libcfs_ioctl_is_invalid(struct libcfs_ioctl_data *data) { if (data->ioc_hdr.ioc_len > (1 << 30)) { CERROR("LIBCFS ioctl: ioc_len larger than 1<<30\n"); - return 1; + return true; } if (data->ioc_inllen1 > (1<<30)) { CERROR("LIBCFS ioctl: ioc_inllen1 larger than 1<<30\n"); - return 1; + return true; } if (data->ioc_inllen2 > (1<<30)) { CERROR("LIBCFS ioctl: ioc_inllen2 larger than 1<<30\n"); - return 1; + return true; } if (data->ioc_inlbuf1 && !data->ioc_inllen1) { CERROR("LIBCFS ioctl: inlbuf1 pointer but 0 length\n"); - return 1; + return true; } if (data->ioc_inlbuf2 && !data->ioc_inllen2) { CERROR("LIBCFS ioctl: inlbuf2 pointer but 0 length\n"); - return 1; + return true; } if (data->ioc_pbuf1 && !data->ioc_plen1) { CERROR("LIBCFS ioctl: pbuf1 pointer but 0 length\n"); - return 1; + return true; } if (data->ioc_pbuf2 && !data->ioc_plen2) { CERROR("LIBCFS ioctl: pbuf2 pointer but 0 length\n"); - return 1; + return true; } if (data->ioc_plen1 && !data->ioc_pbuf1) { CERROR("LIBCFS ioctl: plen1 nonzero but no pbuf1 pointer\n"); - return 1; + return true; } if (data->ioc_plen2 && !data->ioc_pbuf2) { CERROR("LIBCFS ioctl: plen2 nonzero but no pbuf2 pointer\n"); - return 1; + return true; } if ((__u32)libcfs_ioctl_packlen(data) != data->ioc_hdr.ioc_len) { CERROR("LIBCFS ioctl: packlen != ioc_len\n"); - return 1; + return true; } if (data->ioc_inllen1 && data->ioc_bulk[data->ioc_inllen1 - 1] != '\0') { CERROR("LIBCFS ioctl: inlbuf1 not 0 terminated\n"); - return 1; + return true; } if (data->ioc_inllen2 && data->ioc_bulk[cfs_size_round(data->ioc_inllen1) + data->ioc_inllen2 - 1] != '\0') { CERROR("LIBCFS ioctl: inlbuf2 not 0 terminated\n"); - return 1; + return true; } - return 0; + return false; } int libcfs_ioctl_data_adjust(struct libcfs_ioctl_data *data) -- cgit v1.2.3 From 243fddea35f8337016049d1bffc1599cd28330a4 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Tue, 22 Mar 2016 19:04:15 -0400 Subject: staging: lustre: libcfs: use BIT macro in linux-module.c Use the proper BIT macro for libcfs_ioctl_is_invalid(). Signed-off-by: James Simmons Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6245 Reviewed-on: http://review.whamcloud.com/17643 Reviewed-by: Bob Glossman Reviewed-by: John L. Hammond Reviewed-by: Dmitry Eremin Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/libcfs/linux/linux-module.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c index d5b7d3a210da..cf191ef26410 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c @@ -51,15 +51,15 @@ static inline int libcfs_ioctl_packlen(struct libcfs_ioctl_data *data) static inline bool libcfs_ioctl_is_invalid(struct libcfs_ioctl_data *data) { - if (data->ioc_hdr.ioc_len > (1 << 30)) { + if (data->ioc_hdr.ioc_len > BIT(30)) { CERROR("LIBCFS ioctl: ioc_len larger than 1<<30\n"); return true; } - if (data->ioc_inllen1 > (1<<30)) { + if (data->ioc_inllen1 > BIT(30)) { CERROR("LIBCFS ioctl: ioc_inllen1 larger than 1<<30\n"); return true; } - if (data->ioc_inllen2 > (1<<30)) { + if (data->ioc_inllen2 > BIT(30)) { CERROR("LIBCFS ioctl: ioc_inllen2 larger than 1<<30\n"); return true; } -- cgit v1.2.3 From c9493bd6c98d3f737341dc8eb7d4aac574934a0d Mon Sep 17 00:00:00 2001 From: James Simmons Date: Tue, 22 Mar 2016 19:04:16 -0400 Subject: staging: lustre: libcfs: return size_t for libcfs_ioctl_packlen Change return value to size_t. Signed-off-by: James Simmons Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6245 Reviewed-on: http://review.whamcloud.com/17643 Reviewed-by: Bob Glossman Reviewed-by: John L. Hammond Reviewed-by: Dmitry Eremin Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/libcfs/linux/linux-module.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c index cf191ef26410..b86e93795846 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c @@ -40,9 +40,9 @@ #define LNET_MINOR 240 -static inline int libcfs_ioctl_packlen(struct libcfs_ioctl_data *data) +static inline size_t libcfs_ioctl_packlen(struct libcfs_ioctl_data *data) { - int len = sizeof(*data); + size_t len = sizeof(*data); len += cfs_size_round(data->ioc_inllen1); len += cfs_size_round(data->ioc_inllen2); -- cgit v1.2.3 From 800aecc30b946e849f256e52dfe5c278fc32eb13 Mon Sep 17 00:00:00 2001 From: Erik Arfvidson Date: Thu, 24 Mar 2016 09:18:09 -0400 Subject: staging: unisys: remove channel.h double negative comparison This patch removes the double negative comparisons for function readb. Signed-off-by: Erik Arfvidson Signed-off-by: David Kershner Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/channel.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/unisys/include/channel.h b/drivers/staging/unisys/include/channel.h index 5af59a5fce61..b3c747b77dd0 100644 --- a/drivers/staging/unisys/include/channel.h +++ b/drivers/staging/unisys/include/channel.h @@ -411,7 +411,7 @@ spar_channel_client_acquire_os(void __iomem *ch, u8 *id) mb(); /* required for channel synch */ } if (readl(&hdr->cli_state_os) == CHANNELCLI_OWNED) { - if (readb(&hdr->cli_error_os) != 0) { + if (readb(&hdr->cli_error_os)) { /* we are in an error msg throttling state; * come out of it */ @@ -459,7 +459,7 @@ spar_channel_client_acquire_os(void __iomem *ch, u8 *id) mb(); /* required for channel synch */ return 0; } - if (readb(&hdr->cli_error_os) != 0) { + if (readb(&hdr->cli_error_os)) { /* we are in an error msg throttling state; come out of it */ pr_info("%s Channel OS client acquire now successful\n", id); writeb(0, &hdr->cli_error_os); @@ -472,7 +472,7 @@ spar_channel_client_release_os(void __iomem *ch, u8 *id) { struct channel_header __iomem *hdr = ch; - if (readb(&hdr->cli_error_os) != 0) { + if (readb(&hdr->cli_error_os)) { /* we are in an error msg throttling state; come out of it */ pr_info("%s Channel OS client error state cleared\n", id); writeb(0, &hdr->cli_error_os); -- cgit v1.2.3 From 4d12b5ee26e31b964b8918e7adde081103213b06 Mon Sep 17 00:00:00 2001 From: Erik Arfvidson Date: Thu, 24 Mar 2016 09:18:10 -0400 Subject: staging: unisys: remove visorinput.c double negative comparison This patch simply removes the double negative comparison for test_bit since test_bit already preforms this check. Signed-off-by: Erik Arfvidson Signed-off-by: David Kershner Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorinput/visorinput.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/unisys/visorinput/visorinput.c b/drivers/staging/unisys/visorinput/visorinput.c index 13c0316112ac..3299cf502aa0 100644 --- a/drivers/staging/unisys/visorinput/visorinput.c +++ b/drivers/staging/unisys/visorinput/visorinput.c @@ -470,7 +470,7 @@ handle_locking_key(struct input_dev *visorinput_dev, break; } if (led >= 0) { - int old_state = (test_bit(led, visorinput_dev->led) != 0); + int old_state = (test_bit(led, visorinput_dev->led)); if (old_state != desired_state) { input_report_key(visorinput_dev, keycode, 1); -- cgit v1.2.3 From 48f571489c0e8263b7a37dcd794ecf19b852a4df Mon Sep 17 00:00:00 2001 From: Alexander Curtin Date: Wed, 23 Mar 2016 22:15:49 -0400 Subject: staging: unisys: visorbus: replaced vague variable name in typeguid_show The variable name "s" doesn't indicate the purpose of the string, which is to store the id collected from the visorchannel_id function. This just replaces the name with "typeid". Signed-off-by: Alexander Curtin Signed-off-by: David Kershner Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorbus/visorbus_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c index 54d77dd26be0..af5add50c940 100644 --- a/drivers/staging/unisys/visorbus/visorbus_main.c +++ b/drivers/staging/unisys/visorbus/visorbus_main.c @@ -279,12 +279,12 @@ static ssize_t typeguid_show(struct device *dev, struct device_attribute *attr, char *buf) { struct visor_device *vdev = to_visor_device(dev); - char s[99]; + char typeid[99]; if (!vdev->visorchannel) return 0; return snprintf(buf, PAGE_SIZE, "%s\n", - visorchannel_id(vdev->visorchannel, s)); + visorchannel_id(vdev->visorchannel, typeid)); } static ssize_t zoneguid_show(struct device *dev, struct device_attribute *attr, -- cgit v1.2.3 From 62f3dc856736d5ddc782ee1313626ef1adfe18a9 Mon Sep 17 00:00:00 2001 From: Alexander Curtin Date: Wed, 23 Mar 2016 22:15:50 -0400 Subject: staging: unisys: visorbus: replaced vague variable name in zoneguid_show The variable name "s" doesn't indicate the purpose of the string, which is to store the id collected from the visorchannel_zoneid function. This just replaces the name with "zoneid". Signed-off-by: Alexander Curtin Signed-off-by: David Kershner Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorbus/visorbus_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c index af5add50c940..41a6d3a0d1ca 100644 --- a/drivers/staging/unisys/visorbus/visorbus_main.c +++ b/drivers/staging/unisys/visorbus/visorbus_main.c @@ -291,12 +291,12 @@ static ssize_t zoneguid_show(struct device *dev, struct device_attribute *attr, char *buf) { struct visor_device *vdev = to_visor_device(dev); - char s[99]; + char zoneid[99]; if (!vdev->visorchannel) return 0; return snprintf(buf, PAGE_SIZE, "%s\n", - visorchannel_zoneid(vdev->visorchannel, s)); + visorchannel_zoneid(vdev->visorchannel, zoneid)); } static ssize_t typename_show(struct device *dev, struct device_attribute *attr, -- cgit v1.2.3 From 8d7da1d8c2aa5564af442b4371216b4a4288cd5a Mon Sep 17 00:00:00 2001 From: Alexander Curtin Date: Wed, 23 Mar 2016 22:15:51 -0400 Subject: staging: unisys: visorbus: replaced vague 'p' variable with 'pos' In the case of client_bus_info_show, the variable 'p' was used to indicate the position in the output buffer. This was changed to 'pos' to indicate that it kept track of the current position in the output buffer. Signed-off-by: Alexander Curtin Signed-off-by: David Kershner Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorbus/visorbus_main.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c index 41a6d3a0d1ca..33407a760ab9 100644 --- a/drivers/staging/unisys/visorbus/visorbus_main.c +++ b/drivers/staging/unisys/visorbus/visorbus_main.c @@ -422,7 +422,7 @@ static ssize_t client_bus_info_show(struct device *dev, int i, x, remain = PAGE_SIZE; unsigned long off; - char *p = buf; + char *pos = buf; u8 *partition_name; struct ultra_vbus_deviceinfo dev_info; @@ -430,10 +430,10 @@ static ssize_t client_bus_info_show(struct device *dev, if (channel) { if (vdev->name) partition_name = vdev->name; - x = snprintf(p, remain, + x = snprintf(pos, remain, "Client device / client driver info for %s partition (vbus #%d):\n", partition_name, vdev->chipset_dev_no); - p += x; + pos += x; remain -= x; x = visorchannel_read(channel, offsetof(struct @@ -441,9 +441,9 @@ static ssize_t client_bus_info_show(struct device *dev, chp_info), &dev_info, sizeof(dev_info)); if (x >= 0) { - x = vbuschannel_devinfo_to_string(&dev_info, p, + x = vbuschannel_devinfo_to_string(&dev_info, pos, remain, -1); - p += x; + pos += x; remain -= x; } x = visorchannel_read(channel, @@ -452,9 +452,9 @@ static ssize_t client_bus_info_show(struct device *dev, bus_info), &dev_info, sizeof(dev_info)); if (x >= 0) { - x = vbuschannel_devinfo_to_string(&dev_info, p, + x = vbuschannel_devinfo_to_string(&dev_info, pos, remain, -1); - p += x; + pos += x; remain -= x; } off = offsetof(struct spar_vbus_channel_protocol, dev_info); @@ -465,8 +465,8 @@ static ssize_t client_bus_info_show(struct device *dev, off, &dev_info, sizeof(dev_info)); if (x >= 0) { x = vbuschannel_devinfo_to_string - (&dev_info, p, remain, i); - p += x; + (&dev_info, pos, remain, i); + pos += x; remain -= x; } off += sizeof(dev_info); -- cgit v1.2.3 From a22f57c65062a5ca6b4e7ccfbd143c3819b9045b Mon Sep 17 00:00:00 2001 From: Alexander Curtin Date: Wed, 23 Mar 2016 22:15:52 -0400 Subject: staging: unisys: visorbus: replaced use of vague 'x' variable In client_bus_info_show, the variable 'x' is used to create keep track of the offset that the current 'pos' in the output buffer needs to be incremented by. Since 'off' is already taken 'shift' was used since it's used to shift the pointer. Signed-off-by: Alexander Curtin Signed-off-by: David Kershner Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorbus/visorbus_main.c | 65 +++++++++++++------------ 1 file changed, 33 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c index 33407a760ab9..1fcb1775bb59 100644 --- a/drivers/staging/unisys/visorbus/visorbus_main.c +++ b/drivers/staging/unisys/visorbus/visorbus_main.c @@ -420,7 +420,7 @@ static ssize_t client_bus_info_show(struct device *dev, struct visor_device *vdev = to_visor_device(dev); struct visorchannel *channel = vdev->visorchannel; - int i, x, remain = PAGE_SIZE; + int i, shift, remain = PAGE_SIZE; unsigned long off; char *pos = buf; u8 *partition_name; @@ -430,44 +430,45 @@ static ssize_t client_bus_info_show(struct device *dev, if (channel) { if (vdev->name) partition_name = vdev->name; - x = snprintf(pos, remain, - "Client device / client driver info for %s partition (vbus #%d):\n", - partition_name, vdev->chipset_dev_no); - pos += x; - remain -= x; - x = visorchannel_read(channel, - offsetof(struct - spar_vbus_channel_protocol, - chp_info), - &dev_info, sizeof(dev_info)); - if (x >= 0) { - x = vbuschannel_devinfo_to_string(&dev_info, pos, - remain, -1); - pos += x; - remain -= x; + shift = snprintf(pos, remain, + "Client device / client driver info for %s eartition (vbus #%d):\n", + partition_name, vdev->chipset_dev_no); + pos += shift; + remain -= shift; + shift = visorchannel_read(channel, + offsetof(struct + spar_vbus_channel_protocol, + chp_info), + &dev_info, sizeof(dev_info)); + if (shift >= 0) { + shift = vbuschannel_devinfo_to_string(&dev_info, pos, + remain, -1); + pos += shift; + remain -= shift; } - x = visorchannel_read(channel, - offsetof(struct - spar_vbus_channel_protocol, - bus_info), - &dev_info, sizeof(dev_info)); - if (x >= 0) { - x = vbuschannel_devinfo_to_string(&dev_info, pos, - remain, -1); - pos += x; - remain -= x; + shift = visorchannel_read(channel, + offsetof(struct + spar_vbus_channel_protocol, + bus_info), + &dev_info, sizeof(dev_info)); + if (shift >= 0) { + shift = vbuschannel_devinfo_to_string(&dev_info, pos, + remain, -1); + pos += shift; + remain -= shift; } off = offsetof(struct spar_vbus_channel_protocol, dev_info); i = 0; while (off + sizeof(dev_info) <= visorchannel_get_nbytes(channel)) { - x = visorchannel_read(channel, - off, &dev_info, sizeof(dev_info)); - if (x >= 0) { - x = vbuschannel_devinfo_to_string + shift = visorchannel_read(channel, + off, &dev_info, + sizeof(dev_info)); + if (shift >= 0) { + shift = vbuschannel_devinfo_to_string (&dev_info, pos, remain, i); - pos += x; - remain -= x; + pos += shift; + remain -= shift; } off += sizeof(dev_info); i++; -- cgit v1.2.3 From 85d83cd8c629e053e3aaec0a4dd6c798d46c109d Mon Sep 17 00:00:00 2001 From: Alexander Curtin Date: Wed, 23 Mar 2016 22:15:53 -0400 Subject: staging: unisys: include: changed 'v' variable to 'state' The argument for ULTRA_CHANNELCLI_STRING is supposed to be an integer representing the channel state. 'state' is a more descriptive variable name for this. Signed-off-by: Alexander Curtin Signed-off-by: David Kershner Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/channel.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/unisys/include/channel.h b/drivers/staging/unisys/include/channel.h index b3c747b77dd0..db4e6b28755b 100644 --- a/drivers/staging/unisys/include/channel.h +++ b/drivers/staging/unisys/include/channel.h @@ -76,9 +76,9 @@ enum channel_clientstate { }; static inline const u8 * -ULTRA_CHANNELCLI_STRING(u32 v) +ULTRA_CHANNELCLI_STRING(u32 state) { - switch (v) { + switch (state) { case CHANNELCLI_DETACHED: return (const u8 *)("DETACHED"); case CHANNELCLI_DISABLED: -- cgit v1.2.3 From 04dd9a421111dfb88e1ae73af0ea27f285c89b74 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Wed, 23 Mar 2016 21:28:33 +0900 Subject: staging: wilc1000: use completion instead of struct semaphore hif_sema_thread struct semaphore hif_sema_thread is used to signal completion of host interface thread. This patch replaces struct semaphore hif_sema_thread with struct completion hif_thread_comp. It is better to use completion than semaphore for this case. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index b1ffa91dfe52..3d1797201c2c 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -231,7 +231,7 @@ bool wilc_optaining_ip; static u8 P2P_LISTEN_STATE; static struct task_struct *hif_thread_handler; static struct message_queue hif_msg_q; -static struct semaphore hif_sema_thread; +static struct completion hif_thread_comp; static struct semaphore hif_sema_driver; static struct completion hif_wait_response; static struct mutex hif_deinit_lock; @@ -2668,7 +2668,7 @@ static int hostIFthread(void *pvArg) } } - up(&hif_sema_thread); + complete(&hif_thread_comp); return 0; } @@ -3400,7 +3400,7 @@ int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) wilc_optaining_ip = false; if (clients_count == 0) { - sema_init(&hif_sema_thread, 0); + init_completion(&hif_thread_comp); sema_init(&hif_sema_driver, 0); mutex_init(&hif_deinit_lock); } @@ -3503,7 +3503,7 @@ int wilc_deinit(struct wilc_vif *vif) if (result != 0) netdev_err(vif->ndev, "deinit : Error(%d)\n", result); - down(&hif_sema_thread); + wait_for_completion(&hif_thread_comp); wilc_mq_destroy(&hif_msg_q); } -- cgit v1.2.3 From 2bb02584cd95405da72b009d0960f803d31e2302 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Wed, 23 Mar 2016 21:28:34 +0900 Subject: staging: wilc1000: use completion instead of struct semaphore hif_sema_driver struct semaphore hif_sema_driver is used to signal completion of host interface message. This patch replaces struct semaphore hif_sema_driver with struct completion hif_driver_comp. It is better to use completion than semaphore for this case. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 3d1797201c2c..29d4d8a88d12 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -232,7 +232,7 @@ static u8 P2P_LISTEN_STATE; static struct task_struct *hif_thread_handler; static struct message_queue hif_msg_q; static struct completion hif_thread_comp; -static struct semaphore hif_sema_driver; +static struct completion hif_driver_comp; static struct completion hif_wait_response; static struct mutex hif_deinit_lock; static struct timer_list periodic_rssi; @@ -321,7 +321,7 @@ static s32 handle_set_wfi_drv_handler(struct wilc_vif *vif, hif_drv_handler->handler); if (!hif_drv_handler->handler) - up(&hif_sema_driver); + complete(&hif_driver_comp); if (result) { netdev_err(vif->ndev, "Failed to set driver handler\n"); @@ -346,7 +346,7 @@ static s32 handle_set_operation_mode(struct wilc_vif *vif, wilc_get_vif_idx(vif)); if ((hif_op_mode->mode) == IDLE_MODE) - up(&hif_sema_driver); + complete(&hif_driver_comp); if (result) { netdev_err(vif->ndev, "Failed to set driver handler\n"); @@ -3401,7 +3401,7 @@ int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) if (clients_count == 0) { init_completion(&hif_thread_comp); - sema_init(&hif_sema_driver, 0); + init_completion(&hif_driver_comp); mutex_init(&hif_deinit_lock); } @@ -3480,7 +3480,7 @@ int wilc_deinit(struct wilc_vif *vif) del_timer_sync(&hif_drv->remain_on_ch_timer); wilc_set_wfi_drv_handler(vif, 0, 0); - down(&hif_sema_driver); + wait_for_completion(&hif_driver_comp); if (hif_drv->usr_scan_req.scan_result) { hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED, NULL, -- cgit v1.2.3 From 58e7003f53f32d5beb1a047fd41125d09a1a2467 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 25 Mar 2016 21:16:46 +0900 Subject: staging: wilc1000: removes WIRELESS_EXT This patch removes WIRELESS_EXT. Does not used the WIRELESS_EXT define. Signed-off-by: Leo Kim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/Kconfig | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/Kconfig b/drivers/staging/wilc1000/Kconfig index dce9cee9134a..73f7fefd3bc3 100644 --- a/drivers/staging/wilc1000/Kconfig +++ b/drivers/staging/wilc1000/Kconfig @@ -1,6 +1,5 @@ config WILC1000 tristate - select WIRELESS_EXT ---help--- This module only support IEEE 802.11n WiFi. -- cgit v1.2.3 From 6d11c5517f544b50827e4ee720fad512ac28e14a Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 25 Mar 2016 21:16:47 +0900 Subject: staging: wilc1000: wilc_frame_register: removes unused hif_drv This patch removes unused hif_drv of wilc_frame_register function. It's perform an unnecessary null check and debug print log. Signed-off-by: Leo Kim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/host_interface.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 29d4d8a88d12..04cbff50a0f1 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -3689,12 +3689,6 @@ int wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg) { int result = 0; struct host_if_msg msg; - struct host_if_drv *hif_drv = vif->hif_drv; - - if (!hif_drv) { - netdev_err(vif->ndev, "driver is null\n"); - return -EFAULT; - } memset(&msg, 0, sizeof(struct host_if_msg)); -- cgit v1.2.3 From c92a869e6170c06219ca550a0e87fbefaa92a30b Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 25 Mar 2016 21:16:48 +0900 Subject: staging: wilc1000: removes typedef of struct struct_frame_reg This patch removes typedef of struct struct_frame_reg. Renames the struct_frame_reg to frame_reg as well. Signed-off-by: Leo Kim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wfi_netdevice.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index 4123cffe3a6e..f394484a1ceb 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -139,18 +139,17 @@ struct wilc_priv { }; -typedef struct { +struct frame_reg { u16 frame_type; bool reg; - -} struct_frame_reg; +}; struct wilc_vif { u8 idx; u8 iftype; int monitor_flag; int mac_opened; - struct_frame_reg g_struct_frame_reg[num_reg_frame]; + struct frame_reg g_struct_frame_reg[num_reg_frame]; struct net_device_stats netstats; struct wilc *wilc; u8 src_addr[ETH_ALEN]; -- cgit v1.2.3 From 89febb21c4ca25030c75ba5a7cb64fe02c2cb156 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 25 Mar 2016 21:16:49 +0900 Subject: staging: wilc1000: replaces g_struct_frame_reg with frame_reg This patch replaces g_struct_frame_reg with frame_reg. Signed-off-by: Leo Kim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 12 ++++++------ drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 8 ++++---- drivers/staging/wilc1000/wilc_wfi_netdevice.h | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index e949f218885c..2f830cd3163b 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -966,12 +966,12 @@ int wilc_mac_open(struct net_device *ndev) wilc_mgmt_frame_register(vif->ndev->ieee80211_ptr->wiphy, vif->ndev->ieee80211_ptr, - vif->g_struct_frame_reg[0].frame_type, - vif->g_struct_frame_reg[0].reg); + vif->frame_reg[0].frame_type, + vif->frame_reg[0].reg); wilc_mgmt_frame_register(vif->ndev->ieee80211_ptr->wiphy, vif->ndev->ieee80211_ptr, - vif->g_struct_frame_reg[1].frame_type, - vif->g_struct_frame_reg[1].reg); + vif->frame_reg[1].frame_type, + vif->frame_reg[1].reg); netif_wake_queue(ndev); wl->open_ifcs++; vif->mac_opened = 1; @@ -1260,8 +1260,8 @@ void WILC_WFI_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size) } vif = netdev_priv(wilc->vif[1]->ndev); - if ((buff[0] == vif->g_struct_frame_reg[0].frame_type && vif->g_struct_frame_reg[0].reg) || - (buff[0] == vif->g_struct_frame_reg[1].frame_type && vif->g_struct_frame_reg[1].reg)) + if ((buff[0] == vif->frame_reg[0].frame_type && vif->frame_reg[0].reg) || + (buff[0] == vif->frame_reg[1].frame_type && vif->frame_reg[1].reg)) WILC_WFI_p2p_rx(wilc->vif[1]->ndev, buff, size); } diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 70625f8a2e3c..3e0ffee89416 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -1745,15 +1745,15 @@ void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, switch (frame_type) { case PROBE_REQ: { - vif->g_struct_frame_reg[0].frame_type = frame_type; - vif->g_struct_frame_reg[0].reg = reg; + vif->frame_reg[0].frame_type = frame_type; + vif->frame_reg[0].reg = reg; } break; case ACTION: { - vif->g_struct_frame_reg[1].frame_type = frame_type; - vif->g_struct_frame_reg[1].reg = reg; + vif->frame_reg[1].frame_type = frame_type; + vif->frame_reg[1].reg = reg; } break; diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index f394484a1ceb..3abe48188d3d 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -149,7 +149,7 @@ struct wilc_vif { u8 iftype; int monitor_flag; int mac_opened; - struct frame_reg g_struct_frame_reg[num_reg_frame]; + struct frame_reg frame_reg[num_reg_frame]; struct net_device_stats netstats; struct wilc *wilc; u8 src_addr[ETH_ALEN]; -- cgit v1.2.3 From 340a84ff96c4d9effbc841a085e2101c3977e5cf Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 25 Mar 2016 21:16:50 +0900 Subject: staging: wilc1000: replaces frame_type with type of struct frame_reg This patch replaces frame_type with type of struct frame_reg. Signed-off-by: Leo Kim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 8 ++++---- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 4 ++-- drivers/staging/wilc1000/wilc_wfi_netdevice.h | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 2f830cd3163b..760d44d17056 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -966,11 +966,11 @@ int wilc_mac_open(struct net_device *ndev) wilc_mgmt_frame_register(vif->ndev->ieee80211_ptr->wiphy, vif->ndev->ieee80211_ptr, - vif->frame_reg[0].frame_type, + vif->frame_reg[0].type, vif->frame_reg[0].reg); wilc_mgmt_frame_register(vif->ndev->ieee80211_ptr->wiphy, vif->ndev->ieee80211_ptr, - vif->frame_reg[1].frame_type, + vif->frame_reg[1].type, vif->frame_reg[1].reg); netif_wake_queue(ndev); wl->open_ifcs++; @@ -1260,8 +1260,8 @@ void WILC_WFI_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size) } vif = netdev_priv(wilc->vif[1]->ndev); - if ((buff[0] == vif->frame_reg[0].frame_type && vif->frame_reg[0].reg) || - (buff[0] == vif->frame_reg[1].frame_type && vif->frame_reg[1].reg)) + if ((buff[0] == vif->frame_reg[0].type && vif->frame_reg[0].reg) || + (buff[0] == vif->frame_reg[1].type && vif->frame_reg[1].reg)) WILC_WFI_p2p_rx(wilc->vif[1]->ndev, buff, size); } diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 3e0ffee89416..5785dda8f9d3 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -1745,14 +1745,14 @@ void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, switch (frame_type) { case PROBE_REQ: { - vif->frame_reg[0].frame_type = frame_type; + vif->frame_reg[0].type = frame_type; vif->frame_reg[0].reg = reg; } break; case ACTION: { - vif->frame_reg[1].frame_type = frame_type; + vif->frame_reg[1].type = frame_type; vif->frame_reg[1].reg = reg; } break; diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index 3abe48188d3d..debb139b7687 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -140,7 +140,7 @@ struct wilc_priv { }; struct frame_reg { - u16 frame_type; + u16 type; bool reg; }; -- cgit v1.2.3 From 5510730d5f95a37e9de29597e8e7328103bbaf60 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 25 Mar 2016 21:16:51 +0900 Subject: staging: wilc1000: removes unused dead codes This patch removes unused dead codes that define custom feature. Signed-off-by: Leo Kim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 760d44d17056..db624ef31e69 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -691,14 +691,6 @@ void wilc1000_wlan_deinit(struct net_device *dev) wilc_wlan_stop(wl); wilc_wlan_cleanup(dev); -#if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31) - if (!wl->dev_irq_num && - wl->hif_func->disable_interrupt) { - mutex_lock(&wl->hif_cs); - wl->hif_func->disable_interrupt(wl); - mutex_unlock(&wl->hif_cs); - } -#endif wlan_deinit_locks(dev); wl->initialized = false; -- cgit v1.2.3 From e944ad751ff4fbbd0278ba4dd8595bf7fa3c7e9e Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 25 Mar 2016 21:16:52 +0900 Subject: staging: wilc1000: removes unused debug flags This patch removes unused debug flags. Signed-off-by: Leo Kim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan_if.h | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h b/drivers/staging/wilc1000/wilc_wlan_if.h index 83cf84dd63b5..119b31348a1b 100644 --- a/drivers/staging/wilc1000/wilc_wlan_if.h +++ b/drivers/staging/wilc1000/wilc_wlan_if.h @@ -13,18 +13,6 @@ #include #include -/******************************************** - * - * Debug Flags - * - ********************************************/ - -#define N_INIT 0x00000001 -#define N_ERR 0x00000002 -#define N_TXQ 0x00000004 -#define N_INTR 0x00000008 -#define N_RXQ 0x00000010 - /******************************************** * * Host Interface Defines -- cgit v1.2.3 From fa63394152e9675c6d9ce32e57fbe00094efb4b8 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 25 Mar 2016 21:16:53 +0900 Subject: staging: wilc1000: replaces memcmp with ether_addr_equal_unaligned This patch replaces memcmp with ether_addr_equal_unaligned. Warning reported by checkpatch.pl - Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp() Signed-off-by: Leo Kim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index db624ef31e69..8f0a74d3ff86 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -259,10 +259,12 @@ static struct net_device *get_if_handler(struct wilc *wilc, u8 *mac_header) for (i = 0; i < wilc->vif_num; i++) { if (wilc->vif[i]->mode == STATION_MODE) - if (!memcmp(bssid, wilc->vif[i]->bssid, ETH_ALEN)) + if (ether_addr_equal_unaligned(bssid, + wilc->vif[i]->bssid)) return wilc->vif[i]->ndev; if (wilc->vif[i]->mode == AP_MODE) - if (!memcmp(bssid1, wilc->vif[i]->bssid, ETH_ALEN)) + if (ether_addr_equal_unaligned(bssid1, + wilc->vif[i]->bssid)) return wilc->vif[i]->ndev; } -- cgit v1.2.3 From 7632d9b1a073834df3f3b1d59b9159d9fe5b5419 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 25 Mar 2016 21:16:54 +0900 Subject: staging: wilc1000: removes unused define This patch removes unused define. Signed-off-by: Leo Kim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 2 -- drivers/staging/wilc1000/wilc_wlan_if.h | 9 --------- 2 files changed, 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 8f0a74d3ff86..127a9679cdae 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -30,8 +30,6 @@ static struct notifier_block g_dev_notifier = { .notifier_call = dev_state_ev_handler }; -#define IRQ_WAIT 1 -#define IRQ_NO_WAIT 0 static struct semaphore close_exit_sync; static int wlan_deinit_locks(struct net_device *dev); diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h b/drivers/staging/wilc1000/wilc_wlan_if.h index 119b31348a1b..410bfc034319 100644 --- a/drivers/staging/wilc1000/wilc_wlan_if.h +++ b/drivers/staging/wilc1000/wilc_wlan_if.h @@ -23,15 +23,6 @@ #define HIF_SPI BIT(0) #define HIF_SDIO_GPIO_IRQ BIT(2) -/******************************************** - * - * Tx/Rx Buffer Size Defines - * - ********************************************/ - -#define CE_TX_BUFFER_SIZE (64 * 1024) -#define CE_RX_BUFFER_SIZE (384 * 1024) - /******************************************** * * Wlan Interface Defines -- cgit v1.2.3 From 847109fc0f4e5f703107492684de1943069f4530 Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 25 Mar 2016 21:16:55 +0900 Subject: staging: wilc1000: removes define USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS This patch removes define USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS and use it's feature codes. Signed-off-by: Leo Kim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 127a9679cdae..fae03e8cda6f 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -303,22 +303,18 @@ int wilc_wlan_get_num_conn_ifcs(struct wilc *wilc) return ret_val; } -#define USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS - static int linux_wlan_txq_task(void *vp) { int ret, txq_count; struct wilc_vif *vif; struct wilc *wl; struct net_device *dev = vp; -#if defined USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS #define TX_BACKOFF_WEIGHT_INCR_STEP (1) #define TX_BACKOFF_WEIGHT_DECR_STEP (1) #define TX_BACKOFF_WEIGHT_MAX (7) #define TX_BACKOFF_WEIGHT_MIN (0) #define TX_BACKOFF_WEIGHT_UNIT_MS (10) int backoff_weight = TX_BACKOFF_WEIGHT_MIN; -#endif vif = netdev_priv(dev); wl = vif->wilc; @@ -334,9 +330,6 @@ static int linux_wlan_txq_task(void *vp) schedule(); break; } -#if !defined USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS - ret = wilc_wlan_handle_txq(dev, &txq_count); -#else do { ret = wilc_wlan_handle_txq(dev, &txq_count); if (txq_count < FLOW_CONTROL_LOWER_THRESHOLD) { @@ -358,7 +351,6 @@ static int linux_wlan_txq_task(void *vp) } } } while (ret == WILC_TX_ERR_NO_BUF && !wl->close); -#endif } return 0; } -- cgit v1.2.3 From 8dc5fb4e0eb8802ff0615b0fde92f43f3bd5d56d Mon Sep 17 00:00:00 2001 From: Leo Kim Date: Fri, 25 Mar 2016 21:16:56 +0900 Subject: staging: wilc1000: removes unused local variable This patch removes unused local variable. This variable is operation definition that back off from sending packets for some time. However, that has been deleted operation code. That is removes all relative code. Signed-off-by: Leo Kim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/linux_wlan.c | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index fae03e8cda6f..a858552737b6 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -309,12 +309,6 @@ static int linux_wlan_txq_task(void *vp) struct wilc_vif *vif; struct wilc *wl; struct net_device *dev = vp; -#define TX_BACKOFF_WEIGHT_INCR_STEP (1) -#define TX_BACKOFF_WEIGHT_DECR_STEP (1) -#define TX_BACKOFF_WEIGHT_MAX (7) -#define TX_BACKOFF_WEIGHT_MIN (0) -#define TX_BACKOFF_WEIGHT_UNIT_MS (10) - int backoff_weight = TX_BACKOFF_WEIGHT_MIN; vif = netdev_priv(dev); wl = vif->wilc; @@ -338,18 +332,6 @@ static int linux_wlan_txq_task(void *vp) if (netif_queue_stopped(wl->vif[1]->ndev)) netif_wake_queue(wl->vif[1]->ndev); } - - if (ret == WILC_TX_ERR_NO_BUF) { - backoff_weight += TX_BACKOFF_WEIGHT_INCR_STEP; - if (backoff_weight > TX_BACKOFF_WEIGHT_MAX) - backoff_weight = TX_BACKOFF_WEIGHT_MAX; - } else { - if (backoff_weight > TX_BACKOFF_WEIGHT_MIN) { - backoff_weight -= TX_BACKOFF_WEIGHT_DECR_STEP; - if (backoff_weight < TX_BACKOFF_WEIGHT_MIN) - backoff_weight = TX_BACKOFF_WEIGHT_MIN; - } - } } while (ret == WILC_TX_ERR_NO_BUF && !wl->close); } return 0; -- cgit v1.2.3 From 22acd860137ad6952fec8f6041efa9a30e49c22d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:11 -0700 Subject: staging: comedi: ni_660x: change IOConfigReg() into a macro The BUG_ON() in this function is unnecessary. The 'pfi_channel' will always be in range of the subdevice 'n_chan' (NUM_PFI_CHANNELS) which will return a valid 'reg'. Convert the inline function into a simple macro. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 46647c64f369..10db2fff899e 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -156,13 +156,7 @@ enum ni_660x_register { NI660X_NUM_REGS, }; -static inline unsigned IOConfigReg(unsigned pfi_channel) -{ - unsigned reg = NI660X_IO_CFG_0_1 + pfi_channel / 2; - - BUG_ON(reg > NI660X_IO_CFG_38_39); - return reg; -} +#define NI660X_IO_CFG(x) (NI660X_IO_CFG_0_1 + ((x) / 2)) enum ni_660x_register_width { DATA_1B, @@ -893,7 +887,7 @@ static void init_tio_chip(struct comedi_device *dev, int chipset) devpriv->dma_configuration_soft_copies[chipset], NI660X_DMA_CFG); for (i = 0; i < NUM_PFI_CHANNELS; ++i) - ni_660x_write_register(dev, chipset, 0, IOConfigReg(i)); + ni_660x_write_register(dev, chipset, 0, NI660X_IO_CFG(i)); } static int ni_660x_dio_insn_bits(struct comedi_device *dev, @@ -944,22 +938,22 @@ static void ni_660x_select_pfi_output(struct comedi_device *dev, if (idle_chipset != active_chipset) { idle_bits = ni_660x_read_register(dev, idle_chipset, - IOConfigReg(pfi_channel)); + NI660X_IO_CFG(pfi_channel)); idle_bits &= ~pfi_output_select_mask(pfi_channel); idle_bits |= pfi_output_select_bits(pfi_channel, pfi_output_select_high_Z); ni_660x_write_register(dev, idle_chipset, idle_bits, - IOConfigReg(pfi_channel)); + NI660X_IO_CFG(pfi_channel)); } active_bits = ni_660x_read_register(dev, active_chipset, - IOConfigReg(pfi_channel)); + NI660X_IO_CFG(pfi_channel)); active_bits &= ~pfi_output_select_mask(pfi_channel); active_bits |= pfi_output_select_bits(pfi_channel, output_select); ni_660x_write_register(dev, active_chipset, active_bits, - IOConfigReg(pfi_channel)); + NI660X_IO_CFG(pfi_channel)); } static int ni_660x_set_pfi_routing(struct comedi_device *dev, unsigned chan, @@ -1025,10 +1019,10 @@ static int ni_660x_dio_insn_config(struct comedi_device *dev, break; case INSN_CONFIG_FILTER: - val = ni_660x_read_register(dev, 0, IOConfigReg(chan)); + val = ni_660x_read_register(dev, 0, NI660X_IO_CFG(chan)); val &= ~pfi_input_select_mask(chan); val |= pfi_input_select_bits(chan, data[1]); - ni_660x_write_register(dev, 0, val, IOConfigReg(chan)); + ni_660x_write_register(dev, 0, val, NI660X_IO_CFG(chan)); break; default: -- cgit v1.2.3 From f9565977bf488bd4bf9ef7322728970c20bbc908 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:12 -0700 Subject: staging: comedi: ni_660x: remove struct NI_660xRegisterData 'name' This member of the struct is not used, and just takes up space. Remove it. Instead, add the enum ni_660x_register indexes to the table to clarify, and document, the entries. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 197 +++++++++++++++---------------- 1 file changed, 98 insertions(+), 99 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 10db2fff899e..10bb8394fd99 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -187,111 +187,110 @@ static inline unsigned NI_660X_GPCT_SUBDEV(unsigned index) } struct NI_660xRegisterData { - const char *name; /* Register Name */ int offset; /* Offset from base address from GPCT chip */ enum ni_660x_register_direction direction; enum ni_660x_register_width size; /* 1 byte, 2 bytes, or 4 bytes */ }; static const struct NI_660xRegisterData registerData[NI660X_NUM_REGS] = { - {"G0 Interrupt Acknowledge", 0x004, NI_660x_WRITE, DATA_2B}, - {"G0 Status Register", 0x004, NI_660x_READ, DATA_2B}, - {"G1 Interrupt Acknowledge", 0x006, NI_660x_WRITE, DATA_2B}, - {"G1 Status Register", 0x006, NI_660x_READ, DATA_2B}, - {"G01 Status Register ", 0x008, NI_660x_READ, DATA_2B}, - {"G0 Command Register", 0x00C, NI_660x_WRITE, DATA_2B}, - {"STC DIO Parallel Input", 0x00E, NI_660x_READ, DATA_2B}, - {"G1 Command Register", 0x00E, NI_660x_WRITE, DATA_2B}, - {"G0 HW Save Register", 0x010, NI_660x_READ, DATA_4B}, - {"G1 HW Save Register", 0x014, NI_660x_READ, DATA_4B}, - {"STC DIO Output", 0x014, NI_660x_WRITE, DATA_2B}, - {"STC DIO Control", 0x016, NI_660x_WRITE, DATA_2B}, - {"G0 SW Save Register", 0x018, NI_660x_READ, DATA_4B}, - {"G1 SW Save Register", 0x01C, NI_660x_READ, DATA_4B}, - {"G0 Mode Register", 0x034, NI_660x_WRITE, DATA_2B}, - {"G01 Joint Status 1 Register", 0x036, NI_660x_READ, DATA_2B}, - {"G1 Mode Register", 0x036, NI_660x_WRITE, DATA_2B}, - {"STC DIO Serial Input", 0x038, NI_660x_READ, DATA_2B}, - {"G0 Load A Register", 0x038, NI_660x_WRITE, DATA_4B}, - {"G01 Joint Status 2 Register", 0x03A, NI_660x_READ, DATA_2B}, - {"G0 Load B Register", 0x03C, NI_660x_WRITE, DATA_4B}, - {"G1 Load A Register", 0x040, NI_660x_WRITE, DATA_4B}, - {"G1 Load B Register", 0x044, NI_660x_WRITE, DATA_4B}, - {"G0 Input Select Register", 0x048, NI_660x_WRITE, DATA_2B}, - {"G1 Input Select Register", 0x04A, NI_660x_WRITE, DATA_2B}, - {"G0 Autoincrement Register", 0x088, NI_660x_WRITE, DATA_2B}, - {"G1 Autoincrement Register", 0x08A, NI_660x_WRITE, DATA_2B}, - {"G01 Joint Reset Register", 0x090, NI_660x_WRITE, DATA_2B}, - {"G0 Interrupt Enable", 0x092, NI_660x_WRITE, DATA_2B}, - {"G1 Interrupt Enable", 0x096, NI_660x_WRITE, DATA_2B}, - {"G0 Counting Mode Register", 0x0B0, NI_660x_WRITE, DATA_2B}, - {"G1 Counting Mode Register", 0x0B2, NI_660x_WRITE, DATA_2B}, - {"G0 Second Gate Register", 0x0B4, NI_660x_WRITE, DATA_2B}, - {"G1 Second Gate Register", 0x0B6, NI_660x_WRITE, DATA_2B}, - {"G0 DMA Config Register", 0x0B8, NI_660x_WRITE, DATA_2B}, - {"G0 DMA Status Register", 0x0B8, NI_660x_READ, DATA_2B}, - {"G1 DMA Config Register", 0x0BA, NI_660x_WRITE, DATA_2B}, - {"G1 DMA Status Register", 0x0BA, NI_660x_READ, DATA_2B}, - {"G2 Interrupt Acknowledge", 0x104, NI_660x_WRITE, DATA_2B}, - {"G2 Status Register", 0x104, NI_660x_READ, DATA_2B}, - {"G3 Interrupt Acknowledge", 0x106, NI_660x_WRITE, DATA_2B}, - {"G3 Status Register", 0x106, NI_660x_READ, DATA_2B}, - {"G23 Status Register", 0x108, NI_660x_READ, DATA_2B}, - {"G2 Command Register", 0x10C, NI_660x_WRITE, DATA_2B}, - {"G3 Command Register", 0x10E, NI_660x_WRITE, DATA_2B}, - {"G2 HW Save Register", 0x110, NI_660x_READ, DATA_4B}, - {"G3 HW Save Register", 0x114, NI_660x_READ, DATA_4B}, - {"G2 SW Save Register", 0x118, NI_660x_READ, DATA_4B}, - {"G3 SW Save Register", 0x11C, NI_660x_READ, DATA_4B}, - {"G2 Mode Register", 0x134, NI_660x_WRITE, DATA_2B}, - {"G23 Joint Status 1 Register", 0x136, NI_660x_READ, DATA_2B}, - {"G3 Mode Register", 0x136, NI_660x_WRITE, DATA_2B}, - {"G2 Load A Register", 0x138, NI_660x_WRITE, DATA_4B}, - {"G23 Joint Status 2 Register", 0x13A, NI_660x_READ, DATA_2B}, - {"G2 Load B Register", 0x13C, NI_660x_WRITE, DATA_4B}, - {"G3 Load A Register", 0x140, NI_660x_WRITE, DATA_4B}, - {"G3 Load B Register", 0x144, NI_660x_WRITE, DATA_4B}, - {"G2 Input Select Register", 0x148, NI_660x_WRITE, DATA_2B}, - {"G3 Input Select Register", 0x14A, NI_660x_WRITE, DATA_2B}, - {"G2 Autoincrement Register", 0x188, NI_660x_WRITE, DATA_2B}, - {"G3 Autoincrement Register", 0x18A, NI_660x_WRITE, DATA_2B}, - {"G23 Joint Reset Register", 0x190, NI_660x_WRITE, DATA_2B}, - {"G2 Interrupt Enable", 0x192, NI_660x_WRITE, DATA_2B}, - {"G3 Interrupt Enable", 0x196, NI_660x_WRITE, DATA_2B}, - {"G2 Counting Mode Register", 0x1B0, NI_660x_WRITE, DATA_2B}, - {"G3 Counting Mode Register", 0x1B2, NI_660x_WRITE, DATA_2B}, - {"G3 Second Gate Register", 0x1B6, NI_660x_WRITE, DATA_2B}, - {"G2 Second Gate Register", 0x1B4, NI_660x_WRITE, DATA_2B}, - {"G2 DMA Config Register", 0x1B8, NI_660x_WRITE, DATA_2B}, - {"G2 DMA Status Register", 0x1B8, NI_660x_READ, DATA_2B}, - {"G3 DMA Config Register", 0x1BA, NI_660x_WRITE, DATA_2B}, - {"G3 DMA Status Register", 0x1BA, NI_660x_READ, DATA_2B}, - {"32 bit Digital Input", 0x414, NI_660x_READ, DATA_4B}, - {"32 bit Digital Output", 0x510, NI_660x_WRITE, DATA_4B}, - {"Clock Config Register", 0x73C, NI_660x_WRITE, DATA_4B}, - {"Global Interrupt Status Register", 0x754, NI_660x_READ, DATA_4B}, - {"DMA Configuration Register", 0x76C, NI_660x_WRITE, DATA_4B}, - {"Global Interrupt Config Register", 0x770, NI_660x_WRITE, DATA_4B}, - {"IO Config Register 0-1", 0x77C, NI_660x_READ_WRITE, DATA_2B}, - {"IO Config Register 2-3", 0x77E, NI_660x_READ_WRITE, DATA_2B}, - {"IO Config Register 4-5", 0x780, NI_660x_READ_WRITE, DATA_2B}, - {"IO Config Register 6-7", 0x782, NI_660x_READ_WRITE, DATA_2B}, - {"IO Config Register 8-9", 0x784, NI_660x_READ_WRITE, DATA_2B}, - {"IO Config Register 10-11", 0x786, NI_660x_READ_WRITE, DATA_2B}, - {"IO Config Register 12-13", 0x788, NI_660x_READ_WRITE, DATA_2B}, - {"IO Config Register 14-15", 0x78A, NI_660x_READ_WRITE, DATA_2B}, - {"IO Config Register 16-17", 0x78C, NI_660x_READ_WRITE, DATA_2B}, - {"IO Config Register 18-19", 0x78E, NI_660x_READ_WRITE, DATA_2B}, - {"IO Config Register 20-21", 0x790, NI_660x_READ_WRITE, DATA_2B}, - {"IO Config Register 22-23", 0x792, NI_660x_READ_WRITE, DATA_2B}, - {"IO Config Register 24-25", 0x794, NI_660x_READ_WRITE, DATA_2B}, - {"IO Config Register 26-27", 0x796, NI_660x_READ_WRITE, DATA_2B}, - {"IO Config Register 28-29", 0x798, NI_660x_READ_WRITE, DATA_2B}, - {"IO Config Register 30-31", 0x79A, NI_660x_READ_WRITE, DATA_2B}, - {"IO Config Register 32-33", 0x79C, NI_660x_READ_WRITE, DATA_2B}, - {"IO Config Register 34-35", 0x79E, NI_660x_READ_WRITE, DATA_2B}, - {"IO Config Register 36-37", 0x7A0, NI_660x_READ_WRITE, DATA_2B}, - {"IO Config Register 38-39", 0x7A2, NI_660x_READ_WRITE, DATA_2B} + [NI660X_G0_INT_ACK] = {0x004, NI_660x_WRITE, DATA_2B}, + [NI660X_G0_STATUS] = {0x004, NI_660x_READ, DATA_2B}, + [NI660X_G1_INT_ACK] = {0x006, NI_660x_WRITE, DATA_2B}, + [NI660X_G1_STATUS] = {0x006, NI_660x_READ, DATA_2B}, + [NI660X_G01_STATUS] = {0x008, NI_660x_READ, DATA_2B}, + [NI660X_G0_CMD] = {0x00c, NI_660x_WRITE, DATA_2B}, + [NI660X_STC_DIO_PARALLEL_INPUT] = {0x00e, NI_660x_READ, DATA_2B}, + [NI660X_G1_CMD] = {0x00e, NI_660x_WRITE, DATA_2B}, + [NI660X_G0_HW_SAVE] = {0x010, NI_660x_READ, DATA_4B}, + [NI660X_G1_HW_SAVE] = {0x014, NI_660x_READ, DATA_4B}, + [NI660X_STC_DIO_OUTPUT] = {0x014, NI_660x_WRITE, DATA_2B}, + [NI660X_STC_DIO_CONTROL] = {0x016, NI_660x_WRITE, DATA_2B}, + [NI660X_G0_SW_SAVE] = {0x018, NI_660x_READ, DATA_4B}, + [NI660X_G1_SW_SAVE] = {0x01c, NI_660x_READ, DATA_4B}, + [NI660X_G0_MODE] = {0x034, NI_660x_WRITE, DATA_2B}, + [NI660X_G01_STATUS1] = {0x036, NI_660x_READ, DATA_2B}, + [NI660X_G1_MODE] = {0x036, NI_660x_WRITE, DATA_2B}, + [NI660X_STC_DIO_SERIAL_INPUT] = {0x038, NI_660x_READ, DATA_2B}, + [NI660X_G0_LOADA] = {0x038, NI_660x_WRITE, DATA_4B}, + [NI660X_G01_STATUS2] = {0x03a, NI_660x_READ, DATA_2B}, + [NI660X_G0_LOADB] = {0x03c, NI_660x_WRITE, DATA_4B}, + [NI660X_G1_LOADA] = {0x040, NI_660x_WRITE, DATA_4B}, + [NI660X_G1_LOADB] = {0x044, NI_660x_WRITE, DATA_4B}, + [NI660X_G0_INPUT_SEL] = {0x048, NI_660x_WRITE, DATA_2B}, + [NI660X_G1_INPUT_SEL] = {0x04a, NI_660x_WRITE, DATA_2B}, + [NI660X_G0_AUTO_INC] = {0x088, NI_660x_WRITE, DATA_2B}, + [NI660X_G1_AUTO_INC] = {0x08a, NI_660x_WRITE, DATA_2B}, + [NI660X_G01_RESET] = {0x090, NI_660x_WRITE, DATA_2B}, + [NI660X_G0_INT_ENA] = {0x092, NI_660x_WRITE, DATA_2B}, + [NI660X_G1_INT_ENA] = {0x096, NI_660x_WRITE, DATA_2B}, + [NI660X_G0_CNT_MODE] = {0x0b0, NI_660x_WRITE, DATA_2B}, + [NI660X_G1_CNT_MODE] = {0x0b2, NI_660x_WRITE, DATA_2B}, + [NI660X_G0_GATE2] = {0x0b4, NI_660x_WRITE, DATA_2B}, + [NI660X_G1_GATE2] = {0x0b6, NI_660x_WRITE, DATA_2B}, + [NI660X_G0_DMA_CFG] = {0x0b8, NI_660x_WRITE, DATA_2B}, + [NI660X_G0_DMA_STATUS] = {0x0b8, NI_660x_READ, DATA_2B}, + [NI660X_G1_DMA_CFG] = {0x0ba, NI_660x_WRITE, DATA_2B}, + [NI660X_G1_DMA_STATUS] = {0x0ba, NI_660x_READ, DATA_2B}, + [NI660X_G2_INT_ACK] = {0x104, NI_660x_WRITE, DATA_2B}, + [NI660X_G2_STATUS] = {0x104, NI_660x_READ, DATA_2B}, + [NI660X_G3_INT_ACK] = {0x106, NI_660x_WRITE, DATA_2B}, + [NI660X_G3_STATUS] = {0x106, NI_660x_READ, DATA_2B}, + [NI660X_G23_STATUS] = {0x108, NI_660x_READ, DATA_2B}, + [NI660X_G2_CMD] = {0x10c, NI_660x_WRITE, DATA_2B}, + [NI660X_G3_CMD] = {0x10e, NI_660x_WRITE, DATA_2B}, + [NI660X_G2_HW_SAVE] = {0x110, NI_660x_READ, DATA_4B}, + [NI660X_G3_HW_SAVE] = {0x114, NI_660x_READ, DATA_4B}, + [NI660X_G2_SW_SAVE] = {0x118, NI_660x_READ, DATA_4B}, + [NI660X_G3_SW_SAVE] = {0x11c, NI_660x_READ, DATA_4B}, + [NI660X_G2_MODE] = {0x134, NI_660x_WRITE, DATA_2B}, + [NI660X_G23_STATUS1] = {0x136, NI_660x_READ, DATA_2B}, + [NI660X_G3_MODE] = {0x136, NI_660x_WRITE, DATA_2B}, + [NI660X_G2_LOADA] = {0x138, NI_660x_WRITE, DATA_4B}, + [NI660X_G23_STATUS2] = {0x13a, NI_660x_READ, DATA_2B}, + [NI660X_G2_LOADB] = {0x13c, NI_660x_WRITE, DATA_4B}, + [NI660X_G3_LOADA] = {0x140, NI_660x_WRITE, DATA_4B}, + [NI660X_G3_LOADB] = {0x144, NI_660x_WRITE, DATA_4B}, + [NI660X_G2_INPUT_SEL] = {0x148, NI_660x_WRITE, DATA_2B}, + [NI660X_G3_INPUT_SEL] = {0x14a, NI_660x_WRITE, DATA_2B}, + [NI660X_G2_AUTO_INC] = {0x188, NI_660x_WRITE, DATA_2B}, + [NI660X_G3_AUTO_INC] = {0x18a, NI_660x_WRITE, DATA_2B}, + [NI660X_G23_RESET] = {0x190, NI_660x_WRITE, DATA_2B}, + [NI660X_G2_INT_ENA] = {0x192, NI_660x_WRITE, DATA_2B}, + [NI660X_G3_INT_ENA] = {0x196, NI_660x_WRITE, DATA_2B}, + [NI660X_G2_CNT_MODE] = {0x1b0, NI_660x_WRITE, DATA_2B}, + [NI660X_G3_CNT_MODE] = {0x1b2, NI_660x_WRITE, DATA_2B}, + [NI660X_G3_GATE2] = {0x1b6, NI_660x_WRITE, DATA_2B}, + [NI660X_G2_GATE2] = {0x1b4, NI_660x_WRITE, DATA_2B}, + [NI660X_G2_DMA_CFG] = {0x1b8, NI_660x_WRITE, DATA_2B}, + [NI660X_G2_DMA_STATUS] = {0x1b8, NI_660x_READ, DATA_2B}, + [NI660X_G3_DMA_CFG] = {0x1ba, NI_660x_WRITE, DATA_2B}, + [NI660X_G3_DMA_STATUS] = {0x1ba, NI_660x_READ, DATA_2B}, + [NI660X_DIO32_INPUT] = {0x414, NI_660x_READ, DATA_4B}, + [NI660X_DIO32_OUTPUT] = {0x510, NI_660x_WRITE, DATA_4B}, + [NI660X_CLK_CFG] = {0x73c, NI_660x_WRITE, DATA_4B}, + [NI660X_GLOBAL_INT_STATUS] = {0x754, NI_660x_READ, DATA_4B}, + [NI660X_DMA_CFG] = {0x76c, NI_660x_WRITE, DATA_4B}, + [NI660X_GLOBAL_INT_CFG] = {0x770, NI_660x_WRITE, DATA_4B}, + [NI660X_IO_CFG_0_1] = {0x77c, NI_660x_READ_WRITE, DATA_2B}, + [NI660X_IO_CFG_2_3] = {0x77e, NI_660x_READ_WRITE, DATA_2B}, + [NI660X_IO_CFG_4_5] = {0x780, NI_660x_READ_WRITE, DATA_2B}, + [NI660X_IO_CFG_6_7] = {0x782, NI_660x_READ_WRITE, DATA_2B}, + [NI660X_IO_CFG_8_9] = {0x784, NI_660x_READ_WRITE, DATA_2B}, + [NI660X_IO_CFG_10_11] = {0x786, NI_660x_READ_WRITE, DATA_2B}, + [NI660X_IO_CFG_12_13] = {0x788, NI_660x_READ_WRITE, DATA_2B}, + [NI660X_IO_CFG_14_15] = {0x78a, NI_660x_READ_WRITE, DATA_2B}, + [NI660X_IO_CFG_16_17] = {0x78c, NI_660x_READ_WRITE, DATA_2B}, + [NI660X_IO_CFG_18_19] = {0x78e, NI_660x_READ_WRITE, DATA_2B}, + [NI660X_IO_CFG_20_21] = {0x790, NI_660x_READ_WRITE, DATA_2B}, + [NI660X_IO_CFG_22_23] = {0x792, NI_660x_READ_WRITE, DATA_2B}, + [NI660X_IO_CFG_24_25] = {0x794, NI_660x_READ_WRITE, DATA_2B}, + [NI660X_IO_CFG_26_27] = {0x796, NI_660x_READ_WRITE, DATA_2B}, + [NI660X_IO_CFG_28_29] = {0x798, NI_660x_READ_WRITE, DATA_2B}, + [NI660X_IO_CFG_30_31] = {0x79a, NI_660x_READ_WRITE, DATA_2B}, + [NI660X_IO_CFG_32_33] = {0x79c, NI_660x_READ_WRITE, DATA_2B}, + [NI660X_IO_CFG_34_35] = {0x79e, NI_660x_READ_WRITE, DATA_2B}, + [NI660X_IO_CFG_36_37] = {0x7a0, NI_660x_READ_WRITE, DATA_2B}, + [NI660X_IO_CFG_38_39] = {0x7a2, NI_660x_READ_WRITE, DATA_2B} }; /* kind of ENABLE for the second counter */ -- cgit v1.2.3 From 87090141749ad320d937375dcec6d5b925f728c7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:13 -0700 Subject: staging: comedi: ni_660x: remove enum ni_register_width All the registers are defined struct NI_660xRegisterData and they are either 2 or 4 bytes in size. Remove the enum and just use a char member to define the size as 2 or 4 bytes. Simplify the ni_660x_{write,read}_register() functions and remove the unnecessary BUG() in each. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 226 ++++++++++++++----------------- 1 file changed, 103 insertions(+), 123 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 10bb8394fd99..dbbeb968ae59 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -158,12 +158,6 @@ enum ni_660x_register { #define NI660X_IO_CFG(x) (NI660X_IO_CFG_0_1 + ((x) / 2)) -enum ni_660x_register_width { - DATA_1B, - DATA_2B, - DATA_4B -}; - enum ni_660x_register_direction { NI_660x_READ, NI_660x_WRITE, @@ -189,108 +183,108 @@ static inline unsigned NI_660X_GPCT_SUBDEV(unsigned index) struct NI_660xRegisterData { int offset; /* Offset from base address from GPCT chip */ enum ni_660x_register_direction direction; - enum ni_660x_register_width size; /* 1 byte, 2 bytes, or 4 bytes */ + char size; /* 2 or 4 bytes */ }; static const struct NI_660xRegisterData registerData[NI660X_NUM_REGS] = { - [NI660X_G0_INT_ACK] = {0x004, NI_660x_WRITE, DATA_2B}, - [NI660X_G0_STATUS] = {0x004, NI_660x_READ, DATA_2B}, - [NI660X_G1_INT_ACK] = {0x006, NI_660x_WRITE, DATA_2B}, - [NI660X_G1_STATUS] = {0x006, NI_660x_READ, DATA_2B}, - [NI660X_G01_STATUS] = {0x008, NI_660x_READ, DATA_2B}, - [NI660X_G0_CMD] = {0x00c, NI_660x_WRITE, DATA_2B}, - [NI660X_STC_DIO_PARALLEL_INPUT] = {0x00e, NI_660x_READ, DATA_2B}, - [NI660X_G1_CMD] = {0x00e, NI_660x_WRITE, DATA_2B}, - [NI660X_G0_HW_SAVE] = {0x010, NI_660x_READ, DATA_4B}, - [NI660X_G1_HW_SAVE] = {0x014, NI_660x_READ, DATA_4B}, - [NI660X_STC_DIO_OUTPUT] = {0x014, NI_660x_WRITE, DATA_2B}, - [NI660X_STC_DIO_CONTROL] = {0x016, NI_660x_WRITE, DATA_2B}, - [NI660X_G0_SW_SAVE] = {0x018, NI_660x_READ, DATA_4B}, - [NI660X_G1_SW_SAVE] = {0x01c, NI_660x_READ, DATA_4B}, - [NI660X_G0_MODE] = {0x034, NI_660x_WRITE, DATA_2B}, - [NI660X_G01_STATUS1] = {0x036, NI_660x_READ, DATA_2B}, - [NI660X_G1_MODE] = {0x036, NI_660x_WRITE, DATA_2B}, - [NI660X_STC_DIO_SERIAL_INPUT] = {0x038, NI_660x_READ, DATA_2B}, - [NI660X_G0_LOADA] = {0x038, NI_660x_WRITE, DATA_4B}, - [NI660X_G01_STATUS2] = {0x03a, NI_660x_READ, DATA_2B}, - [NI660X_G0_LOADB] = {0x03c, NI_660x_WRITE, DATA_4B}, - [NI660X_G1_LOADA] = {0x040, NI_660x_WRITE, DATA_4B}, - [NI660X_G1_LOADB] = {0x044, NI_660x_WRITE, DATA_4B}, - [NI660X_G0_INPUT_SEL] = {0x048, NI_660x_WRITE, DATA_2B}, - [NI660X_G1_INPUT_SEL] = {0x04a, NI_660x_WRITE, DATA_2B}, - [NI660X_G0_AUTO_INC] = {0x088, NI_660x_WRITE, DATA_2B}, - [NI660X_G1_AUTO_INC] = {0x08a, NI_660x_WRITE, DATA_2B}, - [NI660X_G01_RESET] = {0x090, NI_660x_WRITE, DATA_2B}, - [NI660X_G0_INT_ENA] = {0x092, NI_660x_WRITE, DATA_2B}, - [NI660X_G1_INT_ENA] = {0x096, NI_660x_WRITE, DATA_2B}, - [NI660X_G0_CNT_MODE] = {0x0b0, NI_660x_WRITE, DATA_2B}, - [NI660X_G1_CNT_MODE] = {0x0b2, NI_660x_WRITE, DATA_2B}, - [NI660X_G0_GATE2] = {0x0b4, NI_660x_WRITE, DATA_2B}, - [NI660X_G1_GATE2] = {0x0b6, NI_660x_WRITE, DATA_2B}, - [NI660X_G0_DMA_CFG] = {0x0b8, NI_660x_WRITE, DATA_2B}, - [NI660X_G0_DMA_STATUS] = {0x0b8, NI_660x_READ, DATA_2B}, - [NI660X_G1_DMA_CFG] = {0x0ba, NI_660x_WRITE, DATA_2B}, - [NI660X_G1_DMA_STATUS] = {0x0ba, NI_660x_READ, DATA_2B}, - [NI660X_G2_INT_ACK] = {0x104, NI_660x_WRITE, DATA_2B}, - [NI660X_G2_STATUS] = {0x104, NI_660x_READ, DATA_2B}, - [NI660X_G3_INT_ACK] = {0x106, NI_660x_WRITE, DATA_2B}, - [NI660X_G3_STATUS] = {0x106, NI_660x_READ, DATA_2B}, - [NI660X_G23_STATUS] = {0x108, NI_660x_READ, DATA_2B}, - [NI660X_G2_CMD] = {0x10c, NI_660x_WRITE, DATA_2B}, - [NI660X_G3_CMD] = {0x10e, NI_660x_WRITE, DATA_2B}, - [NI660X_G2_HW_SAVE] = {0x110, NI_660x_READ, DATA_4B}, - [NI660X_G3_HW_SAVE] = {0x114, NI_660x_READ, DATA_4B}, - [NI660X_G2_SW_SAVE] = {0x118, NI_660x_READ, DATA_4B}, - [NI660X_G3_SW_SAVE] = {0x11c, NI_660x_READ, DATA_4B}, - [NI660X_G2_MODE] = {0x134, NI_660x_WRITE, DATA_2B}, - [NI660X_G23_STATUS1] = {0x136, NI_660x_READ, DATA_2B}, - [NI660X_G3_MODE] = {0x136, NI_660x_WRITE, DATA_2B}, - [NI660X_G2_LOADA] = {0x138, NI_660x_WRITE, DATA_4B}, - [NI660X_G23_STATUS2] = {0x13a, NI_660x_READ, DATA_2B}, - [NI660X_G2_LOADB] = {0x13c, NI_660x_WRITE, DATA_4B}, - [NI660X_G3_LOADA] = {0x140, NI_660x_WRITE, DATA_4B}, - [NI660X_G3_LOADB] = {0x144, NI_660x_WRITE, DATA_4B}, - [NI660X_G2_INPUT_SEL] = {0x148, NI_660x_WRITE, DATA_2B}, - [NI660X_G3_INPUT_SEL] = {0x14a, NI_660x_WRITE, DATA_2B}, - [NI660X_G2_AUTO_INC] = {0x188, NI_660x_WRITE, DATA_2B}, - [NI660X_G3_AUTO_INC] = {0x18a, NI_660x_WRITE, DATA_2B}, - [NI660X_G23_RESET] = {0x190, NI_660x_WRITE, DATA_2B}, - [NI660X_G2_INT_ENA] = {0x192, NI_660x_WRITE, DATA_2B}, - [NI660X_G3_INT_ENA] = {0x196, NI_660x_WRITE, DATA_2B}, - [NI660X_G2_CNT_MODE] = {0x1b0, NI_660x_WRITE, DATA_2B}, - [NI660X_G3_CNT_MODE] = {0x1b2, NI_660x_WRITE, DATA_2B}, - [NI660X_G3_GATE2] = {0x1b6, NI_660x_WRITE, DATA_2B}, - [NI660X_G2_GATE2] = {0x1b4, NI_660x_WRITE, DATA_2B}, - [NI660X_G2_DMA_CFG] = {0x1b8, NI_660x_WRITE, DATA_2B}, - [NI660X_G2_DMA_STATUS] = {0x1b8, NI_660x_READ, DATA_2B}, - [NI660X_G3_DMA_CFG] = {0x1ba, NI_660x_WRITE, DATA_2B}, - [NI660X_G3_DMA_STATUS] = {0x1ba, NI_660x_READ, DATA_2B}, - [NI660X_DIO32_INPUT] = {0x414, NI_660x_READ, DATA_4B}, - [NI660X_DIO32_OUTPUT] = {0x510, NI_660x_WRITE, DATA_4B}, - [NI660X_CLK_CFG] = {0x73c, NI_660x_WRITE, DATA_4B}, - [NI660X_GLOBAL_INT_STATUS] = {0x754, NI_660x_READ, DATA_4B}, - [NI660X_DMA_CFG] = {0x76c, NI_660x_WRITE, DATA_4B}, - [NI660X_GLOBAL_INT_CFG] = {0x770, NI_660x_WRITE, DATA_4B}, - [NI660X_IO_CFG_0_1] = {0x77c, NI_660x_READ_WRITE, DATA_2B}, - [NI660X_IO_CFG_2_3] = {0x77e, NI_660x_READ_WRITE, DATA_2B}, - [NI660X_IO_CFG_4_5] = {0x780, NI_660x_READ_WRITE, DATA_2B}, - [NI660X_IO_CFG_6_7] = {0x782, NI_660x_READ_WRITE, DATA_2B}, - [NI660X_IO_CFG_8_9] = {0x784, NI_660x_READ_WRITE, DATA_2B}, - [NI660X_IO_CFG_10_11] = {0x786, NI_660x_READ_WRITE, DATA_2B}, - [NI660X_IO_CFG_12_13] = {0x788, NI_660x_READ_WRITE, DATA_2B}, - [NI660X_IO_CFG_14_15] = {0x78a, NI_660x_READ_WRITE, DATA_2B}, - [NI660X_IO_CFG_16_17] = {0x78c, NI_660x_READ_WRITE, DATA_2B}, - [NI660X_IO_CFG_18_19] = {0x78e, NI_660x_READ_WRITE, DATA_2B}, - [NI660X_IO_CFG_20_21] = {0x790, NI_660x_READ_WRITE, DATA_2B}, - [NI660X_IO_CFG_22_23] = {0x792, NI_660x_READ_WRITE, DATA_2B}, - [NI660X_IO_CFG_24_25] = {0x794, NI_660x_READ_WRITE, DATA_2B}, - [NI660X_IO_CFG_26_27] = {0x796, NI_660x_READ_WRITE, DATA_2B}, - [NI660X_IO_CFG_28_29] = {0x798, NI_660x_READ_WRITE, DATA_2B}, - [NI660X_IO_CFG_30_31] = {0x79a, NI_660x_READ_WRITE, DATA_2B}, - [NI660X_IO_CFG_32_33] = {0x79c, NI_660x_READ_WRITE, DATA_2B}, - [NI660X_IO_CFG_34_35] = {0x79e, NI_660x_READ_WRITE, DATA_2B}, - [NI660X_IO_CFG_36_37] = {0x7a0, NI_660x_READ_WRITE, DATA_2B}, - [NI660X_IO_CFG_38_39] = {0x7a2, NI_660x_READ_WRITE, DATA_2B} + [NI660X_G0_INT_ACK] = { 0x004, NI_660x_WRITE, 2 }, + [NI660X_G0_STATUS] = { 0x004, NI_660x_READ, 2 }, + [NI660X_G1_INT_ACK] = { 0x006, NI_660x_WRITE, 2 }, + [NI660X_G1_STATUS] = { 0x006, NI_660x_READ, 2 }, + [NI660X_G01_STATUS] = { 0x008, NI_660x_READ, 2 }, + [NI660X_G0_CMD] = { 0x00c, NI_660x_WRITE, 2 }, + [NI660X_STC_DIO_PARALLEL_INPUT] = { 0x00e, NI_660x_READ, 2 }, + [NI660X_G1_CMD] = { 0x00e, NI_660x_WRITE, 2 }, + [NI660X_G0_HW_SAVE] = { 0x010, NI_660x_READ, 4 }, + [NI660X_G1_HW_SAVE] = { 0x014, NI_660x_READ, 4 }, + [NI660X_STC_DIO_OUTPUT] = { 0x014, NI_660x_WRITE, 2 }, + [NI660X_STC_DIO_CONTROL] = { 0x016, NI_660x_WRITE, 2 }, + [NI660X_G0_SW_SAVE] = { 0x018, NI_660x_READ, 4 }, + [NI660X_G1_SW_SAVE] = { 0x01c, NI_660x_READ, 4 }, + [NI660X_G0_MODE] = { 0x034, NI_660x_WRITE, 2 }, + [NI660X_G01_STATUS1] = { 0x036, NI_660x_READ, 2 }, + [NI660X_G1_MODE] = { 0x036, NI_660x_WRITE, 2 }, + [NI660X_STC_DIO_SERIAL_INPUT] = { 0x038, NI_660x_READ, 2 }, + [NI660X_G0_LOADA] = { 0x038, NI_660x_WRITE, 4 }, + [NI660X_G01_STATUS2] = { 0x03a, NI_660x_READ, 2 }, + [NI660X_G0_LOADB] = { 0x03c, NI_660x_WRITE, 4 }, + [NI660X_G1_LOADA] = { 0x040, NI_660x_WRITE, 4 }, + [NI660X_G1_LOADB] = { 0x044, NI_660x_WRITE, 4 }, + [NI660X_G0_INPUT_SEL] = { 0x048, NI_660x_WRITE, 2 }, + [NI660X_G1_INPUT_SEL] = { 0x04a, NI_660x_WRITE, 2 }, + [NI660X_G0_AUTO_INC] = { 0x088, NI_660x_WRITE, 2 }, + [NI660X_G1_AUTO_INC] = { 0x08a, NI_660x_WRITE, 2 }, + [NI660X_G01_RESET] = { 0x090, NI_660x_WRITE, 2 }, + [NI660X_G0_INT_ENA] = { 0x092, NI_660x_WRITE, 2 }, + [NI660X_G1_INT_ENA] = { 0x096, NI_660x_WRITE, 2 }, + [NI660X_G0_CNT_MODE] = { 0x0b0, NI_660x_WRITE, 2 }, + [NI660X_G1_CNT_MODE] = { 0x0b2, NI_660x_WRITE, 2 }, + [NI660X_G0_GATE2] = { 0x0b4, NI_660x_WRITE, 2 }, + [NI660X_G1_GATE2] = { 0x0b6, NI_660x_WRITE, 2 }, + [NI660X_G0_DMA_CFG] = { 0x0b8, NI_660x_WRITE, 2 }, + [NI660X_G0_DMA_STATUS] = { 0x0b8, NI_660x_READ, 2 }, + [NI660X_G1_DMA_CFG] = { 0x0ba, NI_660x_WRITE, 2 }, + [NI660X_G1_DMA_STATUS] = { 0x0ba, NI_660x_READ, 2 }, + [NI660X_G2_INT_ACK] = { 0x104, NI_660x_WRITE, 2 }, + [NI660X_G2_STATUS] = { 0x104, NI_660x_READ, 2 }, + [NI660X_G3_INT_ACK] = { 0x106, NI_660x_WRITE, 2 }, + [NI660X_G3_STATUS] = { 0x106, NI_660x_READ, 2 }, + [NI660X_G23_STATUS] = { 0x108, NI_660x_READ, 2 }, + [NI660X_G2_CMD] = { 0x10c, NI_660x_WRITE, 2 }, + [NI660X_G3_CMD] = { 0x10e, NI_660x_WRITE, 2 }, + [NI660X_G2_HW_SAVE] = { 0x110, NI_660x_READ, 4 }, + [NI660X_G3_HW_SAVE] = { 0x114, NI_660x_READ, 4 }, + [NI660X_G2_SW_SAVE] = { 0x118, NI_660x_READ, 4 }, + [NI660X_G3_SW_SAVE] = { 0x11c, NI_660x_READ, 4 }, + [NI660X_G2_MODE] = { 0x134, NI_660x_WRITE, 2 }, + [NI660X_G23_STATUS1] = { 0x136, NI_660x_READ, 2 }, + [NI660X_G3_MODE] = { 0x136, NI_660x_WRITE, 2 }, + [NI660X_G2_LOADA] = { 0x138, NI_660x_WRITE, 4 }, + [NI660X_G23_STATUS2] = { 0x13a, NI_660x_READ, 2 }, + [NI660X_G2_LOADB] = { 0x13c, NI_660x_WRITE, 4 }, + [NI660X_G3_LOADA] = { 0x140, NI_660x_WRITE, 4 }, + [NI660X_G3_LOADB] = { 0x144, NI_660x_WRITE, 4 }, + [NI660X_G2_INPUT_SEL] = { 0x148, NI_660x_WRITE, 2 }, + [NI660X_G3_INPUT_SEL] = { 0x14a, NI_660x_WRITE, 2 }, + [NI660X_G2_AUTO_INC] = { 0x188, NI_660x_WRITE, 2 }, + [NI660X_G3_AUTO_INC] = { 0x18a, NI_660x_WRITE, 2 }, + [NI660X_G23_RESET] = { 0x190, NI_660x_WRITE, 2 }, + [NI660X_G2_INT_ENA] = { 0x192, NI_660x_WRITE, 2 }, + [NI660X_G3_INT_ENA] = { 0x196, NI_660x_WRITE, 2 }, + [NI660X_G2_CNT_MODE] = { 0x1b0, NI_660x_WRITE, 2 }, + [NI660X_G3_CNT_MODE] = { 0x1b2, NI_660x_WRITE, 2 }, + [NI660X_G3_GATE2] = { 0x1b6, NI_660x_WRITE, 2 }, + [NI660X_G2_GATE2] = { 0x1b4, NI_660x_WRITE, 2 }, + [NI660X_G2_DMA_CFG] = { 0x1b8, NI_660x_WRITE, 2 }, + [NI660X_G2_DMA_STATUS] = { 0x1b8, NI_660x_READ, 2 }, + [NI660X_G3_DMA_CFG] = { 0x1ba, NI_660x_WRITE, 2 }, + [NI660X_G3_DMA_STATUS] = { 0x1ba, NI_660x_READ, 2 }, + [NI660X_DIO32_INPUT] = { 0x414, NI_660x_READ, 4 }, + [NI660X_DIO32_OUTPUT] = { 0x510, NI_660x_WRITE, 4 }, + [NI660X_CLK_CFG] = { 0x73c, NI_660x_WRITE, 4 }, + [NI660X_GLOBAL_INT_STATUS] = { 0x754, NI_660x_READ, 4 }, + [NI660X_DMA_CFG] = { 0x76c, NI_660x_WRITE, 4 }, + [NI660X_GLOBAL_INT_CFG] = { 0x770, NI_660x_WRITE, 4 }, + [NI660X_IO_CFG_0_1] = { 0x77c, NI_660x_READ_WRITE, 2 }, + [NI660X_IO_CFG_2_3] = { 0x77e, NI_660x_READ_WRITE, 2 }, + [NI660X_IO_CFG_4_5] = { 0x780, NI_660x_READ_WRITE, 2 }, + [NI660X_IO_CFG_6_7] = { 0x782, NI_660x_READ_WRITE, 2 }, + [NI660X_IO_CFG_8_9] = { 0x784, NI_660x_READ_WRITE, 2 }, + [NI660X_IO_CFG_10_11] = { 0x786, NI_660x_READ_WRITE, 2 }, + [NI660X_IO_CFG_12_13] = { 0x788, NI_660x_READ_WRITE, 2 }, + [NI660X_IO_CFG_14_15] = { 0x78a, NI_660x_READ_WRITE, 2 }, + [NI660X_IO_CFG_16_17] = { 0x78c, NI_660x_READ_WRITE, 2 }, + [NI660X_IO_CFG_18_19] = { 0x78e, NI_660x_READ_WRITE, 2 }, + [NI660X_IO_CFG_20_21] = { 0x790, NI_660x_READ_WRITE, 2 }, + [NI660X_IO_CFG_22_23] = { 0x792, NI_660x_READ_WRITE, 2 }, + [NI660X_IO_CFG_24_25] = { 0x794, NI_660x_READ_WRITE, 2 }, + [NI660X_IO_CFG_26_27] = { 0x796, NI_660x_READ_WRITE, 2 }, + [NI660X_IO_CFG_28_29] = { 0x798, NI_660x_READ_WRITE, 2 }, + [NI660X_IO_CFG_30_31] = { 0x79a, NI_660x_READ_WRITE, 2 }, + [NI660X_IO_CFG_32_33] = { 0x79c, NI_660x_READ_WRITE, 2 }, + [NI660X_IO_CFG_34_35] = { 0x79e, NI_660x_READ_WRITE, 2 }, + [NI660X_IO_CFG_36_37] = { 0x7a0, NI_660x_READ_WRITE, 2 }, + [NI660X_IO_CFG_38_39] = { 0x7a2, NI_660x_READ_WRITE, 2 } }; /* kind of ENABLE for the second counter */ @@ -579,17 +573,10 @@ static inline void ni_660x_write_register(struct comedi_device *dev, { unsigned int addr = GPCT_OFFSET[chip] + registerData[reg].offset; - switch (registerData[reg].size) { - case DATA_2B: + if (registerData[reg].size == 2) writew(bits, dev->mmio + addr); - break; - case DATA_4B: + else writel(bits, dev->mmio + addr); - break; - default: - BUG(); - break; - } } static inline unsigned ni_660x_read_register(struct comedi_device *dev, @@ -598,16 +585,9 @@ static inline unsigned ni_660x_read_register(struct comedi_device *dev, { unsigned int addr = GPCT_OFFSET[chip] + registerData[reg].offset; - switch (registerData[reg].size) { - case DATA_2B: + if (registerData[reg].size == 2) return readw(dev->mmio + addr); - case DATA_4B: - return readl(dev->mmio + addr); - default: - BUG(); - break; - } - return 0; + return readl(dev->mmio + addr); } static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits, -- cgit v1.2.3 From 9392e5dde2652ec335f48f28db3c0433cbdc9d92 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:14 -0700 Subject: staging: comedi: ni_660x: remove enum ni_660x_register_direction This enum is used to define the, unused, 'direction' of each register in struct NI_660xRegisterData. Remove the unused member, as well as the enum. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 203 +++++++++++++++---------------- 1 file changed, 98 insertions(+), 105 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index dbbeb968ae59..409a776caac7 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -158,12 +158,6 @@ enum ni_660x_register { #define NI660X_IO_CFG(x) (NI660X_IO_CFG_0_1 + ((x) / 2)) -enum ni_660x_register_direction { - NI_660x_READ, - NI_660x_WRITE, - NI_660x_READ_WRITE -}; - enum ni_660x_pfi_output_select { pfi_output_select_high_Z = 0, pfi_output_select_counter = 1, @@ -182,109 +176,108 @@ static inline unsigned NI_660X_GPCT_SUBDEV(unsigned index) struct NI_660xRegisterData { int offset; /* Offset from base address from GPCT chip */ - enum ni_660x_register_direction direction; char size; /* 2 or 4 bytes */ }; static const struct NI_660xRegisterData registerData[NI660X_NUM_REGS] = { - [NI660X_G0_INT_ACK] = { 0x004, NI_660x_WRITE, 2 }, - [NI660X_G0_STATUS] = { 0x004, NI_660x_READ, 2 }, - [NI660X_G1_INT_ACK] = { 0x006, NI_660x_WRITE, 2 }, - [NI660X_G1_STATUS] = { 0x006, NI_660x_READ, 2 }, - [NI660X_G01_STATUS] = { 0x008, NI_660x_READ, 2 }, - [NI660X_G0_CMD] = { 0x00c, NI_660x_WRITE, 2 }, - [NI660X_STC_DIO_PARALLEL_INPUT] = { 0x00e, NI_660x_READ, 2 }, - [NI660X_G1_CMD] = { 0x00e, NI_660x_WRITE, 2 }, - [NI660X_G0_HW_SAVE] = { 0x010, NI_660x_READ, 4 }, - [NI660X_G1_HW_SAVE] = { 0x014, NI_660x_READ, 4 }, - [NI660X_STC_DIO_OUTPUT] = { 0x014, NI_660x_WRITE, 2 }, - [NI660X_STC_DIO_CONTROL] = { 0x016, NI_660x_WRITE, 2 }, - [NI660X_G0_SW_SAVE] = { 0x018, NI_660x_READ, 4 }, - [NI660X_G1_SW_SAVE] = { 0x01c, NI_660x_READ, 4 }, - [NI660X_G0_MODE] = { 0x034, NI_660x_WRITE, 2 }, - [NI660X_G01_STATUS1] = { 0x036, NI_660x_READ, 2 }, - [NI660X_G1_MODE] = { 0x036, NI_660x_WRITE, 2 }, - [NI660X_STC_DIO_SERIAL_INPUT] = { 0x038, NI_660x_READ, 2 }, - [NI660X_G0_LOADA] = { 0x038, NI_660x_WRITE, 4 }, - [NI660X_G01_STATUS2] = { 0x03a, NI_660x_READ, 2 }, - [NI660X_G0_LOADB] = { 0x03c, NI_660x_WRITE, 4 }, - [NI660X_G1_LOADA] = { 0x040, NI_660x_WRITE, 4 }, - [NI660X_G1_LOADB] = { 0x044, NI_660x_WRITE, 4 }, - [NI660X_G0_INPUT_SEL] = { 0x048, NI_660x_WRITE, 2 }, - [NI660X_G1_INPUT_SEL] = { 0x04a, NI_660x_WRITE, 2 }, - [NI660X_G0_AUTO_INC] = { 0x088, NI_660x_WRITE, 2 }, - [NI660X_G1_AUTO_INC] = { 0x08a, NI_660x_WRITE, 2 }, - [NI660X_G01_RESET] = { 0x090, NI_660x_WRITE, 2 }, - [NI660X_G0_INT_ENA] = { 0x092, NI_660x_WRITE, 2 }, - [NI660X_G1_INT_ENA] = { 0x096, NI_660x_WRITE, 2 }, - [NI660X_G0_CNT_MODE] = { 0x0b0, NI_660x_WRITE, 2 }, - [NI660X_G1_CNT_MODE] = { 0x0b2, NI_660x_WRITE, 2 }, - [NI660X_G0_GATE2] = { 0x0b4, NI_660x_WRITE, 2 }, - [NI660X_G1_GATE2] = { 0x0b6, NI_660x_WRITE, 2 }, - [NI660X_G0_DMA_CFG] = { 0x0b8, NI_660x_WRITE, 2 }, - [NI660X_G0_DMA_STATUS] = { 0x0b8, NI_660x_READ, 2 }, - [NI660X_G1_DMA_CFG] = { 0x0ba, NI_660x_WRITE, 2 }, - [NI660X_G1_DMA_STATUS] = { 0x0ba, NI_660x_READ, 2 }, - [NI660X_G2_INT_ACK] = { 0x104, NI_660x_WRITE, 2 }, - [NI660X_G2_STATUS] = { 0x104, NI_660x_READ, 2 }, - [NI660X_G3_INT_ACK] = { 0x106, NI_660x_WRITE, 2 }, - [NI660X_G3_STATUS] = { 0x106, NI_660x_READ, 2 }, - [NI660X_G23_STATUS] = { 0x108, NI_660x_READ, 2 }, - [NI660X_G2_CMD] = { 0x10c, NI_660x_WRITE, 2 }, - [NI660X_G3_CMD] = { 0x10e, NI_660x_WRITE, 2 }, - [NI660X_G2_HW_SAVE] = { 0x110, NI_660x_READ, 4 }, - [NI660X_G3_HW_SAVE] = { 0x114, NI_660x_READ, 4 }, - [NI660X_G2_SW_SAVE] = { 0x118, NI_660x_READ, 4 }, - [NI660X_G3_SW_SAVE] = { 0x11c, NI_660x_READ, 4 }, - [NI660X_G2_MODE] = { 0x134, NI_660x_WRITE, 2 }, - [NI660X_G23_STATUS1] = { 0x136, NI_660x_READ, 2 }, - [NI660X_G3_MODE] = { 0x136, NI_660x_WRITE, 2 }, - [NI660X_G2_LOADA] = { 0x138, NI_660x_WRITE, 4 }, - [NI660X_G23_STATUS2] = { 0x13a, NI_660x_READ, 2 }, - [NI660X_G2_LOADB] = { 0x13c, NI_660x_WRITE, 4 }, - [NI660X_G3_LOADA] = { 0x140, NI_660x_WRITE, 4 }, - [NI660X_G3_LOADB] = { 0x144, NI_660x_WRITE, 4 }, - [NI660X_G2_INPUT_SEL] = { 0x148, NI_660x_WRITE, 2 }, - [NI660X_G3_INPUT_SEL] = { 0x14a, NI_660x_WRITE, 2 }, - [NI660X_G2_AUTO_INC] = { 0x188, NI_660x_WRITE, 2 }, - [NI660X_G3_AUTO_INC] = { 0x18a, NI_660x_WRITE, 2 }, - [NI660X_G23_RESET] = { 0x190, NI_660x_WRITE, 2 }, - [NI660X_G2_INT_ENA] = { 0x192, NI_660x_WRITE, 2 }, - [NI660X_G3_INT_ENA] = { 0x196, NI_660x_WRITE, 2 }, - [NI660X_G2_CNT_MODE] = { 0x1b0, NI_660x_WRITE, 2 }, - [NI660X_G3_CNT_MODE] = { 0x1b2, NI_660x_WRITE, 2 }, - [NI660X_G3_GATE2] = { 0x1b6, NI_660x_WRITE, 2 }, - [NI660X_G2_GATE2] = { 0x1b4, NI_660x_WRITE, 2 }, - [NI660X_G2_DMA_CFG] = { 0x1b8, NI_660x_WRITE, 2 }, - [NI660X_G2_DMA_STATUS] = { 0x1b8, NI_660x_READ, 2 }, - [NI660X_G3_DMA_CFG] = { 0x1ba, NI_660x_WRITE, 2 }, - [NI660X_G3_DMA_STATUS] = { 0x1ba, NI_660x_READ, 2 }, - [NI660X_DIO32_INPUT] = { 0x414, NI_660x_READ, 4 }, - [NI660X_DIO32_OUTPUT] = { 0x510, NI_660x_WRITE, 4 }, - [NI660X_CLK_CFG] = { 0x73c, NI_660x_WRITE, 4 }, - [NI660X_GLOBAL_INT_STATUS] = { 0x754, NI_660x_READ, 4 }, - [NI660X_DMA_CFG] = { 0x76c, NI_660x_WRITE, 4 }, - [NI660X_GLOBAL_INT_CFG] = { 0x770, NI_660x_WRITE, 4 }, - [NI660X_IO_CFG_0_1] = { 0x77c, NI_660x_READ_WRITE, 2 }, - [NI660X_IO_CFG_2_3] = { 0x77e, NI_660x_READ_WRITE, 2 }, - [NI660X_IO_CFG_4_5] = { 0x780, NI_660x_READ_WRITE, 2 }, - [NI660X_IO_CFG_6_7] = { 0x782, NI_660x_READ_WRITE, 2 }, - [NI660X_IO_CFG_8_9] = { 0x784, NI_660x_READ_WRITE, 2 }, - [NI660X_IO_CFG_10_11] = { 0x786, NI_660x_READ_WRITE, 2 }, - [NI660X_IO_CFG_12_13] = { 0x788, NI_660x_READ_WRITE, 2 }, - [NI660X_IO_CFG_14_15] = { 0x78a, NI_660x_READ_WRITE, 2 }, - [NI660X_IO_CFG_16_17] = { 0x78c, NI_660x_READ_WRITE, 2 }, - [NI660X_IO_CFG_18_19] = { 0x78e, NI_660x_READ_WRITE, 2 }, - [NI660X_IO_CFG_20_21] = { 0x790, NI_660x_READ_WRITE, 2 }, - [NI660X_IO_CFG_22_23] = { 0x792, NI_660x_READ_WRITE, 2 }, - [NI660X_IO_CFG_24_25] = { 0x794, NI_660x_READ_WRITE, 2 }, - [NI660X_IO_CFG_26_27] = { 0x796, NI_660x_READ_WRITE, 2 }, - [NI660X_IO_CFG_28_29] = { 0x798, NI_660x_READ_WRITE, 2 }, - [NI660X_IO_CFG_30_31] = { 0x79a, NI_660x_READ_WRITE, 2 }, - [NI660X_IO_CFG_32_33] = { 0x79c, NI_660x_READ_WRITE, 2 }, - [NI660X_IO_CFG_34_35] = { 0x79e, NI_660x_READ_WRITE, 2 }, - [NI660X_IO_CFG_36_37] = { 0x7a0, NI_660x_READ_WRITE, 2 }, - [NI660X_IO_CFG_38_39] = { 0x7a2, NI_660x_READ_WRITE, 2 } + [NI660X_G0_INT_ACK] = { 0x004, 2 }, /* write */ + [NI660X_G0_STATUS] = { 0x004, 2 }, /* read */ + [NI660X_G1_INT_ACK] = { 0x006, 2 }, /* write */ + [NI660X_G1_STATUS] = { 0x006, 2 }, /* read */ + [NI660X_G01_STATUS] = { 0x008, 2 }, /* read */ + [NI660X_G0_CMD] = { 0x00c, 2 }, /* write */ + [NI660X_STC_DIO_PARALLEL_INPUT] = { 0x00e, 2 }, /* read */ + [NI660X_G1_CMD] = { 0x00e, 2 }, /* write */ + [NI660X_G0_HW_SAVE] = { 0x010, 4 }, /* read */ + [NI660X_G1_HW_SAVE] = { 0x014, 4 }, /* read */ + [NI660X_STC_DIO_OUTPUT] = { 0x014, 2 }, /* write */ + [NI660X_STC_DIO_CONTROL] = { 0x016, 2 }, /* write */ + [NI660X_G0_SW_SAVE] = { 0x018, 4 }, /* read */ + [NI660X_G1_SW_SAVE] = { 0x01c, 4 }, /* read */ + [NI660X_G0_MODE] = { 0x034, 2 }, /* write */ + [NI660X_G01_STATUS1] = { 0x036, 2 }, /* read */ + [NI660X_G1_MODE] = { 0x036, 2 }, /* write */ + [NI660X_STC_DIO_SERIAL_INPUT] = { 0x038, 2 }, /* read */ + [NI660X_G0_LOADA] = { 0x038, 4 }, /* write */ + [NI660X_G01_STATUS2] = { 0x03a, 2 }, /* read */ + [NI660X_G0_LOADB] = { 0x03c, 4 }, /* write */ + [NI660X_G1_LOADA] = { 0x040, 4 }, /* write */ + [NI660X_G1_LOADB] = { 0x044, 4 }, /* write */ + [NI660X_G0_INPUT_SEL] = { 0x048, 2 }, /* write */ + [NI660X_G1_INPUT_SEL] = { 0x04a, 2 }, /* write */ + [NI660X_G0_AUTO_INC] = { 0x088, 2 }, /* write */ + [NI660X_G1_AUTO_INC] = { 0x08a, 2 }, /* write */ + [NI660X_G01_RESET] = { 0x090, 2 }, /* write */ + [NI660X_G0_INT_ENA] = { 0x092, 2 }, /* write */ + [NI660X_G1_INT_ENA] = { 0x096, 2 }, /* write */ + [NI660X_G0_CNT_MODE] = { 0x0b0, 2 }, /* write */ + [NI660X_G1_CNT_MODE] = { 0x0b2, 2 }, /* write */ + [NI660X_G0_GATE2] = { 0x0b4, 2 }, /* write */ + [NI660X_G1_GATE2] = { 0x0b6, 2 }, /* write */ + [NI660X_G0_DMA_CFG] = { 0x0b8, 2 }, /* write */ + [NI660X_G0_DMA_STATUS] = { 0x0b8, 2 }, /* read */ + [NI660X_G1_DMA_CFG] = { 0x0ba, 2 }, /* write */ + [NI660X_G1_DMA_STATUS] = { 0x0ba, 2 }, /* read */ + [NI660X_G2_INT_ACK] = { 0x104, 2 }, /* write */ + [NI660X_G2_STATUS] = { 0x104, 2 }, /* read */ + [NI660X_G3_INT_ACK] = { 0x106, 2 }, /* write */ + [NI660X_G3_STATUS] = { 0x106, 2 }, /* read */ + [NI660X_G23_STATUS] = { 0x108, 2 }, /* read */ + [NI660X_G2_CMD] = { 0x10c, 2 }, /* write */ + [NI660X_G3_CMD] = { 0x10e, 2 }, /* write */ + [NI660X_G2_HW_SAVE] = { 0x110, 4 }, /* read */ + [NI660X_G3_HW_SAVE] = { 0x114, 4 }, /* read */ + [NI660X_G2_SW_SAVE] = { 0x118, 4 }, /* read */ + [NI660X_G3_SW_SAVE] = { 0x11c, 4 }, /* read */ + [NI660X_G2_MODE] = { 0x134, 2 }, /* write */ + [NI660X_G23_STATUS1] = { 0x136, 2 }, /* read */ + [NI660X_G3_MODE] = { 0x136, 2 }, /* write */ + [NI660X_G2_LOADA] = { 0x138, 4 }, /* write */ + [NI660X_G23_STATUS2] = { 0x13a, 2 }, /* read */ + [NI660X_G2_LOADB] = { 0x13c, 4 }, /* write */ + [NI660X_G3_LOADA] = { 0x140, 4 }, /* write */ + [NI660X_G3_LOADB] = { 0x144, 4 }, /* write */ + [NI660X_G2_INPUT_SEL] = { 0x148, 2 }, /* write */ + [NI660X_G3_INPUT_SEL] = { 0x14a, 2 }, /* write */ + [NI660X_G2_AUTO_INC] = { 0x188, 2 }, /* write */ + [NI660X_G3_AUTO_INC] = { 0x18a, 2 }, /* write */ + [NI660X_G23_RESET] = { 0x190, 2 }, /* write */ + [NI660X_G2_INT_ENA] = { 0x192, 2 }, /* write */ + [NI660X_G3_INT_ENA] = { 0x196, 2 }, /* write */ + [NI660X_G2_CNT_MODE] = { 0x1b0, 2 }, /* write */ + [NI660X_G3_CNT_MODE] = { 0x1b2, 2 }, /* write */ + [NI660X_G3_GATE2] = { 0x1b6, 2 }, /* write */ + [NI660X_G2_GATE2] = { 0x1b4, 2 }, /* write */ + [NI660X_G2_DMA_CFG] = { 0x1b8, 2 }, /* write */ + [NI660X_G2_DMA_STATUS] = { 0x1b8, 2 }, /* read */ + [NI660X_G3_DMA_CFG] = { 0x1ba, 2 }, /* write */ + [NI660X_G3_DMA_STATUS] = { 0x1ba, 2 }, /* read */ + [NI660X_DIO32_INPUT] = { 0x414, 4 }, /* read */ + [NI660X_DIO32_OUTPUT] = { 0x510, 4 }, /* write */ + [NI660X_CLK_CFG] = { 0x73c, 4 }, /* write */ + [NI660X_GLOBAL_INT_STATUS] = { 0x754, 4 }, /* read */ + [NI660X_DMA_CFG] = { 0x76c, 4 }, /* write */ + [NI660X_GLOBAL_INT_CFG] = { 0x770, 4 }, /* write */ + [NI660X_IO_CFG_0_1] = { 0x77c, 2 }, /* read/write */ + [NI660X_IO_CFG_2_3] = { 0x77e, 2 }, /* read/write */ + [NI660X_IO_CFG_4_5] = { 0x780, 2 }, /* read/write */ + [NI660X_IO_CFG_6_7] = { 0x782, 2 }, /* read/write */ + [NI660X_IO_CFG_8_9] = { 0x784, 2 }, /* read/write */ + [NI660X_IO_CFG_10_11] = { 0x786, 2 }, /* read/write */ + [NI660X_IO_CFG_12_13] = { 0x788, 2 }, /* read/write */ + [NI660X_IO_CFG_14_15] = { 0x78a, 2 }, /* read/write */ + [NI660X_IO_CFG_16_17] = { 0x78c, 2 }, /* read/write */ + [NI660X_IO_CFG_18_19] = { 0x78e, 2 }, /* read/write */ + [NI660X_IO_CFG_20_21] = { 0x790, 2 }, /* read/write */ + [NI660X_IO_CFG_22_23] = { 0x792, 2 }, /* read/write */ + [NI660X_IO_CFG_24_25] = { 0x794, 2 }, /* read/write */ + [NI660X_IO_CFG_26_27] = { 0x796, 2 }, /* read/write */ + [NI660X_IO_CFG_28_29] = { 0x798, 2 }, /* read/write */ + [NI660X_IO_CFG_30_31] = { 0x79a, 2 }, /* read/write */ + [NI660X_IO_CFG_32_33] = { 0x79c, 2 }, /* read/write */ + [NI660X_IO_CFG_34_35] = { 0x79e, 2 }, /* read/write */ + [NI660X_IO_CFG_36_37] = { 0x7a0, 2 }, /* read/write */ + [NI660X_IO_CFG_38_39] = { 0x7a2, 2 } /* read/write */ }; /* kind of ENABLE for the second counter */ -- cgit v1.2.3 From b38700a22a62aaaff04e644a7f1c6b2733249294 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:15 -0700 Subject: staging: comedi: ni_660x: rename CamelCase 'NI_660xRegisterData' Rename this CamelCase struct and the associated 'registerData' variable. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 409a776caac7..d76a5b026b91 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -174,12 +174,12 @@ static inline unsigned NI_660X_GPCT_SUBDEV(unsigned index) return NI_660X_GPCT_SUBDEV_0 + index; } -struct NI_660xRegisterData { +struct ni_660x_register_data { int offset; /* Offset from base address from GPCT chip */ char size; /* 2 or 4 bytes */ }; -static const struct NI_660xRegisterData registerData[NI660X_NUM_REGS] = { +static const struct ni_660x_register_data ni_660x_reg_data[NI660X_NUM_REGS] = { [NI660X_G0_INT_ACK] = { 0x004, 2 }, /* write */ [NI660X_G0_STATUS] = { 0x004, 2 }, /* read */ [NI660X_G1_INT_ACK] = { 0x006, 2 }, /* write */ @@ -564,9 +564,9 @@ static inline void ni_660x_write_register(struct comedi_device *dev, unsigned chip, unsigned bits, enum ni_660x_register reg) { - unsigned int addr = GPCT_OFFSET[chip] + registerData[reg].offset; + unsigned int addr = GPCT_OFFSET[chip] + ni_660x_reg_data[reg].offset; - if (registerData[reg].size == 2) + if (ni_660x_reg_data[reg].size == 2) writew(bits, dev->mmio + addr); else writel(bits, dev->mmio + addr); @@ -576,9 +576,9 @@ static inline unsigned ni_660x_read_register(struct comedi_device *dev, unsigned chip, enum ni_660x_register reg) { - unsigned int addr = GPCT_OFFSET[chip] + registerData[reg].offset; + unsigned int addr = GPCT_OFFSET[chip] + ni_660x_reg_data[reg].offset; - if (registerData[reg].size == 2) + if (ni_660x_reg_data[reg].size == 2) return readw(dev->mmio + addr); return readl(dev->mmio + addr); } -- cgit v1.2.3 From 01ead0ded315d660b07baccb68ca36c2a7f3da0a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:16 -0700 Subject: staging: comedi: ni_660x: cleanup the NI660X_IO_CFG register helpers Convert the inline functions used to set the bits in the NI600X_IO_CFG registers into macros. Also convert the enum ni_660x_pfi_output_select into defines. This clarifies the association with the register. This also fixes a number of checkpatch.pl issues about: WARNING: Prefer 'unsigned int' to bare use of 'unsigned' Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 81 +++++++++++--------------------- 1 file changed, 28 insertions(+), 53 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index d76a5b026b91..75c60322a05d 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -156,14 +156,15 @@ enum ni_660x_register { NI660X_NUM_REGS, }; -#define NI660X_IO_CFG(x) (NI660X_IO_CFG_0_1 + ((x) / 2)) - -enum ni_660x_pfi_output_select { - pfi_output_select_high_Z = 0, - pfi_output_select_counter = 1, - pfi_output_select_do = 2, - num_pfi_output_selects -}; +#define NI660X_IO_CFG(x) (NI660X_IO_CFG_0_1 + ((x) / 2)) +#define NI660X_IO_CFG_OUT_SEL(_c, _s) (((_s) & 0x3) << (((_c) % 2) ? 0 : 8)) +#define NI660X_IO_CFG_OUT_SEL_MASK(_c) NI660X_IO_CFG_OUT_SEL((_c), 0x3) +#define NI660X_IO_CFG_OUT_SEL_HIGH_Z 0 +#define NI660X_IO_CFG_OUT_SEL_COUNTER 1 +#define NI660X_IO_CFG_OUT_SEL_DO 2 +#define NI660X_IO_CFG_OUT_SEL_MAX 3 +#define NI660X_IO_CFG_IN_SEL(_c, _s) (((_s) & 0x7) << (((_c) % 2) ? 4 : 12)) +#define NI660X_IO_CFG_IN_SEL_MASK(_c) NI660X_IO_CFG_IN_SEL((_c), 0x7) enum ni_660x_subdevices { NI_660X_DIO_SUBDEV = 1, @@ -285,34 +286,6 @@ enum clock_config_register_bits { CounterSwap = 0x1 << 21 }; -/* ioconfigreg */ -static inline unsigned ioconfig_bitshift(unsigned pfi_channel) -{ - return (pfi_channel % 2) ? 0 : 8; -} - -static inline unsigned pfi_output_select_mask(unsigned pfi_channel) -{ - return 0x3 << ioconfig_bitshift(pfi_channel); -} - -static inline unsigned pfi_output_select_bits(unsigned pfi_channel, - unsigned output_select) -{ - return (output_select & 0x3) << ioconfig_bitshift(pfi_channel); -} - -static inline unsigned pfi_input_select_mask(unsigned pfi_channel) -{ - return 0x7 << (4 + ioconfig_bitshift(pfi_channel)); -} - -static inline unsigned pfi_input_select_bits(unsigned pfi_channel, - unsigned input_select) -{ - return (input_select & 0x7) << (4 + ioconfig_bitshift(pfi_channel)); -} - /* dma configuration register bits */ static inline unsigned dma_select_mask(unsigned dma_channel) { @@ -808,7 +781,7 @@ static int ni_660x_allocate_private(struct comedi_device *dev) spin_lock_init(&devpriv->interrupt_lock); spin_lock_init(&devpriv->soft_reg_copy_lock); for (i = 0; i < NUM_PFI_CHANNELS; ++i) - devpriv->pfi_output_selects[i] = pfi_output_select_counter; + devpriv->pfi_output_selects[i] = NI660X_IO_CFG_OUT_SEL_COUNTER; return 0; } @@ -896,7 +869,7 @@ static void ni_660x_select_pfi_output(struct comedi_device *dev, unsigned idle_bits; if (board->n_chips > 1) { - if (output_select == pfi_output_select_counter && + if (output_select == NI660X_IO_CFG_OUT_SEL_COUNTER && pfi_channel >= counter_4_7_first_pfi && pfi_channel <= counter_4_7_last_pfi) { active_chipset = 1; @@ -911,10 +884,10 @@ static void ni_660x_select_pfi_output(struct comedi_device *dev, idle_bits = ni_660x_read_register(dev, idle_chipset, NI660X_IO_CFG(pfi_channel)); - idle_bits &= ~pfi_output_select_mask(pfi_channel); + idle_bits &= ~NI660X_IO_CFG_OUT_SEL_MASK(pfi_channel); idle_bits |= - pfi_output_select_bits(pfi_channel, - pfi_output_select_high_Z); + NI660X_IO_CFG_OUT_SEL(pfi_channel, + NI660X_IO_CFG_OUT_SEL_HIGH_Z); ni_660x_write_register(dev, idle_chipset, idle_bits, NI660X_IO_CFG(pfi_channel)); } @@ -922,8 +895,8 @@ static void ni_660x_select_pfi_output(struct comedi_device *dev, active_bits = ni_660x_read_register(dev, active_chipset, NI660X_IO_CFG(pfi_channel)); - active_bits &= ~pfi_output_select_mask(pfi_channel); - active_bits |= pfi_output_select_bits(pfi_channel, output_select); + active_bits &= ~NI660X_IO_CFG_OUT_SEL_MASK(pfi_channel); + active_bits |= NI660X_IO_CFG_OUT_SEL(pfi_channel, output_select); ni_660x_write_register(dev, active_chipset, active_bits, NI660X_IO_CFG(pfi_channel)); } @@ -933,15 +906,15 @@ static int ni_660x_set_pfi_routing(struct comedi_device *dev, unsigned chan, { struct ni_660x_private *devpriv = dev->private; - if (source > num_pfi_output_selects) + if (source > NI660X_IO_CFG_OUT_SEL_MAX) return -EINVAL; - if (source == pfi_output_select_high_Z) + if (source == NI660X_IO_CFG_OUT_SEL_HIGH_Z) return -EINVAL; if (chan < min_counter_pfi_chan) { - if (source == pfi_output_select_counter) + if (source == NI660X_IO_CFG_OUT_SEL_COUNTER) return -EINVAL; } else if (chan > max_dio_pfi_chan) { - if (source == pfi_output_select_do) + if (source == NI660X_IO_CFG_OUT_SEL_DO) return -EINVAL; } @@ -972,7 +945,8 @@ static int ni_660x_dio_insn_config(struct comedi_device *dev, case INSN_CONFIG_DIO_INPUT: devpriv->pfi_direction_bits &= ~bit; - ni_660x_select_pfi_output(dev, chan, pfi_output_select_high_Z); + ni_660x_select_pfi_output(dev, chan, + NI660X_IO_CFG_OUT_SEL_HIGH_Z); break; case INSN_CONFIG_DIO_QUERY: @@ -992,8 +966,8 @@ static int ni_660x_dio_insn_config(struct comedi_device *dev, case INSN_CONFIG_FILTER: val = ni_660x_read_register(dev, 0, NI660X_IO_CFG(chan)); - val &= ~pfi_input_select_mask(chan); - val |= pfi_input_select_bits(chan, data[1]); + val &= ~NI660X_IO_CFG_IN_SEL_MASK(chan); + val |= NI660X_IO_CFG_IN_SEL(chan, data[1]); ni_660x_write_register(dev, 0, val, NI660X_IO_CFG(chan)); break; @@ -1108,11 +1082,12 @@ static int ni_660x_auto_attach(struct comedi_device *dev, for (i = 0; i < NUM_PFI_CHANNELS; ++i) { if (i < min_counter_pfi_chan) - ni_660x_set_pfi_routing(dev, i, pfi_output_select_do); + ni_660x_set_pfi_routing(dev, i, + NI660X_IO_CFG_OUT_SEL_DO); else ni_660x_set_pfi_routing(dev, i, - pfi_output_select_counter); - ni_660x_select_pfi_output(dev, i, pfi_output_select_high_Z); + NI660X_IO_CFG_OUT_SEL_COUNTER); + ni_660x_select_pfi_output(dev, i, NI660X_IO_CFG_OUT_SEL_HIGH_Z); } /* to be safe, set counterswap bits on tio chips after all the counter outputs have been set to high impedance mode */ -- cgit v1.2.3 From aa36af205e4e7fd94842be73c1f8a5bb5b12d302 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:17 -0700 Subject: staging: comedi: ni_660x: tidy up multi-line comment Reformat the multi-line comment in the kernel CodingStyle. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 75c60322a05d..ab761aa040d7 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -1,17 +1,16 @@ /* - comedi/drivers/ni_660x.c - Hardware driver for NI 660x devices - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -*/ + * Hardware driver for NI 660x devices + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ /* * Driver: ni_660x -- cgit v1.2.3 From 502552e161aee965026f9b5cc0da3dfb3775a8c7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:18 -0700 Subject: staging: comedi: ni_660x: remove enum clock_config_register_bits Remove this enum and add a define for the bit. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index ab761aa040d7..30089cd7f89b 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -155,6 +155,8 @@ enum ni_660x_register { NI660X_NUM_REGS, }; +#define NI660X_CLK_CFG_COUNTER_SWAP BIT(21) + #define NI660X_IO_CFG(x) (NI660X_IO_CFG_0_1 + ((x) / 2)) #define NI660X_IO_CFG_OUT_SEL(_c, _s) (((_s) & 0x3) << (((_c) % 2) ? 0 : 8)) #define NI660X_IO_CFG_OUT_SEL_MASK(_c) NI660X_IO_CFG_OUT_SEL((_c), 0x3) @@ -280,11 +282,6 @@ static const struct ni_660x_register_data ni_660x_reg_data[NI660X_NUM_REGS] = { [NI660X_IO_CFG_38_39] = { 0x7a2, 2 } /* read/write */ }; -/* kind of ENABLE for the second counter */ -enum clock_config_register_bits { - CounterSwap = 0x1 << 21 -}; - /* dma configuration register bits */ static inline unsigned dma_select_mask(unsigned dma_channel) { @@ -704,7 +701,7 @@ static void set_tio_counterswap(struct comedi_device *dev, int chip) * first chip. */ if (chip) - bits = CounterSwap; + bits = NI660X_CLK_CFG_COUNTER_SWAP; ni_660x_write_register(dev, chip, bits, NI660X_CLK_CFG); } -- cgit v1.2.3 From fecf4cce0021aebd587f7bbd970806c24988ef26 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:19 -0700 Subject: staging: comedi: ni_660x: cleanup the NI660X_DMA_CFG register helpers The BUG_ON() checks in the helper functions are not necessary. The mite driver quiries the PCI chip to determine the number of DMA channels. This is then used when a DMA channel is requested so the channel will always be in range. Convert the inline functions used to set the bits in the NI600X_DMA_CFG register into macros. Also convert the associated enum dma_selection. This clarifies the association with the register. Rename the associated 'dma_configuration_soft_copies' member of the private data to allow shorting some of the ugly long lines in the driver. This also fixes a number of checkpatch.pl issues about: WARNING: Prefer 'unsigned int' to bare use of 'unsigned' Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 63 ++++++++++---------------------- 1 file changed, 19 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 30089cd7f89b..0b37982f021e 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -157,6 +157,11 @@ enum ni_660x_register { #define NI660X_CLK_CFG_COUNTER_SWAP BIT(21) +#define NI660X_DMA_CFG_SEL(_c, _s) (((_s) & 0x1f) << (8 * (_c))) +#define NI660X_DMA_CFG_SEL_MASK(_c) NI660X_DMA_CFG_SEL((_c), 0x1f) +#define NI660X_DMA_CFG_SEL_NONE(_c) NI660X_DMA_CFG_SEL((_c), 0x1f) +#define NI660X_DMA_CFG_RESET(_c) NI660X_DMA_CFG_SEL((_c), 0x80) + #define NI660X_IO_CFG(x) (NI660X_IO_CFG_0_1 + ((x) / 2)) #define NI660X_IO_CFG_OUT_SEL(_c, _s) (((_s) & 0x3) << (((_c) % 2) ? 0 : 8)) #define NI660X_IO_CFG_OUT_SEL_MASK(_c) NI660X_IO_CFG_OUT_SEL((_c), 0x3) @@ -282,29 +287,6 @@ static const struct ni_660x_register_data ni_660x_reg_data[NI660X_NUM_REGS] = { [NI660X_IO_CFG_38_39] = { 0x7a2, 2 } /* read/write */ }; -/* dma configuration register bits */ -static inline unsigned dma_select_mask(unsigned dma_channel) -{ - BUG_ON(dma_channel >= MAX_DMA_CHANNEL); - return 0x1f << (8 * dma_channel); -} - -enum dma_selection { - dma_selection_none = 0x1f, -}; - -static inline unsigned dma_select_bits(unsigned dma_channel, unsigned selection) -{ - BUG_ON(dma_channel >= MAX_DMA_CHANNEL); - return (selection << (8 * dma_channel)) & dma_select_mask(dma_channel); -} - -static inline unsigned dma_reset_bit(unsigned dma_channel) -{ - BUG_ON(dma_channel >= MAX_DMA_CHANNEL); - return 0x80 << (8 * dma_channel); -} - enum global_interrupt_status_register_bits { Counter_0_Int_Bit = 0x100, Counter_1_Int_Bit = 0x200, @@ -372,7 +354,7 @@ struct ni_660x_private { spinlock_t mite_channel_lock; /* interrupt_lock prevents races between interrupt and comedi_poll */ spinlock_t interrupt_lock; - unsigned dma_configuration_soft_copies[NI_660X_MAX_NUM_CHIPS]; + unsigned dma_cfg[NI_660X_MAX_NUM_CHIPS]; spinlock_t soft_reg_copy_lock; unsigned short pfi_output_selects[NUM_PFI_CHANNELS]; }; @@ -591,13 +573,12 @@ static inline void ni_660x_set_dma_channel(struct comedi_device *dev, unsigned long flags; spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags); - devpriv->dma_configuration_soft_copies[chip] &= - ~dma_select_mask(mite_channel); - devpriv->dma_configuration_soft_copies[chip] |= - dma_select_bits(mite_channel, counter->counter_index); - ni_660x_write_register(dev, chip, - devpriv->dma_configuration_soft_copies[chip] | - dma_reset_bit(mite_channel), NI660X_DMA_CFG); + devpriv->dma_cfg[chip] &= ~NI660X_DMA_CFG_SEL_MASK(mite_channel); + devpriv->dma_cfg[chip] |= NI660X_DMA_CFG_SEL(mite_channel, + counter->counter_index); + ni_660x_write_register(dev, chip, devpriv->dma_cfg[chip] | + NI660X_DMA_CFG_RESET(mite_channel), + NI660X_DMA_CFG); mmiowb(); spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags); } @@ -611,12 +592,9 @@ static inline void ni_660x_unset_dma_channel(struct comedi_device *dev, unsigned long flags; spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags); - devpriv->dma_configuration_soft_copies[chip] &= - ~dma_select_mask(mite_channel); - devpriv->dma_configuration_soft_copies[chip] |= - dma_select_bits(mite_channel, dma_selection_none); - ni_660x_write_register(dev, chip, - devpriv->dma_configuration_soft_copies[chip], + devpriv->dma_cfg[chip] &= ~NI660X_DMA_CFG_SEL_MASK(mite_channel); + devpriv->dma_cfg[chip] |= NI660X_DMA_CFG_SEL_NONE(mite_channel); + ni_660x_write_register(dev, chip, devpriv->dma_cfg[chip], NI660X_DMA_CFG); mmiowb(); spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags); @@ -819,13 +797,10 @@ static void init_tio_chip(struct comedi_device *dev, int chipset) unsigned i; /* init dma configuration register */ - devpriv->dma_configuration_soft_copies[chipset] = 0; - for (i = 0; i < MAX_DMA_CHANNEL; ++i) { - devpriv->dma_configuration_soft_copies[chipset] |= - dma_select_bits(i, dma_selection_none) & dma_select_mask(i); - } - ni_660x_write_register(dev, chipset, - devpriv->dma_configuration_soft_copies[chipset], + devpriv->dma_cfg[chipset] = 0; + for (i = 0; i < MAX_DMA_CHANNEL; ++i) + devpriv->dma_cfg[chipset] |= NI660X_DMA_CFG_SEL_NONE(i); + ni_660x_write_register(dev, chipset, devpriv->dma_cfg[chipset], NI660X_DMA_CFG); for (i = 0; i < NUM_PFI_CHANNELS; ++i) ni_660x_write_register(dev, chipset, 0, NI660X_IO_CFG(i)); -- cgit v1.2.3 From 41014593caebadec2f022d96d3326816599d439d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:20 -0700 Subject: staging: comedi: ni_660x: cleanup the NI660X_GLOBAL_INT_{STATUS, CFG} Remove the enums global_interrupt_{status,config}_register_bits and add defines for the CamelCase values. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 0b37982f021e..773147af4137 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -157,6 +157,14 @@ enum ni_660x_register { #define NI660X_CLK_CFG_COUNTER_SWAP BIT(21) +#define NI660X_GLOBAL_INT_COUNTER0 BIT(8) +#define NI660X_GLOBAL_INT_COUNTER1 BIT(9) +#define NI660X_GLOBAL_INT_COUNTER2 BIT(10) +#define NI660X_GLOBAL_INT_COUNTER3 BIT(11) +#define NI660X_GLOBAL_INT_CASCADE BIT(29) +#define NI660X_GLOBAL_INT_GLOBAL_POL BIT(30) +#define NI660X_GLOBAL_INT_GLOBAL BIT(31) + #define NI660X_DMA_CFG_SEL(_c, _s) (((_s) & 0x1f) << (8 * (_c))) #define NI660X_DMA_CFG_SEL_MASK(_c) NI660X_DMA_CFG_SEL((_c), 0x1f) #define NI660X_DMA_CFG_SEL_NONE(_c) NI660X_DMA_CFG_SEL((_c), 0x1f) @@ -287,21 +295,6 @@ static const struct ni_660x_register_data ni_660x_reg_data[NI660X_NUM_REGS] = { [NI660X_IO_CFG_38_39] = { 0x7a2, 2 } /* read/write */ }; -enum global_interrupt_status_register_bits { - Counter_0_Int_Bit = 0x100, - Counter_1_Int_Bit = 0x200, - Counter_2_Int_Bit = 0x400, - Counter_3_Int_Bit = 0x800, - Cascade_Int_Bit = 0x20000000, - Global_Int_Bit = 0x80000000 -}; - -enum global_interrupt_config_register_bits { - Cascade_Int_Enable_Bit = 0x20000000, - Global_Int_Polarity_Bit = 0x40000000, - Global_Int_Enable_Bit = 0x80000000 -}; - /* Offset of the GPCT chips from the base-address of the card */ /* First chip is at base-address + 0x00, etc. */ static const unsigned GPCT_OFFSET[2] = { 0x0, 0x800 }; @@ -1072,9 +1065,9 @@ static int ni_660x_auto_attach(struct comedi_device *dev, return ret; } dev->irq = pcidev->irq; - global_interrupt_config_bits = Global_Int_Enable_Bit; + global_interrupt_config_bits = NI660X_GLOBAL_INT_GLOBAL; if (board->n_chips > 1) - global_interrupt_config_bits |= Cascade_Int_Enable_Bit; + global_interrupt_config_bits |= NI660X_GLOBAL_INT_CASCADE; ni_660x_write_register(dev, 0, global_interrupt_config_bits, NI660X_GLOBAL_INT_CFG); -- cgit v1.2.3 From 9678b73e273abcd5ab13b7ecc44521f501529ca4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:21 -0700 Subject: staging: comedi: ni_660x: tidy up ni_660x_write_register() Rename this function to help shorten some of the long lines. Remove the inline, let the compiler figure it out. Change the 'unsigned' parameters to 'unsigned int' to fix the checkpatch.pl issues: WARNING: Prefer 'unsigned int' to bare use of 'unsigned' Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 42 +++++++++++++++----------------- 1 file changed, 20 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 773147af4137..aa40ab6f02fa 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -504,9 +504,9 @@ static enum ni_660x_register ni_gpct_to_660x_register(enum ni_gpct_register reg) } } -static inline void ni_660x_write_register(struct comedi_device *dev, - unsigned chip, unsigned bits, - enum ni_660x_register reg) +static void ni_660x_write(struct comedi_device *dev, + unsigned int chip, unsigned int bits, + enum ni_660x_register reg) { unsigned int addr = GPCT_OFFSET[chip] + ni_660x_reg_data[reg].offset; @@ -534,7 +534,7 @@ static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits, enum ni_660x_register ni_660x_register = ni_gpct_to_660x_register(reg); unsigned chip = counter->chip_index; - ni_660x_write_register(dev, chip, bits, ni_660x_register); + ni_660x_write(dev, chip, bits, ni_660x_register); } static unsigned ni_gpct_read_register(struct ni_gpct *counter, @@ -569,9 +569,9 @@ static inline void ni_660x_set_dma_channel(struct comedi_device *dev, devpriv->dma_cfg[chip] &= ~NI660X_DMA_CFG_SEL_MASK(mite_channel); devpriv->dma_cfg[chip] |= NI660X_DMA_CFG_SEL(mite_channel, counter->counter_index); - ni_660x_write_register(dev, chip, devpriv->dma_cfg[chip] | - NI660X_DMA_CFG_RESET(mite_channel), - NI660X_DMA_CFG); + ni_660x_write(dev, chip, devpriv->dma_cfg[chip] | + NI660X_DMA_CFG_RESET(mite_channel), + NI660X_DMA_CFG); mmiowb(); spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags); } @@ -587,8 +587,7 @@ static inline void ni_660x_unset_dma_channel(struct comedi_device *dev, spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags); devpriv->dma_cfg[chip] &= ~NI660X_DMA_CFG_SEL_MASK(mite_channel); devpriv->dma_cfg[chip] |= NI660X_DMA_CFG_SEL_NONE(mite_channel); - ni_660x_write_register(dev, chip, devpriv->dma_cfg[chip], - NI660X_DMA_CFG); + ni_660x_write(dev, chip, devpriv->dma_cfg[chip], NI660X_DMA_CFG); mmiowb(); spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags); } @@ -674,7 +673,7 @@ static void set_tio_counterswap(struct comedi_device *dev, int chip) if (chip) bits = NI660X_CLK_CFG_COUNTER_SWAP; - ni_660x_write_register(dev, chip, bits, NI660X_CLK_CFG); + ni_660x_write(dev, chip, bits, NI660X_CLK_CFG); } static void ni_660x_handle_gpct_interrupt(struct comedi_device *dev, @@ -793,10 +792,9 @@ static void init_tio_chip(struct comedi_device *dev, int chipset) devpriv->dma_cfg[chipset] = 0; for (i = 0; i < MAX_DMA_CHANNEL; ++i) devpriv->dma_cfg[chipset] |= NI660X_DMA_CFG_SEL_NONE(i); - ni_660x_write_register(dev, chipset, devpriv->dma_cfg[chipset], - NI660X_DMA_CFG); + ni_660x_write(dev, chipset, devpriv->dma_cfg[chipset], NI660X_DMA_CFG); for (i = 0; i < NUM_PFI_CHANNELS; ++i) - ni_660x_write_register(dev, chipset, 0, NI660X_IO_CFG(i)); + ni_660x_write(dev, chipset, 0, NI660X_IO_CFG(i)); } static int ni_660x_dio_insn_bits(struct comedi_device *dev, @@ -810,7 +808,7 @@ static int ni_660x_dio_insn_bits(struct comedi_device *dev, s->state &= ~(data[0] << base_bitfield_channel); s->state |= (data[0] & data[1]) << base_bitfield_channel; /* Write out the new digital output lines */ - ni_660x_write_register(dev, 0, s->state, NI660X_DIO32_OUTPUT); + ni_660x_write(dev, 0, s->state, NI660X_DIO32_OUTPUT); } /* on return, data[1] contains the value of the digital * input and output lines. */ @@ -852,8 +850,8 @@ static void ni_660x_select_pfi_output(struct comedi_device *dev, idle_bits |= NI660X_IO_CFG_OUT_SEL(pfi_channel, NI660X_IO_CFG_OUT_SEL_HIGH_Z); - ni_660x_write_register(dev, idle_chipset, idle_bits, - NI660X_IO_CFG(pfi_channel)); + ni_660x_write(dev, idle_chipset, idle_bits, + NI660X_IO_CFG(pfi_channel)); } active_bits = @@ -861,8 +859,8 @@ static void ni_660x_select_pfi_output(struct comedi_device *dev, NI660X_IO_CFG(pfi_channel)); active_bits &= ~NI660X_IO_CFG_OUT_SEL_MASK(pfi_channel); active_bits |= NI660X_IO_CFG_OUT_SEL(pfi_channel, output_select); - ni_660x_write_register(dev, active_chipset, active_bits, - NI660X_IO_CFG(pfi_channel)); + ni_660x_write(dev, active_chipset, active_bits, + NI660X_IO_CFG(pfi_channel)); } static int ni_660x_set_pfi_routing(struct comedi_device *dev, unsigned chan, @@ -932,7 +930,7 @@ static int ni_660x_dio_insn_config(struct comedi_device *dev, val = ni_660x_read_register(dev, 0, NI660X_IO_CFG(chan)); val &= ~NI660X_IO_CFG_IN_SEL_MASK(chan); val |= NI660X_IO_CFG_IN_SEL(chan, data[1]); - ni_660x_write_register(dev, 0, val, NI660X_IO_CFG(chan)); + ni_660x_write(dev, 0, val, NI660X_IO_CFG(chan)); break; default: @@ -1000,7 +998,7 @@ static int ni_660x_auto_attach(struct comedi_device *dev, s->insn_config = ni_660x_dio_insn_config; /* we use the ioconfig registers to control dio direction, so zero output enables in stc dio control reg */ - ni_660x_write_register(dev, 0, 0, NI660X_STC_DIO_CONTROL); + ni_660x_write(dev, 0, 0, NI660X_STC_DIO_CONTROL); devpriv->counter_dev = ni_gpct_device_construct(dev, &ni_gpct_write_register, @@ -1068,8 +1066,8 @@ static int ni_660x_auto_attach(struct comedi_device *dev, global_interrupt_config_bits = NI660X_GLOBAL_INT_GLOBAL; if (board->n_chips > 1) global_interrupt_config_bits |= NI660X_GLOBAL_INT_CASCADE; - ni_660x_write_register(dev, 0, global_interrupt_config_bits, - NI660X_GLOBAL_INT_CFG); + ni_660x_write(dev, 0, global_interrupt_config_bits, + NI660X_GLOBAL_INT_CFG); return 0; } -- cgit v1.2.3 From ad98c18cb9de633d1023114842d1e895766b99b2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:22 -0700 Subject: staging: comedi: ni_660x: tidy up ni_660x_read_register() Rename this function to help shorten some of the long lines. Remove the inline, let the compiler figure it out. Change the 'unsigned' parameters to 'unsigned int' to fix the checkpatch.pl issues: WARNING: Prefer 'unsigned int' to bare use of 'unsigned' Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index aa40ab6f02fa..cd101bb66bad 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -516,9 +516,9 @@ static void ni_660x_write(struct comedi_device *dev, writel(bits, dev->mmio + addr); } -static inline unsigned ni_660x_read_register(struct comedi_device *dev, - unsigned chip, - enum ni_660x_register reg) +static unsigned int ni_660x_read(struct comedi_device *dev, + unsigned int chip, + enum ni_660x_register reg) { unsigned int addr = GPCT_OFFSET[chip] + ni_660x_reg_data[reg].offset; @@ -544,7 +544,7 @@ static unsigned ni_gpct_read_register(struct ni_gpct *counter, enum ni_660x_register ni_660x_register = ni_gpct_to_660x_register(reg); unsigned chip = counter->chip_index; - return ni_660x_read_register(dev, chip, ni_660x_register); + return ni_660x_read(dev, chip, ni_660x_register); } static inline struct mite_dma_descriptor_ring *mite_ring(struct ni_660x_private @@ -812,7 +812,7 @@ static int ni_660x_dio_insn_bits(struct comedi_device *dev, } /* on return, data[1] contains the value of the digital * input and output lines. */ - data[1] = (ni_660x_read_register(dev, 0, NI660X_DIO32_INPUT) >> + data[1] = (ni_660x_read(dev, 0, NI660X_DIO32_INPUT) >> base_bitfield_channel); return insn->n; @@ -843,9 +843,8 @@ static void ni_660x_select_pfi_output(struct comedi_device *dev, } if (idle_chipset != active_chipset) { - idle_bits = - ni_660x_read_register(dev, idle_chipset, - NI660X_IO_CFG(pfi_channel)); + idle_bits = ni_660x_read(dev, idle_chipset, + NI660X_IO_CFG(pfi_channel)); idle_bits &= ~NI660X_IO_CFG_OUT_SEL_MASK(pfi_channel); idle_bits |= NI660X_IO_CFG_OUT_SEL(pfi_channel, @@ -854,9 +853,8 @@ static void ni_660x_select_pfi_output(struct comedi_device *dev, NI660X_IO_CFG(pfi_channel)); } - active_bits = - ni_660x_read_register(dev, active_chipset, - NI660X_IO_CFG(pfi_channel)); + active_bits = ni_660x_read(dev, active_chipset, + NI660X_IO_CFG(pfi_channel)); active_bits &= ~NI660X_IO_CFG_OUT_SEL_MASK(pfi_channel); active_bits |= NI660X_IO_CFG_OUT_SEL(pfi_channel, output_select); ni_660x_write(dev, active_chipset, active_bits, @@ -927,7 +925,7 @@ static int ni_660x_dio_insn_config(struct comedi_device *dev, break; case INSN_CONFIG_FILTER: - val = ni_660x_read_register(dev, 0, NI660X_IO_CFG(chan)); + val = ni_660x_read(dev, 0, NI660X_IO_CFG(chan)); val &= ~NI660X_IO_CFG_IN_SEL_MASK(chan); val |= NI660X_IO_CFG_IN_SEL(chan, data[1]); ni_660x_write(dev, 0, val, NI660X_IO_CFG(chan)); -- cgit v1.2.3 From dc285820cc19a666aea45ac74e9737c2afcf8189 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:23 -0700 Subject: staging: comedi: ni_660x: tidy up ni_gpct_{write, read}_register() Rename these functions so they have namespace associated with the driver. Fix the checkpatch.pl issues: WARNING: Prefer 'unsigned int' to bare use of 'unsigned' Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index cd101bb66bad..e0532f4d6bc7 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -527,24 +527,22 @@ static unsigned int ni_660x_read(struct comedi_device *dev, return readl(dev->mmio + addr); } -static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits, - enum ni_gpct_register reg) +static void ni_660x_gpct_write(struct ni_gpct *counter, unsigned int bits, + enum ni_gpct_register reg) { struct comedi_device *dev = counter->counter_dev->dev; enum ni_660x_register ni_660x_register = ni_gpct_to_660x_register(reg); - unsigned chip = counter->chip_index; - ni_660x_write(dev, chip, bits, ni_660x_register); + ni_660x_write(dev, counter->chip_index, bits, ni_660x_register); } -static unsigned ni_gpct_read_register(struct ni_gpct *counter, +static unsigned int ni_660x_gpct_read(struct ni_gpct *counter, enum ni_gpct_register reg) { struct comedi_device *dev = counter->counter_dev->dev; enum ni_660x_register ni_660x_register = ni_gpct_to_660x_register(reg); - unsigned chip = counter->chip_index; - return ni_660x_read(dev, chip, ni_660x_register); + return ni_660x_read(dev, counter->chip_index, ni_660x_register); } static inline struct mite_dma_descriptor_ring *mite_ring(struct ni_660x_private @@ -999,8 +997,8 @@ static int ni_660x_auto_attach(struct comedi_device *dev, ni_660x_write(dev, 0, 0, NI660X_STC_DIO_CONTROL); devpriv->counter_dev = ni_gpct_device_construct(dev, - &ni_gpct_write_register, - &ni_gpct_read_register, + ni_660x_gpct_write, + ni_660x_gpct_read, ni_gpct_variant_660x, ni_660x_num_counters (dev)); -- cgit v1.2.3 From 518d38423b48ad23b2f4b13dd9a027aa37423f1d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:24 -0700 Subject: staging: comedi: ni_660x: tidy up ni_660x_select_pfi_output() Tidy up this function to fix the checkpatch.pl issues: WARNING: Prefer 'unsigned int' to bare use of 'unsigned' For aesthetics, remove the static const local variables. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 54 ++++++++++++++------------------ 1 file changed, 24 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index e0532f4d6bc7..79678af8e02c 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -817,46 +817,40 @@ static int ni_660x_dio_insn_bits(struct comedi_device *dev, } static void ni_660x_select_pfi_output(struct comedi_device *dev, - unsigned pfi_channel, - unsigned output_select) + unsigned int chan, unsigned int out_sel) { const struct ni_660x_board *board = dev->board_ptr; - static const unsigned counter_4_7_first_pfi = 8; - static const unsigned counter_4_7_last_pfi = 23; - unsigned active_chipset = 0; - unsigned idle_chipset = 0; - unsigned active_bits; - unsigned idle_bits; + unsigned int active_chip = 0; + unsigned int idle_chip = 0; + unsigned int bits; if (board->n_chips > 1) { - if (output_select == NI660X_IO_CFG_OUT_SEL_COUNTER && - pfi_channel >= counter_4_7_first_pfi && - pfi_channel <= counter_4_7_last_pfi) { - active_chipset = 1; - idle_chipset = 0; + if (out_sel == NI660X_IO_CFG_OUT_SEL_COUNTER && + chan >= 8 && chan <= 23) { + /* counters 4-7 pfi channels */ + active_chip = 1; + idle_chip = 0; } else { - active_chipset = 0; - idle_chipset = 1; + /* counters 0-3 pfi channels */ + active_chip = 0; + idle_chip = 1; } } - if (idle_chipset != active_chipset) { - idle_bits = ni_660x_read(dev, idle_chipset, - NI660X_IO_CFG(pfi_channel)); - idle_bits &= ~NI660X_IO_CFG_OUT_SEL_MASK(pfi_channel); - idle_bits |= - NI660X_IO_CFG_OUT_SEL(pfi_channel, - NI660X_IO_CFG_OUT_SEL_HIGH_Z); - ni_660x_write(dev, idle_chipset, idle_bits, - NI660X_IO_CFG(pfi_channel)); + if (idle_chip != active_chip) { + /* set the pfi channel to high-z on the inactive chip */ + bits = ni_660x_read(dev, idle_chip, NI660X_IO_CFG(chan)); + bits &= ~NI660X_IO_CFG_OUT_SEL_MASK(chan); + bits |= NI660X_IO_CFG_OUT_SEL(chan, + NI660X_IO_CFG_OUT_SEL_HIGH_Z); + ni_660x_write(dev, idle_chip, bits, NI660X_IO_CFG(chan)); } - active_bits = ni_660x_read(dev, active_chipset, - NI660X_IO_CFG(pfi_channel)); - active_bits &= ~NI660X_IO_CFG_OUT_SEL_MASK(pfi_channel); - active_bits |= NI660X_IO_CFG_OUT_SEL(pfi_channel, output_select); - ni_660x_write(dev, active_chipset, active_bits, - NI660X_IO_CFG(pfi_channel)); + /* set the pfi channel output on the active chip */ + bits = ni_660x_read(dev, active_chip, NI660X_IO_CFG(chan)); + bits &= ~NI660X_IO_CFG_OUT_SEL_MASK(chan); + bits |= NI660X_IO_CFG_OUT_SEL(chan, out_sel); + ni_660x_write(dev, active_chip, bits, NI660X_IO_CFG(chan)); } static int ni_660x_set_pfi_routing(struct comedi_device *dev, unsigned chan, -- cgit v1.2.3 From ff1e71be56d6c493084eac86afa0aeb59bca9c53 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:25 -0700 Subject: staging: comedi: ni_660x: remove BUG_ON() in ni_660x_request_mite_channel() This BUG_ON() happens if a mite DMA channel is already requested when an ansynchronous command is started for one of the counter subdevices. The comedi core will only call the (*do_cmd) if the subdevice is not busy. In this driver, the (*cancel) for the subdevice will always release any requested mite DMA channel. Remove the BUG_ON() which can never occur. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 79678af8e02c..232c89767da8 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -599,7 +599,6 @@ static int ni_660x_request_mite_channel(struct comedi_device *dev, struct mite_channel *mite_chan; spin_lock_irqsave(&devpriv->mite_channel_lock, flags); - BUG_ON(counter->mite_chan); mite_chan = mite_request_channel(devpriv->mite, mite_ring(devpriv, counter)); if (!mite_chan) { -- cgit v1.2.3 From 6d40805b0b4e4392e68fea0028edcafa5fcdc04a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:26 -0700 Subject: staging: comedi: ni_660x: fix block comment issues Fix the checkpatch.pl issues about: WARNING: Block comments use * on subsequent lines WARNING: Block comments use a trailing */ on a separate line Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 232c89767da8..018349707947 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -48,8 +48,7 @@ enum ni_660x_constants { }; #define NUM_PFI_CHANNELS 40 -/* really there are only up to 3 dma channels, but the register layout allows -for 4 */ +/* there are only up to 3 dma channels, but the register layout allows for 4 */ #define MAX_DMA_CHANNEL 4 /* See Register-Level Programmer Manual page 3.1 */ @@ -985,8 +984,11 @@ static int ni_660x_auto_attach(struct comedi_device *dev, s->range_table = &range_digital; s->insn_bits = ni_660x_dio_insn_bits; s->insn_config = ni_660x_dio_insn_config; - /* we use the ioconfig registers to control dio direction, so zero - output enables in stc dio control reg */ + + /* + * We use the ioconfig registers to control dio direction, so zero + * output enables in stc dio control reg. + */ ni_660x_write(dev, 0, 0, NI660X_STC_DIO_CONTROL); devpriv->counter_dev = ni_gpct_device_construct(dev, @@ -1040,8 +1042,11 @@ static int ni_660x_auto_attach(struct comedi_device *dev, NI660X_IO_CFG_OUT_SEL_COUNTER); ni_660x_select_pfi_output(dev, i, NI660X_IO_CFG_OUT_SEL_HIGH_Z); } - /* to be safe, set counterswap bits on tio chips after all the counter - outputs have been set to high impedance mode */ + + /* + * To be safe, set counterswap bits on tio chips after all the counter + * outputs have been set to high impedance mode. + */ for (i = 0; i < board->n_chips; ++i) set_tio_counterswap(dev, i); -- cgit v1.2.3 From 520e61915186e0538a8fc46e5e268a2000141545 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:27 -0700 Subject: staging: comedi: ni_660x: remove enum ni_660x_subdevices Hard-coding the subdevice order is normally a bad idea. If a new subdevice is added, or removed, it could potentially break pretty badly. Remove the enum and associated NI_660X_GPCT_SUBDEV() helper that hard-code the subdevice order. Fix the (*auto_attach) so it initializes all the subdevices without depending on the hard-coded order. Change the interrupt handler so that all the counter subdevices are handled without depending on the hard-coded order. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 018349707947..595c862f236b 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -179,15 +179,6 @@ enum ni_660x_register { #define NI660X_IO_CFG_IN_SEL(_c, _s) (((_s) & 0x7) << (((_c) % 2) ? 4 : 12)) #define NI660X_IO_CFG_IN_SEL_MASK(_c) NI660X_IO_CFG_IN_SEL((_c), 0x7) -enum ni_660x_subdevices { - NI_660X_DIO_SUBDEV = 1, - NI_660X_GPCT_SUBDEV_0 = 2 -}; -static inline unsigned NI_660X_GPCT_SUBDEV(unsigned index) -{ - return NI_660X_GPCT_SUBDEV_0 + index; -} - struct ni_660x_register_data { int offset; /* Offset from base address from GPCT chip */ char size; /* 2 or 4 bytes */ @@ -694,9 +685,10 @@ static irqreturn_t ni_660x_interrupt(int irq, void *d) /* lock to avoid race with comedi_poll */ spin_lock_irqsave(&devpriv->interrupt_lock, flags); smp_mb(); - for (i = 0; i < ni_660x_num_counters(dev); ++i) { - s = &dev->subdevices[NI_660X_GPCT_SUBDEV(i)]; - ni_660x_handle_gpct_interrupt(dev, s); + for (i = 0; i < dev->n_subdevices; ++i) { + s = &dev->subdevices[i]; + if (s->type == COMEDI_SUBD_COUNTER) + ni_660x_handle_gpct_interrupt(dev, s); } spin_unlock_irqrestore(&devpriv->interrupt_lock, flags); return IRQ_HANDLED; @@ -935,6 +927,7 @@ static int ni_660x_auto_attach(struct comedi_device *dev, const struct ni_660x_board *board = NULL; struct ni_660x_private *devpriv; struct comedi_subdevice *s; + int subdev; int ret; unsigned i; unsigned global_interrupt_config_bits; @@ -971,11 +964,13 @@ static int ni_660x_auto_attach(struct comedi_device *dev, if (ret) return ret; - s = &dev->subdevices[0]; + subdev = 0; + + s = &dev->subdevices[subdev++]; /* Old GENERAL-PURPOSE COUNTER/TIME (GPCT) subdevice, no longer used */ s->type = COMEDI_SUBD_UNUSED; - s = &dev->subdevices[NI_660X_DIO_SUBDEV]; + s = &dev->subdevices[subdev++]; /* DIGITAL I/O SUBDEVICE */ s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; @@ -1000,7 +995,7 @@ static int ni_660x_auto_attach(struct comedi_device *dev, if (!devpriv->counter_dev) return -ENOMEM; for (i = 0; i < NI_660X_MAX_NUM_COUNTERS; ++i) { - s = &dev->subdevices[NI_660X_GPCT_SUBDEV(i)]; + s = &dev->subdevices[subdev++]; if (i < ni_660x_num_counters(dev)) { s->type = COMEDI_SUBD_COUNTER; s->subdev_flags = SDF_READABLE | SDF_WRITABLE | -- cgit v1.2.3 From b15f5069087128d42d2e00b6b1c666fd3ec42bfe Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:28 -0700 Subject: staging: comedi: ni_660x: remove ni_660x_num_counters() This inline function is only used by the (*auto_attach). Remove it and just use a local variable for the calculation. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 595c862f236b..6a3a12e03a21 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -342,13 +342,6 @@ struct ni_660x_private { unsigned short pfi_output_selects[NUM_PFI_CHANNELS]; }; -static inline unsigned ni_660x_num_counters(struct comedi_device *dev) -{ - const struct ni_660x_board *board = dev->board_ptr; - - return board->n_chips * counters_per_chip; -} - static enum ni_660x_register ni_gpct_to_660x_register(enum ni_gpct_register reg) { switch (reg) { @@ -927,6 +920,7 @@ static int ni_660x_auto_attach(struct comedi_device *dev, const struct ni_660x_board *board = NULL; struct ni_660x_private *devpriv; struct comedi_subdevice *s; + unsigned int n_counters; int subdev; int ret; unsigned i; @@ -986,17 +980,17 @@ static int ni_660x_auto_attach(struct comedi_device *dev, */ ni_660x_write(dev, 0, 0, NI660X_STC_DIO_CONTROL); + n_counters = board->n_chips * counters_per_chip; devpriv->counter_dev = ni_gpct_device_construct(dev, ni_660x_gpct_write, ni_660x_gpct_read, ni_gpct_variant_660x, - ni_660x_num_counters - (dev)); + n_counters); if (!devpriv->counter_dev) return -ENOMEM; for (i = 0; i < NI_660X_MAX_NUM_COUNTERS; ++i) { s = &dev->subdevices[subdev++]; - if (i < ni_660x_num_counters(dev)) { + if (i < n_counters) { s->type = COMEDI_SUBD_COUNTER; s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_CMD_READ; @@ -1025,7 +1019,7 @@ static int ni_660x_auto_attach(struct comedi_device *dev, for (i = 0; i < board->n_chips; ++i) init_tio_chip(dev, i); - for (i = 0; i < ni_660x_num_counters(dev); ++i) + for (i = 0; i < n_counters; ++i) ni_tio_init_counter(&devpriv->counter_dev->counters[i]); for (i = 0; i < NUM_PFI_CHANNELS; ++i) { -- cgit v1.2.3 From 2225320ec8cc7f99c05ff217343eb63d5319c314 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:29 -0700 Subject: staging: comedi: ni_660x: Prefer 'unsigned int' to bare use of 'unsigned' Fix the checkpatch.pl issues. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 40 ++++++++++++++++---------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 6a3a12e03a21..6ca5c67b1a80 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -299,7 +299,7 @@ enum ni_660x_boardid { struct ni_660x_board { const char *name; - unsigned n_chips; /* total number of TIO chips */ + unsigned int n_chips; /* total number of TIO chips */ }; static const struct ni_660x_board ni_660x_boards[] = { @@ -337,7 +337,7 @@ struct ni_660x_private { spinlock_t mite_channel_lock; /* interrupt_lock prevents races between interrupt and comedi_poll */ spinlock_t interrupt_lock; - unsigned dma_cfg[NI_660X_MAX_NUM_CHIPS]; + unsigned int dma_cfg[NI_660X_MAX_NUM_CHIPS]; spinlock_t soft_reg_copy_lock; unsigned short pfi_output_selects[NUM_PFI_CHANNELS]; }; @@ -533,17 +533,17 @@ static inline struct mite_dma_descriptor_ring *mite_ring(struct ni_660x_private struct ni_gpct *counter) { - unsigned chip = counter->chip_index; + unsigned int chip = counter->chip_index; return priv->mite_rings[chip][counter->counter_index]; } static inline void ni_660x_set_dma_channel(struct comedi_device *dev, - unsigned mite_channel, + unsigned int mite_channel, struct ni_gpct *counter) { struct ni_660x_private *devpriv = dev->private; - unsigned chip = counter->chip_index; + unsigned int chip = counter->chip_index; unsigned long flags; spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags); @@ -558,11 +558,11 @@ static inline void ni_660x_set_dma_channel(struct comedi_device *dev, } static inline void ni_660x_unset_dma_channel(struct comedi_device *dev, - unsigned mite_channel, + unsigned int mite_channel, struct ni_gpct *counter) { struct ni_660x_private *devpriv = dev->private; - unsigned chip = counter->chip_index; + unsigned int chip = counter->chip_index; unsigned long flags; spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags); @@ -642,7 +642,7 @@ static int ni_660x_cancel(struct comedi_device *dev, struct comedi_subdevice *s) static void set_tio_counterswap(struct comedi_device *dev, int chip) { - unsigned bits = 0; + unsigned int bits = 0; /* * See P. 3.5 of the Register-Level Programming manual. @@ -670,7 +670,7 @@ static irqreturn_t ni_660x_interrupt(int irq, void *d) struct comedi_device *dev = d; struct ni_660x_private *devpriv = dev->private; struct comedi_subdevice *s; - unsigned i; + unsigned int i; unsigned long flags; if (!dev->attached) @@ -718,7 +718,7 @@ static int ni_660x_buf_change(struct comedi_device *dev, static int ni_660x_allocate_private(struct comedi_device *dev) { struct ni_660x_private *devpriv; - unsigned i; + unsigned int i; devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) @@ -737,8 +737,8 @@ static int ni_660x_alloc_mite_rings(struct comedi_device *dev) { const struct ni_660x_board *board = dev->board_ptr; struct ni_660x_private *devpriv = dev->private; - unsigned i; - unsigned j; + unsigned int i; + unsigned int j; for (i = 0; i < board->n_chips; ++i) { for (j = 0; j < counters_per_chip; ++j) { @@ -755,8 +755,8 @@ static void ni_660x_free_mite_rings(struct comedi_device *dev) { const struct ni_660x_board *board = dev->board_ptr; struct ni_660x_private *devpriv = dev->private; - unsigned i; - unsigned j; + unsigned int i; + unsigned int j; for (i = 0; i < board->n_chips; ++i) { for (j = 0; j < counters_per_chip; ++j) @@ -767,7 +767,7 @@ static void ni_660x_free_mite_rings(struct comedi_device *dev) static void init_tio_chip(struct comedi_device *dev, int chipset) { struct ni_660x_private *devpriv = dev->private; - unsigned i; + unsigned int i; /* init dma configuration register */ devpriv->dma_cfg[chipset] = 0; @@ -782,7 +782,7 @@ static int ni_660x_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - unsigned base_bitfield_channel = CR_CHAN(insn->chanspec); + unsigned int base_bitfield_channel = CR_CHAN(insn->chanspec); /* Check if we have to write some bits */ if (data[0]) { @@ -836,8 +836,8 @@ static void ni_660x_select_pfi_output(struct comedi_device *dev, ni_660x_write(dev, active_chip, bits, NI660X_IO_CFG(chan)); } -static int ni_660x_set_pfi_routing(struct comedi_device *dev, unsigned chan, - unsigned source) +static int ni_660x_set_pfi_routing(struct comedi_device *dev, + unsigned int chan, unsigned int source) { struct ni_660x_private *devpriv = dev->private; @@ -923,8 +923,8 @@ static int ni_660x_auto_attach(struct comedi_device *dev, unsigned int n_counters; int subdev; int ret; - unsigned i; - unsigned global_interrupt_config_bits; + unsigned int i; + unsigned int global_interrupt_config_bits; if (context < ARRAY_SIZE(ni_660x_boards)) board = &ni_660x_boards[context]; -- cgit v1.2.3 From cded944fa90cf8105eedb5766ecaee82a2f86b3a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:30 -0700 Subject: staging: comedi: ni_660x: Prefer kernel type 'u64' over 'uint64_t' Fix the checkpatch.pl issues. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 6ca5c67b1a80..4f7f5ca01e97 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -331,7 +331,7 @@ static const struct ni_660x_board ni_660x_boards[] = { struct ni_660x_private { struct mite_struct *mite; struct ni_gpct_device *counter_dev; - uint64_t pfi_direction_bits; + u64 pfi_direction_bits; struct mite_dma_descriptor_ring *mite_rings[NI_660X_MAX_NUM_CHIPS][counters_per_chip]; spinlock_t mite_channel_lock; @@ -854,7 +854,7 @@ static int ni_660x_set_pfi_routing(struct comedi_device *dev, } devpriv->pfi_output_selects[chan] = source; - if (devpriv->pfi_direction_bits & (((uint64_t) 1) << chan)) + if (devpriv->pfi_direction_bits & (1ULL << chan)) ni_660x_select_pfi_output(dev, chan, devpriv->pfi_output_selects[chan]); return 0; @@ -867,7 +867,7 @@ static int ni_660x_dio_insn_config(struct comedi_device *dev, { struct ni_660x_private *devpriv = dev->private; unsigned int chan = CR_CHAN(insn->chanspec); - uint64_t bit = 1ULL << chan; + u64 bit = 1ULL << chan; unsigned int val; int ret; -- cgit v1.2.3 From 7e9061869435dbeefff970b032d2b8141ce9e301 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:31 -0700 Subject: staging: comedi: ni_660x: tidy up Digital I/O subdevice init Add some whitespace to the Digital I/O subdevice init and add a comment about the channels. This driver is a bit goofy, only 32 of the 40 channels can actually be used for Digital I/Os and 32 of them can be routed to the counters for alternate use. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 68 ++++++++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 4f7f5ca01e97..f24009c98e0a 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -964,15 +964,67 @@ static int ni_660x_auto_attach(struct comedi_device *dev, /* Old GENERAL-PURPOSE COUNTER/TIME (GPCT) subdevice, no longer used */ s->type = COMEDI_SUBD_UNUSED; + /* + * Digital I/O subdevice + * + * There are 40 channels but only the first 32 can be digital I/Os. + * The last 8 are dedicated to counters 0 and 1. + * + * Counter 0-3 signals are from the first TIO chip. + * Counter 4-7 signals are from the second TIO chip. + * + * Comedi External + * PFI Chan DIO Chan Counter Signal + * ------- -------- -------------- + * 0 0 + * 1 1 + * 2 2 + * 3 3 + * 4 4 + * 5 5 + * 6 6 + * 7 7 + * 8 8 CTR 7 OUT + * 9 9 CTR 7 AUX + * 10 10 CTR 7 GATE + * 11 11 CTR 7 SOURCE + * 12 12 CTR 6 OUT + * 13 13 CTR 6 AUX + * 14 14 CTR 6 GATE + * 15 15 CTR 6 SOURCE + * 16 16 CTR 5 OUT + * 17 17 CTR 5 AUX + * 18 18 CTR 5 GATE + * 19 19 CTR 5 SOURCE + * 20 20 CTR 4 OUT + * 21 21 CTR 4 AUX + * 22 22 CTR 4 GATE + * 23 23 CTR 4 SOURCE + * 24 24 CTR 3 OUT + * 25 25 CTR 3 AUX + * 26 26 CTR 3 GATE + * 27 27 CTR 3 SOURCE + * 28 28 CTR 2 OUT + * 29 29 CTR 2 AUX + * 30 30 CTR 2 GATE + * 31 31 CTR 2 SOURCE + * 32 CTR 1 OUT + * 33 CTR 1 AUX + * 34 CTR 1 GATE + * 35 CTR 1 SOURCE + * 36 CTR 0 OUT + * 37 CTR 0 AUX + * 38 CTR 0 GATE + * 39 CTR 0 SOURCE + */ s = &dev->subdevices[subdev++]; - /* DIGITAL I/O SUBDEVICE */ - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = NUM_PFI_CHANNELS; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = ni_660x_dio_insn_bits; - s->insn_config = ni_660x_dio_insn_config; + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = NUM_PFI_CHANNELS; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = ni_660x_dio_insn_bits; + s->insn_config = ni_660x_dio_insn_config; /* * We use the ioconfig registers to control dio direction, so zero -- cgit v1.2.3 From 826f783a0eb15c6860d03af6d88eea3eaea34ff4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:32 -0700 Subject: staging: comedi: ni_660x: tidy up ni_660x_dio_insn_bits() Use some local variables to clarify this function. This (*insn_bits) function is a bit different from most comedi drivers. Add some comments to clarify why the shifts are used. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index f24009c98e0a..f614927411cb 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -780,21 +780,30 @@ static void init_tio_chip(struct comedi_device *dev, int chipset) static int ni_660x_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { - unsigned int base_bitfield_channel = CR_CHAN(insn->chanspec); + unsigned int shift = CR_CHAN(insn->chanspec); + unsigned int mask = data[0] << shift; + unsigned int bits = data[1] << shift; - /* Check if we have to write some bits */ - if (data[0]) { - s->state &= ~(data[0] << base_bitfield_channel); - s->state |= (data[0] & data[1]) << base_bitfield_channel; - /* Write out the new digital output lines */ + /* + * There are 40 channels in this subdevice but only 32 are usable + * as DIO. The shift adjusts the mask/bits to account for the base + * channel in insn->chanspec. The state update can then be handled + * normally for the 32 usable channels. + */ + if (mask) { + s->state &= ~mask; + s->state |= (bits & mask); ni_660x_write(dev, 0, s->state, NI660X_DIO32_OUTPUT); } - /* on return, data[1] contains the value of the digital - * input and output lines. */ - data[1] = (ni_660x_read(dev, 0, NI660X_DIO32_INPUT) >> - base_bitfield_channel); + + /* + * Return the input channels, shifted back to account for the base + * channel. + */ + data[1] = ni_660x_read(dev, 0, NI660X_DIO32_INPUT) >> shift; return insn->n; } -- cgit v1.2.3 From aa94f288882583fb2a214110ad021a75e78ff809 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:33 -0700 Subject: staging: comedi: ni_660x: tidy up ni_660x_set_pfi_routing() Use the comedi.h provided constants (enum ni_660x_pfi_routing) instead of defining new ones for the output sources. Use a switch to clarify the channel/source validation. For aesthetics, rename the private data members 'pfi_output_selects' and 'pfi_direction_bits'. Remove the 'min_counter_pfi_chan' and 'max_dio_pfi_chan' from enum ni_660x_constants. The open coded values make the code easier to follow. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 65 +++++++++++++------------------- 1 file changed, 27 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index f614927411cb..3415a15650fe 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -42,8 +42,6 @@ #include "ni_tio.h" enum ni_660x_constants { - min_counter_pfi_chan = 8, - max_dio_pfi_chan = 31, counters_per_chip = 4 }; @@ -172,10 +170,6 @@ enum ni_660x_register { #define NI660X_IO_CFG(x) (NI660X_IO_CFG_0_1 + ((x) / 2)) #define NI660X_IO_CFG_OUT_SEL(_c, _s) (((_s) & 0x3) << (((_c) % 2) ? 0 : 8)) #define NI660X_IO_CFG_OUT_SEL_MASK(_c) NI660X_IO_CFG_OUT_SEL((_c), 0x3) -#define NI660X_IO_CFG_OUT_SEL_HIGH_Z 0 -#define NI660X_IO_CFG_OUT_SEL_COUNTER 1 -#define NI660X_IO_CFG_OUT_SEL_DO 2 -#define NI660X_IO_CFG_OUT_SEL_MAX 3 #define NI660X_IO_CFG_IN_SEL(_c, _s) (((_s) & 0x7) << (((_c) % 2) ? 4 : 12)) #define NI660X_IO_CFG_IN_SEL_MASK(_c) NI660X_IO_CFG_IN_SEL((_c), 0x7) @@ -331,7 +325,6 @@ static const struct ni_660x_board ni_660x_boards[] = { struct ni_660x_private { struct mite_struct *mite; struct ni_gpct_device *counter_dev; - u64 pfi_direction_bits; struct mite_dma_descriptor_ring *mite_rings[NI_660X_MAX_NUM_CHIPS][counters_per_chip]; spinlock_t mite_channel_lock; @@ -339,7 +332,8 @@ struct ni_660x_private { spinlock_t interrupt_lock; unsigned int dma_cfg[NI_660X_MAX_NUM_CHIPS]; spinlock_t soft_reg_copy_lock; - unsigned short pfi_output_selects[NUM_PFI_CHANNELS]; + unsigned int io_cfg[NUM_PFI_CHANNELS]; + u64 io_dir; }; static enum ni_660x_register ni_gpct_to_660x_register(enum ni_gpct_register reg) @@ -728,7 +722,7 @@ static int ni_660x_allocate_private(struct comedi_device *dev) spin_lock_init(&devpriv->interrupt_lock); spin_lock_init(&devpriv->soft_reg_copy_lock); for (i = 0; i < NUM_PFI_CHANNELS; ++i) - devpriv->pfi_output_selects[i] = NI660X_IO_CFG_OUT_SEL_COUNTER; + devpriv->io_cfg[i] = NI_660X_PFI_OUTPUT_COUNTER; return 0; } @@ -817,7 +811,7 @@ static void ni_660x_select_pfi_output(struct comedi_device *dev, unsigned int bits; if (board->n_chips > 1) { - if (out_sel == NI660X_IO_CFG_OUT_SEL_COUNTER && + if (out_sel == NI_660X_PFI_OUTPUT_COUNTER && chan >= 8 && chan <= 23) { /* counters 4-7 pfi channels */ active_chip = 1; @@ -833,8 +827,7 @@ static void ni_660x_select_pfi_output(struct comedi_device *dev, /* set the pfi channel to high-z on the inactive chip */ bits = ni_660x_read(dev, idle_chip, NI660X_IO_CFG(chan)); bits &= ~NI660X_IO_CFG_OUT_SEL_MASK(chan); - bits |= NI660X_IO_CFG_OUT_SEL(chan, - NI660X_IO_CFG_OUT_SEL_HIGH_Z); + bits |= NI660X_IO_CFG_OUT_SEL(chan, 0); /* high-z */ ni_660x_write(dev, idle_chip, bits, NI660X_IO_CFG(chan)); } @@ -850,22 +843,21 @@ static int ni_660x_set_pfi_routing(struct comedi_device *dev, { struct ni_660x_private *devpriv = dev->private; - if (source > NI660X_IO_CFG_OUT_SEL_MAX) - return -EINVAL; - if (source == NI660X_IO_CFG_OUT_SEL_HIGH_Z) - return -EINVAL; - if (chan < min_counter_pfi_chan) { - if (source == NI660X_IO_CFG_OUT_SEL_COUNTER) + switch (source) { + case NI_660X_PFI_OUTPUT_COUNTER: + if (chan < 8) return -EINVAL; - } else if (chan > max_dio_pfi_chan) { - if (source == NI660X_IO_CFG_OUT_SEL_DO) + break; + case NI_660X_PFI_OUTPUT_DIO: + if (chan > 31) return -EINVAL; + default: + return -EINVAL; } - devpriv->pfi_output_selects[chan] = source; - if (devpriv->pfi_direction_bits & (1ULL << chan)) - ni_660x_select_pfi_output(dev, chan, - devpriv->pfi_output_selects[chan]); + devpriv->io_cfg[chan] = source; + if (devpriv->io_dir & (1ULL << chan)) + ni_660x_select_pfi_output(dev, chan, devpriv->io_cfg[chan]); return 0; } @@ -882,20 +874,18 @@ static int ni_660x_dio_insn_config(struct comedi_device *dev, switch (data[0]) { case INSN_CONFIG_DIO_OUTPUT: - devpriv->pfi_direction_bits |= bit; - ni_660x_select_pfi_output(dev, chan, - devpriv->pfi_output_selects[chan]); + devpriv->io_dir |= bit; + ni_660x_select_pfi_output(dev, chan, devpriv->io_cfg[chan]); break; case INSN_CONFIG_DIO_INPUT: - devpriv->pfi_direction_bits &= ~bit; - ni_660x_select_pfi_output(dev, chan, - NI660X_IO_CFG_OUT_SEL_HIGH_Z); + devpriv->io_dir &= ~bit; + ni_660x_select_pfi_output(dev, chan, 0); /* high-z */ break; case INSN_CONFIG_DIO_QUERY: - data[1] = (devpriv->pfi_direction_bits & bit) ? COMEDI_OUTPUT - : COMEDI_INPUT; + data[1] = (devpriv->io_dir & bit) ? COMEDI_OUTPUT + : COMEDI_INPUT; break; case INSN_CONFIG_SET_ROUTING: @@ -905,7 +895,7 @@ static int ni_660x_dio_insn_config(struct comedi_device *dev, break; case INSN_CONFIG_GET_ROUTING: - data[1] = devpriv->pfi_output_selects[chan]; + data[1] = devpriv->io_cfg[chan]; break; case INSN_CONFIG_FILTER: @@ -1084,13 +1074,12 @@ static int ni_660x_auto_attach(struct comedi_device *dev, ni_tio_init_counter(&devpriv->counter_dev->counters[i]); for (i = 0; i < NUM_PFI_CHANNELS; ++i) { - if (i < min_counter_pfi_chan) - ni_660x_set_pfi_routing(dev, i, - NI660X_IO_CFG_OUT_SEL_DO); + if (i < 8) + ni_660x_set_pfi_routing(dev, i, NI_660X_PFI_OUTPUT_DIO); else ni_660x_set_pfi_routing(dev, i, - NI660X_IO_CFG_OUT_SEL_COUNTER); - ni_660x_select_pfi_output(dev, i, NI660X_IO_CFG_OUT_SEL_HIGH_Z); + NI_660X_PFI_OUTPUT_COUNTER); + ni_660x_select_pfi_output(dev, i, 0); /* high-z */ } /* -- cgit v1.2.3 From f0c9305ede52b42021ea53a33b3a2878e0c5d51e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:34 -0700 Subject: staging: comedi: ni_660x: add a comment about the initial DIO state The (*auto_attach) initializes all the DIO channels to a default state. Add a comment for clarity. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 3415a15650fe..6f84946ea9a4 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -1073,6 +1073,11 @@ static int ni_660x_auto_attach(struct comedi_device *dev, for (i = 0; i < n_counters; ++i) ni_tio_init_counter(&devpriv->counter_dev->counters[i]); + /* + * Default the DIO channels as: + * chan 0-7: DIO inputs + * chan 8-39: counter signal inputs + */ for (i = 0; i < NUM_PFI_CHANNELS; ++i) { if (i < 8) ni_660x_set_pfi_routing(dev, i, NI_660X_PFI_OUTPUT_DIO); -- cgit v1.2.3 From 0c9434e352d0ae9ddb84a89716e1d1e82f3185f1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:35 -0700 Subject: staging: comedi: ni_660x: refactor ni_gpct_to_660x_register() Convert this big switch into an array and refactor ni_660x_gpct_{write,read}() functions to use the array to find the register offset. All the TIO (GPCT) registers are included in the array except for NITIO_G0_ABZ and NITIO_G1_ABZ. These registers only exist on the ni_pcimio m-series boards and this driver will never read/write them. Just in case someone adds a new entry to the enum ni_gpct_register in ni_tio.h, add a dev_warn() for any unhandled registers. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 236 ++++++++++++------------------- 1 file changed, 89 insertions(+), 147 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 6f84946ea9a4..3edea9928b09 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -279,6 +279,77 @@ static const struct ni_660x_register_data ni_660x_reg_data[NI660X_NUM_REGS] = { [NI660X_IO_CFG_38_39] = { 0x7a2, 2 } /* read/write */ }; +static const enum ni_660x_register ni_gpct_to_660x_register[] = { + [NITIO_G0_AUTO_INC] = NI660X_G0_AUTO_INC, + [NITIO_G1_AUTO_INC] = NI660X_G1_AUTO_INC, + [NITIO_G2_AUTO_INC] = NI660X_G2_AUTO_INC, + [NITIO_G3_AUTO_INC] = NI660X_G3_AUTO_INC, + [NITIO_G0_CMD] = NI660X_G0_CMD, + [NITIO_G1_CMD] = NI660X_G1_CMD, + [NITIO_G2_CMD] = NI660X_G2_CMD, + [NITIO_G3_CMD] = NI660X_G3_CMD, + [NITIO_G0_HW_SAVE] = NI660X_G0_HW_SAVE, + [NITIO_G1_HW_SAVE] = NI660X_G1_HW_SAVE, + [NITIO_G2_HW_SAVE] = NI660X_G2_HW_SAVE, + [NITIO_G3_HW_SAVE] = NI660X_G3_HW_SAVE, + [NITIO_G0_SW_SAVE] = NI660X_G0_SW_SAVE, + [NITIO_G1_SW_SAVE] = NI660X_G1_SW_SAVE, + [NITIO_G2_SW_SAVE] = NI660X_G2_SW_SAVE, + [NITIO_G3_SW_SAVE] = NI660X_G3_SW_SAVE, + [NITIO_G0_MODE] = NI660X_G0_MODE, + [NITIO_G1_MODE] = NI660X_G1_MODE, + [NITIO_G2_MODE] = NI660X_G2_MODE, + [NITIO_G3_MODE] = NI660X_G3_MODE, + [NITIO_G0_LOADA] = NI660X_G0_LOADA, + [NITIO_G1_LOADA] = NI660X_G1_LOADA, + [NITIO_G2_LOADA] = NI660X_G2_LOADA, + [NITIO_G3_LOADA] = NI660X_G3_LOADA, + [NITIO_G0_LOADB] = NI660X_G0_LOADB, + [NITIO_G1_LOADB] = NI660X_G1_LOADB, + [NITIO_G2_LOADB] = NI660X_G2_LOADB, + [NITIO_G3_LOADB] = NI660X_G3_LOADB, + [NITIO_G0_INPUT_SEL] = NI660X_G0_INPUT_SEL, + [NITIO_G1_INPUT_SEL] = NI660X_G1_INPUT_SEL, + [NITIO_G2_INPUT_SEL] = NI660X_G2_INPUT_SEL, + [NITIO_G3_INPUT_SEL] = NI660X_G3_INPUT_SEL, + [NITIO_G0_CNT_MODE] = NI660X_G0_CNT_MODE, + [NITIO_G1_CNT_MODE] = NI660X_G1_CNT_MODE, + [NITIO_G2_CNT_MODE] = NI660X_G2_CNT_MODE, + [NITIO_G3_CNT_MODE] = NI660X_G3_CNT_MODE, + [NITIO_G0_GATE2] = NI660X_G0_GATE2, + [NITIO_G1_GATE2] = NI660X_G1_GATE2, + [NITIO_G2_GATE2] = NI660X_G2_GATE2, + [NITIO_G3_GATE2] = NI660X_G3_GATE2, + [NITIO_G01_STATUS] = NI660X_G01_STATUS, + [NITIO_G23_STATUS] = NI660X_G23_STATUS, + [NITIO_G01_RESET] = NI660X_G01_RESET, + [NITIO_G23_RESET] = NI660X_G23_RESET, + [NITIO_G01_STATUS1] = NI660X_G01_STATUS1, + [NITIO_G23_STATUS1] = NI660X_G23_STATUS1, + [NITIO_G01_STATUS2] = NI660X_G01_STATUS2, + [NITIO_G23_STATUS2] = NI660X_G23_STATUS2, + [NITIO_G0_DMA_CFG] = NI660X_G0_DMA_CFG, + [NITIO_G1_DMA_CFG] = NI660X_G1_DMA_CFG, + [NITIO_G2_DMA_CFG] = NI660X_G2_DMA_CFG, + [NITIO_G3_DMA_CFG] = NI660X_G3_DMA_CFG, + [NITIO_G0_DMA_STATUS] = NI660X_G0_DMA_STATUS, + [NITIO_G1_DMA_STATUS] = NI660X_G1_DMA_STATUS, + [NITIO_G2_DMA_STATUS] = NI660X_G2_DMA_STATUS, + [NITIO_G3_DMA_STATUS] = NI660X_G3_DMA_STATUS, + [NITIO_G0_INT_ACK] = NI660X_G0_INT_ACK, + [NITIO_G1_INT_ACK] = NI660X_G1_INT_ACK, + [NITIO_G2_INT_ACK] = NI660X_G2_INT_ACK, + [NITIO_G3_INT_ACK] = NI660X_G3_INT_ACK, + [NITIO_G0_STATUS] = NI660X_G0_STATUS, + [NITIO_G1_STATUS] = NI660X_G1_STATUS, + [NITIO_G2_STATUS] = NI660X_G2_STATUS, + [NITIO_G3_STATUS] = NI660X_G3_STATUS, + [NITIO_G0_INT_ENA] = NI660X_G0_INT_ENA, + [NITIO_G1_INT_ENA] = NI660X_G1_INT_ENA, + [NITIO_G2_INT_ENA] = NI660X_G2_INT_ENA, + [NITIO_G3_INT_ENA] = NI660X_G3_INT_ENA, +}; + /* Offset of the GPCT chips from the base-address of the card */ /* First chip is at base-address + 0x00, etc. */ static const unsigned GPCT_OFFSET[2] = { 0x0, 0x800 }; @@ -336,151 +407,6 @@ struct ni_660x_private { u64 io_dir; }; -static enum ni_660x_register ni_gpct_to_660x_register(enum ni_gpct_register reg) -{ - switch (reg) { - case NITIO_G0_AUTO_INC: - return NI660X_G0_AUTO_INC; - case NITIO_G1_AUTO_INC: - return NI660X_G1_AUTO_INC; - case NITIO_G2_AUTO_INC: - return NI660X_G2_AUTO_INC; - case NITIO_G3_AUTO_INC: - return NI660X_G3_AUTO_INC; - case NITIO_G0_CMD: - return NI660X_G0_CMD; - case NITIO_G1_CMD: - return NI660X_G1_CMD; - case NITIO_G2_CMD: - return NI660X_G2_CMD; - case NITIO_G3_CMD: - return NI660X_G3_CMD; - case NITIO_G0_HW_SAVE: - return NI660X_G0_HW_SAVE; - case NITIO_G1_HW_SAVE: - return NI660X_G1_HW_SAVE; - case NITIO_G2_HW_SAVE: - return NI660X_G2_HW_SAVE; - case NITIO_G3_HW_SAVE: - return NI660X_G3_HW_SAVE; - case NITIO_G0_SW_SAVE: - return NI660X_G0_SW_SAVE; - case NITIO_G1_SW_SAVE: - return NI660X_G1_SW_SAVE; - case NITIO_G2_SW_SAVE: - return NI660X_G2_SW_SAVE; - case NITIO_G3_SW_SAVE: - return NI660X_G3_SW_SAVE; - case NITIO_G0_MODE: - return NI660X_G0_MODE; - case NITIO_G1_MODE: - return NI660X_G1_MODE; - case NITIO_G2_MODE: - return NI660X_G2_MODE; - case NITIO_G3_MODE: - return NI660X_G3_MODE; - case NITIO_G0_LOADA: - return NI660X_G0_LOADA; - case NITIO_G1_LOADA: - return NI660X_G1_LOADA; - case NITIO_G2_LOADA: - return NI660X_G2_LOADA; - case NITIO_G3_LOADA: - return NI660X_G3_LOADA; - case NITIO_G0_LOADB: - return NI660X_G0_LOADB; - case NITIO_G1_LOADB: - return NI660X_G1_LOADB; - case NITIO_G2_LOADB: - return NI660X_G2_LOADB; - case NITIO_G3_LOADB: - return NI660X_G3_LOADB; - case NITIO_G0_INPUT_SEL: - return NI660X_G0_INPUT_SEL; - case NITIO_G1_INPUT_SEL: - return NI660X_G1_INPUT_SEL; - case NITIO_G2_INPUT_SEL: - return NI660X_G2_INPUT_SEL; - case NITIO_G3_INPUT_SEL: - return NI660X_G3_INPUT_SEL; - case NITIO_G01_STATUS: - return NI660X_G01_STATUS; - case NITIO_G23_STATUS: - return NI660X_G23_STATUS; - case NITIO_G01_RESET: - return NI660X_G01_RESET; - case NITIO_G23_RESET: - return NI660X_G23_RESET; - case NITIO_G01_STATUS1: - return NI660X_G01_STATUS1; - case NITIO_G23_STATUS1: - return NI660X_G23_STATUS1; - case NITIO_G01_STATUS2: - return NI660X_G01_STATUS2; - case NITIO_G23_STATUS2: - return NI660X_G23_STATUS2; - case NITIO_G0_CNT_MODE: - return NI660X_G0_CNT_MODE; - case NITIO_G1_CNT_MODE: - return NI660X_G1_CNT_MODE; - case NITIO_G2_CNT_MODE: - return NI660X_G2_CNT_MODE; - case NITIO_G3_CNT_MODE: - return NI660X_G3_CNT_MODE; - case NITIO_G0_GATE2: - return NI660X_G0_GATE2; - case NITIO_G1_GATE2: - return NI660X_G1_GATE2; - case NITIO_G2_GATE2: - return NI660X_G2_GATE2; - case NITIO_G3_GATE2: - return NI660X_G3_GATE2; - case NITIO_G0_DMA_CFG: - return NI660X_G0_DMA_CFG; - case NITIO_G0_DMA_STATUS: - return NI660X_G0_DMA_STATUS; - case NITIO_G1_DMA_CFG: - return NI660X_G1_DMA_CFG; - case NITIO_G1_DMA_STATUS: - return NI660X_G1_DMA_STATUS; - case NITIO_G2_DMA_CFG: - return NI660X_G2_DMA_CFG; - case NITIO_G2_DMA_STATUS: - return NI660X_G2_DMA_STATUS; - case NITIO_G3_DMA_CFG: - return NI660X_G3_DMA_CFG; - case NITIO_G3_DMA_STATUS: - return NI660X_G3_DMA_STATUS; - case NITIO_G0_INT_ACK: - return NI660X_G0_INT_ACK; - case NITIO_G1_INT_ACK: - return NI660X_G1_INT_ACK; - case NITIO_G2_INT_ACK: - return NI660X_G2_INT_ACK; - case NITIO_G3_INT_ACK: - return NI660X_G3_INT_ACK; - case NITIO_G0_STATUS: - return NI660X_G0_STATUS; - case NITIO_G1_STATUS: - return NI660X_G1_STATUS; - case NITIO_G2_STATUS: - return NI660X_G2_STATUS; - case NITIO_G3_STATUS: - return NI660X_G3_STATUS; - case NITIO_G0_INT_ENA: - return NI660X_G0_INT_ENA; - case NITIO_G1_INT_ENA: - return NI660X_G1_INT_ENA; - case NITIO_G2_INT_ENA: - return NI660X_G2_INT_ENA; - case NITIO_G3_INT_ENA: - return NI660X_G3_INT_ENA; - default: - BUG(); - return 0; - } -} - static void ni_660x_write(struct comedi_device *dev, unsigned int chip, unsigned int bits, enum ni_660x_register reg) @@ -508,7 +434,15 @@ static void ni_660x_gpct_write(struct ni_gpct *counter, unsigned int bits, enum ni_gpct_register reg) { struct comedi_device *dev = counter->counter_dev->dev; - enum ni_660x_register ni_660x_register = ni_gpct_to_660x_register(reg); + enum ni_660x_register ni_660x_register; + + if (reg < ARRAY_SIZE(ni_gpct_to_660x_register)) { + ni_660x_register = ni_gpct_to_660x_register[reg]; + } else { + dev_warn(dev->class_dev, "%s: unhandled register=0x%x\n", + __func__, reg); + return; + } ni_660x_write(dev, counter->chip_index, bits, ni_660x_register); } @@ -517,7 +451,15 @@ static unsigned int ni_660x_gpct_read(struct ni_gpct *counter, enum ni_gpct_register reg) { struct comedi_device *dev = counter->counter_dev->dev; - enum ni_660x_register ni_660x_register = ni_gpct_to_660x_register(reg); + enum ni_660x_register ni_660x_register; + + if (reg < ARRAY_SIZE(ni_gpct_to_660x_register)) { + ni_660x_register = ni_gpct_to_660x_register[reg]; + } else { + dev_warn(dev->class_dev, "%s: unhandled register=0x%x\n", + __func__, reg); + return 0; + } return ni_660x_read(dev, counter->chip_index, ni_660x_register); } -- cgit v1.2.3 From e8f6e2b98d164d94bc29bb488413301d26cc5b3c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:36 -0700 Subject: staging: comedi: ni_660x: add comments for the spinlock_t definitions Fix the checkpatch.pl issues: CHECK: spinlock_t definition without comment For aesthetics, rename the 'soft_reg_copy_lock' to clarify what it's used for. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 3edea9928b09..2926d265f0bd 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -398,11 +398,13 @@ struct ni_660x_private { struct ni_gpct_device *counter_dev; struct mite_dma_descriptor_ring *mite_rings[NI_660X_MAX_NUM_CHIPS][counters_per_chip]; + /* protects mite channel request/release */ spinlock_t mite_channel_lock; - /* interrupt_lock prevents races between interrupt and comedi_poll */ + /* prevents races between interrupt and comedi_poll */ spinlock_t interrupt_lock; + /* protects dma_cfg changes */ + spinlock_t dma_cfg_lock; unsigned int dma_cfg[NI_660X_MAX_NUM_CHIPS]; - spinlock_t soft_reg_copy_lock; unsigned int io_cfg[NUM_PFI_CHANNELS]; u64 io_dir; }; @@ -482,7 +484,7 @@ static inline void ni_660x_set_dma_channel(struct comedi_device *dev, unsigned int chip = counter->chip_index; unsigned long flags; - spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags); + spin_lock_irqsave(&devpriv->dma_cfg_lock, flags); devpriv->dma_cfg[chip] &= ~NI660X_DMA_CFG_SEL_MASK(mite_channel); devpriv->dma_cfg[chip] |= NI660X_DMA_CFG_SEL(mite_channel, counter->counter_index); @@ -490,7 +492,7 @@ static inline void ni_660x_set_dma_channel(struct comedi_device *dev, NI660X_DMA_CFG_RESET(mite_channel), NI660X_DMA_CFG); mmiowb(); - spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags); + spin_unlock_irqrestore(&devpriv->dma_cfg_lock, flags); } static inline void ni_660x_unset_dma_channel(struct comedi_device *dev, @@ -501,12 +503,12 @@ static inline void ni_660x_unset_dma_channel(struct comedi_device *dev, unsigned int chip = counter->chip_index; unsigned long flags; - spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags); + spin_lock_irqsave(&devpriv->dma_cfg_lock, flags); devpriv->dma_cfg[chip] &= ~NI660X_DMA_CFG_SEL_MASK(mite_channel); devpriv->dma_cfg[chip] |= NI660X_DMA_CFG_SEL_NONE(mite_channel); ni_660x_write(dev, chip, devpriv->dma_cfg[chip], NI660X_DMA_CFG); mmiowb(); - spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags); + spin_unlock_irqrestore(&devpriv->dma_cfg_lock, flags); } static int ni_660x_request_mite_channel(struct comedi_device *dev, @@ -662,7 +664,7 @@ static int ni_660x_allocate_private(struct comedi_device *dev) spin_lock_init(&devpriv->mite_channel_lock); spin_lock_init(&devpriv->interrupt_lock); - spin_lock_init(&devpriv->soft_reg_copy_lock); + spin_lock_init(&devpriv->dma_cfg_lock); for (i = 0; i < NUM_PFI_CHANNELS; ++i) devpriv->io_cfg[i] = NI_660X_PFI_OUTPUT_COUNTER; -- cgit v1.2.3 From 5262d035ef260c3417254b2309892bba013dcab7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:37 -0700 Subject: staging: comedi: ni_660x: fix memory barrier without comment Fix the checkpatch.pl issue. Move the memory barrier to a better place. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 2926d265f0bd..bb5b5ff4e32f 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -613,9 +613,11 @@ static irqreturn_t ni_660x_interrupt(int irq, void *d) if (!dev->attached) return IRQ_NONE; + /* make sure dev->attached is checked before doing anything else */ + smp_mb(); + /* lock to avoid race with comedi_poll */ spin_lock_irqsave(&devpriv->interrupt_lock, flags); - smp_mb(); for (i = 0; i < dev->n_subdevices; ++i) { s = &dev->subdevices[i]; if (s->type == COMEDI_SUBD_COUNTER) -- cgit v1.2.3 From ccef0da819dd7fa716b90e584a7793a8849b06f1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:38 -0700 Subject: staging: comedi: ni_660x: tidy up the misc. constants Remove enum ni_660x_constants and just #define the value. Move all the constant #defines so they are in one place and rename them so they are more conesistent. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 49 ++++++++++++++++---------------- 1 file changed, 24 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index bb5b5ff4e32f..80499d6de44b 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -41,14 +41,6 @@ #include "mite.h" #include "ni_tio.h" -enum ni_660x_constants { - counters_per_chip = 4 -}; - -#define NUM_PFI_CHANNELS 40 -/* there are only up to 3 dma channels, but the register layout allows for 4 */ -#define MAX_DMA_CHANNEL 4 - /* See Register-Level Programmer Manual page 3.1 */ enum ni_660x_register { NI660X_G0_INT_ACK, @@ -390,22 +382,29 @@ static const struct ni_660x_board ni_660x_boards[] = { }, }; -#define NI_660X_MAX_NUM_CHIPS 2 -#define NI_660X_MAX_NUM_COUNTERS (NI_660X_MAX_NUM_CHIPS * counters_per_chip) +#define NI660X_NUM_PFI_CHANNELS 40 + +/* there are only up to 3 dma channels, but the register layout allows for 4 */ +#define NI660X_MAX_DMA_CHANNEL 4 + +#define NI660X_COUNTERS_PER_CHIP 4 +#define NI660X_MAX_CHIPS 2 +#define NI660X_MAX_COUNTERS (NI660X_MAX_CHIPS * \ + NI660X_COUNTERS_PER_CHIP) struct ni_660x_private { struct mite_struct *mite; struct ni_gpct_device *counter_dev; struct mite_dma_descriptor_ring - *mite_rings[NI_660X_MAX_NUM_CHIPS][counters_per_chip]; + *mite_rings[NI660X_MAX_CHIPS][NI660X_COUNTERS_PER_CHIP]; /* protects mite channel request/release */ spinlock_t mite_channel_lock; /* prevents races between interrupt and comedi_poll */ spinlock_t interrupt_lock; /* protects dma_cfg changes */ spinlock_t dma_cfg_lock; - unsigned int dma_cfg[NI_660X_MAX_NUM_CHIPS]; - unsigned int io_cfg[NUM_PFI_CHANNELS]; + unsigned int dma_cfg[NI660X_MAX_CHIPS]; + unsigned int io_cfg[NI660X_NUM_PFI_CHANNELS]; u64 io_dir; }; @@ -667,7 +666,7 @@ static int ni_660x_allocate_private(struct comedi_device *dev) spin_lock_init(&devpriv->mite_channel_lock); spin_lock_init(&devpriv->interrupt_lock); spin_lock_init(&devpriv->dma_cfg_lock); - for (i = 0; i < NUM_PFI_CHANNELS; ++i) + for (i = 0; i < NI660X_NUM_PFI_CHANNELS; ++i) devpriv->io_cfg[i] = NI_660X_PFI_OUTPUT_COUNTER; return 0; @@ -681,7 +680,7 @@ static int ni_660x_alloc_mite_rings(struct comedi_device *dev) unsigned int j; for (i = 0; i < board->n_chips; ++i) { - for (j = 0; j < counters_per_chip; ++j) { + for (j = 0; j < NI660X_COUNTERS_PER_CHIP; ++j) { devpriv->mite_rings[i][j] = mite_alloc_ring(devpriv->mite); if (!devpriv->mite_rings[i][j]) @@ -699,7 +698,7 @@ static void ni_660x_free_mite_rings(struct comedi_device *dev) unsigned int j; for (i = 0; i < board->n_chips; ++i) { - for (j = 0; j < counters_per_chip; ++j) + for (j = 0; j < NI660X_COUNTERS_PER_CHIP; ++j) mite_free_ring(devpriv->mite_rings[i][j]); } } @@ -711,10 +710,10 @@ static void init_tio_chip(struct comedi_device *dev, int chipset) /* init dma configuration register */ devpriv->dma_cfg[chipset] = 0; - for (i = 0; i < MAX_DMA_CHANNEL; ++i) + for (i = 0; i < NI660X_MAX_DMA_CHANNEL; ++i) devpriv->dma_cfg[chipset] |= NI660X_DMA_CFG_SEL_NONE(i); ni_660x_write(dev, chipset, devpriv->dma_cfg[chipset], NI660X_DMA_CFG); - for (i = 0; i < NUM_PFI_CHANNELS; ++i) + for (i = 0; i < NI660X_NUM_PFI_CHANNELS; ++i) ni_660x_write(dev, chipset, 0, NI660X_IO_CFG(i)); } @@ -899,7 +898,7 @@ static int ni_660x_auto_attach(struct comedi_device *dev, if (ret < 0) return ret; - ret = comedi_alloc_subdevices(dev, 2 + NI_660X_MAX_NUM_COUNTERS); + ret = comedi_alloc_subdevices(dev, 2 + NI660X_MAX_COUNTERS); if (ret) return ret; @@ -965,7 +964,7 @@ static int ni_660x_auto_attach(struct comedi_device *dev, s = &dev->subdevices[subdev++]; s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = NUM_PFI_CHANNELS; + s->n_chan = NI660X_NUM_PFI_CHANNELS; s->maxdata = 1; s->range_table = &range_digital; s->insn_bits = ni_660x_dio_insn_bits; @@ -977,7 +976,7 @@ static int ni_660x_auto_attach(struct comedi_device *dev, */ ni_660x_write(dev, 0, 0, NI660X_STC_DIO_CONTROL); - n_counters = board->n_chips * counters_per_chip; + n_counters = board->n_chips * NI660X_COUNTERS_PER_CHIP; devpriv->counter_dev = ni_gpct_device_construct(dev, ni_660x_gpct_write, ni_660x_gpct_read, @@ -985,7 +984,7 @@ static int ni_660x_auto_attach(struct comedi_device *dev, n_counters); if (!devpriv->counter_dev) return -ENOMEM; - for (i = 0; i < NI_660X_MAX_NUM_COUNTERS; ++i) { + for (i = 0; i < NI660X_MAX_COUNTERS; ++i) { s = &dev->subdevices[subdev++]; if (i < n_counters) { s->type = COMEDI_SUBD_COUNTER; @@ -1006,9 +1005,9 @@ static int ni_660x_auto_attach(struct comedi_device *dev, s->private = &devpriv->counter_dev->counters[i]; devpriv->counter_dev->counters[i].chip_index = - i / counters_per_chip; + i / NI660X_COUNTERS_PER_CHIP; devpriv->counter_dev->counters[i].counter_index = - i % counters_per_chip; + i % NI660X_COUNTERS_PER_CHIP; } else { s->type = COMEDI_SUBD_UNUSED; } @@ -1024,7 +1023,7 @@ static int ni_660x_auto_attach(struct comedi_device *dev, * chan 0-7: DIO inputs * chan 8-39: counter signal inputs */ - for (i = 0; i < NUM_PFI_CHANNELS; ++i) { + for (i = 0; i < NI660X_NUM_PFI_CHANNELS; ++i) { if (i < 8) ni_660x_set_pfi_routing(dev, i, NI_660X_PFI_OUTPUT_DIO); else -- cgit v1.2.3 From 32f89d8e70106f2b636c716a7cfb7fe53cfc5ebf Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:39 -0700 Subject: staging: comedi: ni_660x: tidy up the counter subdevices init For aesthetics, add some whitespace to the subdevice init and use a couple local variables to make the code easier to follow. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 59 +++++++++++++++++--------------- 1 file changed, 32 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 80499d6de44b..35602cc7af61 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -864,6 +864,7 @@ static int ni_660x_auto_attach(struct comedi_device *dev, const struct ni_660x_board *board = NULL; struct ni_660x_private *devpriv; struct comedi_subdevice *s; + struct ni_gpct_device *gpct_dev; unsigned int n_counters; int subdev; int ret; @@ -977,46 +978,50 @@ static int ni_660x_auto_attach(struct comedi_device *dev, ni_660x_write(dev, 0, 0, NI660X_STC_DIO_CONTROL); n_counters = board->n_chips * NI660X_COUNTERS_PER_CHIP; - devpriv->counter_dev = ni_gpct_device_construct(dev, - ni_660x_gpct_write, - ni_660x_gpct_read, - ni_gpct_variant_660x, - n_counters); - if (!devpriv->counter_dev) + gpct_dev = ni_gpct_device_construct(dev, + ni_660x_gpct_write, + ni_660x_gpct_read, + ni_gpct_variant_660x, + n_counters); + if (!gpct_dev) return -ENOMEM; + devpriv->counter_dev = gpct_dev; + + /* Counter subdevices (4 NI TIO General Purpose Counters per chip) */ for (i = 0; i < NI660X_MAX_COUNTERS; ++i) { s = &dev->subdevices[subdev++]; if (i < n_counters) { - s->type = COMEDI_SUBD_COUNTER; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE | + struct ni_gpct *counter = &gpct_dev->counters[i]; + + counter->chip_index = i / NI660X_COUNTERS_PER_CHIP; + counter->counter_index = i % NI660X_COUNTERS_PER_CHIP; + + s->type = COMEDI_SUBD_COUNTER; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_CMD_READ; - s->n_chan = 3; - s->maxdata = 0xffffffff; - s->insn_read = ni_tio_insn_read; - s->insn_write = ni_tio_insn_write; - s->insn_config = ni_tio_insn_config; - s->do_cmd = &ni_660x_cmd; - s->len_chanlist = 1; - s->do_cmdtest = ni_tio_cmdtest; - s->cancel = &ni_660x_cancel; - s->poll = &ni_660x_input_poll; + s->n_chan = 3; + s->maxdata = 0xffffffff; + s->insn_read = ni_tio_insn_read; + s->insn_write = ni_tio_insn_write; + s->insn_config = ni_tio_insn_config; + s->len_chanlist = 1; + s->do_cmd = ni_660x_cmd; + s->do_cmdtest = ni_tio_cmdtest; + s->cancel = ni_660x_cancel; + s->poll = ni_660x_input_poll; + s->buf_change = ni_660x_buf_change; s->async_dma_dir = DMA_BIDIRECTIONAL; - s->buf_change = &ni_660x_buf_change; - s->private = &devpriv->counter_dev->counters[i]; - - devpriv->counter_dev->counters[i].chip_index = - i / NI660X_COUNTERS_PER_CHIP; - devpriv->counter_dev->counters[i].counter_index = - i % NI660X_COUNTERS_PER_CHIP; + s->private = counter; } else { - s->type = COMEDI_SUBD_UNUSED; + s->type = COMEDI_SUBD_UNUSED; } } + for (i = 0; i < board->n_chips; ++i) init_tio_chip(dev, i); for (i = 0; i < n_counters; ++i) - ni_tio_init_counter(&devpriv->counter_dev->counters[i]); + ni_tio_init_counter(&gpct_dev->counters[i]); /* * Default the DIO channels as: -- cgit v1.2.3 From 26a0fe3ffa24c63a99b1fb314e03723c1e470ba0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:41 -0700 Subject: staging: comedi: ni_660x: ni_gpct_device_destroy() can handle a NULL pointer Remove the unnecessary NULL pointer check. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 35602cc7af61..2440cb6a72c7 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -1067,8 +1067,7 @@ static void ni_660x_detach(struct comedi_device *dev) if (dev->irq) free_irq(dev->irq, dev); if (devpriv) { - if (devpriv->counter_dev) - ni_gpct_device_destroy(devpriv->counter_dev); + ni_gpct_device_destroy(devpriv->counter_dev); ni_660x_free_mite_rings(dev); mite_detach(devpriv->mite); } -- cgit v1.2.3 From 78d514fa4cc0f195e060b7918d3548b63d27050f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:43 -0700 Subject: staging: comedi: ni_660x: disable interrupts when detaching driver Make sure the interrupts are disabled before freeing the irq. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 2440cb6a72c7..c71dae8da804 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -1064,8 +1064,10 @@ static void ni_660x_detach(struct comedi_device *dev) { struct ni_660x_private *devpriv = dev->private; - if (dev->irq) + if (dev->irq) { + ni_660x_write(dev, 0, 0, NI660X_GLOBAL_INT_CFG); free_irq(dev->irq, dev); + } if (devpriv) { ni_gpct_device_destroy(devpriv->counter_dev); ni_660x_free_mite_rings(dev); -- cgit v1.2.3 From 2363cbf073225537016aceb6bf122bbee6a0caa0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:44 -0700 Subject: staging: comedi: ni_660x: init TIO chips before subdevice init For aesthetics, initialize the TIO chips before the subdevices are allocated and initialized. Refactor the function to initialize all the TIO chips and move it to a better place in the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 52 ++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index c71dae8da804..afe62bf2de8b 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -703,20 +703,6 @@ static void ni_660x_free_mite_rings(struct comedi_device *dev) } } -static void init_tio_chip(struct comedi_device *dev, int chipset) -{ - struct ni_660x_private *devpriv = dev->private; - unsigned int i; - - /* init dma configuration register */ - devpriv->dma_cfg[chipset] = 0; - for (i = 0; i < NI660X_MAX_DMA_CHANNEL; ++i) - devpriv->dma_cfg[chipset] |= NI660X_DMA_CFG_SEL_NONE(i); - ni_660x_write(dev, chipset, devpriv->dma_cfg[chipset], NI660X_DMA_CFG); - for (i = 0; i < NI660X_NUM_PFI_CHANNELS; ++i) - ni_660x_write(dev, chipset, 0, NI660X_IO_CFG(i)); -} - static int ni_660x_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, @@ -857,6 +843,33 @@ static int ni_660x_dio_insn_config(struct comedi_device *dev, return insn->n; } +static void ni_660x_init_tio_chips(struct comedi_device *dev, + unsigned int n_chips) +{ + struct ni_660x_private *devpriv = dev->private; + unsigned int chip; + unsigned int chan; + + /* + * We use the ioconfig registers to control dio direction, so zero + * output enables in stc dio control reg. + */ + ni_660x_write(dev, 0, 0, NI660X_STC_DIO_CONTROL); + + for (chip = 0; chip < n_chips; ++chip) { + /* init dma configuration register */ + devpriv->dma_cfg[chip] = 0; + for (chan = 0; chan < NI660X_MAX_DMA_CHANNEL; ++chan) + devpriv->dma_cfg[chip] |= NI660X_DMA_CFG_SEL_NONE(chan); + ni_660x_write(dev, chip, devpriv->dma_cfg[chip], + NI660X_DMA_CFG); + + /* init ioconfig registers */ + for (chan = 0; chan < NI660X_NUM_PFI_CHANNELS; ++chan) + ni_660x_write(dev, chip, 0, NI660X_IO_CFG(chan)); + } +} + static int ni_660x_auto_attach(struct comedi_device *dev, unsigned long context) { @@ -899,6 +912,8 @@ static int ni_660x_auto_attach(struct comedi_device *dev, if (ret < 0) return ret; + ni_660x_init_tio_chips(dev, board->n_chips); + ret = comedi_alloc_subdevices(dev, 2 + NI660X_MAX_COUNTERS); if (ret) return ret; @@ -971,12 +986,6 @@ static int ni_660x_auto_attach(struct comedi_device *dev, s->insn_bits = ni_660x_dio_insn_bits; s->insn_config = ni_660x_dio_insn_config; - /* - * We use the ioconfig registers to control dio direction, so zero - * output enables in stc dio control reg. - */ - ni_660x_write(dev, 0, 0, NI660X_STC_DIO_CONTROL); - n_counters = board->n_chips * NI660X_COUNTERS_PER_CHIP; gpct_dev = ni_gpct_device_construct(dev, ni_660x_gpct_write, @@ -1017,9 +1026,6 @@ static int ni_660x_auto_attach(struct comedi_device *dev, } } - for (i = 0; i < board->n_chips; ++i) - init_tio_chip(dev, i); - for (i = 0; i < n_counters; ++i) ni_tio_init_counter(&gpct_dev->counters[i]); -- cgit v1.2.3 From f229594a327720c0761e7307a5472aea780268c3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:45 -0700 Subject: staging: comedi: ni_660x: allocate counters early in (*auto_attach) The ni_gpct_device_construct() could fail allocating the memory for device and its counters. For aesthetics, call the function before initializing the subdevices. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index afe62bf2de8b..636630380100 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -914,6 +914,16 @@ static int ni_660x_auto_attach(struct comedi_device *dev, ni_660x_init_tio_chips(dev, board->n_chips); + n_counters = board->n_chips * NI660X_COUNTERS_PER_CHIP; + gpct_dev = ni_gpct_device_construct(dev, + ni_660x_gpct_write, + ni_660x_gpct_read, + ni_gpct_variant_660x, + n_counters); + if (!gpct_dev) + return -ENOMEM; + devpriv->counter_dev = gpct_dev; + ret = comedi_alloc_subdevices(dev, 2 + NI660X_MAX_COUNTERS); if (ret) return ret; @@ -986,16 +996,6 @@ static int ni_660x_auto_attach(struct comedi_device *dev, s->insn_bits = ni_660x_dio_insn_bits; s->insn_config = ni_660x_dio_insn_config; - n_counters = board->n_chips * NI660X_COUNTERS_PER_CHIP; - gpct_dev = ni_gpct_device_construct(dev, - ni_660x_gpct_write, - ni_660x_gpct_read, - ni_gpct_variant_660x, - n_counters); - if (!gpct_dev) - return -ENOMEM; - devpriv->counter_dev = gpct_dev; - /* Counter subdevices (4 NI TIO General Purpose Counters per chip) */ for (i = 0; i < NI660X_MAX_COUNTERS; ++i) { s = &dev->subdevices[subdev++]; -- cgit v1.2.3 From 90ad57be6be10e7084ca677d6eddfba612b55a62 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:46 -0700 Subject: staging: comedi: ni_660x: initialize the counter with the subdevice init Remove the extra for loop and just initialize the counter as the subdevices are created. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 636630380100..5969723b6167 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -1021,14 +1021,13 @@ static int ni_660x_auto_attach(struct comedi_device *dev, s->buf_change = ni_660x_buf_change; s->async_dma_dir = DMA_BIDIRECTIONAL; s->private = counter; + + ni_tio_init_counter(counter); } else { s->type = COMEDI_SUBD_UNUSED; } } - for (i = 0; i < n_counters; ++i) - ni_tio_init_counter(&gpct_dev->counters[i]); - /* * Default the DIO channels as: * chan 0-7: DIO inputs -- cgit v1.2.3 From 34b7f1f8194da6600eda6bb7c26659de19047a39 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:47 -0700 Subject: staging: comedi: ni_660x: default DIO channels with subdevice init For aesthetics, move the initialization of the default routing for the DIO channels so it happens when the subdevice is initialized. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 5969723b6167..cf25892d92b2 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -996,6 +996,19 @@ static int ni_660x_auto_attach(struct comedi_device *dev, s->insn_bits = ni_660x_dio_insn_bits; s->insn_config = ni_660x_dio_insn_config; + /* + * Default the DIO channels as: + * chan 0-7: DIO inputs + * chan 8-39: counter signal inputs + */ + for (i = 0; i < s->n_chan; ++i) { + unsigned int source = (i < 8) ? NI_660X_PFI_OUTPUT_DIO + : NI_660X_PFI_OUTPUT_COUNTER; + + ni_660x_set_pfi_routing(dev, i, source); + ni_660x_select_pfi_output(dev, i, 0); /* high-z */ + } + /* Counter subdevices (4 NI TIO General Purpose Counters per chip) */ for (i = 0; i < NI660X_MAX_COUNTERS; ++i) { s = &dev->subdevices[subdev++]; @@ -1028,20 +1041,6 @@ static int ni_660x_auto_attach(struct comedi_device *dev, } } - /* - * Default the DIO channels as: - * chan 0-7: DIO inputs - * chan 8-39: counter signal inputs - */ - for (i = 0; i < NI660X_NUM_PFI_CHANNELS; ++i) { - if (i < 8) - ni_660x_set_pfi_routing(dev, i, NI_660X_PFI_OUTPUT_DIO); - else - ni_660x_set_pfi_routing(dev, i, - NI_660X_PFI_OUTPUT_COUNTER); - ni_660x_select_pfi_output(dev, i, 0); /* high-z */ - } - /* * To be safe, set counterswap bits on tio chips after all the counter * outputs have been set to high impedance mode. -- cgit v1.2.3 From 515b5e6b8afdd32a3b528a331f23b852fe083c26 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:48 -0700 Subject: staging: comedi: ni_660x: remove inline mite_ring() This fuction just returns a pointer from the private data. The name might provide some confusion since it appears to be an exported function from the mite driver. Just remove it and get the pointer directly where needed. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index cf25892d92b2..1cca9ea5cdd2 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -465,16 +465,6 @@ static unsigned int ni_660x_gpct_read(struct ni_gpct *counter, return ni_660x_read(dev, counter->chip_index, ni_660x_register); } -static inline struct mite_dma_descriptor_ring *mite_ring(struct ni_660x_private - *priv, - struct ni_gpct - *counter) -{ - unsigned int chip = counter->chip_index; - - return priv->mite_rings[chip][counter->counter_index]; -} - static inline void ni_660x_set_dma_channel(struct comedi_device *dev, unsigned int mite_channel, struct ni_gpct *counter) @@ -515,12 +505,13 @@ static int ni_660x_request_mite_channel(struct comedi_device *dev, enum comedi_io_direction direction) { struct ni_660x_private *devpriv = dev->private; - unsigned long flags; + struct mite_dma_descriptor_ring *ring; struct mite_channel *mite_chan; + unsigned long flags; spin_lock_irqsave(&devpriv->mite_channel_lock, flags); - mite_chan = mite_request_channel(devpriv->mite, - mite_ring(devpriv, counter)); + ring = devpriv->mite_rings[counter->chip_index][counter->counter_index]; + mite_chan = mite_request_channel(devpriv->mite, ring); if (!mite_chan) { spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); dev_err(dev->class_dev, @@ -645,9 +636,11 @@ static int ni_660x_buf_change(struct comedi_device *dev, { struct ni_660x_private *devpriv = dev->private; struct ni_gpct *counter = s->private; + struct mite_dma_descriptor_ring *ring; int ret; - ret = mite_buf_change(mite_ring(devpriv, counter), s); + ring = devpriv->mite_rings[counter->chip_index][counter->counter_index]; + ret = mite_buf_change(ring, s); if (ret < 0) return ret; -- cgit v1.2.3 From 242311d1a9e5cebde39855e064dcc4ac0dabde93 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:49 -0700 Subject: staging: comedi: ni_660x: sort enum ni_660x_register Sort this enum so that it has a 1:1 relationship with the ni_tio.h enum ni_gpct_register. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 95 ++++++++++++++++---------------- 1 file changed, 48 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 1cca9ea5cdd2..ad67ee5ec7ff 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -43,78 +43,79 @@ /* See Register-Level Programmer Manual page 3.1 */ enum ni_660x_register { - NI660X_G0_INT_ACK, - NI660X_G0_STATUS, - NI660X_G1_INT_ACK, - NI660X_G1_STATUS, - NI660X_G01_STATUS, + NI660X_G0_AUTO_INC, + NI660X_G1_AUTO_INC, + NI660X_G2_AUTO_INC, + NI660X_G3_AUTO_INC, NI660X_G0_CMD, - NI660X_STC_DIO_PARALLEL_INPUT, NI660X_G1_CMD, + NI660X_G2_CMD, + NI660X_G3_CMD, NI660X_G0_HW_SAVE, NI660X_G1_HW_SAVE, - NI660X_STC_DIO_OUTPUT, - NI660X_STC_DIO_CONTROL, + NI660X_G2_HW_SAVE, + NI660X_G3_HW_SAVE, NI660X_G0_SW_SAVE, NI660X_G1_SW_SAVE, + NI660X_G2_SW_SAVE, + NI660X_G3_SW_SAVE, NI660X_G0_MODE, - NI660X_G01_STATUS1, NI660X_G1_MODE, - NI660X_STC_DIO_SERIAL_INPUT, + NI660X_G2_MODE, + NI660X_G3_MODE, NI660X_G0_LOADA, - NI660X_G01_STATUS2, - NI660X_G0_LOADB, NI660X_G1_LOADA, + NI660X_G2_LOADA, + NI660X_G3_LOADA, + NI660X_G0_LOADB, NI660X_G1_LOADB, + NI660X_G2_LOADB, + NI660X_G3_LOADB, NI660X_G0_INPUT_SEL, NI660X_G1_INPUT_SEL, - NI660X_G0_AUTO_INC, - NI660X_G1_AUTO_INC, - NI660X_G01_RESET, - NI660X_G0_INT_ENA, - NI660X_G1_INT_ENA, + NI660X_G2_INPUT_SEL, + NI660X_G3_INPUT_SEL, NI660X_G0_CNT_MODE, NI660X_G1_CNT_MODE, + NI660X_G2_CNT_MODE, + NI660X_G3_CNT_MODE, NI660X_G0_GATE2, NI660X_G1_GATE2, + NI660X_G2_GATE2, + NI660X_G3_GATE2, + NI660X_G01_STATUS, + NI660X_G23_STATUS, + NI660X_G01_RESET, + NI660X_G23_RESET, + NI660X_G01_STATUS1, + NI660X_G23_STATUS1, + NI660X_G01_STATUS2, + NI660X_G23_STATUS2, NI660X_G0_DMA_CFG, - NI660X_G0_DMA_STATUS, NI660X_G1_DMA_CFG, + NI660X_G2_DMA_CFG, + NI660X_G3_DMA_CFG, + NI660X_G0_DMA_STATUS, NI660X_G1_DMA_STATUS, + NI660X_G2_DMA_STATUS, + NI660X_G3_DMA_STATUS, + NI660X_G0_INT_ACK, + NI660X_G1_INT_ACK, NI660X_G2_INT_ACK, - NI660X_G2_STATUS, NI660X_G3_INT_ACK, + NI660X_G0_STATUS, + NI660X_G1_STATUS, + NI660X_G2_STATUS, NI660X_G3_STATUS, - NI660X_G23_STATUS, - NI660X_G2_CMD, - NI660X_G3_CMD, - NI660X_G2_HW_SAVE, - NI660X_G3_HW_SAVE, - NI660X_G2_SW_SAVE, - NI660X_G3_SW_SAVE, - NI660X_G2_MODE, - NI660X_G23_STATUS1, - NI660X_G3_MODE, - NI660X_G2_LOADA, - NI660X_G23_STATUS2, - NI660X_G2_LOADB, - NI660X_G3_LOADA, - NI660X_G3_LOADB, - NI660X_G2_INPUT_SEL, - NI660X_G3_INPUT_SEL, - NI660X_G2_AUTO_INC, - NI660X_G3_AUTO_INC, - NI660X_G23_RESET, + NI660X_G0_INT_ENA, + NI660X_G1_INT_ENA, NI660X_G2_INT_ENA, NI660X_G3_INT_ENA, - NI660X_G2_CNT_MODE, - NI660X_G3_CNT_MODE, - NI660X_G3_GATE2, - NI660X_G2_GATE2, - NI660X_G2_DMA_CFG, - NI660X_G2_DMA_STATUS, - NI660X_G3_DMA_CFG, - NI660X_G3_DMA_STATUS, + + NI660X_STC_DIO_PARALLEL_INPUT = NITIO_NUM_REGS, + NI660X_STC_DIO_OUTPUT, + NI660X_STC_DIO_CONTROL, + NI660X_STC_DIO_SERIAL_INPUT, NI660X_DIO32_INPUT, NI660X_DIO32_OUTPUT, NI660X_CLK_CFG, -- cgit v1.2.3 From 4f2c3b2077a9bb34c7b5afe31633a1f5b1ca80b4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:50 -0700 Subject: staging: comedi: ni_660x: remove ni_gpct_to_660x_register[] enum ni_gpct_register and enum ni_660x_register now have a 1:1 relationship for the NITIO_* registers. The static const array is no longer necessary to find the proper NI660X_* register for a given NITIO_*. Remove it and refactor the register read/write functions. Use the NITIO_* values to init the ni_660x_reg_data[] array and remove the unnecessary NI660X_* enum values. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 307 ++++++++----------------------- 1 file changed, 74 insertions(+), 233 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index ad67ee5ec7ff..85c793a458f8 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -43,75 +43,7 @@ /* See Register-Level Programmer Manual page 3.1 */ enum ni_660x_register { - NI660X_G0_AUTO_INC, - NI660X_G1_AUTO_INC, - NI660X_G2_AUTO_INC, - NI660X_G3_AUTO_INC, - NI660X_G0_CMD, - NI660X_G1_CMD, - NI660X_G2_CMD, - NI660X_G3_CMD, - NI660X_G0_HW_SAVE, - NI660X_G1_HW_SAVE, - NI660X_G2_HW_SAVE, - NI660X_G3_HW_SAVE, - NI660X_G0_SW_SAVE, - NI660X_G1_SW_SAVE, - NI660X_G2_SW_SAVE, - NI660X_G3_SW_SAVE, - NI660X_G0_MODE, - NI660X_G1_MODE, - NI660X_G2_MODE, - NI660X_G3_MODE, - NI660X_G0_LOADA, - NI660X_G1_LOADA, - NI660X_G2_LOADA, - NI660X_G3_LOADA, - NI660X_G0_LOADB, - NI660X_G1_LOADB, - NI660X_G2_LOADB, - NI660X_G3_LOADB, - NI660X_G0_INPUT_SEL, - NI660X_G1_INPUT_SEL, - NI660X_G2_INPUT_SEL, - NI660X_G3_INPUT_SEL, - NI660X_G0_CNT_MODE, - NI660X_G1_CNT_MODE, - NI660X_G2_CNT_MODE, - NI660X_G3_CNT_MODE, - NI660X_G0_GATE2, - NI660X_G1_GATE2, - NI660X_G2_GATE2, - NI660X_G3_GATE2, - NI660X_G01_STATUS, - NI660X_G23_STATUS, - NI660X_G01_RESET, - NI660X_G23_RESET, - NI660X_G01_STATUS1, - NI660X_G23_STATUS1, - NI660X_G01_STATUS2, - NI660X_G23_STATUS2, - NI660X_G0_DMA_CFG, - NI660X_G1_DMA_CFG, - NI660X_G2_DMA_CFG, - NI660X_G3_DMA_CFG, - NI660X_G0_DMA_STATUS, - NI660X_G1_DMA_STATUS, - NI660X_G2_DMA_STATUS, - NI660X_G3_DMA_STATUS, - NI660X_G0_INT_ACK, - NI660X_G1_INT_ACK, - NI660X_G2_INT_ACK, - NI660X_G3_INT_ACK, - NI660X_G0_STATUS, - NI660X_G1_STATUS, - NI660X_G2_STATUS, - NI660X_G3_STATUS, - NI660X_G0_INT_ENA, - NI660X_G1_INT_ENA, - NI660X_G2_INT_ENA, - NI660X_G3_INT_ENA, - + /* see enum ni_gpct_register */ NI660X_STC_DIO_PARALLEL_INPUT = NITIO_NUM_REGS, NI660X_STC_DIO_OUTPUT, NI660X_STC_DIO_CONTROL, @@ -172,78 +104,78 @@ struct ni_660x_register_data { }; static const struct ni_660x_register_data ni_660x_reg_data[NI660X_NUM_REGS] = { - [NI660X_G0_INT_ACK] = { 0x004, 2 }, /* write */ - [NI660X_G0_STATUS] = { 0x004, 2 }, /* read */ - [NI660X_G1_INT_ACK] = { 0x006, 2 }, /* write */ - [NI660X_G1_STATUS] = { 0x006, 2 }, /* read */ - [NI660X_G01_STATUS] = { 0x008, 2 }, /* read */ - [NI660X_G0_CMD] = { 0x00c, 2 }, /* write */ + [NITIO_G0_INT_ACK] = { 0x004, 2 }, /* write */ + [NITIO_G0_STATUS] = { 0x004, 2 }, /* read */ + [NITIO_G1_INT_ACK] = { 0x006, 2 }, /* write */ + [NITIO_G1_STATUS] = { 0x006, 2 }, /* read */ + [NITIO_G01_STATUS] = { 0x008, 2 }, /* read */ + [NITIO_G0_CMD] = { 0x00c, 2 }, /* write */ [NI660X_STC_DIO_PARALLEL_INPUT] = { 0x00e, 2 }, /* read */ - [NI660X_G1_CMD] = { 0x00e, 2 }, /* write */ - [NI660X_G0_HW_SAVE] = { 0x010, 4 }, /* read */ - [NI660X_G1_HW_SAVE] = { 0x014, 4 }, /* read */ + [NITIO_G1_CMD] = { 0x00e, 2 }, /* write */ + [NITIO_G0_HW_SAVE] = { 0x010, 4 }, /* read */ + [NITIO_G1_HW_SAVE] = { 0x014, 4 }, /* read */ [NI660X_STC_DIO_OUTPUT] = { 0x014, 2 }, /* write */ [NI660X_STC_DIO_CONTROL] = { 0x016, 2 }, /* write */ - [NI660X_G0_SW_SAVE] = { 0x018, 4 }, /* read */ - [NI660X_G1_SW_SAVE] = { 0x01c, 4 }, /* read */ - [NI660X_G0_MODE] = { 0x034, 2 }, /* write */ - [NI660X_G01_STATUS1] = { 0x036, 2 }, /* read */ - [NI660X_G1_MODE] = { 0x036, 2 }, /* write */ + [NITIO_G0_SW_SAVE] = { 0x018, 4 }, /* read */ + [NITIO_G1_SW_SAVE] = { 0x01c, 4 }, /* read */ + [NITIO_G0_MODE] = { 0x034, 2 }, /* write */ + [NITIO_G01_STATUS1] = { 0x036, 2 }, /* read */ + [NITIO_G1_MODE] = { 0x036, 2 }, /* write */ [NI660X_STC_DIO_SERIAL_INPUT] = { 0x038, 2 }, /* read */ - [NI660X_G0_LOADA] = { 0x038, 4 }, /* write */ - [NI660X_G01_STATUS2] = { 0x03a, 2 }, /* read */ - [NI660X_G0_LOADB] = { 0x03c, 4 }, /* write */ - [NI660X_G1_LOADA] = { 0x040, 4 }, /* write */ - [NI660X_G1_LOADB] = { 0x044, 4 }, /* write */ - [NI660X_G0_INPUT_SEL] = { 0x048, 2 }, /* write */ - [NI660X_G1_INPUT_SEL] = { 0x04a, 2 }, /* write */ - [NI660X_G0_AUTO_INC] = { 0x088, 2 }, /* write */ - [NI660X_G1_AUTO_INC] = { 0x08a, 2 }, /* write */ - [NI660X_G01_RESET] = { 0x090, 2 }, /* write */ - [NI660X_G0_INT_ENA] = { 0x092, 2 }, /* write */ - [NI660X_G1_INT_ENA] = { 0x096, 2 }, /* write */ - [NI660X_G0_CNT_MODE] = { 0x0b0, 2 }, /* write */ - [NI660X_G1_CNT_MODE] = { 0x0b2, 2 }, /* write */ - [NI660X_G0_GATE2] = { 0x0b4, 2 }, /* write */ - [NI660X_G1_GATE2] = { 0x0b6, 2 }, /* write */ - [NI660X_G0_DMA_CFG] = { 0x0b8, 2 }, /* write */ - [NI660X_G0_DMA_STATUS] = { 0x0b8, 2 }, /* read */ - [NI660X_G1_DMA_CFG] = { 0x0ba, 2 }, /* write */ - [NI660X_G1_DMA_STATUS] = { 0x0ba, 2 }, /* read */ - [NI660X_G2_INT_ACK] = { 0x104, 2 }, /* write */ - [NI660X_G2_STATUS] = { 0x104, 2 }, /* read */ - [NI660X_G3_INT_ACK] = { 0x106, 2 }, /* write */ - [NI660X_G3_STATUS] = { 0x106, 2 }, /* read */ - [NI660X_G23_STATUS] = { 0x108, 2 }, /* read */ - [NI660X_G2_CMD] = { 0x10c, 2 }, /* write */ - [NI660X_G3_CMD] = { 0x10e, 2 }, /* write */ - [NI660X_G2_HW_SAVE] = { 0x110, 4 }, /* read */ - [NI660X_G3_HW_SAVE] = { 0x114, 4 }, /* read */ - [NI660X_G2_SW_SAVE] = { 0x118, 4 }, /* read */ - [NI660X_G3_SW_SAVE] = { 0x11c, 4 }, /* read */ - [NI660X_G2_MODE] = { 0x134, 2 }, /* write */ - [NI660X_G23_STATUS1] = { 0x136, 2 }, /* read */ - [NI660X_G3_MODE] = { 0x136, 2 }, /* write */ - [NI660X_G2_LOADA] = { 0x138, 4 }, /* write */ - [NI660X_G23_STATUS2] = { 0x13a, 2 }, /* read */ - [NI660X_G2_LOADB] = { 0x13c, 4 }, /* write */ - [NI660X_G3_LOADA] = { 0x140, 4 }, /* write */ - [NI660X_G3_LOADB] = { 0x144, 4 }, /* write */ - [NI660X_G2_INPUT_SEL] = { 0x148, 2 }, /* write */ - [NI660X_G3_INPUT_SEL] = { 0x14a, 2 }, /* write */ - [NI660X_G2_AUTO_INC] = { 0x188, 2 }, /* write */ - [NI660X_G3_AUTO_INC] = { 0x18a, 2 }, /* write */ - [NI660X_G23_RESET] = { 0x190, 2 }, /* write */ - [NI660X_G2_INT_ENA] = { 0x192, 2 }, /* write */ - [NI660X_G3_INT_ENA] = { 0x196, 2 }, /* write */ - [NI660X_G2_CNT_MODE] = { 0x1b0, 2 }, /* write */ - [NI660X_G3_CNT_MODE] = { 0x1b2, 2 }, /* write */ - [NI660X_G3_GATE2] = { 0x1b6, 2 }, /* write */ - [NI660X_G2_GATE2] = { 0x1b4, 2 }, /* write */ - [NI660X_G2_DMA_CFG] = { 0x1b8, 2 }, /* write */ - [NI660X_G2_DMA_STATUS] = { 0x1b8, 2 }, /* read */ - [NI660X_G3_DMA_CFG] = { 0x1ba, 2 }, /* write */ - [NI660X_G3_DMA_STATUS] = { 0x1ba, 2 }, /* read */ + [NITIO_G0_LOADA] = { 0x038, 4 }, /* write */ + [NITIO_G01_STATUS2] = { 0x03a, 2 }, /* read */ + [NITIO_G0_LOADB] = { 0x03c, 4 }, /* write */ + [NITIO_G1_LOADA] = { 0x040, 4 }, /* write */ + [NITIO_G1_LOADB] = { 0x044, 4 }, /* write */ + [NITIO_G0_INPUT_SEL] = { 0x048, 2 }, /* write */ + [NITIO_G1_INPUT_SEL] = { 0x04a, 2 }, /* write */ + [NITIO_G0_AUTO_INC] = { 0x088, 2 }, /* write */ + [NITIO_G1_AUTO_INC] = { 0x08a, 2 }, /* write */ + [NITIO_G01_RESET] = { 0x090, 2 }, /* write */ + [NITIO_G0_INT_ENA] = { 0x092, 2 }, /* write */ + [NITIO_G1_INT_ENA] = { 0x096, 2 }, /* write */ + [NITIO_G0_CNT_MODE] = { 0x0b0, 2 }, /* write */ + [NITIO_G1_CNT_MODE] = { 0x0b2, 2 }, /* write */ + [NITIO_G0_GATE2] = { 0x0b4, 2 }, /* write */ + [NITIO_G1_GATE2] = { 0x0b6, 2 }, /* write */ + [NITIO_G0_DMA_CFG] = { 0x0b8, 2 }, /* write */ + [NITIO_G0_DMA_STATUS] = { 0x0b8, 2 }, /* read */ + [NITIO_G1_DMA_CFG] = { 0x0ba, 2 }, /* write */ + [NITIO_G1_DMA_STATUS] = { 0x0ba, 2 }, /* read */ + [NITIO_G2_INT_ACK] = { 0x104, 2 }, /* write */ + [NITIO_G2_STATUS] = { 0x104, 2 }, /* read */ + [NITIO_G3_INT_ACK] = { 0x106, 2 }, /* write */ + [NITIO_G3_STATUS] = { 0x106, 2 }, /* read */ + [NITIO_G23_STATUS] = { 0x108, 2 }, /* read */ + [NITIO_G2_CMD] = { 0x10c, 2 }, /* write */ + [NITIO_G3_CMD] = { 0x10e, 2 }, /* write */ + [NITIO_G2_HW_SAVE] = { 0x110, 4 }, /* read */ + [NITIO_G3_HW_SAVE] = { 0x114, 4 }, /* read */ + [NITIO_G2_SW_SAVE] = { 0x118, 4 }, /* read */ + [NITIO_G3_SW_SAVE] = { 0x11c, 4 }, /* read */ + [NITIO_G2_MODE] = { 0x134, 2 }, /* write */ + [NITIO_G23_STATUS1] = { 0x136, 2 }, /* read */ + [NITIO_G3_MODE] = { 0x136, 2 }, /* write */ + [NITIO_G2_LOADA] = { 0x138, 4 }, /* write */ + [NITIO_G23_STATUS2] = { 0x13a, 2 }, /* read */ + [NITIO_G2_LOADB] = { 0x13c, 4 }, /* write */ + [NITIO_G3_LOADA] = { 0x140, 4 }, /* write */ + [NITIO_G3_LOADB] = { 0x144, 4 }, /* write */ + [NITIO_G2_INPUT_SEL] = { 0x148, 2 }, /* write */ + [NITIO_G3_INPUT_SEL] = { 0x14a, 2 }, /* write */ + [NITIO_G2_AUTO_INC] = { 0x188, 2 }, /* write */ + [NITIO_G3_AUTO_INC] = { 0x18a, 2 }, /* write */ + [NITIO_G23_RESET] = { 0x190, 2 }, /* write */ + [NITIO_G2_INT_ENA] = { 0x192, 2 }, /* write */ + [NITIO_G3_INT_ENA] = { 0x196, 2 }, /* write */ + [NITIO_G2_CNT_MODE] = { 0x1b0, 2 }, /* write */ + [NITIO_G3_CNT_MODE] = { 0x1b2, 2 }, /* write */ + [NITIO_G2_GATE2] = { 0x1b4, 2 }, /* write */ + [NITIO_G3_GATE2] = { 0x1b6, 2 }, /* write */ + [NITIO_G2_DMA_CFG] = { 0x1b8, 2 }, /* write */ + [NITIO_G2_DMA_STATUS] = { 0x1b8, 2 }, /* read */ + [NITIO_G3_DMA_CFG] = { 0x1ba, 2 }, /* write */ + [NITIO_G3_DMA_STATUS] = { 0x1ba, 2 }, /* read */ [NI660X_DIO32_INPUT] = { 0x414, 4 }, /* read */ [NI660X_DIO32_OUTPUT] = { 0x510, 4 }, /* write */ [NI660X_CLK_CFG] = { 0x73c, 4 }, /* write */ @@ -272,77 +204,6 @@ static const struct ni_660x_register_data ni_660x_reg_data[NI660X_NUM_REGS] = { [NI660X_IO_CFG_38_39] = { 0x7a2, 2 } /* read/write */ }; -static const enum ni_660x_register ni_gpct_to_660x_register[] = { - [NITIO_G0_AUTO_INC] = NI660X_G0_AUTO_INC, - [NITIO_G1_AUTO_INC] = NI660X_G1_AUTO_INC, - [NITIO_G2_AUTO_INC] = NI660X_G2_AUTO_INC, - [NITIO_G3_AUTO_INC] = NI660X_G3_AUTO_INC, - [NITIO_G0_CMD] = NI660X_G0_CMD, - [NITIO_G1_CMD] = NI660X_G1_CMD, - [NITIO_G2_CMD] = NI660X_G2_CMD, - [NITIO_G3_CMD] = NI660X_G3_CMD, - [NITIO_G0_HW_SAVE] = NI660X_G0_HW_SAVE, - [NITIO_G1_HW_SAVE] = NI660X_G1_HW_SAVE, - [NITIO_G2_HW_SAVE] = NI660X_G2_HW_SAVE, - [NITIO_G3_HW_SAVE] = NI660X_G3_HW_SAVE, - [NITIO_G0_SW_SAVE] = NI660X_G0_SW_SAVE, - [NITIO_G1_SW_SAVE] = NI660X_G1_SW_SAVE, - [NITIO_G2_SW_SAVE] = NI660X_G2_SW_SAVE, - [NITIO_G3_SW_SAVE] = NI660X_G3_SW_SAVE, - [NITIO_G0_MODE] = NI660X_G0_MODE, - [NITIO_G1_MODE] = NI660X_G1_MODE, - [NITIO_G2_MODE] = NI660X_G2_MODE, - [NITIO_G3_MODE] = NI660X_G3_MODE, - [NITIO_G0_LOADA] = NI660X_G0_LOADA, - [NITIO_G1_LOADA] = NI660X_G1_LOADA, - [NITIO_G2_LOADA] = NI660X_G2_LOADA, - [NITIO_G3_LOADA] = NI660X_G3_LOADA, - [NITIO_G0_LOADB] = NI660X_G0_LOADB, - [NITIO_G1_LOADB] = NI660X_G1_LOADB, - [NITIO_G2_LOADB] = NI660X_G2_LOADB, - [NITIO_G3_LOADB] = NI660X_G3_LOADB, - [NITIO_G0_INPUT_SEL] = NI660X_G0_INPUT_SEL, - [NITIO_G1_INPUT_SEL] = NI660X_G1_INPUT_SEL, - [NITIO_G2_INPUT_SEL] = NI660X_G2_INPUT_SEL, - [NITIO_G3_INPUT_SEL] = NI660X_G3_INPUT_SEL, - [NITIO_G0_CNT_MODE] = NI660X_G0_CNT_MODE, - [NITIO_G1_CNT_MODE] = NI660X_G1_CNT_MODE, - [NITIO_G2_CNT_MODE] = NI660X_G2_CNT_MODE, - [NITIO_G3_CNT_MODE] = NI660X_G3_CNT_MODE, - [NITIO_G0_GATE2] = NI660X_G0_GATE2, - [NITIO_G1_GATE2] = NI660X_G1_GATE2, - [NITIO_G2_GATE2] = NI660X_G2_GATE2, - [NITIO_G3_GATE2] = NI660X_G3_GATE2, - [NITIO_G01_STATUS] = NI660X_G01_STATUS, - [NITIO_G23_STATUS] = NI660X_G23_STATUS, - [NITIO_G01_RESET] = NI660X_G01_RESET, - [NITIO_G23_RESET] = NI660X_G23_RESET, - [NITIO_G01_STATUS1] = NI660X_G01_STATUS1, - [NITIO_G23_STATUS1] = NI660X_G23_STATUS1, - [NITIO_G01_STATUS2] = NI660X_G01_STATUS2, - [NITIO_G23_STATUS2] = NI660X_G23_STATUS2, - [NITIO_G0_DMA_CFG] = NI660X_G0_DMA_CFG, - [NITIO_G1_DMA_CFG] = NI660X_G1_DMA_CFG, - [NITIO_G2_DMA_CFG] = NI660X_G2_DMA_CFG, - [NITIO_G3_DMA_CFG] = NI660X_G3_DMA_CFG, - [NITIO_G0_DMA_STATUS] = NI660X_G0_DMA_STATUS, - [NITIO_G1_DMA_STATUS] = NI660X_G1_DMA_STATUS, - [NITIO_G2_DMA_STATUS] = NI660X_G2_DMA_STATUS, - [NITIO_G3_DMA_STATUS] = NI660X_G3_DMA_STATUS, - [NITIO_G0_INT_ACK] = NI660X_G0_INT_ACK, - [NITIO_G1_INT_ACK] = NI660X_G1_INT_ACK, - [NITIO_G2_INT_ACK] = NI660X_G2_INT_ACK, - [NITIO_G3_INT_ACK] = NI660X_G3_INT_ACK, - [NITIO_G0_STATUS] = NI660X_G0_STATUS, - [NITIO_G1_STATUS] = NI660X_G1_STATUS, - [NITIO_G2_STATUS] = NI660X_G2_STATUS, - [NITIO_G3_STATUS] = NI660X_G3_STATUS, - [NITIO_G0_INT_ENA] = NI660X_G0_INT_ENA, - [NITIO_G1_INT_ENA] = NI660X_G1_INT_ENA, - [NITIO_G2_INT_ENA] = NI660X_G2_INT_ENA, - [NITIO_G3_INT_ENA] = NI660X_G3_INT_ENA, -}; - /* Offset of the GPCT chips from the base-address of the card */ /* First chip is at base-address + 0x00, etc. */ static const unsigned GPCT_OFFSET[2] = { 0x0, 0x800 }; @@ -409,9 +270,8 @@ struct ni_660x_private { u64 io_dir; }; -static void ni_660x_write(struct comedi_device *dev, - unsigned int chip, unsigned int bits, - enum ni_660x_register reg) +static void ni_660x_write(struct comedi_device *dev, unsigned int chip, + unsigned int bits, unsigned int reg) { unsigned int addr = GPCT_OFFSET[chip] + ni_660x_reg_data[reg].offset; @@ -422,8 +282,7 @@ static void ni_660x_write(struct comedi_device *dev, } static unsigned int ni_660x_read(struct comedi_device *dev, - unsigned int chip, - enum ni_660x_register reg) + unsigned int chip, unsigned int reg) { unsigned int addr = GPCT_OFFSET[chip] + ni_660x_reg_data[reg].offset; @@ -436,34 +295,16 @@ static void ni_660x_gpct_write(struct ni_gpct *counter, unsigned int bits, enum ni_gpct_register reg) { struct comedi_device *dev = counter->counter_dev->dev; - enum ni_660x_register ni_660x_register; - - if (reg < ARRAY_SIZE(ni_gpct_to_660x_register)) { - ni_660x_register = ni_gpct_to_660x_register[reg]; - } else { - dev_warn(dev->class_dev, "%s: unhandled register=0x%x\n", - __func__, reg); - return; - } - ni_660x_write(dev, counter->chip_index, bits, ni_660x_register); + ni_660x_write(dev, counter->chip_index, bits, reg); } static unsigned int ni_660x_gpct_read(struct ni_gpct *counter, enum ni_gpct_register reg) { struct comedi_device *dev = counter->counter_dev->dev; - enum ni_660x_register ni_660x_register; - - if (reg < ARRAY_SIZE(ni_gpct_to_660x_register)) { - ni_660x_register = ni_gpct_to_660x_register[reg]; - } else { - dev_warn(dev->class_dev, "%s: unhandled register=0x%x\n", - __func__, reg); - return 0; - } - return ni_660x_read(dev, counter->chip_index, ni_660x_register); + return ni_660x_read(dev, counter->chip_index, reg); } static inline void ni_660x_set_dma_channel(struct comedi_device *dev, -- cgit v1.2.3 From 80c67b37fc27a3fc0542916798242e4af8148f28 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:51 -0700 Subject: staging: comedi: ni_660x: remove spinlock 'dma_cfg_lock' This spinlock is only used to protect changes to the private data 'dma_cfg'. Before calling any function that would change the 'dma_cfg' the spinlock 'mite_channel_lock' is also locked. That spinlock is not unlocked until after the 'dma_cfg' change. Remove the redundant spinlock. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 85c793a458f8..3b57ce59273e 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -263,8 +263,6 @@ struct ni_660x_private { spinlock_t mite_channel_lock; /* prevents races between interrupt and comedi_poll */ spinlock_t interrupt_lock; - /* protects dma_cfg changes */ - spinlock_t dma_cfg_lock; unsigned int dma_cfg[NI660X_MAX_CHIPS]; unsigned int io_cfg[NI660X_NUM_PFI_CHANNELS]; u64 io_dir; @@ -313,9 +311,7 @@ static inline void ni_660x_set_dma_channel(struct comedi_device *dev, { struct ni_660x_private *devpriv = dev->private; unsigned int chip = counter->chip_index; - unsigned long flags; - spin_lock_irqsave(&devpriv->dma_cfg_lock, flags); devpriv->dma_cfg[chip] &= ~NI660X_DMA_CFG_SEL_MASK(mite_channel); devpriv->dma_cfg[chip] |= NI660X_DMA_CFG_SEL(mite_channel, counter->counter_index); @@ -323,7 +319,6 @@ static inline void ni_660x_set_dma_channel(struct comedi_device *dev, NI660X_DMA_CFG_RESET(mite_channel), NI660X_DMA_CFG); mmiowb(); - spin_unlock_irqrestore(&devpriv->dma_cfg_lock, flags); } static inline void ni_660x_unset_dma_channel(struct comedi_device *dev, @@ -332,14 +327,11 @@ static inline void ni_660x_unset_dma_channel(struct comedi_device *dev, { struct ni_660x_private *devpriv = dev->private; unsigned int chip = counter->chip_index; - unsigned long flags; - spin_lock_irqsave(&devpriv->dma_cfg_lock, flags); devpriv->dma_cfg[chip] &= ~NI660X_DMA_CFG_SEL_MASK(mite_channel); devpriv->dma_cfg[chip] |= NI660X_DMA_CFG_SEL_NONE(mite_channel); ni_660x_write(dev, chip, devpriv->dma_cfg[chip], NI660X_DMA_CFG); mmiowb(); - spin_unlock_irqrestore(&devpriv->dma_cfg_lock, flags); } static int ni_660x_request_mite_channel(struct comedi_device *dev, @@ -500,7 +492,6 @@ static int ni_660x_allocate_private(struct comedi_device *dev) spin_lock_init(&devpriv->mite_channel_lock); spin_lock_init(&devpriv->interrupt_lock); - spin_lock_init(&devpriv->dma_cfg_lock); for (i = 0; i < NI660X_NUM_PFI_CHANNELS; ++i) devpriv->io_cfg[i] = NI_660X_PFI_OUTPUT_COUNTER; -- cgit v1.2.3 From 8f266d508c7aa7dad84fbb0d793aa95e8af95169 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:52 -0700 Subject: staging: comedi: ni_660x: refactor GPCT_OFFSET This driver supports boards that have 1 or 2 TIO chips with base addresses 0x800 apart. Replace the static const array 'GPCT_OFFSET' with a define and calculate the base address based on the chip index. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 3b57ce59273e..73ccd62eb450 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -204,9 +204,7 @@ static const struct ni_660x_register_data ni_660x_reg_data[NI660X_NUM_REGS] = { [NI660X_IO_CFG_38_39] = { 0x7a2, 2 } /* read/write */ }; -/* Offset of the GPCT chips from the base-address of the card */ -/* First chip is at base-address + 0x00, etc. */ -static const unsigned GPCT_OFFSET[2] = { 0x0, 0x800 }; +#define NI660X_CHIP_OFFSET 0x800 enum ni_660x_boardid { BOARD_PCI6601, @@ -271,7 +269,8 @@ struct ni_660x_private { static void ni_660x_write(struct comedi_device *dev, unsigned int chip, unsigned int bits, unsigned int reg) { - unsigned int addr = GPCT_OFFSET[chip] + ni_660x_reg_data[reg].offset; + unsigned int addr = (chip * NI660X_CHIP_OFFSET) + + ni_660x_reg_data[reg].offset; if (ni_660x_reg_data[reg].size == 2) writew(bits, dev->mmio + addr); @@ -282,7 +281,8 @@ static void ni_660x_write(struct comedi_device *dev, unsigned int chip, static unsigned int ni_660x_read(struct comedi_device *dev, unsigned int chip, unsigned int reg) { - unsigned int addr = GPCT_OFFSET[chip] + ni_660x_reg_data[reg].offset; + unsigned int addr = (chip * NI660X_CHIP_OFFSET) + + ni_660x_reg_data[reg].offset; if (ni_660x_reg_data[reg].size == 2) return readw(dev->mmio + addr); -- cgit v1.2.3 From 47470216cc2fe413156aa44d7ae55e65712b0931 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:53 -0700 Subject: staging: comedi: ni_660x: update the MODULE_DESCRIPTION Change the generic MODULE_DESCRIPTION text to something more useful. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 73ccd62eb450..4345bdcec68e 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -940,5 +940,5 @@ static struct pci_driver ni_660x_pci_driver = { module_comedi_pci_driver(ni_660x_driver, ni_660x_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); -MODULE_DESCRIPTION("Comedi low-level driver"); +MODULE_DESCRIPTION("Comedi driver for NI 660x counter/timer boards"); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 581867bd9151ee77fad4b0fe47af96d923ac9ec2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 Mar 2016 12:24:29 -0700 Subject: staging: comedi: dt282x: refactor dt282x_ns_to_timer() Define the pacer clock limits and remove the magic numbers. Refactor the code to use a common path to return the actual 'ns' timing and the timer divisor value. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt282x.c | 36 ++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index 06a87a10a2d0..e6958eaf5178 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -113,6 +113,17 @@ #define DT2821_SUPCSR_XCLK BIT(1) #define DT2821_SUPCSR_BDINIT BIT(0) #define DT2821_TMRCTR_REG 0x0e +#define DT2821_TMRCTR_PRESCALE(x) (((x) & 0xf) << 8) +#define DT2821_TMRCTR_DIVIDER(x) ((255 - ((x) & 0xff)) << 0) + +/* Pacer Clock */ +#define DT2821_OSC_BASE 250 /* 4 MHz (in nanoseconds) */ +#define DT2821_PRESCALE(x) BIT(x) +#define DT2821_PRESCALE_MAX 15 +#define DT2821_DIVIDER_MAX 255 +#define DT2821_OSC_MAX (DT2821_OSC_BASE * \ + DT2821_PRESCALE(DT2821_PRESCALE_MAX) * \ + DT2821_DIVIDER_MAX) static const struct comedi_lrange range_dt282x_ai_lo_bipolar = { 4, { @@ -365,10 +376,10 @@ static unsigned int dt282x_ns_to_timer(unsigned int *ns, unsigned int flags) { unsigned int prescale, base, divider; - for (prescale = 0; prescale < 16; prescale++) { - if (prescale == 1) + for (prescale = 0; prescale <= DT2821_PRESCALE_MAX; prescale++) { + if (prescale == 1) /* 0 and 1 are both divide by 1 */ continue; - base = 250 * (1 << prescale); + base = DT2821_OSC_BASE * DT2821_PRESCALE(prescale); switch (flags & CMDF_ROUND_MASK) { case CMDF_ROUND_NEAREST: default: @@ -381,15 +392,17 @@ static unsigned int dt282x_ns_to_timer(unsigned int *ns, unsigned int flags) divider = DIV_ROUND_UP(*ns, base); break; } - if (divider < 256) { - *ns = divider * base; - return (prescale << 8) | (255 - divider); - } + if (divider <= DT2821_DIVIDER_MAX) + break; + } + if (divider > DT2821_DIVIDER_MAX) { + prescale = DT2821_PRESCALE_MAX; + divider = DT2821_DIVIDER_MAX; + base = DT2821_OSC_BASE * DT2821_PRESCALE(prescale); } - base = 250 * (1 << 15); - divider = 255; *ns = divider * base; - return (15 << 8) | (255 - divider); + return DT2821_TMRCTR_PRESCALE(prescale) | + DT2821_TMRCTR_DIVIDER(divider); } static void dt282x_munge(struct comedi_device *dev, @@ -689,8 +702,7 @@ static int dt282x_ai_cmdtest(struct comedi_device *dev, err |= comedi_check_trigger_arg_min(&cmd->convert_arg, 4000); -#define SLOWEST_TIMER (250*(1<<15)*255) - err |= comedi_check_trigger_arg_max(&cmd->convert_arg, SLOWEST_TIMER); + err |= comedi_check_trigger_arg_max(&cmd->convert_arg, DT2821_OSC_MAX); err |= comedi_check_trigger_arg_min(&cmd->convert_arg, board->ai_speed); err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); -- cgit v1.2.3 From 20ea5c3506abfe46c98dfa47d1bf933e2efa15c9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 Mar 2016 12:24:30 -0700 Subject: staging: comedi: dt282x: remove redundant comedi_check_trigger_arg_min() The 'convert_arg' sets the acquisition timing of the analog input command. The maximum speed (the minimum timing) depends on the board 'ai_speed' which if always >= 4000. Remove the redundant 'min' check, Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt282x.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index e6958eaf5178..661c3ada0712 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -697,11 +697,7 @@ static int dt282x_ai_cmdtest(struct comedi_device *dev, /* Step 3: check if arguments are trivially valid */ err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0); - err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0); - - err |= comedi_check_trigger_arg_min(&cmd->convert_arg, 4000); - err |= comedi_check_trigger_arg_max(&cmd->convert_arg, DT2821_OSC_MAX); err |= comedi_check_trigger_arg_min(&cmd->convert_arg, board->ai_speed); err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg, -- cgit v1.2.3 From f91e45e2acbd300c5042c9ce0133dbc602da9788 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 Mar 2016 12:24:31 -0700 Subject: staging: comedi: dt282x: remove unnecessary comment The "Configuration options" are documented in the comedi driver comment block. Remove the redundant comment before the drivers (*attach) function. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt282x.c | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index 661c3ada0712..d5295bbdd28c 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -1093,20 +1093,6 @@ static int dt282x_initialize(struct comedi_device *dev) return 0; } -/* - options: - 0 i/o base - 1 irq - 2 dma1 - 3 dma2 - 4 0=single ended, 1=differential - 5 ai 0=straight binary, 1=2's comp - 6 ao0 0=straight binary, 1=2's comp - 7 ao1 0=straight binary, 1=2's comp - 8 ai 0=±10 V, 1=0-10 V, 2=±5 V, 3=0-5 V - 9 ao0 0=±10 V, 1=0-10 V, 2=±5 V, 3=0-5 V, 4=±2.5 V - 10 ao1 0=±10 V, 1=0-10 V, 2=±5 V, 3=0-5 V, 4=±2.5 V - */ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct dt282x_board *board = dev->board_ptr; -- cgit v1.2.3 From c5f764057f2313673aaf046776e6d573bf2662b6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:21:35 -0700 Subject: staging: comedi: ni_labpc: remove some unnecessary defines The EEPROM_SIZE and NUM_AO_CHAN defines are only used once and they don't add any significant clarity to the driver. They are also pretty generic symbol names. Remove them and just open code the values. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_labpc.h | 3 --- drivers/staging/comedi/drivers/ni_labpc_common.c | 6 +++--- 2 files changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_labpc.h b/drivers/staging/comedi/drivers/ni_labpc.h index 83f878adbd53..74db3ba82ab5 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.h +++ b/drivers/staging/comedi/drivers/ni_labpc.h @@ -19,9 +19,6 @@ #ifndef _NI_LABPC_H #define _NI_LABPC_H -#define EEPROM_SIZE 256 /* 256 byte eeprom */ -#define NUM_AO_CHAN 2 /* boards have two analog output channels */ - enum transfer_type { fifo_not_empty_transfer, fifo_half_full_transfer, isa_dma_transfer }; diff --git a/drivers/staging/comedi/drivers/ni_labpc_common.c b/drivers/staging/comedi/drivers/ni_labpc_common.c index 863afb28ee28..55ab05e3196b 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_common.c +++ b/drivers/staging/comedi/drivers/ni_labpc_common.c @@ -1261,7 +1261,7 @@ int labpc_common_attach(struct comedi_device *dev, if (board->has_ao) { s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND; - s->n_chan = NUM_AO_CHAN; + s->n_chan = 2; s->maxdata = 0x0fff; s->range_table = &range_labpc_ao; s->insn_write = labpc_ao_insn_write; @@ -1307,12 +1307,12 @@ int labpc_common_attach(struct comedi_device *dev, s->type = COMEDI_SUBD_UNUSED; } - /* EEPROM */ + /* EEPROM (256 bytes) */ s = &dev->subdevices[4]; if (board->is_labpc1200) { s->type = COMEDI_SUBD_MEMORY; s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; - s->n_chan = EEPROM_SIZE; + s->n_chan = 256; s->maxdata = 0xff; s->insn_write = labpc_eeprom_insn_write; -- cgit v1.2.3 From 447785c641cafe586bcb6678e63e436904536432 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:21:36 -0700 Subject: staging: comedi: ni_labpc_regs.h: tidy up bit defines As suggested by checkpatch.pl: CHECK: Prefer using the BIT macro Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_labpc_regs.h | 82 +++++++++++++------------- 1 file changed, 41 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_labpc_regs.h b/drivers/staging/comedi/drivers/ni_labpc_regs.h index 2a274a3e4e73..8c52179e36fc 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_regs.h +++ b/drivers/staging/comedi/drivers/ni_labpc_regs.h @@ -9,32 +9,32 @@ * Register map (all registers are 8-bit) */ #define STAT1_REG 0x00 /* R: Status 1 reg */ -#define STAT1_DAVAIL (1 << 0) -#define STAT1_OVERRUN (1 << 1) -#define STAT1_OVERFLOW (1 << 2) -#define STAT1_CNTINT (1 << 3) -#define STAT1_GATA0 (1 << 5) -#define STAT1_EXTGATA0 (1 << 6) +#define STAT1_DAVAIL BIT(0) +#define STAT1_OVERRUN BIT(1) +#define STAT1_OVERFLOW BIT(2) +#define STAT1_CNTINT BIT(3) +#define STAT1_GATA0 BIT(5) +#define STAT1_EXTGATA0 BIT(6) #define CMD1_REG 0x00 /* W: Command 1 reg */ #define CMD1_MA(x) (((x) & 0x7) << 0) -#define CMD1_TWOSCMP (1 << 3) +#define CMD1_TWOSCMP BIT(3) #define CMD1_GAIN(x) (((x) & 0x7) << 4) -#define CMD1_SCANEN (1 << 7) +#define CMD1_SCANEN BIT(7) #define CMD2_REG 0x01 /* W: Command 2 reg */ -#define CMD2_PRETRIG (1 << 0) -#define CMD2_HWTRIG (1 << 1) -#define CMD2_SWTRIG (1 << 2) -#define CMD2_TBSEL (1 << 3) -#define CMD2_2SDAC0 (1 << 4) -#define CMD2_2SDAC1 (1 << 5) -#define CMD2_LDAC(x) (1 << (6 + (x))) +#define CMD2_PRETRIG BIT(0) +#define CMD2_HWTRIG BIT(1) +#define CMD2_SWTRIG BIT(2) +#define CMD2_TBSEL BIT(3) +#define CMD2_2SDAC0 BIT(4) +#define CMD2_2SDAC1 BIT(5) +#define CMD2_LDAC(x) BIT(6 + ((x) & 0x1)) #define CMD3_REG 0x02 /* W: Command 3 reg */ -#define CMD3_DMAEN (1 << 0) -#define CMD3_DIOINTEN (1 << 1) -#define CMD3_DMATCINTEN (1 << 2) -#define CMD3_CNTINTEN (1 << 3) -#define CMD3_ERRINTEN (1 << 4) -#define CMD3_FIFOINTEN (1 << 5) +#define CMD3_DMAEN BIT(0) +#define CMD3_DIOINTEN BIT(1) +#define CMD3_DMATCINTEN BIT(2) +#define CMD3_CNTINTEN BIT(3) +#define CMD3_ERRINTEN BIT(4) +#define CMD3_FIFOINTEN BIT(5) #define ADC_START_CONVERT_REG 0x03 /* W: Start Convert reg */ #define DAC_LSB_REG(x) (0x04 + 2 * (x)) /* W: DAC0/1 LSB reg */ #define DAC_MSB_REG(x) (0x05 + 2 * (x)) /* W: DAC0/1 MSB reg */ @@ -43,32 +43,32 @@ #define DMATC_CLEAR_REG 0x0a /* W: DMA Interrupt Clear reg */ #define TIMER_CLEAR_REG 0x0c /* W: Timer Interrupt Clear reg */ #define CMD6_REG 0x0e /* W: Command 6 reg */ -#define CMD6_NRSE (1 << 0) -#define CMD6_ADCUNI (1 << 1) -#define CMD6_DACUNI(x) (1 << (2 + (x))) -#define CMD6_HFINTEN (1 << 5) -#define CMD6_DQINTEN (1 << 6) -#define CMD6_SCANUP (1 << 7) +#define CMD6_NRSE BIT(0) +#define CMD6_ADCUNI BIT(1) +#define CMD6_DACUNI(x) BIT(2 + ((x) & 0x1)) +#define CMD6_HFINTEN BIT(5) +#define CMD6_DQINTEN BIT(6) +#define CMD6_SCANUP BIT(7) #define CMD4_REG 0x0f /* W: Command 3 reg */ -#define CMD4_INTSCAN (1 << 0) -#define CMD4_EOIRCV (1 << 1) -#define CMD4_ECLKDRV (1 << 2) -#define CMD4_SEDIFF (1 << 3) -#define CMD4_ECLKRCV (1 << 4) +#define CMD4_INTSCAN BIT(0) +#define CMD4_EOIRCV BIT(1) +#define CMD4_ECLKDRV BIT(2) +#define CMD4_SEDIFF BIT(3) +#define CMD4_ECLKRCV BIT(4) #define DIO_BASE_REG 0x10 /* R/W: 8255 DIO base reg */ #define COUNTER_A_BASE_REG 0x14 /* R/W: 8253 Counter A base reg */ #define COUNTER_B_BASE_REG 0x18 /* R/W: 8253 Counter B base reg */ #define CMD5_REG 0x1c /* W: Command 5 reg */ -#define CMD5_WRTPRT (1 << 2) -#define CMD5_DITHEREN (1 << 3) -#define CMD5_CALDACLD (1 << 4) -#define CMD5_SCLK (1 << 5) -#define CMD5_SDATA (1 << 6) -#define CMD5_EEPROMCS (1 << 7) +#define CMD5_WRTPRT BIT(2) +#define CMD5_DITHEREN BIT(3) +#define CMD5_CALDACLD BIT(4) +#define CMD5_SCLK BIT(5) +#define CMD5_SDATA BIT(6) +#define CMD5_EEPROMCS BIT(7) #define STAT2_REG 0x1d /* R: Status 2 reg */ -#define STAT2_PROMOUT (1 << 0) -#define STAT2_OUTA1 (1 << 1) -#define STAT2_FIFONHF (1 << 2) +#define STAT2_PROMOUT BIT(0) +#define STAT2_OUTA1 BIT(1) +#define STAT2_FIFONHF BIT(2) #define INTERVAL_COUNT_REG 0x1e /* W: Interval Counter Data reg */ #define INTERVAL_STROBE_REG 0x1f /* W: Interval Counter Strobe reg */ -- cgit v1.2.3 From a444abfc668405746767eb53f920531b2d40e8af Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:21:37 -0700 Subject: staging: comedi: ni_labpc_common: tidy up block comments Fix the checkpatch.pl issues: WARNING: Block comments use a trailing */ on a separate line Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_labpc_common.c | 59 +++++++++++++++--------- 1 file changed, 37 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_labpc_common.c b/drivers/staging/comedi/drivers/ni_labpc_common.c index 55ab05e3196b..b0dfb8eed16d 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_common.c +++ b/drivers/staging/comedi/drivers/ni_labpc_common.c @@ -84,8 +84,10 @@ static const struct comedi_lrange range_labpc_ao = { } }; -/* functions that do inb/outb and readb/writeb so we can use - * function pointers to decide which to use */ +/* + * functions that do inb/outb and readb/writeb so we can use + * function pointers to decide which to use + */ static unsigned int labpc_inb(struct comedi_device *dev, unsigned long reg) { return inb(dev->iobase + reg); @@ -656,19 +658,24 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* figure out what method we will use to transfer data */ if (devpriv->dma && - /* dma unsafe at RT priority, - * and too much setup time for CMDF_WAKE_EOS */ - (cmd->flags & (CMDF_WAKE_EOS | CMDF_PRIORITY)) == 0) + (cmd->flags & (CMDF_WAKE_EOS | CMDF_PRIORITY)) == 0) { + /* + * dma unsafe at RT priority, + * and too much setup time for CMDF_WAKE_EOS + */ xfer = isa_dma_transfer; - else if (/* pc-plus has no fifo-half full interrupt */ - board->is_labpc1200 && - /* wake-end-of-scan should interrupt on fifo not empty */ - (cmd->flags & CMDF_WAKE_EOS) == 0 && - /* make sure we are taking more than just a few points */ - (cmd->stop_src != TRIG_COUNT || devpriv->count > 256)) + } else if (board->is_labpc1200 && + (cmd->flags & CMDF_WAKE_EOS) == 0 && + (cmd->stop_src != TRIG_COUNT || devpriv->count > 256)) { + /* + * pc-plus has no fifo-half full interrupt + * wake-end-of-scan should interrupt on fifo not empty + * make sure we are taking more than just a few points + */ xfer = fifo_half_full_transfer; - else + } else { xfer = fifo_not_empty_transfer; + } devpriv->current_transfer = xfer; labpc_ai_set_chan_and_gain(dev, mode, chan, range, aref); @@ -679,9 +686,11 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* manual says to set scan enable bit on second pass */ if (mode == MODE_MULT_CHAN_UP || mode == MODE_MULT_CHAN_DOWN) { devpriv->cmd1 |= CMD1_SCANEN; - /* need a brief delay before enabling scan, or scan - * list will get screwed when you switch - * between scan up to scan down mode - dunno why */ + /* + * Need a brief delay before enabling scan, or scan + * list will get screwed when you switch between + * scan up to scan down mode - dunno why. + */ udelay(1); devpriv->write_byte(dev, devpriv->cmd1, CMD1_REG); } @@ -728,8 +737,10 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->cmd4 = 0; if (cmd->convert_src != TRIG_EXT) devpriv->cmd4 |= CMD4_ECLKRCV; - /* XXX should discard first scan when using interval scanning - * since manual says it is not synced with scan clock */ + /* + * XXX should discard first scan when using interval scanning + * since manual says it is not synced with scan clock. + */ if (!labpc_use_continuous_mode(cmd, mode)) { devpriv->cmd4 |= CMD4_INTSCAN; if (cmd->scan_begin_src == TRIG_EXT) @@ -795,8 +806,10 @@ static int labpc_drain_fifo(struct comedi_device *dev) return 0; } -/* makes sure all data acquired by board is transferred to comedi (used - * when acquisition is terminated by stop_src == TRIG_EXT). */ +/* + * Makes sure all data acquired by board is transferred to comedi (used + * when acquisition is terminated by stop_src == TRIG_EXT). + */ static void labpc_drain_dregs(struct comedi_device *dev) { struct labpc_private *devpriv = dev->private; @@ -907,9 +920,11 @@ static int labpc_ao_insn_write(struct comedi_device *dev, channel = CR_CHAN(insn->chanspec); - /* turn off pacing of analog output channel */ - /* note: hardware bug in daqcard-1200 means pacing cannot - * be independently enabled/disabled for its the two channels */ + /* + * Turn off pacing of analog output channel. + * NOTE: hardware bug in daqcard-1200 means pacing cannot + * be independently enabled/disabled for its the two channels. + */ spin_lock_irqsave(&dev->spinlock, flags); devpriv->cmd2 &= ~CMD2_LDAC(channel); devpriv->write_byte(dev, devpriv->cmd2, CMD2_REG); -- cgit v1.2.3 From a0b201caebfa863d89f0685127117c6c0dfe8c85 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:21:38 -0700 Subject: staging: comedi: ni_labpc_cs: fix block comment issues Fix the checkpatch.pl issues: WARNING: Block comments use * on subsequent lines WARNING: line over 80 characters Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_labpc_cs.c | 95 +++++++++++++--------------- 1 file changed, 44 insertions(+), 51 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_labpc_cs.c b/drivers/staging/comedi/drivers/ni_labpc_cs.c index a1c69ac075d5..3d4d0b9ad4e1 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_cs.c +++ b/drivers/staging/comedi/drivers/ni_labpc_cs.c @@ -1,57 +1,50 @@ /* - comedi/drivers/ni_labpc_cs.c - Driver for National Instruments daqcard-1200 boards - Copyright (C) 2001, 2002, 2003 Frank Mori Hess - - PCMCIA crap is adapted from dummy_cs.c 1.31 2001/08/24 12:13:13 - from the pcmcia package. - The initial developer of the pcmcia dummy_cs.c code is David A. Hinds - . Portions created by David A. Hinds - are Copyright (C) 1999 David A. Hinds. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -*/ -/* -Driver: ni_labpc_cs -Description: National Instruments Lab-PC (& compatibles) -Author: Frank Mori Hess -Devices: [National Instruments] DAQCard-1200 (daqcard-1200) -Status: works - -Thanks go to Fredrik Lingvall for much testing and perseverance in -helping to debug daqcard-1200 support. - -The 1200 series boards have onboard calibration dacs for correcting -analog input/output offsets and gains. The proper settings for these -caldacs are stored on the board's eeprom. To read the caldac values -from the eeprom and store them into a file that can be then be used by -comedilib, use the comedi_calibrate program. - -Configuration options: - none - -The daqcard-1200 has quirky chanlist requirements -when scanning multiple channels. Multiple channel scan -sequence must start at highest channel, then decrement down to -channel 0. Chanlists consisting of all one channel -are also legal, and allow you to pace conversions in bursts. - -*/ + * Driver for National Instruments daqcard-1200 boards + * Copyright (C) 2001, 2002, 2003 Frank Mori Hess + * + * PCMCIA crap is adapted from dummy_cs.c 1.31 2001/08/24 12:13:13 + * from the pcmcia package. + * The initial developer of the pcmcia dummy_cs.c code is David A. Hinds + * . Portions created by David A. Hinds + * are Copyright (C) 1999 David A. Hinds. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * General Public License for more details. + */ /* - -NI manuals: -340988a (daqcard-1200) - -*/ + * Driver: ni_labpc_cs + * Description: National Instruments Lab-PC (& compatibles) + * Author: Frank Mori Hess + * Devices: [National Instruments] DAQCard-1200 (daqcard-1200) + * Status: works + * + * Thanks go to Fredrik Lingvall for much testing and perseverance in + * helping to debug daqcard-1200 support. + * + * The 1200 series boards have onboard calibration dacs for correcting + * analog input/output offsets and gains. The proper settings for these + * caldacs are stored on the board's eeprom. To read the caldac values + * from the eeprom and store them into a file that can be then be used by + * comedilib, use the comedi_calibrate program. + * + * Configuration options: none + * + * The daqcard-1200 has quirky chanlist requirements when scanning multiple + * channels. Multiple channel scan sequence must start at highest channel, + * then decrement down to channel 0. Chanlists consisting of all one channel + * are also legal, and allow you to pace conversions in bursts. + * + * NI manuals: + * 340988a (daqcard-1200) + */ #include -- cgit v1.2.3 From 0edf7b85d31f5255814483dbedd70ed13456e7a5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:21:39 -0700 Subject: staging: comedi: ni_labpc_pci: tidy up bit define As suggested by checkpatch.pl: CHECK: Prefer using the BIT macro Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_labpc_pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_labpc_pci.c b/drivers/staging/comedi/drivers/ni_labpc_pci.c index 77d403801db5..cac089193121 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_pci.c +++ b/drivers/staging/comedi/drivers/ni_labpc_pci.c @@ -51,8 +51,8 @@ static const struct labpc_boardinfo labpc_pci_boards[] = { }; /* ripped from mite.h and mite_setup2() to avoid mite dependency */ -#define MITE_IODWBSR 0xc0 /* IO Device Window Base Size Register */ -#define WENAB (1 << 7) /* window enable */ +#define MITE_IODWBSR 0xc0 /* IO Device Window Base Size Register */ +#define WENAB BIT(7) /* window enable */ static int labpc_pci_mite_init(struct pci_dev *pcidev) { -- cgit v1.2.3 From 2460e3cd9f5fad5630b3f9ce556bd37b7b5323f0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:21:40 -0700 Subject: staging: comedi: ni_labpc.h: fix block comment issues Fix the checkpatch.pl issues: WARNING: Block comments use * on subsequent lines Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_labpc.h | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_labpc.h b/drivers/staging/comedi/drivers/ni_labpc.h index 74db3ba82ab5..be8d5cd3f7f0 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.h +++ b/drivers/staging/comedi/drivers/ni_labpc.h @@ -1,20 +1,18 @@ /* - ni_labpc.h - - Header for ni_labpc.c and ni_labpc_cs.c - - Copyright (C) 2003 Frank Mori Hess - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -*/ + * Header for ni_labpc ISA/PCMCIA/PCI drivers + * + * Copyright (C) 2003 Frank Mori Hess + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ #ifndef _NI_LABPC_H #define _NI_LABPC_H -- cgit v1.2.3 From bed05b6c3434e62310c2e37ef234f02ce57cf74d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:40 -0700 Subject: staging: comedi: ni_tio: make ni_gpct_device_destroy() NULL pointer safe Modify the pointer check to make this function NULL pointer safe. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c index b74e44ec521a..623fc6c7bff0 100644 --- a/drivers/staging/comedi/drivers/ni_tio.c +++ b/drivers/staging/comedi/drivers/ni_tio.c @@ -1413,7 +1413,7 @@ EXPORT_SYMBOL_GPL(ni_gpct_device_construct); void ni_gpct_device_destroy(struct ni_gpct_device *counter_dev) { - if (!counter_dev->counters) + if (!counter_dev) return; kfree(counter_dev->counters); kfree(counter_dev); -- cgit v1.2.3 From 99307a69bf7166325bb8f0b1f1afcb0a0a1aca9a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:10:42 -0700 Subject: staging: comedi: ni_mio_common: ni_gpct_device_destroy() can handle a NULL pointer Remove the unnecessary NULL pointer check. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_mio_common.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index dcaf7e89f299..71c8fd2cfff6 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -5675,8 +5675,6 @@ static void mio_common_detach(struct comedi_device *dev) { struct ni_private *devpriv = dev->private; - if (devpriv) { - if (devpriv->counter_dev) - ni_gpct_device_destroy(devpriv->counter_dev); - } + if (devpriv) + ni_gpct_device_destroy(devpriv->counter_dev); } -- cgit v1.2.3 From 1d734e3efabc6a4e6c68b2b21f626af1799124d6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:29:27 -0700 Subject: staging: comedi: z8536: tidy up bit defines Fix the checkpatch.pl issues: CHECK: Prefer using the BIT macro Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/z8536.h | 89 ++++++++++++++++++---------------- 1 file changed, 48 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/z8536.h b/drivers/staging/comedi/drivers/z8536.h index 7be53109cc8d..47eadbf4dcc0 100644 --- a/drivers/staging/comedi/drivers/z8536.h +++ b/drivers/staging/comedi/drivers/z8536.h @@ -24,11 +24,12 @@ #define Z8536_CFG_CTRL_PCE_CT3E BIT(4) /* Port C & C/T 3 Enable */ #define Z8536_CFG_CTRL_PLC BIT(3) /* Port A/B Link Control */ #define Z8536_CFG_CTRL_PAE BIT(2) /* Port A Enable */ -#define Z8536_CFG_CTRL_LC_INDEP (0 << 0)/* C/Ts Independent */ -#define Z8536_CFG_CTRL_LC_GATE (1 << 0)/* C/T 1 Out Gates C/T 2 */ -#define Z8536_CFG_CTRL_LC_TRIG (2 << 0)/* C/T 1 Out Triggers C/T 2 */ -#define Z8536_CFG_CTRL_LC_CLK (3 << 0)/* C/T 1 Out Clocks C/T 2 */ -#define Z8536_CFG_CTRL_LC_MASK (3 << 0)/* C/T Link Control mask */ +#define Z8536_CFG_CTRL_LC(x) (((x) & 0x3) << 0) /* Link Control */ +#define Z8536_CFG_CTRL_LC_INDEP Z8536_CFG_CTRL_LC(0)/* Independent */ +#define Z8536_CFG_CTRL_LC_GATE Z8536_CFG_CTRL_LC(1)/* 1 Gates 2 */ +#define Z8536_CFG_CTRL_LC_TRIG Z8536_CFG_CTRL_LC(2)/* 1 Triggers 2 */ +#define Z8536_CFG_CTRL_LC_CLK Z8536_CFG_CTRL_LC(3)/* 1 Clocks 2 */ +#define Z8536_CFG_CTRL_LC_MASK Z8536_CFG_CTRL_LC(3) /* Interrupt Vector registers */ #define Z8536_PA_INT_VECT_REG 0x02 @@ -43,15 +44,16 @@ #define Z8536_CT2_CMDSTAT_REG 0x0b #define Z8536_CT3_CMDSTAT_REG 0x0c #define Z8536_CT_CMDSTAT_REG(x) (0x0a + (x)) -#define Z8536_CMD_NULL (0 << 5)/* Null Code */ -#define Z8536_CMD_CLR_IP_IUS (1 << 5)/* Clear IP & IUS */ -#define Z8536_CMD_SET_IUS (2 << 5)/* Set IUS */ -#define Z8536_CMD_CLR_IUS (3 << 5)/* Clear IUS */ -#define Z8536_CMD_SET_IP (4 << 5)/* Set IP */ -#define Z8536_CMD_CLR_IP (5 << 5)/* Clear IP */ -#define Z8536_CMD_SET_IE (6 << 5)/* Set IE */ -#define Z8536_CMD_CLR_IE (7 << 5)/* Clear IE */ -#define Z8536_CMD_MASK (7 << 5) +#define Z8536_CMD(x) (((x) & 0x7) << 5) +#define Z8536_CMD_NULL Z8536_CMD(0) /* Null Code */ +#define Z8536_CMD_CLR_IP_IUS Z8536_CMD(1) /* Clear IP & IUS */ +#define Z8536_CMD_SET_IUS Z8536_CMD(2) /* Set IUS */ +#define Z8536_CMD_CLR_IUS Z8536_CMD(3) /* Clear IUS */ +#define Z8536_CMD_SET_IP Z8536_CMD(4) /* Set IP */ +#define Z8536_CMD_CLR_IP Z8536_CMD(5) /* Clear IP */ +#define Z8536_CMD_SET_IE Z8536_CMD(6) /* Set IE */ +#define Z8536_CMD_CLR_IE Z8536_CMD(7) /* Clear IE */ +#define Z8536_CMD_MASK Z8536_CMD(7) #define Z8536_STAT_IUS BIT(7) /* Interrupt Under Service */ #define Z8536_STAT_IE BIT(6) /* Interrupt Enable */ @@ -105,46 +107,51 @@ #define Z8536_CT_MODE_ETE BIT(4) /* External Trigger Enable */ #define Z8536_CT_MODE_EGE BIT(3) /* External Gate Enable */ #define Z8536_CT_MODE_REB BIT(2) /* Retrigger Enable Bit */ -#define Z8536_CT_MODE_DCS_PULSE (0 << 0)/* Duty Cycle - Pulse */ -#define Z8536_CT_MODE_DCS_ONESHOT (1 << 0)/* Duty Cycle - One-Shot */ -#define Z8536_CT_MODE_DCS_SQRWAVE (2 << 0)/* Duty Cycle - Square Wave */ -#define Z8536_CT_MODE_DCS_DO_NOT_USE (3 << 0)/* Duty Cycle - Do Not Use */ -#define Z8536_CT_MODE_DCS_MASK (3 << 0)/* Duty Cycle mask */ +#define Z8536_CT_MODE_DCS(x) (((x) & 0x3) << 0) /* Duty Cycle */ +#define Z8536_CT_MODE_DCS_PULSE Z8536_CT_MODE_DCS(0) /* Pulse */ +#define Z8536_CT_MODE_DCS_ONESHOT Z8536_CT_MODE_DCS(1) /* One-Shot */ +#define Z8536_CT_MODE_DCS_SQRWAVE Z8536_CT_MODE_DCS(2) /* Square Wave */ +#define Z8536_CT_MODE_DCS_DO_NOT_USE Z8536_CT_MODE_DCS(3) /* Do Not Use */ +#define Z8536_CT_MODE_DCS_MASK Z8536_CT_MODE_DCS(3) /* Port A/B Mode Specification registers */ #define Z8536_PA_MODE_REG 0x20 #define Z8536_PB_MODE_REG 0x28 -#define Z8536_PAB_MODE_PTS_BIT (0 << 6)/* Bit Port */ -#define Z8536_PAB_MODE_PTS_INPUT (1 << 6)/* Input Port */ -#define Z8536_PAB_MODE_PTS_OUTPUT (2 << 6)/* Output Port */ -#define Z8536_PAB_MODE_PTS_BIDIR (3 << 6)/* Bidirectional Port */ -#define Z8536_PAB_MODE_PTS_MASK (3 << 6)/* Port Type Select mask */ +#define Z8536_PAB_MODE_PTS(x) (((x) & 0x3) << 6) /* Port type */ +#define Z8536_PAB_MODE_PTS_BIT Z8536_PAB_MODE_PTS(0 << 6)/* Bit */ +#define Z8536_PAB_MODE_PTS_INPUT Z8536_PAB_MODE_PTS(1 << 6)/* Input */ +#define Z8536_PAB_MODE_PTS_OUTPUT Z8536_PAB_MODE_PTS(2 << 6)/* Output */ +#define Z8536_PAB_MODE_PTS_BIDIR Z8536_PAB_MODE_PTS(3 << 6)/* Bidir */ +#define Z8536_PAB_MODE_PTS_MASK Z8536_PAB_MODE_PTS(3 << 6) #define Z8536_PAB_MODE_ITB BIT(5) /* Interrupt on Two Bytes */ #define Z8536_PAB_MODE_SB BIT(4) /* Single Buffered mode */ #define Z8536_PAB_MODE_IMO BIT(3) /* Interrupt on Match Only */ -#define Z8536_PAB_MODE_PMS_DISABLE (0 << 1)/* Disable Pattern Match */ -#define Z8536_PAB_MODE_PMS_AND (1 << 1)/* "AND" mode */ -#define Z8536_PAB_MODE_PMS_OR (2 << 1)/* "OR" mode */ -#define Z8536_PAB_MODE_PMS_OR_PEV (3 << 1)/* "OR-Priority" mode */ -#define Z8536_PAB_MODE_PMS_MASK (3 << 1)/* Pattern Mode mask */ +#define Z8536_PAB_MODE_PMS(x) (((x) & 0x3) << 1) /* Pattern Mode */ +#define Z8536_PAB_MODE_PMS_DISABLE Z8536_PAB_MODE_PMS(0)/* Disabled */ +#define Z8536_PAB_MODE_PMS_AND Z8536_PAB_MODE_PMS(1)/* "AND" */ +#define Z8536_PAB_MODE_PMS_OR Z8536_PAB_MODE_PMS(2)/* "OR" */ +#define Z8536_PAB_MODE_PMS_OR_PEV Z8536_PAB_MODE_PMS(3)/* "OR-Priority" */ +#define Z8536_PAB_MODE_PMS_MASK Z8536_PAB_MODE_PMS(3) #define Z8536_PAB_MODE_LPM BIT(0) /* Latch on Pattern Match */ #define Z8536_PAB_MODE_DTE BIT(0) /* Deskew Timer Enabled */ /* Port A/B Handshake Specification registers */ #define Z8536_PA_HANDSHAKE_REG 0x21 #define Z8536_PB_HANDSHAKE_REG 0x29 -#define Z8536_PAB_HANDSHAKE_HST_INTER (0 << 6)/* Interlocked Handshake */ -#define Z8536_PAB_HANDSHAKE_HST_STROBED (1 << 6)/* Strobed Handshake */ -#define Z8536_PAB_HANDSHAKE_HST_PULSED (2 << 6)/* Pulsed Handshake */ -#define Z8536_PAB_HANDSHAKE_HST_3WIRE (3 << 6)/* Three-Wire Handshake */ -#define Z8536_PAB_HANDSHAKE_HST_MASK (3 << 6)/* Handshake Type mask */ -#define Z8536_PAB_HANDSHAKE_RWS_DISABLE (0 << 3)/* Req/Wait Disabled */ -#define Z8536_PAB_HANDSHAKE_RWS_OUTWAIT (1 << 3)/* Output Wait */ -#define Z8536_PAB_HANDSHAKE_RWS_INWAIT (3 << 3)/* Input Wait */ -#define Z8536_PAB_HANDSHAKE_RWS_SPREQ (4 << 3)/* Special Request */ -#define Z8536_PAB_HANDSHAKE_RWS_OUTREQ (5 << 4)/* Output Request */ -#define Z8536_PAB_HANDSHAKE_RWS_INREQ (7 << 3)/* Input Request */ -#define Z8536_PAB_HANDSHAKE_RWS_MASK (7 << 3)/* Req/Wait mask */ +#define Z8536_PAB_HANDSHAKE_HST(x) (((x) & 0x3) << 6) /* Handshake Type */ +#define Z8536_PAB_HANDSHAKE_HST_INTER Z8536_PAB_HANDSHAKE_HST(0)/*Interlock*/ +#define Z8536_PAB_HANDSHAKE_HST_STROBED Z8536_PAB_HANDSHAKE_HST(1)/* Strobed */ +#define Z8536_PAB_HANDSHAKE_HST_PULSED Z8536_PAB_HANDSHAKE_HST(2)/* Pulsed */ +#define Z8536_PAB_HANDSHAKE_HST_3WIRE Z8536_PAB_HANDSHAKE_HST(3)/* 3-Wire */ +#define Z8536_PAB_HANDSHAKE_HST_MASK Z8536_PAB_HANDSHAKE_HST(3) +#define Z8536_PAB_HANDSHAKE_RWS(x) (((x) & 0x7) << 3) /* Req/Wait */ +#define Z8536_PAB_HANDSHAKE_RWS_DISABLE Z8536_PAB_HANDSHAKE_RWS(0)/* Disabled */ +#define Z8536_PAB_HANDSHAKE_RWS_OUTWAIT Z8536_PAB_HANDSHAKE_RWS(1)/* Out Wait */ +#define Z8536_PAB_HANDSHAKE_RWS_INWAIT Z8536_PAB_HANDSHAKE_RWS(3)/* In Wait */ +#define Z8536_PAB_HANDSHAKE_RWS_SPREQ Z8536_PAB_HANDSHAKE_RWS(4)/* Special */ +#define Z8536_PAB_HANDSHAKE_RWS_OUTREQ Z8536_PAB_HANDSHAKE_RWS(5)/* Out Req */ +#define Z8536_PAB_HANDSHAKE_RWS_INREQ Z8536_PAB_HANDSHAKE_RWS(7)/* In Req */ +#define Z8536_PAB_HANDSHAKE_RWS_MASK Z8536_PAB_HANDSHAKE_RWS(7) #define Z8536_PAB_HANDSHAKE_DESKEW(x) ((x) << 0)/* Deskew Time */ #define Z8536_PAB_HANDSHAKE_DESKEW_MASK (3 << 0)/* Deskew Time mask */ -- cgit v1.2.3 From 5c0d139243c32ebfe1f4aabd3d2a9817e23e07a5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:51:54 -0700 Subject: staging: comedi: plx9052.h: tidy up bit defines Fix the checkpatch.pl issues: CHECK: Prefer using the BIT macro Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/plx9052.h | 87 ++++++++++++++++---------------- 1 file changed, 44 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/plx9052.h b/drivers/staging/comedi/drivers/plx9052.h index fbcf25069807..131ebffa9376 100644 --- a/drivers/staging/comedi/drivers/plx9052.h +++ b/drivers/staging/comedi/drivers/plx9052.h @@ -25,55 +25,56 @@ * INTCSR - Interrupt Control/Status register */ #define PLX9052_INTCSR 0x4c -#define PLX9052_INTCSR_LI1ENAB (1 << 0) /* LI1 enabled */ -#define PLX9052_INTCSR_LI1POL (1 << 1) /* LI1 active high */ -#define PLX9052_INTCSR_LI1STAT (1 << 2) /* LI1 active */ -#define PLX9052_INTCSR_LI2ENAB (1 << 3) /* LI2 enabled */ -#define PLX9052_INTCSR_LI2POL (1 << 4) /* LI2 active high */ -#define PLX9052_INTCSR_LI2STAT (1 << 5) /* LI2 active */ -#define PLX9052_INTCSR_PCIENAB (1 << 6) /* PCIINT enabled */ -#define PLX9052_INTCSR_SOFTINT (1 << 7) /* generate soft int */ -#define PLX9052_INTCSR_LI1SEL (1 << 8) /* LI1 edge */ -#define PLX9052_INTCSR_LI2SEL (1 << 9) /* LI2 edge */ -#define PLX9052_INTCSR_LI1CLRINT (1 << 10) /* LI1 clear int */ -#define PLX9052_INTCSR_LI2CLRINT (1 << 11) /* LI2 clear int */ -#define PLX9052_INTCSR_ISAMODE (1 << 12) /* ISA interface mode */ +#define PLX9052_INTCSR_LI1ENAB BIT(0) /* LI1 enabled */ +#define PLX9052_INTCSR_LI1POL BIT(1) /* LI1 active high */ +#define PLX9052_INTCSR_LI1STAT BIT(2) /* LI1 active */ +#define PLX9052_INTCSR_LI2ENAB BIT(3) /* LI2 enabled */ +#define PLX9052_INTCSR_LI2POL BIT(4) /* LI2 active high */ +#define PLX9052_INTCSR_LI2STAT BIT(5) /* LI2 active */ +#define PLX9052_INTCSR_PCIENAB BIT(6) /* PCIINT enabled */ +#define PLX9052_INTCSR_SOFTINT BIT(7) /* generate soft int */ +#define PLX9052_INTCSR_LI1SEL BIT(8) /* LI1 edge */ +#define PLX9052_INTCSR_LI2SEL BIT(9) /* LI2 edge */ +#define PLX9052_INTCSR_LI1CLRINT BIT(10) /* LI1 clear int */ +#define PLX9052_INTCSR_LI2CLRINT BIT(11) /* LI2 clear int */ +#define PLX9052_INTCSR_ISAMODE BIT(12) /* ISA interface mode */ /* * CNTRL - User I/O, Direct Slave Response, Serial EEPROM, and * Initialization Control register */ #define PLX9052_CNTRL 0x50 -#define PLX9052_CNTRL_WAITO (1 << 0) /* UIO0 or WAITO# select */ -#define PLX9052_CNTRL_UIO0_DIR (1 << 1) /* UIO0 direction */ -#define PLX9052_CNTRL_UIO0_DATA (1 << 2) /* UIO0 data */ -#define PLX9052_CNTRL_LLOCKO (1 << 3) /* UIO1 or LLOCKo# select */ -#define PLX9052_CNTRL_UIO1_DIR (1 << 4) /* UIO1 direction */ -#define PLX9052_CNTRL_UIO1_DATA (1 << 5) /* UIO1 data */ -#define PLX9052_CNTRL_CS2 (1 << 6) /* UIO2 or CS2# select */ -#define PLX9052_CNTRL_UIO2_DIR (1 << 7) /* UIO2 direction */ -#define PLX9052_CNTRL_UIO2_DATA (1 << 8) /* UIO2 data */ -#define PLX9052_CNTRL_CS3 (1 << 9) /* UIO3 or CS3# select */ -#define PLX9052_CNTRL_UIO3_DIR (1 << 10) /* UIO3 direction */ -#define PLX9052_CNTRL_UIO3_DATA (1 << 11) /* UIO3 data */ -#define PLX9052_CNTRL_PCIBAR01 (0 << 12) /* bar 0 (mem) and 1 (I/O) */ -#define PLX9052_CNTRL_PCIBAR0 (1 << 12) /* bar 0 (mem) only */ -#define PLX9052_CNTRL_PCIBAR1 (2 << 12) /* bar 1 (I/O) only */ -#define PLX9052_CNTRL_PCI2_1_FEATURES (1 << 14) /* PCI r2.1 features enabled */ -#define PLX9052_CNTRL_PCI_R_W_FLUSH (1 << 15) /* read w/write flush mode */ -#define PLX9052_CNTRL_PCI_R_NO_FLUSH (1 << 16) /* read no flush mode */ -#define PLX9052_CNTRL_PCI_R_NO_WRITE (1 << 17) /* read no write mode */ -#define PLX9052_CNTRL_PCI_W_RELEASE (1 << 18) /* write release bus mode */ -#define PLX9052_CNTRL_RETRY_CLKS(x) (((x) & 0xf) << 19) /* slave retry clks */ -#define PLX9052_CNTRL_LOCK_ENAB (1 << 23) /* slave LOCK# enable */ +#define PLX9052_CNTRL_WAITO BIT(0) /* UIO0 or WAITO# select */ +#define PLX9052_CNTRL_UIO0_DIR BIT(1) /* UIO0 direction */ +#define PLX9052_CNTRL_UIO0_DATA BIT(2) /* UIO0 data */ +#define PLX9052_CNTRL_LLOCKO BIT(3) /* UIO1 or LLOCKo# select */ +#define PLX9052_CNTRL_UIO1_DIR BIT(4) /* UIO1 direction */ +#define PLX9052_CNTRL_UIO1_DATA BIT(5) /* UIO1 data */ +#define PLX9052_CNTRL_CS2 BIT(6) /* UIO2 or CS2# select */ +#define PLX9052_CNTRL_UIO2_DIR BIT(7) /* UIO2 direction */ +#define PLX9052_CNTRL_UIO2_DATA BIT(8) /* UIO2 data */ +#define PLX9052_CNTRL_CS3 BIT(9) /* UIO3 or CS3# select */ +#define PLX9052_CNTRL_UIO3_DIR BIT(10) /* UIO3 direction */ +#define PLX9052_CNTRL_UIO3_DATA BIT(11) /* UIO3 data */ +#define PLX9052_CNTRL_PCIBAR(x) (((x) & 0x3) << 12) +#define PLX9052_CNTRL_PCIBAR01 PLX9052_CNTRL_PCIBAR(0) /* mem and IO */ +#define PLX9052_CNTRL_PCIBAR0 PLX9052_CNTRL_PCIBAR(1) /* mem only */ +#define PLX9052_CNTRL_PCIBAR1 PLX9052_CNTRL_PCIBAR(2) /* IO only */ +#define PLX9052_CNTRL_PCI2_1_FEATURES BIT(14) /* PCI v2.1 features enabled */ +#define PLX9052_CNTRL_PCI_R_W_FLUSH BIT(15) /* read w/write flush mode */ +#define PLX9052_CNTRL_PCI_R_NO_FLUSH BIT(16) /* read no flush mode */ +#define PLX9052_CNTRL_PCI_R_NO_WRITE BIT(17) /* read no write mode */ +#define PLX9052_CNTRL_PCI_W_RELEASE BIT(18) /* write release bus mode */ +#define PLX9052_CNTRL_RETRY_CLKS(x) (((x) & 0xf) << 19) /* retry clks */ +#define PLX9052_CNTRL_LOCK_ENAB BIT(23) /* slave LOCK# enable */ #define PLX9052_CNTRL_EEPROM_MASK (0x1f << 24) /* EEPROM bits */ -#define PLX9052_CNTRL_EEPROM_CLK (1 << 24) /* EEPROM clock */ -#define PLX9052_CNTRL_EEPROM_CS (1 << 25) /* EEPROM chip select */ -#define PLX9052_CNTRL_EEPROM_DOUT (1 << 26) /* EEPROM write bit */ -#define PLX9052_CNTRL_EEPROM_DIN (1 << 27) /* EEPROM read bit */ -#define PLX9052_CNTRL_EEPROM_PRESENT (1 << 28) /* EEPROM present */ -#define PLX9052_CNTRL_RELOAD_CFG (1 << 29) /* reload configuration */ -#define PLX9052_CNTRL_PCI_RESET (1 << 30) /* PCI adapter reset */ -#define PLX9052_CNTRL_MASK_REV (1 << 31) /* mask revision */ +#define PLX9052_CNTRL_EEPROM_CLK BIT(24) /* EEPROM clock */ +#define PLX9052_CNTRL_EEPROM_CS BIT(25) /* EEPROM chip select */ +#define PLX9052_CNTRL_EEPROM_DOUT BIT(26) /* EEPROM write bit */ +#define PLX9052_CNTRL_EEPROM_DIN BIT(27) /* EEPROM read bit */ +#define PLX9052_CNTRL_EEPROM_PRESENT BIT(28) /* EEPROM present */ +#define PLX9052_CNTRL_RELOAD_CFG BIT(29) /* reload configuration */ +#define PLX9052_CNTRL_PCI_RESET BIT(30) /* PCI adapter reset */ +#define PLX9052_CNTRL_MASK_REV BIT(31) /* mask revision */ #endif /* _PLX9052_H_ */ -- cgit v1.2.3 From 2892b3fa16d8950b2385ad8fcd7ca84fa54aefaf Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 Mar 2016 11:51:55 -0700 Subject: staging: comedi: plx9052.h: fix block comment issues Fix the checkpatch.pl issues: WARNING: Block comments use * on subsequent lines Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/plx9052.h | 35 ++++++++++++++++---------------- 1 file changed, 17 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/plx9052.h b/drivers/staging/comedi/drivers/plx9052.h index 131ebffa9376..2892e6528967 100644 --- a/drivers/staging/comedi/drivers/plx9052.h +++ b/drivers/staging/comedi/drivers/plx9052.h @@ -1,22 +1,21 @@ /* - comedi/drivers/plx9052.h - Definitions for the PLX-9052 PCI interface chip - - Copyright (C) 2002 MEV Ltd. - - COMEDI - Linux Control and Measurement Device Interface - Copyright (C) 2000 David A. Schleef - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -*/ + * Definitions for the PLX-9052 PCI interface chip + * + * Copyright (C) 2002 MEV Ltd. + * + * COMEDI - Linux Control and Measurement Device Interface + * Copyright (C) 2000 David A. Schleef + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ #ifndef _PLX9052_H_ #define _PLX9052_H_ -- cgit v1.2.3 From 12fc6688ea34bd8b378e105da46ca016177f7c84 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 Mar 2016 15:36:37 -0700 Subject: staging: comedi: ni_tio_internal.h: tidy up bit defines Fix the checkpatch.pl issues: CHECK: Prefer using the BIT macro Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tio_internal.h | 199 ++++++++++++----------- 1 file changed, 102 insertions(+), 97 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_tio_internal.h b/drivers/staging/comedi/drivers/ni_tio_internal.h index 2bceae493e23..c51e01eb3de0 100644 --- a/drivers/staging/comedi/drivers/ni_tio_internal.h +++ b/drivers/staging/comedi/drivers/ni_tio_internal.h @@ -24,68 +24,73 @@ #define NITIO_AUTO_INC_REG(x) (NITIO_G0_AUTO_INC + (x)) #define GI_AUTO_INC_MASK 0xff #define NITIO_CMD_REG(x) (NITIO_G0_CMD + (x)) -#define GI_ARM (1 << 0) -#define GI_SAVE_TRACE (1 << 1) -#define GI_LOAD (1 << 2) -#define GI_DISARM (1 << 4) +#define GI_ARM BIT(0) +#define GI_SAVE_TRACE BIT(1) +#define GI_LOAD BIT(2) +#define GI_DISARM BIT(4) #define GI_CNT_DIR(x) (((x) & 0x3) << 5) -#define GI_CNT_DIR_MASK (3 << 5) -#define GI_WRITE_SWITCH (1 << 7) -#define GI_SYNC_GATE (1 << 8) -#define GI_LITTLE_BIG_ENDIAN (1 << 9) -#define GI_BANK_SWITCH_START (1 << 10) -#define GI_BANK_SWITCH_MODE (1 << 11) -#define GI_BANK_SWITCH_ENABLE (1 << 12) -#define GI_ARM_COPY (1 << 13) -#define GI_SAVE_TRACE_COPY (1 << 14) -#define GI_DISARM_COPY (1 << 15) +#define GI_CNT_DIR_MASK GI_CNT_DIR(3) +#define GI_WRITE_SWITCH BIT(7) +#define GI_SYNC_GATE BIT(8) +#define GI_LITTLE_BIG_ENDIAN BIT(9) +#define GI_BANK_SWITCH_START BIT(10) +#define GI_BANK_SWITCH_MODE BIT(11) +#define GI_BANK_SWITCH_ENABLE BIT(12) +#define GI_ARM_COPY BIT(13) +#define GI_SAVE_TRACE_COPY BIT(14) +#define GI_DISARM_COPY BIT(15) #define NITIO_HW_SAVE_REG(x) (NITIO_G0_HW_SAVE + (x)) #define NITIO_SW_SAVE_REG(x) (NITIO_G0_SW_SAVE + (x)) #define NITIO_MODE_REG(x) (NITIO_G0_MODE + (x)) -#define GI_GATING_DISABLED (0 << 0) -#define GI_LEVEL_GATING (1 << 0) -#define GI_RISING_EDGE_GATING (2 << 0) -#define GI_FALLING_EDGE_GATING (3 << 0) -#define GI_GATING_MODE_MASK (3 << 0) -#define GI_GATE_ON_BOTH_EDGES (1 << 2) -#define GI_EDGE_GATE_STARTS_STOPS (0 << 3) -#define GI_EDGE_GATE_STOPS_STARTS (1 << 3) -#define GI_EDGE_GATE_STARTS (2 << 3) -#define GI_EDGE_GATE_NO_STARTS_OR_STOPS (3 << 3) -#define GI_EDGE_GATE_MODE_MASK (3 << 3) -#define GI_STOP_ON_GATE (0 << 5) -#define GI_STOP_ON_GATE_OR_TC (1 << 5) -#define GI_STOP_ON_GATE_OR_SECOND_TC (2 << 5) -#define GI_STOP_MODE_MASK (3 << 5) -#define GI_LOAD_SRC_SEL (1 << 7) -#define GI_OUTPUT_TC_PULSE (1 << 8) -#define GI_OUTPUT_TC_TOGGLE (2 << 8) -#define GI_OUTPUT_TC_OR_GATE_TOGGLE (3 << 8) -#define GI_OUTPUT_MODE_MASK (3 << 8) -#define GI_NO_HARDWARE_DISARM (0 << 10) -#define GI_DISARM_AT_TC (1 << 10) -#define GI_DISARM_AT_GATE (2 << 10) -#define GI_DISARM_AT_TC_OR_GATE (3 << 10) -#define GI_COUNTING_ONCE_MASK (3 << 10) -#define GI_LOADING_ON_TC (1 << 12) -#define GI_GATE_POL_INVERT (1 << 13) -#define GI_LOADING_ON_GATE (1 << 14) -#define GI_RELOAD_SRC_SWITCHING (1 << 15) +#define GI_GATING_MODE(x) (((x) & 0x3) << 0) +#define GI_GATING_DISABLED GI_GATING_MODE(0) +#define GI_LEVEL_GATING GI_GATING_MODE(1) +#define GI_RISING_EDGE_GATING GI_GATING_MODE(2) +#define GI_FALLING_EDGE_GATING GI_GATING_MODE(3) +#define GI_GATING_MODE_MASK GI_GATING_MODE(3) +#define GI_GATE_ON_BOTH_EDGES BIT(2) +#define GI_EDGE_GATE_MODE(x) (((x) & 0x3) << 3) +#define GI_EDGE_GATE_STARTS_STOPS GI_EDGE_GATE_MODE(0) +#define GI_EDGE_GATE_STOPS_STARTS GI_EDGE_GATE_MODE(1) +#define GI_EDGE_GATE_STARTS GI_EDGE_GATE_MODE(2) +#define GI_EDGE_GATE_NO_STARTS_OR_STOPS GI_EDGE_GATE_MODE(3) +#define GI_EDGE_GATE_MODE_MASK GI_EDGE_GATE_MODE(3) +#define GI_STOP_MODE(x) (((x) & 0x3) << 5) +#define GI_STOP_ON_GATE GI_STOP_MODE(0) +#define GI_STOP_ON_GATE_OR_TC GI_STOP_MODE(1) +#define GI_STOP_ON_GATE_OR_SECOND_TC GI_STOP_MODE(2) +#define GI_STOP_MODE_MASK GI_STOP_MODE(3) +#define GI_LOAD_SRC_SEL BIT(7) +#define GI_OUTPUT_MODE(x) (((x) & 0x3) << 8) +#define GI_OUTPUT_TC_PULSE GI_OUTPUT_MODE(1) +#define GI_OUTPUT_TC_TOGGLE GI_OUTPUT_MODE(2) +#define GI_OUTPUT_TC_OR_GATE_TOGGLE GI_OUTPUT_MODE(3) +#define GI_OUTPUT_MODE_MASK GI_OUTPUT_MODE(3) +#define GI_COUNTING_ONCE(x) (((x) & 0x3) << 10) +#define GI_NO_HARDWARE_DISARM GI_COUNTING_ONCE(0) +#define GI_DISARM_AT_TC GI_COUNTING_ONCE(1) +#define GI_DISARM_AT_GATE GI_COUNTING_ONCE(2) +#define GI_DISARM_AT_TC_OR_GATE GI_COUNTING_ONCE(3) +#define GI_COUNTING_ONCE_MASK GI_COUNTING_ONCE(3) +#define GI_LOADING_ON_TC BIT(12) +#define GI_GATE_POL_INVERT BIT(13) +#define GI_LOADING_ON_GATE BIT(14) +#define GI_RELOAD_SRC_SWITCHING BIT(15) #define NITIO_LOADA_REG(x) (NITIO_G0_LOADA + (x)) #define NITIO_LOADB_REG(x) (NITIO_G0_LOADB + (x)) #define NITIO_INPUT_SEL_REG(x) (NITIO_G0_INPUT_SEL + (x)) -#define GI_READ_ACKS_IRQ (1 << 0) -#define GI_WRITE_ACKS_IRQ (1 << 1) +#define GI_READ_ACKS_IRQ BIT(0) +#define GI_WRITE_ACKS_IRQ BIT(1) #define GI_BITS_TO_SRC(x) (((x) >> 2) & 0x1f) #define GI_SRC_SEL(x) (((x) & 0x1f) << 2) -#define GI_SRC_SEL_MASK (0x1f << 2) +#define GI_SRC_SEL_MASK GI_SRC_SEL(0x1f) #define GI_BITS_TO_GATE(x) (((x) >> 7) & 0x1f) #define GI_GATE_SEL(x) (((x) & 0x1f) << 7) -#define GI_GATE_SEL_MASK (0x1f << 7) -#define GI_GATE_SEL_LOAD_SRC (1 << 12) -#define GI_OR_GATE (1 << 13) -#define GI_OUTPUT_POL_INVERT (1 << 14) -#define GI_SRC_POL_INVERT (1 << 15) +#define GI_GATE_SEL_MASK GI_GATE_SEL(0x1f) +#define GI_GATE_SEL_LOAD_SRC BIT(12) +#define GI_OR_GATE BIT(13) +#define GI_OUTPUT_POL_INVERT BIT(14) +#define GI_SRC_POL_INVERT BIT(15) #define NITIO_CNT_MODE_REG(x) (NITIO_G0_CNT_MODE + (x)) #define GI_CNT_MODE(x) (((x) & 0x7) << 0) #define GI_CNT_MODE_NORMAL GI_CNT_MODE(0) @@ -94,67 +99,67 @@ #define GI_CNT_MODE_QUADX4 GI_CNT_MODE(3) #define GI_CNT_MODE_TWO_PULSE GI_CNT_MODE(4) #define GI_CNT_MODE_SYNC_SRC GI_CNT_MODE(6) -#define GI_CNT_MODE_MASK (7 << 0) -#define GI_INDEX_MODE (1 << 4) +#define GI_CNT_MODE_MASK GI_CNT_MODE(7) +#define GI_INDEX_MODE BIT(4) #define GI_INDEX_PHASE(x) (((x) & 0x3) << 5) -#define GI_INDEX_PHASE_MASK (3 << 5) -#define GI_HW_ARM_ENA (1 << 7) +#define GI_INDEX_PHASE_MASK GI_INDEX_PHASE(3) +#define GI_HW_ARM_ENA BIT(7) #define GI_HW_ARM_SEL(x) ((x) << 8) -#define GI_660X_HW_ARM_SEL_MASK (0x7 << 8) -#define GI_M_HW_ARM_SEL_MASK (0x1f << 8) -#define GI_660X_PRESCALE_X8 (1 << 12) -#define GI_M_PRESCALE_X8 (1 << 13) -#define GI_660X_ALT_SYNC (1 << 13) -#define GI_M_ALT_SYNC (1 << 14) -#define GI_660X_PRESCALE_X2 (1 << 14) -#define GI_M_PRESCALE_X2 (1 << 15) +#define GI_660X_HW_ARM_SEL_MASK GI_HW_ARM_SEL(0x7) +#define GI_M_HW_ARM_SEL_MASK GI_HW_ARM_SEL(0x1f) +#define GI_660X_PRESCALE_X8 BIT(12) +#define GI_M_PRESCALE_X8 BIT(13) +#define GI_660X_ALT_SYNC BIT(13) +#define GI_M_ALT_SYNC BIT(14) +#define GI_660X_PRESCALE_X2 BIT(14) +#define GI_M_PRESCALE_X2 BIT(15) #define NITIO_GATE2_REG(x) (NITIO_G0_GATE2 + (x)) -#define GI_GATE2_MODE (1 << 0) +#define GI_GATE2_MODE BIT(0) #define GI_BITS_TO_GATE2(x) (((x) >> 7) & 0x1f) #define GI_GATE2_SEL(x) (((x) & 0x1f) << 7) -#define GI_GATE2_SEL_MASK (0x1f << 7) -#define GI_GATE2_POL_INVERT (1 << 13) -#define GI_GATE2_SUBSEL (1 << 14) -#define GI_SRC_SUBSEL (1 << 15) +#define GI_GATE2_SEL_MASK GI_GATE2_SEL(0x1f) +#define GI_GATE2_POL_INVERT BIT(13) +#define GI_GATE2_SUBSEL BIT(14) +#define GI_SRC_SUBSEL BIT(15) #define NITIO_SHARED_STATUS_REG(x) (NITIO_G01_STATUS + ((x) / 2)) -#define GI_SAVE(x) (((x) % 2) ? (1 << 1) : (1 << 0)) -#define GI_COUNTING(x) (((x) % 2) ? (1 << 3) : (1 << 2)) -#define GI_NEXT_LOAD_SRC(x) (((x) % 2) ? (1 << 5) : (1 << 4)) -#define GI_STALE_DATA(x) (((x) % 2) ? (1 << 7) : (1 << 6)) -#define GI_ARMED(x) (((x) % 2) ? (1 << 9) : (1 << 8)) -#define GI_NO_LOAD_BETWEEN_GATES(x) (((x) % 2) ? (1 << 11) : (1 << 10)) -#define GI_TC_ERROR(x) (((x) % 2) ? (1 << 13) : (1 << 12)) -#define GI_GATE_ERROR(x) (((x) % 2) ? (1 << 15) : (1 << 14)) +#define GI_SAVE(x) (((x) % 2) ? BIT(1) : BIT(0)) +#define GI_COUNTING(x) (((x) % 2) ? BIT(3) : BIT(2)) +#define GI_NEXT_LOAD_SRC(x) (((x) % 2) ? BIT(5) : BIT(4)) +#define GI_STALE_DATA(x) (((x) % 2) ? BIT(7) : BIT(6)) +#define GI_ARMED(x) (((x) % 2) ? BIT(9) : BIT(8)) +#define GI_NO_LOAD_BETWEEN_GATES(x) (((x) % 2) ? BIT(11) : BIT(10)) +#define GI_TC_ERROR(x) (((x) % 2) ? BIT(13) : BIT(12)) +#define GI_GATE_ERROR(x) (((x) % 2) ? BIT(15) : BIT(14)) #define NITIO_RESET_REG(x) (NITIO_G01_RESET + ((x) / 2)) -#define GI_RESET(x) (1 << (2 + ((x) % 2))) +#define GI_RESET(x) BIT(2 + ((x) % 2)) #define NITIO_STATUS1_REG(x) (NITIO_G01_STATUS1 + ((x) / 2)) #define NITIO_STATUS2_REG(x) (NITIO_G01_STATUS2 + ((x) / 2)) -#define GI_OUTPUT(x) (((x) % 2) ? (1 << 1) : (1 << 0)) -#define GI_HW_SAVE(x) (((x) % 2) ? (1 << 13) : (1 << 12)) -#define GI_PERMANENT_STALE(x) (((x) % 2) ? (1 << 15) : (1 << 14)) +#define GI_OUTPUT(x) (((x) % 2) ? BIT(1) : BIT(0)) +#define GI_HW_SAVE(x) (((x) % 2) ? BIT(13) : BIT(12)) +#define GI_PERMANENT_STALE(x) (((x) % 2) ? BIT(15) : BIT(14)) #define NITIO_DMA_CFG_REG(x) (NITIO_G0_DMA_CFG + (x)) -#define GI_DMA_ENABLE (1 << 0) -#define GI_DMA_WRITE (1 << 1) -#define GI_DMA_INT_ENA (1 << 2) -#define GI_DMA_RESET (1 << 3) -#define GI_DMA_BANKSW_ERROR (1 << 4) +#define GI_DMA_ENABLE BIT(0) +#define GI_DMA_WRITE BIT(1) +#define GI_DMA_INT_ENA BIT(2) +#define GI_DMA_RESET BIT(3) +#define GI_DMA_BANKSW_ERROR BIT(4) #define NITIO_DMA_STATUS_REG(x) (NITIO_G0_DMA_STATUS + (x)) -#define GI_DMA_READBANK (1 << 13) -#define GI_DRQ_ERROR (1 << 14) -#define GI_DRQ_STATUS (1 << 15) +#define GI_DMA_READBANK BIT(13) +#define GI_DRQ_ERROR BIT(14) +#define GI_DRQ_STATUS BIT(15) #define NITIO_ABZ_REG(x) (NITIO_G0_ABZ + (x)) #define NITIO_INT_ACK_REG(x) (NITIO_G0_INT_ACK + (x)) -#define GI_GATE_ERROR_CONFIRM(x) (((x) % 2) ? (1 << 1) : (1 << 5)) -#define GI_TC_ERROR_CONFIRM(x) (((x) % 2) ? (1 << 2) : (1 << 6)) -#define GI_TC_INTERRUPT_ACK (1 << 14) -#define GI_GATE_INTERRUPT_ACK (1 << 15) +#define GI_GATE_ERROR_CONFIRM(x) (((x) % 2) ? BIT(1) : BIT(5)) +#define GI_TC_ERROR_CONFIRM(x) (((x) % 2) ? BIT(2) : BIT(6)) +#define GI_TC_INTERRUPT_ACK BIT(14) +#define GI_GATE_INTERRUPT_ACK BIT(15) #define NITIO_STATUS_REG(x) (NITIO_G0_STATUS + (x)) -#define GI_GATE_INTERRUPT (1 << 2) -#define GI_TC (1 << 3) -#define GI_INTERRUPT (1 << 15) +#define GI_GATE_INTERRUPT BIT(2) +#define GI_TC BIT(3) +#define GI_INTERRUPT BIT(15) #define NITIO_INT_ENA_REG(x) (NITIO_G0_INT_ENA + (x)) -#define GI_TC_INTERRUPT_ENABLE(x) (((x) % 2) ? (1 << 9) : (1 << 6)) -#define GI_GATE_INTERRUPT_ENABLE(x) (((x) % 2) ? (1 << 10) : (1 << 8)) +#define GI_TC_INTERRUPT_ENABLE(x) (((x) % 2) ? BIT(9) : BIT(6)) +#define GI_GATE_INTERRUPT_ENABLE(x) (((x) % 2) ? BIT(10) : BIT(8)) static inline void write_register(struct ni_gpct *counter, unsigned bits, enum ni_gpct_register reg) -- cgit v1.2.3 From f79f218ec2aa2ac761e426f54419f8d27aa46d53 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 Mar 2016 15:36:38 -0700 Subject: staging: comedi: ni_tio_internal.h: fix block comment issues Fix the checkpatch.pl issues: WARNING: Block comments use * on subsequent lines Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tio_internal.h | 43 ++++++++++++------------ 1 file changed, 22 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_tio_internal.h b/drivers/staging/comedi/drivers/ni_tio_internal.h index c51e01eb3de0..b659f058c8dc 100644 --- a/drivers/staging/comedi/drivers/ni_tio_internal.h +++ b/drivers/staging/comedi/drivers/ni_tio_internal.h @@ -1,20 +1,19 @@ /* - drivers/ni_tio_internal.h - Header file for NI general purpose counter support code (ni_tio.c and - ni_tiocmd.c) - - COMEDI - Linux Control and Measurement Device Interface - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -*/ + * Header file for NI general purpose counter support code (ni_tio.c and + * ni_tiocmd.c) + * + * COMEDI - Linux Control and Measurement Device Interface + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ #ifndef _COMEDI_NI_TIO_INTERNAL_H #define _COMEDI_NI_TIO_INTERNAL_H @@ -212,7 +211,8 @@ static inline void ni_tio_set_bits_transient(struct ni_gpct *counter, spin_unlock_irqrestore(&counter_dev->regs_lock, flags); } -/* ni_tio_set_bits( ) is for safely writing to registers whose bits may be +/* + * ni_tio_set_bits( ) is for safely writing to registers whose bits may be * twiddled in interrupt context, or whose software copy may be read in * interrupt context. */ @@ -224,10 +224,11 @@ static inline void ni_tio_set_bits(struct ni_gpct *counter, 0x0); } -/* ni_tio_get_soft_copy( ) is for safely reading the software copy of a register -whose bits might be modified in interrupt context, or whose software copy -might need to be read in interrupt context. -*/ +/* + * ni_tio_get_soft_copy( ) is for safely reading the software copy of a + * register whose bits might be modified in interrupt context, or whose + * software copy might need to be read in interrupt context. + */ static inline unsigned ni_tio_get_soft_copy(const struct ni_gpct *counter, enum ni_gpct_register register_index) -- cgit v1.2.3 From a4915d543f5bbb775a5fa6d012d33606ba22389b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 Mar 2016 15:36:39 -0700 Subject: staging: comedi: ni_tio: fix ni_tio_set_gate_src() params/vars As suggested by checkpatch.pl: WARNING: Prefer 'unsigned int' to bare use of 'unsigned' Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tio.c | 28 ++++++++++++------------ drivers/staging/comedi/drivers/ni_tio_internal.h | 3 +-- 2 files changed, 15 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c index 623fc6c7bff0..abbc8b7a7092 100644 --- a/drivers/staging/comedi/drivers/ni_tio.c +++ b/drivers/staging/comedi/drivers/ni_tio.c @@ -891,16 +891,16 @@ static int ni_m_set_gate2(struct ni_gpct *counter, unsigned int gate_source) return 0; } -int ni_tio_set_gate_src(struct ni_gpct *counter, unsigned gate_index, - unsigned int gate_source) +int ni_tio_set_gate_src(struct ni_gpct *counter, + unsigned int gate, unsigned int src) { struct ni_gpct_device *counter_dev = counter->counter_dev; - unsigned cidx = counter->counter_index; - unsigned int chan = CR_CHAN(gate_source); - unsigned gate2_reg = NITIO_GATE2_REG(cidx); - unsigned mode = 0; + unsigned int cidx = counter->counter_index; + unsigned int chan = CR_CHAN(src); + unsigned int gate2_reg = NITIO_GATE2_REG(cidx); + unsigned int mode = 0; - switch (gate_index) { + switch (gate) { case 0: if (chan == NI_GPCT_DISABLED_GATE_SELECT) { ni_tio_set_bits(counter, NITIO_MODE_REG(cidx), @@ -908,9 +908,9 @@ int ni_tio_set_gate_src(struct ni_gpct *counter, unsigned gate_index, GI_GATING_DISABLED); return 0; } - if (gate_source & CR_INVERT) + if (src & CR_INVERT) mode |= GI_GATE_POL_INVERT; - if (gate_source & CR_EDGE) + if (src & CR_EDGE) mode |= GI_RISING_EDGE_GATING; else mode |= GI_LEVEL_GATING; @@ -921,9 +921,9 @@ int ni_tio_set_gate_src(struct ni_gpct *counter, unsigned gate_index, case ni_gpct_variant_e_series: case ni_gpct_variant_m_series: default: - return ni_m_set_gate(counter, gate_source); + return ni_m_set_gate(counter, src); case ni_gpct_variant_660x: - return ni_660x_set_gate(counter, gate_source); + return ni_660x_set_gate(counter, src); } break; case 1: @@ -936,15 +936,15 @@ int ni_tio_set_gate_src(struct ni_gpct *counter, unsigned gate_index, gate2_reg); return 0; } - if (gate_source & CR_INVERT) + if (src & CR_INVERT) counter_dev->regs[gate2_reg] |= GI_GATE2_POL_INVERT; else counter_dev->regs[gate2_reg] &= ~GI_GATE2_POL_INVERT; switch (counter_dev->variant) { case ni_gpct_variant_m_series: - return ni_m_set_gate2(counter, gate_source); + return ni_m_set_gate2(counter, src); case ni_gpct_variant_660x: - return ni_660x_set_gate2(counter, gate_source); + return ni_660x_set_gate2(counter, src); default: BUG(); break; diff --git a/drivers/staging/comedi/drivers/ni_tio_internal.h b/drivers/staging/comedi/drivers/ni_tio_internal.h index b659f058c8dc..ee02b36aa51d 100644 --- a/drivers/staging/comedi/drivers/ni_tio_internal.h +++ b/drivers/staging/comedi/drivers/ni_tio_internal.h @@ -245,7 +245,6 @@ static inline unsigned ni_tio_get_soft_copy(const struct ni_gpct *counter, } int ni_tio_arm(struct ni_gpct *counter, int arm, unsigned start_trigger); -int ni_tio_set_gate_src(struct ni_gpct *counter, unsigned gate_index, - unsigned int gate_source); +int ni_tio_set_gate_src(struct ni_gpct *, unsigned int gate, unsigned int src); #endif /* _COMEDI_NI_TIO_INTERNAL_H */ -- cgit v1.2.3 From c9813d50a514b451c4ad3acf1f5a400fff005c70 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 Mar 2016 15:36:40 -0700 Subject: staging: comedi: ni_tio: fix ni_tio_arm() params/vars As suggested by checkpatch.pl: WARNING: Prefer 'unsigned int' to bare use of 'unsigned' The 'arm' parameter is really a true/false flag. For aesthetics, change it to a bool. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tio.c | 14 +++++++------- drivers/staging/comedi/drivers/ni_tio_internal.h | 2 +- drivers/staging/comedi/drivers/ni_tiocmd.c | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c index abbc8b7a7092..35596b1a075c 100644 --- a/drivers/staging/comedi/drivers/ni_tio.c +++ b/drivers/staging/comedi/drivers/ni_tio.c @@ -484,11 +484,11 @@ static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned mode) return 0; } -int ni_tio_arm(struct ni_gpct *counter, int arm, unsigned start_trigger) +int ni_tio_arm(struct ni_gpct *counter, bool arm, unsigned int start_trigger) { struct ni_gpct_device *counter_dev = counter->counter_dev; - unsigned cidx = counter->counter_index; - unsigned command_transient_bits = 0; + unsigned int cidx = counter->counter_index; + unsigned int command_transient_bits = 0; if (arm) { switch (start_trigger) { @@ -502,8 +502,8 @@ int ni_tio_arm(struct ni_gpct *counter, int arm, unsigned start_trigger) break; } if (ni_tio_counting_mode_registers_present(counter_dev)) { - unsigned bits = 0; - unsigned sel_mask; + unsigned int bits = 0; + unsigned int sel_mask; sel_mask = GI_HW_ARM_SEL_MASK(counter_dev->variant); @@ -1180,9 +1180,9 @@ int ni_tio_insn_config(struct comedi_device *dev, case INSN_CONFIG_SET_COUNTER_MODE: return ni_tio_set_counter_mode(counter, data[1]); case INSN_CONFIG_ARM: - return ni_tio_arm(counter, 1, data[1]); + return ni_tio_arm(counter, true, data[1]); case INSN_CONFIG_DISARM: - ni_tio_arm(counter, 0, 0); + ni_tio_arm(counter, false, 0); return 0; case INSN_CONFIG_GET_COUNTER_STATUS: data[1] = 0; diff --git a/drivers/staging/comedi/drivers/ni_tio_internal.h b/drivers/staging/comedi/drivers/ni_tio_internal.h index ee02b36aa51d..1e9163304692 100644 --- a/drivers/staging/comedi/drivers/ni_tio_internal.h +++ b/drivers/staging/comedi/drivers/ni_tio_internal.h @@ -244,7 +244,7 @@ static inline unsigned ni_tio_get_soft_copy(const struct ni_gpct *counter, return value; } -int ni_tio_arm(struct ni_gpct *counter, int arm, unsigned start_trigger); +int ni_tio_arm(struct ni_gpct *, bool arm, unsigned int start_trigger); int ni_tio_set_gate_src(struct ni_gpct *, unsigned int gate, unsigned int src); #endif /* _COMEDI_NI_TIO_INTERNAL_H */ diff --git a/drivers/staging/comedi/drivers/ni_tiocmd.c b/drivers/staging/comedi/drivers/ni_tiocmd.c index 823e47910004..0546a55b7277 100644 --- a/drivers/staging/comedi/drivers/ni_tiocmd.c +++ b/drivers/staging/comedi/drivers/ni_tiocmd.c @@ -103,7 +103,7 @@ static int ni_tio_input_inttrig(struct comedi_device *dev, spin_unlock_irqrestore(&counter->lock, flags); if (ret < 0) return ret; - ret = ni_tio_arm(counter, 1, NI_GPCT_ARM_IMMEDIATE); + ret = ni_tio_arm(counter, true, NI_GPCT_ARM_IMMEDIATE); s->async->inttrig = NULL; return ret; @@ -143,9 +143,9 @@ static int ni_tio_input_cmd(struct comedi_subdevice *s) mite_dma_arm(counter->mite_chan); if (cmd->start_src == TRIG_NOW) - ret = ni_tio_arm(counter, 1, NI_GPCT_ARM_IMMEDIATE); + ret = ni_tio_arm(counter, true, NI_GPCT_ARM_IMMEDIATE); else if (cmd->start_src == TRIG_EXT) - ret = ni_tio_arm(counter, 1, cmd->start_arg); + ret = ni_tio_arm(counter, true, cmd->start_arg); } return ret; } @@ -292,7 +292,7 @@ int ni_tio_cancel(struct ni_gpct *counter) unsigned cidx = counter->counter_index; unsigned long flags; - ni_tio_arm(counter, 0, 0); + ni_tio_arm(counter, false, 0); spin_lock_irqsave(&counter->lock, flags); if (counter->mite_chan) mite_dma_disarm(counter->mite_chan); -- cgit v1.2.3 From 85bfafa81f8e422503d31d48ae2658675aad1929 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 Mar 2016 15:36:41 -0700 Subject: staging: comedi: ni_tio: export and fix ni_tio_get_soft_copy() Move the inline function from the header and export it instead. For the checkpatch.pl issues: WARNING: Prefer 'unsigned int' to bare use of 'unsigned' CHECK: Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON() The 'unsigned' vars can safely be changed to 'unsigned int'. The BUG_ON() is overkill. All the drivers that call this function pass 'register_index' values that are valid. Just check the 'register_index' and return 0 if it's not valid. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tio.c | 25 ++++++++++++++++++++++++ drivers/staging/comedi/drivers/ni_tio_internal.h | 21 ++------------------ 2 files changed, 27 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c index 35596b1a075c..abbdad59552a 100644 --- a/drivers/staging/comedi/drivers/ni_tio.c +++ b/drivers/staging/comedi/drivers/ni_tio.c @@ -228,6 +228,31 @@ static uint64_t ni_tio_clock_period_ps(const struct ni_gpct *counter, return clock_period_ps; } +/** + * ni_tio_get_soft_copy() - Safely read the software copy of a counter register. + * @counter: struct ni_gpct counter. + * @reg: the register to read. + * + * Used to get the software copy of a register whose bits might be modified + * in interrupt context, or whose software copy might need to be read in + * interrupt context. + */ +unsigned int ni_tio_get_soft_copy(const struct ni_gpct *counter, + enum ni_gpct_register reg) +{ + struct ni_gpct_device *counter_dev = counter->counter_dev; + unsigned int value = 0; + unsigned long flags; + + if (reg < NITIO_NUM_REGS) { + spin_lock_irqsave(&counter_dev->regs_lock, flags); + value = counter_dev->regs[reg]; + spin_unlock_irqrestore(&counter_dev->regs_lock, flags); + } + return value; +} +EXPORT_SYMBOL_GPL(ni_tio_get_soft_copy); + static unsigned ni_tio_clock_src_modifiers(const struct ni_gpct *counter) { struct ni_gpct_device *counter_dev = counter->counter_dev; diff --git a/drivers/staging/comedi/drivers/ni_tio_internal.h b/drivers/staging/comedi/drivers/ni_tio_internal.h index 1e9163304692..8c9027690c36 100644 --- a/drivers/staging/comedi/drivers/ni_tio_internal.h +++ b/drivers/staging/comedi/drivers/ni_tio_internal.h @@ -224,25 +224,8 @@ static inline void ni_tio_set_bits(struct ni_gpct *counter, 0x0); } -/* - * ni_tio_get_soft_copy( ) is for safely reading the software copy of a - * register whose bits might be modified in interrupt context, or whose - * software copy might need to be read in interrupt context. - */ -static inline unsigned ni_tio_get_soft_copy(const struct ni_gpct *counter, - enum ni_gpct_register - register_index) -{ - struct ni_gpct_device *counter_dev = counter->counter_dev; - unsigned long flags; - unsigned value; - - BUG_ON(register_index >= NITIO_NUM_REGS); - spin_lock_irqsave(&counter_dev->regs_lock, flags); - value = counter_dev->regs[register_index]; - spin_unlock_irqrestore(&counter_dev->regs_lock, flags); - return value; -} +unsigned int ni_tio_get_soft_copy(const struct ni_gpct *, + enum ni_gpct_register reg); int ni_tio_arm(struct ni_gpct *, bool arm, unsigned int start_trigger); int ni_tio_set_gate_src(struct ni_gpct *, unsigned int gate, unsigned int src); -- cgit v1.2.3 From f4e0331f3050f051ad0e8818635fc157cf354713 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 Mar 2016 15:36:42 -0700 Subject: staging: comedi: ni_tio: export and fix ni_tio_set_bits() Move the inline function from the header and export it instead. Fix the checkpatch.pl issue: WARNING: Prefer 'unsigned int' to bare use of 'unsigned' The 'unsigned' vars can safely be changed to 'unsigned int'. This allows moving ni_tio_set_bits_transient() into the driver and making it static. Fix the checkpatch.pl issue: CHECK: Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON() The BUG_ON() is overkill. All the drivers that call this function pass 'register_index' values that are valid. Just check the 'register_index' before updating the software copy and writing the register. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tio.c | 37 ++++++++++++++++++++++++ drivers/staging/comedi/drivers/ni_tio_internal.h | 35 ++-------------------- 2 files changed, 39 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c index abbdad59552a..5343fce88ebf 100644 --- a/drivers/staging/comedi/drivers/ni_tio.c +++ b/drivers/staging/comedi/drivers/ni_tio.c @@ -228,6 +228,43 @@ static uint64_t ni_tio_clock_period_ps(const struct ni_gpct *counter, return clock_period_ps; } +static void ni_tio_set_bits_transient(struct ni_gpct *counter, + enum ni_gpct_register reg, + unsigned int mask, unsigned int value, + unsigned int transient) +{ + struct ni_gpct_device *counter_dev = counter->counter_dev; + unsigned long flags; + + if (reg < NITIO_NUM_REGS) { + spin_lock_irqsave(&counter_dev->regs_lock, flags); + counter_dev->regs[reg] &= ~mask; + counter_dev->regs[reg] |= (value & mask); + write_register(counter, counter_dev->regs[reg] | transient, + reg); + mmiowb(); + spin_unlock_irqrestore(&counter_dev->regs_lock, flags); + } +} + +/** + * ni_tio_set_bits() - Safely write a counter register. + * @counter: struct ni_gpct counter. + * @reg: the register to write. + * @mask: the bits to change. + * @value: the new bits value. + * + * Used to write to, and update the software copy, a register whose bits may + * be twiddled in interrupt context, or whose software copy may be read in + * interrupt context. + */ +void ni_tio_set_bits(struct ni_gpct *counter, enum ni_gpct_register reg, + unsigned int mask, unsigned int value) +{ + ni_tio_set_bits_transient(counter, reg, mask, value, 0x0); +} +EXPORT_SYMBOL_GPL(ni_tio_set_bits); + /** * ni_tio_get_soft_copy() - Safely read the software copy of a counter register. * @counter: struct ni_gpct counter. diff --git a/drivers/staging/comedi/drivers/ni_tio_internal.h b/drivers/staging/comedi/drivers/ni_tio_internal.h index 8c9027690c36..c8ad66a9237f 100644 --- a/drivers/staging/comedi/drivers/ni_tio_internal.h +++ b/drivers/staging/comedi/drivers/ni_tio_internal.h @@ -191,39 +191,8 @@ static inline int ni_tio_counting_mode_registers_present(const struct return 0; } -static inline void ni_tio_set_bits_transient(struct ni_gpct *counter, - enum ni_gpct_register - register_index, unsigned bit_mask, - unsigned bit_values, - unsigned transient_bit_values) -{ - struct ni_gpct_device *counter_dev = counter->counter_dev; - unsigned long flags; - - BUG_ON(register_index >= NITIO_NUM_REGS); - spin_lock_irqsave(&counter_dev->regs_lock, flags); - counter_dev->regs[register_index] &= ~bit_mask; - counter_dev->regs[register_index] |= (bit_values & bit_mask); - write_register(counter, - counter_dev->regs[register_index] | transient_bit_values, - register_index); - mmiowb(); - spin_unlock_irqrestore(&counter_dev->regs_lock, flags); -} - -/* - * ni_tio_set_bits( ) is for safely writing to registers whose bits may be - * twiddled in interrupt context, or whose software copy may be read in - * interrupt context. - */ -static inline void ni_tio_set_bits(struct ni_gpct *counter, - enum ni_gpct_register register_index, - unsigned bit_mask, unsigned bit_values) -{ - ni_tio_set_bits_transient(counter, register_index, bit_mask, bit_values, - 0x0); -} - +void ni_tio_set_bits(struct ni_gpct *, enum ni_gpct_register reg, + unsigned int mask, unsigned int value); unsigned int ni_tio_get_soft_copy(const struct ni_gpct *, enum ni_gpct_register reg); -- cgit v1.2.3 From 73b2d13607f075ff27abbf75d57320a8b9f82461 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 Mar 2016 15:36:43 -0700 Subject: staging: comedi: ni_tio_internal: simplify ni_tio_counting_mode_registers_present() Only the e series gpct variant does not have counting mode registers. Simplfy this function. For aesthetics, return bool instead of int. This fixes the checkpatch.pl issues: CHECK: spaces preferred around that '*' (ctx:ExV) CHECK: Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON() Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tio.c | 2 +- drivers/staging/comedi/drivers/ni_tio_internal.h | 18 ++++-------------- 2 files changed, 5 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c index 5343fce88ebf..44dea4c4da20 100644 --- a/drivers/staging/comedi/drivers/ni_tio.c +++ b/drivers/staging/comedi/drivers/ni_tio.c @@ -451,7 +451,7 @@ static void ni_tio_set_sync_mode(struct ni_gpct *counter, int force_alt_sync) unsigned mode; uint64_t clock_period_ps; - if (ni_tio_counting_mode_registers_present(counter_dev) == 0) + if (!ni_tio_counting_mode_registers_present(counter_dev)) return; mode = ni_tio_get_soft_copy(counter, counting_mode_reg); diff --git a/drivers/staging/comedi/drivers/ni_tio_internal.h b/drivers/staging/comedi/drivers/ni_tio_internal.h index c8ad66a9237f..1e795fd6f288 100644 --- a/drivers/staging/comedi/drivers/ni_tio_internal.h +++ b/drivers/staging/comedi/drivers/ni_tio_internal.h @@ -174,21 +174,11 @@ static inline unsigned read_register(struct ni_gpct *counter, return counter->counter_dev->read_register(counter, reg); } -static inline int ni_tio_counting_mode_registers_present(const struct - ni_gpct_device - *counter_dev) +static inline bool +ni_tio_counting_mode_registers_present(const struct ni_gpct_device *counter_dev) { - switch (counter_dev->variant) { - case ni_gpct_variant_e_series: - return 0; - case ni_gpct_variant_m_series: - case ni_gpct_variant_660x: - return 1; - default: - BUG(); - break; - } - return 0; + /* m series and 660x variants have counting mode registers */ + return counter_dev->variant != ni_gpct_variant_e_series; } void ni_tio_set_bits(struct ni_gpct *, enum ni_gpct_register reg, -- cgit v1.2.3 From 51f2e4eb2882209c84c2546b5a9b5c638b850f95 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 Mar 2016 15:36:44 -0700 Subject: staging: comedi: ni_tio_internal: export {read, write)_register() Move these inline functions out of the header and export them instead. These functions have pretty generic names, rename them. Fix the checkpatch.pl issues: WARNING: Prefer 'unsigned int' to bare use of 'unsigned' CHECK: Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON() Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tio.c | 72 ++++++++++++++++-------- drivers/staging/comedi/drivers/ni_tio_internal.h | 15 +---- drivers/staging/comedi/drivers/ni_tiocmd.c | 10 ++-- 3 files changed, 56 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c index 44dea4c4da20..a225279cb83f 100644 --- a/drivers/staging/comedi/drivers/ni_tio.c +++ b/drivers/staging/comedi/drivers/ni_tio.c @@ -179,11 +179,38 @@ static bool ni_tio_has_gate2_registers(const struct ni_gpct_device *counter_dev) } } +/** + * ni_tio_write() - Write a TIO register using the driver provided callback. + * @counter: struct ni_gpct counter. + * @value: the value to write + * @reg: the register to write. + */ +void ni_tio_write(struct ni_gpct *counter, unsigned int value, + enum ni_gpct_register reg) +{ + if (reg < NITIO_NUM_REGS) + counter->counter_dev->write_register(counter, value, reg); +} +EXPORT_SYMBOL_GPL(ni_tio_write); + +/** + * ni_tio_read() - Read a TIO register using the driver provided callback. + * @counter: struct ni_gpct counter. + * @reg: the register to read. + */ +unsigned int ni_tio_read(struct ni_gpct *counter, enum ni_gpct_register reg) +{ + if (reg < NITIO_NUM_REGS) + return counter->counter_dev->read_register(counter, reg); + return 0; +} +EXPORT_SYMBOL_GPL(ni_tio_read); + static void ni_tio_reset_count_and_disarm(struct ni_gpct *counter) { unsigned cidx = counter->counter_index; - write_register(counter, GI_RESET(cidx), NITIO_RESET_REG(cidx)); + ni_tio_write(counter, GI_RESET(cidx), NITIO_RESET_REG(cidx)); } static uint64_t ni_tio_clock_period_ps(const struct ni_gpct *counter, @@ -240,8 +267,7 @@ static void ni_tio_set_bits_transient(struct ni_gpct *counter, spin_lock_irqsave(&counter_dev->regs_lock, flags); counter_dev->regs[reg] &= ~mask; counter_dev->regs[reg] |= (value & mask); - write_register(counter, counter_dev->regs[reg] | transient, - reg); + ni_tio_write(counter, counter_dev->regs[reg] | transient, reg); mmiowb(); spin_unlock_irqrestore(&counter_dev->regs_lock, flags); } @@ -736,8 +762,8 @@ static void ni_tio_set_source_subselect(struct ni_gpct *counter, default: return; } - write_register(counter, counter_dev->regs[second_gate_reg], - second_gate_reg); + ni_tio_write(counter, counter_dev->regs[second_gate_reg], + second_gate_reg); } static int ni_tio_set_clock_src(struct ni_gpct *counter, @@ -925,7 +951,7 @@ static int ni_660x_set_gate2(struct ni_gpct *counter, unsigned int gate_source) counter_dev->regs[gate2_reg] |= GI_GATE2_MODE; counter_dev->regs[gate2_reg] &= ~GI_GATE2_SEL_MASK; counter_dev->regs[gate2_reg] |= GI_GATE2_SEL(gate2_sel); - write_register(counter, counter_dev->regs[gate2_reg], gate2_reg); + ni_tio_write(counter, counter_dev->regs[gate2_reg], gate2_reg); return 0; } @@ -949,7 +975,7 @@ static int ni_m_set_gate2(struct ni_gpct *counter, unsigned int gate_source) counter_dev->regs[gate2_reg] |= GI_GATE2_MODE; counter_dev->regs[gate2_reg] &= ~GI_GATE2_SEL_MASK; counter_dev->regs[gate2_reg] |= GI_GATE2_SEL(gate2_sel); - write_register(counter, counter_dev->regs[gate2_reg], gate2_reg); + ni_tio_write(counter, counter_dev->regs[gate2_reg], gate2_reg); return 0; } @@ -994,8 +1020,8 @@ int ni_tio_set_gate_src(struct ni_gpct *counter, if (chan == NI_GPCT_DISABLED_GATE_SELECT) { counter_dev->regs[gate2_reg] &= ~GI_GATE2_MODE; - write_register(counter, counter_dev->regs[gate2_reg], - gate2_reg); + ni_tio_write(counter, counter_dev->regs[gate2_reg], + gate2_reg); return 0; } if (src & CR_INVERT) @@ -1049,7 +1075,7 @@ static int ni_tio_set_other_src(struct ni_gpct *counter, unsigned index, counter_dev->regs[abz_reg] &= ~mask; counter_dev->regs[abz_reg] |= (source << shift) & mask; - write_register(counter, counter_dev->regs[abz_reg], abz_reg); + ni_tio_write(counter, counter_dev->regs[abz_reg], abz_reg); return 0; } @@ -1248,7 +1274,7 @@ int ni_tio_insn_config(struct comedi_device *dev, return 0; case INSN_CONFIG_GET_COUNTER_STATUS: data[1] = 0; - status = read_register(counter, NITIO_SHARED_STATUS_REG(cidx)); + status = ni_tio_read(counter, NITIO_SHARED_STATUS_REG(cidx)); if (status & GI_ARMED(cidx)) { data[1] |= COMEDI_COUNTER_ARMED; if (status & GI_COUNTING(cidx)) @@ -1297,9 +1323,9 @@ static unsigned int ni_tio_read_sw_save_reg(struct comedi_device *dev, * will be correct since the count value will definitely have latched * by then. */ - val = read_register(counter, NITIO_SW_SAVE_REG(cidx)); - if (val != read_register(counter, NITIO_SW_SAVE_REG(cidx))) - val = read_register(counter, NITIO_SW_SAVE_REG(cidx)); + val = ni_tio_read(counter, NITIO_SW_SAVE_REG(cidx)); + if (val != ni_tio_read(counter, NITIO_SW_SAVE_REG(cidx))) + val = ni_tio_read(counter, NITIO_SW_SAVE_REG(cidx)); return val; } @@ -1336,7 +1362,7 @@ static unsigned ni_tio_next_load_register(struct ni_gpct *counter) { unsigned cidx = counter->counter_index; const unsigned bits = - read_register(counter, NITIO_SHARED_STATUS_REG(cidx)); + ni_tio_read(counter, NITIO_SHARED_STATUS_REG(cidx)); return (bits & GI_NEXT_LOAD_SRC(cidx)) ? NITIO_LOADB_REG(cidx) @@ -1368,19 +1394,19 @@ int ni_tio_insn_write(struct comedi_device *dev, * load register is already selected. */ load_reg = ni_tio_next_load_register(counter); - write_register(counter, data[0], load_reg); + ni_tio_write(counter, data[0], load_reg); ni_tio_set_bits_transient(counter, NITIO_CMD_REG(cidx), 0, 0, GI_LOAD); /* restore load reg */ - write_register(counter, counter_dev->regs[load_reg], load_reg); + ni_tio_write(counter, counter_dev->regs[load_reg], load_reg); break; case 1: counter_dev->regs[NITIO_LOADA_REG(cidx)] = data[0]; - write_register(counter, data[0], NITIO_LOADA_REG(cidx)); + ni_tio_write(counter, data[0], NITIO_LOADA_REG(cidx)); break; case 2: counter_dev->regs[NITIO_LOADB_REG(cidx)] = data[0]; - write_register(counter, data[0], NITIO_LOADB_REG(cidx)); + ni_tio_write(counter, data[0], NITIO_LOADB_REG(cidx)); break; default: return -EINVAL; @@ -1398,7 +1424,7 @@ void ni_tio_init_counter(struct ni_gpct *counter) /* initialize counter registers */ counter_dev->regs[NITIO_AUTO_INC_REG(cidx)] = 0x0; - write_register(counter, 0x0, NITIO_AUTO_INC_REG(cidx)); + ni_tio_write(counter, 0x0, NITIO_AUTO_INC_REG(cidx)); ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), ~0, GI_SYNC_GATE); @@ -1406,10 +1432,10 @@ void ni_tio_init_counter(struct ni_gpct *counter) ni_tio_set_bits(counter, NITIO_MODE_REG(cidx), ~0, 0); counter_dev->regs[NITIO_LOADA_REG(cidx)] = 0x0; - write_register(counter, 0x0, NITIO_LOADA_REG(cidx)); + ni_tio_write(counter, 0x0, NITIO_LOADA_REG(cidx)); counter_dev->regs[NITIO_LOADB_REG(cidx)] = 0x0; - write_register(counter, 0x0, NITIO_LOADB_REG(cidx)); + ni_tio_write(counter, 0x0, NITIO_LOADB_REG(cidx)); ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx), ~0, 0); @@ -1418,7 +1444,7 @@ void ni_tio_init_counter(struct ni_gpct *counter) if (ni_tio_has_gate2_registers(counter_dev)) { counter_dev->regs[NITIO_GATE2_REG(cidx)] = 0x0; - write_register(counter, 0x0, NITIO_GATE2_REG(cidx)); + ni_tio_write(counter, 0x0, NITIO_GATE2_REG(cidx)); } ni_tio_set_bits(counter, NITIO_DMA_CFG_REG(cidx), ~0, 0x0); diff --git a/drivers/staging/comedi/drivers/ni_tio_internal.h b/drivers/staging/comedi/drivers/ni_tio_internal.h index 1e795fd6f288..b15b10833c42 100644 --- a/drivers/staging/comedi/drivers/ni_tio_internal.h +++ b/drivers/staging/comedi/drivers/ni_tio_internal.h @@ -160,19 +160,8 @@ #define GI_TC_INTERRUPT_ENABLE(x) (((x) % 2) ? BIT(9) : BIT(6)) #define GI_GATE_INTERRUPT_ENABLE(x) (((x) % 2) ? BIT(10) : BIT(8)) -static inline void write_register(struct ni_gpct *counter, unsigned bits, - enum ni_gpct_register reg) -{ - BUG_ON(reg >= NITIO_NUM_REGS); - counter->counter_dev->write_register(counter, bits, reg); -} - -static inline unsigned read_register(struct ni_gpct *counter, - enum ni_gpct_register reg) -{ - BUG_ON(reg >= NITIO_NUM_REGS); - return counter->counter_dev->read_register(counter, reg); -} +void ni_tio_write(struct ni_gpct *, unsigned int value, enum ni_gpct_register); +unsigned int ni_tio_read(struct ni_gpct *, enum ni_gpct_register); static inline bool ni_tio_counting_mode_registers_present(const struct ni_gpct_device *counter_dev) diff --git a/drivers/staging/comedi/drivers/ni_tiocmd.c b/drivers/staging/comedi/drivers/ni_tiocmd.c index 0546a55b7277..d5ffbb135844 100644 --- a/drivers/staging/comedi/drivers/ni_tiocmd.c +++ b/drivers/staging/comedi/drivers/ni_tiocmd.c @@ -342,9 +342,9 @@ static void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, int *stale_data) { unsigned cidx = counter->counter_index; - const unsigned short gxx_status = read_register(counter, + const unsigned short gxx_status = ni_tio_read(counter, NITIO_SHARED_STATUS_REG(cidx)); - const unsigned short gi_status = read_register(counter, + const unsigned short gi_status = ni_tio_read(counter, NITIO_STATUS_REG(cidx)); unsigned ack = 0; @@ -380,14 +380,14 @@ static void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, ack |= GI_GATE_INTERRUPT_ACK; } if (ack) - write_register(counter, ack, NITIO_INT_ACK_REG(cidx)); + ni_tio_write(counter, ack, NITIO_INT_ACK_REG(cidx)); if (ni_tio_get_soft_copy(counter, NITIO_MODE_REG(cidx)) & GI_LOADING_ON_GATE) { if (gxx_status & GI_STALE_DATA(cidx)) { if (stale_data) *stale_data = 1; } - if (read_register(counter, NITIO_STATUS2_REG(cidx)) & + if (ni_tio_read(counter, NITIO_STATUS2_REG(cidx)) & GI_PERMANENT_STALE(cidx)) { dev_info(counter->counter_dev->dev->class_dev, "%s: Gi_Permanent_Stale_Data detected.\n", @@ -426,7 +426,7 @@ void ni_tio_handle_interrupt(struct ni_gpct *counter, switch (counter->counter_dev->variant) { case ni_gpct_variant_m_series: case ni_gpct_variant_660x: - if (read_register(counter, NITIO_DMA_STATUS_REG(cidx)) & + if (ni_tio_read(counter, NITIO_DMA_STATUS_REG(cidx)) & GI_DRQ_ERROR) { dev_notice(counter->counter_dev->dev->class_dev, "%s: Gi_DRQ_Error detected.\n", __func__); -- cgit v1.2.3 From 5994e51b20600accd55e9aaeeb0b78e5ca038e19 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 Mar 2016 15:36:45 -0700 Subject: staging: comedi: ni_tio: tidy up struct ni_gpct_device (*{write, read}_register) For aesthetics, rename these callbacks to simply read/write. Change the 'unsigned' parameters to 'unsigned int'. This fixes a number of checkpatch.pl issues: WARNING: Prefer 'unsigned int' to bare use of 'unsigned' Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tio.c | 22 +++++++++++----------- drivers/staging/comedi/drivers/ni_tio.h | 19 +++++++++---------- 2 files changed, 20 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c index a225279cb83f..28bec3cfeef5 100644 --- a/drivers/staging/comedi/drivers/ni_tio.c +++ b/drivers/staging/comedi/drivers/ni_tio.c @@ -189,7 +189,7 @@ void ni_tio_write(struct ni_gpct *counter, unsigned int value, enum ni_gpct_register reg) { if (reg < NITIO_NUM_REGS) - counter->counter_dev->write_register(counter, value, reg); + counter->counter_dev->write(counter, value, reg); } EXPORT_SYMBOL_GPL(ni_tio_write); @@ -201,7 +201,7 @@ EXPORT_SYMBOL_GPL(ni_tio_write); unsigned int ni_tio_read(struct ni_gpct *counter, enum ni_gpct_register reg) { if (reg < NITIO_NUM_REGS) - return counter->counter_dev->read_register(counter, reg); + return counter->counter_dev->read(counter, reg); return 0; } EXPORT_SYMBOL_GPL(ni_tio_read); @@ -1455,17 +1455,17 @@ EXPORT_SYMBOL_GPL(ni_tio_init_counter); struct ni_gpct_device * ni_gpct_device_construct(struct comedi_device *dev, - void (*write_register)(struct ni_gpct *counter, - unsigned bits, - enum ni_gpct_register reg), - unsigned (*read_register)(struct ni_gpct *counter, - enum ni_gpct_register reg), + void (*write)(struct ni_gpct *counter, + unsigned int value, + enum ni_gpct_register reg), + unsigned int (*read)(struct ni_gpct *counter, + enum ni_gpct_register reg), enum ni_gpct_variant variant, - unsigned num_counters) + unsigned int num_counters) { struct ni_gpct_device *counter_dev; struct ni_gpct *counter; - unsigned i; + unsigned int i; if (num_counters == 0) return NULL; @@ -1475,8 +1475,8 @@ ni_gpct_device_construct(struct comedi_device *dev, return NULL; counter_dev->dev = dev; - counter_dev->write_register = write_register; - counter_dev->read_register = read_register; + counter_dev->write = write; + counter_dev->read = read; counter_dev->variant = variant; spin_lock_init(&counter_dev->regs_lock); diff --git a/drivers/staging/comedi/drivers/ni_tio.h b/drivers/staging/comedi/drivers/ni_tio.h index 25aedd0e5867..63cec3edcfd4 100644 --- a/drivers/staging/comedi/drivers/ni_tio.h +++ b/drivers/staging/comedi/drivers/ni_tio.h @@ -115,10 +115,9 @@ struct ni_gpct { struct ni_gpct_device { struct comedi_device *dev; - void (*write_register)(struct ni_gpct *counter, unsigned bits, - enum ni_gpct_register reg); - unsigned (*read_register)(struct ni_gpct *counter, - enum ni_gpct_register reg); + void (*write)(struct ni_gpct *, unsigned int value, + enum ni_gpct_register); + unsigned int (*read)(struct ni_gpct *, enum ni_gpct_register); enum ni_gpct_variant variant; struct ni_gpct *counters; unsigned num_counters; @@ -128,13 +127,13 @@ struct ni_gpct_device { struct ni_gpct_device * ni_gpct_device_construct(struct comedi_device *, - void (*write_register)(struct ni_gpct *, - unsigned bits, - enum ni_gpct_register), - unsigned (*read_register)(struct ni_gpct *, - enum ni_gpct_register), + void (*write)(struct ni_gpct *, + unsigned int value, + enum ni_gpct_register), + unsigned int (*read)(struct ni_gpct *, + enum ni_gpct_register), enum ni_gpct_variant, - unsigned num_counters); + unsigned int num_counters); void ni_gpct_device_destroy(struct ni_gpct_device *); void ni_tio_init_counter(struct ni_gpct *); int ni_tio_insn_read(struct comedi_device *, struct comedi_subdevice *, -- cgit v1.2.3 From a38a1408868c6f476f8f41881b7d7757e24f61c2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 Mar 2016 15:36:46 -0700 Subject: staging: comedi: ni_tio.h: tidy up struct ni_gpct_device Fix the checkpatch.pl issues: WARNING: Prefer 'unsigned int' to bare use of 'unsigned' CHECK: spinlock_t definition without comment Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tio.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_tio.h b/drivers/staging/comedi/drivers/ni_tio.h index 63cec3edcfd4..2f36dc1cad63 100644 --- a/drivers/staging/comedi/drivers/ni_tio.h +++ b/drivers/staging/comedi/drivers/ni_tio.h @@ -120,9 +120,9 @@ struct ni_gpct_device { unsigned int (*read)(struct ni_gpct *, enum ni_gpct_register); enum ni_gpct_variant variant; struct ni_gpct *counters; - unsigned num_counters; - unsigned regs[NITIO_NUM_REGS]; - spinlock_t regs_lock; + unsigned int num_counters; + unsigned int regs[NITIO_NUM_REGS]; + spinlock_t regs_lock; /* protects 'regs' */ }; struct ni_gpct_device * -- cgit v1.2.3 From 10142ced7dc10261b7ff3598dedb3f6c4cb64e6d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 Mar 2016 15:36:47 -0700 Subject: staging: comedi: ni_tio.h: tidy up struct ni_gpct Fix the checkpatch.pl issues: WARNING: Prefer 'unsigned int' to bare use of 'unsigned' CHECK: Prefer kernel type 'u64' over 'uint64_t' CHECK: spinlock_t definition without comment Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tio.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_tio.h b/drivers/staging/comedi/drivers/ni_tio.h index 2f36dc1cad63..5d0374302301 100644 --- a/drivers/staging/comedi/drivers/ni_tio.h +++ b/drivers/staging/comedi/drivers/ni_tio.h @@ -106,11 +106,11 @@ enum ni_gpct_variant { struct ni_gpct { struct ni_gpct_device *counter_dev; - unsigned counter_index; - unsigned chip_index; - uint64_t clock_period_ps; /* clock period in picoseconds */ + unsigned int counter_index; + unsigned int chip_index; + u64 clock_period_ps; /* clock period in picoseconds */ struct mite_channel *mite_chan; - spinlock_t lock; + spinlock_t lock; /* protects 'mite_chan' */ }; struct ni_gpct_device { -- cgit v1.2.3 From 80168e9e583717b061cc144a06fc35dca2cc2e26 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 Mar 2016 15:36:48 -0700 Subject: staging: comedi: ni_tio.h: fix block comment Fix the checkpatch.pl issue: WARNING: Block comments use * on subsequent lines Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tio.h | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_tio.h b/drivers/staging/comedi/drivers/ni_tio.h index 5d0374302301..7ddafdd74095 100644 --- a/drivers/staging/comedi/drivers/ni_tio.h +++ b/drivers/staging/comedi/drivers/ni_tio.h @@ -1,19 +1,18 @@ /* - drivers/ni_tio.h - Header file for NI general purpose counter support code (ni_tio.c) - - COMEDI - Linux Control and Measurement Device Interface - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -*/ + * Header file for NI general purpose counter support code (ni_tio.c) + * + * COMEDI - Linux Control and Measurement Device Interface + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ #ifndef _COMEDI_NI_TIO_H #define _COMEDI_NI_TIO_H -- cgit v1.2.3 From 58011fdebb21a746ce43c8ada363a65c55200d74 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 Mar 2016 15:36:49 -0700 Subject: staging: comedi: ni_tio.h: remove unnecessary forward declarations These struct forward declarations are not needed. Remove them. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tio.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_tio.h b/drivers/staging/comedi/drivers/ni_tio.h index 7ddafdd74095..4978358f9b13 100644 --- a/drivers/staging/comedi/drivers/ni_tio.h +++ b/drivers/staging/comedi/drivers/ni_tio.h @@ -19,10 +19,6 @@ #include "../comedidev.h" -/* forward declarations */ -struct mite_struct; -struct ni_gpct_device; - enum ni_gpct_register { NITIO_G0_AUTO_INC, NITIO_G1_AUTO_INC, -- cgit v1.2.3 From 74ea93be6ce16f01e9e73a4ad5abeb984b0b02fc Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 Mar 2016 15:36:50 -0700 Subject: staging: comedi: ni_tio: Prefer 'unsigned int' to bare use of 'unsigned' Fix the checkpatch.pl issues. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tio.c | 166 ++++++++++++++++---------------- 1 file changed, 83 insertions(+), 83 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c index 28bec3cfeef5..ecf85270c264 100644 --- a/drivers/staging/comedi/drivers/ni_tio.c +++ b/drivers/staging/comedi/drivers/ni_tio.c @@ -115,7 +115,7 @@ TODO: #define NI_660X_LOGIC_LOW_GATE2_SEL 0x1f #define NI_660X_MAX_UP_DOWN_PIN 7 -static inline unsigned GI_ALT_SYNC(enum ni_gpct_variant variant) +static inline unsigned int GI_ALT_SYNC(enum ni_gpct_variant variant) { switch (variant) { case ni_gpct_variant_e_series: @@ -128,7 +128,7 @@ static inline unsigned GI_ALT_SYNC(enum ni_gpct_variant variant) } } -static inline unsigned GI_PRESCALE_X2(enum ni_gpct_variant variant) +static inline unsigned int GI_PRESCALE_X2(enum ni_gpct_variant variant) { switch (variant) { case ni_gpct_variant_e_series: @@ -141,7 +141,7 @@ static inline unsigned GI_PRESCALE_X2(enum ni_gpct_variant variant) } } -static inline unsigned GI_PRESCALE_X8(enum ni_gpct_variant variant) +static inline unsigned int GI_PRESCALE_X8(enum ni_gpct_variant variant) { switch (variant) { case ni_gpct_variant_e_series: @@ -154,7 +154,7 @@ static inline unsigned GI_PRESCALE_X8(enum ni_gpct_variant variant) } } -static inline unsigned GI_HW_ARM_SEL_MASK(enum ni_gpct_variant variant) +static inline unsigned int GI_HW_ARM_SEL_MASK(enum ni_gpct_variant variant) { switch (variant) { case ni_gpct_variant_e_series: @@ -208,13 +208,13 @@ EXPORT_SYMBOL_GPL(ni_tio_read); static void ni_tio_reset_count_and_disarm(struct ni_gpct *counter) { - unsigned cidx = counter->counter_index; + unsigned int cidx = counter->counter_index; ni_tio_write(counter, GI_RESET(cidx), NITIO_RESET_REG(cidx)); } static uint64_t ni_tio_clock_period_ps(const struct ni_gpct *counter, - unsigned generic_clock_source) + unsigned int generic_clock_source) { uint64_t clock_period_ps; @@ -316,13 +316,13 @@ unsigned int ni_tio_get_soft_copy(const struct ni_gpct *counter, } EXPORT_SYMBOL_GPL(ni_tio_get_soft_copy); -static unsigned ni_tio_clock_src_modifiers(const struct ni_gpct *counter) +static unsigned int ni_tio_clock_src_modifiers(const struct ni_gpct *counter) { struct ni_gpct_device *counter_dev = counter->counter_dev; - unsigned cidx = counter->counter_index; - const unsigned counting_mode_bits = + unsigned int cidx = counter->counter_index; + unsigned int counting_mode_bits = ni_tio_get_soft_copy(counter, NITIO_CNT_MODE_REG(cidx)); - unsigned bits = 0; + unsigned int bits = 0; if (ni_tio_get_soft_copy(counter, NITIO_INPUT_SEL_REG(cidx)) & GI_SRC_POL_INVERT) @@ -334,14 +334,14 @@ static unsigned ni_tio_clock_src_modifiers(const struct ni_gpct *counter) return bits; } -static unsigned ni_m_series_clock_src_select(const struct ni_gpct *counter) +static unsigned int ni_m_series_clock_src_select(const struct ni_gpct *counter) { struct ni_gpct_device *counter_dev = counter->counter_dev; - unsigned cidx = counter->counter_index; - const unsigned second_gate_reg = NITIO_GATE2_REG(cidx); - unsigned clock_source = 0; - unsigned src; - unsigned i; + unsigned int cidx = counter->counter_index; + unsigned int second_gate_reg = NITIO_GATE2_REG(cidx); + unsigned int clock_source = 0; + unsigned int src; + unsigned int i; src = GI_BITS_TO_SRC(ni_tio_get_soft_copy(counter, NITIO_INPUT_SEL_REG(cidx))); @@ -399,12 +399,12 @@ static unsigned ni_m_series_clock_src_select(const struct ni_gpct *counter) return clock_source; } -static unsigned ni_660x_clock_src_select(const struct ni_gpct *counter) +static unsigned int ni_660x_clock_src_select(const struct ni_gpct *counter) { - unsigned clock_source = 0; - unsigned cidx = counter->counter_index; - unsigned src; - unsigned i; + unsigned int clock_source = 0; + unsigned int cidx = counter->counter_index; + unsigned int src; + unsigned int i; src = GI_BITS_TO_SRC(ni_tio_get_soft_copy(counter, NITIO_INPUT_SEL_REG(cidx))); @@ -456,7 +456,8 @@ static unsigned ni_660x_clock_src_select(const struct ni_gpct *counter) return clock_source; } -static unsigned ni_tio_generic_clock_src_select(const struct ni_gpct *counter) +static unsigned int +ni_tio_generic_clock_src_select(const struct ni_gpct *counter) { switch (counter->counter_dev->variant) { case ni_gpct_variant_e_series: @@ -471,10 +472,10 @@ static unsigned ni_tio_generic_clock_src_select(const struct ni_gpct *counter) static void ni_tio_set_sync_mode(struct ni_gpct *counter, int force_alt_sync) { struct ni_gpct_device *counter_dev = counter->counter_dev; - unsigned cidx = counter->counter_index; - const unsigned counting_mode_reg = NITIO_CNT_MODE_REG(cidx); + unsigned int cidx = counter->counter_index; + unsigned int counting_mode_reg = NITIO_CNT_MODE_REG(cidx); static const uint64_t min_normal_sync_period_ps = 25000; - unsigned mode; + unsigned int mode; uint64_t clock_period_ps; if (!ni_tio_counting_mode_registers_present(counter_dev)) @@ -512,15 +513,15 @@ static void ni_tio_set_sync_mode(struct ni_gpct *counter, int force_alt_sync) } } -static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned mode) +static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned int mode) { struct ni_gpct_device *counter_dev = counter->counter_dev; - unsigned cidx = counter->counter_index; - unsigned mode_reg_mask; - unsigned mode_reg_values; - unsigned input_select_bits = 0; + unsigned int cidx = counter->counter_index; + unsigned int mode_reg_mask; + unsigned int mode_reg_values; + unsigned int input_select_bits = 0; /* these bits map directly on to the mode register */ - static const unsigned mode_reg_direct_mask = + static const unsigned int mode_reg_direct_mask = NI_GPCT_GATE_ON_BOTH_EDGES_BIT | NI_GPCT_EDGE_GATE_MODE_MASK | NI_GPCT_STOP_MODE_MASK | NI_GPCT_OUTPUT_MODE_MASK | NI_GPCT_HARDWARE_DISARM_MASK | NI_GPCT_LOADING_ON_TC_BIT | @@ -546,7 +547,7 @@ static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned mode) mode_reg_mask, mode_reg_values); if (ni_tio_counting_mode_registers_present(counter_dev)) { - unsigned bits = 0; + unsigned int bits = 0; bits |= GI_CNT_MODE(mode >> NI_GPCT_COUNTING_MODE_SHIFT); bits |= GI_INDEX_PHASE((mode >> NI_GPCT_INDEX_PHASE_BITSHIFT)); @@ -626,11 +627,11 @@ int ni_tio_arm(struct ni_gpct *counter, bool arm, unsigned int start_trigger) } EXPORT_SYMBOL_GPL(ni_tio_arm); -static unsigned ni_660x_clk_src(unsigned int clock_source) +static unsigned int ni_660x_clk_src(unsigned int clock_source) { - unsigned clk_src = clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK; - unsigned ni_660x_clock; - unsigned i; + unsigned int clk_src = clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK; + unsigned int ni_660x_clock; + unsigned int i; switch (clk_src) { case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS: @@ -678,11 +679,11 @@ static unsigned ni_660x_clk_src(unsigned int clock_source) return GI_SRC_SEL(ni_660x_clock); } -static unsigned ni_m_clk_src(unsigned int clock_source) +static unsigned int ni_m_clk_src(unsigned int clock_source) { - unsigned clk_src = clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK; - unsigned ni_m_series_clock; - unsigned i; + unsigned int clk_src = clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK; + unsigned int ni_m_series_clock; + unsigned int i; switch (clk_src) { case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS: @@ -742,8 +743,8 @@ static void ni_tio_set_source_subselect(struct ni_gpct *counter, unsigned int clock_source) { struct ni_gpct_device *counter_dev = counter->counter_dev; - unsigned cidx = counter->counter_index; - const unsigned second_gate_reg = NITIO_GATE2_REG(cidx); + unsigned int cidx = counter->counter_index; + unsigned int second_gate_reg = NITIO_GATE2_REG(cidx); if (counter_dev->variant != ni_gpct_variant_m_series) return; @@ -771,8 +772,8 @@ static int ni_tio_set_clock_src(struct ni_gpct *counter, unsigned int period_ns) { struct ni_gpct_device *counter_dev = counter->counter_dev; - unsigned cidx = counter->counter_index; - unsigned bits = 0; + unsigned int cidx = counter->counter_index; + unsigned int bits = 0; /* FIXME: validate clock source */ switch (counter_dev->variant) { @@ -829,9 +830,9 @@ static void ni_tio_get_clock_src(struct ni_gpct *counter, static int ni_660x_set_gate(struct ni_gpct *counter, unsigned int gate_source) { unsigned int chan = CR_CHAN(gate_source); - unsigned cidx = counter->counter_index; - unsigned gate_sel; - unsigned i; + unsigned int cidx = counter->counter_index; + unsigned int gate_sel; + unsigned int i; switch (chan) { case NI_GPCT_NEXT_SOURCE_GATE_SELECT: @@ -870,9 +871,9 @@ static int ni_660x_set_gate(struct ni_gpct *counter, unsigned int gate_source) static int ni_m_set_gate(struct ni_gpct *counter, unsigned int gate_source) { unsigned int chan = CR_CHAN(gate_source); - unsigned cidx = counter->counter_index; - unsigned gate_sel; - unsigned i; + unsigned int cidx = counter->counter_index; + unsigned int gate_sel; + unsigned int i; switch (chan) { case NI_GPCT_TIMESTAMP_MUX_GATE_SELECT: @@ -912,11 +913,11 @@ static int ni_m_set_gate(struct ni_gpct *counter, unsigned int gate_source) static int ni_660x_set_gate2(struct ni_gpct *counter, unsigned int gate_source) { struct ni_gpct_device *counter_dev = counter->counter_dev; - unsigned cidx = counter->counter_index; + unsigned int cidx = counter->counter_index; unsigned int chan = CR_CHAN(gate_source); - unsigned gate2_reg = NITIO_GATE2_REG(cidx); - unsigned gate2_sel; - unsigned i; + unsigned int gate2_reg = NITIO_GATE2_REG(cidx); + unsigned int gate2_sel; + unsigned int i; switch (chan) { case NI_GPCT_SOURCE_PIN_i_GATE_SELECT: @@ -958,10 +959,10 @@ static int ni_660x_set_gate2(struct ni_gpct *counter, unsigned int gate_source) static int ni_m_set_gate2(struct ni_gpct *counter, unsigned int gate_source) { struct ni_gpct_device *counter_dev = counter->counter_dev; - unsigned cidx = counter->counter_index; + unsigned int cidx = counter->counter_index; unsigned int chan = CR_CHAN(gate_source); - unsigned gate2_reg = NITIO_GATE2_REG(cidx); - unsigned gate2_sel; + unsigned int gate2_reg = NITIO_GATE2_REG(cidx); + unsigned int gate2_sel; /* * FIXME: We don't know what the m-series second gate codes are, @@ -1045,11 +1046,11 @@ int ni_tio_set_gate_src(struct ni_gpct *counter, } EXPORT_SYMBOL_GPL(ni_tio_set_gate_src); -static int ni_tio_set_other_src(struct ni_gpct *counter, unsigned index, +static int ni_tio_set_other_src(struct ni_gpct *counter, unsigned int index, unsigned int source) { struct ni_gpct_device *counter_dev = counter->counter_dev; - unsigned cidx = counter->counter_index; + unsigned int cidx = counter->counter_index; unsigned int abz_reg, shift, mask; if (counter_dev->variant != ni_gpct_variant_m_series) @@ -1079,9 +1080,9 @@ static int ni_tio_set_other_src(struct ni_gpct *counter, unsigned index, return 0; } -static unsigned ni_660x_gate_to_generic_gate(unsigned gate) +static unsigned int ni_660x_gate_to_generic_gate(unsigned int gate) { - unsigned i; + unsigned int i; switch (gate) { case NI_660X_SRC_PIN_I_GATE_SEL: @@ -1109,9 +1110,9 @@ static unsigned ni_660x_gate_to_generic_gate(unsigned gate) return 0; }; -static unsigned ni_m_gate_to_generic_gate(unsigned gate) +static unsigned int ni_m_gate_to_generic_gate(unsigned int gate) { - unsigned i; + unsigned int i; switch (gate) { case NI_M_TIMESTAMP_MUX_GATE_SEL: @@ -1145,9 +1146,9 @@ static unsigned ni_m_gate_to_generic_gate(unsigned gate) return 0; }; -static unsigned ni_660x_gate2_to_generic_gate(unsigned gate) +static unsigned int ni_660x_gate2_to_generic_gate(unsigned int gate) { - unsigned i; + unsigned int i; switch (gate) { case NI_660X_SRC_PIN_I_GATE2_SEL: @@ -1177,7 +1178,7 @@ static unsigned ni_660x_gate2_to_generic_gate(unsigned gate) return 0; }; -static unsigned ni_m_gate2_to_generic_gate(unsigned gate) +static unsigned int ni_m_gate2_to_generic_gate(unsigned int gate) { /* * FIXME: the second gate sources for the m series are undocumented, @@ -1190,14 +1191,14 @@ static unsigned ni_m_gate2_to_generic_gate(unsigned gate) return 0; }; -static int ni_tio_get_gate_src(struct ni_gpct *counter, unsigned gate_index, +static int ni_tio_get_gate_src(struct ni_gpct *counter, unsigned int gate_index, unsigned int *gate_source) { struct ni_gpct_device *counter_dev = counter->counter_dev; - unsigned cidx = counter->counter_index; - unsigned mode = ni_tio_get_soft_copy(counter, NITIO_MODE_REG(cidx)); - unsigned gate2_reg = NITIO_GATE2_REG(cidx); - unsigned gate; + unsigned int cidx = counter->counter_index; + unsigned int mode = ni_tio_get_soft_copy(counter, NITIO_MODE_REG(cidx)); + unsigned int gate2_reg = NITIO_GATE2_REG(cidx); + unsigned int gate; switch (gate_index) { case 0: @@ -1261,8 +1262,8 @@ int ni_tio_insn_config(struct comedi_device *dev, unsigned int *data) { struct ni_gpct *counter = s->private; - unsigned cidx = counter->counter_index; - unsigned status; + unsigned int cidx = counter->counter_index; + unsigned int status; switch (data[0]) { case INSN_CONFIG_SET_COUNTER_MODE: @@ -1307,7 +1308,7 @@ static unsigned int ni_tio_read_sw_save_reg(struct comedi_device *dev, struct comedi_subdevice *s) { struct ni_gpct *counter = s->private; - unsigned cidx = counter->counter_index; + unsigned int cidx = counter->counter_index; unsigned int val; ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), GI_SAVE_TRACE, 0); @@ -1338,7 +1339,7 @@ int ni_tio_insn_read(struct comedi_device *dev, struct ni_gpct *counter = s->private; struct ni_gpct_device *counter_dev = counter->counter_dev; unsigned int channel = CR_CHAN(insn->chanspec); - unsigned cidx = counter->counter_index; + unsigned int cidx = counter->counter_index; int i; for (i = 0; i < insn->n; i++) { @@ -1358,11 +1359,10 @@ int ni_tio_insn_read(struct comedi_device *dev, } EXPORT_SYMBOL_GPL(ni_tio_insn_read); -static unsigned ni_tio_next_load_register(struct ni_gpct *counter) +static unsigned int ni_tio_next_load_register(struct ni_gpct *counter) { - unsigned cidx = counter->counter_index; - const unsigned bits = - ni_tio_read(counter, NITIO_SHARED_STATUS_REG(cidx)); + unsigned int cidx = counter->counter_index; + unsigned int bits = ni_tio_read(counter, NITIO_SHARED_STATUS_REG(cidx)); return (bits & GI_NEXT_LOAD_SRC(cidx)) ? NITIO_LOADB_REG(cidx) @@ -1376,9 +1376,9 @@ int ni_tio_insn_write(struct comedi_device *dev, { struct ni_gpct *counter = s->private; struct ni_gpct_device *counter_dev = counter->counter_dev; - const unsigned channel = CR_CHAN(insn->chanspec); - unsigned cidx = counter->counter_index; - unsigned load_reg; + unsigned int channel = CR_CHAN(insn->chanspec); + unsigned int cidx = counter->counter_index; + unsigned int load_reg; if (insn->n < 1) return 0; @@ -1418,7 +1418,7 @@ EXPORT_SYMBOL_GPL(ni_tio_insn_write); void ni_tio_init_counter(struct ni_gpct *counter) { struct ni_gpct_device *counter_dev = counter->counter_dev; - unsigned cidx = counter->counter_index; + unsigned int cidx = counter->counter_index; ni_tio_reset_count_and_disarm(counter); -- cgit v1.2.3 From 3676cdd9539a64d1b3e8cad8d8e5184bf860841a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 Mar 2016 15:36:51 -0700 Subject: staging: comedi: ni_tio: Prefer kernel type 'u64' over 'uint64_t' Fix the checkpatch.pl issues. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tio.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c index ecf85270c264..e4fd22123ef0 100644 --- a/drivers/staging/comedi/drivers/ni_tio.c +++ b/drivers/staging/comedi/drivers/ni_tio.c @@ -213,10 +213,10 @@ static void ni_tio_reset_count_and_disarm(struct ni_gpct *counter) ni_tio_write(counter, GI_RESET(cidx), NITIO_RESET_REG(cidx)); } -static uint64_t ni_tio_clock_period_ps(const struct ni_gpct *counter, - unsigned int generic_clock_source) +static u64 ni_tio_clock_period_ps(const struct ni_gpct *counter, + unsigned int generic_clock_source) { - uint64_t clock_period_ps; + u64 clock_period_ps; switch (generic_clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK) { case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS: @@ -474,9 +474,9 @@ static void ni_tio_set_sync_mode(struct ni_gpct *counter, int force_alt_sync) struct ni_gpct_device *counter_dev = counter->counter_dev; unsigned int cidx = counter->counter_index; unsigned int counting_mode_reg = NITIO_CNT_MODE_REG(cidx); - static const uint64_t min_normal_sync_period_ps = 25000; + static const u64 min_normal_sync_period_ps = 25000; unsigned int mode; - uint64_t clock_period_ps; + u64 clock_period_ps; if (!ni_tio_counting_mode_registers_present(counter_dev)) return; @@ -819,7 +819,7 @@ static void ni_tio_get_clock_src(struct ni_gpct *counter, unsigned int *clock_source, unsigned int *period_ns) { - uint64_t temp64; + u64 temp64; *clock_source = ni_tio_generic_clock_src_select(counter); temp64 = ni_tio_clock_period_ps(counter, *clock_source); -- cgit v1.2.3 From 8e621cf0cb9761b7ef74a63d228ce62418dc5b8c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 Mar 2016 15:36:52 -0700 Subject: staging: comedi: ni_tio: fix block comments Fix the checkpatch.pl issues: WARNING: Block comments use * on subsequent lines Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tio.c | 36 +++++++++++++++------------------ 1 file changed, 16 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c index e4fd22123ef0..e7af98d78607 100644 --- a/drivers/staging/comedi/drivers/ni_tio.c +++ b/drivers/staging/comedi/drivers/ni_tio.c @@ -1,19 +1,18 @@ /* - comedi/drivers/ni_tio.c - Support for NI general purpose counters - - Copyright (C) 2006 Frank Mori Hess - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -*/ + * Support for NI general purpose counters + * + * Copyright (C) 2006 Frank Mori Hess + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ /* * Module: ni_tio @@ -36,13 +35,10 @@ * DAQ 660x Register-Level Programmer Manual (NI 370505A-01) * DAQ 6601/6602 User Manual (NI 322137B-01) * 340934b.pdf DAQ-STC reference manual + * + * TODO: Support use of both banks X and Y */ -/* -TODO: - Support use of both banks X and Y -*/ - #include #include -- cgit v1.2.3 From a56b3f57c2f08a6f42c957c3731ca9f8158b6355 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 Mar 2016 15:36:53 -0700 Subject: staging: comedi: ni_tio: tidy up ni_tio_get_gate_src() Clarify the code a bit by handling the NI_GPCT_DISABLED_GATE_SELECT source in the common code path. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tio.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c index e7af98d78607..ce64cc39e49c 100644 --- a/drivers/staging/comedi/drivers/ni_tio.c +++ b/drivers/staging/comedi/drivers/ni_tio.c @@ -1192,19 +1192,22 @@ static int ni_tio_get_gate_src(struct ni_gpct *counter, unsigned int gate_index, { struct ni_gpct_device *counter_dev = counter->counter_dev; unsigned int cidx = counter->counter_index; - unsigned int mode = ni_tio_get_soft_copy(counter, NITIO_MODE_REG(cidx)); - unsigned int gate2_reg = NITIO_GATE2_REG(cidx); + unsigned int mode; + unsigned int reg; unsigned int gate; + mode = ni_tio_get_soft_copy(counter, NITIO_MODE_REG(cidx)); + if (((mode & GI_GATING_MODE_MASK) == GI_GATING_DISABLED) || + (gate_index == 1 && + !(counter_dev->regs[NITIO_GATE2_REG(cidx)] & GI_GATE2_MODE))) { + *gate_source = NI_GPCT_DISABLED_GATE_SELECT; + return 0; + } + switch (gate_index) { case 0: - if ((mode & GI_GATING_MODE_MASK) == GI_GATING_DISABLED) { - *gate_source = NI_GPCT_DISABLED_GATE_SELECT; - return 0; - } - - gate = GI_BITS_TO_GATE(ni_tio_get_soft_copy(counter, - NITIO_INPUT_SEL_REG(cidx))); + reg = NITIO_INPUT_SEL_REG(cidx); + gate = GI_BITS_TO_GATE(ni_tio_get_soft_copy(counter, reg)); switch (counter_dev->variant) { case ni_gpct_variant_e_series: @@ -1222,13 +1225,8 @@ static int ni_tio_get_gate_src(struct ni_gpct *counter, unsigned int gate_index, *gate_source |= CR_EDGE; break; case 1: - if ((mode & GI_GATING_MODE_MASK) == GI_GATING_DISABLED || - !(counter_dev->regs[gate2_reg] & GI_GATE2_MODE)) { - *gate_source = NI_GPCT_DISABLED_GATE_SELECT; - return 0; - } - - gate = GI_BITS_TO_GATE2(counter_dev->regs[gate2_reg]); + reg = NITIO_GATE2_REG(cidx); + gate = GI_BITS_TO_GATE2(counter_dev->regs[reg]); switch (counter_dev->variant) { case ni_gpct_variant_e_series: @@ -1240,7 +1238,7 @@ static int ni_tio_get_gate_src(struct ni_gpct *counter, unsigned int gate_index, *gate_source = ni_660x_gate2_to_generic_gate(gate); break; } - if (counter_dev->regs[gate2_reg] & GI_GATE2_POL_INVERT) + if (counter_dev->regs[reg] & GI_GATE2_POL_INVERT) *gate_source |= CR_INVERT; /* second gate can't have edge/level mode set independently */ if ((mode & GI_GATING_MODE_MASK) != GI_LEVEL_GATING) -- cgit v1.2.3 From f51700a6428d7c8e94d48fd2fbb1062c604e8b2c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 Mar 2016 15:36:54 -0700 Subject: staging: comedi: ni_tio: tidy up ni_tio_set_sync_mode() The 'force_alt_sync' paramater is always 0. Remove it. Absorb the GI_ALT_SYNC() inline helper and use some local variables to clarify this function. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tio.c | 65 +++++++++++++++------------------ 1 file changed, 30 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c index ce64cc39e49c..2c33b28bf114 100644 --- a/drivers/staging/comedi/drivers/ni_tio.c +++ b/drivers/staging/comedi/drivers/ni_tio.c @@ -111,19 +111,6 @@ #define NI_660X_LOGIC_LOW_GATE2_SEL 0x1f #define NI_660X_MAX_UP_DOWN_PIN 7 -static inline unsigned int GI_ALT_SYNC(enum ni_gpct_variant variant) -{ - switch (variant) { - case ni_gpct_variant_e_series: - default: - return 0; - case ni_gpct_variant_m_series: - return GI_M_ALT_SYNC; - case ni_gpct_variant_660x: - return GI_660X_ALT_SYNC; - } -} - static inline unsigned int GI_PRESCALE_X2(enum ni_gpct_variant variant) { switch (variant) { @@ -465,48 +452,56 @@ ni_tio_generic_clock_src_select(const struct ni_gpct *counter) } } -static void ni_tio_set_sync_mode(struct ni_gpct *counter, int force_alt_sync) +static void ni_tio_set_sync_mode(struct ni_gpct *counter) { struct ni_gpct_device *counter_dev = counter->counter_dev; unsigned int cidx = counter->counter_index; - unsigned int counting_mode_reg = NITIO_CNT_MODE_REG(cidx); static const u64 min_normal_sync_period_ps = 25000; + unsigned int mask = 0; + unsigned int bits = 0; + unsigned int reg; unsigned int mode; - u64 clock_period_ps; + u64 ps; + bool force_alt_sync; - if (!ni_tio_counting_mode_registers_present(counter_dev)) + /* only m series and 660x variants have counting mode registers */ + switch (counter_dev->variant) { + case ni_gpct_variant_e_series: + default: return; + case ni_gpct_variant_m_series: + mask = GI_M_ALT_SYNC; + break; + case ni_gpct_variant_660x: + mask = GI_660X_ALT_SYNC; + break; + } - mode = ni_tio_get_soft_copy(counter, counting_mode_reg); + reg = NITIO_CNT_MODE_REG(cidx); + mode = ni_tio_get_soft_copy(counter, reg); switch (mode & GI_CNT_MODE_MASK) { case GI_CNT_MODE_QUADX1: case GI_CNT_MODE_QUADX2: case GI_CNT_MODE_QUADX4: case GI_CNT_MODE_SYNC_SRC: - force_alt_sync = 1; + force_alt_sync = true; break; default: + force_alt_sync = false; break; } - clock_period_ps = ni_tio_clock_period_ps(counter, - ni_tio_generic_clock_src_select(counter)); + ps = ni_tio_clock_period_ps(counter, + ni_tio_generic_clock_src_select(counter)); /* * It's not clear what we should do if clock_period is unknown, so we - * are not using the alt sync bit in that case, but allow the caller - * to decide by using the force_alt_sync parameter. + * are not using the alt sync bit in that case. */ - if (force_alt_sync || - (clock_period_ps && clock_period_ps < min_normal_sync_period_ps)) { - ni_tio_set_bits(counter, counting_mode_reg, - GI_ALT_SYNC(counter_dev->variant), - GI_ALT_SYNC(counter_dev->variant)); - } else { - ni_tio_set_bits(counter, counting_mode_reg, - GI_ALT_SYNC(counter_dev->variant), - 0x0); - } + if (force_alt_sync || (ps && ps < min_normal_sync_period_ps)) + bits = mask; + + ni_tio_set_bits(counter, reg, mask, bits); } static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned int mode) @@ -552,7 +547,7 @@ static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned int mode) ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx), GI_CNT_MODE_MASK | GI_INDEX_PHASE_MASK | GI_INDEX_MODE, bits); - ni_tio_set_sync_mode(counter, 0); + ni_tio_set_sync_mode(counter); } ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), GI_CNT_DIR_MASK, @@ -807,7 +802,7 @@ static int ni_tio_set_clock_src(struct ni_gpct *counter, GI_PRESCALE_X8(counter_dev->variant), bits); } counter->clock_period_ps = period_ns * 1000; - ni_tio_set_sync_mode(counter, 0); + ni_tio_set_sync_mode(counter); return 0; } -- cgit v1.2.3 From e3f7bb258b2f73c595ea8f2d26ad2cb137844b8a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 Mar 2016 15:36:55 -0700 Subject: staging: comedi: ni_tio: tidy up ni_tio_arm() Make this function a bit more consise by absorbing the GI_HW_ARM_SEL_MASK() inline helper and combine the two switch (start_trigger) code paths. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tio.c | 78 ++++++++++++++------------------- 1 file changed, 34 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c index 2c33b28bf114..e7209c1ca816 100644 --- a/drivers/staging/comedi/drivers/ni_tio.c +++ b/drivers/staging/comedi/drivers/ni_tio.c @@ -137,19 +137,6 @@ static inline unsigned int GI_PRESCALE_X8(enum ni_gpct_variant variant) } } -static inline unsigned int GI_HW_ARM_SEL_MASK(enum ni_gpct_variant variant) -{ - switch (variant) { - case ni_gpct_variant_e_series: - default: - return 0; - case ni_gpct_variant_m_series: - return GI_M_HW_ARM_SEL_MASK; - case ni_gpct_variant_660x: - return GI_660X_HW_ARM_SEL_MASK; - } -} - static bool ni_tio_has_gate2_registers(const struct ni_gpct_device *counter_dev) { switch (counter_dev->variant) { @@ -568,52 +555,55 @@ int ni_tio_arm(struct ni_gpct *counter, bool arm, unsigned int start_trigger) { struct ni_gpct_device *counter_dev = counter->counter_dev; unsigned int cidx = counter->counter_index; - unsigned int command_transient_bits = 0; + unsigned int transient_bits = 0; if (arm) { + unsigned int mask = 0; + unsigned int bits = 0; + + /* only m series and 660x have counting mode registers */ + switch (counter_dev->variant) { + case ni_gpct_variant_e_series: + default: + break; + case ni_gpct_variant_m_series: + mask = GI_M_HW_ARM_SEL_MASK; + break; + case ni_gpct_variant_660x: + mask = GI_660X_HW_ARM_SEL_MASK; + break; + } + switch (start_trigger) { case NI_GPCT_ARM_IMMEDIATE: - command_transient_bits |= GI_ARM; + transient_bits |= GI_ARM; break; case NI_GPCT_ARM_PAIRED_IMMEDIATE: - command_transient_bits |= GI_ARM | GI_ARM_COPY; + transient_bits |= GI_ARM | GI_ARM_COPY; break; default: + /* + * for m series and 660x, pass-through the least + * significant bits so we can figure out what select + * later + */ + if (mask && (start_trigger & NI_GPCT_ARM_UNKNOWN)) { + bits |= GI_HW_ARM_ENA | + (GI_HW_ARM_SEL(start_trigger) & mask); + } else { + return -EINVAL; + } break; } - if (ni_tio_counting_mode_registers_present(counter_dev)) { - unsigned int bits = 0; - unsigned int sel_mask; - sel_mask = GI_HW_ARM_SEL_MASK(counter_dev->variant); - - switch (start_trigger) { - case NI_GPCT_ARM_IMMEDIATE: - case NI_GPCT_ARM_PAIRED_IMMEDIATE: - break; - default: - if (start_trigger & NI_GPCT_ARM_UNKNOWN) { - /* - * pass-through the least significant - * bits so we can figure out what - * select later - */ - bits |= GI_HW_ARM_ENA | - (GI_HW_ARM_SEL(start_trigger) & - sel_mask); - } else { - return -EINVAL; - } - break; - } + if (mask) ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx), - GI_HW_ARM_ENA | sel_mask, bits); - } + GI_HW_ARM_ENA | mask, bits); } else { - command_transient_bits |= GI_DISARM; + transient_bits |= GI_DISARM; } ni_tio_set_bits_transient(counter, NITIO_CMD_REG(cidx), - 0, 0, command_transient_bits); + 0, 0, transient_bits); return 0; } EXPORT_SYMBOL_GPL(ni_tio_arm); -- cgit v1.2.3 From 9f62bee520b04346c3501a5da7534a96b873c01f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 Mar 2016 15:36:56 -0700 Subject: staging: comedi: ni_tiocmd: Prefer 'unsigned int' to bare use of 'unsigned' Fix the checkpatch.pl issues. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tiocmd.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_tiocmd.c b/drivers/staging/comedi/drivers/ni_tiocmd.c index d5ffbb135844..df4ffdbcd96d 100644 --- a/drivers/staging/comedi/drivers/ni_tiocmd.c +++ b/drivers/staging/comedi/drivers/ni_tiocmd.c @@ -51,9 +51,9 @@ static void ni_tio_configure_dma(struct ni_gpct *counter, bool enable, bool read) { struct ni_gpct_device *counter_dev = counter->counter_dev; - unsigned cidx = counter->counter_index; - unsigned mask; - unsigned bits; + unsigned int cidx = counter->counter_index; + unsigned int mask; + unsigned int bits; mask = GI_READ_ACKS_IRQ | GI_WRITE_ACKS_IRQ; bits = 0; @@ -113,7 +113,7 @@ static int ni_tio_input_cmd(struct comedi_subdevice *s) { struct ni_gpct *counter = s->private; struct ni_gpct_device *counter_dev = counter->counter_dev; - unsigned cidx = counter->counter_index; + unsigned int cidx = counter->counter_index; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; int ret = 0; @@ -163,9 +163,9 @@ static int ni_tio_cmd_setup(struct comedi_subdevice *s) { struct comedi_cmd *cmd = &s->async->cmd; struct ni_gpct *counter = s->private; - unsigned cidx = counter->counter_index; + unsigned int cidx = counter->counter_index; int set_gate_source = 0; - unsigned gate_source; + unsigned int gate_source; int retval = 0; if (cmd->scan_begin_src == TRIG_EXT) { @@ -289,7 +289,7 @@ EXPORT_SYMBOL_GPL(ni_tio_cmdtest); int ni_tio_cancel(struct ni_gpct *counter) { - unsigned cidx = counter->counter_index; + unsigned int cidx = counter->counter_index; unsigned long flags; ni_tio_arm(counter, false, 0); @@ -341,12 +341,12 @@ static void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, int *perm_stale_data, int *stale_data) { - unsigned cidx = counter->counter_index; + unsigned int cidx = counter->counter_index; const unsigned short gxx_status = ni_tio_read(counter, NITIO_SHARED_STATUS_REG(cidx)); const unsigned short gi_status = ni_tio_read(counter, NITIO_STATUS_REG(cidx)); - unsigned ack = 0; + unsigned int ack = 0; if (gate_error) *gate_error = 0; @@ -407,8 +407,8 @@ EXPORT_SYMBOL_GPL(ni_tio_acknowledge); void ni_tio_handle_interrupt(struct ni_gpct *counter, struct comedi_subdevice *s) { - unsigned cidx = counter->counter_index; - unsigned gpct_mite_status; + unsigned int cidx = counter->counter_index; + unsigned int gpct_mite_status; unsigned long flags; int gate_error; int tc_error; -- cgit v1.2.3 From b878a82ee15f77ff1106aa0e5be36a1ee3ec85ea Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 Mar 2016 15:36:57 -0700 Subject: staging: comedi: ni_tiocmd: fix block comments Fix the checkpatch.pl issues: WARNING: Block comments use * on subsequent lines Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tiocmd.c | 60 +++++++++++++++--------------- 1 file changed, 31 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_tiocmd.c b/drivers/staging/comedi/drivers/ni_tiocmd.c index df4ffdbcd96d..1400b1f2305d 100644 --- a/drivers/staging/comedi/drivers/ni_tiocmd.c +++ b/drivers/staging/comedi/drivers/ni_tiocmd.c @@ -1,19 +1,18 @@ /* - comedi/drivers/ni_tiocmd.c - Command support for NI general purpose counters - - Copyright (C) 2006 Frank Mori Hess - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -*/ + * Command support for NI general purpose counters + * + * Copyright (C) 2006 Frank Mori Hess + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ /* * Module: ni_tiocmd @@ -36,13 +35,10 @@ * DAQ 660x Register-Level Programmer Manual (NI 370505A-01) * DAQ 6601/6602 User Manual (NI 322137B-01) * 340934b.pdf DAQ-STC reference manual + * + * TODO: Support use of both banks X and Y */ -/* -TODO: - Support use of both banks X and Y -*/ - #include #include "ni_tio_internal.h" #include "mite.h" @@ -305,9 +301,6 @@ int ni_tio_cancel(struct ni_gpct *counter) } EXPORT_SYMBOL_GPL(ni_tio_cancel); - /* During buffered input counter operation for e-series, the gate - interrupt is acked automatically by the dma controller, due to the - Gi_Read/Write_Acknowledges_IRQ bits in the input select register. */ static int should_ack_gate(struct ni_gpct *counter) { unsigned long flags; @@ -315,12 +308,19 @@ static int should_ack_gate(struct ni_gpct *counter) switch (counter->counter_dev->variant) { case ni_gpct_variant_m_series: - /* not sure if 660x really supports gate - interrupts (the bits are not listed - in register-level manual) */ case ni_gpct_variant_660x: + /* + * not sure if 660x really supports gate interrupts + * (the bits are not listed in register-level manual) + */ return 1; case ni_gpct_variant_e_series: + /* + * During buffered input counter operation for e-series, + * the gate interrupt is acked automatically by the dma + * controller, due to the Gi_Read/Write_Acknowledges_IRQ + * bits in the input select register. + */ spin_lock_irqsave(&counter->lock, flags); { if (!counter->mite_chan || @@ -360,9 +360,11 @@ static void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, if (gxx_status & GI_GATE_ERROR(cidx)) { ack |= GI_GATE_ERROR_CONFIRM(cidx); if (gate_error) { - /*660x don't support automatic acknowledgment - of gate interrupt via dma read/write - and report bogus gate errors */ + /* + * 660x don't support automatic acknowledgment + * of gate interrupt via dma read/write + * and report bogus gate errors + */ if (counter->counter_dev->variant != ni_gpct_variant_660x) *gate_error = 1; -- cgit v1.2.3 From 53d63371293dfc8fdd49f14716c2f2b80aa11373 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 Mar 2016 15:36:58 -0700 Subject: staging: comedi: ni_tiocmd: remove unsed param from ni_tio_acknowledge_and_confirm() The 'stale_data' pointer is always NULL. Just remove it. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tiocmd.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_tiocmd.c b/drivers/staging/comedi/drivers/ni_tiocmd.c index 1400b1f2305d..2d801bf90e52 100644 --- a/drivers/staging/comedi/drivers/ni_tiocmd.c +++ b/drivers/staging/comedi/drivers/ni_tiocmd.c @@ -338,8 +338,7 @@ static int should_ack_gate(struct ni_gpct *counter) static void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, int *gate_error, int *tc_error, - int *perm_stale_data, - int *stale_data) + int *perm_stale_data) { unsigned int cidx = counter->counter_index; const unsigned short gxx_status = ni_tio_read(counter, @@ -354,8 +353,6 @@ static void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, *tc_error = 0; if (perm_stale_data) *perm_stale_data = 0; - if (stale_data) - *stale_data = 0; if (gxx_status & GI_GATE_ERROR(cidx)) { ack |= GI_GATE_ERROR_CONFIRM(cidx); @@ -385,10 +382,6 @@ static void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, ni_tio_write(counter, ack, NITIO_INT_ACK_REG(cidx)); if (ni_tio_get_soft_copy(counter, NITIO_MODE_REG(cidx)) & GI_LOADING_ON_GATE) { - if (gxx_status & GI_STALE_DATA(cidx)) { - if (stale_data) - *stale_data = 1; - } if (ni_tio_read(counter, NITIO_STATUS2_REG(cidx)) & GI_PERMANENT_STALE(cidx)) { dev_info(counter->counter_dev->dev->class_dev, @@ -402,7 +395,7 @@ static void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, void ni_tio_acknowledge(struct ni_gpct *counter) { - ni_tio_acknowledge_and_confirm(counter, NULL, NULL, NULL, NULL); + ni_tio_acknowledge_and_confirm(counter, NULL, NULL, NULL); } EXPORT_SYMBOL_GPL(ni_tio_acknowledge); @@ -417,7 +410,7 @@ void ni_tio_handle_interrupt(struct ni_gpct *counter, int perm_stale_data; ni_tio_acknowledge_and_confirm(counter, &gate_error, &tc_error, - &perm_stale_data, NULL); + &perm_stale_data); if (gate_error) { dev_notice(counter->counter_dev->dev->class_dev, "%s: Gi_Gate_Error detected.\n", __func__); -- cgit v1.2.3 From a19b9b476ae3612e6c61c60e7fad7c8974158ef9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 Mar 2016 15:36:59 -0700 Subject: staging: comedi: ni_tiocmd: remove BUG() which can never occur All the counter_dev->variant options are handled by the switch. Remove the BUG() which can never occur. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tiocmd.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_tiocmd.c b/drivers/staging/comedi/drivers/ni_tiocmd.c index 2d801bf90e52..3c3f5430e552 100644 --- a/drivers/staging/comedi/drivers/ni_tiocmd.c +++ b/drivers/staging/comedi/drivers/ni_tiocmd.c @@ -125,9 +125,6 @@ static int ni_tio_input_cmd(struct comedi_subdevice *s) case ni_gpct_variant_e_series: mite_prep_dma(counter->mite_chan, 16, 32); break; - default: - BUG(); - break; } ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), GI_SAVE_TRACE, 0); ni_tio_configure_dma(counter, true, true); -- cgit v1.2.3 From d87f5e90585a8b8646c3e9fe92d4c47716f5e19d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 Mar 2016 15:37:00 -0700 Subject: staging: comedi: ni_tio: validate clock source Refactor the functions that determine the clock source bits so that they return -EINVAL if the clock source is invalid. Pass the errno back to ni_tio_insn_config(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tio.c | 34 ++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c index e7209c1ca816..564ec9bfd43d 100644 --- a/drivers/staging/comedi/drivers/ni_tio.c +++ b/drivers/staging/comedi/drivers/ni_tio.c @@ -608,7 +608,7 @@ int ni_tio_arm(struct ni_gpct *counter, bool arm, unsigned int start_trigger) } EXPORT_SYMBOL_GPL(ni_tio_arm); -static unsigned int ni_660x_clk_src(unsigned int clock_source) +static int ni_660x_clk_src(unsigned int clock_source, unsigned int *bits) { unsigned int clk_src = clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK; unsigned int ni_660x_clock; @@ -653,14 +653,13 @@ static unsigned int ni_660x_clk_src(unsigned int clock_source) } if (i <= NI_660X_MAX_SRC_PIN) break; - ni_660x_clock = 0; - BUG(); - break; + return -EINVAL; } - return GI_SRC_SEL(ni_660x_clock); + *bits = GI_SRC_SEL(ni_660x_clock); + return 0; } -static unsigned int ni_m_clk_src(unsigned int clock_source) +static int ni_m_clk_src(unsigned int clock_source, unsigned int *bits) { unsigned int clk_src = clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK; unsigned int ni_m_series_clock; @@ -711,13 +710,10 @@ static unsigned int ni_m_clk_src(unsigned int clock_source) } if (i <= NI_M_MAX_PFI_CHAN) break; - pr_err("invalid clock source 0x%lx\n", - (unsigned long)clock_source); - BUG(); - ni_m_series_clock = 0; - break; + return -EINVAL; } - return GI_SRC_SEL(ni_m_series_clock); + *bits = GI_SRC_SEL(ni_m_series_clock); + return 0; }; static void ni_tio_set_source_subselect(struct ni_gpct *counter, @@ -755,18 +751,26 @@ static int ni_tio_set_clock_src(struct ni_gpct *counter, struct ni_gpct_device *counter_dev = counter->counter_dev; unsigned int cidx = counter->counter_index; unsigned int bits = 0; + int ret; - /* FIXME: validate clock source */ switch (counter_dev->variant) { case ni_gpct_variant_660x: - bits |= ni_660x_clk_src(clock_source); + ret = ni_660x_clk_src(clock_source, &bits); break; case ni_gpct_variant_e_series: case ni_gpct_variant_m_series: default: - bits |= ni_m_clk_src(clock_source); + ret = ni_m_clk_src(clock_source, &bits); break; } + if (ret) { + struct comedi_device *dev = counter_dev->dev; + + dev_err(dev->class_dev, "invalid clock source 0x%x\n", + clock_source); + return ret; + } + if (clock_source & NI_GPCT_INVERT_CLOCK_SRC_BIT) bits |= GI_SRC_POL_INVERT; ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx), -- cgit v1.2.3 From 475ea1ed14cce2608ed0f12474be2a3d75880eaf Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 Mar 2016 15:37:01 -0700 Subject: staging: comedi: ni_tio: remove BUG() checks for ni_tio_get_gate_src() This function calls some helper functions to convert the counter variant specific gate select bits into the generic enum ni_gpct_clock_source_bits equivelent. These helper functions currently BUG() if the gate select bits are invalid. This should never happen but refactor the code to return -EINVAL instead and remove the BUG() checks. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tio.c | 146 +++++++++++++++++++++----------- 1 file changed, 97 insertions(+), 49 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c index 564ec9bfd43d..51dd368f788d 100644 --- a/drivers/staging/comedi/drivers/ni_tio.c +++ b/drivers/staging/comedi/drivers/ni_tio.c @@ -1065,114 +1065,157 @@ static int ni_tio_set_other_src(struct ni_gpct *counter, unsigned int index, return 0; } -static unsigned int ni_660x_gate_to_generic_gate(unsigned int gate) +static int ni_660x_gate_to_generic_gate(unsigned int gate, unsigned int *src) { + unsigned int source; unsigned int i; switch (gate) { case NI_660X_SRC_PIN_I_GATE_SEL: - return NI_GPCT_SOURCE_PIN_i_GATE_SELECT; + source = NI_GPCT_SOURCE_PIN_i_GATE_SELECT; + break; case NI_660X_GATE_PIN_I_GATE_SEL: - return NI_GPCT_GATE_PIN_i_GATE_SELECT; + source = NI_GPCT_GATE_PIN_i_GATE_SELECT; + break; case NI_660X_NEXT_SRC_GATE_SEL: - return NI_GPCT_NEXT_SOURCE_GATE_SELECT; + source = NI_GPCT_NEXT_SOURCE_GATE_SELECT; + break; case NI_660X_NEXT_OUT_GATE_SEL: - return NI_GPCT_NEXT_OUT_GATE_SELECT; + source = NI_GPCT_NEXT_OUT_GATE_SELECT; + break; case NI_660X_LOGIC_LOW_GATE_SEL: - return NI_GPCT_LOGIC_LOW_GATE_SELECT; + source = NI_GPCT_LOGIC_LOW_GATE_SELECT; + break; default: for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) { - if (gate == NI_660X_RTSI_GATE_SEL(i)) - return NI_GPCT_RTSI_GATE_SELECT(i); + if (gate == NI_660X_RTSI_GATE_SEL(i)) { + source = NI_GPCT_RTSI_GATE_SELECT(i); + break; + } } + if (i <= NI_660X_MAX_RTSI_CHAN) + break; for (i = 0; i <= NI_660X_MAX_GATE_PIN; ++i) { - if (gate == NI_660X_PIN_GATE_SEL(i)) - return NI_GPCT_GATE_PIN_GATE_SELECT(i); + if (gate == NI_660X_PIN_GATE_SEL(i)) { + source = NI_GPCT_GATE_PIN_GATE_SELECT(i); + break; + } } - BUG(); - break; + if (i <= NI_660X_MAX_GATE_PIN) + break; + return -EINVAL; } + *src = source; return 0; }; -static unsigned int ni_m_gate_to_generic_gate(unsigned int gate) +static int ni_m_gate_to_generic_gate(unsigned int gate, unsigned int *src) { + unsigned int source; unsigned int i; switch (gate) { case NI_M_TIMESTAMP_MUX_GATE_SEL: - return NI_GPCT_TIMESTAMP_MUX_GATE_SELECT; + source = NI_GPCT_TIMESTAMP_MUX_GATE_SELECT; + break; case NI_M_AI_START2_GATE_SEL: - return NI_GPCT_AI_START2_GATE_SELECT; + source = NI_GPCT_AI_START2_GATE_SELECT; + break; case NI_M_PXI_STAR_TRIGGER_GATE_SEL: - return NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT; + source = NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT; + break; case NI_M_NEXT_OUT_GATE_SEL: - return NI_GPCT_NEXT_OUT_GATE_SELECT; + source = NI_GPCT_NEXT_OUT_GATE_SELECT; + break; case NI_M_AI_START1_GATE_SEL: - return NI_GPCT_AI_START1_GATE_SELECT; + source = NI_GPCT_AI_START1_GATE_SELECT; + break; case NI_M_NEXT_SRC_GATE_SEL: - return NI_GPCT_NEXT_SOURCE_GATE_SELECT; + source = NI_GPCT_NEXT_SOURCE_GATE_SELECT; + break; case NI_M_ANALOG_TRIG_OUT_GATE_SEL: - return NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT; + source = NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT; + break; case NI_M_LOGIC_LOW_GATE_SEL: - return NI_GPCT_LOGIC_LOW_GATE_SELECT; + source = NI_GPCT_LOGIC_LOW_GATE_SELECT; + break; default: for (i = 0; i <= NI_M_MAX_RTSI_CHAN; ++i) { - if (gate == NI_M_RTSI_GATE_SEL(i)) - return NI_GPCT_RTSI_GATE_SELECT(i); + if (gate == NI_M_RTSI_GATE_SEL(i)) { + source = NI_GPCT_RTSI_GATE_SELECT(i); + break; + } } + if (i <= NI_M_MAX_RTSI_CHAN) + break; for (i = 0; i <= NI_M_MAX_PFI_CHAN; ++i) { - if (gate == NI_M_PFI_GATE_SEL(i)) - return NI_GPCT_PFI_GATE_SELECT(i); + if (gate == NI_M_PFI_GATE_SEL(i)) { + source = NI_GPCT_PFI_GATE_SELECT(i); + break; + } } - BUG(); - break; + if (i <= NI_M_MAX_PFI_CHAN) + break; + return -EINVAL; } + *src = source; return 0; }; -static unsigned int ni_660x_gate2_to_generic_gate(unsigned int gate) +static int ni_660x_gate2_to_generic_gate(unsigned int gate, unsigned int *src) { + unsigned int source; unsigned int i; switch (gate) { case NI_660X_SRC_PIN_I_GATE2_SEL: - return NI_GPCT_SOURCE_PIN_i_GATE_SELECT; + source = NI_GPCT_SOURCE_PIN_i_GATE_SELECT; + break; case NI_660X_UD_PIN_I_GATE2_SEL: - return NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT; + source = NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT; + break; case NI_660X_NEXT_SRC_GATE2_SEL: - return NI_GPCT_NEXT_SOURCE_GATE_SELECT; + source = NI_GPCT_NEXT_SOURCE_GATE_SELECT; + break; case NI_660X_NEXT_OUT_GATE2_SEL: - return NI_GPCT_NEXT_OUT_GATE_SELECT; + source = NI_GPCT_NEXT_OUT_GATE_SELECT; + break; case NI_660X_SELECTED_GATE2_SEL: - return NI_GPCT_SELECTED_GATE_GATE_SELECT; + source = NI_GPCT_SELECTED_GATE_GATE_SELECT; + break; case NI_660X_LOGIC_LOW_GATE2_SEL: - return NI_GPCT_LOGIC_LOW_GATE_SELECT; + source = NI_GPCT_LOGIC_LOW_GATE_SELECT; + break; default: for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) { - if (gate == NI_660X_RTSI_GATE2_SEL(i)) - return NI_GPCT_RTSI_GATE_SELECT(i); + if (gate == NI_660X_RTSI_GATE2_SEL(i)) { + source = NI_GPCT_RTSI_GATE_SELECT(i); + break; + } } + if (i <= NI_660X_MAX_RTSI_CHAN) + break; for (i = 0; i <= NI_660X_MAX_UP_DOWN_PIN; ++i) { - if (gate == NI_660X_UD_PIN_GATE2_SEL(i)) - return NI_GPCT_UP_DOWN_PIN_GATE_SELECT(i); + if (gate == NI_660X_UD_PIN_GATE2_SEL(i)) { + source = NI_GPCT_UP_DOWN_PIN_GATE_SELECT(i); + break; + } } - BUG(); - break; + if (i <= NI_660X_MAX_UP_DOWN_PIN) + break; + return -EINVAL; } + *src = source; return 0; }; -static unsigned int ni_m_gate2_to_generic_gate(unsigned int gate) +static int ni_m_gate2_to_generic_gate(unsigned int gate, unsigned int *src) { /* * FIXME: the second gate sources for the m series are undocumented, * so we just return the raw bits for now. */ - switch (gate) { - default: - return gate; - } + *src = gate; return 0; }; @@ -1184,6 +1227,7 @@ static int ni_tio_get_gate_src(struct ni_gpct *counter, unsigned int gate_index, unsigned int mode; unsigned int reg; unsigned int gate; + int ret; mode = ni_tio_get_soft_copy(counter, NITIO_MODE_REG(cidx)); if (((mode & GI_GATING_MODE_MASK) == GI_GATING_DISABLED) || @@ -1202,12 +1246,14 @@ static int ni_tio_get_gate_src(struct ni_gpct *counter, unsigned int gate_index, case ni_gpct_variant_e_series: case ni_gpct_variant_m_series: default: - *gate_source = ni_m_gate_to_generic_gate(gate); + ret = ni_m_gate_to_generic_gate(gate, gate_source); break; case ni_gpct_variant_660x: - *gate_source = ni_660x_gate_to_generic_gate(gate); + ret = ni_660x_gate_to_generic_gate(gate, gate_source); break; } + if (ret) + return ret; if (mode & GI_GATE_POL_INVERT) *gate_source |= CR_INVERT; if ((mode & GI_GATING_MODE_MASK) != GI_LEVEL_GATING) @@ -1221,12 +1267,14 @@ static int ni_tio_get_gate_src(struct ni_gpct *counter, unsigned int gate_index, case ni_gpct_variant_e_series: case ni_gpct_variant_m_series: default: - *gate_source = ni_m_gate2_to_generic_gate(gate); + ret = ni_m_gate2_to_generic_gate(gate, gate_source); break; case ni_gpct_variant_660x: - *gate_source = ni_660x_gate2_to_generic_gate(gate); + ret = ni_660x_gate2_to_generic_gate(gate, gate_source); break; } + if (ret) + return ret; if (counter_dev->regs[reg] & GI_GATE2_POL_INVERT) *gate_source |= CR_INVERT; /* second gate can't have edge/level mode set independently */ -- cgit v1.2.3 From 592ef9fb8d7e5deb359b02530c5bb0d0b717cfef Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 Mar 2016 15:37:02 -0700 Subject: staging: comedi: ni_tio: fix ni_tio_insn_config() The (*insn_config) functions are supposed to return an errno or the number of 'data' values used for the instruction (insn->n). Currently this function returns an errno or 0. Fix the function to work like the core expects. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tio.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c index 51dd368f788d..10d4585ab25c 100644 --- a/drivers/staging/comedi/drivers/ni_tio.c +++ b/drivers/staging/comedi/drivers/ni_tio.c @@ -1295,15 +1295,18 @@ int ni_tio_insn_config(struct comedi_device *dev, struct ni_gpct *counter = s->private; unsigned int cidx = counter->counter_index; unsigned int status; + int ret = 0; switch (data[0]) { case INSN_CONFIG_SET_COUNTER_MODE: - return ni_tio_set_counter_mode(counter, data[1]); + ret = ni_tio_set_counter_mode(counter, data[1]); + break; case INSN_CONFIG_ARM: - return ni_tio_arm(counter, true, data[1]); + ret = ni_tio_arm(counter, true, data[1]); + break; case INSN_CONFIG_DISARM: - ni_tio_arm(counter, false, 0); - return 0; + ret = ni_tio_arm(counter, false, 0); + break; case INSN_CONFIG_GET_COUNTER_STATUS: data[1] = 0; status = ni_tio_read(counter, NITIO_SHARED_STATUS_REG(cidx)); @@ -1313,25 +1316,29 @@ int ni_tio_insn_config(struct comedi_device *dev, data[1] |= COMEDI_COUNTER_COUNTING; } data[2] = COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING; - return 0; + break; case INSN_CONFIG_SET_CLOCK_SRC: - return ni_tio_set_clock_src(counter, data[1], data[2]); + ret = ni_tio_set_clock_src(counter, data[1], data[2]); + break; case INSN_CONFIG_GET_CLOCK_SRC: ni_tio_get_clock_src(counter, &data[1], &data[2]); - return 0; + break; case INSN_CONFIG_SET_GATE_SRC: - return ni_tio_set_gate_src(counter, data[1], data[2]); + ret = ni_tio_set_gate_src(counter, data[1], data[2]); + break; case INSN_CONFIG_GET_GATE_SRC: - return ni_tio_get_gate_src(counter, data[1], &data[2]); + ret = ni_tio_get_gate_src(counter, data[1], &data[2]); + break; case INSN_CONFIG_SET_OTHER_SRC: - return ni_tio_set_other_src(counter, data[1], data[2]); + ret = ni_tio_set_other_src(counter, data[1], data[2]); + break; case INSN_CONFIG_RESET: ni_tio_reset_count_and_disarm(counter); - return 0; - default: break; + default: + return -EINVAL; } - return -EINVAL; + return ret ? ret : insn->n; } EXPORT_SYMBOL_GPL(ni_tio_insn_config); -- cgit v1.2.3 From fa74d136fda8512a17918fc5f97a72acd05c22e3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 Mar 2016 15:37:03 -0700 Subject: staging: comedi: ni_tio: remove BUG() in ni_tio_set_gate_src() This BUG() can never happen. The previous ni_tio_has_gate2_registers() check will have already caused the function to return -EINVAL. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tio.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c index 10d4585ab25c..9ce3a9a92a9a 100644 --- a/drivers/staging/comedi/drivers/ni_tio.c +++ b/drivers/staging/comedi/drivers/ni_tio.c @@ -1020,8 +1020,7 @@ int ni_tio_set_gate_src(struct ni_gpct *counter, case ni_gpct_variant_660x: return ni_660x_set_gate2(counter, src); default: - BUG(); - break; + return -EINVAL; } break; default: -- cgit v1.2.3 From b42ca86ad605eb3e3f26618eed35ac6ff7435964 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 Mar 2016 15:37:04 -0700 Subject: staging: comedi: ni_tio: remove BUG() checks for ni_tio_get_clock_src() This function calls some helper functions to convert the counter variant specific clock select bits into the generic enum ni_gpct_clock_source_bits equivelent. These helper functions currently BUG() if the clock select bits are invalid. It then calls ni_tio_clock_period_ps() to figure out the clock period based on the generic clock source. This function could also BUG() if the prescale bits are invalid. In reality this should never happen but refactor the code to return -EINVAL instead and remove the BUG() checks. These functions are also called by ni_tio_set_sync_mode(). When this function is called by ni_tio_set_clock_src() the counter select bits have already been validated. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tio.c | 60 +++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c index 9ce3a9a92a9a..7043eb0543f6 100644 --- a/drivers/staging/comedi/drivers/ni_tio.c +++ b/drivers/staging/comedi/drivers/ni_tio.c @@ -183,8 +183,9 @@ static void ni_tio_reset_count_and_disarm(struct ni_gpct *counter) ni_tio_write(counter, GI_RESET(cidx), NITIO_RESET_REG(cidx)); } -static u64 ni_tio_clock_period_ps(const struct ni_gpct *counter, - unsigned int generic_clock_source) +static int ni_tio_clock_period_ps(const struct ni_gpct *counter, + unsigned int generic_clock_source, + u64 *period_ps) { u64 clock_period_ps; @@ -219,10 +220,10 @@ static u64 ni_tio_clock_period_ps(const struct ni_gpct *counter, clock_period_ps *= 8; break; default: - BUG(); - break; + return -EINVAL; } - return clock_period_ps; + *period_ps = clock_period_ps; + return 0; } static void ni_tio_set_bits_transient(struct ni_gpct *counter, @@ -304,7 +305,8 @@ static unsigned int ni_tio_clock_src_modifiers(const struct ni_gpct *counter) return bits; } -static unsigned int ni_m_series_clock_src_select(const struct ni_gpct *counter) +static int ni_m_series_clock_src_select(const struct ni_gpct *counter, + unsigned int *clk_src) { struct ni_gpct_device *counter_dev = counter->counter_dev; unsigned int cidx = counter->counter_index; @@ -362,14 +364,15 @@ static unsigned int ni_m_series_clock_src_select(const struct ni_gpct *counter) } if (i <= NI_M_MAX_PFI_CHAN) break; - BUG(); - break; + return -EINVAL; } clock_source |= ni_tio_clock_src_modifiers(counter); - return clock_source; + *clk_src = clock_source; + return 0; } -static unsigned int ni_660x_clock_src_select(const struct ni_gpct *counter) +static int ni_660x_clock_src_select(const struct ni_gpct *counter, + unsigned int *clk_src) { unsigned int clock_source = 0; unsigned int cidx = counter->counter_index; @@ -419,23 +422,23 @@ static unsigned int ni_660x_clock_src_select(const struct ni_gpct *counter) } if (i <= NI_660X_MAX_SRC_PIN) break; - BUG(); - break; + return -EINVAL; } clock_source |= ni_tio_clock_src_modifiers(counter); - return clock_source; + *clk_src = clock_source; + return 0; } -static unsigned int -ni_tio_generic_clock_src_select(const struct ni_gpct *counter) +static int ni_tio_generic_clock_src_select(const struct ni_gpct *counter, + unsigned int *clk_src) { switch (counter->counter_dev->variant) { case ni_gpct_variant_e_series: case ni_gpct_variant_m_series: default: - return ni_m_series_clock_src_select(counter); + return ni_m_series_clock_src_select(counter, clk_src); case ni_gpct_variant_660x: - return ni_660x_clock_src_select(counter); + return ni_660x_clock_src_select(counter, clk_src); } } @@ -448,6 +451,7 @@ static void ni_tio_set_sync_mode(struct ni_gpct *counter) unsigned int bits = 0; unsigned int reg; unsigned int mode; + unsigned int clk_src; u64 ps; bool force_alt_sync; @@ -478,8 +482,8 @@ static void ni_tio_set_sync_mode(struct ni_gpct *counter) break; } - ps = ni_tio_clock_period_ps(counter, - ni_tio_generic_clock_src_select(counter)); + ni_tio_generic_clock_src_select(counter, &clk_src); + ni_tio_clock_period_ps(counter, clk_src, &ps); /* * It's not clear what we should do if clock_period is unknown, so we @@ -800,16 +804,22 @@ static int ni_tio_set_clock_src(struct ni_gpct *counter, return 0; } -static void ni_tio_get_clock_src(struct ni_gpct *counter, - unsigned int *clock_source, - unsigned int *period_ns) +static int ni_tio_get_clock_src(struct ni_gpct *counter, + unsigned int *clock_source, + unsigned int *period_ns) { u64 temp64; + int ret; - *clock_source = ni_tio_generic_clock_src_select(counter); - temp64 = ni_tio_clock_period_ps(counter, *clock_source); + ret = ni_tio_generic_clock_src_select(counter, clock_source); + if (ret) + return ret; + ret = ni_tio_clock_period_ps(counter, *clock_source, &temp64); + if (ret) + return ret; do_div(temp64, 1000); /* ps to ns */ *period_ns = temp64; + return 0; } static int ni_660x_set_gate(struct ni_gpct *counter, unsigned int gate_source) @@ -1320,7 +1330,7 @@ int ni_tio_insn_config(struct comedi_device *dev, ret = ni_tio_set_clock_src(counter, data[1], data[2]); break; case INSN_CONFIG_GET_CLOCK_SRC: - ni_tio_get_clock_src(counter, &data[1], &data[2]); + ret = ni_tio_get_clock_src(counter, &data[1], &data[2]); break; case INSN_CONFIG_SET_GATE_SRC: ret = ni_tio_set_gate_src(counter, data[1], data[2]); -- cgit v1.2.3 From ff59f2a6d44e4c96cd56e8b12c5678ef85a3b576 Mon Sep 17 00:00:00 2001 From: Okash Khawaja Date: Thu, 10 Mar 2016 20:21:35 +0000 Subject: staging: speakup: fix type mismatch warnings Compiling speakup driver with sparse produces following warning: drivers/staging/speakup/serialio.c:22:9: warning: incorrect type in initializer (different base types) drivers/staging/speakup/serialio.c:22:9: expected unsigned int [unsigned] flags drivers/staging/speakup/serialio.c:22:9: got restricted upf_t This patch fixes it. Signed-off-by: Okash Khawaja Acked-by: Samuel Thibault Signed-off-by: Greg Kroah-Hartman --- drivers/staging/speakup/serialio.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/speakup/serialio.h b/drivers/staging/speakup/serialio.h index 1b399214ecf7..3ad7ff0bc3c3 100644 --- a/drivers/staging/speakup/serialio.h +++ b/drivers/staging/speakup/serialio.h @@ -6,6 +6,7 @@ #ifndef __sparc__ #include #endif +#include /* * this is cut&paste from 8250.h. Get rid of the structure, the definitions @@ -16,7 +17,7 @@ struct old_serial_port { unsigned int baud_base; unsigned int port; unsigned int irq; - unsigned int flags; /* unused */ + upf_t flags; /* unused */ }; /* countdown values for serial timeouts in us */ -- cgit v1.2.3 From 29efdd3d68fe91f5921e27bce79017e46a5fd57c Mon Sep 17 00:00:00 2001 From: PrasannaKumar Muralidharan Date: Wed, 23 Mar 2016 12:58:28 +0530 Subject: Staging: most: Remove __cplusplus check in header files Remove unnecessary __cplusplus check in header files as it is not required. Signed-off-by: PrasannaKumar Muralidharan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/hdm-dim2/dim2_errors.h | 8 -------- drivers/staging/most/hdm-dim2/dim2_hal.h | 8 -------- drivers/staging/most/hdm-dim2/dim2_reg.h | 8 -------- 3 files changed, 24 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/most/hdm-dim2/dim2_errors.h b/drivers/staging/most/hdm-dim2/dim2_errors.h index 5a713df1d1d4..66343ba426c1 100644 --- a/drivers/staging/most/hdm-dim2/dim2_errors.h +++ b/drivers/staging/most/hdm-dim2/dim2_errors.h @@ -15,10 +15,6 @@ #ifndef _MOST_DIM_ERRORS_H #define _MOST_DIM_ERRORS_H -#ifdef __cplusplus -extern "C" { -#endif - /** * MOST DIM errors. */ @@ -58,8 +54,4 @@ enum dim_errors_t { DIM_ERR_OVERFLOW, }; -#ifdef __cplusplus -} -#endif - #endif /* _MOST_DIM_ERRORS_H */ diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.h b/drivers/staging/most/hdm-dim2/dim2_hal.h index 9f8e88028181..1c924e869de7 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.h +++ b/drivers/staging/most/hdm-dim2/dim2_hal.h @@ -18,10 +18,6 @@ #include #include "dim2_reg.h" -#ifdef __cplusplus -extern "C" { -#endif - /* * The values below are specified in the hardware specification. * So, they should not be changed until the hardware specification changes. @@ -108,8 +104,4 @@ void dimcb_io_write(u32 __iomem *ptr32, u32 value); void dimcb_on_error(u8 error_id, const char *error_message); -#ifdef __cplusplus -} -#endif - #endif /* _DIM2_HAL_H */ diff --git a/drivers/staging/most/hdm-dim2/dim2_reg.h b/drivers/staging/most/hdm-dim2/dim2_reg.h index bcf6a79f6744..e0837b6b9ae1 100644 --- a/drivers/staging/most/hdm-dim2/dim2_reg.h +++ b/drivers/staging/most/hdm-dim2/dim2_reg.h @@ -17,10 +17,6 @@ #include -#ifdef __cplusplus -extern "C" { -#endif - struct dim2_regs { /* 0x00 */ u32 MLBC0; /* 0x01 */ u32 rsvd0[1]; @@ -166,8 +162,4 @@ enum { CAT_CL_MASK = DIM2_MASK(6) }; -#ifdef __cplusplus -} -#endif - #endif /* DIM2_OS62420_H */ -- cgit v1.2.3 From 87787e5ef727ff15f7c552cc48823b469f2eb41b Mon Sep 17 00:00:00 2001 From: Ksenija Stanojevic Date: Wed, 23 Mar 2016 12:06:34 +0100 Subject: Staging: iio: Fix sparse endian warning Fix following sparse warning: warning: cast to restricted __be16 Signed-off-by: Ksenija Stanojevic Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/ad7606_spi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/adc/ad7606_spi.c b/drivers/staging/iio/adc/ad7606_spi.c index d873a5164595..825da0769936 100644 --- a/drivers/staging/iio/adc/ad7606_spi.c +++ b/drivers/staging/iio/adc/ad7606_spi.c @@ -21,7 +21,8 @@ static int ad7606_spi_read_block(struct device *dev, { struct spi_device *spi = to_spi_device(dev); int i, ret; - unsigned short *data = buf; + unsigned short *data; + __be16 *bdata = buf; ret = spi_read(spi, buf, count * 2); if (ret < 0) { @@ -30,7 +31,7 @@ static int ad7606_spi_read_block(struct device *dev, } for (i = 0; i < count; i++) - data[i] = be16_to_cpu(data[i]); + data[i] = be16_to_cpu(bdata[i]); return 0; } -- cgit v1.2.3 From 80e3e241fa56312f7a837b7e4781ecffed0b8db6 Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Wed, 23 Mar 2016 20:54:36 +0900 Subject: staging: dgnc: fix CamelCase in dgnc_driver.c fix checkpatch.pl warning about CamelCase. Signed-off-by: Daeseok Youn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_driver.c | 52 +++++++++++++++++++------------------- drivers/staging/dgnc/dgnc_driver.h | 6 ++--- drivers/staging/dgnc/dgnc_mgmt.c | 28 ++++++++++---------- drivers/staging/dgnc/dgnc_sysfs.c | 2 +- 4 files changed, 44 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index 4eb410e09609..af2e835efa1b 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -48,7 +48,7 @@ static void dgnc_do_remap(struct dgnc_board *brd); /* * File operations permitted on Control/Management major. */ -static const struct file_operations dgnc_BoardFops = { +static const struct file_operations dgnc_board_fops = { .owner = THIS_MODULE, .unlocked_ioctl = dgnc_mgmt_ioctl, .open = dgnc_mgmt_open, @@ -58,11 +58,11 @@ static const struct file_operations dgnc_BoardFops = { /* * Globals */ -uint dgnc_NumBoards; -struct dgnc_board *dgnc_Board[MAXBOARDS]; +uint dgnc_num_boards; +struct dgnc_board *dgnc_board[MAXBOARDS]; DEFINE_SPINLOCK(dgnc_global_lock); DEFINE_SPINLOCK(dgnc_poll_lock); /* Poll scheduling lock */ -uint dgnc_Major; +uint dgnc_major; int dgnc_poll_tick = 20; /* Poll interval - 20 ms */ /* @@ -92,7 +92,7 @@ struct board_id { unsigned int is_pci_express; }; -static struct board_id dgnc_Ids[] = { +static struct board_id dgnc_ids[] = { { PCI_DEVICE_CLASSIC_4_PCI_NAME, 4, 0 }, { PCI_DEVICE_CLASSIC_4_422_PCI_NAME, 4, 0 }, { PCI_DEVICE_CLASSIC_8_PCI_NAME, 8, 0 }, @@ -140,14 +140,14 @@ static void cleanup(bool sysfiles) if (sysfiles) dgnc_remove_driver_sysfiles(&dgnc_driver); - device_destroy(dgnc_class, MKDEV(dgnc_Major, 0)); + device_destroy(dgnc_class, MKDEV(dgnc_major, 0)); class_destroy(dgnc_class); - unregister_chrdev(dgnc_Major, "dgnc"); + unregister_chrdev(dgnc_major, "dgnc"); - for (i = 0; i < dgnc_NumBoards; ++i) { - dgnc_remove_ports_sysfiles(dgnc_Board[i]); - dgnc_tty_uninit(dgnc_Board[i]); - dgnc_cleanup_board(dgnc_Board[i]); + for (i = 0; i < dgnc_num_boards; ++i) { + dgnc_remove_ports_sysfiles(dgnc_board[i]); + dgnc_tty_uninit(dgnc_board[i]); + dgnc_cleanup_board(dgnc_board[i]); } dgnc_tty_post_uninit(); @@ -217,12 +217,12 @@ static int dgnc_start(void) * * Register management/dpa devices */ - rc = register_chrdev(0, "dgnc", &dgnc_BoardFops); + rc = register_chrdev(0, "dgnc", &dgnc_board_fops); if (rc < 0) { pr_err(DRVSTR ": Can't register dgnc driver device (%d)\n", rc); return rc; } - dgnc_Major = rc; + dgnc_major = rc; dgnc_class = class_create(THIS_MODULE, "dgnc_mgmt"); if (IS_ERR(dgnc_class)) { @@ -232,7 +232,7 @@ static int dgnc_start(void) } dev = device_create(dgnc_class, NULL, - MKDEV(dgnc_Major, 0), + MKDEV(dgnc_major, 0), NULL, "dgnc_mgmt"); if (IS_ERR(dev)) { rc = PTR_ERR(dev); @@ -262,11 +262,11 @@ static int dgnc_start(void) return 0; failed_tty: - device_destroy(dgnc_class, MKDEV(dgnc_Major, 0)); + device_destroy(dgnc_class, MKDEV(dgnc_major, 0)); failed_device: class_destroy(dgnc_class); failed_class: - unregister_chrdev(dgnc_Major, "dgnc"); + unregister_chrdev(dgnc_major, "dgnc"); return rc; } @@ -283,7 +283,7 @@ static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) rc = dgnc_found_board(pdev, ent->driver_data); if (rc == 0) - dgnc_NumBoards++; + dgnc_num_boards++; return rc; } @@ -346,7 +346,7 @@ static void dgnc_cleanup_board(struct dgnc_board *brd) } } - dgnc_Board[brd->boardnum] = NULL; + dgnc_board[brd->boardnum] = NULL; kfree(brd); } @@ -365,8 +365,8 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) unsigned long flags; /* get the board structure and prep it */ - dgnc_Board[dgnc_NumBoards] = kzalloc(sizeof(*brd), GFP_KERNEL); - brd = dgnc_Board[dgnc_NumBoards]; + dgnc_board[dgnc_num_boards] = kzalloc(sizeof(*brd), GFP_KERNEL); + brd = dgnc_board[dgnc_num_boards]; if (!brd) return -ENOMEM; @@ -382,15 +382,15 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) /* store the info for the board we've found */ brd->magic = DGNC_BOARD_MAGIC; - brd->boardnum = dgnc_NumBoards; + brd->boardnum = dgnc_num_boards; brd->vendor = dgnc_pci_tbl[id].vendor; brd->device = dgnc_pci_tbl[id].device; brd->pdev = pdev; brd->pci_bus = pdev->bus->number; brd->pci_slot = PCI_SLOT(pdev->devfn); - brd->name = dgnc_Ids[id].name; - brd->maxports = dgnc_Ids[id].maxports; - if (dgnc_Ids[i].is_pci_express) + brd->name = dgnc_ids[id].name; + brd->maxports = dgnc_ids[id].maxports; + if (dgnc_ids[i].is_pci_express) brd->bd_flags |= BD_IS_PCI_EXPRESS; brd->dpastatus = BD_NOFEP; init_waitqueue_head(&brd->state_wait); @@ -642,8 +642,8 @@ static void dgnc_poll_handler(ulong dummy) unsigned long new_time; /* Go thru each board, kicking off a tasklet for each if needed */ - for (i = 0; i < dgnc_NumBoards; i++) { - brd = dgnc_Board[i]; + for (i = 0; i < dgnc_num_boards; i++) { + brd = dgnc_board[i]; spin_lock_irqsave(&brd->bd_lock, flags); diff --git a/drivers/staging/dgnc/dgnc_driver.h b/drivers/staging/dgnc/dgnc_driver.h index 953c891d4064..f3d00dfd2326 100644 --- a/drivers/staging/dgnc/dgnc_driver.h +++ b/drivers/staging/dgnc/dgnc_driver.h @@ -399,12 +399,12 @@ struct channel_t { /* * Our Global Variables. */ -extern uint dgnc_Major; /* Our driver/mgmt major */ +extern uint dgnc_major; /* Our driver/mgmt major */ extern int dgnc_poll_tick; /* Poll interval - 20 ms */ extern spinlock_t dgnc_global_lock; /* Driver global spinlock */ extern spinlock_t dgnc_poll_lock; /* Poll scheduling lock */ -extern uint dgnc_NumBoards; /* Total number of boards */ -extern struct dgnc_board *dgnc_Board[MAXBOARDS]; /* Array of board +extern uint dgnc_num_boards; /* Total number of boards */ +extern struct dgnc_board *dgnc_board[MAXBOARDS]; /* Array of board * structs */ diff --git a/drivers/staging/dgnc/dgnc_mgmt.c b/drivers/staging/dgnc/dgnc_mgmt.c index ba29a8d913f2..683c098391d9 100644 --- a/drivers/staging/dgnc/dgnc_mgmt.c +++ b/drivers/staging/dgnc/dgnc_mgmt.c @@ -111,7 +111,7 @@ long dgnc_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) spin_lock_irqsave(&dgnc_global_lock, flags); memset(&ddi, 0, sizeof(ddi)); - ddi.dinfo_nboards = dgnc_NumBoards; + ddi.dinfo_nboards = dgnc_num_boards; sprintf(ddi.dinfo_version, "%s", DG_PART); spin_unlock_irqrestore(&dgnc_global_lock, flags); @@ -131,27 +131,27 @@ long dgnc_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (copy_from_user(&brd, uarg, sizeof(int))) return -EFAULT; - if (brd < 0 || brd >= dgnc_NumBoards) + if (brd < 0 || brd >= dgnc_num_boards) return -ENODEV; memset(&di, 0, sizeof(di)); di.info_bdnum = brd; - spin_lock_irqsave(&dgnc_Board[brd]->bd_lock, flags); + spin_lock_irqsave(&dgnc_board[brd]->bd_lock, flags); - di.info_bdtype = dgnc_Board[brd]->dpatype; - di.info_bdstate = dgnc_Board[brd]->dpastatus; + di.info_bdtype = dgnc_board[brd]->dpatype; + di.info_bdstate = dgnc_board[brd]->dpastatus; di.info_ioport = 0; - di.info_physaddr = (ulong)dgnc_Board[brd]->membase; - di.info_physsize = (ulong)dgnc_Board[brd]->membase - - dgnc_Board[brd]->membase_end; - if (dgnc_Board[brd]->state != BOARD_FAILED) - di.info_nports = dgnc_Board[brd]->nasync; + di.info_physaddr = (ulong)dgnc_board[brd]->membase; + di.info_physsize = (ulong)dgnc_board[brd]->membase + - dgnc_board[brd]->membase_end; + if (dgnc_board[brd]->state != BOARD_FAILED) + di.info_nports = dgnc_board[brd]->nasync; else di.info_nports = 0; - spin_unlock_irqrestore(&dgnc_Board[brd]->bd_lock, flags); + spin_unlock_irqrestore(&dgnc_board[brd]->bd_lock, flags); if (copy_to_user(uarg, &di, sizeof(di))) return -EFAULT; @@ -174,14 +174,14 @@ long dgnc_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) channel = ni.channel; /* Verify boundaries on board */ - if (board >= dgnc_NumBoards) + if (board >= dgnc_num_boards) return -ENODEV; /* Verify boundaries on channel */ - if (channel >= dgnc_Board[board]->nasync) + if (channel >= dgnc_board[board]->nasync) return -ENODEV; - ch = dgnc_Board[board]->channels[channel]; + ch = dgnc_board[board]->channels[channel]; if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) return -ENODEV; diff --git a/drivers/staging/dgnc/dgnc_sysfs.c b/drivers/staging/dgnc/dgnc_sysfs.c index 74a072599126..d825964180bc 100644 --- a/drivers/staging/dgnc/dgnc_sysfs.c +++ b/drivers/staging/dgnc/dgnc_sysfs.c @@ -33,7 +33,7 @@ static DRIVER_ATTR(version, S_IRUSR, dgnc_driver_version_show, NULL); static ssize_t dgnc_driver_boards_show(struct device_driver *ddp, char *buf) { - return snprintf(buf, PAGE_SIZE, "%d\n", dgnc_NumBoards); + return snprintf(buf, PAGE_SIZE, "%d\n", dgnc_num_boards); } static DRIVER_ATTR(boards, S_IRUSR, dgnc_driver_boards_show, NULL); -- cgit v1.2.3 From f96b36c779f92328bb1c802e6268609191d4449d Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Wed, 23 Mar 2016 20:37:26 +0200 Subject: Staging: wlan-ng: wiphy_free() is not called in case wiphy_register() fails This patch covers wiphy_register() failures in wlan_create_wiphy() from cfg80211.c by calling wiphy_free() for the correspondent struct wiphy allocated structure. Signed-off-by: Claudiu Beznea Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/cfg80211.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c index 8bad018eda47..ee989d1d5715 100644 --- a/drivers/staging/wlan-ng/cfg80211.c +++ b/drivers/staging/wlan-ng/cfg80211.c @@ -771,8 +771,10 @@ static struct wiphy *wlan_create_wiphy(struct device *dev, wlandevice_t *wlandev wiphy->n_cipher_suites = PRISM2_NUM_CIPHER_SUITES; wiphy->cipher_suites = prism2_cipher_suites; - if (wiphy_register(wiphy) < 0) + if (wiphy_register(wiphy) < 0) { + wiphy_free(wiphy); return NULL; + } return wiphy; } -- cgit v1.2.3 From f72ea988418f3b86d4815f427105c4222622dd41 Mon Sep 17 00:00:00 2001 From: Parth Sane Date: Thu, 24 Mar 2016 01:08:29 +0530 Subject: staging: vt6656: Fixed multiple logical comparisions warnings in main_usb.c Using comparison to false and true is error prone. Fixed multiple warnings as per checkpatch guidelines. Signed-off-by: Parth Sane Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/main_usb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index f9afab77b79f..5e774962e547 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -238,7 +238,7 @@ static int vnt_init_registers(struct vnt_private *priv) priv->tx_antenna_mode = ANT_B; priv->rx_antenna_sel = 1; - if (priv->tx_rx_ant_inv == true) + if (priv->tx_rx_ant_inv) priv->rx_antenna_mode = ANT_A; else priv->rx_antenna_mode = ANT_B; @@ -248,14 +248,14 @@ static int vnt_init_registers(struct vnt_private *priv) if (antenna & EEP_ANTENNA_AUX) { priv->tx_antenna_mode = ANT_A; - if (priv->tx_rx_ant_inv == true) + if (priv->tx_rx_ant_inv) priv->rx_antenna_mode = ANT_B; else priv->rx_antenna_mode = ANT_A; } else { priv->tx_antenna_mode = ANT_B; - if (priv->tx_rx_ant_inv == true) + if (priv->tx_rx_ant_inv) priv->rx_antenna_mode = ANT_A; else priv->rx_antenna_mode = ANT_B; -- cgit v1.2.3 From e7c77e437b7cbb632a3708ea3a3bb270f4fc4677 Mon Sep 17 00:00:00 2001 From: Nicholas Sim Date: Wed, 23 Mar 2016 22:35:39 +0000 Subject: staging: rtl8188eu: remove return at end of void function call Remove unnecessary return statements from last lines of void function call (several) Signed-off-by: Nicholas Sim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_mlme_ext.c | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c index 439c035fbb7b..7f32b39e5869 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c @@ -601,8 +601,6 @@ static void issue_probersp(struct adapter *padapter, unsigned char *da) pattrib->last_txcmdsz = pattrib->pktlen; dump_mgntframe(padapter, pmgntframe); - - return; } static int issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da, bool wait_ack) @@ -883,8 +881,6 @@ static void issue_auth(struct adapter *padapter, struct sta_info *psta, rtw_wep_encrypt(padapter, (u8 *)pmgntframe); DBG_88E("%s\n", __func__); dump_mgntframe(padapter, pmgntframe); - - return; } @@ -1207,8 +1203,6 @@ exit: rtw_buf_update(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len, (u8 *)pwlanhdr, pattrib->pktlen); else rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len); - - return; } /* when wait_ack is true, this function should be called at process context */ @@ -4326,8 +4320,6 @@ void report_survey_event(struct adapter *padapter, rtw_enqueue_cmd(pcmdpriv, pcmd_obj); pmlmeext->sitesurvey_res.bss_cnt++; - - return; } void report_surveydone_event(struct adapter *padapter) @@ -4371,8 +4363,6 @@ void report_surveydone_event(struct adapter *padapter) DBG_88E("survey done event(%x)\n", psurveydone_evt->bss_cnt); rtw_enqueue_cmd(pcmdpriv, pcmd_obj); - - return; } void report_join_res(struct adapter *padapter, int res) @@ -4423,8 +4413,6 @@ void report_join_res(struct adapter *padapter, int res) rtw_enqueue_cmd(pcmdpriv, pcmd_obj); - - return; } void report_del_sta_event(struct adapter *padapter, unsigned char *MacAddr, unsigned short reason) @@ -4480,8 +4468,6 @@ void report_del_sta_event(struct adapter *padapter, unsigned char *MacAddr, unsi DBG_88E("report_del_sta_event: delete STA, mac_id =%d\n", mac_id); rtw_enqueue_cmd(pcmdpriv, pcmd_obj); - - return; } void report_add_sta_event(struct adapter *padapter, unsigned char *MacAddr, int cam_idx) @@ -4526,8 +4512,6 @@ void report_add_sta_event(struct adapter *padapter, unsigned char *MacAddr, int DBG_88E("report_add_sta_event: add STA\n"); rtw_enqueue_cmd(pcmdpriv, pcmd_obj); - - return; } @@ -4963,7 +4947,6 @@ void link_timer_hdl(unsigned long data) issue_assocreq(padapter); set_link_timer(pmlmeext, REASSOC_TO); } - return; } void addba_timer_hdl(unsigned long data) -- cgit v1.2.3 From 26b694323637be61be89d391c1713d85d66b457d Mon Sep 17 00:00:00 2001 From: Nicholas Sim Date: Wed, 23 Mar 2016 23:02:24 +0000 Subject: staging: xgifb: ensure braces on all arms of if stmt Added braces on else arm of if statement where if arm already has braces as suggested for clarity in Documentation/CodingStyle Signed-off-by: Nicholas Sim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_setmode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index f97c77d88173..14230c293145 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -3450,8 +3450,9 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, if (!(pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p))) tempbx >>= 1; - } else + } else { tempbx >>= 1; + } } tempbx -= 2; -- cgit v1.2.3 From aaeb5e7f03e97770fe7a0dc122854287ab020f19 Mon Sep 17 00:00:00 2001 From: Nicholas Sim Date: Wed, 23 Mar 2016 23:02:59 +0000 Subject: staging: xgifb: remove extra braces from if stmt (single branch) Remove braces from one branch of if statement where both branches only have a single line of code, as suggested in Documentation/CodingStyle Signed-off-by: Nicholas Sim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_setmode.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 14230c293145..40939c86ab7c 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -3840,9 +3840,9 @@ static void XGI_SetLCDRegs(unsigned short ModeIdIndex, if (pVBInfo->VGAVDE == 525) { if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV | VB_SIS302LV - | VB_XGI301C)) { + | VB_XGI301C)) temp = 0xC6; - } else + else temp = 0xC4; xgifb_reg_set(pVBInfo->Part2Port, 0x2f, temp); @@ -3852,9 +3852,9 @@ static void XGI_SetLCDRegs(unsigned short ModeIdIndex, if (pVBInfo->VGAVDE == 420) { if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV | VB_SIS302LV - | VB_XGI301C)) { + | VB_XGI301C)) temp = 0x4F; - } else + else temp = 0x4E; xgifb_reg_set(pVBInfo->Part2Port, 0x2f, temp); } -- cgit v1.2.3 From a25ad52020b5cde0121830733890c06d3cc2e656 Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Thu, 24 Mar 2016 15:10:43 +0900 Subject: staging: dgnc: fix CamelCase in dgnc_drvier.h and fix checkpatch.pl warning about CamelCase Signed-off-by: Daeseok Youn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_driver.h | 12 ++++++------ drivers/staging/dgnc/dgnc_tty.c | 32 ++++++++++++++++---------------- 2 files changed, 22 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dgnc/dgnc_driver.h b/drivers/staging/dgnc/dgnc_driver.h index f3d00dfd2326..3d8e15f9a606 100644 --- a/drivers/staging/dgnc/dgnc_driver.h +++ b/drivers/staging/dgnc/dgnc_driver.h @@ -203,15 +203,15 @@ struct dgnc_board { */ struct tty_driver serial_driver; - char SerialName[200]; + char serial_name[200]; struct tty_driver print_driver; - char PrintName[200]; + char print_name[200]; - bool dgnc_Major_Serial_Registered; - bool dgnc_Major_TransparentPrint_Registered; + bool dgnc_major_serial_registered; + bool dgnc_major_transparent_print_registered; - uint dgnc_Serial_Major; - uint dgnc_TransparentPrint_Major; + uint dgnc_serial_major; + uint dgnc_transparent_print_major; uint TtyRefCnt; diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index 081ac75abc88..98b88d1a5f04 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -180,9 +180,9 @@ int dgnc_tty_register(struct dgnc_board *brd) brd->serial_driver.magic = TTY_DRIVER_MAGIC; - snprintf(brd->SerialName, MAXTTYNAMELEN, "tty_dgnc_%d_", brd->boardnum); + snprintf(brd->serial_name, MAXTTYNAMELEN, "tty_dgnc_%d_", brd->boardnum); - brd->serial_driver.name = brd->SerialName; + brd->serial_driver.name = brd->serial_name; brd->serial_driver.name_base = 0; brd->serial_driver.major = 0; brd->serial_driver.minor_start = 0; @@ -218,7 +218,7 @@ int dgnc_tty_register(struct dgnc_board *brd) */ tty_set_operations(&brd->serial_driver, &dgnc_tty_ops); - if (!brd->dgnc_Major_Serial_Registered) { + if (!brd->dgnc_major_serial_registered) { /* Register tty devices */ rc = tty_register_driver(&brd->serial_driver); if (rc < 0) { @@ -226,7 +226,7 @@ int dgnc_tty_register(struct dgnc_board *brd) "Can't register tty device (%d)\n", rc); return rc; } - brd->dgnc_Major_Serial_Registered = true; + brd->dgnc_major_serial_registered = true; } /* @@ -235,9 +235,9 @@ int dgnc_tty_register(struct dgnc_board *brd) * we are when we get into the dgnc_tty_open() routine. */ brd->print_driver.magic = TTY_DRIVER_MAGIC; - snprintf(brd->PrintName, MAXTTYNAMELEN, "pr_dgnc_%d_", brd->boardnum); + snprintf(brd->print_name, MAXTTYNAMELEN, "pr_dgnc_%d_", brd->boardnum); - brd->print_driver.name = brd->PrintName; + brd->print_driver.name = brd->print_name; brd->print_driver.name_base = 0; brd->print_driver.major = brd->serial_driver.major; brd->print_driver.minor_start = 0x80; @@ -273,7 +273,7 @@ int dgnc_tty_register(struct dgnc_board *brd) */ tty_set_operations(&brd->print_driver, &dgnc_tty_ops); - if (!brd->dgnc_Major_TransparentPrint_Registered) { + if (!brd->dgnc_major_transparent_print_registered) { /* Register Transparent Print devices */ rc = tty_register_driver(&brd->print_driver); if (rc < 0) { @@ -282,12 +282,12 @@ int dgnc_tty_register(struct dgnc_board *brd) rc); return rc; } - brd->dgnc_Major_TransparentPrint_Registered = true; + brd->dgnc_major_transparent_print_registered = true; } dgnc_BoardsByMajor[brd->serial_driver.major] = brd; - brd->dgnc_Serial_Major = brd->serial_driver.major; - brd->dgnc_TransparentPrint_Major = brd->print_driver.major; + brd->dgnc_serial_major = brd->serial_driver.major; + brd->dgnc_transparent_print_major = brd->print_driver.major; return rc; } @@ -407,9 +407,9 @@ void dgnc_tty_uninit(struct dgnc_board *brd) { int i = 0; - if (brd->dgnc_Major_Serial_Registered) { + if (brd->dgnc_major_serial_registered) { dgnc_BoardsByMajor[brd->serial_driver.major] = NULL; - brd->dgnc_Serial_Major = 0; + brd->dgnc_serial_major = 0; for (i = 0; i < brd->nasync; i++) { if (brd->channels[i]) dgnc_remove_tty_sysfs(brd->channels[i]-> @@ -417,12 +417,12 @@ void dgnc_tty_uninit(struct dgnc_board *brd) tty_unregister_device(&brd->serial_driver, i); } tty_unregister_driver(&brd->serial_driver); - brd->dgnc_Major_Serial_Registered = false; + brd->dgnc_major_serial_registered = false; } - if (brd->dgnc_Major_TransparentPrint_Registered) { + if (brd->dgnc_major_transparent_print_registered) { dgnc_BoardsByMajor[brd->print_driver.major] = NULL; - brd->dgnc_TransparentPrint_Major = 0; + brd->dgnc_transparent_print_major = 0; for (i = 0; i < brd->nasync; i++) { if (brd->channels[i]) dgnc_remove_tty_sysfs(brd->channels[i]-> @@ -430,7 +430,7 @@ void dgnc_tty_uninit(struct dgnc_board *brd) tty_unregister_device(&brd->print_driver, i); } tty_unregister_driver(&brd->print_driver); - brd->dgnc_Major_TransparentPrint_Registered = false; + brd->dgnc_major_transparent_print_registered = false; } kfree(brd->serial_driver.ttys); -- cgit v1.2.3 From 195d85c1a0b37c2dd231980528d46100f35f9a0c Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Thu, 24 Mar 2016 15:11:08 +0900 Subject: staging: dgnc: remove unused variable in dgnc_board TtyRefCnt was not used anywhere in dgnc. Signed-off-by: Daeseok Youn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_driver.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dgnc/dgnc_driver.h b/drivers/staging/dgnc/dgnc_driver.h index 3d8e15f9a606..44216aede109 100644 --- a/drivers/staging/dgnc/dgnc_driver.h +++ b/drivers/staging/dgnc/dgnc_driver.h @@ -213,8 +213,6 @@ struct dgnc_board { uint dgnc_serial_major; uint dgnc_transparent_print_major; - uint TtyRefCnt; - u16 dpatype; /* The board "type", * as defined by DPA */ -- cgit v1.2.3 From 6175e73deeba06365eae1758d964a4e37d8db627 Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Fri, 25 Mar 2016 11:44:06 +0900 Subject: staging: dgnc: fix 'line over 80 characters' fix checkpatch.pl warning about 'line over 80 characters' in dgnc_neo.c Signed-off-by: Daeseok Youn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_neo.c | 66 +++++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dgnc/dgnc_neo.c b/drivers/staging/dgnc/dgnc_neo.c index 31ac437cb4a4..10b596fb4681 100644 --- a/drivers/staging/dgnc/dgnc_neo.c +++ b/drivers/staging/dgnc/dgnc_neo.c @@ -77,7 +77,8 @@ struct board_ops dgnc_neo_ops = { .send_immediate_char = neo_send_immediate_char }; -static uint dgnc_offset_table[8] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; +static uint dgnc_offset_table[8] = { 0x01, 0x02, 0x04, 0x08, + 0x10, 0x20, 0x40, 0x80 }; /* * This function allows calls to ensure that all outstanding @@ -116,7 +117,8 @@ static inline void neo_set_cts_flow_control(struct channel_t *ch) writeb(efr, &ch->ch_neo_uart->efr); /* Turn on table D, with 8 char hi/low watermarks */ - writeb((UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_4DELAY), &ch->ch_neo_uart->fctr); + writeb((UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_4DELAY), + &ch->ch_neo_uart->fctr); /* Feed the UART our trigger levels */ writeb(8, &ch->ch_neo_uart->tfifo); @@ -150,7 +152,8 @@ static inline void neo_set_rts_flow_control(struct channel_t *ch) /* Turn on UART enhanced bits */ writeb(efr, &ch->ch_neo_uart->efr); - writeb((UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_4DELAY), &ch->ch_neo_uart->fctr); + writeb((UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_4DELAY), + &ch->ch_neo_uart->fctr); ch->ch_r_watermark = 4; writeb(32, &ch->ch_neo_uart->rfifo); @@ -187,7 +190,8 @@ static inline void neo_set_ixon_flow_control(struct channel_t *ch) /* Turn on UART enhanced bits */ writeb(efr, &ch->ch_neo_uart->efr); - writeb((UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_8DELAY), &ch->ch_neo_uart->fctr); + writeb((UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_8DELAY), + &ch->ch_neo_uart->fctr); ch->ch_r_watermark = 4; writeb(32, &ch->ch_neo_uart->rfifo); @@ -225,7 +229,8 @@ static inline void neo_set_ixoff_flow_control(struct channel_t *ch) writeb(efr, &ch->ch_neo_uart->efr); /* Turn on table D, with 8 char hi/low watermarks */ - writeb((UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_8DELAY), &ch->ch_neo_uart->fctr); + writeb((UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_8DELAY), + &ch->ch_neo_uart->fctr); writeb(8, &ch->ch_neo_uart->tfifo); ch->ch_t_tlevel = 8; @@ -265,7 +270,8 @@ static inline void neo_set_no_input_flow_control(struct channel_t *ch) writeb(efr, &ch->ch_neo_uart->efr); /* Turn on table D, with 8 char hi/low watermarks */ - writeb((UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_8DELAY), &ch->ch_neo_uart->fctr); + writeb((UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_8DELAY), + &ch->ch_neo_uart->fctr); ch->ch_r_watermark = 0; @@ -302,7 +308,8 @@ static inline void neo_set_no_output_flow_control(struct channel_t *ch) writeb(efr, &ch->ch_neo_uart->efr); /* Turn on table D, with 8 char hi/low watermarks */ - writeb((UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_8DELAY), &ch->ch_neo_uart->fctr); + writeb((UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_8DELAY), + &ch->ch_neo_uart->fctr); ch->ch_r_watermark = 0; @@ -321,7 +328,8 @@ static inline void neo_set_no_output_flow_control(struct channel_t *ch) static inline void neo_set_new_start_stop_chars(struct channel_t *ch) { /* if hardware flow control is set, then skip this whole thing */ - if (ch->ch_digi.digi_flags & (CTSPACE | RTSPACE) || ch->ch_c_cflag & CRTSCTS) + if (ch->ch_digi.digi_flags & (CTSPACE | RTSPACE) || + ch->ch_c_cflag & CRTSCTS) return; /* Tell UART what start/stop chars it should be looking for */ @@ -393,7 +401,8 @@ static inline void neo_parse_isr(struct dgnc_board *brd, uint port) break; /* - * Yank off the upper 2 bits, which just show that the FIFO's are enabled. + * Yank off the upper 2 bits, + * which just show that the FIFO's are enabled. */ isr &= ~(UART_17158_IIR_FIFO_ENABLED); @@ -666,7 +675,8 @@ static void neo_param(struct tty_struct *tty) }; /* Only use the TXPrint baud rate if the terminal unit is NOT open */ - if (!(ch->ch_tun.un_flags & UN_ISOPEN) && (un->un_type == DGNC_PRINT)) + if (!(ch->ch_tun.un_flags & UN_ISOPEN) && + (un->un_type == DGNC_PRINT)) baud = C_BAUD(ch->ch_pun.un_tty) & 0xff; else baud = C_BAUD(ch->ch_tun.un_tty) & 0xff; @@ -679,7 +689,8 @@ static void neo_param(struct tty_struct *tty) jindex = baud; - if ((iindex >= 0) && (iindex < 4) && (jindex >= 0) && (jindex < 16)) + if ((iindex >= 0) && (iindex < 4) && + (jindex >= 0) && (jindex < 16)) baud = bauds[iindex][jindex]; else baud = 0; @@ -787,7 +798,8 @@ static void neo_param(struct tty_struct *tty) neo_set_cts_flow_control(ch); } else if (ch->ch_c_iflag & IXON) { /* If start/stop is set to disable, then we should disable flow control */ - if ((ch->ch_startc == _POSIX_VDISABLE) || (ch->ch_stopc == _POSIX_VDISABLE)) + if ((ch->ch_startc == _POSIX_VDISABLE) || + (ch->ch_stopc == _POSIX_VDISABLE)) neo_set_no_output_flow_control(ch); else neo_set_ixon_flow_control(ch); @@ -799,7 +811,8 @@ static void neo_param(struct tty_struct *tty) neo_set_rts_flow_control(ch); } else if (ch->ch_c_iflag & IXOFF) { /* If start/stop is set to disable, then we should disable flow control */ - if ((ch->ch_startc == _POSIX_VDISABLE) || (ch->ch_stopc == _POSIX_VDISABLE)) + if ((ch->ch_startc == _POSIX_VDISABLE) || + (ch->ch_stopc == _POSIX_VDISABLE)) neo_set_no_input_flow_control(ch); else neo_set_ixoff_flow_control(ch); @@ -1172,7 +1185,8 @@ static void neo_copy_data_from_uart_to_queue(struct channel_t *ch) linestatus = 0; /* Copy data from uart to the queue */ - memcpy_fromio(ch->ch_rqueue + head, &ch->ch_neo_uart->txrxburst, n); + memcpy_fromio(ch->ch_rqueue + head, + &ch->ch_neo_uart->txrxburst, n); /* * Since RX_FIFO_DATA_ERROR was 0, we are guaranteed @@ -1225,7 +1239,8 @@ static void neo_copy_data_from_uart_to_queue(struct channel_t *ch) * we don't miss our TX FIFO emptys. */ if (linestatus & (UART_LSR_THRE | UART_17158_TX_AND_FIFO_CLR)) { - linestatus &= ~(UART_LSR_THRE | UART_17158_TX_AND_FIFO_CLR); + linestatus &= ~(UART_LSR_THRE | + UART_17158_TX_AND_FIFO_CLR); ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); } @@ -1255,7 +1270,8 @@ static void neo_copy_data_from_uart_to_queue(struct channel_t *ch) qleft++; } - memcpy_fromio(ch->ch_rqueue + head, &ch->ch_neo_uart->txrxburst, 1); + memcpy_fromio(ch->ch_rqueue + head, + &ch->ch_neo_uart->txrxburst, 1); ch->ch_equeue[head] = (unsigned char)linestatus; /* Ditch any remaining linestatus value. */ @@ -1328,7 +1344,8 @@ static void neo_flush_uart_write(struct channel_t *ch) if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) return; - writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_XMIT), &ch->ch_neo_uart->isr_fcr); + writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_XMIT), + &ch->ch_neo_uart->isr_fcr); neo_pci_posting_flush(ch->ch_bd); for (i = 0; i < 10; i++) { @@ -1356,7 +1373,8 @@ static void neo_flush_uart_read(struct channel_t *ch) if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) return; - writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR), &ch->ch_neo_uart->isr_fcr); + writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR), + &ch->ch_neo_uart->isr_fcr); neo_pci_posting_flush(ch->ch_bd); for (i = 0; i < 10; i++) { @@ -1427,7 +1445,8 @@ static void neo_copy_data_from_queue_to_uart(struct channel_t *ch) ch->ch_tun.un_flags |= (UN_EMPTY); } - writeb(ch->ch_wqueue[ch->ch_w_tail], &ch->ch_neo_uart->txrx); + writeb(ch->ch_wqueue[ch->ch_w_tail], + &ch->ch_neo_uart->txrx); ch->ch_w_tail++; ch->ch_w_tail &= WQUEUEMASK; ch->ch_txcount++; @@ -1494,7 +1513,8 @@ static void neo_copy_data_from_queue_to_uart(struct channel_t *ch) ch->ch_tun.un_flags |= (UN_EMPTY); } - memcpy_toio(&ch->ch_neo_uart->txrxburst, ch->ch_wqueue + tail, s); + memcpy_toio(&ch->ch_neo_uart->txrxburst, + ch->ch_wqueue + tail, s); /* Add and flip queue if needed */ tail = (tail + s) & WQUEUEMASK; @@ -1628,7 +1648,8 @@ static void neo_uart_init(struct channel_t *ch) /* Clear out UART and FIFO */ readb(&ch->ch_neo_uart->txrx); - writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT), &ch->ch_neo_uart->isr_fcr); + writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT), + &ch->ch_neo_uart->isr_fcr); readb(&ch->ch_neo_uart->lsr); readb(&ch->ch_neo_uart->msr); @@ -1725,7 +1746,8 @@ static void neo_send_immediate_char(struct channel_t *ch, unsigned char c) neo_pci_posting_flush(ch->ch_bd); } -static unsigned int neo_read_eeprom(unsigned char __iomem *base, unsigned int address) +static unsigned int neo_read_eeprom(unsigned char __iomem *base, + unsigned int address) { unsigned int enable; unsigned int bits; -- cgit v1.2.3 From 318723e4ff367f2c0b15eee534ed2854628d292a Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Fri, 25 Mar 2016 11:44:34 +0900 Subject: staging: dgnc: fix Logical continuations should be on the fix checkpatch.pl warning about 'Logical continuations should be on the previous line' in dgnc_neo.c file. I think the 'force' need to check first, because if the 'force' is true, it doesn't need to call another function call. Signed-off-by: Daeseok Youn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_neo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dgnc/dgnc_neo.c b/drivers/staging/dgnc/dgnc_neo.c index 10b596fb4681..d732e6e99408 100644 --- a/drivers/staging/dgnc/dgnc_neo.c +++ b/drivers/staging/dgnc/dgnc_neo.c @@ -359,8 +359,8 @@ static inline void neo_clear_break(struct channel_t *ch, int force) /* Turn break off, and unset some variables */ if (ch->ch_flags & CH_BREAK_SENDING) { - if (time_after_eq(jiffies, ch->ch_stop_sending_break) - || force) { + if (force || + time_after_eq(jiffies, ch->ch_stop_sending_break)) { unsigned char temp = readb(&ch->ch_neo_uart->lcr); writeb((temp & ~UART_LCR_SBC), &ch->ch_neo_uart->lcr); -- cgit v1.2.3 From a12ddd60ed0a88c3bb83a8d4c07762e41620bf8c Mon Sep 17 00:00:00 2001 From: Nobuteru Hayashi Date: Fri, 18 Mar 2016 11:35:21 +0000 Subject: spi/fsl-espi: Don't spin forever on SPIE_RXCNT Infinite loop on SPIE_RXCNT occurred. while (SPIE_RXCNT(events) < min(4, mspi->len)) { cpu_relax(); events = mpc8xxx_spi_read_reg(®_base->event); } We met a soft lockup at fsl_espi_cpu_irq() because of this. Fix it by using spin_event_timeout() so that fsl_espi_cpu_irq() can break loop with timeouts dmesg. Signed-off-by: Nobuteru Hayashi Signed-off-by: Mark Brown --- drivers/spi/spi-fsl-espi.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c index 7cb0c1921495..5d7fb81240cd 100644 --- a/drivers/spi/spi-fsl-espi.c +++ b/drivers/spi/spi-fsl-espi.c @@ -539,11 +539,18 @@ void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events) if (events & SPIE_NE) { u32 rx_data, tmp; u8 rx_data_8; + int ret; /* Spin until RX is done */ - while (SPIE_RXCNT(events) < min(4, mspi->len)) { - cpu_relax(); - events = mpc8xxx_spi_read_reg(®_base->event); + if (SPIE_RXCNT(events) < min(4, mspi->len)) { + ret = spin_event_timeout( + !(SPIE_RXCNT(events = + mpc8xxx_spi_read_reg(®_base->event)) < + min(4, mspi->len)), + 10000, 0); /* 10 msec */ + if (!ret) + dev_err(mspi->dev, + "tired waiting for SPIE_RXCNT\n"); } if (mspi->len >= 4) { -- cgit v1.2.3 From aa70e567c4f0eeb849c6bcef3685bdf1fc3ca19d Mon Sep 17 00:00:00 2001 From: Nobuteru Hayashi Date: Fri, 18 Mar 2016 11:35:21 +0000 Subject: spi/fsl-espi: Don't wait transaction completion forever Because the eSPI driver uses wait_for_completion(), any stuck-able phenomenon at half-way transaction progress made worker task hang up. This phenomenon is perhaps caused by eSPI device errata which seems not to be published from vendor site yet. Anyway, we fix hang task by using fixed 2 seconds timeout that is our preferred value for eSPI maximum transaction size. It seems to be better that eSPI driver can detect this stuck and report error (EMSGSIZE) to the upper device driver because the upper device driver can decide to retry or recover. Signed-off-by: Nobuteru Hayashi Signed-off-by: Mark Brown --- drivers/spi/spi-fsl-espi.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c index 5d7fb81240cd..64d794b99803 100644 --- a/drivers/spi/spi-fsl-espi.c +++ b/drivers/spi/spi-fsl-espi.c @@ -245,7 +245,12 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t) if (ret) return ret; - wait_for_completion(&mpc8xxx_spi->done); + /* Won't hang up forever, SPI bus sometimes got lost interrupts... */ + ret = wait_for_completion_timeout(&mpc8xxx_spi->done, 2 * HZ); + if (ret == 0) + dev_err(mpc8xxx_spi->dev, + "Transaction hanging up (left %d bytes)\n", + mpc8xxx_spi->count); /* disable rx ints */ mpc8xxx_spi_write_reg(®_base->mask, 0); -- cgit v1.2.3 From 6319a68011b86fa61dc63e94dc4fb716628037f3 Mon Sep 17 00:00:00 2001 From: Nobuteru Hayashi Date: Fri, 18 Mar 2016 11:35:21 +0000 Subject: spi/fsl-espi: avoid infinite loops on fsl_espi_cpu_irq() It brought nearly infinite loops, and was possible to be occurred only if the SPI transaction total size are not alighed with 4. Loops are here at while (tmp--), tmp is unsigned, and set it with minus value. The loops are executed as a result of unexpected RX interrupt occurrence after that. This interrupt may be hardware eratta and is not fixed. Fix mspi->len from minus value to 0 and print warning message. Signed-off-by: Nobuteru Hayashi Signed-off-by: Mark Brown --- drivers/spi/spi-fsl-espi.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c index 64d794b99803..8d85a3c343da 100644 --- a/drivers/spi/spi-fsl-espi.c +++ b/drivers/spi/spi-fsl-espi.c @@ -544,6 +544,7 @@ void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events) if (events & SPIE_NE) { u32 rx_data, tmp; u8 rx_data_8; + int rx_nr_bytes = 4; int ret; /* Spin until RX is done */ @@ -560,7 +561,14 @@ void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events) if (mspi->len >= 4) { rx_data = mpc8xxx_spi_read_reg(®_base->receive); + } else if (mspi->len <= 0) { + dev_err(mspi->dev, + "unexpected RX(SPIE_NE) interrupt occurred,\n" + "(local rxlen %d bytes, reg rxlen %d bytes)\n", + min(4, mspi->len), SPIE_RXCNT(events)); + rx_nr_bytes = 0; } else { + rx_nr_bytes = mspi->len; tmp = mspi->len; rx_data = 0; while (tmp--) { @@ -571,7 +579,7 @@ void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events) rx_data <<= (4 - mspi->len) * 8; } - mspi->len -= 4; + mspi->len -= rx_nr_bytes; if (mspi->rx) mspi->get_rx(rx_data, mspi); -- cgit v1.2.3 From a52db659c79ceede44e2d5ca63ca058d49df8dea Mon Sep 17 00:00:00 2001 From: Christophe Ricard Date: Sun, 20 Mar 2016 19:30:17 +0100 Subject: spi: pxa2xx: Fix cs_change management Fix cs_change management so that it is in line with other spi drivers. In the spi core api helpers such as spi_bus_lock/unlock and spi_sync_locked or cs_change field in spi_transfer help to manage chip select from the device driver. The driver was setting the chip select to idle if the message queue was empty despite cs_change or other status field set by spi_bus_lock/unlock or spi_sync_locked. Signed-off-by: Christophe Ricard Signed-off-by: Mark Brown --- drivers/spi/spi-pxa2xx.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index 86c155aea0cf..0ce82db8e484 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -570,9 +570,8 @@ static void giveback(struct driver_data *drv_data) /* see if the next and current messages point * to the same chip */ - if (next_msg && next_msg->spi != msg->spi) - next_msg = NULL; - if (!next_msg || msg->state == ERROR_STATE) + if ((next_msg && next_msg->spi != msg->spi) || + msg->state == ERROR_STATE) cs_deassert(drv_data); } -- cgit v1.2.3 From 11622d4c638ad3dd229e39064d0e5726c4f3b454 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 26 Feb 2016 11:51:06 +0200 Subject: drm: bridge: Make (pre/post) enable/disable callbacks optional Instead of forcing bridges to implement empty callbacks make them all optional. Signed-off-by: Laurent Pinchart Link: http://patchwork.freedesktop.org/patch/msgid/1456480266-7904-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com Acked-by: Archit Taneja Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_bridge.c | 12 ++++++++---- include/drm/drm_crtc.h | 8 ++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index bd93453afa61..b3654404abd0 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -186,7 +186,8 @@ void drm_bridge_disable(struct drm_bridge *bridge) drm_bridge_disable(bridge->next); - bridge->funcs->disable(bridge); + if (bridge->funcs->disable) + bridge->funcs->disable(bridge); } EXPORT_SYMBOL(drm_bridge_disable); @@ -206,7 +207,8 @@ void drm_bridge_post_disable(struct drm_bridge *bridge) if (!bridge) return; - bridge->funcs->post_disable(bridge); + if (bridge->funcs->post_disable) + bridge->funcs->post_disable(bridge); drm_bridge_post_disable(bridge->next); } @@ -256,7 +258,8 @@ void drm_bridge_pre_enable(struct drm_bridge *bridge) drm_bridge_pre_enable(bridge->next); - bridge->funcs->pre_enable(bridge); + if (bridge->funcs->pre_enable) + bridge->funcs->pre_enable(bridge); } EXPORT_SYMBOL(drm_bridge_pre_enable); @@ -276,7 +279,8 @@ void drm_bridge_enable(struct drm_bridge *bridge) if (!bridge) return; - bridge->funcs->enable(bridge); + if (bridge->funcs->enable) + bridge->funcs->enable(bridge); drm_bridge_enable(bridge->next); } diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index b10eba23a744..f048a7b06529 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -1596,6 +1596,8 @@ struct drm_bridge_funcs { * * The bridge can assume that the display pipe (i.e. clocks and timing * signals) feeding it is still running when this callback is called. + * + * The disable callback is optional. */ void (*disable)(struct drm_bridge *bridge); @@ -1612,6 +1614,8 @@ struct drm_bridge_funcs { * The bridge must assume that the display pipe (i.e. clocks and timing * singals) feeding it is no longer running when this callback is * called. + * + * The post_disable callback is optional. */ void (*post_disable)(struct drm_bridge *bridge); @@ -1640,6 +1644,8 @@ struct drm_bridge_funcs { * will not yet be running when this callback is called. The bridge must * not enable the display link feeding the next bridge in the chain (if * there is one) when this callback is called. + * + * The pre_enable callback is optional. */ void (*pre_enable)(struct drm_bridge *bridge); @@ -1657,6 +1663,8 @@ struct drm_bridge_funcs { * signals) feeding it is running when this callback is called. This * callback must enable the display link feeding the next bridge in the * chain if there is one. + * + * The enable callback is optional. */ void (*enable)(struct drm_bridge *bridge); }; -- cgit v1.2.3 From 60d8fcef13e60484ecc5aa2c0a904b250750beba Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sat, 12 Mar 2016 10:15:03 +0100 Subject: pinctrl: sh-pfc: r8a7790: Implement voltage switching for SDHI All the SHDIs can operate with either 3.3V or 1.8V signals, depending on negotiation with the card. Implement the {get,set}_io_voltage operations and set the related capability flag for the associated pins. Signed-off-by: Ben Hutchings Signed-off-by: Wolfram Sang Cc: linux-gpio@vger.kernel.org Signed-off-by: Geert Uytterhoeven --- drivers/pinctrl/sh-pfc/pfc-r8a7790.c | 54 +++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7790.c b/drivers/pinctrl/sh-pfc/pfc-r8a7790.c index 0f4d48f9400b..eed8daa464cc 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7790.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7790.c @@ -21,16 +21,21 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include #include #include "core.h" #include "sh_pfc.h" +/* + * All pins assigned to GPIO bank 3 can be used for SD interfaces in + * which case they support both 3.3V and 1.8V signalling. + */ #define CPU_ALL_PORT(fn, sfx) \ PORT_GP_32(0, fn, sfx), \ PORT_GP_30(1, fn, sfx), \ PORT_GP_30(2, fn, sfx), \ - PORT_GP_32(3, fn, sfx), \ + PORT_GP_CFG_32(3, fn, sfx, SH_PFC_PIN_CFG_IO_VOLTAGE), \ PORT_GP_32(4, fn, sfx), \ PORT_GP_32(5, fn, sfx) @@ -4691,6 +4696,47 @@ static const char * const vin3_groups[] = { "vin3_clk", }; +#define IOCTRL6 0x8c + +static int r8a7790_get_io_voltage(struct sh_pfc *pfc, unsigned int pin) +{ + u32 data, mask; + + if (WARN(pin < RCAR_GP_PIN(3, 0) || pin > RCAR_GP_PIN(3, 31), "invalid pin %#x", pin)) + return -EINVAL; + + data = ioread32(pfc->windows->virt + IOCTRL6), + /* Bits in IOCTRL6 are numbered in opposite order to pins */ + mask = 0x80000000 >> (pin & 0x1f); + + return (data & mask) ? 3300 : 1800; +} + +static int r8a7790_set_io_voltage(struct sh_pfc *pfc, unsigned int pin, u16 mV) +{ + u32 data, mask; + + if (WARN(pin < RCAR_GP_PIN(3, 0) || pin > RCAR_GP_PIN(3, 31), "invalid pin %#x", pin)) + return -EINVAL; + + if (mV != 1800 && mV != 3300) + return -EINVAL; + + data = ioread32(pfc->windows->virt + IOCTRL6); + /* Bits in IOCTRL6 are numbered in opposite order to pins */ + mask = 0x80000000 >> (pin & 0x1f); + + if (mV == 3300) + data |= mask; + else + data &= ~mask; + + iowrite32(~data, pfc->windows->virt); /* unlock reg */ + iowrite32(data, pfc->windows->virt + IOCTRL6); + + return 0; +} + static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(audio_clk), SH_PFC_FUNCTION(avb), @@ -5690,8 +5736,14 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = { { }, }; +static const struct sh_pfc_soc_operations pinmux_ops = { + .get_io_voltage = r8a7790_get_io_voltage, + .set_io_voltage = r8a7790_set_io_voltage, +}; + const struct sh_pfc_soc_info r8a7790_pinmux_info = { .name = "r8a77900_pfc", + .ops = &pinmux_ops, .unlock_reg = 0xe6060000, /* PMMR */ .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, -- cgit v1.2.3 From 93d2185dcabcf8ea08026234e58f5e31484ec6a6 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 16 Mar 2016 00:48:11 +0000 Subject: pinctrl: sh-pfc: IPSRx and MOD_SELx should be set before GPSRx Gen2 / Gen3 datasheet will have below note in next version. This patch follows this note. IPSRx and MOD_SELx registers shall be set before setting GPSRx registers in case that they need to be configured. MOD_SELx registers can be set either earlier or later than setting IPSRx registers. Signed-off-by: Kuninori Morimoto Reviewed-by: Laurent Pinchart Signed-off-by: Geert Uytterhoeven --- drivers/pinctrl/sh-pfc/sh_pfc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h index a490834e2089..87140790d1f1 100644 --- a/drivers/pinctrl/sh-pfc/sh_pfc.h +++ b/drivers/pinctrl/sh-pfc/sh_pfc.h @@ -276,7 +276,7 @@ struct sh_pfc_soc_info { * - msel: Module selector */ #define PINMUX_IPSR_MSEL(ipsr, fn, msel) \ - PINMUX_DATA(fn##_MARK, FN_##msel, FN_##ipsr, FN_##fn) + PINMUX_DATA(fn##_MARK, FN_##msel, FN_##fn, FN_##ipsr) /* * Describe a pinmux configuration for a single-function pin with GPIO -- cgit v1.2.3 From 3caa7d8c3f03ad6f1b66f10f67dc68cb3af55fe1 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 23 Mar 2016 16:06:00 +0200 Subject: pinctrl: sh-pfc: Add drive strength support Add support for the drive-strengh pin configuration using the generic pinconf DT bindings. Signed-off-by: Laurent Pinchart Signed-off-by: Geert Uytterhoeven --- .../bindings/pinctrl/renesas,pfc-pinctrl.txt | 4 +- drivers/pinctrl/sh-pfc/core.c | 15 +++ drivers/pinctrl/sh-pfc/core.h | 3 + drivers/pinctrl/sh-pfc/pinctrl.c | 111 +++++++++++++++++++++ drivers/pinctrl/sh-pfc/sh_pfc.h | 17 ++++ 5 files changed, 148 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt index ffadb7a371f6..74e6ec0339d6 100644 --- a/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt @@ -72,8 +72,8 @@ Pin Configuration Node Properties: The pin configuration parameters use the generic pinconf bindings defined in pinctrl-bindings.txt in this directory. The supported parameters are -bias-disable, bias-pull-up, bias-pull-down and power-source. For pins that -have a configurable I/O voltage, the power-source value should be the +bias-disable, bias-pull-up, bias-pull-down, drive strength and power-source. For +pins that have a configurable I/O voltage, the power-source value should be the nominal I/O voltage in millivolts. diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index dc3609f0c60b..0497bbb8a8e7 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -175,6 +175,21 @@ void sh_pfc_write_raw_reg(void __iomem *mapped_reg, unsigned int reg_width, BUG(); } +u32 sh_pfc_read_reg(struct sh_pfc *pfc, u32 reg, unsigned int width) +{ + return sh_pfc_read_raw_reg(sh_pfc_phys_to_virt(pfc, reg), width); +} + +void sh_pfc_write_reg(struct sh_pfc *pfc, u32 reg, unsigned int width, u32 data) +{ + if (pfc->info->unlock_reg) + sh_pfc_write_raw_reg( + sh_pfc_phys_to_virt(pfc, pfc->info->unlock_reg), 32, + ~data); + + sh_pfc_write_raw_reg(sh_pfc_phys_to_virt(pfc, reg), width, data); +} + static void sh_pfc_config_reg_helper(struct sh_pfc *pfc, const struct pinmux_cfg_reg *crp, unsigned int in_pos, diff --git a/drivers/pinctrl/sh-pfc/core.h b/drivers/pinctrl/sh-pfc/core.h index 62f53b22ae85..fc05d0c516f3 100644 --- a/drivers/pinctrl/sh-pfc/core.h +++ b/drivers/pinctrl/sh-pfc/core.h @@ -62,6 +62,9 @@ int sh_pfc_unregister_pinctrl(struct sh_pfc *pfc); u32 sh_pfc_read_raw_reg(void __iomem *mapped_reg, unsigned int reg_width); void sh_pfc_write_raw_reg(void __iomem *mapped_reg, unsigned int reg_width, u32 data); +u32 sh_pfc_read_reg(struct sh_pfc *pfc, u32 reg, unsigned int width); +void sh_pfc_write_reg(struct sh_pfc *pfc, u32 reg, unsigned int width, + u32 data); int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin); int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type); diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index 87b0a599afaf..8efaa0631be6 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -476,6 +476,91 @@ static const struct pinmux_ops sh_pfc_pinmux_ops = { .gpio_set_direction = sh_pfc_gpio_set_direction, }; +static u32 sh_pfc_pinconf_find_drive_strength_reg(struct sh_pfc *pfc, + unsigned int pin, unsigned int *offset, unsigned int *size) +{ + const struct pinmux_drive_reg_field *field; + const struct pinmux_drive_reg *reg; + unsigned int i; + + for (reg = pfc->info->drive_regs; reg->reg; ++reg) { + for (i = 0; i < ARRAY_SIZE(reg->fields); ++i) { + field = ®->fields[i]; + + if (field->size && field->pin == pin) { + *offset = field->offset; + *size = field->size; + + return reg->reg; + } + } + } + + return 0; +} + +static int sh_pfc_pinconf_get_drive_strength(struct sh_pfc *pfc, + unsigned int pin) +{ + unsigned long flags; + unsigned int offset; + unsigned int size; + u32 reg; + u32 val; + + reg = sh_pfc_pinconf_find_drive_strength_reg(pfc, pin, &offset, &size); + if (!reg) + return -EINVAL; + + spin_lock_irqsave(&pfc->lock, flags); + val = sh_pfc_read_reg(pfc, reg, 32); + spin_unlock_irqrestore(&pfc->lock, flags); + + val = (val >> offset) & GENMASK(size - 1, 0); + + /* Convert the value to mA based on a full drive strength value of 24mA. + * We can make the full value configurable later if needed. + */ + return (val + 1) * (size == 2 ? 6 : 3); +} + +static int sh_pfc_pinconf_set_drive_strength(struct sh_pfc *pfc, + unsigned int pin, u16 strength) +{ + unsigned long flags; + unsigned int offset; + unsigned int size; + unsigned int step; + u32 reg; + u32 val; + + reg = sh_pfc_pinconf_find_drive_strength_reg(pfc, pin, &offset, &size); + if (!reg) + return -EINVAL; + + step = size == 2 ? 6 : 3; + + if (strength < step || strength > 24) + return -EINVAL; + + /* Convert the value from mA based on a full drive strength value of + * 24mA. We can make the full value configurable later if needed. + */ + strength = strength / step - 1; + + spin_lock_irqsave(&pfc->lock, flags); + + val = sh_pfc_read_reg(pfc, reg, 32); + val &= ~GENMASK(offset + size - 1, offset); + val |= strength << offset; + + sh_pfc_write_reg(pfc, reg, 32, val); + + spin_unlock_irqrestore(&pfc->lock, flags); + + return 0; +} + /* Check whether the requested parameter is supported for a pin. */ static bool sh_pfc_pinconf_validate(struct sh_pfc *pfc, unsigned int _pin, enum pin_config_param param) @@ -493,6 +578,9 @@ static bool sh_pfc_pinconf_validate(struct sh_pfc *pfc, unsigned int _pin, case PIN_CONFIG_BIAS_PULL_DOWN: return pin->configs & SH_PFC_PIN_CFG_PULL_DOWN; + case PIN_CONFIG_DRIVE_STRENGTH: + return pin->configs & SH_PFC_PIN_CFG_DRIVE_STRENGTH; + case PIN_CONFIG_POWER_SOURCE: return pin->configs & SH_PFC_PIN_CFG_IO_VOLTAGE; @@ -532,6 +620,17 @@ static int sh_pfc_pinconf_get(struct pinctrl_dev *pctldev, unsigned _pin, break; } + case PIN_CONFIG_DRIVE_STRENGTH: { + int ret; + + ret = sh_pfc_pinconf_get_drive_strength(pfc, _pin); + if (ret < 0) + return ret; + + *config = ret; + break; + } + case PIN_CONFIG_POWER_SOURCE: { int ret; @@ -584,6 +683,18 @@ static int sh_pfc_pinconf_set(struct pinctrl_dev *pctldev, unsigned _pin, break; + case PIN_CONFIG_DRIVE_STRENGTH: { + unsigned int arg = + pinconf_to_config_argument(configs[i]); + int ret; + + ret = sh_pfc_pinconf_set_drive_strength(pfc, _pin, arg); + if (ret < 0) + return ret; + + break; + } + case PIN_CONFIG_POWER_SOURCE: { unsigned int arg = pinconf_to_config_argument(configs[i]); diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h index 87140790d1f1..656ea32f776c 100644 --- a/drivers/pinctrl/sh-pfc/sh_pfc.h +++ b/drivers/pinctrl/sh-pfc/sh_pfc.h @@ -28,6 +28,7 @@ enum { #define SH_PFC_PIN_CFG_PULL_UP (1 << 2) #define SH_PFC_PIN_CFG_PULL_DOWN (1 << 3) #define SH_PFC_PIN_CFG_IO_VOLTAGE (1 << 4) +#define SH_PFC_PIN_CFG_DRIVE_STRENGTH (1 << 5) #define SH_PFC_PIN_CFG_NO_GPIO (1 << 31) struct sh_pfc_pin { @@ -131,6 +132,21 @@ struct pinmux_cfg_reg { { var_fw0, var_fwn, 0 }, \ .enum_ids = (const u16 []) +struct pinmux_drive_reg_field { + u16 pin; + u8 offset; + u8 size; +}; + +struct pinmux_drive_reg { + u32 reg; + const struct pinmux_drive_reg_field fields[8]; +}; + +#define PINMUX_DRIVE_REG(name, r) \ + .reg = r, \ + .fields = + struct pinmux_data_reg { u32 reg; u8 reg_width; @@ -199,6 +215,7 @@ struct sh_pfc_soc_info { #endif const struct pinmux_cfg_reg *cfg_regs; + const struct pinmux_drive_reg *drive_regs; const struct pinmux_data_reg *data_regs; const u16 *pinmux_data; -- cgit v1.2.3 From 92e6d9a2cc827018a18885e0f3050ab9ff8c3206 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 23 Mar 2016 16:06:01 +0200 Subject: pinctrl: sh-pfc: r8a7795: Add drive strength support Define the drive strength registers for the R8A7795. As the PFC driver for the SoC only defines GPIO pins at the moment, limit drive strength support to those pins. Pins without GPIO capabilities will be supported later. Signed-off-by: Laurent Pinchart Signed-off-by: Geert Uytterhoeven --- drivers/pinctrl/sh-pfc/pfc-r8a7795.c | 218 +++++++++++++++++++++++++++++++++-- 1 file changed, 210 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7795.c b/drivers/pinctrl/sh-pfc/pfc-r8a7795.c index 5979dabc02fa..44632b1a5c97 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7795.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7795.c @@ -14,14 +14,14 @@ #include "sh_pfc.h" #define CPU_ALL_PORT(fn, sfx) \ - PORT_GP_16(0, fn, sfx), \ - PORT_GP_28(1, fn, sfx), \ - PORT_GP_15(2, fn, sfx), \ - PORT_GP_16(3, fn, sfx), \ - PORT_GP_18(4, fn, sfx), \ - PORT_GP_26(5, fn, sfx), \ - PORT_GP_32(6, fn, sfx), \ - PORT_GP_4(7, fn, sfx) + PORT_GP_CFG_16(0, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \ + PORT_GP_CFG_28(1, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \ + PORT_GP_CFG_15(2, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \ + PORT_GP_CFG_16(3, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \ + PORT_GP_CFG_18(4, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \ + PORT_GP_CFG_26(5, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \ + PORT_GP_CFG_32(6, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \ + PORT_GP_CFG_4(7, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH) /* * F_() : just information * FM() : macro for FN_xxx / xxx_MARK @@ -4564,6 +4564,207 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = { { }, }; +static const struct pinmux_drive_reg pinmux_drive_regs[] = { + { PINMUX_DRIVE_REG("DRVCTRL3", 0xe606030c) { + { RCAR_GP_PIN(2, 9), 8, 3 }, /* AVB_MDC */ + { RCAR_GP_PIN(2, 10), 4, 3 }, /* AVB_MAGIC */ + { RCAR_GP_PIN(2, 11), 0, 3 }, /* AVB_PHY_INT */ + } }, + { PINMUX_DRIVE_REG("DRVCTRL4", 0xe6060310) { + { RCAR_GP_PIN(2, 12), 28, 3 }, /* AVB_LINK */ + { RCAR_GP_PIN(2, 13), 24, 3 }, /* AVB_AVTP_MATCH */ + { RCAR_GP_PIN(2, 14), 20, 3 }, /* AVB_AVTP_CAPTURE */ + { RCAR_GP_PIN(2, 0), 16, 3 }, /* IRQ0 */ + { RCAR_GP_PIN(2, 1), 12, 3 }, /* IRQ1 */ + { RCAR_GP_PIN(2, 2), 8, 3 }, /* IRQ2 */ + { RCAR_GP_PIN(2, 3), 4, 3 }, /* IRQ3 */ + { RCAR_GP_PIN(2, 4), 0, 3 }, /* IRQ4 */ + } }, + { PINMUX_DRIVE_REG("DRVCTRL5", 0xe6060314) { + { RCAR_GP_PIN(2, 5), 28, 3 }, /* IRQ5 */ + { RCAR_GP_PIN(2, 6), 24, 3 }, /* PWM0 */ + { RCAR_GP_PIN(2, 7), 20, 3 }, /* PWM1 */ + { RCAR_GP_PIN(2, 8), 16, 3 }, /* PWM2 */ + { RCAR_GP_PIN(1, 0), 12, 3 }, /* A0 */ + { RCAR_GP_PIN(1, 1), 8, 3 }, /* A1 */ + { RCAR_GP_PIN(1, 2), 4, 3 }, /* A2 */ + { RCAR_GP_PIN(1, 3), 0, 3 }, /* A3 */ + } }, + { PINMUX_DRIVE_REG("DRVCTRL6", 0xe6060318) { + { RCAR_GP_PIN(1, 4), 28, 3 }, /* A4 */ + { RCAR_GP_PIN(1, 5), 24, 3 }, /* A5 */ + { RCAR_GP_PIN(1, 6), 20, 3 }, /* A6 */ + { RCAR_GP_PIN(1, 7), 16, 3 }, /* A7 */ + { RCAR_GP_PIN(1, 8), 12, 3 }, /* A8 */ + { RCAR_GP_PIN(1, 9), 8, 3 }, /* A9 */ + { RCAR_GP_PIN(1, 10), 4, 3 }, /* A10 */ + { RCAR_GP_PIN(1, 11), 0, 3 }, /* A11 */ + } }, + { PINMUX_DRIVE_REG("DRVCTRL7", 0xe606031c) { + { RCAR_GP_PIN(1, 12), 28, 3 }, /* A12 */ + { RCAR_GP_PIN(1, 13), 24, 3 }, /* A13 */ + { RCAR_GP_PIN(1, 14), 20, 3 }, /* A14 */ + { RCAR_GP_PIN(1, 15), 16, 3 }, /* A15 */ + { RCAR_GP_PIN(1, 16), 12, 3 }, /* A16 */ + { RCAR_GP_PIN(1, 17), 8, 3 }, /* A17 */ + { RCAR_GP_PIN(1, 18), 4, 3 }, /* A18 */ + { RCAR_GP_PIN(1, 19), 0, 3 }, /* A19 */ + } }, + { PINMUX_DRIVE_REG("DRVCTRL8", 0xe6060320) { + { RCAR_GP_PIN(1, 20), 24, 3 }, /* CS0 */ + { RCAR_GP_PIN(1, 21), 20, 3 }, /* CS1_A26 */ + { RCAR_GP_PIN(1, 22), 16, 3 }, /* BS */ + { RCAR_GP_PIN(1, 23), 12, 3 }, /* RD */ + { RCAR_GP_PIN(1, 24), 8, 3 }, /* RD_WR */ + { RCAR_GP_PIN(1, 25), 4, 3 }, /* WE0 */ + { RCAR_GP_PIN(1, 26), 0, 3 }, /* WE1 */ + } }, + { PINMUX_DRIVE_REG("DRVCTRL9", 0xe6060324) { + { RCAR_GP_PIN(1, 27), 28, 3 }, /* EX_WAIT0 */ + { RCAR_GP_PIN(0, 0), 20, 3 }, /* D0 */ + { RCAR_GP_PIN(0, 1), 16, 3 }, /* D1 */ + { RCAR_GP_PIN(0, 2), 12, 3 }, /* D2 */ + { RCAR_GP_PIN(0, 3), 8, 3 }, /* D3 */ + { RCAR_GP_PIN(0, 4), 4, 3 }, /* D4 */ + { RCAR_GP_PIN(0, 5), 0, 3 }, /* D5 */ + } }, + { PINMUX_DRIVE_REG("DRVCTRL10", 0xe6060328) { + { RCAR_GP_PIN(0, 6), 28, 3 }, /* D6 */ + { RCAR_GP_PIN(0, 7), 24, 3 }, /* D7 */ + { RCAR_GP_PIN(0, 8), 20, 3 }, /* D8 */ + { RCAR_GP_PIN(0, 9), 16, 3 }, /* D9 */ + { RCAR_GP_PIN(0, 10), 12, 3 }, /* D10 */ + { RCAR_GP_PIN(0, 11), 8, 3 }, /* D11 */ + { RCAR_GP_PIN(0, 12), 4, 3 }, /* D12 */ + { RCAR_GP_PIN(0, 13), 0, 3 }, /* D13 */ + } }, + { PINMUX_DRIVE_REG("DRVCTRL11", 0xe606032c) { + { RCAR_GP_PIN(0, 14), 28, 3 }, /* D14 */ + { RCAR_GP_PIN(0, 15), 24, 3 }, /* D15 */ + { RCAR_GP_PIN(7, 0), 20, 3 }, /* AVS1 */ + { RCAR_GP_PIN(7, 1), 16, 3 }, /* AVS2 */ + { RCAR_GP_PIN(7, 2), 12, 3 }, /* HDMI0_CEC */ + { RCAR_GP_PIN(7, 3), 8, 3 }, /* HDMI1_CEC */ + } }, + { PINMUX_DRIVE_REG("DRVCTRL13", 0xe6060334) { + { RCAR_GP_PIN(3, 0), 20, 3 }, /* SD0_CLK */ + { RCAR_GP_PIN(3, 1), 16, 3 }, /* SD0_CMD */ + { RCAR_GP_PIN(3, 2), 12, 3 }, /* SD0_DAT0 */ + { RCAR_GP_PIN(3, 3), 8, 3 }, /* SD0_DAT1 */ + { RCAR_GP_PIN(3, 4), 4, 3 }, /* SD0_DAT2 */ + { RCAR_GP_PIN(3, 5), 0, 3 }, /* SD0_DAT3 */ + } }, + { PINMUX_DRIVE_REG("DRVCTRL14", 0xe6060338) { + { RCAR_GP_PIN(3, 6), 28, 3 }, /* SD1_CLK */ + { RCAR_GP_PIN(3, 7), 24, 3 }, /* SD1_CMD */ + { RCAR_GP_PIN(3, 8), 20, 3 }, /* SD1_DAT0 */ + { RCAR_GP_PIN(3, 9), 16, 3 }, /* SD1_DAT1 */ + { RCAR_GP_PIN(3, 10), 12, 3 }, /* SD1_DAT2 */ + { RCAR_GP_PIN(3, 11), 8, 3 }, /* SD1_DAT3 */ + { RCAR_GP_PIN(4, 0), 4, 3 }, /* SD2_CLK */ + { RCAR_GP_PIN(4, 1), 0, 3 }, /* SD2_CMD */ + } }, + { PINMUX_DRIVE_REG("DRVCTRL15", 0xe606033c) { + { RCAR_GP_PIN(4, 2), 28, 3 }, /* SD2_DAT0 */ + { RCAR_GP_PIN(4, 3), 24, 3 }, /* SD2_DAT1 */ + { RCAR_GP_PIN(4, 4), 20, 3 }, /* SD2_DAT2 */ + { RCAR_GP_PIN(4, 5), 16, 3 }, /* SD2_DAT3 */ + { RCAR_GP_PIN(4, 6), 12, 3 }, /* SD2_DS */ + { RCAR_GP_PIN(4, 7), 8, 3 }, /* SD3_CLK */ + { RCAR_GP_PIN(4, 8), 4, 3 }, /* SD3_CMD */ + { RCAR_GP_PIN(4, 9), 0, 3 }, /* SD3_DAT0 */ + } }, + { PINMUX_DRIVE_REG("DRVCTRL16", 0xe6060340) { + { RCAR_GP_PIN(4, 10), 28, 3 }, /* SD3_DAT1 */ + { RCAR_GP_PIN(4, 11), 24, 3 }, /* SD3_DAT2 */ + { RCAR_GP_PIN(4, 12), 20, 3 }, /* SD3_DAT3 */ + { RCAR_GP_PIN(4, 13), 16, 3 }, /* SD3_DAT4 */ + { RCAR_GP_PIN(4, 14), 12, 3 }, /* SD3_DAT5 */ + { RCAR_GP_PIN(4, 15), 8, 3 }, /* SD3_DAT6 */ + { RCAR_GP_PIN(4, 16), 4, 3 }, /* SD3_DAT7 */ + { RCAR_GP_PIN(4, 17), 0, 3 }, /* SD3_DS */ + } }, + { PINMUX_DRIVE_REG("DRVCTRL17", 0xe6060344) { + { RCAR_GP_PIN(3, 12), 28, 3 }, /* SD0_CD */ + { RCAR_GP_PIN(3, 13), 24, 3 }, /* SD0_WP */ + { RCAR_GP_PIN(3, 14), 20, 3 }, /* SD1_CD */ + { RCAR_GP_PIN(3, 15), 16, 3 }, /* SD1_WP */ + { RCAR_GP_PIN(5, 0), 12, 3 }, /* SCK0 */ + { RCAR_GP_PIN(5, 1), 8, 3 }, /* RX0 */ + { RCAR_GP_PIN(5, 2), 4, 3 }, /* TX0 */ + { RCAR_GP_PIN(5, 3), 0, 3 }, /* CTS0 */ + } }, + { PINMUX_DRIVE_REG("DRVCTRL18", 0xe6060348) { + { RCAR_GP_PIN(5, 4), 28, 3 }, /* RTS0_TANS */ + { RCAR_GP_PIN(5, 5), 24, 3 }, /* RX1 */ + { RCAR_GP_PIN(5, 6), 20, 3 }, /* TX1 */ + { RCAR_GP_PIN(5, 7), 16, 3 }, /* CTS1 */ + { RCAR_GP_PIN(5, 8), 12, 3 }, /* RTS1_TANS */ + { RCAR_GP_PIN(5, 9), 8, 3 }, /* SCK2 */ + { RCAR_GP_PIN(5, 10), 4, 3 }, /* TX2 */ + { RCAR_GP_PIN(5, 11), 0, 3 }, /* RX2 */ + } }, + { PINMUX_DRIVE_REG("DRVCTRL19", 0xe606034c) { + { RCAR_GP_PIN(5, 12), 28, 3 }, /* HSCK0 */ + { RCAR_GP_PIN(5, 13), 24, 3 }, /* HRX0 */ + { RCAR_GP_PIN(5, 14), 20, 3 }, /* HTX0 */ + { RCAR_GP_PIN(5, 15), 16, 3 }, /* HCTS0 */ + { RCAR_GP_PIN(5, 16), 12, 3 }, /* HRTS0 */ + { RCAR_GP_PIN(5, 17), 8, 3 }, /* MSIOF0_SCK */ + { RCAR_GP_PIN(5, 18), 4, 3 }, /* MSIOF0_SYNC */ + { RCAR_GP_PIN(5, 19), 0, 3 }, /* MSIOF0_SS1 */ + } }, + { PINMUX_DRIVE_REG("DRVCTRL20", 0xe6060350) { + { RCAR_GP_PIN(5, 20), 28, 3 }, /* MSIOF0_TXD */ + { RCAR_GP_PIN(5, 21), 24, 3 }, /* MSIOF0_SS2 */ + { RCAR_GP_PIN(5, 22), 20, 3 }, /* MSIOF0_RXD */ + { RCAR_GP_PIN(5, 23), 16, 3 }, /* MLB_CLK */ + { RCAR_GP_PIN(5, 24), 12, 3 }, /* MLB_SIG */ + { RCAR_GP_PIN(5, 25), 8, 3 }, /* MLB_DAT */ + { RCAR_GP_PIN(6, 0), 0, 3 }, /* SSI_SCK01239 */ + } }, + { PINMUX_DRIVE_REG("DRVCTRL21", 0xe6060354) { + { RCAR_GP_PIN(6, 1), 28, 3 }, /* SSI_WS01239 */ + { RCAR_GP_PIN(6, 2), 24, 3 }, /* SSI_SDATA0 */ + { RCAR_GP_PIN(6, 3), 20, 3 }, /* SSI_SDATA1 */ + { RCAR_GP_PIN(6, 4), 16, 3 }, /* SSI_SDATA2 */ + { RCAR_GP_PIN(6, 5), 12, 3 }, /* SSI_SCK34 */ + { RCAR_GP_PIN(6, 6), 8, 3 }, /* SSI_WS34 */ + { RCAR_GP_PIN(6, 7), 4, 3 }, /* SSI_SDATA3 */ + { RCAR_GP_PIN(6, 8), 0, 3 }, /* SSI_SCK4 */ + } }, + { PINMUX_DRIVE_REG("DRVCTRL22", 0xe6060358) { + { RCAR_GP_PIN(6, 9), 28, 3 }, /* SSI_WS4 */ + { RCAR_GP_PIN(6, 10), 24, 3 }, /* SSI_SDATA4 */ + { RCAR_GP_PIN(6, 11), 20, 3 }, /* SSI_SCK5 */ + { RCAR_GP_PIN(6, 12), 16, 3 }, /* SSI_WS5 */ + { RCAR_GP_PIN(6, 13), 12, 3 }, /* SSI_SDATA5 */ + { RCAR_GP_PIN(6, 14), 8, 3 }, /* SSI_SCK6 */ + { RCAR_GP_PIN(6, 15), 4, 3 }, /* SSI_WS6 */ + { RCAR_GP_PIN(6, 16), 0, 3 }, /* SSI_SDATA6 */ + } }, + { PINMUX_DRIVE_REG("DRVCTRL23", 0xe606035c) { + { RCAR_GP_PIN(6, 17), 28, 3 }, /* SSI_SCK78 */ + { RCAR_GP_PIN(6, 18), 24, 3 }, /* SSI_WS78 */ + { RCAR_GP_PIN(6, 19), 20, 3 }, /* SSI_SDATA7 */ + { RCAR_GP_PIN(6, 20), 16, 3 }, /* SSI_SDATA8 */ + { RCAR_GP_PIN(6, 21), 12, 3 }, /* SSI_SDATA9 */ + { RCAR_GP_PIN(6, 22), 8, 3 }, /* AUDIO_CLKA */ + { RCAR_GP_PIN(6, 23), 4, 3 }, /* AUDIO_CLKB */ + { RCAR_GP_PIN(6, 24), 0, 3 }, /* USB0_PWEN */ + } }, + { PINMUX_DRIVE_REG("DRVCTRL24", 0xe6060360) { + { RCAR_GP_PIN(6, 25), 28, 3 }, /* USB0_OVC */ + { RCAR_GP_PIN(6, 26), 24, 3 }, /* USB1_PWEN */ + { RCAR_GP_PIN(6, 27), 20, 3 }, /* USB1_OVC */ + { RCAR_GP_PIN(6, 28), 16, 3 }, /* USB30_PWEN */ + { RCAR_GP_PIN(6, 29), 12, 3 }, /* USB30_OVC */ + { RCAR_GP_PIN(6, 30), 8, 3 }, /* USB31_PWEN */ + { RCAR_GP_PIN(6, 31), 4, 3 }, /* USB31_OVC */ + } }, + { }, +}; + const struct sh_pfc_soc_info r8a7795_pinmux_info = { .name = "r8a77950_pfc", .unlock_reg = 0xe6060000, /* PMMR */ @@ -4578,6 +4779,7 @@ const struct sh_pfc_soc_info r8a7795_pinmux_info = { .nr_functions = ARRAY_SIZE(pinmux_functions), .cfg_regs = pinmux_config_regs, + .drive_regs = pinmux_drive_regs, .pinmux_data = pinmux_data, .pinmux_data_size = ARRAY_SIZE(pinmux_data), -- cgit v1.2.3 From 6c87e5c3ec6db052f3744804a517b6fb003906e1 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Wed, 23 Mar 2016 11:42:54 +0300 Subject: drm: Rename drm_connector_unplug_all() to drm_connector_unregister_all() Current name is a bit misleading because what that helper function really does it calls drm_connector_unregister() for all connectors. This all has nothing to do with hotplugging so let's name things properly. And while at it remove potentially dangerous locking around drm_connector_unregister() in rcar_du_remove() as mentioned in kerneldoc for drm_connector_unregister_all(). Signed-off-by: Alexey Brodkin Cc: Daniel Vetter Cc: David Airlie Cc: Boris Brezillon Cc: linux-renesas-soc@vger.kernel.org Acked-by: Laurent Pinchart Acked-by: Boris Brezillon Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1458722577-20283-2-git-send-email-abrodkin@synopsys.com --- drivers/gpu/drm/drm_crtc.c | 18 +++++++++--------- drivers/gpu/drm/rcar-du/rcar_du_drv.c | 5 +---- drivers/gpu/drm/udl/udl_drv.c | 2 +- include/drm/drm_crtc.h | 4 ++-- 4 files changed, 13 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 49781a9f8a94..7675826c63f2 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -1078,25 +1078,25 @@ void drm_connector_unregister(struct drm_connector *connector) } EXPORT_SYMBOL(drm_connector_unregister); - /** - * drm_connector_unplug_all - unregister connector userspace interfaces + * drm_connector_unregister_all - unregister connector userspace interfaces * @dev: drm device * - * This function unregisters all connector userspace interfaces in sysfs. Should - * be call when the device is disconnected, e.g. from an usb driver's - * ->disconnect callback. + * This functions unregisters all connectors from sysfs and other places so + * that userspace can no longer access them. Drivers should call this as the + * first step tearing down the device instace, or when the underlying + * physical device disappeared (e.g. USB unplug), right before calling + * drm_dev_unregister(). */ -void drm_connector_unplug_all(struct drm_device *dev) +void drm_connector_unregister_all(struct drm_device *dev) { struct drm_connector *connector; /* FIXME: taking the mode config mutex ends up in a clash with sysfs */ - list_for_each_entry(connector, &dev->mode_config.connector_list, head) + drm_for_each_connector(connector, dev) drm_connector_unregister(connector); - } -EXPORT_SYMBOL(drm_connector_unplug_all); +EXPORT_SYMBOL(drm_connector_unregister_all); /** * drm_encoder_init - Init a preallocated encoder diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c index ed6006bf6bd8..644db36d0d20 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c @@ -278,10 +278,7 @@ static int rcar_du_remove(struct platform_device *pdev) struct rcar_du_device *rcdu = platform_get_drvdata(pdev); struct drm_device *ddev = rcdu->ddev; - mutex_lock(&ddev->mode_config.mutex); - drm_connector_unplug_all(ddev); - mutex_unlock(&ddev->mode_config.mutex); - + drm_connector_unregister_all(ddev); drm_dev_unregister(ddev); if (rcdu->fbdev) diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 772ec9e1f590..c20408940cd0 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -94,7 +94,7 @@ static void udl_usb_disconnect(struct usb_interface *interface) struct drm_device *dev = usb_get_intfdata(interface); drm_kms_helper_poll_disable(dev); - drm_connector_unplug_all(dev); + drm_connector_unregister_all(dev); udl_fbdev_unplug(dev); udl_drop_usb(dev); drm_unplug_dev(dev); diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index f048a7b06529..12f2bd4cf38a 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -2253,8 +2253,8 @@ void drm_connector_unregister(struct drm_connector *connector); extern void drm_connector_cleanup(struct drm_connector *connector); extern unsigned int drm_connector_index(struct drm_connector *connector); -/* helper to unplug all connectors from sysfs for device */ -extern void drm_connector_unplug_all(struct drm_device *dev); +/* helper to unregister all connectors from sysfs for device */ +extern void drm_connector_unregister_all(struct drm_device *dev); extern int drm_bridge_add(struct drm_bridge *bridge); extern void drm_bridge_remove(struct drm_bridge *bridge); -- cgit v1.2.3 From 6aa23e658d910342e8fedb23780638ddaed744d7 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 24 Mar 2016 17:50:20 +0200 Subject: drm/i915: use a substruct in vbt data for edp Housekeeping, similar to psr, backlight, and dsi. No functional changes. Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1458834623-8734-2-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 19 ++++++++++--------- drivers/gpu/drm/i915/intel_bios.c | 38 +++++++++++++++++++------------------- drivers/gpu/drm/i915/intel_ddi.c | 8 ++++---- drivers/gpu/drm/i915/intel_dp.c | 16 ++++++++-------- drivers/gpu/drm/i915/intel_lvds.c | 2 +- 5 files changed, 42 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b93ef7017c93..fe8021ecb254 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1446,15 +1446,16 @@ struct intel_vbt_data { enum drrs_support_type drrs_type; - /* eDP */ - int edp_rate; - int edp_lanes; - int edp_preemphasis; - int edp_vswing; - bool edp_initialized; - bool edp_support; - int edp_bpp; - struct edp_power_seq edp_pps; + struct { + int rate; + int lanes; + int preemphasis; + int vswing; + bool initialized; + bool support; + int bpp; + struct edp_power_seq pps; + } edp; struct { bool full_link; diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 083003b015f5..61eb7a6bb8f0 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -527,7 +527,7 @@ parse_driver_features(struct drm_i915_private *dev_priv, return; if (driver->lvds_config == BDB_DRIVER_FEATURE_EDP) - dev_priv->vbt.edp_support = 1; + dev_priv->vbt.edp.support = 1; if (driver->dual_frequency) dev_priv->render_reclock_avail = true; @@ -552,20 +552,20 @@ parse_edp(struct drm_i915_private *dev_priv, const struct bdb_header *bdb) edp = find_section(bdb, BDB_EDP); if (!edp) { - if (dev_priv->vbt.edp_support) + if (dev_priv->vbt.edp.support) DRM_DEBUG_KMS("No eDP BDB found but eDP panel supported.\n"); return; } switch ((edp->color_depth >> (panel_type * 2)) & 3) { case EDP_18BPP: - dev_priv->vbt.edp_bpp = 18; + dev_priv->vbt.edp.bpp = 18; break; case EDP_24BPP: - dev_priv->vbt.edp_bpp = 24; + dev_priv->vbt.edp.bpp = 24; break; case EDP_30BPP: - dev_priv->vbt.edp_bpp = 30; + dev_priv->vbt.edp.bpp = 30; break; } @@ -573,14 +573,14 @@ parse_edp(struct drm_i915_private *dev_priv, const struct bdb_header *bdb) edp_pps = &edp->power_seqs[panel_type]; edp_link_params = &edp->link_params[panel_type]; - dev_priv->vbt.edp_pps = *edp_pps; + dev_priv->vbt.edp.pps = *edp_pps; switch (edp_link_params->rate) { case EDP_RATE_1_62: - dev_priv->vbt.edp_rate = DP_LINK_BW_1_62; + dev_priv->vbt.edp.rate = DP_LINK_BW_1_62; break; case EDP_RATE_2_7: - dev_priv->vbt.edp_rate = DP_LINK_BW_2_7; + dev_priv->vbt.edp.rate = DP_LINK_BW_2_7; break; default: DRM_DEBUG_KMS("VBT has unknown eDP link rate value %u\n", @@ -590,13 +590,13 @@ parse_edp(struct drm_i915_private *dev_priv, const struct bdb_header *bdb) switch (edp_link_params->lanes) { case EDP_LANE_1: - dev_priv->vbt.edp_lanes = 1; + dev_priv->vbt.edp.lanes = 1; break; case EDP_LANE_2: - dev_priv->vbt.edp_lanes = 2; + dev_priv->vbt.edp.lanes = 2; break; case EDP_LANE_4: - dev_priv->vbt.edp_lanes = 4; + dev_priv->vbt.edp.lanes = 4; break; default: DRM_DEBUG_KMS("VBT has unknown eDP lane count value %u\n", @@ -606,16 +606,16 @@ parse_edp(struct drm_i915_private *dev_priv, const struct bdb_header *bdb) switch (edp_link_params->preemphasis) { case EDP_PREEMPHASIS_NONE: - dev_priv->vbt.edp_preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_0; + dev_priv->vbt.edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_0; break; case EDP_PREEMPHASIS_3_5dB: - dev_priv->vbt.edp_preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_1; + dev_priv->vbt.edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_1; break; case EDP_PREEMPHASIS_6dB: - dev_priv->vbt.edp_preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_2; + dev_priv->vbt.edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_2; break; case EDP_PREEMPHASIS_9_5dB: - dev_priv->vbt.edp_preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_3; + dev_priv->vbt.edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_3; break; default: DRM_DEBUG_KMS("VBT has unknown eDP pre-emphasis value %u\n", @@ -625,16 +625,16 @@ parse_edp(struct drm_i915_private *dev_priv, const struct bdb_header *bdb) switch (edp_link_params->vswing) { case EDP_VSWING_0_4V: - dev_priv->vbt.edp_vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_0; + dev_priv->vbt.edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_0; break; case EDP_VSWING_0_6V: - dev_priv->vbt.edp_vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_1; + dev_priv->vbt.edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_1; break; case EDP_VSWING_0_8V: - dev_priv->vbt.edp_vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_2; + dev_priv->vbt.edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_2; break; case EDP_VSWING_1_2V: - dev_priv->vbt.edp_vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_3; + dev_priv->vbt.edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_3; break; default: DRM_DEBUG_KMS("VBT has unknown eDP voltage swing value %u\n", diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index e6c3a80e1360..50e4978359a4 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -2002,8 +2002,8 @@ void intel_ddi_get_config(struct intel_encoder *encoder, pipe_config->has_audio = intel_ddi_is_audio_enabled(dev_priv, intel_crtc); - if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp_bpp && - pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) { + if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp.bpp && + pipe_config->pipe_bpp > dev_priv->vbt.edp.bpp) { /* * This is a big fat ugly hack. * @@ -2018,8 +2018,8 @@ void intel_ddi_get_config(struct intel_encoder *encoder, * load. */ DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n", - pipe_config->pipe_bpp, dev_priv->vbt.edp_bpp); - dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp; + pipe_config->pipe_bpp, dev_priv->vbt.edp.bpp); + dev_priv->vbt.edp.bpp = pipe_config->pipe_bpp; } intel_ddi_clock_get(encoder, pipe_config); diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 3ff8f1d67594..55faad13174d 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1500,10 +1500,10 @@ intel_dp_compute_config(struct intel_encoder *encoder, /* Get bpp from vbt only for panels that dont have bpp in edid */ if (intel_connector->base.display_info.bpc == 0 && - (dev_priv->vbt.edp_bpp && dev_priv->vbt.edp_bpp < bpp)) { + (dev_priv->vbt.edp.bpp && dev_priv->vbt.edp.bpp < bpp)) { DRM_DEBUG_KMS("clamping bpp for eDP panel to BIOS-provided %i\n", - dev_priv->vbt.edp_bpp); - bpp = dev_priv->vbt.edp_bpp; + dev_priv->vbt.edp.bpp); + bpp = dev_priv->vbt.edp.bpp; } /* @@ -2386,8 +2386,8 @@ static void intel_dp_get_config(struct intel_encoder *encoder, intel_dotclock_calculate(pipe_config->port_clock, &pipe_config->dp_m_n); - if (is_edp(intel_dp) && dev_priv->vbt.edp_bpp && - pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) { + if (is_edp(intel_dp) && dev_priv->vbt.edp.bpp && + pipe_config->pipe_bpp > dev_priv->vbt.edp.bpp) { /* * This is a big fat ugly hack. * @@ -2402,8 +2402,8 @@ static void intel_dp_get_config(struct intel_encoder *encoder, * load. */ DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n", - pipe_config->pipe_bpp, dev_priv->vbt.edp_bpp); - dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp; + pipe_config->pipe_bpp, dev_priv->vbt.edp.bpp); + dev_priv->vbt.edp.bpp = pipe_config->pipe_bpp; } } @@ -5111,7 +5111,7 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev, DRM_DEBUG_KMS("cur t1_t3 %d t8 %d t9 %d t10 %d t11_t12 %d\n", cur.t1_t3, cur.t8, cur.t9, cur.t10, cur.t11_t12); - vbt = dev_priv->vbt.edp_pps; + vbt = dev_priv->vbt.edp.pps; /* Upper limits from eDP 1.3 spec. Note that we use the clunky units of * our hw here, which are all in 100usec. */ diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 766ba566fef1..5d2b2575de33 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -924,7 +924,7 @@ void intel_lvds_init(struct drm_device *dev) if (HAS_PCH_SPLIT(dev)) { if ((lvds & LVDS_DETECTED) == 0) return; - if (dev_priv->vbt.edp_support) { + if (dev_priv->vbt.edp.support) { DRM_DEBUG_KMS("disable LVDS for eDP support\n"); return; } -- cgit v1.2.3 From 06411f08b3f3a55f621d73356d0326f471978f18 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 24 Mar 2016 17:50:21 +0200 Subject: drm/i915: move edp low vswing config to vbt data Move all data initialized from VBT under dev_priv->vbt. No functional changes. Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1458834623-8734-3-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 3 +-- drivers/gpu/drm/i915/intel_bios.c | 4 ++-- drivers/gpu/drm/i915/intel_ddi.c | 4 ++-- drivers/gpu/drm/i915/intel_dp.c | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index fe8021ecb254..ad6f69ef95d5 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1451,6 +1451,7 @@ struct intel_vbt_data { int lanes; int preemphasis; int vswing; + bool low_vswing; bool initialized; bool support; int bpp; @@ -1963,8 +1964,6 @@ struct drm_i915_private { struct intel_context *kernel_context; - bool edp_low_vswing; - /* perform PHY state sanity checks? */ bool chv_phy_assert[2]; diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 61eb7a6bb8f0..3af8a4a2e145 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -647,10 +647,10 @@ parse_edp(struct drm_i915_private *dev_priv, const struct bdb_header *bdb) /* Don't read from VBT if module parameter has valid value*/ if (i915.edp_vswing) { - dev_priv->edp_low_vswing = i915.edp_vswing == 1; + dev_priv->vbt.edp.low_vswing = i915.edp_vswing == 1; } else { vswing = (edp->edp_vswing_preemph >> (panel_type * 4)) & 0xF; - dev_priv->edp_low_vswing = vswing == 0; + dev_priv->vbt.edp.low_vswing = vswing == 0; } } } diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 50e4978359a4..1e083853c70d 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -360,7 +360,7 @@ skl_get_buf_trans_dp(struct drm_i915_private *dev_priv, int *n_entries) static const struct ddi_buf_trans * skl_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries) { - if (dev_priv->edp_low_vswing) { + if (dev_priv->vbt.edp.low_vswing) { if (IS_SKL_ULX(dev_priv) || IS_KBL_ULX(dev_priv)) { *n_entries = ARRAY_SIZE(skl_y_ddi_translations_edp); return skl_y_ddi_translations_edp; @@ -1431,7 +1431,7 @@ static void bxt_ddi_vswing_sequence(struct drm_i915_private *dev_priv, u32 n_entries, i; uint32_t val; - if (type == INTEL_OUTPUT_EDP && dev_priv->edp_low_vswing) { + if (type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp.low_vswing) { n_entries = ARRAY_SIZE(bxt_ddi_translations_edp); ddi_translations = bxt_ddi_translations_edp; } else if (type == INTEL_OUTPUT_DISPLAYPORT diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 55faad13174d..3bdd8ba59b8c 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3157,7 +3157,7 @@ intel_dp_voltage_max(struct intel_dp *intel_dp) if (IS_BROXTON(dev)) return DP_TRAIN_VOLTAGE_SWING_LEVEL_3; else if (INTEL_INFO(dev)->gen >= 9) { - if (dev_priv->edp_low_vswing && port == PORT_A) + if (dev_priv->vbt.edp.low_vswing && port == PORT_A) return DP_TRAIN_VOLTAGE_SWING_LEVEL_3; return DP_TRAIN_VOLTAGE_SWING_LEVEL_2; } else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) -- cgit v1.2.3 From 9d6c875db4ada9f91e1643b5a72d74bea043d67e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 24 Mar 2016 17:50:22 +0200 Subject: drm/i915: move sdvo mappings to vbt data Move all data initialized from VBT under dev_priv->vbt. No functional changes. Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1458834623-8734-4-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 3 +-- drivers/gpu/drm/i915/intel_bios.c | 2 +- drivers/gpu/drm/i915/intel_sdvo.c | 16 ++++++++-------- 3 files changed, 10 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ad6f69ef95d5..bf867e28731d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1491,6 +1491,7 @@ struct intel_vbt_data { union child_device_config *child_dev; struct ddi_vbt_port_info ddi_port_info[I915_MAX_PORTS]; + struct sdvo_device_mapping sdvo_mappings[2]; }; enum intel_ddb_partitioning { @@ -1823,8 +1824,6 @@ struct drm_i915_private { /* Kernel Modesetting */ - struct sdvo_device_mapping sdvo_mappings[2]; - struct drm_crtc *plane_to_crtc_mapping[I915_MAX_PIPES]; struct drm_crtc *pipe_to_crtc_mapping[I915_MAX_PIPES]; wait_queue_head_t pending_flip_queue; diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 3af8a4a2e145..407fb7a12a49 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -482,7 +482,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, child->slave_addr, (child->dvo_port == DEVICE_PORT_DVOB) ? "SDVOB" : "SDVOC"); - p_mapping = &(dev_priv->sdvo_mappings[child->dvo_port - 1]); + p_mapping = &dev_priv->vbt.sdvo_mappings[child->dvo_port - 1]; if (!p_mapping->initialized) { p_mapping->dvo_port = child->dvo_port; p_mapping->slave_addr = child->slave_addr; diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index fae64bc93c1b..2128fae5687d 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -2260,9 +2260,9 @@ intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv, struct sdvo_device_mapping *mapping; if (sdvo->port == PORT_B) - mapping = &(dev_priv->sdvo_mappings[0]); + mapping = &dev_priv->vbt.sdvo_mappings[0]; else - mapping = &(dev_priv->sdvo_mappings[1]); + mapping = &dev_priv->vbt.sdvo_mappings[1]; if (mapping->initialized) sdvo->ddc_bus = 1 << ((mapping->ddc_pin & 0xf0) >> 4); @@ -2278,9 +2278,9 @@ intel_sdvo_select_i2c_bus(struct drm_i915_private *dev_priv, u8 pin; if (sdvo->port == PORT_B) - mapping = &dev_priv->sdvo_mappings[0]; + mapping = &dev_priv->vbt.sdvo_mappings[0]; else - mapping = &dev_priv->sdvo_mappings[1]; + mapping = &dev_priv->vbt.sdvo_mappings[1]; if (mapping->initialized && intel_gmbus_is_valid_pin(dev_priv, mapping->i2c_pin)) @@ -2316,11 +2316,11 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, struct intel_sdvo *sdvo) struct sdvo_device_mapping *my_mapping, *other_mapping; if (sdvo->port == PORT_B) { - my_mapping = &dev_priv->sdvo_mappings[0]; - other_mapping = &dev_priv->sdvo_mappings[1]; + my_mapping = &dev_priv->vbt.sdvo_mappings[0]; + other_mapping = &dev_priv->vbt.sdvo_mappings[1]; } else { - my_mapping = &dev_priv->sdvo_mappings[1]; - other_mapping = &dev_priv->sdvo_mappings[0]; + my_mapping = &dev_priv->vbt.sdvo_mappings[1]; + other_mapping = &dev_priv->vbt.sdvo_mappings[0]; } /* If the BIOS described our SDVO device, take advantage of it. */ -- cgit v1.2.3 From 583349896482ed1d6af3cd75b2a15bb334df2777 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 24 Mar 2016 17:50:23 +0200 Subject: drm/i915: remove unused dev_priv->render_reclock_avail Set from VBT, but never used. Good riddance. Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1458834623-8734-5-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 3 --- drivers/gpu/drm/i915/intel_bios.c | 3 --- 2 files changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index bf867e28731d..0906dfd7b1a9 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1844,9 +1844,6 @@ struct drm_i915_private { struct i915_workarounds workarounds; - /* Reclocking support */ - bool render_reclock_avail; - struct i915_frontbuffer_tracking fb_tracking; u16 orig_clock; diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 407fb7a12a49..9c406b0f4173 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -529,9 +529,6 @@ parse_driver_features(struct drm_i915_private *dev_priv, if (driver->lvds_config == BDB_DRIVER_FEATURE_EDP) dev_priv->vbt.edp.support = 1; - if (driver->dual_frequency) - dev_priv->render_reclock_avail = true; - DRM_DEBUG_KMS("DRRS State Enabled:%d\n", driver->drrs_enabled); /* * If DRRS is not supported, drrs_type has to be set to 0. -- cgit v1.2.3 From 222b90943446e36d44395917b1be28732cbdab08 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 29 Mar 2016 14:14:25 +0200 Subject: drm/atmel: Fixup drm_connector_/unplug/unregister/_all Accidentally fell through the cracks in commit 6c87e5c3ec6db052f3744804a517b6fb003906e1 Author: Alexey Brodkin Date: Wed Mar 23 11:42:54 2016 +0300 drm: Rename drm_connector_unplug_all() to drm_connector_unregister_all() despite that Boris acked that patch. Cc: Boris Brezillon Cc: Alexey Brodkin Acked-by: Boris Brezillon Reported-by: kbuild test robot Signed-off-by: Daniel Vetter --- drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c index 3d8d16402d07..8ab4318e57a1 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c @@ -615,7 +615,7 @@ err: static void atmel_hlcdc_dc_connector_unplug_all(struct drm_device *dev) { mutex_lock(&dev->mode_config.mutex); - drm_connector_unplug_all(dev); + drm_connector_unregister_all(dev); mutex_unlock(&dev->mode_config.mutex); } -- cgit v1.2.3 From 00411b7b1e3ec477b75bb83ccd417c7609832db6 Mon Sep 17 00:00:00 2001 From: Gabriel Somlo Date: Mon, 22 Feb 2016 16:18:18 -0500 Subject: firmware: fw_cfg register offsets on supported architectures only Refrain from defining default fw_cfg register offsets on unsupported architectures -- throw an error instead. If QEMU were to add fw_cfg support on additional architectures, we should add them to the FW_CFG_SYSFS depends statement in drivers/firmware/Kconfig, and provide default values for register offsets in drivers/firmware/qemu_fw_cfg.c at that time. Suggested-by: Michael S. Tsirkin Signed-off-by: Gabriel Somlo Acked-by: Michael S. Tsirkin Signed-off-by: Greg Kroah-Hartman --- drivers/firmware/qemu_fw_cfg.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c index fedbff55a7f3..7bba76c0206c 100644 --- a/drivers/firmware/qemu_fw_cfg.c +++ b/drivers/firmware/qemu_fw_cfg.c @@ -109,9 +109,7 @@ static void fw_cfg_io_cleanup(void) # define FW_CFG_CTRL_OFF 0x00 # define FW_CFG_DATA_OFF 0x01 # else -# warning "QEMU FW_CFG may not be available on this architecture!" -# define FW_CFG_CTRL_OFF 0x00 -# define FW_CFG_DATA_OFF 0x01 +# error "QEMU FW_CFG not available on this architecture!" # endif #endif -- cgit v1.2.3 From b3c1be1b789cca6d3e39c950dfed690f0511fe76 Mon Sep 17 00:00:00 2001 From: William Breathitt Gray Date: Fri, 22 Jan 2016 11:28:07 -0500 Subject: base: isa: Remove X86_32 dependency Many motherboards utilize a LPC to ISA bridge in order to decode ISA-style port-mapped I/O addresses. This is particularly true for embedded motherboards supporting the PC/104 bus (a bus specification derived from ISA). These motherboards are now commonly running 64-bit x86 processors. The X86_32 dependency should be removed from the ISA bus configuration option in order to support these newer motherboards. A new config option, CONFIG_ISA_BUS, is introduced to allow for the compilation of the ISA bus driver independent of the CONFIG_ISA option. Devices which communicate via ISA-compatible buses can now be supported independent of the dependencies of the CONFIG_ISA option. Signed-off-by: William Breathitt Gray Reviewed-by: Thomas Gleixner Signed-off-by: Greg Kroah-Hartman --- arch/x86/Kconfig | 6 ++++++ drivers/base/Makefile | 2 +- include/linux/isa.h | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 2dc18605831f..a5977986f38b 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -2472,10 +2472,16 @@ config ISA_DMA_API Enables ISA-style DMA support for devices requiring such controllers. If unsure, say Y. +config ISA_BUS + bool "ISA bus support" + help + Enables ISA bus support for devices requiring such controllers. + if X86_32 config ISA bool "ISA support" + depends on ISA_BUS ---help--- Find out whether you have ISA slots on your motherboard. ISA is the name of a bus system, i.e. the way the CPU talks to the other stuff diff --git a/drivers/base/Makefile b/drivers/base/Makefile index 6b2a84e7f2be..4ebfb81cc7e9 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile @@ -10,7 +10,7 @@ obj-$(CONFIG_DMA_CMA) += dma-contiguous.o obj-y += power/ obj-$(CONFIG_HAS_DMA) += dma-mapping.o obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o -obj-$(CONFIG_ISA) += isa.o +obj-$(CONFIG_ISA_BUS) += isa.o obj-$(CONFIG_FW_LOADER) += firmware_class.o obj-$(CONFIG_NUMA) += node.o obj-$(CONFIG_MEMORY_HOTPLUG_SPARSE) += memory.o diff --git a/include/linux/isa.h b/include/linux/isa.h index b0270e3814c8..2a02862775eb 100644 --- a/include/linux/isa.h +++ b/include/linux/isa.h @@ -22,7 +22,7 @@ struct isa_driver { #define to_isa_driver(x) container_of((x), struct isa_driver, driver) -#ifdef CONFIG_ISA +#ifdef CONFIG_ISA_BUS int isa_register_driver(struct isa_driver *, unsigned int); void isa_unregister_driver(struct isa_driver *); #else -- cgit v1.2.3 From 997e518821ea0565bb92c5feba43c24c46be933d Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Sat, 26 Mar 2016 15:40:45 -0400 Subject: staging: lustre: libcfs: limit scope of libcfs_crypto.h Remove from and only include it into the places where it is actually needed. This works out to be the same places as , so put it there. Signed-off-by: Andreas Dilger Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5053 Reviewed-on: http://review.whamcloud.com/9990 Reviewed-by: Bob Glossman Reviewed-by: James Simmons Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/include/linux/libcfs/libcfs.h | 1 - drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c | 1 + drivers/staging/lustre/lustre/include/obd_cksum.h | 1 + 3 files changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs.h b/drivers/staging/lustre/include/linux/libcfs/libcfs.h index 6a8e0d0d61bf..d2e43617b0a1 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs.h @@ -96,7 +96,6 @@ void cfs_get_random_bytes(void *buf, int size); #include "libcfs_workitem.h" #include "libcfs_hash.h" #include "libcfs_fail.h" -#include "libcfs_crypto.h" struct libcfs_ioctl_handler { struct list_head item; diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c index 8c9377ed850c..d4cb260dbcf7 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c @@ -30,6 +30,7 @@ #include #include #include "../../../include/linux/libcfs/libcfs.h" +#include "../../../include/linux/libcfs/libcfs_crypto.h" #include "linux-crypto.h" /** * Array of hash algorithm speed in MByte per second diff --git a/drivers/staging/lustre/lustre/include/obd_cksum.h b/drivers/staging/lustre/lustre/include/obd_cksum.h index 637fa22110a4..f6c18df906a8 100644 --- a/drivers/staging/lustre/lustre/include/obd_cksum.h +++ b/drivers/staging/lustre/lustre/include/obd_cksum.h @@ -35,6 +35,7 @@ #ifndef __OBD_CKSUM #define __OBD_CKSUM #include "../../include/linux/libcfs/libcfs.h" +#include "../../include/linux/libcfs/libcfs_crypto.h" #include "lustre/lustre_idl.h" static inline unsigned char cksum_obd2cfs(enum cksum_type cksum_type) -- cgit v1.2.3 From 020b02154d79e1e01f846da7a6beab59fd7c7840 Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Sat, 26 Mar 2016 15:40:46 -0400 Subject: staging: lustre: libcfs: add documentation for cfs_crypto_hash_*() Add comment blocks for cfs_crypto_hash_*() in linux-crypto.c and libcfs_crypto.h. Delete obsolete comment about shash handling in cfs_crypto_hash_alloc(). Signed-off-by: Andreas Dilger Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5053 Reviewed-on: http://review.whamcloud.com/9990 Reviewed-by: Bob Glossman Reviewed-by: James Simmons Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- .../lustre/include/linux/libcfs/libcfs_crypto.h | 101 ++++---------- .../lustre/lnet/libcfs/linux/linux-crypto.c | 153 +++++++++++++++++++-- 2 files changed, 174 insertions(+), 80 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_crypto.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_crypto.h index e8663697e7a6..518241669ac8 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_crypto.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_crypto.h @@ -61,7 +61,14 @@ static struct cfs_crypto_hash_type hash_types[] = { [CFS_HASH_ALG_SHA512] = { "sha512", 0, 64 }, }; -/** Return pointer to type of hash for valid hash algorithm identifier */ +/** + * Return hash algorithm information for the specified algorithm identifier + * + * Hash information includes algorithm name, initial seed, hash size. + * + * \retval cfs_crypto_hash_type for valid ID (CFS_HASH_ALG_*) + * \retval NULL for unknown algorithm identifier + */ static inline const struct cfs_crypto_hash_type * cfs_crypto_hash_type(unsigned char hash_alg) { @@ -75,7 +82,14 @@ static inline const struct cfs_crypto_hash_type * return NULL; } -/** Return hash name for valid hash algorithm identifier or "unknown" */ +/** + * Return hash name for hash algorithm identifier + * + * \param[in] hash_alg hash alrgorithm id (CFS_HASH_ALG_*) + * + * \retval string name of known hash algorithm + * \retval "unknown" if hash algorithm is unknown + */ static inline const char *cfs_crypto_hash_name(unsigned char hash_alg) { const struct cfs_crypto_hash_type *ht; @@ -86,7 +100,14 @@ static inline const char *cfs_crypto_hash_name(unsigned char hash_alg) return "unknown"; } -/** Return digest size for valid algorithm identifier or 0 */ +/** + * Return digest size for hash algorithm type + * + * \param[in] hash_alg hash alrgorithm id (CFS_HASH_ALG_*) + * + * \retval hash algorithm digest size in bytes + * \retval 0 if hash algorithm type is unknown + */ static inline int cfs_crypto_hash_digestsize(unsigned char hash_alg) { const struct cfs_crypto_hash_type *ht; @@ -97,7 +118,12 @@ static inline int cfs_crypto_hash_digestsize(unsigned char hash_alg) return 0; } -/** Return hash identifier for valid hash algorithm name or 0xFF */ +/** + * Find hash algorithm ID for the specified algorithm name + * + * \retval hash algorithm ID for valid ID (CFS_HASH_ALG_*) + * \retval CFS_HASH_ALG_UNKNOWN for unknown algorithm name + */ static inline unsigned char cfs_crypto_hash_alg(const char *algname) { unsigned char i; @@ -108,24 +134,6 @@ static inline unsigned char cfs_crypto_hash_alg(const char *algname) return (i == CFS_HASH_ALG_MAX ? 0xFF : i); } -/** Calculate hash digest for buffer. - * @param alg id of hash algorithm - * @param buf buffer of data - * @param buf_len buffer len - * @param key initial value for algorithm, if it is NULL, - * default initial value should be used. - * @param key_len len of initial value - * @param hash [out] pointer to hash, if it is NULL, hash_len is - * set to valid digest size in bytes, retval -ENOSPC. - * @param hash_len [in,out] size of hash buffer - * @returns status of operation - * @retval -EINVAL if buf, buf_len, hash_len or alg_id is invalid - * @retval -ENODEV if this algorithm is unsupported - * @retval -ENOSPC if pointer to hash is NULL, or hash_len less than - * digest size - * @retval 0 for success - * @retval < 0 other errors from lower layers. - */ int cfs_crypto_hash_digest(unsigned char alg, const void *buf, unsigned int buf_len, unsigned char *key, unsigned int key_len, @@ -134,66 +142,17 @@ int cfs_crypto_hash_digest(unsigned char alg, /* cfs crypto hash descriptor */ struct cfs_crypto_hash_desc; -/** Allocate and initialize descriptor for hash algorithm. - * @param alg algorithm id - * @param key initial value for algorithm, if it is NULL, - * default initial value should be used. - * @param key_len len of initial value - * @returns pointer to descriptor of hash instance - * @retval ERR_PTR(error) when errors occurred. - */ struct cfs_crypto_hash_desc* cfs_crypto_hash_init(unsigned char alg, unsigned char *key, unsigned int key_len); - -/** Update digest by part of data. - * @param desc hash descriptor - * @param page data page - * @param offset data offset - * @param len data len - * @returns status of operation - * @retval 0 for success. - */ int cfs_crypto_hash_update_page(struct cfs_crypto_hash_desc *desc, struct page *page, unsigned int offset, unsigned int len); - -/** Update digest by part of data. - * @param desc hash descriptor - * @param buf pointer to data buffer - * @param buf_len size of data at buffer - * @returns status of operation - * @retval 0 for success. - */ int cfs_crypto_hash_update(struct cfs_crypto_hash_desc *desc, const void *buf, unsigned int buf_len); - -/** Finalize hash calculation, copy hash digest to buffer, destroy hash - * descriptor. - * @param desc hash descriptor - * @param hash buffer pointer to store hash digest - * @param hash_len pointer to hash buffer size, if NULL - * destroy hash descriptor - * @returns status of operation - * @retval -ENOSPC if hash is NULL, or *hash_len less than - * digest size - * @retval 0 for success - * @retval < 0 other errors from lower layers. - */ int cfs_crypto_hash_final(struct cfs_crypto_hash_desc *desc, unsigned char *hash, unsigned int *hash_len); -/** - * Register crypto hash algorithms - */ int cfs_crypto_register(void); - -/** - * Unregister - */ void cfs_crypto_unregister(void); - -/** Return hash speed in Mbytes per second for valid hash algorithm - * identifier. If test was unsuccessful -1 would be returned. - */ int cfs_crypto_hash_speed(unsigned char hash_alg); #endif diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c index d4cb260dbcf7..8960c3aca10b 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c @@ -32,11 +32,31 @@ #include "../../../include/linux/libcfs/libcfs.h" #include "../../../include/linux/libcfs/libcfs_crypto.h" #include "linux-crypto.h" + /** - * Array of hash algorithm speed in MByte per second + * Array of hash algorithm speed in MByte per second */ static int cfs_crypto_hash_speeds[CFS_HASH_ALG_MAX]; +/** + * Initialize the state descriptor for the specified hash algorithm. + * + * An internal routine to allocate the hash-specific state in \a hdesc for + * use with cfs_crypto_hash_digest() to compute the hash of a single message, + * though possibly in multiple chunks. The descriptor internal state should + * be freed with cfs_crypto_hash_final(). + * + * \param[in] hash_alg hash algorithm id (CFS_HASH_ALG_*) + * \param[out] type pointer to the hash description in hash_types[] + * array + * \param[in,out] hdesc hash state descriptor to be initialized + * \param[in] key initial hash value/state, NULL to use default + * value + * \param[in] key_len length of \a key + * + * \retval 0 on success + * \retval negative errno on failure + */ static int cfs_crypto_hash_alloc(unsigned char alg_id, const struct cfs_crypto_hash_type **type, struct ahash_request **req, @@ -71,12 +91,6 @@ static int cfs_crypto_hash_alloc(unsigned char alg_id, ahash_request_set_callback(*req, 0, NULL, NULL); - /** Shash have different logic for initialization then digest - * shash: crypto_hash_setkey, crypto_hash_init - * digest: crypto_digest_init, crypto_digest_setkey - * Skip this function for digest, because we use shash logic at - * cfs_crypto_hash_alloc. - */ if (key) err = crypto_ahash_setkey(tfm, key, key_len); else if ((*type)->cht_key != 0) @@ -101,6 +115,32 @@ static int cfs_crypto_hash_alloc(unsigned char alg_id, return err; } +/** + * Calculate hash digest for the passed buffer. + * + * This should be used when computing the hash on a single contiguous buffer. + * It combines the hash initialization, computation, and cleanup. + * + * \param[in] hash_alg id of hash algorithm (CFS_HASH_ALG_*) + * \param[in] buf data buffer on which to compute hash + * \param[in] buf_len length of \a buf in bytes + * \param[in] key initial value/state for algorithm, + * if \a key = NULL use default initial value + * \param[in] key_len length of \a key in bytes + * \param[out] hash pointer to computed hash value, + * if \a hash = NULL then \a hash_len is to digest + * size in bytes, retval -ENOSPC + * \param[in,out] hash_len size of \a hash buffer + * + * \retval -EINVAL \a buf, \a buf_len, \a hash_len, + * \a alg_id invalid + * \retval -ENOENT \a hash_alg is unsupported + * \retval -ENOSPC \a hash is NULL, or \a hash_len less than + * digest size + * \retval 0 for success + * \retval negative errno for other errors from lower + * layers. + */ int cfs_crypto_hash_digest(unsigned char alg_id, const void *buf, unsigned int buf_len, unsigned char *key, unsigned int key_len, @@ -135,6 +175,23 @@ int cfs_crypto_hash_digest(unsigned char alg_id, } EXPORT_SYMBOL(cfs_crypto_hash_digest); +/** + * Allocate and initialize desriptor for hash algorithm. + * + * This should be used to initialize a hash descriptor for multiple calls + * to a single hash function when computing the hash across multiple + * separate buffers or pages using cfs_crypto_hash_update{,_page}(). + * + * The hash descriptor should be freed with cfs_crypto_hash_final(). + * + * \param[in] hash_alg algorithm id (CFS_HASH_ALG_*) + * \param[in] key initial value/state for algorithm, if \a key = NULL + * use default initial value + * \param[in] key_len length of \a key in bytes + * + * \retval pointer to descriptor of hash instance + * \retval ERR_PTR(errno) in case of error + */ struct cfs_crypto_hash_desc * cfs_crypto_hash_init(unsigned char alg_id, unsigned char *key, unsigned int key_len) @@ -151,6 +208,17 @@ struct cfs_crypto_hash_desc * } EXPORT_SYMBOL(cfs_crypto_hash_init); +/** + * Update hash digest computed on data within the given \a page + * + * \param[in] hdesc hash state descriptor + * \param[in] page data page on which to compute the hash + * \param[in] offset offset within \a page at which to start hash + * \param[in] len length of data on which to compute hash + * + * \retval 0 for success + * \retval negative errno on failure + */ int cfs_crypto_hash_update_page(struct cfs_crypto_hash_desc *hdesc, struct page *page, unsigned int offset, unsigned int len) @@ -166,6 +234,16 @@ int cfs_crypto_hash_update_page(struct cfs_crypto_hash_desc *hdesc, } EXPORT_SYMBOL(cfs_crypto_hash_update_page); +/** + * Update hash digest computed on the specified data + * + * \param[in] hdesc hash state descriptor + * \param[in] buf data buffer on which to compute the hash + * \param[in] buf_len length of \buf on which to compute hash + * + * \retval 0 for success + * \retval negative errno on failure + */ int cfs_crypto_hash_update(struct cfs_crypto_hash_desc *hdesc, const void *buf, unsigned int buf_len) { @@ -179,7 +257,18 @@ int cfs_crypto_hash_update(struct cfs_crypto_hash_desc *hdesc, } EXPORT_SYMBOL(cfs_crypto_hash_update); -/* If hash_len pointer is NULL - destroy descriptor. */ +/** + * Finish hash calculation, copy hash digest to buffer, clean up hash descriptor + * + * \param[in] hdesc hash descriptor + * \param[out] hash pointer to hash buffer to store hash digest + * \param[in,out] hash_len pointer to hash buffer size, if \a hdesc = NULL + * only free \a hdesc instead of computing the hash + * + * \retval -ENOSPC if \a hash = NULL, or \a hash_len < digest size + * \retval 0 for success + * \retval negative errno for other errors from lower layers + */ int cfs_crypto_hash_final(struct cfs_crypto_hash_desc *hdesc, unsigned char *hash, unsigned int *hash_len) { @@ -209,6 +298,17 @@ int cfs_crypto_hash_final(struct cfs_crypto_hash_desc *hdesc, } EXPORT_SYMBOL(cfs_crypto_hash_final); +/** + * Compute the speed of specified hash function + * + * Run a speed test on the given hash algorithm on buffer of the given size. + * The speed is stored internally in the cfs_crypto_hash_speeds[] array, and + * is available through the cfs_crypto_hash_speed() function. + * + * \param[in] hash_alg hash algorithm id (CFS_HASH_ALG_*) + * \param[in] buf data buffer on which to compute the hash + * \param[in] buf_len length of \buf on which to compute hash + */ static void cfs_crypto_performance_test(unsigned char alg_id, const unsigned char *buf, unsigned int buf_len) @@ -243,6 +343,18 @@ static void cfs_crypto_performance_test(unsigned char alg_id, cfs_crypto_hash_name(alg_id), cfs_crypto_hash_speeds[alg_id]); } +/** + * hash speed in Mbytes per second for valid hash algorithm + * + * Return the performance of the specified \a hash_alg that was previously + * computed using cfs_crypto_performance_test(). + * + * \param[in] hash_alg hash algorithm id (CFS_HASH_ALG_*) + * + * \retval positive speed of the hash function in MB/s + * \retval -ENOENT if \a hash_alg is unsupported + * \retval negative errno if \a hash_alg speed is unavailable + */ int cfs_crypto_hash_speed(unsigned char hash_alg) { if (hash_alg < CFS_HASH_ALG_MAX) @@ -252,7 +364,22 @@ int cfs_crypto_hash_speed(unsigned char hash_alg) EXPORT_SYMBOL(cfs_crypto_hash_speed); /** - * Do performance test for all hash algorithms. + * Run the performance test for all hash algorithms. + * + * Run the cfs_crypto_performance_test() benchmark for all of the available + * hash functions using a 1MB buffer size. This is a reasonable buffer size + * for Lustre RPCs, even if the actual RPC size is larger or smaller. + * + * Since the setup cost and computation speed of various hash algorithms is + * a function of the buffer size (and possibly internal contention of offload + * engines), this speed only represents an estimate of the actual speed under + * actual usage, but is reasonable for comparing available algorithms. + * + * The actual speeds are available via cfs_crypto_hash_speed() for later + * comparison. + * + * \retval 0 on success + * \retval -ENOMEM if no memory is available for test buffer */ static int cfs_crypto_test_hashes(void) { @@ -280,6 +407,11 @@ static int cfs_crypto_test_hashes(void) static int adler32; +/** + * Register available hash functions + * + * \retval 0 + */ int cfs_crypto_register(void) { request_module("crc32c"); @@ -291,6 +423,9 @@ int cfs_crypto_register(void) return 0; } +/** + * Unregister previously registered hash functions + */ void cfs_crypto_unregister(void) { if (adler32 == 0) -- cgit v1.2.3 From 4d60ffa12c887e1944d5582d79cc9d7f3593eb00 Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Sat, 26 Mar 2016 15:40:47 -0400 Subject: staging: lustre: libcfs: rename some variables for crypto handling For the crypto algorthim type use the same name hash_alg everywhere. Signed-off-by: Andreas Dilger Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5053 Reviewed-on: http://review.whamcloud.com/9990 Reviewed-by: Bob Glossman Reviewed-by: James Simmons Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- .../lustre/include/linux/libcfs/libcfs_crypto.h | 4 +-- .../lustre/lnet/libcfs/linux/linux-crypto.c | 30 +++++++++++----------- 2 files changed, 17 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_crypto.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_crypto.h index 518241669ac8..0782bfb11ffa 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_crypto.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_crypto.h @@ -134,7 +134,7 @@ static inline unsigned char cfs_crypto_hash_alg(const char *algname) return (i == CFS_HASH_ALG_MAX ? 0xFF : i); } -int cfs_crypto_hash_digest(unsigned char alg, +int cfs_crypto_hash_digest(unsigned char hash_alg, const void *buf, unsigned int buf_len, unsigned char *key, unsigned int key_len, unsigned char *hash, unsigned int *hash_len); @@ -143,7 +143,7 @@ int cfs_crypto_hash_digest(unsigned char alg, struct cfs_crypto_hash_desc; struct cfs_crypto_hash_desc* - cfs_crypto_hash_init(unsigned char alg, + cfs_crypto_hash_init(unsigned char hash_alg, unsigned char *key, unsigned int key_len); int cfs_crypto_hash_update_page(struct cfs_crypto_hash_desc *desc, struct page *page, unsigned int offset, diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c index 8960c3aca10b..1a9eb77ec986 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c @@ -57,7 +57,7 @@ static int cfs_crypto_hash_speeds[CFS_HASH_ALG_MAX]; * \retval 0 on success * \retval negative errno on failure */ -static int cfs_crypto_hash_alloc(unsigned char alg_id, +static int cfs_crypto_hash_alloc(unsigned char hash_alg, const struct cfs_crypto_hash_type **type, struct ahash_request **req, unsigned char *key, @@ -66,11 +66,11 @@ static int cfs_crypto_hash_alloc(unsigned char alg_id, struct crypto_ahash *tfm; int err = 0; - *type = cfs_crypto_hash_type(alg_id); + *type = cfs_crypto_hash_type(hash_alg); if (!*type) { CWARN("Unsupported hash algorithm id = %d, max id is %d\n", - alg_id, CFS_HASH_ALG_MAX); + hash_alg, CFS_HASH_ALG_MAX); return -EINVAL; } tfm = crypto_alloc_ahash((*type)->cht_name, 0, CRYPTO_ALG_ASYNC); @@ -105,7 +105,7 @@ static int cfs_crypto_hash_alloc(unsigned char alg_id, CDEBUG(D_INFO, "Using crypto hash: %s (%s) speed %d MB/s\n", crypto_ahash_alg_name(tfm), crypto_ahash_driver_name(tfm), - cfs_crypto_hash_speeds[alg_id]); + cfs_crypto_hash_speeds[hash_alg]); err = crypto_ahash_init(*req); if (err) { @@ -133,7 +133,7 @@ static int cfs_crypto_hash_alloc(unsigned char alg_id, * \param[in,out] hash_len size of \a hash buffer * * \retval -EINVAL \a buf, \a buf_len, \a hash_len, - * \a alg_id invalid + * \a hash_alg invalid * \retval -ENOENT \a hash_alg is unsupported * \retval -ENOSPC \a hash is NULL, or \a hash_len less than * digest size @@ -141,7 +141,7 @@ static int cfs_crypto_hash_alloc(unsigned char alg_id, * \retval negative errno for other errors from lower * layers. */ -int cfs_crypto_hash_digest(unsigned char alg_id, +int cfs_crypto_hash_digest(unsigned char hash_alg, const void *buf, unsigned int buf_len, unsigned char *key, unsigned int key_len, unsigned char *hash, unsigned int *hash_len) @@ -154,7 +154,7 @@ int cfs_crypto_hash_digest(unsigned char alg_id, if (!buf || buf_len == 0 || !hash_len) return -EINVAL; - err = cfs_crypto_hash_alloc(alg_id, &type, &req, key, key_len); + err = cfs_crypto_hash_alloc(hash_alg, &type, &req, key, key_len); if (err != 0) return err; @@ -193,14 +193,14 @@ EXPORT_SYMBOL(cfs_crypto_hash_digest); * \retval ERR_PTR(errno) in case of error */ struct cfs_crypto_hash_desc * - cfs_crypto_hash_init(unsigned char alg_id, + cfs_crypto_hash_init(unsigned char hash_alg, unsigned char *key, unsigned int key_len) { struct ahash_request *req; int err; const struct cfs_crypto_hash_type *type; - err = cfs_crypto_hash_alloc(alg_id, &type, &req, key, key_len); + err = cfs_crypto_hash_alloc(hash_alg, &type, &req, key, key_len); if (err) return ERR_PTR(err); @@ -309,7 +309,7 @@ EXPORT_SYMBOL(cfs_crypto_hash_final); * \param[in] buf data buffer on which to compute the hash * \param[in] buf_len length of \buf on which to compute hash */ -static void cfs_crypto_performance_test(unsigned char alg_id, +static void cfs_crypto_performance_test(unsigned char hash_alg, const unsigned char *buf, unsigned int buf_len) { @@ -321,7 +321,7 @@ static void cfs_crypto_performance_test(unsigned char alg_id, for (start = jiffies, end = start + sec * HZ, bcount = 0; time_before(jiffies, end); bcount++) { - err = cfs_crypto_hash_digest(alg_id, buf, buf_len, NULL, 0, + err = cfs_crypto_hash_digest(hash_alg, buf, buf_len, NULL, 0, hash, &hash_len); if (err) break; @@ -329,18 +329,18 @@ static void cfs_crypto_performance_test(unsigned char alg_id, end = jiffies; if (err) { - cfs_crypto_hash_speeds[alg_id] = -1; + cfs_crypto_hash_speeds[hash_alg] = -1; CDEBUG(D_INFO, "Crypto hash algorithm %s, err = %d\n", - cfs_crypto_hash_name(alg_id), err); + cfs_crypto_hash_name(hash_alg), err); } else { unsigned long tmp; tmp = ((bcount * buf_len / jiffies_to_msecs(end - start)) * 1000) / (1024 * 1024); - cfs_crypto_hash_speeds[alg_id] = (int)tmp; + cfs_crypto_hash_speeds[hash_alg] = (int)tmp; } CDEBUG(D_INFO, "Crypto hash algorithm %s speed = %d MB/s\n", - cfs_crypto_hash_name(alg_id), cfs_crypto_hash_speeds[alg_id]); + cfs_crypto_hash_name(hash_alg), cfs_crypto_hash_speeds[hash_alg]); } /** -- cgit v1.2.3 From 24a4e1ec63ffcd87f656f507709b5f03f6a5f155 Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Sat, 26 Mar 2016 15:40:48 -0400 Subject: staging: lustre: libcfs: add new definitions for cfs_crypto api Add CFS_HASH_ALG_UNKOWN for unknown hash names instead of using "0xFF" directly. Define the max digestsize the cfs crypto api can handle. Signed-off-by: Andreas Dilger Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5053 Reviewed-on: http://review.whamcloud.com/9990 Reviewed-by: Bob Glossman Reviewed-by: James Simmons Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/include/linux/libcfs/libcfs_crypto.h | 9 +++++++-- drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_crypto.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_crypto.h index 0782bfb11ffa..921aa7cbff97 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_crypto.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_crypto.h @@ -46,7 +46,8 @@ enum cfs_crypto_hash_alg { CFS_HASH_ALG_SHA384, CFS_HASH_ALG_SHA512, CFS_HASH_ALG_CRC32C, - CFS_HASH_ALG_MAX + CFS_HASH_ALG_MAX, + CFS_HASH_ALG_UNKNOWN = 0xff }; static struct cfs_crypto_hash_type hash_types[] = { @@ -59,8 +60,12 @@ static struct cfs_crypto_hash_type hash_types[] = { [CFS_HASH_ALG_SHA256] = { "sha256", 0, 32 }, [CFS_HASH_ALG_SHA384] = { "sha384", 0, 48 }, [CFS_HASH_ALG_SHA512] = { "sha512", 0, 64 }, + [CFS_HASH_ALG_MAX] = { NULL, 0, 64 }, }; +/* Maximum size of hash_types[].cht_size */ +#define CFS_CRYPTO_HASH_DIGESTSIZE_MAX 64 + /** * Return hash algorithm information for the specified algorithm identifier * @@ -131,7 +136,7 @@ static inline unsigned char cfs_crypto_hash_alg(const char *algname) for (i = 0; i < CFS_HASH_ALG_MAX; i++) if (!strcmp(hash_types[i].cht_name, algname)) break; - return (i == CFS_HASH_ALG_MAX ? 0xFF : i); + return (i == CFS_HASH_ALG_MAX ? CFS_HASH_ALG_UNKNOWN : i); } int cfs_crypto_hash_digest(unsigned char hash_alg, diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c index 1a9eb77ec986..b4e203dacd38 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c @@ -316,8 +316,8 @@ static void cfs_crypto_performance_test(unsigned char hash_alg, unsigned long start, end; int bcount, err = 0; int sec = 1; /* do test only 1 sec */ - unsigned char hash[64]; - unsigned int hash_len = 64; + unsigned char hash[CFS_CRYPTO_HASH_DIGESTSIZE_MAX]; + unsigned int hash_len = sizeof(hash); for (start = jiffies, end = start + sec * HZ, bcount = 0; time_before(jiffies, end); bcount++) { -- cgit v1.2.3 From 56ebc2e875f1103b941163008ece8612c9e97ba4 Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Sat, 26 Mar 2016 15:40:49 -0400 Subject: staging: lustre: libcfs: small alignment change for cfs_crypto_hash_*() Change the aligment of some of the functions. Signed-off-by: Andreas Dilger Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5053 Reviewed-on: http://review.whamcloud.com/9990 Reviewed-by: Bob Glossman Reviewed-by: James Simmons Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/include/linux/libcfs/libcfs_crypto.h | 11 ++++++----- drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c | 4 ++-- 2 files changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_crypto.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_crypto.h index 921aa7cbff97..ade88944988d 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_crypto.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_crypto.h @@ -75,7 +75,7 @@ static struct cfs_crypto_hash_type hash_types[] = { * \retval NULL for unknown algorithm identifier */ static inline const struct cfs_crypto_hash_type * - cfs_crypto_hash_type(unsigned char hash_alg) +cfs_crypto_hash_type(unsigned char hash_alg) { struct cfs_crypto_hash_type *ht; @@ -95,7 +95,8 @@ static inline const struct cfs_crypto_hash_type * * \retval string name of known hash algorithm * \retval "unknown" if hash algorithm is unknown */ -static inline const char *cfs_crypto_hash_name(unsigned char hash_alg) +static inline const char * +cfs_crypto_hash_name(unsigned char hash_alg) { const struct cfs_crypto_hash_type *ht; @@ -147,9 +148,9 @@ int cfs_crypto_hash_digest(unsigned char hash_alg, /* cfs crypto hash descriptor */ struct cfs_crypto_hash_desc; -struct cfs_crypto_hash_desc* - cfs_crypto_hash_init(unsigned char hash_alg, - unsigned char *key, unsigned int key_len); +struct cfs_crypto_hash_desc * +cfs_crypto_hash_init(unsigned char hash_alg, + unsigned char *key, unsigned int key_len); int cfs_crypto_hash_update_page(struct cfs_crypto_hash_desc *desc, struct page *page, unsigned int offset, unsigned int len); diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c index b4e203dacd38..024172929b62 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c @@ -193,8 +193,8 @@ EXPORT_SYMBOL(cfs_crypto_hash_digest); * \retval ERR_PTR(errno) in case of error */ struct cfs_crypto_hash_desc * - cfs_crypto_hash_init(unsigned char hash_alg, - unsigned char *key, unsigned int key_len) +cfs_crypto_hash_init(unsigned char hash_alg, + unsigned char *key, unsigned int key_len) { struct ahash_request *req; int err; -- cgit v1.2.3 From 244cd87cc078fd18a8cbbb4db2998b95760007f6 Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Sat, 26 Mar 2016 15:40:50 -0400 Subject: staging: lustre: libcfs: start using enum cfs_crypto_hash_alg Fix the cfs_crypto_hash_* functions to take enum cfs_crypto_hash_alg as the algorithm type, instead of an unsigned char. Signed-off-by: Andreas Dilger Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5053 Reviewed-on: http://review.whamcloud.com/9990 Reviewed-by: Bob Glossman Reviewed-by: James Simmons Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- .../lustre/include/linux/libcfs/libcfs_crypto.h | 23 +++++++++++----------- .../lustre/lnet/libcfs/linux/linux-crypto.c | 10 +++++----- 2 files changed, 17 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_crypto.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_crypto.h index ade88944988d..02be7d7608a5 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_crypto.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_crypto.h @@ -75,7 +75,7 @@ static struct cfs_crypto_hash_type hash_types[] = { * \retval NULL for unknown algorithm identifier */ static inline const struct cfs_crypto_hash_type * -cfs_crypto_hash_type(unsigned char hash_alg) +cfs_crypto_hash_type(enum cfs_crypto_hash_alg hash_alg) { struct cfs_crypto_hash_type *ht; @@ -96,7 +96,7 @@ cfs_crypto_hash_type(unsigned char hash_alg) * \retval "unknown" if hash algorithm is unknown */ static inline const char * -cfs_crypto_hash_name(unsigned char hash_alg) +cfs_crypto_hash_name(enum cfs_crypto_hash_alg hash_alg) { const struct cfs_crypto_hash_type *ht; @@ -114,7 +114,7 @@ cfs_crypto_hash_name(unsigned char hash_alg) * \retval hash algorithm digest size in bytes * \retval 0 if hash algorithm type is unknown */ -static inline int cfs_crypto_hash_digestsize(unsigned char hash_alg) +static inline int cfs_crypto_hash_digestsize(enum cfs_crypto_hash_alg hash_alg) { const struct cfs_crypto_hash_type *ht; @@ -132,15 +132,16 @@ static inline int cfs_crypto_hash_digestsize(unsigned char hash_alg) */ static inline unsigned char cfs_crypto_hash_alg(const char *algname) { - unsigned char i; + enum cfs_crypto_hash_alg hash_alg; - for (i = 0; i < CFS_HASH_ALG_MAX; i++) - if (!strcmp(hash_types[i].cht_name, algname)) - break; - return (i == CFS_HASH_ALG_MAX ? CFS_HASH_ALG_UNKNOWN : i); + for (hash_alg = 0; hash_alg < CFS_HASH_ALG_MAX; hash_alg++) + if (strcmp(hash_types[hash_alg].cht_name, algname) == 0) + return hash_alg; + + return CFS_HASH_ALG_UNKNOWN; } -int cfs_crypto_hash_digest(unsigned char hash_alg, +int cfs_crypto_hash_digest(enum cfs_crypto_hash_alg hash_alg, const void *buf, unsigned int buf_len, unsigned char *key, unsigned int key_len, unsigned char *hash, unsigned int *hash_len); @@ -149,7 +150,7 @@ int cfs_crypto_hash_digest(unsigned char hash_alg, struct cfs_crypto_hash_desc; struct cfs_crypto_hash_desc * -cfs_crypto_hash_init(unsigned char hash_alg, +cfs_crypto_hash_init(enum cfs_crypto_hash_alg hash_alg, unsigned char *key, unsigned int key_len); int cfs_crypto_hash_update_page(struct cfs_crypto_hash_desc *desc, struct page *page, unsigned int offset, @@ -160,5 +161,5 @@ int cfs_crypto_hash_final(struct cfs_crypto_hash_desc *desc, unsigned char *hash, unsigned int *hash_len); int cfs_crypto_register(void); void cfs_crypto_unregister(void); -int cfs_crypto_hash_speed(unsigned char hash_alg); +int cfs_crypto_hash_speed(enum cfs_crypto_hash_alg hash_alg); #endif diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c index 024172929b62..6fe1fdde001e 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c @@ -57,7 +57,7 @@ static int cfs_crypto_hash_speeds[CFS_HASH_ALG_MAX]; * \retval 0 on success * \retval negative errno on failure */ -static int cfs_crypto_hash_alloc(unsigned char hash_alg, +static int cfs_crypto_hash_alloc(enum cfs_crypto_hash_alg hash_alg, const struct cfs_crypto_hash_type **type, struct ahash_request **req, unsigned char *key, @@ -141,7 +141,7 @@ static int cfs_crypto_hash_alloc(unsigned char hash_alg, * \retval negative errno for other errors from lower * layers. */ -int cfs_crypto_hash_digest(unsigned char hash_alg, +int cfs_crypto_hash_digest(enum cfs_crypto_hash_alg hash_alg, const void *buf, unsigned int buf_len, unsigned char *key, unsigned int key_len, unsigned char *hash, unsigned int *hash_len) @@ -193,7 +193,7 @@ EXPORT_SYMBOL(cfs_crypto_hash_digest); * \retval ERR_PTR(errno) in case of error */ struct cfs_crypto_hash_desc * -cfs_crypto_hash_init(unsigned char hash_alg, +cfs_crypto_hash_init(enum cfs_crypto_hash_alg hash_alg, unsigned char *key, unsigned int key_len) { struct ahash_request *req; @@ -309,7 +309,7 @@ EXPORT_SYMBOL(cfs_crypto_hash_final); * \param[in] buf data buffer on which to compute the hash * \param[in] buf_len length of \buf on which to compute hash */ -static void cfs_crypto_performance_test(unsigned char hash_alg, +static void cfs_crypto_performance_test(enum cfs_crypto_hash_alg hash_alg, const unsigned char *buf, unsigned int buf_len) { @@ -355,7 +355,7 @@ static void cfs_crypto_performance_test(unsigned char hash_alg, * \retval -ENOENT if \a hash_alg is unsupported * \retval negative errno if \a hash_alg speed is unavailable */ -int cfs_crypto_hash_speed(unsigned char hash_alg) +int cfs_crypto_hash_speed(enum cfs_crypto_hash_alg hash_alg) { if (hash_alg < CFS_HASH_ALG_MAX) return cfs_crypto_hash_speeds[hash_alg]; -- cgit v1.2.3 From c11e27a4ee39479b9afef86bfed8ef3f75756262 Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Sat, 26 Mar 2016 15:40:51 -0400 Subject: staging: lustre: libcfs: bug fixes for cfs_crypto_hash_final() Change cfs_crypto_hash_final() to always clean up the hash descrptor instead of not doing this in error cases. All of the callers were just calling cfs_crypto_hash_final() immediately to clean up the descriptor anyway, and the old behaviour is unlike other init/fini functions, and prone to memory leaks and other incorrect usage. The callers can call cfs_crypto_digest_size() to determine the hash size in advance if needed, and avoid complexity in cfs_crypto_hash_final(). Signed-off-by: Andreas Dilger Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5053 Reviewed-on: http://review.whamcloud.com/9990 Reviewed-by: Bob Glossman Reviewed-by: James Simmons Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- .../lustre/lnet/libcfs/linux/linux-crypto.c | 24 ++++++++++------------ drivers/staging/lustre/lustre/osc/osc_request.c | 5 +---- drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c | 12 +++++------ 3 files changed, 18 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c index 6fe1fdde001e..d5bb10fec511 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c @@ -265,8 +265,8 @@ EXPORT_SYMBOL(cfs_crypto_hash_update); * \param[in,out] hash_len pointer to hash buffer size, if \a hdesc = NULL * only free \a hdesc instead of computing the hash * - * \retval -ENOSPC if \a hash = NULL, or \a hash_len < digest size * \retval 0 for success + * \retval -EOVERFLOW if hash_len is too small for the hash digest * \retval negative errno for other errors from lower layers */ int cfs_crypto_hash_final(struct cfs_crypto_hash_desc *hdesc, @@ -276,22 +276,20 @@ int cfs_crypto_hash_final(struct cfs_crypto_hash_desc *hdesc, struct ahash_request *req = (void *)hdesc; int size = crypto_ahash_digestsize(crypto_ahash_reqtfm(req)); - if (!hash_len) { - crypto_free_ahash(crypto_ahash_reqtfm(req)); - ahash_request_free(req); - return 0; + if (!hash || !hash_len) { + err = 0; + goto free_ahash; } - if (!hash || *hash_len < size) { - *hash_len = size; - return -ENOSPC; + if (*hash_len < size) { + err = -EOVERFLOW; + goto free_ahash; } + ahash_request_set_crypt(req, NULL, hash, 0); err = crypto_ahash_final(req); - - if (err < 0) { - /* May be caller can fix error */ - return err; - } + if (!err) + *hash_len = size; +free_ahash: crypto_free_ahash(crypto_ahash_reqtfm(req)); ahash_request_free(req); return err; diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c index 74805f1ae888..ec0287feb3ce 100644 --- a/drivers/staging/lustre/lustre/osc/osc_request.c +++ b/drivers/staging/lustre/lustre/osc/osc_request.c @@ -1208,12 +1208,9 @@ static u32 osc_checksum_bulk(int nob, u32 pg_count, i++; } - bufsize = 4; + bufsize = sizeof(cksum); err = cfs_crypto_hash_final(hdesc, (unsigned char *)&cksum, &bufsize); - if (err) - cfs_crypto_hash_final(hdesc, NULL, NULL); - /* For sending we only compute the wrong checksum instead * of corrupting the data so it is still correct on a redo */ diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c b/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c index 72d5b9bf5b29..54a0c1ff7b20 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c +++ b/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c @@ -41,7 +41,6 @@ #define DEBUG_SUBSYSTEM S_SEC #include "../../include/linux/libcfs/libcfs.h" -#include #include "../include/obd.h" #include "../include/obd_cksum.h" @@ -511,7 +510,6 @@ int sptlrpc_get_bulk_checksum(struct ptlrpc_bulk_desc *desc, __u8 alg, { struct cfs_crypto_hash_desc *hdesc; int hashsize; - char hashbuf[64]; unsigned int bufsize; int i, err; @@ -532,18 +530,20 @@ int sptlrpc_get_bulk_checksum(struct ptlrpc_bulk_desc *desc, __u8 alg, desc->bd_iov[i].kiov_offset & ~CFS_PAGE_MASK, desc->bd_iov[i].kiov_len); } + if (hashsize > buflen) { + unsigned char hashbuf[CFS_CRYPTO_HASH_DIGESTSIZE_MAX]; + bufsize = sizeof(hashbuf); - err = cfs_crypto_hash_final(hdesc, (unsigned char *)hashbuf, - &bufsize); + LASSERTF(bufsize >= hashsize, "bufsize = %u < hashsize %u\n", + bufsize, hashsize); + err = cfs_crypto_hash_final(hdesc, hashbuf, &bufsize); memcpy(buf, hashbuf, buflen); } else { bufsize = buflen; err = cfs_crypto_hash_final(hdesc, buf, &bufsize); } - if (err) - cfs_crypto_hash_final(hdesc, NULL, NULL); return err; } EXPORT_SYMBOL(sptlrpc_get_bulk_checksum); -- cgit v1.2.3 From e43c658c5a97570f4c5be8e94eb2ad30d4033123 Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Sat, 26 Mar 2016 15:40:52 -0400 Subject: staging: lustre: libcfs: return proper error code for cfs_crypto_hash_speed() Return a real error code, -ENOENT, instead of a -1. Signed-off-by: Andreas Dilger Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5053 Reviewed-on: http://review.whamcloud.com/9990 Reviewed-by: Bob Glossman Reviewed-by: James Simmons Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c index d5bb10fec511..90d6e082aead 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c @@ -357,7 +357,7 @@ int cfs_crypto_hash_speed(enum cfs_crypto_hash_alg hash_alg) { if (hash_alg < CFS_HASH_ALG_MAX) return cfs_crypto_hash_speeds[hash_alg]; - return -1; + return -ENOENT; } EXPORT_SYMBOL(cfs_crypto_hash_speed); -- cgit v1.2.3 From 6ba3f37825982cf71e55ef87aadbffe8f4345a05 Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Sat, 26 Mar 2016 15:40:53 -0400 Subject: staging: lustre: libcfs: allocate memory in cfs_crypto_performance_test() Move memory allocation from cfs_crypto_test_hashes() into the function cfs_crypto_performance_test(). Signed-off-by: Andreas Dilger Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5053 Reviewed-on: http://review.whamcloud.com/9990 Reviewed-by: Bob Glossman Reviewed-by: James Simmons Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- .../lustre/lnet/libcfs/linux/linux-crypto.c | 40 ++++++++++------------ 1 file changed, 19 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c index 90d6e082aead..4857a11c0dd6 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c @@ -307,16 +307,27 @@ EXPORT_SYMBOL(cfs_crypto_hash_final); * \param[in] buf data buffer on which to compute the hash * \param[in] buf_len length of \buf on which to compute hash */ -static void cfs_crypto_performance_test(enum cfs_crypto_hash_alg hash_alg, - const unsigned char *buf, - unsigned int buf_len) +static void cfs_crypto_performance_test(enum cfs_crypto_hash_alg hash_alg) { + int buf_len = max(PAGE_SIZE, 1048576UL); + void *buf; unsigned long start, end; int bcount, err = 0; int sec = 1; /* do test only 1 sec */ + struct page *page; unsigned char hash[CFS_CRYPTO_HASH_DIGESTSIZE_MAX]; unsigned int hash_len = sizeof(hash); + page = alloc_page(GFP_KERNEL); + if (!page) { + err = -ENOMEM; + goto out_err; + } + + buf = kmap(page); + memset(buf, 0xAD, PAGE_SIZE); + kunmap(page); + for (start = jiffies, end = start + sec * HZ, bcount = 0; time_before(jiffies, end); bcount++) { err = cfs_crypto_hash_digest(hash_alg, buf, buf_len, NULL, 0, @@ -325,7 +336,8 @@ static void cfs_crypto_performance_test(enum cfs_crypto_hash_alg hash_alg, break; } end = jiffies; - + __free_page(page); +out_err: if (err) { cfs_crypto_hash_speeds[hash_alg] = -1; CDEBUG(D_INFO, "Crypto hash algorithm %s, err = %d\n", @@ -381,25 +393,11 @@ EXPORT_SYMBOL(cfs_crypto_hash_speed); */ static int cfs_crypto_test_hashes(void) { - unsigned char i; - unsigned char *data; - unsigned int j; - /* Data block size for testing hash. Maximum - * kmalloc size for 2.6.18 kernel is 128K - */ - unsigned int data_len = 1 * 128 * 1024; - - data = kmalloc(data_len, 0); - if (!data) - return -ENOMEM; - - for (j = 0; j < data_len; j++) - data[j] = j & 0xff; + enum cfs_crypto_hash_alg hash_alg; - for (i = 0; i < CFS_HASH_ALG_MAX; i++) - cfs_crypto_performance_test(i, data, data_len); + for (hash_alg = 0; hash_alg < CFS_HASH_ALG_MAX; hash_alg++) + cfs_crypto_performance_test(hash_alg); - kfree(data); return 0; } -- cgit v1.2.3 From 8260d4e2c72b6fc02ab0bae45f3ed0f259092368 Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Sat, 26 Mar 2016 15:40:54 -0400 Subject: staging: lustre: libcfs: print crypto performance result only on success Only print info about the crypto performance when no error is encounter. Signed-off-by: Andreas Dilger Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5053 Reviewed-on: http://review.whamcloud.com/9990 Reviewed-by: Bob Glossman Reviewed-by: James Simmons Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c index 4857a11c0dd6..3d74fd1937c8 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c @@ -348,9 +348,10 @@ out_err: tmp = ((bcount * buf_len / jiffies_to_msecs(end - start)) * 1000) / (1024 * 1024); cfs_crypto_hash_speeds[hash_alg] = (int)tmp; + CDEBUG(D_CONFIG, "Crypto hash algorithm %s speed = %d MB/s\n", + cfs_crypto_hash_name(hash_alg), + cfs_crypto_hash_speeds[hash_alg]); } - CDEBUG(D_INFO, "Crypto hash algorithm %s speed = %d MB/s\n", - cfs_crypto_hash_name(hash_alg), cfs_crypto_hash_speeds[hash_alg]); } /** -- cgit v1.2.3 From 78675cb1abec09f1c93f53457b4f7859273d8d0a Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Sat, 26 Mar 2016 15:40:55 -0400 Subject: staging: lustre: libcfs: improve reporting error for crypto performance Set cfs_crypto_hash_speeds[X] result to the actual error instead of -1. Make the error message more clear and informative. Signed-off-by: Andreas Dilger Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5053 Reviewed-on: http://review.whamcloud.com/9990 Reviewed-by: Bob Glossman Reviewed-by: James Simmons Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c index 3d74fd1937c8..aec79165b5c7 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c @@ -339,8 +339,8 @@ static void cfs_crypto_performance_test(enum cfs_crypto_hash_alg hash_alg) __free_page(page); out_err: if (err) { - cfs_crypto_hash_speeds[hash_alg] = -1; - CDEBUG(D_INFO, "Crypto hash algorithm %s, err = %d\n", + cfs_crypto_hash_speeds[hash_alg] = err; + CDEBUG(D_INFO, "Crypto hash algorithm %s test error: rc = %d\n", cfs_crypto_hash_name(hash_alg), err); } else { unsigned long tmp; -- cgit v1.2.3 From 1bc55f796a9872208e19b57fd00f4c484be35318 Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Sat, 26 Mar 2016 15:40:56 -0400 Subject: staging: lustre: libcfs: calculate crypto performance using pages Use alloc_page() and use cfs_crypto_hash_update_page() to compute the hash instead of cfs_crypto_hash_digest(), since tgt_checksum_bulk() computes the hash by page anyway. Signed-off-by: Andreas Dilger Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5279 Reviewed-on: http://review.whamcloud.com/10982 Reviewed-by: John L. Hammond Reviewed-by: James Simmons Reviewed-by: Alexander Boyko Reviewed-by: Bob Glossman Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- .../staging/lustre/lnet/libcfs/linux/linux-crypto.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c index aec79165b5c7..f8383dc430a5 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c @@ -330,8 +330,23 @@ static void cfs_crypto_performance_test(enum cfs_crypto_hash_alg hash_alg) for (start = jiffies, end = start + sec * HZ, bcount = 0; time_before(jiffies, end); bcount++) { - err = cfs_crypto_hash_digest(hash_alg, buf, buf_len, NULL, 0, - hash, &hash_len); + struct cfs_crypto_hash_desc *hdesc; + int i; + + hdesc = cfs_crypto_hash_init(hash_alg, NULL, 0); + if (IS_ERR(hdesc)) { + err = PTR_ERR(hdesc); + break; + } + + for (i = 0; i < buf_len / PAGE_SIZE; i++) { + err = cfs_crypto_hash_update_page(hdesc, page, 0, + PAGE_SIZE); + if (err) + break; + } + + err = cfs_crypto_hash_final(hdesc, hash, &hash_len); if (err) break; } -- cgit v1.2.3 From 78ab125e63115a7f42d598a2113cd75092a40335 Mon Sep 17 00:00:00 2001 From: Oleg Drokin Date: Sun, 27 Mar 2016 12:05:03 -0400 Subject: staging/lustre/libcfs: Copy correct amount in libcfs_ioctl_getdata Commit b8ff756bc351 ("staging: lustre: libcfs: merge code from libcfs_ioctl into libcfs_ioctl_getdata") introduced a problem copying just a single pointer worth of data from userspace instead of whole libcfs_ioctl_hdr structure. Adjust the copying amount. Signed-off-by: Oleg Drokin Acked-by: James Simmons Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/libcfs/linux/linux-module.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c index b86e93795846..d89f71ee45b2 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c @@ -128,7 +128,7 @@ int libcfs_ioctl_getdata(struct libcfs_ioctl_hdr **hdr_pp, struct libcfs_ioctl_hdr hdr; int err = 0; - if (copy_from_user(&hdr, uhdr, sizeof(uhdr))) + if (copy_from_user(&hdr, uhdr, sizeof(hdr))) return -EFAULT; if (hdr.ioc_version != LIBCFS_IOCTL_VERSION && -- cgit v1.2.3 From 3404f60d8b54647eff52b6aa03d60ef1ffa3deb2 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Sun, 27 Mar 2016 20:26:21 -0400 Subject: staging: lustre: libcfs: remove function declarations in libcfs.h A few function declarations are in libcfs.h that are not needed. Signed-off-by: James Simmons Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6245 Reviewed-on: http://review.whamcloud.com/13874 Reviewed-by: Dmitry Eremin Reviewed-by: John L. Hammond Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/include/linux/libcfs/libcfs.h | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs.h b/drivers/staging/lustre/include/linux/libcfs/libcfs.h index d2e43617b0a1..332394cca741 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs.h @@ -59,16 +59,9 @@ #define LNET_ACCEPTOR_MIN_RESERVED_PORT 512 #define LNET_ACCEPTOR_MAX_RESERVED_PORT 1023 -/* - * Drop into debugger, if possible. Implementation is provided by platform. - */ - -void cfs_enter_debugger(void); - /* * Defined by platform */ -int unshare_fs_struct(void); sigset_t cfs_block_allsigs(void); sigset_t cfs_block_sigs(unsigned long sigs); sigset_t cfs_block_sigsinv(unsigned long sigs); -- cgit v1.2.3 From 9af4826aeb4e12ba84a824d516432e223868f3b1 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Sun, 27 Mar 2016 20:26:22 -0400 Subject: staging: lustre: libcfs: remove cfs_signal_pending wrapper Use signal_pending() directly instead of a one line function wrapper. Signed-off-by: James Simmons Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6245 Reviewed-on: http://review.whamcloud.com/13874 Reviewed-by: Dmitry Eremin Reviewed-by: John L. Hammond Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/include/linux/libcfs/libcfs.h | 1 - drivers/staging/lustre/lnet/libcfs/linux/linux-prim.c | 7 ------- drivers/staging/lustre/lustre/include/lustre_lib.h | 2 +- drivers/staging/lustre/lustre/obdclass/cl_lock.c | 2 +- drivers/staging/lustre/lustre/ptlrpc/client.c | 6 +++--- 5 files changed, 5 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs.h b/drivers/staging/lustre/include/linux/libcfs/libcfs.h index 332394cca741..9158c61f6851 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs.h @@ -66,7 +66,6 @@ sigset_t cfs_block_allsigs(void); sigset_t cfs_block_sigs(unsigned long sigs); sigset_t cfs_block_sigsinv(unsigned long sigs); void cfs_restore_sigs(sigset_t); -int cfs_signal_pending(void); void cfs_clear_sigpending(void); /* diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-prim.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-prim.c index 89084460231a..7e5ef0a20f93 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-prim.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-prim.c @@ -128,13 +128,6 @@ cfs_restore_sigs(sigset_t old) } EXPORT_SYMBOL(cfs_restore_sigs); -int -cfs_signal_pending(void) -{ - return signal_pending(current); -} -EXPORT_SYMBOL(cfs_signal_pending); - void cfs_clear_sigpending(void) { diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h b/drivers/staging/lustre/lustre/include/lustre_lib.h index f2223d55850a..c5713d74486a 100644 --- a/drivers/staging/lustre/lustre/include/lustre_lib.h +++ b/drivers/staging/lustre/lustre/include/lustre_lib.h @@ -578,7 +578,7 @@ do { \ \ if (condition) \ break; \ - if (cfs_signal_pending()) { \ + if (signal_pending(current)) { \ if (info->lwi_on_signal && \ (__timeout == 0 || __allow_intr)) { \ if (info->lwi_on_signal != LWI_ON_SIGNAL_NOOP) \ diff --git a/drivers/staging/lustre/lustre/obdclass/cl_lock.c b/drivers/staging/lustre/lustre/obdclass/cl_lock.c index aec644eb4db9..f952c1cb0761 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_lock.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_lock.c @@ -951,7 +951,7 @@ int cl_lock_state_wait(const struct lu_env *env, struct cl_lock *lock) result = -ERESTARTSYS; if (likely(!OBD_FAIL_CHECK(OBD_FAIL_LOCK_STATE_WAIT_INTR))) { schedule(); - if (!cfs_signal_pending()) + if (!signal_pending(current)) result = 0; } diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c index 1b7673eec4d7..32a7c8710119 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/client.c +++ b/drivers/staging/lustre/lustre/ptlrpc/client.c @@ -2087,7 +2087,7 @@ int ptlrpc_set_wait(struct ptlrpc_request_set *set) CDEBUG(D_RPCTRACE, "set %p going to sleep for %d seconds\n", set, timeout); - if (timeout == 0 && !cfs_signal_pending()) + if (timeout == 0 && !signal_pending(current)) /* * No requests are in-flight (ether timed out * or delayed), so we can allow interrupts. @@ -2114,7 +2114,7 @@ int ptlrpc_set_wait(struct ptlrpc_request_set *set) * it being ignored forever */ if (rc == -ETIMEDOUT && !lwi.lwi_allow_intr && - cfs_signal_pending()) { + signal_pending(current)) { sigset_t blocked_sigs = cfs_block_sigsinv(LUSTRE_FATAL_SIGS); @@ -2124,7 +2124,7 @@ int ptlrpc_set_wait(struct ptlrpc_request_set *set) * important signals since ptlrpc set is not easily * reentrant from userspace again */ - if (cfs_signal_pending()) + if (signal_pending(current)) ptlrpc_interrupted_set(set); cfs_restore_sigs(blocked_sigs); } -- cgit v1.2.3 From ccfb80c1861f9480572462b35f75451fc7c3517a Mon Sep 17 00:00:00 2001 From: James Simmons Date: Sun, 27 Mar 2016 20:26:23 -0400 Subject: staging: lustre: libcfs: remove atomic cpt allocations libcfs contains functions to perform atomic memory operations. These functions have never been used so remove them. Signed-off-by: frank zago Signed-off-by: James Simmons Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6245 Reviewed-on: http://review.whamcloud.com/15913 Reviewed-by: John L. Hammond Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- .../lustre/include/linux/libcfs/libcfs_private.h | 6 ---- drivers/staging/lustre/lnet/libcfs/libcfs_lock.c | 41 ---------------------- 2 files changed, 47 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h index dab486261154..63e394eac47d 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h @@ -351,12 +351,6 @@ void cfs_percpt_lock_free(struct cfs_percpt_lock *pcl); void cfs_percpt_lock(struct cfs_percpt_lock *pcl, int index); /* unlock private lock \a index of \a pcl */ void cfs_percpt_unlock(struct cfs_percpt_lock *pcl, int index); -/* create percpt (atomic) refcount based on @cptab */ -atomic_t **cfs_percpt_atomic_alloc(struct cfs_cpt_table *cptab, int val); -/* destroy percpt refcount */ -void cfs_percpt_atomic_free(atomic_t **refs); -/* return sum of all percpu refs */ -int cfs_percpt_atomic_summary(atomic_t **refs); /** Compile-time assertion. diff --git a/drivers/staging/lustre/lnet/libcfs/libcfs_lock.c b/drivers/staging/lustre/lnet/libcfs/libcfs_lock.c index 2de9eeae0232..d38954a38f9e 100644 --- a/drivers/staging/lustre/lnet/libcfs/libcfs_lock.c +++ b/drivers/staging/lustre/lnet/libcfs/libcfs_lock.c @@ -142,44 +142,3 @@ cfs_percpt_unlock(struct cfs_percpt_lock *pcl, int index) } } EXPORT_SYMBOL(cfs_percpt_unlock); - -/** free cpu-partition refcount */ -void -cfs_percpt_atomic_free(atomic_t **refs) -{ - cfs_percpt_free(refs); -} -EXPORT_SYMBOL(cfs_percpt_atomic_free); - -/** allocate cpu-partition refcount with initial value @init_val */ -atomic_t ** -cfs_percpt_atomic_alloc(struct cfs_cpt_table *cptab, int init_val) -{ - atomic_t **refs; - atomic_t *ref; - int i; - - refs = cfs_percpt_alloc(cptab, sizeof(*ref)); - if (!refs) - return NULL; - - cfs_percpt_for_each(ref, i, refs) - atomic_set(ref, init_val); - return refs; -} -EXPORT_SYMBOL(cfs_percpt_atomic_alloc); - -/** return sum of cpu-partition refs */ -int -cfs_percpt_atomic_summary(atomic_t **refs) -{ - atomic_t *ref; - int i; - int val = 0; - - cfs_percpt_for_each(ref, i, refs) - val += atomic_read(ref); - - return val; -} -EXPORT_SYMBOL(cfs_percpt_atomic_summary); -- cgit v1.2.3 From a18332b4564318c27cbc11596b2fe8b832e4c6c0 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Sun, 27 Mar 2016 20:26:24 -0400 Subject: staging: lustre: libcfs: remove cfs_percpt_[current|index] The functions cfs_percpt_current() and cfs_percpt_index() are not used anywhere. Remove it. Signed-off-by: frank zago Signed-off-by: James Simmons Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6245 Reviewed-on: http://review.whamcloud.com/15913 Reviewed-by: John L. Hammond Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- .../lustre/include/linux/libcfs/libcfs_private.h | 2 -- drivers/staging/lustre/lnet/libcfs/libcfs_mem.c | 28 ---------------------- 2 files changed, 30 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h index 63e394eac47d..a41152745c2d 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h @@ -193,8 +193,6 @@ void *cfs_percpt_alloc(struct cfs_cpt_table *cptab, unsigned int size); */ void cfs_percpt_free(void *vars); int cfs_percpt_number(void *vars); -void *cfs_percpt_current(void *vars); -void *cfs_percpt_index(void *vars, int idx); #define cfs_percpt_for_each(var, i, vars) \ for (i = 0; i < cfs_percpt_number(vars) && \ diff --git a/drivers/staging/lustre/lnet/libcfs/libcfs_mem.c b/drivers/staging/lustre/lnet/libcfs/libcfs_mem.c index c5a6951516ed..d0e81bb41cdc 100644 --- a/drivers/staging/lustre/lnet/libcfs/libcfs_mem.c +++ b/drivers/staging/lustre/lnet/libcfs/libcfs_mem.c @@ -114,34 +114,6 @@ cfs_percpt_number(void *vars) } EXPORT_SYMBOL(cfs_percpt_number); -/* - * return memory block shadowed from current CPU - */ -void * -cfs_percpt_current(void *vars) -{ - struct cfs_var_array *arr; - int cpt; - - arr = container_of(vars, struct cfs_var_array, va_ptrs[0]); - cpt = cfs_cpt_current(arr->va_cptab, 0); - if (cpt < 0) - return NULL; - - return arr->va_ptrs[cpt]; -} - -void * -cfs_percpt_index(void *vars, int idx) -{ - struct cfs_var_array *arr; - - arr = container_of(vars, struct cfs_var_array, va_ptrs[0]); - - LASSERT(idx >= 0 && idx < arr->va_count); - return arr->va_ptrs[idx]; -} - /* * free variable array, see more detail in cfs_array_alloc */ -- cgit v1.2.3 From 762d266d7d27bc00f9249a21feadc03154ab07c7 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Sun, 27 Mar 2016 20:26:25 -0400 Subject: staging: lustre: libcfs: move all cpt handling to libcfs_cpu.h Move the CPT handling declartions out of libcfs_private.h to libcfs_cpu.h where it belongs. Signed-off-by: frank zago Signed-off-by: James Simmons Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6245 Reviewed-on: http://review.whamcloud.com/15913 Reviewed-by: John L. Hammond Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- .../lustre/include/linux/libcfs/libcfs_cpu.h | 64 +++++++++++++++++++++ .../lustre/include/linux/libcfs/libcfs_private.h | 67 ---------------------- 2 files changed, 64 insertions(+), 67 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_cpu.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_cpu.h index 9e62c59714b7..71ad93b2c6af 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_cpu.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_cpu.h @@ -203,6 +203,70 @@ int cfs_cpt_spread_node(struct cfs_cpt_table *cptab, int cpt); */ int cfs_cpu_ht_nsiblings(int cpu); +/* + * allocate per-cpu-partition data, returned value is an array of pointers, + * variable can be indexed by CPU ID. + * cptab != NULL: size of array is number of CPU partitions + * cptab == NULL: size of array is number of HW cores + */ +void *cfs_percpt_alloc(struct cfs_cpt_table *cptab, unsigned int size); +/* + * destory per-cpu-partition variable + */ +void cfs_percpt_free(void *vars); +int cfs_percpt_number(void *vars); + +#define cfs_percpt_for_each(var, i, vars) \ + for (i = 0; i < cfs_percpt_number(vars) && \ + ((var) = (vars)[i]) != NULL; i++) + +/* + * percpu partition lock + * + * There are some use-cases like this in Lustre: + * . each CPU partition has it's own private data which is frequently changed, + * and mostly by the local CPU partition. + * . all CPU partitions share some global data, these data are rarely changed. + * + * LNet is typical example. + * CPU partition lock is designed for this kind of use-cases: + * . each CPU partition has it's own private lock + * . change on private data just needs to take the private lock + * . read on shared data just needs to take _any_ of private locks + * . change on shared data needs to take _all_ private locks, + * which is slow and should be really rare. + */ +enum { + CFS_PERCPT_LOCK_EX = -1, /* negative */ +}; + +struct cfs_percpt_lock { + /* cpu-partition-table for this lock */ + struct cfs_cpt_table *pcl_cptab; + /* exclusively locked */ + unsigned int pcl_locked; + /* private lock table */ + spinlock_t **pcl_locks; +}; + +/* return number of private locks */ +#define cfs_percpt_lock_num(pcl) cfs_cpt_number(pcl->pcl_cptab) + +/* + * create a cpu-partition lock based on CPU partition table \a cptab, + * each private lock has extra \a psize bytes padding data + */ +struct cfs_percpt_lock *cfs_percpt_lock_alloc(struct cfs_cpt_table *cptab); + +/* destroy a cpu-partition lock */ +void cfs_percpt_lock_free(struct cfs_percpt_lock *pcl); + +/* lock private lock \a index of \a pcl */ +void cfs_percpt_lock(struct cfs_percpt_lock *pcl, int index); + +/* unlock private lock \a index of \a pcl */ +void cfs_percpt_unlock(struct cfs_percpt_lock *pcl, int index); + /** * iterate over all CPU partitions in \a cptab */ diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h index a41152745c2d..e18b57b5c64e 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h @@ -181,23 +181,6 @@ int libcfs_debug_cleanup(void); int libcfs_debug_clear_buffer(void); int libcfs_debug_mark_buffer(const char *text); -/* - * allocate per-cpu-partition data, returned value is an array of pointers, - * variable can be indexed by CPU ID. - * cptable != NULL: size of array is number of CPU partitions - * cptable == NULL: size of array is number of HW cores - */ -void *cfs_percpt_alloc(struct cfs_cpt_table *cptab, unsigned int size); -/* - * destroy per-cpu-partition variable - */ -void cfs_percpt_free(void *vars); -int cfs_percpt_number(void *vars); - -#define cfs_percpt_for_each(var, i, vars) \ - for (i = 0; i < cfs_percpt_number(vars) && \ - ((var) = (vars)[i]) != NULL; i++) - /* * allocate a variable array, returned value is an array of pointers. * Caller can specify length of array by count. @@ -300,56 +283,6 @@ do { \ #define CFS_ALLOC_PTR(ptr) LIBCFS_ALLOC(ptr, sizeof(*(ptr))) #define CFS_FREE_PTR(ptr) LIBCFS_FREE(ptr, sizeof(*(ptr))) -/* - * percpu partition lock - * - * There are some use-cases like this in Lustre: - * . each CPU partition has it's own private data which is frequently changed, - * and mostly by the local CPU partition. - * . all CPU partitions share some global data, these data are rarely changed. - * - * LNet is typical example. - * CPU partition lock is designed for this kind of use-cases: - * . each CPU partition has it's own private lock - * . change on private data just needs to take the private lock - * . read on shared data just needs to take _any_ of private locks - * . change on shared data needs to take _all_ private locks, - * which is slow and should be really rare. - */ - -enum { - CFS_PERCPT_LOCK_EX = -1, /* negative */ -}; - -struct cfs_percpt_lock { - /* cpu-partition-table for this lock */ - struct cfs_cpt_table *pcl_cptab; - /* exclusively locked */ - unsigned int pcl_locked; - /* private lock table */ - spinlock_t **pcl_locks; -}; - -/* return number of private locks */ -static inline int -cfs_percpt_lock_num(struct cfs_percpt_lock *pcl) -{ - return cfs_cpt_number(pcl->pcl_cptab); -} - -/* - * create a cpu-partition lock based on CPU partition table \a cptab, - * each private lock has extra \a psize bytes padding data - */ -struct cfs_percpt_lock *cfs_percpt_lock_alloc(struct cfs_cpt_table *cptab); -/* destroy a cpu-partition lock */ -void cfs_percpt_lock_free(struct cfs_percpt_lock *pcl); - -/* lock private lock \a index of \a pcl */ -void cfs_percpt_lock(struct cfs_percpt_lock *pcl, int index); -/* unlock private lock \a index of \a pcl */ -void cfs_percpt_unlock(struct cfs_percpt_lock *pcl, int index); - /** Compile-time assertion. * Check an invariant described by a constant expression at compile time by -- cgit v1.2.3 From 2dc09ea8d91a97dd01c675f2903ce5b4d1fd48d3 Mon Sep 17 00:00:00 2001 From: Liang Zhen Date: Sun, 27 Mar 2016 20:26:26 -0400 Subject: staging: lustre: libcfs: add lock-class for cfs_percpt_lock initialise lock-class for each sublock of cfs_percpt_lock to eliminate false alarm ""possible recursive locking detected" Signed-off-by: Liang Zhen Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6432 Reviewed-on: http://review.whamcloud.com/14368 Reviewed-by: James Simmons Reviewed-by: Andreas Dilger Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- .../staging/lustre/include/linux/libcfs/libcfs_cpu.h | 19 +++++++++++++++++-- drivers/staging/lustre/lnet/libcfs/libcfs_lock.c | 13 ++++++++++--- 2 files changed, 27 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_cpu.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_cpu.h index 71ad93b2c6af..81d8079e3b5e 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_cpu.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_cpu.h @@ -256,8 +256,8 @@ struct cfs_percpt_lock { * create a cpu-partition lock based on CPU partition table \a cptab, * each private lock has extra \a psize bytes padding data */ -struct cfs_percpt_lock *cfs_percpt_lock_alloc(struct cfs_cpt_table *cptab); - +struct cfs_percpt_lock *cfs_percpt_lock_create(struct cfs_cpt_table *cptab, + struct lock_class_key *keys); /* destroy a cpu-partition lock */ void cfs_percpt_lock_free(struct cfs_percpt_lock *pcl); @@ -267,6 +267,21 @@ void cfs_percpt_lock(struct cfs_percpt_lock *pcl, int index); /* unlock private lock \a index of \a pcl */ void cfs_percpt_unlock(struct cfs_percpt_lock *pcl, int index); +#define CFS_PERCPT_LOCK_KEYS 256 + +/* NB: don't allocate keys dynamically, lockdep needs them to be in ".data" */ +#define cfs_percpt_lock_alloc(cptab) \ +({ \ + static struct lock_class_key ___keys[CFS_PERCPT_LOCK_KEYS]; \ + struct cfs_percpt_lock *___lk; \ + \ + if (cfs_cpt_number(cptab) > CFS_PERCPT_LOCK_KEYS) \ + ___lk = cfs_percpt_lock_create(cptab, NULL); \ + else \ + ___lk = cfs_percpt_lock_create(cptab, ___keys); \ + ___lk; \ +}) + /** * iterate over all CPU partitions in \a cptab */ diff --git a/drivers/staging/lustre/lnet/libcfs/libcfs_lock.c b/drivers/staging/lustre/lnet/libcfs/libcfs_lock.c index d38954a38f9e..83543f928279 100644 --- a/drivers/staging/lustre/lnet/libcfs/libcfs_lock.c +++ b/drivers/staging/lustre/lnet/libcfs/libcfs_lock.c @@ -49,7 +49,8 @@ EXPORT_SYMBOL(cfs_percpt_lock_free); * reason we always allocate cacheline-aligned memory block. */ struct cfs_percpt_lock * -cfs_percpt_lock_alloc(struct cfs_cpt_table *cptab) +cfs_percpt_lock_create(struct cfs_cpt_table *cptab, + struct lock_class_key *keys) { struct cfs_percpt_lock *pcl; spinlock_t *lock; @@ -67,12 +68,18 @@ cfs_percpt_lock_alloc(struct cfs_cpt_table *cptab) return NULL; } - cfs_percpt_for_each(lock, i, pcl->pcl_locks) + if (!keys) + CWARN("Cannot setup class key for percpt lock, you may see recursive locking warnings which are actually fake.\n"); + + cfs_percpt_for_each(lock, i, pcl->pcl_locks) { spin_lock_init(lock); + if (keys != NULL) + lockdep_set_class(lock, &keys[i]); + } return pcl; } -EXPORT_SYMBOL(cfs_percpt_lock_alloc); +EXPORT_SYMBOL(cfs_percpt_lock_create); /** * lock a CPU partition -- cgit v1.2.3 From 304d13ff4d5dcccea2cf199d96d6716de31b7321 Mon Sep 17 00:00:00 2001 From: Jian Yu Date: Sun, 27 Mar 2016 20:26:27 -0400 Subject: staging: lustre: libcfs: replace direct HZ access with kernel APIs On some customers' systems, the kernel was compiled with HZ defined to 100, instead of 1000. This improves performance for HPC applications. However, to use these systems with Lustre, customers have to re-build Lustre for the kernel because Lustre directly uses the defined constant HZ. Since kernel 2.6.21, some non-HZ dependent timing APIs become non- inline functions, which can be used in Lustre codes to replace the direct HZ access. These kernel APIs include: jiffies_to_msecs() jiffies_to_usecs() jiffies_to_timespec() msecs_to_jiffies() usecs_to_jiffies() timespec_to_jiffies() And here are some samples of the replacement: HZ -> msecs_to_jiffies(MSEC_PER_SEC) n * HZ -> msecs_to_jiffies(n * MSEC_PER_SEC) HZ / n -> msecs_to_jiffies(MSEC_PER_SEC / n) n / HZ -> jiffies_to_msecs(n) / MSEC_PER_SEC n / HZ * 1000 -> jiffies_to_msecs(n) This patch replaces the direct HZ access in the libcfs module. Signed-off-by: Jian Yu Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5443 Reviewed-on: http://review.whamcloud.com/11993 Reviewed-by: Nathaniel Clark Reviewed-by: James Simmons Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/include/linux/libcfs/linux/linux-time.h | 4 ++-- drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/linux-time.h b/drivers/staging/lustre/include/linux/libcfs/linux/linux-time.h index ed8764b11c80..7656b09b8752 100644 --- a/drivers/staging/lustre/include/linux/libcfs/linux/linux-time.h +++ b/drivers/staging/lustre/include/linux/libcfs/linux/linux-time.h @@ -70,12 +70,12 @@ static inline unsigned long cfs_time_current(void) static inline long cfs_time_seconds(int seconds) { - return ((long)seconds) * HZ; + return ((long)seconds) * msecs_to_jiffies(MSEC_PER_SEC); } static inline long cfs_duration_sec(long d) { - return d / HZ; + return d / msecs_to_jiffies(MSEC_PER_SEC); } #define cfs_time_current_64 get_jiffies_64 diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c index f8383dc430a5..0715101c577c 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c @@ -313,7 +313,6 @@ static void cfs_crypto_performance_test(enum cfs_crypto_hash_alg hash_alg) void *buf; unsigned long start, end; int bcount, err = 0; - int sec = 1; /* do test only 1 sec */ struct page *page; unsigned char hash[CFS_CRYPTO_HASH_DIGESTSIZE_MAX]; unsigned int hash_len = sizeof(hash); @@ -328,8 +327,8 @@ static void cfs_crypto_performance_test(enum cfs_crypto_hash_alg hash_alg) memset(buf, 0xAD, PAGE_SIZE); kunmap(page); - for (start = jiffies, end = start + sec * HZ, bcount = 0; - time_before(jiffies, end); bcount++) { + for (start = jiffies, end = start + msecs_to_jiffies(MSEC_PER_SEC), + bcount = 0; time_before(jiffies, end); bcount++) { struct cfs_crypto_hash_desc *hdesc; int i; -- cgit v1.2.3 From d47b7026ba96f604318e46354e8ec129f9b960d7 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Sun, 27 Mar 2016 20:26:28 -0400 Subject: staging: lustre: libcfs: add CFS_FAULT_CHECK() Add the macro CFS_FAULT_CHECK() which behaves like CFS_FAIL_CHECK() except that any site may be matched by setting CFS_FAULT (0x02000000) in cfs_fail_loc. Add cfs_fail_err for use as a return value with CFS_FAULT_CHECK(). Signed-off-by: John L. Hammond Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5409 Reviewed-on: http://review.whamcloud.com/11263 Reviewed-by: Robert Read Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/include/linux/libcfs/libcfs_fail.h | 15 ++++++++++++--- drivers/staging/lustre/lnet/libcfs/fail.c | 3 +++ drivers/staging/lustre/lnet/libcfs/module.c | 7 +++++++ 3 files changed, 22 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_fail.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_fail.h index aa69c6a33d19..2e008bffc89a 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_fail.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_fail.h @@ -38,6 +38,7 @@ extern unsigned long cfs_fail_loc; extern unsigned int cfs_fail_val; +extern int cfs_fail_err; extern wait_queue_head_t cfs_race_waitq; extern int cfs_race_state; @@ -70,9 +71,14 @@ enum { #define CFS_FAIL_RAND 0x08000000 /* fail 1/N of the times */ #define CFS_FAIL_USR1 0x04000000 /* user flag */ -#define CFS_FAIL_PRECHECK(id) (cfs_fail_loc && \ - (cfs_fail_loc & CFS_FAIL_MASK_LOC) == \ - ((id) & CFS_FAIL_MASK_LOC)) +#define CFS_FAULT 0x02000000 /* match any CFS_FAULT_CHECK */ + +static inline bool CFS_FAIL_PRECHECK(__u32 id) +{ + return cfs_fail_loc != 0 && + ((cfs_fail_loc & CFS_FAIL_MASK_LOC) == (id & CFS_FAIL_MASK_LOC) || + (cfs_fail_loc & id & CFS_FAULT)); +} static inline int cfs_fail_check_set(__u32 id, __u32 value, int set, int quiet) @@ -144,6 +150,9 @@ static inline int cfs_fail_timeout_set(__u32 id, __u32 value, int ms, int set) #define CFS_FAIL_TIMEOUT_MS_ORSET(id, value, ms) \ cfs_fail_timeout_set(id, value, ms, CFS_FAIL_LOC_ORSET) +#define CFS_FAULT_CHECK(id) \ + CFS_FAIL_CHECK(CFS_FAULT | (id)) + /* The idea here is to synchronise two threads to force a race. The * first thread that calls this with a matching fail_loc is put to * sleep. The next thread that calls with the same fail_loc wakes up diff --git a/drivers/staging/lustre/lnet/libcfs/fail.c b/drivers/staging/lustre/lnet/libcfs/fail.c index dadaf7685cbd..086e690bd6f2 100644 --- a/drivers/staging/lustre/lnet/libcfs/fail.c +++ b/drivers/staging/lustre/lnet/libcfs/fail.c @@ -41,6 +41,9 @@ EXPORT_SYMBOL(cfs_fail_loc); unsigned int cfs_fail_val; EXPORT_SYMBOL(cfs_fail_val); +int cfs_fail_err; +EXPORT_SYMBOL(cfs_fail_err); + DECLARE_WAIT_QUEUE_HEAD(cfs_race_waitq); EXPORT_SYMBOL(cfs_race_waitq); diff --git a/drivers/staging/lustre/lnet/libcfs/module.c b/drivers/staging/lustre/lnet/libcfs/module.c index 49c2d03dc9de..f2d041118cf7 100644 --- a/drivers/staging/lustre/lnet/libcfs/module.c +++ b/drivers/staging/lustre/lnet/libcfs/module.c @@ -424,6 +424,13 @@ static struct ctl_table lnet_table[] = { .mode = 0644, .proc_handler = &proc_dointvec }, + { + .procname = "fail_err", + .data = &cfs_fail_err, + .maxlen = sizeof(cfs_fail_err), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, { } }; -- cgit v1.2.3 From 5d145b1ad404e8cb260283d8a8b0747261698c73 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Sun, 27 Mar 2016 20:26:29 -0400 Subject: staging: lustre: libcfs: remove cfs_workitem_t typedefs Convert cfs_workitem_t to proper structure. Signed-off-by: James Simmons Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6245 Reviewed-on: http://review.whamcloud.com/17202 Reviewed-by: John L. Hammond Reviewed-by: Dmitry Eremin Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h | 4 ++-- .../staging/lustre/include/linux/libcfs/libcfs_workitem.h | 12 ++++++------ drivers/staging/lustre/lnet/libcfs/hash.c | 6 +++--- drivers/staging/lustre/lnet/libcfs/workitem.c | 12 ++++++------ drivers/staging/lustre/lnet/selftest/selftest.h | 4 ++-- 5 files changed, 19 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h index c3f2332fa043..119986bc7961 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h @@ -245,7 +245,7 @@ struct cfs_hash { /** # of iterators (caller of cfs_hash_for_each_*) */ __u32 hs_iterators; /** rehash workitem */ - cfs_workitem_t hs_rehash_wi; + struct cfs_workitem hs_rehash_wi; /** refcount on this hash table */ atomic_t hs_refcount; /** rehash buckets-table */ @@ -262,7 +262,7 @@ struct cfs_hash { /** bits when we found the max depth */ unsigned int hs_dep_bits; /** workitem to output max depth */ - cfs_workitem_t hs_dep_wi; + struct cfs_workitem hs_dep_wi; #endif /** name of htable */ char hs_name[0]; diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_workitem.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_workitem.h index 5cc64f327a87..f9b20c5accbf 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_workitem.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_workitem.h @@ -73,7 +73,7 @@ int cfs_wi_sched_create(char *name, struct cfs_cpt_table *cptab, int cpt, struct cfs_workitem; typedef int (*cfs_wi_action_t) (struct cfs_workitem *); -typedef struct cfs_workitem { +struct cfs_workitem { /** chain on runq or rerunq */ struct list_head wi_list; /** working function */ @@ -84,10 +84,10 @@ typedef struct cfs_workitem { unsigned short wi_running:1; /** scheduled */ unsigned short wi_scheduled:1; -} cfs_workitem_t; +}; static inline void -cfs_wi_init(cfs_workitem_t *wi, void *data, cfs_wi_action_t action) +cfs_wi_init(struct cfs_workitem *wi, void *data, cfs_wi_action_t action) { INIT_LIST_HEAD(&wi->wi_list); @@ -97,9 +97,9 @@ cfs_wi_init(cfs_workitem_t *wi, void *data, cfs_wi_action_t action) wi->wi_action = action; } -void cfs_wi_schedule(struct cfs_wi_sched *sched, cfs_workitem_t *wi); -int cfs_wi_deschedule(struct cfs_wi_sched *sched, cfs_workitem_t *wi); -void cfs_wi_exit(struct cfs_wi_sched *sched, cfs_workitem_t *wi); +void cfs_wi_schedule(struct cfs_wi_sched *sched, struct cfs_workitem *wi); +int cfs_wi_deschedule(struct cfs_wi_sched *sched, struct cfs_workitem *wi); +void cfs_wi_exit(struct cfs_wi_sched *sched, struct cfs_workitem *wi); int cfs_wi_startup(void); void cfs_wi_shutdown(void); diff --git a/drivers/staging/lustre/lnet/libcfs/hash.c b/drivers/staging/lustre/lnet/libcfs/hash.c index f60feb3a3dc7..cc45ed82b2be 100644 --- a/drivers/staging/lustre/lnet/libcfs/hash.c +++ b/drivers/staging/lustre/lnet/libcfs/hash.c @@ -942,10 +942,10 @@ cfs_hash_buckets_realloc(struct cfs_hash *hs, struct cfs_hash_bucket **old_bkts, * @flags - CFS_HASH_REHASH enable synamic hash resizing * - CFS_HASH_SORT enable chained hash sort */ -static int cfs_hash_rehash_worker(cfs_workitem_t *wi); +static int cfs_hash_rehash_worker(struct cfs_workitem *wi); #if CFS_HASH_DEBUG_LEVEL >= CFS_HASH_DEBUG_1 -static int cfs_hash_dep_print(cfs_workitem_t *wi) +static int cfs_hash_dep_print(struct cfs_workitem *wi) { struct cfs_hash *hs = container_of(wi, struct cfs_hash, hs_dep_wi); int dep; @@ -1847,7 +1847,7 @@ cfs_hash_rehash_bd(struct cfs_hash *hs, struct cfs_hash_bd *old) } static int -cfs_hash_rehash_worker(cfs_workitem_t *wi) +cfs_hash_rehash_worker(struct cfs_workitem *wi) { struct cfs_hash *hs = container_of(wi, struct cfs_hash, hs_rehash_wi); struct cfs_hash_bucket **bkts; diff --git a/drivers/staging/lustre/lnet/libcfs/workitem.c b/drivers/staging/lustre/lnet/libcfs/workitem.c index c72fe00dce8d..92236ae59e49 100644 --- a/drivers/staging/lustre/lnet/libcfs/workitem.c +++ b/drivers/staging/lustre/lnet/libcfs/workitem.c @@ -111,7 +111,7 @@ cfs_wi_sched_cansleep(struct cfs_wi_sched *sched) * 1. when it returns no one shall try to schedule the workitem. */ void -cfs_wi_exit(struct cfs_wi_sched *sched, cfs_workitem_t *wi) +cfs_wi_exit(struct cfs_wi_sched *sched, struct cfs_workitem *wi) { LASSERT(!in_interrupt()); /* because we use plain spinlock */ LASSERT(!sched->ws_stopping); @@ -138,7 +138,7 @@ EXPORT_SYMBOL(cfs_wi_exit); * cancel schedule request of workitem \a wi */ int -cfs_wi_deschedule(struct cfs_wi_sched *sched, cfs_workitem_t *wi) +cfs_wi_deschedule(struct cfs_wi_sched *sched, struct cfs_workitem *wi) { int rc; @@ -179,7 +179,7 @@ EXPORT_SYMBOL(cfs_wi_deschedule); * be added, and even dynamic creation of serialised queues might be supported. */ void -cfs_wi_schedule(struct cfs_wi_sched *sched, cfs_workitem_t *wi) +cfs_wi_schedule(struct cfs_wi_sched *sched, struct cfs_workitem *wi) { LASSERT(!in_interrupt()); /* because we use plain spinlock */ LASSERT(!sched->ws_stopping); @@ -229,12 +229,12 @@ static int cfs_wi_scheduler(void *arg) while (!sched->ws_stopping) { int nloops = 0; int rc; - cfs_workitem_t *wi; + struct cfs_workitem *wi; while (!list_empty(&sched->ws_runq) && nloops < CFS_WI_RESCHED) { - wi = list_entry(sched->ws_runq.next, cfs_workitem_t, - wi_list); + wi = list_entry(sched->ws_runq.next, + struct cfs_workitem, wi_list); LASSERT(wi->wi_scheduled && !wi->wi_running); list_del_init(&wi->wi_list); diff --git a/drivers/staging/lustre/lnet/selftest/selftest.h b/drivers/staging/lustre/lnet/selftest/selftest.h index 288522d4d7b9..f50580e5b02a 100644 --- a/drivers/staging/lustre/lnet/selftest/selftest.h +++ b/drivers/staging/lustre/lnet/selftest/selftest.h @@ -176,7 +176,7 @@ typedef int (*swi_action_t) (struct swi_workitem *); typedef struct swi_workitem { struct cfs_wi_sched *swi_sched; - cfs_workitem_t swi_workitem; + struct cfs_workitem swi_workitem; swi_action_t swi_action; int swi_state; } swi_workitem_t; @@ -461,7 +461,7 @@ srpc_serv_is_framework(struct srpc_service *svc) } static inline int -swi_wi_action(cfs_workitem_t *wi) +swi_wi_action(struct cfs_workitem *wi) { swi_workitem_t *swi = container_of(wi, swi_workitem_t, swi_workitem); -- cgit v1.2.3 From 70011f5f2cbdadb52536ae752d2a4d59189df03f Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Mon, 28 Mar 2016 13:55:56 +0900 Subject: staging: wilc1000: change data type of wid argument in wilc_wlan_cfg_set This patch changes data type of wid argument in wilc_wlan_cfg_set from u32 to u16. It is better to change data type of wid because wid has one of enum WID_T that is data type of u16. And, there is no need to use u16 type casting when calling wilc_wlan_cfg_set_wid function. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 4 ++-- drivers/staging/wilc1000/wilc_wlan.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 30e1c039e80a..d09aa3bd0c16 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -1197,7 +1197,7 @@ static int wilc_wlan_cfg_commit(struct wilc_vif *vif, int type, return 0; } -int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, u32 wid, u8 *buffer, +int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, u16 wid, u8 *buffer, u32 buffer_size, int commit, u32 drv_handler) { u32 offset; @@ -1212,7 +1212,7 @@ int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, u32 wid, u8 *buffer, offset = wilc->cfg_frame_offset; ret_size = wilc_wlan_cfg_set_wid(wilc->cfg_frame.frame, offset, - (u16)wid, buffer, buffer_size); + wid, buffer, buffer_size); offset += ret_size; wilc->cfg_frame_offset = offset; diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index bcd4bfa5accc..ef7064207a9d 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -284,7 +284,7 @@ int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer, int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count); void wilc_handle_isr(struct wilc *wilc); void wilc_wlan_cleanup(struct net_device *dev); -int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, u32 wid, u8 *buffer, +int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, u16 wid, u8 *buffer, u32 buffer_size, int commit, u32 drv_handler); int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, u32 wid, int commit, u32 drv_handler); -- cgit v1.2.3 From 7db699dbe5107073050c123b05495e9c271f62fe Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Mon, 28 Mar 2016 13:55:57 +0900 Subject: staging: wilc1000: change data type of wid argument in wilc_wlan_cfg_get This patch changes data type of wid argument in wilc_wlan_cfg_get from u32 to u16. It is better to change data type of wid because wid has one of enum WID_T that is data type of u16. And, there is no need to use u16 type casting when calling wilc_wlan_cfg_get_wid function. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 5 ++--- drivers/staging/wilc1000/wilc_wlan.h | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index d09aa3bd0c16..db79ae246828 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -1239,7 +1239,7 @@ int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, u16 wid, u8 *buffer, return ret_size; } -int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, u32 wid, int commit, +int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, u16 wid, int commit, u32 drv_handler) { u32 offset; @@ -1253,8 +1253,7 @@ int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, u32 wid, int commit, wilc->cfg_frame_offset = 0; offset = wilc->cfg_frame_offset; - ret_size = wilc_wlan_cfg_get_wid(wilc->cfg_frame.frame, offset, - (u16)wid); + ret_size = wilc_wlan_cfg_get_wid(wilc->cfg_frame.frame, offset, wid); offset += ret_size; wilc->cfg_frame_offset = offset; diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index ef7064207a9d..38edeeb53d7c 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -286,7 +286,7 @@ void wilc_handle_isr(struct wilc *wilc); void wilc_wlan_cleanup(struct net_device *dev); int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, u16 wid, u8 *buffer, u32 buffer_size, int commit, u32 drv_handler); -int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, u32 wid, int commit, +int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, u16 wid, int commit, u32 drv_handler); int wilc_wlan_cfg_get_val(u32 wid, u8 *buffer, u32 buffer_size); int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, -- cgit v1.2.3 From c975f9dd106461794d339348e2f4b4812d154875 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Mon, 28 Mar 2016 13:55:58 +0900 Subject: staging: wilc1000: change data type of wid argument in wilc_wlan_cfg_get_val This patch changes data type of wid argument in wilc_wlan_cfg_get_val from u32 to u16. It is better to change data type of wid because wid has one of enum WID_T that is data type of u16. And, there is no need to use u16 type casting when calling wilc_wlan_cfg_get_wid_value function. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 4 ++-- drivers/staging/wilc1000/wilc_wlan.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index db79ae246828..7da3b4ac1dc5 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -1276,9 +1276,9 @@ int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, u16 wid, int commit, return ret_size; } -int wilc_wlan_cfg_get_val(u32 wid, u8 *buffer, u32 buffer_size) +int wilc_wlan_cfg_get_val(u16 wid, u8 *buffer, u32 buffer_size) { - return wilc_wlan_cfg_get_wid_value((u16)wid, buffer, buffer_size); + return wilc_wlan_cfg_get_wid_value(wid, buffer, buffer_size); } int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids, diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index 38edeeb53d7c..30e5312ee87e 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -288,7 +288,7 @@ int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, u16 wid, u8 *buffer, u32 buffer_size, int commit, u32 drv_handler); int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, u16 wid, int commit, u32 drv_handler); -int wilc_wlan_cfg_get_val(u32 wid, u8 *buffer, u32 buffer_size); +int wilc_wlan_cfg_get_val(u16 wid, u8 *buffer, u32 buffer_size); int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, u32 buffer_size, wilc_tx_complete_func_t func); void wilc_chip_sleep_manually(struct wilc *wilc); -- cgit v1.2.3 From 589c667d8ae1d7359a974719dd0d09f85aee5606 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Mon, 28 Mar 2016 13:55:59 +0900 Subject: staging: wilc1000: remove unused struct semaphore SemHandleUpdateStats struct semaphore SemHandleUpdateStats is defined but never used in this driver, so just remove it. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 1 - drivers/staging/wilc1000/wilc_wfi_netdevice.h | 1 - 2 files changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 5785dda8f9d3..f6aec474ff3a 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -2262,7 +2262,6 @@ struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *de } priv = wdev_priv(wdev); - sema_init(&(priv->SemHandleUpdateStats), 1); priv->wdev = wdev; wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID; #ifdef CONFIG_PM diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index debb139b7687..94a41b4a21a7 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -130,7 +130,6 @@ struct wilc_priv { struct wilc_wfi_key *wilc_ptk[MAX_NUM_STA]; u8 wilc_groupkey; /* semaphores */ - struct semaphore SemHandleUpdateStats; struct semaphore hSemScanReq; /* */ bool gbAutoRateAdjusted; -- cgit v1.2.3 From 086620978b2d06378f4a41afce2f7705c76a4625 Mon Sep 17 00:00:00 2001 From: Chaehyun Lim Date: Mon, 28 Mar 2016 13:56:00 +0900 Subject: staging: wilc1000: use mutex instead of struct semaphore hSemScanReq This patch replaces struct semaphore hSemScanReq with struct mutex scan_req_lock. It is better to use mutex than semaphore. Signed-off-by: Chaehyun Lim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 10 +++++----- drivers/staging/wilc1000/wilc_wfi_netdevice.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index f6aec474ff3a..358632b9aa83 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -451,7 +451,7 @@ static void CfgScanResult(enum scan_event scan_event, } else if (scan_event == SCAN_EVENT_DONE) { refresh_scan(priv, 1, false); - down(&(priv->hSemScanReq)); + mutex_lock(&priv->scan_req_lock); if (priv->pstrScanReq) { cfg80211_scan_done(priv->pstrScanReq, false); @@ -459,9 +459,9 @@ static void CfgScanResult(enum scan_event scan_event, priv->bCfgScanning = false; priv->pstrScanReq = NULL; } - up(&(priv->hSemScanReq)); + mutex_unlock(&priv->scan_req_lock); } else if (scan_event == SCAN_EVENT_ABORTED) { - down(&(priv->hSemScanReq)); + mutex_lock(&priv->scan_req_lock); if (priv->pstrScanReq) { update_scan_time(); @@ -471,7 +471,7 @@ static void CfgScanResult(enum scan_event scan_event, priv->bCfgScanning = false; priv->pstrScanReq = NULL; } - up(&(priv->hSemScanReq)); + mutex_unlock(&priv->scan_req_lock); } } } @@ -2307,7 +2307,7 @@ int wilc_init_host_int(struct net_device *net) priv->bInP2PlistenState = false; - sema_init(&(priv->hSemScanReq), 1); + mutex_init(&priv->scan_req_lock); s32Error = wilc_init(net, &priv->hif_drv); if (s32Error) netdev_err(net, "Error while initializing hostinterface\n"); diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index 94a41b4a21a7..3d0ca8e3ae24 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -130,7 +130,7 @@ struct wilc_priv { struct wilc_wfi_key *wilc_ptk[MAX_NUM_STA]; u8 wilc_groupkey; /* semaphores */ - struct semaphore hSemScanReq; + struct mutex scan_req_lock; /* */ bool gbAutoRateAdjusted; -- cgit v1.2.3 From ff3334276744ad49477e60c3c9e6acec8399b25d Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 28 Mar 2016 16:51:17 -0700 Subject: staging: skein: Convert local rotl_64 to kernel's rol64 Remove the local inline and use the generic kernel rol64 instead. Miscellanea: o Added a newline between a multiple line macro for consistency with the other multiple line macros Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/skein/skein_base.h | 5 ----- drivers/staging/skein/skein_block.c | 30 ++++++++++++++++-------------- 2 files changed, 16 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/skein/skein_base.h b/drivers/staging/skein/skein_base.h index 3c7f8ad3627d..9c4be1ab2c5d 100644 --- a/drivers/staging/skein/skein_base.h +++ b/drivers/staging/skein/skein_base.h @@ -84,11 +84,6 @@ struct skein_1024_ctx { /* 1024-bit Skein hash context structure */ u8 b[SKEIN_1024_BLOCK_BYTES]; /* partial block buf (8-byte aligned) */ }; -static inline u64 rotl_64(u64 x, u8 N) -{ - return (x << N) | (x >> (64 - N)); -} - /* Skein APIs for (incremental) "straight hashing" */ int skein_256_init(struct skein_256_ctx *ctx, size_t hash_bit_len); int skein_512_init(struct skein_512_ctx *ctx, size_t hash_bit_len); diff --git a/drivers/staging/skein/skein_block.c b/drivers/staging/skein/skein_block.c index 45b47327e024..1a547b307b33 100644 --- a/drivers/staging/skein/skein_block.c +++ b/drivers/staging/skein/skein_block.c @@ -15,6 +15,7 @@ ************************************************************************/ #include +#include #include "skein_base.h" #include "skein_block.h" @@ -59,10 +60,10 @@ #define ROUND256(p0, p1, p2, p3, ROT, r_num) \ do { \ X##p0 += X##p1; \ - X##p1 = rotl_64(X##p1, ROT##_0); \ + X##p1 = rol64(X##p1, ROT##_0); \ X##p1 ^= X##p0; \ X##p2 += X##p3; \ - X##p3 = rotl_64(X##p3, ROT##_1); \ + X##p3 = rol64(X##p3, ROT##_1); \ X##p3 ^= X##p2; \ } while (0) @@ -136,15 +137,16 @@ #define ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \ do { \ X##p0 += X##p1; \ - X##p1 = rotl_64(X##p1, ROT##_0); \ + X##p1 = rol64(X##p1, ROT##_0); \ X##p1 ^= X##p0; \ X##p2 += X##p3; \ - X##p3 = rotl_64(X##p3, ROT##_1); \ + X##p3 = rol64(X##p3, ROT##_1); \ X##p3 ^= X##p2; \ X##p4 += X##p5; \ - X##p5 = rotl_64(X##p5, ROT##_2); \ + X##p5 = rol64(X##p5, ROT##_2); \ X##p5 ^= X##p4; \ - X##p6 += X##p7; X##p7 = rotl_64(X##p7, ROT##_3);\ + X##p6 += X##p7; \ + X##p7 = rol64(X##p7, ROT##_3); \ X##p7 ^= X##p6; \ } while (0) @@ -226,28 +228,28 @@ pF, ROT, r_num) \ do { \ X##p0 += X##p1; \ - X##p1 = rotl_64(X##p1, ROT##_0); \ + X##p1 = rol64(X##p1, ROT##_0); \ X##p1 ^= X##p0; \ X##p2 += X##p3; \ - X##p3 = rotl_64(X##p3, ROT##_1); \ + X##p3 = rol64(X##p3, ROT##_1); \ X##p3 ^= X##p2; \ X##p4 += X##p5; \ - X##p5 = rotl_64(X##p5, ROT##_2); \ + X##p5 = rol64(X##p5, ROT##_2); \ X##p5 ^= X##p4; \ X##p6 += X##p7; \ - X##p7 = rotl_64(X##p7, ROT##_3); \ + X##p7 = rol64(X##p7, ROT##_3); \ X##p7 ^= X##p6; \ X##p8 += X##p9; \ - X##p9 = rotl_64(X##p9, ROT##_4); \ + X##p9 = rol64(X##p9, ROT##_4); \ X##p9 ^= X##p8; \ X##pA += X##pB; \ - X##pB = rotl_64(X##pB, ROT##_5); \ + X##pB = rol64(X##pB, ROT##_5); \ X##pB ^= X##pA; \ X##pC += X##pD; \ - X##pD = rotl_64(X##pD, ROT##_6); \ + X##pD = rol64(X##pD, ROT##_6); \ X##pD ^= X##pC; \ X##pE += X##pF; \ - X##pF = rotl_64(X##pF, ROT##_7); \ + X##pF = rol64(X##pF, ROT##_7); \ X##pF ^= X##pE; \ } while (0) -- cgit v1.2.3 From d3d62d1d6c479dd2058694c36b7d7d54cbe3d42f Mon Sep 17 00:00:00 2001 From: Clifton Barnes Date: Sun, 27 Mar 2016 15:13:00 -0400 Subject: staging: xgifb: fix 'line over 80 characters' fix checkpatch.pl warning about 'line over 80 characters' Signed-off-by: Clifton Barnes Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_init.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 26b539bc6faf..29da955493c1 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -551,7 +551,8 @@ static int XGINew_ReadWriteRest(unsigned short StopAddr, writel(Position, fbaddr + Position); } - usleep_range(500, 1500); /* Fix #1759 Memory Size error in Multi-Adapter. */ + /* Fix #1759 Memory Size error in Multi-Adapter. */ + usleep_range(500, 1500); Position = 0; -- cgit v1.2.3 From c3f0692aeed9e79f52c53284df7471aeb8006b43 Mon Sep 17 00:00:00 2001 From: Clifton Barnes Date: Sun, 27 Mar 2016 15:13:01 -0400 Subject: staging: xgifb: fix code indent fix checkpatch.pl warning about 'suspect code indent for conditional statements' Signed-off-by: Clifton Barnes Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_setmode.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 40939c86ab7c..cc1ad768918a 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -108,9 +108,9 @@ static void XGI_SetATTRegs(unsigned short ModeIdIndex, if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { ARdata = 0; } else if ((pVBInfo->VBInfo & - (SetCRT2ToTV | SetCRT2ToLCD)) && - (pVBInfo->VBInfo & SetInSlaveMode)) { - ARdata = 0; + (SetCRT2ToTV | SetCRT2ToLCD)) && + (pVBInfo->VBInfo & SetInSlaveMode)) { + ARdata = 0; } } @@ -2983,7 +2983,7 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, if ((pVBInfo->VBInfo & SetCRT2ToHiVision) && !(pVBInfo->VBType & VB_SIS301LV) && (resinfo == 7)) - temp -= 2; + temp -= 2; } /* 0x05 Horizontal Display Start */ -- cgit v1.2.3 From d312007698241b79153d5ac101bddb14fa9c4956 Mon Sep 17 00:00:00 2001 From: Clifton Barnes Date: Sun, 27 Mar 2016 15:13:03 -0400 Subject: staging: xgifb: fix bare use of 'unsigned' fix checkpatch.pl warning about 'Prefer 'unsigned int' to bare use of 'unsigned'' Signed-off-by: Clifton Barnes Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 5 +++-- drivers/staging/xgifb/vb_util.h | 8 +++++--- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 7eadf922b21f..d56ef1425f6b 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -1130,8 +1130,9 @@ static int XGIfb_get_cmap_len(const struct fb_var_screeninfo *var) return (var->bits_per_pixel == 8) ? 256 : 16; } -static int XGIfb_setcolreg(unsigned regno, unsigned red, unsigned green, - unsigned blue, unsigned transp, struct fb_info *info) +static int XGIfb_setcolreg(unsigned int regno, unsigned int red, + unsigned int green, unsigned int blue, + unsigned int transp, struct fb_info *info) { struct xgifb_video_info *xgifb_info = info->par; diff --git a/drivers/staging/xgifb/vb_util.h b/drivers/staging/xgifb/vb_util.h index f613f54d522f..08db58b396b2 100644 --- a/drivers/staging/xgifb/vb_util.h +++ b/drivers/staging/xgifb/vb_util.h @@ -13,7 +13,7 @@ static inline u8 xgifb_reg_get(unsigned long port, u8 index) } static inline void xgifb_reg_and_or(unsigned long port, u8 index, - unsigned data_and, unsigned data_or) + unsigned int data_and, unsigned int data_or) { u8 temp; @@ -22,7 +22,8 @@ static inline void xgifb_reg_and_or(unsigned long port, u8 index, xgifb_reg_set(port, index, temp); } -static inline void xgifb_reg_and(unsigned long port, u8 index, unsigned data_and) +static inline void xgifb_reg_and(unsigned long port, u8 index, + unsigned int data_and) { u8 temp; @@ -31,7 +32,8 @@ static inline void xgifb_reg_and(unsigned long port, u8 index, unsigned data_and xgifb_reg_set(port, index, temp); } -static inline void xgifb_reg_or(unsigned long port, u8 index, unsigned data_or) +static inline void xgifb_reg_or(unsigned long port, u8 index, + unsigned int data_or) { u8 temp; -- cgit v1.2.3 From 0d6b23a427a9c62f93a175187cedcd4f3a3a95d7 Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Sat, 26 Mar 2016 11:44:52 +0530 Subject: Staging: rtl8723au: Remove unused functions The functions rtw_get_oper_bw23a and rtw_get_oper_ch23aoffset are never used anywhere in the kernel. So, remove their definition and prototype. Grepped to find occurences. Signed-off-by: Bhumika Goyal Reviewed-by: Julian Calaby Acked-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_wlan_util.c | 10 ---------- drivers/staging/rtl8723au/include/rtw_mlme_ext.h | 2 -- 2 files changed, 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8723au/core/rtw_wlan_util.c b/drivers/staging/rtl8723au/core/rtw_wlan_util.c index cc2b84be9774..694cf17f82cf 100644 --- a/drivers/staging/rtl8723au/core/rtw_wlan_util.c +++ b/drivers/staging/rtl8723au/core/rtw_wlan_util.c @@ -304,21 +304,11 @@ inline void rtw_set_oper_ch23a(struct rtw_adapter *adapter, u8 ch) adapter_to_dvobj(adapter)->oper_channel = ch; } -inline u8 rtw_get_oper_bw23a(struct rtw_adapter *adapter) -{ - return adapter_to_dvobj(adapter)->oper_bwmode; -} - inline void rtw_set_oper_bw23a(struct rtw_adapter *adapter, u8 bw) { adapter_to_dvobj(adapter)->oper_bwmode = bw; } -inline u8 rtw_get_oper_ch23aoffset(struct rtw_adapter *adapter) -{ - return adapter_to_dvobj(adapter)->oper_ch_offset; -} - inline void rtw_set_oper_ch23aoffset23a(struct rtw_adapter *adapter, u8 offset) { adapter_to_dvobj(adapter)->oper_ch_offset = offset; diff --git a/drivers/staging/rtl8723au/include/rtw_mlme_ext.h b/drivers/staging/rtl8723au/include/rtw_mlme_ext.h index ea2a6c914d38..0e7d3da91471 100644 --- a/drivers/staging/rtl8723au/include/rtw_mlme_ext.h +++ b/drivers/staging/rtl8723au/include/rtw_mlme_ext.h @@ -461,9 +461,7 @@ void Update23aTblForSoftAP(u8 *bssrateset, u32 bssratelen); u8 rtw_get_oper_ch23a(struct rtw_adapter *adapter); void rtw_set_oper_ch23a(struct rtw_adapter *adapter, u8 ch); -u8 rtw_get_oper_bw23a(struct rtw_adapter *adapter); void rtw_set_oper_bw23a(struct rtw_adapter *adapter, u8 bw); -u8 rtw_get_oper_ch23aoffset(struct rtw_adapter *adapter); void rtw_set_oper_ch23aoffset23a(struct rtw_adapter *adapter, u8 offset); void set_channel_bwmode23a(struct rtw_adapter *padapter, unsigned char channel, -- cgit v1.2.3 From 15ac352c5402513bd7bee5cfe6439118b5a5f337 Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Sat, 26 Mar 2016 11:54:55 +0530 Subject: Staging: rtl8723au: Remove function rtw_enqueue_{recvbuf23a/recvbuf23a_to_head} The functions rtw_enqueue_recvbuf23a and rtw_enqueue_recvbuf23a_to_head are never used anywhere in the kernel. So, remove their definition and prototype. Grepped to find occurences. Signed-off-by: Bhumika Goyal Reviewed-by: Julian Calaby Acked-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_recv.c | 25 ------------------------- drivers/staging/rtl8723au/include/rtw_recv.h | 2 -- 2 files changed, 27 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8723au/core/rtw_recv.c b/drivers/staging/rtl8723au/core/rtw_recv.c index 989ed0726817..150dabc2a58d 100644 --- a/drivers/staging/rtl8723au/core/rtw_recv.c +++ b/drivers/staging/rtl8723au/core/rtw_recv.c @@ -211,31 +211,6 @@ u32 rtw_free_uc_swdec_pending_queue23a(struct rtw_adapter *adapter) return cnt; } -int rtw_enqueue_recvbuf23a_to_head(struct recv_buf *precvbuf, struct rtw_queue *queue) -{ - spin_lock_bh(&queue->lock); - - list_del_init(&precvbuf->list); - list_add(&precvbuf->list, get_list_head(queue)); - - spin_unlock_bh(&queue->lock); - - return _SUCCESS; -} - -int rtw_enqueue_recvbuf23a(struct recv_buf *precvbuf, struct rtw_queue *queue) -{ - unsigned long irqL; - - spin_lock_irqsave(&queue->lock, irqL); - - list_del_init(&precvbuf->list); - - list_add_tail(&precvbuf->list, get_list_head(queue)); - spin_unlock_irqrestore(&queue->lock, irqL); - return _SUCCESS; -} - struct recv_buf *rtw_dequeue_recvbuf23a (struct rtw_queue *queue) { unsigned long irqL; diff --git a/drivers/staging/rtl8723au/include/rtw_recv.h b/drivers/staging/rtl8723au/include/rtw_recv.h index dc784be3ddd9..85a5edb450e3 100644 --- a/drivers/staging/rtl8723au/include/rtw_recv.h +++ b/drivers/staging/rtl8723au/include/rtw_recv.h @@ -279,8 +279,6 @@ int rtw_enqueue_recvframe23a(struct recv_frame *precvframe, struct rtw_queue *qu u32 rtw_free_uc_swdec_pending_queue23a(struct rtw_adapter *adapter); -int rtw_enqueue_recvbuf23a_to_head(struct recv_buf *precvbuf, struct rtw_queue *queue); -int rtw_enqueue_recvbuf23a(struct recv_buf *precvbuf, struct rtw_queue *queue); struct recv_buf *rtw_dequeue_recvbuf23a(struct rtw_queue *queue); void rtw_reordering_ctrl_timeout_handler23a(unsigned long pcontext); -- cgit v1.2.3 From db71dd988af5ffdc6280e93977591b3ebc4c7673 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 23 Mar 2016 10:55:21 +0000 Subject: staging: comedi: drivers: remove bogus ni_mio_c_common.c The zero-length file "ni_mio_c_common.c" was inadvertantly created by commit e563637b5fef ("staging: comedi: Use ARRAY_SIZE for sizes of arrays"). Remove it. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_mio_c_common.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/ni_mio_c_common.c (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_mio_c_common.c b/drivers/staging/comedi/drivers/ni_mio_c_common.c deleted file mode 100644 index e69de29bb2d1..000000000000 -- cgit v1.2.3 From 7a4000e7128d9432ba78bc398bbedc6066825b80 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Fri, 25 Mar 2016 22:54:48 +0200 Subject: Staging: wlan-ng: no need for memcpy() since its arguments are already equal This patch removes the memcpy() for two variables which were previously tested with memcmp(). The result of memcmp() was zero which means that the previously tested variables were already equal. Signed-off-by: Claudiu Beznea Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/p80211conv.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/wlan-ng/p80211conv.c b/drivers/staging/wlan-ng/p80211conv.c index bdb50a51483b..6354036ffb42 100644 --- a/drivers/staging/wlan-ng/p80211conv.c +++ b/drivers/staging/wlan-ng/p80211conv.c @@ -243,7 +243,6 @@ static void orinoco_spy_gather(wlandevice_t *wlandev, char *mac, for (i = 0; i < wlandev->spy_number; i++) { if (!memcmp(wlandev->spy_address[i], mac, ETH_ALEN)) { - memcpy(wlandev->spy_address[i], mac, ETH_ALEN); wlandev->spy_stat[i].level = rxmeta->signal; wlandev->spy_stat[i].noise = rxmeta->noise; wlandev->spy_stat[i].qual = -- cgit v1.2.3 From 71fa2cf90ad46b925c27c372fac9b927e8014ebf Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Fri, 25 Mar 2016 23:28:54 +0200 Subject: Staging: wlan-ng: convert usb_prism_tbl[] array into a const array This patch convert usb_prism_tbl[] into a const array since it is not modified anywhere in prism2usb.c file. Signed-off-by: Claudiu Beznea Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/prism2usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/wlan-ng/prism2usb.c b/drivers/staging/wlan-ng/prism2usb.c index 41358bbc6246..b26d09ff840c 100644 --- a/drivers/staging/wlan-ng/prism2usb.c +++ b/drivers/staging/wlan-ng/prism2usb.c @@ -8,7 +8,7 @@ { USB_DEVICE(vid, pid), \ .driver_info = (unsigned long)name } -static struct usb_device_id usb_prism_tbl[] = { +static const struct usb_device_id usb_prism_tbl[] = { PRISM_DEV(0x04bb, 0x0922, "IOData AirPort WN-B11/USBS"), PRISM_DEV(0x07aa, 0x0012, "Corega Wireless LAN USB Stick-11"), PRISM_DEV(0x09aa, 0x3642, "Prism2.x 11Mbps WLAN USB Adapter"), -- cgit v1.2.3 From 686855e033faf191b499315758ae2c40f230a3bc Mon Sep 17 00:00:00 2001 From: Ben Marsh Date: Fri, 25 Mar 2016 22:44:48 +0100 Subject: Staging: gs_fpgaboot: remove blank line in io.c Removes a blank line in order to silence a checkpatch.pl warning. Signed-off-by: Ben Marsh Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gs_fpgaboot/io.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/gs_fpgaboot/io.c b/drivers/staging/gs_fpgaboot/io.c index 819db53da64d..c9391198fbfb 100644 --- a/drivers/staging/gs_fpgaboot/io.c +++ b/drivers/staging/gs_fpgaboot/io.c @@ -35,7 +35,6 @@ static inline void byte0_out(unsigned char data); static inline void byte1_out(unsigned char data); static inline void xl_cclk_b(int32_t i); - /* Assert and Deassert CCLK */ void xl_shift_cclk(int count) { -- cgit v1.2.3 From 3cb61bdf14af55e71095f4d11187a79116b30e3f Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Sat, 26 Mar 2016 12:42:43 +0530 Subject: Staging: rts5208: Remove unused functions The functions rtsx_disable_card_int, rtsx_undo_delink, rtsx_check_link_ready are not used anywhere in the kernel. So,remove their definition and prototype. Signed-off-by: Bhumika Goyal Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts5208/rtsx_chip.c | 35 ----------------------------------- drivers/staging/rts5208/rtsx_chip.h | 3 --- 2 files changed, 38 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rts5208/rtsx_chip.c b/drivers/staging/rts5208/rtsx_chip.c index c0ce659a5aa6..bcc4b666d79f 100644 --- a/drivers/staging/rts5208/rtsx_chip.c +++ b/drivers/staging/rts5208/rtsx_chip.c @@ -43,14 +43,6 @@ static void rtsx_calibration(struct rtsx_chip *chip) rtsx_write_phy_register(chip, 0x00, 0x0288); } -void rtsx_disable_card_int(struct rtsx_chip *chip) -{ - u32 reg = rtsx_readl(chip, RTSX_BIER); - - reg &= ~(XD_INT_EN | SD_INT_EN | MS_INT_EN); - rtsx_writel(chip, RTSX_BIER, reg); -} - void rtsx_enable_card_int(struct rtsx_chip *chip) { u32 reg = rtsx_readl(chip, RTSX_BIER); @@ -1447,12 +1439,6 @@ delink_stage: rtsx_delink_stage(chip); } -void rtsx_undo_delink(struct rtsx_chip *chip) -{ - chip->auto_delink_allowed = 0; - rtsx_write_register(chip, CHANGE_LINK_STATE, 0x0A, 0x00); -} - /** * rtsx_stop_cmd - stop command transfer and DMA transfer * @chip: Realtek's card reader chip @@ -2000,27 +1986,6 @@ int rtsx_set_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit) return STATUS_SUCCESS; } -int rtsx_check_link_ready(struct rtsx_chip *chip) -{ - int retval; - u8 val; - - retval = rtsx_read_register(chip, IRQSTAT0, &val); - if (retval) { - rtsx_trace(chip); - return retval; - } - - dev_dbg(rtsx_dev(chip), "IRQSTAT0: 0x%x\n", val); - if (val & LINK_RDY_INT) { - dev_dbg(rtsx_dev(chip), "Delinked!\n"); - rtsx_write_register(chip, IRQSTAT0, LINK_RDY_INT, LINK_RDY_INT); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - static void rtsx_handle_pm_dstate(struct rtsx_chip *chip, u8 dstate) { u32 ultmp; diff --git a/drivers/staging/rts5208/rtsx_chip.h b/drivers/staging/rts5208/rtsx_chip.h index c295b1eedb44..c08164f3247e 100644 --- a/drivers/staging/rts5208/rtsx_chip.h +++ b/drivers/staging/rts5208/rtsx_chip.h @@ -950,7 +950,6 @@ do { \ int rtsx_force_power_on(struct rtsx_chip *chip, u8 ctl); int rtsx_force_power_down(struct rtsx_chip *chip, u8 ctl); -void rtsx_disable_card_int(struct rtsx_chip *chip); void rtsx_enable_card_int(struct rtsx_chip *chip); void rtsx_enable_bus_int(struct rtsx_chip *chip); void rtsx_disable_bus_int(struct rtsx_chip *chip); @@ -958,7 +957,6 @@ int rtsx_reset_chip(struct rtsx_chip *chip); int rtsx_init_chip(struct rtsx_chip *chip); void rtsx_release_chip(struct rtsx_chip *chip); void rtsx_polling_func(struct rtsx_chip *chip); -void rtsx_undo_delink(struct rtsx_chip *chip); void rtsx_stop_cmd(struct rtsx_chip *chip, int card); int rtsx_write_register(struct rtsx_chip *chip, u16 addr, u8 mask, u8 data); int rtsx_read_register(struct rtsx_chip *chip, u16 addr, u8 *data); @@ -975,7 +973,6 @@ int rtsx_read_efuse(struct rtsx_chip *chip, u8 addr, u8 *val); int rtsx_write_efuse(struct rtsx_chip *chip, u8 addr, u8 val); int rtsx_clr_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit); int rtsx_set_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit); -int rtsx_check_link_ready(struct rtsx_chip *chip); void rtsx_enter_ss(struct rtsx_chip *chip); void rtsx_exit_ss(struct rtsx_chip *chip); int rtsx_pre_handle_interrupt(struct rtsx_chip *chip); -- cgit v1.2.3 From 143b3bf6d3f7e14945af589414f1bd29efe36a72 Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Sat, 26 Mar 2016 12:52:28 +0530 Subject: Staging: rts5208: rtsx_card.c: Remove unused function The functions double_depth, check_card_fail, check_card_ejected are not used anywhere in the kernel. So, remove their prototype and definition. Grepped to find occurences. Signed-off-by: Bhumika Goyal Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts5208/rtsx_card.c | 21 --------------------- drivers/staging/rts5208/rtsx_card.h | 2 -- 2 files changed, 23 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rts5208/rtsx_card.c b/drivers/staging/rts5208/rtsx_card.c index 437436f5dbdd..231833a3045e 100644 --- a/drivers/staging/rts5208/rtsx_card.c +++ b/drivers/staging/rts5208/rtsx_card.c @@ -628,11 +628,6 @@ void rtsx_init_cards(struct rtsx_chip *chip) } } -static inline u8 double_depth(u8 depth) -{ - return (depth > 1) ? (depth - 1) : depth; -} - int switch_ssc_clock(struct rtsx_chip *chip, int clk) { int retval; @@ -1184,22 +1179,6 @@ int check_card_wp(struct rtsx_chip *chip, unsigned int lun) return 0; } -int check_card_fail(struct rtsx_chip *chip, unsigned int lun) -{ - if (chip->card_fail & chip->lun2card[lun]) - return 1; - - return 0; -} - -int check_card_ejected(struct rtsx_chip *chip, unsigned int lun) -{ - if (chip->card_ejected & chip->lun2card[lun]) - return 1; - - return 0; -} - u8 get_lun_card(struct rtsx_chip *chip, unsigned int lun) { if ((chip->card_ready & chip->lun2card[lun]) == XD_CARD) diff --git a/drivers/staging/rts5208/rtsx_card.h b/drivers/staging/rts5208/rtsx_card.h index 8f2cf9a4ec69..56df9a431d6d 100644 --- a/drivers/staging/rts5208/rtsx_card.h +++ b/drivers/staging/rts5208/rtsx_card.h @@ -1024,8 +1024,6 @@ int detect_card_cd(struct rtsx_chip *chip, int card); int check_card_exist(struct rtsx_chip *chip, unsigned int lun); int check_card_ready(struct rtsx_chip *chip, unsigned int lun); int check_card_wp(struct rtsx_chip *chip, unsigned int lun); -int check_card_fail(struct rtsx_chip *chip, unsigned int lun); -int check_card_ejected(struct rtsx_chip *chip, unsigned int lun); void eject_card(struct rtsx_chip *chip, unsigned int lun); u8 get_lun_card(struct rtsx_chip *chip, unsigned int lun); -- cgit v1.2.3 From ae6b08672fd1802abbdd12dcda7553a7f1f009ad Mon Sep 17 00:00:00 2001 From: Aniket Sharma Date: Sun, 27 Mar 2016 10:52:19 -0700 Subject: Staging: comedi: Fix 'unsigned' warning style This patch fixes the checkpatch.pl warning: WARNING: Prefer 'unsigned int' to bare use of 'unsigned' + unsigned runflags; WARNING: Prefer 'unsigned int' to bare use of 'unsigned' +struct comedi_device *comedi_dev_get_from_minor(unsigned minor); Signed-off-by: Aniket Sharma Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 115807215484..dcb637665eb7 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -173,7 +173,7 @@ struct comedi_subdevice { void *lock; void *busy; - unsigned runflags; + unsigned int runflags; spinlock_t spin_lock; /* generic spin-lock for COMEDI and drivers */ unsigned int io_bits; @@ -566,7 +566,7 @@ struct comedi_device { void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s); -struct comedi_device *comedi_dev_get_from_minor(unsigned minor); +struct comedi_device *comedi_dev_get_from_minor(unsigned int minor); int comedi_dev_put(struct comedi_device *dev); bool comedi_is_subdevice_running(struct comedi_subdevice *s); -- cgit v1.2.3 From b2073dcb80b61043f6ae6aeb2311907b0418392a Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 29 Mar 2016 10:49:04 +0100 Subject: staging: comedi: comedi_fops.c: fix lines over 80 characters Fix checkpatch.pl warnings about lines over 80 characters in "comedi_fops.c". Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 4bdea202c46c..629080f39db0 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -209,8 +209,8 @@ static void comedi_free_board_dev(struct comedi_device *dev) } } -static struct comedi_subdevice -*comedi_subdevice_from_minor(const struct comedi_device *dev, unsigned int minor) +static struct comedi_subdevice * +comedi_subdevice_from_minor(const struct comedi_device *dev, unsigned int minor) { struct comedi_subdevice *s; unsigned int i = minor - COMEDI_NUM_BOARD_MINORS; @@ -233,7 +233,8 @@ static struct comedi_device *comedi_dev_get_from_board_minor(unsigned int minor) return dev; } -static struct comedi_device *comedi_dev_get_from_subdevice_minor(unsigned int minor) +static struct comedi_device * +comedi_dev_get_from_subdevice_minor(unsigned int minor) { struct comedi_device *dev; struct comedi_subdevice *s; @@ -342,7 +343,8 @@ static struct comedi_subdevice *comedi_file_write_subdevice(struct file *file) } static int resize_async_buffer(struct comedi_device *dev, - struct comedi_subdevice *s, unsigned int new_size) + struct comedi_subdevice *s, + unsigned int new_size) { struct comedi_async *async = s->async; int retval; @@ -628,7 +630,8 @@ static void __comedi_set_subdevice_runflags(struct comedi_subdevice *s, } static void comedi_update_subdevice_runflags(struct comedi_subdevice *s, - unsigned int mask, unsigned int bits) + unsigned int mask, + unsigned int bits) { unsigned long flags; @@ -2485,7 +2488,8 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, n = min_t(size_t, m, nbytes); if (n == 0) { - unsigned int runflags = comedi_get_subdevice_runflags(s); + unsigned int runflags = + comedi_get_subdevice_runflags(s); if (!comedi_is_runflags_running(runflags)) { if (comedi_is_runflags_in_error(runflags)) -- cgit v1.2.3 From eeb6f1ba921d413157282a573290c0eb57d549d7 Mon Sep 17 00:00:00 2001 From: Dominique van den Broeck Date: Tue, 29 Mar 2016 19:14:20 +0200 Subject: staging: fwserial: (coding style) Turning every "unsigned" into "unsigned int" Coding-style-only modifications to remove every warning saying: WARNING: Prefer 'unsigned int' to bare use of 'unsigned' Compiled against revision "next-20160327". (checkpatch.pl was updated to treat "UNSPECIFIED_INT" warnings as of commit a1ce18e4f941d20 ) Signed-off-by: Dominique van den Broeck Signed-off-by: Greg Kroah-Hartman --- drivers/staging/fwserial/dma_fifo.c | 8 +++---- drivers/staging/fwserial/dma_fifo.h | 16 +++++++------- drivers/staging/fwserial/fwserial.c | 38 +++++++++++++++++---------------- drivers/staging/fwserial/fwserial.h | 42 ++++++++++++++++++------------------- 4 files changed, 53 insertions(+), 51 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/fwserial/dma_fifo.c b/drivers/staging/fwserial/dma_fifo.c index 4cd3ed3ee141..8b23a553fd4a 100644 --- a/drivers/staging/fwserial/dma_fifo.c +++ b/drivers/staging/fwserial/dma_fifo.c @@ -35,7 +35,7 @@ /* * private helper fn to determine if check is in open interval (lo,hi) */ -static bool addr_check(unsigned check, unsigned lo, unsigned hi) +static bool addr_check(unsigned int check, unsigned int lo, unsigned int hi) { return check - (lo + 1) < (hi - 1) - lo; } @@ -64,7 +64,7 @@ void dma_fifo_init(struct dma_fifo *fifo) * The 'apparent' size will be rounded up to next greater aligned size. * Returns 0 if no error, otherwise an error code */ -int dma_fifo_alloc(struct dma_fifo *fifo, int size, unsigned align, +int dma_fifo_alloc(struct dma_fifo *fifo, int size, unsigned int align, int tx_limit, int open_limit, gfp_t gfp_mask) { int capacity; @@ -190,7 +190,7 @@ int dma_fifo_in(struct dma_fifo *fifo, const void *src, int n) */ int dma_fifo_out_pend(struct dma_fifo *fifo, struct dma_pending *pended) { - unsigned len, n, ofs, l, limit; + unsigned int len, n, ofs, l, limit; if (!fifo->data) return -ENOENT; @@ -210,7 +210,7 @@ int dma_fifo_out_pend(struct dma_fifo *fifo, struct dma_pending *pended) n = len; ofs = fifo->out % fifo->capacity; l = fifo->capacity - ofs; - limit = min_t(unsigned, l, fifo->tx_limit); + limit = min_t(unsigned int, l, fifo->tx_limit); if (n > limit) { n = limit; fifo->out += limit; diff --git a/drivers/staging/fwserial/dma_fifo.h b/drivers/staging/fwserial/dma_fifo.h index 410988224f89..37a91c6a1709 100644 --- a/drivers/staging/fwserial/dma_fifo.h +++ b/drivers/staging/fwserial/dma_fifo.h @@ -45,9 +45,9 @@ #define DMA_FIFO_GUARD 3 /* # of cache lines to reserve for the guard area */ struct dma_fifo { - unsigned in; - unsigned out; /* updated when dma is pended */ - unsigned done; /* updated upon dma completion */ + unsigned int in; + unsigned int out; /* updated when dma is pended */ + unsigned int done; /* updated upon dma completion */ struct { unsigned corrupt:1; }; @@ -55,7 +55,7 @@ struct dma_fifo { int guard; /* ofs of guard area */ int capacity; /* size + reserved */ int avail; /* # of unused bytes in fifo */ - unsigned align; /* must be power of 2 */ + unsigned int align; /* must be power of 2 */ int tx_limit; /* max # of bytes per dma transaction */ int open_limit; /* max # of outstanding allowed */ int open; /* # of outstanding dma transactions */ @@ -66,9 +66,9 @@ struct dma_fifo { struct dma_pending { struct list_head link; void *data; - unsigned len; - unsigned next; - unsigned out; + unsigned int len; + unsigned int next; + unsigned int out; }; static inline void dp_mark_completed(struct dma_pending *dp) @@ -82,7 +82,7 @@ static inline bool dp_is_completed(struct dma_pending *dp) } void dma_fifo_init(struct dma_fifo *fifo); -int dma_fifo_alloc(struct dma_fifo *fifo, int size, unsigned align, +int dma_fifo_alloc(struct dma_fifo *fifo, int size, unsigned int align, int tx_limit, int open_limit, gfp_t gfp_mask); void dma_fifo_free(struct dma_fifo *fifo); void dma_fifo_reset(struct dma_fifo *fifo); diff --git a/drivers/staging/fwserial/fwserial.c b/drivers/staging/fwserial/fwserial.c index 9b23b5c95f5e..66e54e767c98 100644 --- a/drivers/staging/fwserial/fwserial.c +++ b/drivers/staging/fwserial/fwserial.c @@ -132,7 +132,7 @@ static struct fwtty_peer *__fwserial_peer_by_node_id(struct fw_card *card, #ifdef FWTTY_PROFILING -static void fwtty_profile_fifo(struct fwtty_port *port, unsigned *stat) +static void fwtty_profile_fifo(struct fwtty_port *port, unsigned int *stat) { spin_lock_bh(&port->lock); fwtty_profile_data(stat, dma_fifo_avail(&port->tx_fifo)); @@ -143,7 +143,7 @@ static void fwtty_dump_profile(struct seq_file *m, struct stats *stats) { /* for each stat, print sum of 0 to 2^k, then individually */ int k = 4; - unsigned sum; + unsigned int sum; int j; char t[10]; @@ -303,9 +303,10 @@ static void fwtty_restart_tx(struct fwtty_port *port) * Note: in loopback, the port->lock is being held. Only use functions that * don't attempt to reclaim the port->lock. */ -static void fwtty_update_port_status(struct fwtty_port *port, unsigned status) +static void fwtty_update_port_status(struct fwtty_port *port, + unsigned int status) { - unsigned delta; + unsigned int delta; struct tty_struct *tty; /* simulated LSR/MSR status from remote */ @@ -396,9 +397,9 @@ static void fwtty_update_port_status(struct fwtty_port *port, unsigned status) * * Note: caller must be holding port lock */ -static unsigned __fwtty_port_line_status(struct fwtty_port *port) +static unsigned int __fwtty_port_line_status(struct fwtty_port *port) { - unsigned status = 0; + unsigned int status = 0; /* TODO: add module param to tie RNG to DTR as well */ @@ -424,7 +425,7 @@ static int __fwtty_write_port_status(struct fwtty_port *port) { struct fwtty_peer *peer; int err = -ENOENT; - unsigned status = __fwtty_port_line_status(port); + unsigned int status = __fwtty_port_line_status(port); rcu_read_lock(); peer = rcu_dereference(port->peer); @@ -454,7 +455,7 @@ static int fwtty_write_port_status(struct fwtty_port *port) static void fwtty_throttle_port(struct fwtty_port *port) { struct tty_struct *tty; - unsigned old; + unsigned int old; tty = tty_port_tty_get(&port->port); if (!tty) @@ -540,7 +541,7 @@ static void fwtty_emit_breaks(struct work_struct *work) static int fwtty_rx(struct fwtty_port *port, unsigned char *data, size_t len) { int c, n = len; - unsigned lsr; + unsigned int lsr; int err = 0; fwtty_dbg(port, "%d\n", n); @@ -635,7 +636,7 @@ static void fwtty_port_handler(struct fw_card *card, if (addr != port->rx_handler.offset || len != 4) { rcode = RCODE_ADDRESS_ERROR; } else { - fwtty_update_port_status(port, *(unsigned *)data); + fwtty_update_port_status(port, *(unsigned int *)data); rcode = RCODE_COMPLETE; } break; @@ -828,7 +829,7 @@ static void fwtty_write_xchar(struct fwtty_port *port, char ch) rcu_read_unlock(); } -static struct fwtty_port *fwtty_port_get(unsigned index) +static struct fwtty_port *fwtty_port_get(unsigned int index) { struct fwtty_port *port; @@ -934,9 +935,9 @@ static int fwtty_port_carrier_raised(struct tty_port *tty_port) return rc; } -static unsigned set_termios(struct fwtty_port *port, struct tty_struct *tty) +static unsigned int set_termios(struct fwtty_port *port, struct tty_struct *tty) { - unsigned baud, frame; + unsigned int baud, frame; baud = tty_termios_baud_rate(&tty->termios); tty_termios_encode_baud_rate(&tty->termios, baud, baud); @@ -988,7 +989,7 @@ static int fwtty_port_activate(struct tty_port *tty_port, struct tty_struct *tty) { struct fwtty_port *port = to_port(tty_port, port); - unsigned baud; + unsigned int baud; int err; set_bit(TTY_IO_ERROR, &tty->flags); @@ -1264,7 +1265,7 @@ static int set_serial_info(struct fwtty_port *port, return 0; } -static int fwtty_ioctl(struct tty_struct *tty, unsigned cmd, +static int fwtty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct fwtty_port *port = tty->driver_data; @@ -1297,7 +1298,7 @@ static int fwtty_ioctl(struct tty_struct *tty, unsigned cmd, static void fwtty_set_termios(struct tty_struct *tty, struct ktermios *old) { struct fwtty_port *port = tty->driver_data; - unsigned baud; + unsigned int baud; spin_lock_bh(&port->lock); baud = set_termios(port, tty); @@ -1369,7 +1370,7 @@ static int fwtty_break_ctl(struct tty_struct *tty, int state) static int fwtty_tiocmget(struct tty_struct *tty) { struct fwtty_port *port = tty->driver_data; - unsigned tiocm; + unsigned int tiocm; spin_lock_bh(&port->lock); tiocm = (port->mctrl & MCTRL_MASK) | (port->mstatus & ~MCTRL_MASK); @@ -1380,7 +1381,8 @@ static int fwtty_tiocmget(struct tty_struct *tty) return tiocm; } -static int fwtty_tiocmset(struct tty_struct *tty, unsigned set, unsigned clear) +static int fwtty_tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) { struct fwtty_port *port = tty->driver_data; diff --git a/drivers/staging/fwserial/fwserial.h b/drivers/staging/fwserial/fwserial.h index 6fa936501b3f..30b2481fe32b 100644 --- a/drivers/staging/fwserial/fwserial.h +++ b/drivers/staging/fwserial/fwserial.h @@ -22,7 +22,7 @@ #ifdef FWTTY_PROFILING #define DISTRIBUTION_MAX_SIZE 8192 #define DISTRIBUTION_MAX_INDEX (ilog2(DISTRIBUTION_MAX_SIZE) + 1) -static inline void fwtty_profile_data(unsigned stat[], unsigned val) +static inline void fwtty_profile_data(unsigned int stat[], unsigned int val) { int n = (val) ? min(ilog2(val) + 1, DISTRIBUTION_MAX_INDEX) : 0; ++stat[n]; @@ -78,7 +78,7 @@ struct fwtty_peer { u64 guid; int generation; int node_id; - unsigned speed; + unsigned int speed; int max_payload; u64 mgmt_addr; @@ -160,17 +160,17 @@ struct fwserial_mgmt_pkt { #define VIRT_CABLE_PLUG_TIMEOUT (60 * HZ) struct stats { - unsigned xchars; - unsigned dropped; - unsigned tx_stall; - unsigned fifo_errs; - unsigned sent; - unsigned lost; - unsigned throttled; - unsigned reads[DISTRIBUTION_MAX_INDEX + 1]; - unsigned writes[DISTRIBUTION_MAX_INDEX + 1]; - unsigned txns[DISTRIBUTION_MAX_INDEX + 1]; - unsigned unthrottle[DISTRIBUTION_MAX_INDEX + 1]; + unsigned int xchars; + unsigned int dropped; + unsigned int tx_stall; + unsigned int fifo_errs; + unsigned int sent; + unsigned int lost; + unsigned int throttled; + unsigned int reads[DISTRIBUTION_MAX_INDEX + 1]; + unsigned int writes[DISTRIBUTION_MAX_INDEX + 1]; + unsigned int txns[DISTRIBUTION_MAX_INDEX + 1]; + unsigned int unthrottle[DISTRIBUTION_MAX_INDEX + 1]; }; struct fwconsole_ops { @@ -237,7 +237,7 @@ struct fwconsole_ops { struct fwtty_port { struct tty_port port; struct device *device; - unsigned index; + unsigned int index; struct fw_serial *serial; struct fw_address_handler rx_handler; @@ -246,21 +246,21 @@ struct fwtty_port { wait_queue_head_t wait_tx; struct delayed_work emit_breaks; - unsigned cps; + unsigned int cps; unsigned long break_last; struct work_struct hangup; - unsigned mstatus; + unsigned int mstatus; spinlock_t lock; - unsigned mctrl; + unsigned int mctrl; struct delayed_work drain; struct dma_fifo tx_fifo; int max_payload; - unsigned status_mask; - unsigned ignore_mask; - unsigned break_ctl:1, + unsigned int status_mask; + unsigned int ignore_mask; + unsigned int break_ctl:1, write_only:1, overrun:1, loopback:1; @@ -349,7 +349,7 @@ extern struct tty_driver *fwtty_driver; * being used for isochronous traffic) * 2) isochronous arbitration always wins. */ -static inline int link_speed_to_max_payload(unsigned speed) +static inline int link_speed_to_max_payload(unsigned int speed) { /* Max async payload is 4096 - see IEEE 1394-2008 tables 6-4, 16-18 */ return min(512 << speed, 4096); -- cgit v1.2.3 From 7d47383dcb3f5867de56ac04ce46db06ac47ad0b Mon Sep 17 00:00:00 2001 From: Dominique van den Broeck Date: Tue, 29 Mar 2016 19:14:21 +0200 Subject: staging: fwserial: (coding style) removing "!= NULL" to comply with checkpatch.pl Removing two "!= NULL" from fwserial.c as suggested by checkpatch.pl. Note that the associated expression "port->port.console" is a 1-bit-field that is already assumed as an implicit boolean (that is: without comparison) Signed-off-by: Dominique van den Broeck Signed-off-by: Greg Kroah-Hartman --- drivers/staging/fwserial/fwserial.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/fwserial/fwserial.c b/drivers/staging/fwserial/fwserial.c index 66e54e767c98..4dd5304cb718 100644 --- a/drivers/staging/fwserial/fwserial.c +++ b/drivers/staging/fwserial/fwserial.c @@ -1701,7 +1701,7 @@ static void fwserial_virt_plug_complete(struct fwtty_peer *peer, dma_fifo_change_tx_limit(&port->tx_fifo, port->max_payload); spin_unlock_bh(&peer->port->lock); - if (port->port.console && port->fwcon_ops->notify != NULL) + if (port->port.console && port->fwcon_ops->notify) (*port->fwcon_ops->notify)(FWCON_NOTIFY_ATTACH, port->con_data); fwtty_info(&peer->unit, "peer (guid:%016llx) connected on %s\n", @@ -1808,7 +1808,7 @@ static void fwserial_release_port(struct fwtty_port *port, bool reset) RCU_INIT_POINTER(port->peer, NULL); spin_unlock_bh(&port->lock); - if (port->port.console && port->fwcon_ops->notify != NULL) + if (port->port.console && port->fwcon_ops->notify) (*port->fwcon_ops->notify)(FWCON_NOTIFY_DETACH, port->con_data); } -- cgit v1.2.3 From f0e00da2db61c9052fbc07edf2b2bf615b7a4bbe Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Tue, 29 Mar 2016 17:53:23 +0100 Subject: staging: sm750fb: initialize max_d to maximum D value of 6 max_d is not initialized and should be set to the largest D value of 6. Signed-off-by: Colin Ian King Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sm750fb/ddk750_chip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/sm750fb/ddk750_chip.c b/drivers/staging/sm750fb/ddk750_chip.c index 95f7cae3cc23..f80ee776677f 100644 --- a/drivers/staging/sm750fb/ddk750_chip.c +++ b/drivers/staging/sm750fb/ddk750_chip.c @@ -306,7 +306,7 @@ unsigned int calcPllValue(unsigned int request_orig, pll_value_t *pll) unsigned int input, request; unsigned int tmpClock, ret; const int max_OD = 3; - int max_d; + int max_d = 6; if (getChipType() == SM750LE) { /* SM750LE don't have prgrammable PLL and M/N values to work on. -- cgit v1.2.3 From 9fca845577c07e7bbd659625e03dfda8ebda4b91 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Sat, 26 Mar 2016 10:54:13 +0200 Subject: Staging: wlan-ng: removed "next" member of wlandevice_t since it is not used anywhere in code. This patch removes "next" member of wlandevice_t since it is not used anywhere in the wlan-ng code. Signed-off-by: Claudiu Beznea Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/p80211netdev.h | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/wlan-ng/p80211netdev.h b/drivers/staging/wlan-ng/p80211netdev.h index 810ee68aa18e..820a0e20a941 100644 --- a/drivers/staging/wlan-ng/p80211netdev.h +++ b/drivers/staging/wlan-ng/p80211netdev.h @@ -158,7 +158,6 @@ extern int wlan_wext_write; /* WLAN device type */ typedef struct wlandevice { - struct wlandevice *next; /* link for list of devices */ void *priv; /* private data for MSD */ /* Subsystem State */ -- cgit v1.2.3 From a7442b93cf32c1e1ddb721a26cd1f92302e2a222 Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Wed, 9 Mar 2016 12:52:53 +0100 Subject: drm/i915: Fix races on fbdev MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ->lastclose callback invokes intel_fbdev_restore_mode() and has been witnessed to run before intel_fbdev_initial_config_async() has finished. We might likewise receive hotplug events before we've had a chance to fully set up the fbdev. Fix by waiting for the asynchronous thread to finish. v2: An async_synchronize_full() was also added to intel_fbdev_set_suspend() in v1 which turned out to be entirely gratuitous. It caused a deadlock on suspend (discovered by CI, thanks to Damien Lespiau and Tomi Sarvela for CI support) and was unnecessary since a device is never suspended until its ->probe callback (and all asynchronous tasks it scheduled) have finished. See dpm_prepare(), which calls wait_for_device_probe(), which calls async_synchronize_full(). Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93580 Reported-by: Gustav Fägerlind Reported-by: "Li, Weinan Z" Cc: Chris Wilson Cc: stable@vger.kernel.org Signed-off-by: Lukas Wunner Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20160309115147.67B2B6E0D3@gabe.freedesktop.org --- drivers/gpu/drm/i915/i915_dma.c | 8 +++----- drivers/gpu/drm/i915/intel_fbdev.c | 3 +++ 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index fc8ac98c12d7..1ac1ea969eec 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -493,11 +493,9 @@ static int i915_load_modeset_init(struct drm_device *dev) * Some ports require correctly set-up hpd registers for detection to * work properly (leading to ghost connected connector status), e.g. VGA * on gm45. Hence we can only set up the initial fbdev config after hpd - * irqs are fully enabled. Now we should scan for the initial config - * only once hotplug handling is enabled, but due to screwed-up locking - * around kms/fbdev init we can't protect the fdbev initial config - * scanning against hotplug events. Hence do this first and ignore the - * tiny window where we will loose hotplug notifactions. + * irqs are fully enabled. We protect the fbdev initial config scanning + * against hotplug events by waiting in intel_fbdev_output_poll_changed + * until the asynchronous thread has finished. */ intel_fbdev_initial_config_async(dev); diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index 5e0dcb3961be..153ea7a3fcf6 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -808,6 +808,8 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous void intel_fbdev_output_poll_changed(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + + async_synchronize_full(); if (dev_priv->fbdev) drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper); } @@ -819,6 +821,7 @@ void intel_fbdev_restore_mode(struct drm_device *dev) struct intel_fbdev *ifbdev = dev_priv->fbdev; struct drm_fb_helper *fb_helper; + async_synchronize_full(); if (!ifbdev) return; -- cgit v1.2.3 From a16b7658f4e0d4aec9bc3e75a5f0cc3f7a3a0422 Mon Sep 17 00:00:00 2001 From: Lyude Date: Fri, 11 Mar 2016 10:57:01 -0500 Subject: drm/i915: Call intel_dp_mst_resume() before resuming displays Since we need MST devices ready before we try to resume displays, calling this after intel_display_resume() can result in some issues with various laptop docks where the monitor won't turn back on after suspending the system. This order was originally changed in commit e7d6f7d70829 ("drm/i915: resume MST after reading back hw state") In order to fix some unclaimed register errors, however the actual cause of those has since been fixed. CC: stable@vger.kernel.org Signed-off-by: Lyude [danvet: Resolve conflicts with locking changes.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 20f8dbe7b21c..f73b4f7b2d39 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -770,10 +770,10 @@ static int i915_drm_resume(struct drm_device *dev) dev_priv->display.hpd_irq_setup(dev); spin_unlock_irq(&dev_priv->irq_lock); - intel_display_resume(dev); - intel_dp_mst_resume(dev); + intel_display_resume(dev); + /* * ... but also need to make sure that hotplug processing * doesn't cause havoc. Like in the driver load code we don't -- cgit v1.2.3 From a91d7b9142b91c9567bc0304cb7d718ac411e85e Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 29 Mar 2016 13:12:22 +0200 Subject: Revert "drm: Don't pass negative delta to ktime_sub_ns()" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit e91abf80a0998f326107874c88d549f94839f13c. Since commit 24e4a8c3e8868874835b0f1ad6dd417341e99822 Author: John Stultz Date: Wed Jul 16 21:03:53 2014 +0000 ktime: Kill non-scalar ktime_t implementation for 2038 there is no longer a 32bit version that's unsigned, and we don't have to jump through ridiculous hoops to make the calculations correct. I didn't look whether there's more of this pattern in the kernel. Cc: John Stultz Cc: Thomas Gleixner Cc: Michel Dänzer Cc: Imre Deak Cc: Dave Airlie Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1459249942-21589-1-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/drm_irq.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 96d03ac38ef7..bfc4b379f0b5 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -805,10 +805,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, /* Subtract time delta from raw timestamp to get final * vblank_time timestamp for end of vblank. */ - if (delta_ns < 0) - etime = ktime_add_ns(etime, -delta_ns); - else - etime = ktime_sub_ns(etime, delta_ns); + etime = ktime_sub_ns(etime, delta_ns); *vblank_time = ktime_to_timeval(etime); DRM_DEBUG_VBL("crtc %u : v 0x%x p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d rep]\n", -- cgit v1.2.3 From 68d4aee9d1f271fe06e904cb99a10cf8479d3d2e Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 30 Mar 2016 09:33:11 +0200 Subject: drm/i915: Update DRIVER_DATE to 20160330 Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0906dfd7b1a9..f6d71590bd7b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -60,7 +60,7 @@ #define DRIVER_NAME "i915" #define DRIVER_DESC "Intel Graphics" -#define DRIVER_DATE "20160314" +#define DRIVER_DATE "20160330" #undef WARN_ON /* Many gcc seem to no see through this and fall over :( */ -- cgit v1.2.3 From 67535531b1b2bfcc707c8c37f35196cf4ede4252 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Wed, 30 Mar 2016 14:53:24 +0530 Subject: drm: bridge/dw-hdmi: Remove pre_enable/post_disable dummy funcs We don't need to keep empty callbacks for the (pre/post) enable/disable drm_bridge ops anymore. Remove the nop callback used here for pre_enable and post_disable ops. Signed-off-by: Archit Taneja Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1459329804-10488-1-git-send-email-architt@codeaurora.org --- drivers/gpu/drm/bridge/dw-hdmi.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c index 9795b72472ba..c9d941283d30 100644 --- a/drivers/gpu/drm/bridge/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/dw-hdmi.c @@ -1413,11 +1413,6 @@ static void dw_hdmi_bridge_enable(struct drm_bridge *bridge) mutex_unlock(&hdmi->mutex); } -static void dw_hdmi_bridge_nop(struct drm_bridge *bridge) -{ - /* do nothing */ -} - static enum drm_connector_status dw_hdmi_connector_detect(struct drm_connector *connector, bool force) { @@ -1536,8 +1531,6 @@ static const struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = { .enable = dw_hdmi_bridge_enable, .disable = dw_hdmi_bridge_disable, - .pre_enable = dw_hdmi_bridge_nop, - .post_disable = dw_hdmi_bridge_nop, .mode_set = dw_hdmi_bridge_mode_set, }; -- cgit v1.2.3 From 9f54d4bd5808b5c892a44c539c126b71d299f341 Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Wed, 30 Mar 2016 11:08:33 +0200 Subject: drm/i915: fix deadlock on lid open MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit e2c8b8701e2d moved modeset locking inside resume/suspend functions, but missed a code path only executed on lid close/open on older hardware. The result was a deadlock when closing and opening the lid without suspending on such hardware: ============================================= [ INFO: possible recursive locking detected ] 4.6.0-rc1 #385 Not tainted --------------------------------------------- kworker/0:3/88 is trying to acquire lock: (&dev->mode_config.mutex){+.+.+.}, at: [] intel_display_resume+0x4a/0x12f [i915] but task is already holding lock: (&dev->mode_config.mutex){+.+.+.}, at: [] drm_modeset_lock_all+0x3e/0xa6 [drm] other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(&dev->mode_config.mutex); lock(&dev->mode_config.mutex); *** DEADLOCK *** May be due to missing lock nesting notation 7 locks held by kworker/0:3/88: #0: ("kacpi_notify"){++++.+}, at: [] process_one_work+0x14a/0x50b #1: ((&dpc->work)#2){+.+.+.}, at: [] process_one_work+0x14a/0x50b #2: ((acpi_lid_notifier).rwsem){++++.+}, at: [] __blocking_notifier_call_chain+0x34/0x65 #3: (&dev_priv->modeset_restore_lock){+.+.+.}, at: [] intel_lid_notify+0x3c/0xd9 [i915] #4: (&dev->mode_config.mutex){+.+.+.}, at: [] drm_modeset_lock_all+0x3e/0xa6 [drm] #5: (crtc_ww_class_acquire){+.+.+.}, at: [] drm_modeset_lock_all+0x48/0xa6 [drm] #6: (crtc_ww_class_mutex){+.+.+.}, at: [] modeset_lock+0x13c/0x1cd [drm] stack backtrace: CPU: 0 PID: 88 Comm: kworker/0:3 Not tainted 4.6.0-rc1 #385 Hardware name: LENOVO 2776LEG/2776LEG, BIOS 6EET55WW (3.15 ) 12/19/2011 Workqueue: kacpi_notify acpi_os_execute_deferred 0000000000000000 ffff88022fd5f990 ffffffff8124af06 ffffffff825b39c0 ffffffff825b39c0 ffff88022fd5fa60 ffffffff8108f547 ffff88022fd5fa70 000000008108e817 ffff880230236cc0 0000000000000000 ffffffff825b39c0 Call Trace: [] dump_stack+0x67/0x90 [] __lock_acquire+0xdb5/0xf71 [] ? look_up_lock_class+0xbe/0x10a [] lock_acquire+0x137/0x1cb [] ? lock_acquire+0x137/0x1cb [] ? intel_display_resume+0x4a/0x12f [i915] [] mutex_lock_nested+0x7e/0x3a4 [] ? intel_display_resume+0x4a/0x12f [i915] [] ? intel_display_resume+0x4a/0x12f [i915] [] ? modeset_lock+0x13c/0x1cd [drm] [] intel_display_resume+0x4a/0x12f [i915] [] ? intel_display_resume+0x4a/0x12f [i915] [] ? modeset_lock+0x13c/0x1cd [drm] [] ? modeset_lock+0x13c/0x1cd [drm] [] ? drm_modeset_lock+0x17/0x24 [drm] [] ? drm_modeset_lock_all_ctx+0x87/0xa1 [drm] [] intel_lid_notify+0xb0/0xd9 [i915] [] notifier_call_chain+0x4a/0x6c [] __blocking_notifier_call_chain+0x4d/0x65 [] blocking_notifier_call_chain+0x14/0x16 [] acpi_lid_send_state+0x83/0xad [button] [] acpi_button_notify+0x41/0x132 [button] [] acpi_device_notify+0x19/0x1b [] acpi_ev_notify_dispatch+0x49/0x64 [] acpi_os_execute_deferred+0x14/0x20 [] process_one_work+0x265/0x50b [] worker_thread+0x1fc/0x2dd [] ? rescuer_thread+0x309/0x309 [] ? rescuer_thread+0x309/0x309 [] kthread+0xe0/0xe8 [] ? local_clock+0x19/0x22 [] ret_from_fork+0x22/0x40 [] ? kthread_create_on_node+0x1b5/0x1b5 Fixes: e2c8b8701e2d ("drm/i915: Use atomic helpers for suspend, v2.") Cc: Maarten Lankhorst Signed-off-by: Bjørn Mork Signed-off-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1459328913-13719-1-git-send-email-bjorn@mork.no --- drivers/gpu/drm/i915/intel_lvds.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 5d2b2575de33..66e832beeb37 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -472,11 +472,8 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val, * and as part of the cleanup in the hw state restore we also redisable * the vga plane. */ - if (!HAS_PCH_SPLIT(dev)) { - drm_modeset_lock_all(dev); + if (!HAS_PCH_SPLIT(dev)) intel_display_resume(dev); - drm_modeset_unlock_all(dev); - } dev_priv->modeset_restore = MODESET_DONE; -- cgit v1.2.3 From ade7daa164709e5851836195c6cd7502cea1eb5e Mon Sep 17 00:00:00 2001 From: Matthew Auld Date: Thu, 24 Mar 2016 15:54:20 +0000 Subject: drm/i915: BUG_ON when ggtt_view is NULL Lets BUG_ON and don't bother with a WARN and returning an error, so we can remove the need to pollute the code with error handling, after all it is a programmer error to provide NULL view. Also while we're here remove redundant NULL ggtt_view check. Cc: Joonas Lahtinen Cc: Tvrtko Ursulin Signed-off-by: Matthew Auld Acked-by: Daniel Vetter Reviewed-by: Joonas Lahtinen Signed-off-by: Joonas Lahtinen Link: http://patchwork.freedesktop.org/patch/msgid/1458834860-7898-1-git-send-email-matthew.auld@intel.com --- drivers/gpu/drm/i915/i915_gem.c | 9 ++------- drivers/gpu/drm/i915/i915_gem_gtt.c | 10 +--------- 2 files changed, 3 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index c7a997aeb33f..cbf616af9281 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4235,9 +4235,6 @@ i915_gem_object_do_pin(struct drm_i915_gem_object *obj, vma = ggtt_view ? i915_gem_obj_to_ggtt_view(obj, ggtt_view) : i915_gem_obj_to_vma(obj, vm); - if (IS_ERR(vma)) - return PTR_ERR(vma); - if (vma) { if (WARN_ON(vma->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT)) return -EBUSY; @@ -4300,8 +4297,7 @@ i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj, uint32_t alignment, uint64_t flags) { - if (WARN_ONCE(!view, "no view specified")) - return -EINVAL; + BUG_ON(!view); return i915_gem_object_do_pin(obj, i915_obj_to_ggtt(obj), view, alignment, flags | PIN_GLOBAL); @@ -4618,8 +4614,7 @@ struct i915_vma *i915_gem_obj_to_ggtt_view(struct drm_i915_gem_object *obj, struct i915_address_space *ggtt = i915_obj_to_ggtt(obj); struct i915_vma *vma; - if (WARN_ONCE(!view, "no view specified")) - return ERR_PTR(-EINVAL); + BUG_ON(!view); list_for_each_entry(vma, &obj->vma_list, obj_link) if (vma->vm == ggtt && diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 7cfafdc80b17..073c6bbe3388 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -3341,15 +3341,7 @@ i915_gem_obj_lookup_or_create_ggtt_vma(struct drm_i915_gem_object *obj, const struct i915_ggtt_view *view) { struct i915_address_space *ggtt = i915_obj_to_ggtt(obj); - struct i915_vma *vma; - - if (WARN_ON(!view)) - return ERR_PTR(-EINVAL); - - vma = i915_gem_obj_to_ggtt_view(obj, view); - - if (IS_ERR(vma)) - return vma; + struct i915_vma *vma = i915_gem_obj_to_ggtt_view(obj, view); if (!vma) vma = __i915_gem_vma_create(obj, ggtt, view); -- cgit v1.2.3 From d85489d314f2d273ffb4217b77bc659900b8a3f6 Mon Sep 17 00:00:00 2001 From: Joonas Lahtinen Date: Thu, 24 Mar 2016 16:47:46 +0200 Subject: drm/i915: Rename GGTT init functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename and document the GGTT init functions to give a better idea of the context where they are called from. i915_gem_gtt_init => i915_ggtt_init_hw i915_gem_init_global_gtt => i915_gem_init_ggtt i915_global_gtt_cleanup => i915_ggtt_cleanup_hw Cc: Tvrtko Ursulin Cc: Mika Kuoppala Cc: Ville Syrjälä Cc: Chris Wilson Reviewed-by: Chris Wilson Signed-off-by: Joonas Lahtinen Link: http://patchwork.freedesktop.org/patch/msgid/1458830866-12578-1-git-send-email-joonas.lahtinen@linux.intel.com --- drivers/gpu/drm/i915/i915_dma.c | 14 +++++++------- drivers/gpu/drm/i915/i915_gem.c | 2 +- drivers/gpu/drm/i915/i915_gem_gtt.c | 18 +++++++++++++++--- drivers/gpu/drm/i915/i915_gem_gtt.h | 7 +++---- 4 files changed, 26 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 1ac1ea969eec..d3011735c9c8 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1178,7 +1178,7 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv) intel_device_info_runtime_init(dev); - ret = i915_gem_gtt_init(dev); + ret = i915_ggtt_init_hw(dev); if (ret) return ret; @@ -1187,13 +1187,13 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv) ret = i915_kick_out_firmware_fb(dev_priv); if (ret) { DRM_ERROR("failed to remove conflicting framebuffer drivers\n"); - goto out_gtt; + goto out_ggtt; } ret = i915_kick_out_vgacon(dev_priv); if (ret) { DRM_ERROR("failed to remove conflicting VGA console\n"); - goto out_gtt; + goto out_ggtt; } pci_set_master(dev->pdev); @@ -1220,7 +1220,7 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv) aperture_size); if (dev_priv->ggtt.mappable == NULL) { ret = -EIO; - goto out_gtt; + goto out_ggtt; } dev_priv->ggtt.mtrr = arch_phys_wc_add(dev_priv->ggtt.mappable_base, @@ -1253,8 +1253,8 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv) return 0; -out_gtt: - i915_global_gtt_cleanup(dev); +out_ggtt: + i915_ggtt_cleanup_hw(dev); return ret; } @@ -1273,7 +1273,7 @@ static void i915_driver_cleanup_hw(struct drm_i915_private *dev_priv) pm_qos_remove_request(&dev_priv->pm_qos); arch_phys_wc_del(dev_priv->ggtt.mtrr); io_mapping_free(dev_priv->ggtt.mappable); - i915_global_gtt_cleanup(dev); + i915_ggtt_cleanup_hw(dev); } /** diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index cbf616af9281..11a6ccd8c607 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4962,7 +4962,7 @@ int i915_gem_init(struct drm_device *dev) if (ret) goto out_unlock; - i915_gem_init_global_gtt(dev); + i915_gem_init_ggtt(dev); ret = i915_gem_context_init(dev); if (ret) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 073c6bbe3388..f8f09d1cb5ae 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -2804,7 +2804,11 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev, return 0; } -void i915_gem_init_global_gtt(struct drm_device *dev) +/** + * i915_gem_init_ggtt - Initialize GEM for Global GTT + * @dev: DRM device + */ +void i915_gem_init_ggtt(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; u64 gtt_size, mappable_size; @@ -2815,7 +2819,11 @@ void i915_gem_init_global_gtt(struct drm_device *dev) i915_gem_setup_global_gtt(dev, 0, mappable_size, gtt_size); } -void i915_global_gtt_cleanup(struct drm_device *dev) +/** + * i915_ggtt_cleanup_hw - Clean up GGTT hardware initialization + * @dev: DRM device + */ +void i915_ggtt_cleanup_hw(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct i915_address_space *vm = &dev_priv->ggtt.base; @@ -3153,7 +3161,11 @@ static void i915_gmch_remove(struct i915_address_space *vm) intel_gmch_remove(); } -int i915_gem_gtt_init(struct drm_device *dev) +/** + * i915_ggtt_init_hw - Initialize GGTT hardware + * @dev: DRM device + */ +int i915_ggtt_init_hw(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct i915_ggtt *ggtt = &dev_priv->ggtt; diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index d804be00ab41..242a13b8129a 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -513,10 +513,9 @@ i915_page_dir_dma_addr(const struct i915_hw_ppgtt *ppgtt, const unsigned n) px_dma(ppgtt->base.scratch_pd); } -int i915_gem_gtt_init(struct drm_device *dev); -void i915_gem_init_global_gtt(struct drm_device *dev); -void i915_global_gtt_cleanup(struct drm_device *dev); - +int i915_ggtt_init_hw(struct drm_device *dev); +void i915_gem_init_ggtt(struct drm_device *dev); +void i915_ggtt_cleanup_hw(struct drm_device *dev); int i915_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt); int i915_ppgtt_init_hw(struct drm_device *dev); -- cgit v1.2.3 From b208ba8e49cd2b70a5e8f8f778627e5a2f050fed Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 24 Mar 2016 14:31:47 +0000 Subject: drm/i915: Rename __force_wake_get to __force_wake_auto __force_wake_get() only acquires a temporary wakeref on forcewake that is automatically released when a timer expires. When reading the code again, I confused __intel_uncore_forcewake_get() for __force_wake_get() and to my shame thought I found a bug in unbalanced wake_count handling. I claim that if the function had been called __force_wake_auto() instead I would not have embarrassed myself. Signed-off-by: Chris Wilson Cc: Mika Kuoppala Cc: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1458829907-26596-1-git-send-email-chris@chris-wilson.co.uk Reviewed-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/intel_uncore.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 512b7faedefd..ac1c545436af 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -716,8 +716,8 @@ __gen2_read(64) trace_i915_reg_rw(false, reg, val, sizeof(val), trace); \ return val -static inline void __force_wake_get(struct drm_i915_private *dev_priv, - enum forcewake_domains fw_domains) +static inline void __force_wake_auto(struct drm_i915_private *dev_priv, + enum forcewake_domains fw_domains) { struct intel_uncore_forcewake_domain *domain; enum forcewake_domain_id id; @@ -745,7 +745,7 @@ static u##x \ gen6_read##x(struct drm_i915_private *dev_priv, i915_reg_t reg, bool trace) { \ GEN6_READ_HEADER(x); \ if (NEEDS_FORCE_WAKE(offset)) \ - __force_wake_get(dev_priv, FORCEWAKE_RENDER); \ + __force_wake_auto(dev_priv, FORCEWAKE_RENDER); \ val = __raw_i915_read##x(dev_priv, reg); \ GEN6_READ_FOOTER; \ } @@ -762,7 +762,7 @@ vlv_read##x(struct drm_i915_private *dev_priv, i915_reg_t reg, bool trace) { \ else if (FORCEWAKE_VLV_MEDIA_RANGE_OFFSET(offset)) \ fw_engine = FORCEWAKE_MEDIA; \ if (fw_engine) \ - __force_wake_get(dev_priv, fw_engine); \ + __force_wake_auto(dev_priv, fw_engine); \ val = __raw_i915_read##x(dev_priv, reg); \ GEN6_READ_FOOTER; \ } @@ -781,7 +781,7 @@ chv_read##x(struct drm_i915_private *dev_priv, i915_reg_t reg, bool trace) { \ else if (FORCEWAKE_CHV_COMMON_RANGE_OFFSET(offset)) \ fw_engine = FORCEWAKE_RENDER | FORCEWAKE_MEDIA; \ if (fw_engine) \ - __force_wake_get(dev_priv, fw_engine); \ + __force_wake_auto(dev_priv, fw_engine); \ val = __raw_i915_read##x(dev_priv, reg); \ GEN6_READ_FOOTER; \ } @@ -805,7 +805,7 @@ gen9_read##x(struct drm_i915_private *dev_priv, i915_reg_t reg, bool trace) { \ else \ fw_engine = FORCEWAKE_BLITTER; \ if (fw_engine) \ - __force_wake_get(dev_priv, fw_engine); \ + __force_wake_auto(dev_priv, fw_engine); \ val = __raw_i915_read##x(dev_priv, reg); \ GEN6_READ_FOOTER; \ } @@ -969,7 +969,7 @@ static void \ gen8_write##x(struct drm_i915_private *dev_priv, i915_reg_t reg, u##x val, bool trace) { \ GEN6_WRITE_HEADER; \ if (NEEDS_FORCE_WAKE(offset) && !is_gen8_shadowed(dev_priv, reg)) \ - __force_wake_get(dev_priv, FORCEWAKE_RENDER); \ + __force_wake_auto(dev_priv, FORCEWAKE_RENDER); \ __raw_i915_write##x(dev_priv, reg, val); \ GEN6_WRITE_FOOTER; \ } @@ -989,7 +989,7 @@ chv_write##x(struct drm_i915_private *dev_priv, i915_reg_t reg, u##x val, bool t else if (FORCEWAKE_CHV_COMMON_RANGE_OFFSET(offset)) \ fw_engine = FORCEWAKE_RENDER | FORCEWAKE_MEDIA; \ if (fw_engine) \ - __force_wake_get(dev_priv, fw_engine); \ + __force_wake_auto(dev_priv, fw_engine); \ __raw_i915_write##x(dev_priv, reg, val); \ GEN6_WRITE_FOOTER; \ } @@ -1036,7 +1036,7 @@ gen9_write##x(struct drm_i915_private *dev_priv, i915_reg_t reg, u##x val, \ else \ fw_engine = FORCEWAKE_BLITTER; \ if (fw_engine) \ - __force_wake_get(dev_priv, fw_engine); \ + __force_wake_auto(dev_priv, fw_engine); \ __raw_i915_write##x(dev_priv, reg, val); \ GEN6_WRITE_FOOTER; \ } -- cgit v1.2.3 From 579de73b048a0a4c66c25a033ac76a2836e0cf73 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 14 Mar 2016 09:01:57 +0000 Subject: drm/i915: Exit cherryview_irq_handler() after one pass MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This effectively reverts commit 8e5fd599eb219f1054e39b40d18b217af669eea9 Author: Ville Syrjälä Date: Wed Apr 9 13:28:50 2014 +0300 drm/i915/chv: Make CHV irq handler loop until all interrupts are consumed as under continuous execlists load we can saturate the IRQ handler, destablising the tsc clock and triggering the NMI watchdog to declare a hung CPU. [ 552.756051] clocksource: timekeeping watchdog on CPU0: Marking clocksource 'tsc' as unstable because the skew is too large: [ 552.756080] clocksource: 'refined-jiffies' wd_now: 10003b480 wd_last: 10003b28c mask: ffffffff [ 552.756091] clocksource: 'tsc' cs_now: d55d31aa50 cs_last: d17446166c mask: ffffffffffffffff [ 552.756210] clocksource: Switched to clocksource refined-jiffies [ 575.217870] NMI watchdog: Watchdog detected hard LOCKUP on cpu 1 [ 575.217893] CPU: 1 PID: 0 Comm: swapper/1 Not tainted 4.5.0-rc7+ #18 [ 575.217905] Hardware name: /NUC5CPYB, BIOS PYBSWCEL.86A.0027.2015.0507.1758 05/07/2015 [ 575.217915] 0000000000000000 ffff88027fd05bc0 ffffffff81288c6d 0000000000000000 [ 575.217935] 0000000000000001 ffff88027fd05be0 ffffffff810e72d1 0000000000000000 [ 575.217951] ffff88027fd05c80 ffff88027fd05c20 ffffffff81114b60 0000000181015f1e [ 575.217967] Call Trace: [ 575.217973] [] dump_stack+0x4f/0x72 [ 575.217994] [] watchdog_overflow_callback+0x151/0x160 [ 575.218003] [] __perf_event_overflow+0xa0/0x1e0 [ 575.218016] [] perf_event_overflow+0x14/0x20 [ 575.218028] [] intel_pmu_handle_irq+0x1da/0x460 [ 575.218042] [] ? poll_idle+0x3e/0x70 [ 575.218052] [] ? poll_idle+0x3e/0x70 [ 575.218064] [] perf_event_nmi_handler+0x28/0x50 [ 575.218075] [] nmi_handle+0x60/0x130 [ 575.218086] [] ? poll_idle+0x3e/0x70 [ 575.218096] [] do_nmi+0x140/0x470 [ 575.218108] [] end_repeat_nmi+0x1a/0x1e [ 575.218119] [] ? poll_idle+0x3e/0x70 [ 575.218129] [] ? poll_idle+0x3e/0x70 [ 575.218139] [] ? poll_idle+0x3e/0x70 [ 575.218148] <> [] cpuidle_enter_state+0xf3/0x2f0 [ 575.218164] [] cpuidle_enter+0x17/0x20 [ 575.218175] [] call_cpuidle+0x2a/0x40 [ 575.218185] [] cpu_startup_entry+0x273/0x330 [ 575.218196] [] start_secondary+0x10e/0x130 However, not servicing all available IIR within the handler does hurt the throughput of pathological nop execbuf by about 20%, with a similar effect upon the dispatch latency of a series of execbuf. v2: use do {} while(0) for a smaller patch, and easier to revert again I have reasonable confidence that we do not miss GT interrupts (as execlists provides a stress case with a failure mechanism easily detected by igt), however I have less confidence about all the other sources of interrupts and worry that may lose a display hotplug interrupt, for example. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93467 Testcase: igt/gem_exec_nop/basic # requires NMI watchdog Signed-off-by: Chris Wilson Cc: Ville Syrjälä Cc: Antti Koskipää Cc: Tvrtko Ursulin Cc: stable@vger.kernel.org Reviewed-by: Tvrtko Ursulin Reviewed-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1457946117-6714-1-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_irq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 5aa42395241d..a9c18137e3f5 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1828,7 +1828,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg) /* IRQs are synced during runtime_suspend, we don't require a wakeref */ disable_rpm_wakeref_asserts(dev_priv); - for (;;) { + do { master_ctl = I915_READ(GEN8_MASTER_IRQ) & ~GEN8_MASTER_IRQ_CONTROL; iir = I915_READ(VLV_IIR); @@ -1856,7 +1856,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg) I915_WRITE(GEN8_MASTER_IRQ, DE_MASTER_IRQ_CONTROL); POSTING_READ(GEN8_MASTER_IRQ); - } + } while (0); enable_rpm_wakeref_asserts(dev_priv); -- cgit v1.2.3 From e6bf6e5799f72f04bac61056804d6dd8dac98062 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 30 Mar 2016 13:24:06 +0200 Subject: drm/ttm: Remove TTM_HAS_AGP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It tries to do fancy things with excluding agp support if ttm is built-in, but agp isn't. Instead just express this depency like drm does and use CONFIG_AGP everywhere. Also use the neat Makefile magic to make the entire ttm_agp_backend file optional. v2: Use IS_ENABLED(CONFIG_AGP) as suggested by Ville v3: Review from Emil. v4: Actually get it right as spotted by 0-day. Cc: Emil Velikov Cc: Ville Syrjälä Reviewed-by: Emil Velikov Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1459337046-25882-1-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/ttm/Makefile | 3 ++- drivers/gpu/drm/ttm/ttm_agp_backend.c | 3 --- drivers/gpu/drm/ttm/ttm_page_alloc.c | 8 ++++---- drivers/gpu/drm/ttm/ttm_page_alloc_dma.c | 8 ++++---- include/drm/ttm/ttm_bo_driver.h | 3 +-- 5 files changed, 11 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/ttm/Makefile b/drivers/gpu/drm/ttm/Makefile index b433b9f040c9..f92325800f8a 100644 --- a/drivers/gpu/drm/ttm/Makefile +++ b/drivers/gpu/drm/ttm/Makefile @@ -2,9 +2,10 @@ # Makefile for the drm device driver. This driver provides support for the ccflags-y := -Iinclude/drm -ttm-y := ttm_agp_backend.o ttm_memory.o ttm_tt.o ttm_bo.o \ +ttm-y := ttm_memory.o ttm_tt.o ttm_bo.o \ ttm_bo_util.o ttm_bo_vm.o ttm_module.o \ ttm_object.o ttm_lock.o ttm_execbuf_util.o ttm_page_alloc.o \ ttm_bo_manager.o ttm_page_alloc_dma.o +ttm-$(CONFIG_AGP) += ttm_agp_backend.o obj-$(CONFIG_DRM_TTM) += ttm.o diff --git a/drivers/gpu/drm/ttm/ttm_agp_backend.c b/drivers/gpu/drm/ttm/ttm_agp_backend.c index 764be36397fd..028ab6007873 100644 --- a/drivers/gpu/drm/ttm/ttm_agp_backend.c +++ b/drivers/gpu/drm/ttm/ttm_agp_backend.c @@ -34,7 +34,6 @@ #include #include #include -#ifdef TTM_HAS_AGP #include #include #include @@ -148,5 +147,3 @@ void ttm_agp_tt_unpopulate(struct ttm_tt *ttm) ttm_pool_unpopulate(ttm); } EXPORT_SYMBOL(ttm_agp_tt_unpopulate); - -#endif diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c index 025c429050c0..a37de5db5731 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c @@ -48,7 +48,7 @@ #include #include -#ifdef TTM_HAS_AGP +#if IS_ENABLED(CONFIG_AGP) #include #endif @@ -219,7 +219,7 @@ static struct ttm_pool_manager *_manager; #ifndef CONFIG_X86 static int set_pages_array_wb(struct page **pages, int addrinarray) { -#ifdef TTM_HAS_AGP +#if IS_ENABLED(CONFIG_AGP) int i; for (i = 0; i < addrinarray; i++) @@ -230,7 +230,7 @@ static int set_pages_array_wb(struct page **pages, int addrinarray) static int set_pages_array_wc(struct page **pages, int addrinarray) { -#ifdef TTM_HAS_AGP +#if IS_ENABLED(CONFIG_AGP) int i; for (i = 0; i < addrinarray; i++) @@ -241,7 +241,7 @@ static int set_pages_array_wc(struct page **pages, int addrinarray) static int set_pages_array_uc(struct page **pages, int addrinarray) { -#ifdef TTM_HAS_AGP +#if IS_ENABLED(CONFIG_AGP) int i; for (i = 0; i < addrinarray; i++) diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c index 624d941aaad1..bef9f6feb635 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c @@ -50,7 +50,7 @@ #include #include #include -#ifdef TTM_HAS_AGP +#if IS_ENABLED(CONFIG_AGP) #include #endif @@ -271,7 +271,7 @@ static struct kobj_type ttm_pool_kobj_type = { #ifndef CONFIG_X86 static int set_pages_array_wb(struct page **pages, int addrinarray) { -#ifdef TTM_HAS_AGP +#if IS_ENABLED(CONFIG_AGP) int i; for (i = 0; i < addrinarray; i++) @@ -282,7 +282,7 @@ static int set_pages_array_wb(struct page **pages, int addrinarray) static int set_pages_array_wc(struct page **pages, int addrinarray) { -#ifdef TTM_HAS_AGP +#if IS_ENABLED(CONFIG_AGP) int i; for (i = 0; i < addrinarray; i++) @@ -293,7 +293,7 @@ static int set_pages_array_wc(struct page **pages, int addrinarray) static int set_pages_array_uc(struct page **pages, int addrinarray) { -#ifdef TTM_HAS_AGP +#if IS_ENABLED(CONFIG_AGP) int i; for (i = 0; i < addrinarray; i++) diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index 3d4bf08aa21f..cb91f80c15b3 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h @@ -1030,8 +1030,7 @@ extern pgprot_t ttm_io_prot(uint32_t caching_flags, pgprot_t tmp); extern const struct ttm_mem_type_manager_func ttm_bo_manager_func; -#if (defined(CONFIG_AGP) || (defined(CONFIG_AGP_MODULE) && defined(MODULE))) -#define TTM_HAS_AGP +#if IS_ENABLED(CONFIG_AGP) #include /** -- cgit v1.2.3 From aa2e2996b1518b3e4b72dab5c2cb6cd082e3002e Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 30 Mar 2016 11:45:14 +0200 Subject: drm/sysfs: Nuke TV/DVI property files This goes all the way back to the original KMS commit aeons ago commit f453ba0460742ad027ae0c4c7d61e62817b3e7ef Author: Dave Airlie Date: Fri Nov 7 14:05:41 2008 -0800 DRM: add mode setting support But it seems to be completely unused. Only i915 and nouveau even register these properties, and the corresponding DDX don't even look at them. Also the sysfs files are read-only, so not useful to configure anything. I suspect that this was added with the goal to have read-only access to all properties in sysfs, but we never followed through on that. Also, that should be done in a more generic fashion. Since it would be real work to fix up the locking (with atomic we're now chasing pointers when reading properties) and it seems unused lets just nuke this all. It's easier. Of course we'll keep the properties themselves, those are still exposed through the KMS ioctls. Reviewed-by: Alex Deucher Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1459331120-27864-5-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/drm_sysfs.c | 156 -------------------------------------------- 1 file changed, 156 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index d503f8e8c2d1..d7d8cecfb0e6 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c @@ -287,102 +287,6 @@ static ssize_t modes_show(struct device *device, return written; } -static ssize_t tv_subconnector_show(struct device *device, - struct device_attribute *attr, - char *buf) -{ - struct drm_connector *connector = to_drm_connector(device); - struct drm_device *dev = connector->dev; - struct drm_property *prop; - uint64_t subconnector; - int ret; - - prop = dev->mode_config.tv_subconnector_property; - if (!prop) { - DRM_ERROR("Unable to find subconnector property\n"); - return 0; - } - - ret = drm_object_property_get_value(&connector->base, prop, &subconnector); - if (ret) - return 0; - - return snprintf(buf, PAGE_SIZE, "%s", - drm_get_tv_subconnector_name((int)subconnector)); -} - -static ssize_t tv_select_subconnector_show(struct device *device, - struct device_attribute *attr, - char *buf) -{ - struct drm_connector *connector = to_drm_connector(device); - struct drm_device *dev = connector->dev; - struct drm_property *prop; - uint64_t subconnector; - int ret; - - prop = dev->mode_config.tv_select_subconnector_property; - if (!prop) { - DRM_ERROR("Unable to find select subconnector property\n"); - return 0; - } - - ret = drm_object_property_get_value(&connector->base, prop, &subconnector); - if (ret) - return 0; - - return snprintf(buf, PAGE_SIZE, "%s", - drm_get_tv_select_name((int)subconnector)); -} - -static ssize_t dvii_subconnector_show(struct device *device, - struct device_attribute *attr, - char *buf) -{ - struct drm_connector *connector = to_drm_connector(device); - struct drm_device *dev = connector->dev; - struct drm_property *prop; - uint64_t subconnector; - int ret; - - prop = dev->mode_config.dvi_i_subconnector_property; - if (!prop) { - DRM_ERROR("Unable to find subconnector property\n"); - return 0; - } - - ret = drm_object_property_get_value(&connector->base, prop, &subconnector); - if (ret) - return 0; - - return snprintf(buf, PAGE_SIZE, "%s", - drm_get_dvi_i_subconnector_name((int)subconnector)); -} - -static ssize_t dvii_select_subconnector_show(struct device *device, - struct device_attribute *attr, - char *buf) -{ - struct drm_connector *connector = to_drm_connector(device); - struct drm_device *dev = connector->dev; - struct drm_property *prop; - uint64_t subconnector; - int ret; - - prop = dev->mode_config.dvi_i_select_subconnector_property; - if (!prop) { - DRM_ERROR("Unable to find select subconnector property\n"); - return 0; - } - - ret = drm_object_property_get_value(&connector->base, prop, &subconnector); - if (ret) - return 0; - - return snprintf(buf, PAGE_SIZE, "%s", - drm_get_dvi_i_select_name((int)subconnector)); -} - static DEVICE_ATTR_RW(status); static DEVICE_ATTR_RO(enabled); static DEVICE_ATTR_RO(dpms); @@ -396,54 +300,6 @@ static struct attribute *connector_dev_attrs[] = { NULL }; -static DEVICE_ATTR_RO(tv_subconnector); -static DEVICE_ATTR_RO(tv_select_subconnector); - -static struct attribute *connector_tv_dev_attrs[] = { - &dev_attr_tv_subconnector.attr, - &dev_attr_tv_select_subconnector.attr, - NULL -}; - -static DEVICE_ATTR_RO(dvii_subconnector); -static DEVICE_ATTR_RO(dvii_select_subconnector); - -static struct attribute *connector_dvii_dev_attrs[] = { - &dev_attr_dvii_subconnector.attr, - &dev_attr_dvii_select_subconnector.attr, - NULL -}; - -/* Connector type related helpers */ -static int kobj_connector_type(struct kobject *kobj) -{ - struct device *dev = kobj_to_dev(kobj); - struct drm_connector *connector = to_drm_connector(dev); - - return connector->connector_type; -} - -static umode_t connector_is_dvii(struct kobject *kobj, - struct attribute *attr, int idx) -{ - return kobj_connector_type(kobj) == DRM_MODE_CONNECTOR_DVII ? - attr->mode : 0; -} - -static umode_t connector_is_tv(struct kobject *kobj, - struct attribute *attr, int idx) -{ - switch (kobj_connector_type(kobj)) { - case DRM_MODE_CONNECTOR_Composite: - case DRM_MODE_CONNECTOR_SVIDEO: - case DRM_MODE_CONNECTOR_Component: - case DRM_MODE_CONNECTOR_TV: - return attr->mode; - } - - return 0; -} - static struct bin_attribute edid_attr = { .attr.name = "edid", .attr.mode = 0444, @@ -461,20 +317,8 @@ static const struct attribute_group connector_dev_group = { .bin_attrs = connector_bin_attrs, }; -static const struct attribute_group connector_tv_dev_group = { - .attrs = connector_tv_dev_attrs, - .is_visible = connector_is_tv, -}; - -static const struct attribute_group connector_dvii_dev_group = { - .attrs = connector_dvii_dev_attrs, - .is_visible = connector_is_dvii, -}; - static const struct attribute_group *connector_dev_groups[] = { &connector_dev_group, - &connector_tv_dev_group, - &connector_dvii_dev_group, NULL }; -- cgit v1.2.3 From 44debe7a123cc760fc90ccbe253210798c917fa7 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 30 Mar 2016 11:26:35 +0200 Subject: vgacon: dummy implementation for vgacon_text_force MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows us to ditch a ton of ugly #ifdefs from a bunch of drm modeset drivers. v2: Make the dummy function actually return a sane value, spotted by Ville. v3: Because the patch is still in limbo there's no more drivers to convert, noticed by Emil. v4: Rebase once more, because hooray. I'll just go ahead an apply this one later on to drm-misc. Cc: Emil Velikov Cc: Ville Syrjälä Cc: Andrew Morton Cc: Greg Kroah-Hartman Reviewed-by: Emil Velikov Reviewed-by: Alex Deucher Signed-off-by: Daniel Vetter --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 -- drivers/gpu/drm/ast/ast_drv.c | 2 -- drivers/gpu/drm/cirrus/cirrus_drv.c | 2 -- drivers/gpu/drm/i915/i915_drv.c | 2 -- drivers/gpu/drm/mgag200/mgag200_drv.c | 2 -- drivers/gpu/drm/nouveau/nouveau_drm.c | 2 -- drivers/gpu/drm/qxl/qxl_drv.c | 2 -- drivers/gpu/drm/radeon/radeon_drv.c | 2 -- drivers/gpu/drm/virtio/virtgpu_drv.c | 2 -- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 2 -- include/linux/console.h | 2 ++ 11 files changed, 2 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index ce79a8b605a0..fba20bd59cfa 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -539,12 +539,10 @@ static struct pci_driver amdgpu_kms_pci_driver = { static int __init amdgpu_init(void) { -#ifdef CONFIG_VGA_CONSOLE if (vgacon_text_force()) { DRM_ERROR("VGACON disables amdgpu kernel modesetting.\n"); return -EINVAL; } -#endif DRM_INFO("amdgpu kernel modesetting enabled.\n"); driver = &kms_driver; pdriver = &amdgpu_kms_pci_driver; diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c index 9a32d9dfdd26..fcd9c0714836 100644 --- a/drivers/gpu/drm/ast/ast_drv.c +++ b/drivers/gpu/drm/ast/ast_drv.c @@ -218,10 +218,8 @@ static struct drm_driver driver = { static int __init ast_init(void) { -#ifdef CONFIG_VGA_CONSOLE if (vgacon_text_force() && ast_modeset == -1) return -EINVAL; -#endif if (ast_modeset == 0) return -EINVAL; diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c index b1619e29a564..b394e6d8f01e 100644 --- a/drivers/gpu/drm/cirrus/cirrus_drv.c +++ b/drivers/gpu/drm/cirrus/cirrus_drv.c @@ -162,10 +162,8 @@ static struct pci_driver cirrus_pci_driver = { static int __init cirrus_init(void) { -#ifdef CONFIG_VGA_CONSOLE if (vgacon_text_force() && cirrus_modeset == -1) return -EINVAL; -#endif if (cirrus_modeset == 0) return -EINVAL; diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 44912ecebc1a..8a62690e6513 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1750,10 +1750,8 @@ static int __init i915_init(void) if (i915.modeset == 0) driver.driver_features &= ~DRIVER_MODESET; -#ifdef CONFIG_VGA_CONSOLE if (vgacon_text_force() && i915.modeset == -1) driver.driver_features &= ~DRIVER_MODESET; -#endif if (!(driver.driver_features & DRIVER_MODESET)) { /* Silently fail loading to not upset userspace. */ diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c index b0af77454d52..ebb470ff7200 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.c +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c @@ -116,10 +116,8 @@ static struct pci_driver mgag200_pci_driver = { static int __init mgag200_init(void) { -#ifdef CONFIG_VGA_CONSOLE if (vgacon_text_force() && mgag200_modeset == -1) return -EINVAL; -#endif if (mgag200_modeset == 0) return -EINVAL; diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index bb8498c9b13e..731c5c2a8933 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -1082,10 +1082,8 @@ nouveau_drm_init(void) nouveau_display_options(); if (nouveau_modeset == -1) { -#ifdef CONFIG_VGA_CONSOLE if (vgacon_text_force()) nouveau_modeset = 0; -#endif } if (!nouveau_modeset) diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c index 7307b07fe06b..dc9df5fe50ba 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.c +++ b/drivers/gpu/drm/qxl/qxl_drv.c @@ -272,10 +272,8 @@ static struct drm_driver qxl_driver = { static int __init qxl_init(void) { -#ifdef CONFIG_VGA_CONSOLE if (vgacon_text_force() && qxl_modeset == -1) return -EINVAL; -#endif if (qxl_modeset == 0) return -EINVAL; diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index cad25557650f..ad136fc081c8 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -558,12 +558,10 @@ static struct pci_driver radeon_kms_pci_driver = { static int __init radeon_init(void) { -#ifdef CONFIG_VGA_CONSOLE if (vgacon_text_force() && radeon_modeset == -1) { DRM_INFO("VGACON disable radeon kernel modesetting.\n"); radeon_modeset = 0; } -#endif /* set to modesetting by default if not nomodeset */ if (radeon_modeset == -1) radeon_modeset = 1; diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index 7f898cfdc746..3cc7afa77a35 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -42,10 +42,8 @@ module_param_named(modeset, virtio_gpu_modeset, int, 0400); static int virtio_gpu_probe(struct virtio_device *vdev) { -#ifdef CONFIG_VGA_CONSOLE if (vgacon_text_force() && virtio_gpu_modeset == -1) return -EINVAL; -#endif if (virtio_gpu_modeset == 0) return -EINVAL; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 0ee76e523a90..fa10395e2a18 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -1529,10 +1529,8 @@ static int __init vmwgfx_init(void) { int ret; -#ifdef CONFIG_VGA_CONSOLE if (vgacon_text_force()) return -EINVAL; -#endif ret = drm_pci_init(&driver, &vmw_pci_driver); if (ret) diff --git a/include/linux/console.h b/include/linux/console.h index ea731af2451e..e49cc1ef19be 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -191,6 +191,8 @@ void vcs_remove_sysfs(int index); #ifdef CONFIG_VGA_CONSOLE extern bool vgacon_text_force(void); +#else +static inline bool vgacon_text_force(void) { return false; } #endif #endif /* _LINUX_CONSOLE_H */ -- cgit v1.2.3 From 9c7417022ded5700a4b1a11da59951ebf080e4e0 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Wed, 30 Mar 2016 07:58:01 -0700 Subject: drm/i915/kbl: Remove preliminary_hw_support protection from KBL. We now have KBL machines running in our CI systems and with no blocking issues that could cause a full hangs or blank screens. Signed-off-by: Rodrigo Vivi Link: http://patchwork.freedesktop.org/patch/msgid/1459349881-951-1-git-send-email-rodrigo.vivi@intel.com Acked-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index f73b4f7b2d39..79b63cb4ddcf 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -360,14 +360,12 @@ static const struct intel_device_info intel_broxton_info = { static const struct intel_device_info intel_kabylake_info = { BDW_FEATURES, - .is_preliminary = 1, .is_kabylake = 1, .gen = 9, }; static const struct intel_device_info intel_kabylake_gt3_info = { BDW_FEATURES, - .is_preliminary = 1, .is_kabylake = 1, .gen = 9, .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, -- cgit v1.2.3 From 55c561a708eec328822721233b1148119e80f5c3 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 30 Mar 2016 11:34:36 +0200 Subject: drm/i915: Remove PIPE_CONF_CHECK_I_ALT And move the comment to the right macro. This was mixed up in commit cfb23ed622d040619abb91e625fcba74d356b8a8 Author: Maarten Lankhorst Date: Tue Jul 14 12:17:40 2015 +0200 drm/i915: Allow fuzzy matching in pipe_config_compare, v2 v2: Rebase. Cc: Maarten Lankhorst Cc: Daniel Stone Acked-by: Maarten Lankhorst Reviewed-by: Jani Nikula Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1459330476-32453-1-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/i915/intel_display.c | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 29aa64be1f03..fec6392dfc02 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12569,6 +12569,11 @@ intel_pipe_config_compare(struct drm_device *dev, ret = false; \ } +/* This is required for BDW+ where there is only one set of registers for + * switching between high and low RR. + * This macro can be used whenever a comparison has to be made between one + * hw state and multiple sw state variables. + */ #define PIPE_CONF_CHECK_M_N_ALT(name, alt_name) \ if (!intel_compare_link_m_n(¤t_config->name, \ &pipe_config->name, adjust) && \ @@ -12596,22 +12601,6 @@ intel_pipe_config_compare(struct drm_device *dev, ret = false; \ } -/* This is required for BDW+ where there is only one set of registers for - * switching between high and low RR. - * This macro can be used whenever a comparison has to be made between one - * hw state and multiple sw state variables. - */ -#define PIPE_CONF_CHECK_I_ALT(name, alt_name) \ - if ((current_config->name != pipe_config->name) && \ - (current_config->alt_name != pipe_config->name)) { \ - INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \ - "(expected %i or %i, found %i)\n", \ - current_config->name, \ - current_config->alt_name, \ - pipe_config->name); \ - ret = false; \ - } - #define PIPE_CONF_CHECK_FLAGS(name, mask) \ if ((current_config->name ^ pipe_config->name) & (mask)) { \ INTEL_ERR_OR_DBG_KMS("mismatch in " #name "(" #mask ") " \ @@ -12736,7 +12725,6 @@ intel_pipe_config_compare(struct drm_device *dev, #undef PIPE_CONF_CHECK_X #undef PIPE_CONF_CHECK_I #undef PIPE_CONF_CHECK_P -#undef PIPE_CONF_CHECK_I_ALT #undef PIPE_CONF_CHECK_FLAGS #undef PIPE_CONF_CHECK_CLOCK_FUZZY #undef PIPE_CONF_QUIRK -- cgit v1.2.3 From a0fcb63586a57560de28c333127bb0e36c01c70c Mon Sep 17 00:00:00 2001 From: Alexander Curtin Date: Wed, 30 Mar 2016 10:41:42 -0400 Subject: staging: unisys: removed unused switch/port info from visorbus.h The fields 'switch_no' and 'internal_port_no' were originally added to the visor_device struct in preparation of removing the 'device_info' struct in the now removed 'uislib' library. After the refactoring was complete, these attributes are not referenced anywhere, and there are no plans to use them. Signed-off-by: Alexander Curtin Signed-off-by: David Kershner Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/visorbus.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/unisys/include/visorbus.h b/drivers/staging/unisys/include/visorbus.h index 9c47a138e748..25ffdc03f020 100644 --- a/drivers/staging/unisys/include/visorbus.h +++ b/drivers/staging/unisys/include/visorbus.h @@ -155,8 +155,6 @@ struct visor_device { u8 *description; struct controlvm_message_header *pending_msg_hdr; void *vbus_hdr_info; - u32 switch_no; - u32 internal_port_no; uuid_le partition_uuid; }; -- cgit v1.2.3 From 378d638a89b67bf2bb2de34786f3a27b41203357 Mon Sep 17 00:00:00 2001 From: Alexander Curtin Date: Wed, 30 Mar 2016 10:41:43 -0400 Subject: staging: unisys: include: removed unused 'visor_device.description' The 'description' variable in visor_device was added in preparation for removing the 'device_info' struct when the uislib files were removed. That attribute is never accessed nor set, and the 'name' attribute provides enough information to correctly identify the driver, it is not needed. Signed-off-by: Alexander Curtin Signed-off-by: David Kershner Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/visorbus.h | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/unisys/include/visorbus.h b/drivers/staging/unisys/include/visorbus.h index 25ffdc03f020..f7e753f2ba6c 100644 --- a/drivers/staging/unisys/include/visorbus.h +++ b/drivers/staging/unisys/include/visorbus.h @@ -152,7 +152,6 @@ struct visor_device { uuid_le type; uuid_le inst; u8 *name; - u8 *description; struct controlvm_message_header *pending_msg_hdr; void *vbus_hdr_info; uuid_le partition_uuid; -- cgit v1.2.3 From 240f7ec1f49aef8fe28d13ad52ced6c28ccc8f02 Mon Sep 17 00:00:00 2001 From: Alexander Curtin Date: Wed, 30 Mar 2016 10:41:44 -0400 Subject: staging: unisys: removed unused visor_device.type field The visor_device.type field was included when preparing to remove the device_info struct. However, it's not used at all, and was already redundant by the existence of the 'visor_device.channel_type_guid' field. Signed-off-by: Alexander Curtin Signed-off-by: David Kershner Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/visorbus.h | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/unisys/include/visorbus.h b/drivers/staging/unisys/include/visorbus.h index f7e753f2ba6c..729ca7e51d17 100644 --- a/drivers/staging/unisys/include/visorbus.h +++ b/drivers/staging/unisys/include/visorbus.h @@ -149,7 +149,6 @@ struct visor_device { u32 chipset_bus_no; u32 chipset_dev_no; struct visorchipset_state state; - uuid_le type; uuid_le inst; u8 *name; struct controlvm_message_header *pending_msg_hdr; -- cgit v1.2.3 From 03d0d045c8884df5e0576d3eb7dbf53fa95fe7ce Mon Sep 17 00:00:00 2001 From: Alexander Curtin Date: Wed, 30 Mar 2016 10:41:45 -0400 Subject: staging: unisys: removed 'visor_device.devnodes' field The 'visor_device.devnodes' field was used for displaying driver version information through the devmajorminor sysfs attribute, which has recently been removed, rendering the field unnecessary. Signed-off-by: Alexander Curtin Signed-off-by: David Kershner Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/visorbus.h | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/unisys/include/visorbus.h b/drivers/staging/unisys/include/visorbus.h index 729ca7e51d17..cbc6d8f06c9b 100644 --- a/drivers/staging/unisys/include/visorbus.h +++ b/drivers/staging/unisys/include/visorbus.h @@ -136,12 +136,6 @@ struct visor_device { struct periodic_work *periodic_work; bool being_removed; bool responded_to_device_create; - struct { - int major, minor; - void *attr; /* private use by devmajorminor_attr.c you can - * change this constant to whatever you want - */ - } devnodes[5]; /* the code will detect and behave appropriately) */ struct semaphore visordriver_callback_lock; bool pausing; -- cgit v1.2.3 From 527486ee8fbb28fabd8fa51ddd4339a37ee15c5c Mon Sep 17 00:00:00 2001 From: Alexander Curtin Date: Wed, 30 Mar 2016 10:41:46 -0400 Subject: staging: unisys: removed unused channel_bytes attribute The channel_bytes attribute in the visor_device struct was meant to keep track of the number of bytes in the associated channel of the device. Not only is the variable never set nor used, but the information can already be accessed by referencing visor_device->visorchannel->nbytes. Signed-off-by: Alexander Curtin Signed-off-by: David Kershner Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/visorbus.h | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/unisys/include/visorbus.h b/drivers/staging/unisys/include/visorbus.h index cbc6d8f06c9b..3788d167b3c6 100644 --- a/drivers/staging/unisys/include/visorbus.h +++ b/drivers/staging/unisys/include/visorbus.h @@ -124,7 +124,6 @@ struct visor_device { */ struct visorchannel *visorchannel; uuid_le channel_type_guid; - u64 channel_bytes; /** These fields are for private use by the bus driver only. * A notable exception is that the visor driver can use -- cgit v1.2.3 From 64938182e7836650feeb9b2b9dadd510ed4b0dad Mon Sep 17 00:00:00 2001 From: David Kershner Date: Wed, 30 Mar 2016 20:38:49 -0400 Subject: staging: unisys: remove wmb() in visordriver_remove_device Don't need to have a wmb() in visordriver_remove_device. Also removed an unnecessary check for drv being null. Signed-off-by: David Kershner Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorbus/visorbus_main.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c index 1fcb1775bb59..547be8b50956 100644 --- a/drivers/staging/unisys/visorbus/visorbus_main.c +++ b/drivers/staging/unisys/visorbus/visorbus_main.c @@ -613,20 +613,12 @@ visordriver_remove_device(struct device *xdev) drv = to_visor_driver(xdev->driver); down(&dev->visordriver_callback_lock); dev->being_removed = true; - /* - * ensure that the dev->being_removed flag is set before we start the - * actual removal - */ - wmb(); - if (drv) { - if (drv->remove) - drv->remove(dev); - } + if (drv->remove) + drv->remove(dev); up(&dev->visordriver_callback_lock); dev_stop_periodic_work(dev); put_device(&dev->device); - return 0; } -- cgit v1.2.3 From 9f6b68774f29692f3e5b87e8eae29da61c3b1171 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 24 Mar 2016 15:58:17 -0500 Subject: android: remove timed output/gpio driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit timed_output was only used by the Android vibrator HAL which has now learned how to use LED triggers instead[1]. Any users of it in AOSP are on ancient kernels. Adding support for LED triggers is purely DT changes and proper kernel config. [1] https://android.googlesource.com/platform%2Fhardware%2Flibhardware/+/61701df363310a5cbd95e3e1638baa9526e42c9b Cc: John Stultz Cc: "Arve Hjønnevåg" Cc: Riley Andrews Signed-off-by: Rob Herring Acked-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/Kconfig | 14 --- drivers/staging/android/Makefile | 2 - drivers/staging/android/timed_gpio.c | 166 --------------------------------- drivers/staging/android/timed_gpio.h | 33 ------- drivers/staging/android/timed_output.c | 110 ---------------------- drivers/staging/android/timed_output.h | 37 -------- 6 files changed, 362 deletions(-) delete mode 100644 drivers/staging/android/timed_gpio.c delete mode 100644 drivers/staging/android/timed_gpio.h delete mode 100644 drivers/staging/android/timed_output.c delete mode 100644 drivers/staging/android/timed_output.h (limited to 'drivers') diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig index bd90d2002afb..4244821e32fc 100644 --- a/drivers/staging/android/Kconfig +++ b/drivers/staging/android/Kconfig @@ -14,20 +14,6 @@ config ASHMEM It is, in theory, a good memory allocator for low-memory devices, because it can discard shared memory units when under memory pressure. -config ANDROID_TIMED_OUTPUT - bool "Timed output class driver" - default y - -config ANDROID_TIMED_GPIO - tristate "Android timed gpio driver" - depends on GPIOLIB || COMPILE_TEST - depends on ANDROID_TIMED_OUTPUT - default n - ---help--- - Unlike generic gpio is to allow programs to access and manipulate gpio - registers from user space, timed output/gpio is a system to allow changing - a gpio pin and restore it automatically after a specified timeout. - config ANDROID_LOW_MEMORY_KILLER bool "Android Low Memory Killer" ---help--- diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile index c7b6c99cc5ce..980d6dc4b265 100644 --- a/drivers/staging/android/Makefile +++ b/drivers/staging/android/Makefile @@ -3,8 +3,6 @@ ccflags-y += -I$(src) # needed for trace events obj-y += ion/ obj-$(CONFIG_ASHMEM) += ashmem.o -obj-$(CONFIG_ANDROID_TIMED_OUTPUT) += timed_output.o -obj-$(CONFIG_ANDROID_TIMED_GPIO) += timed_gpio.o obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER) += lowmemorykiller.o obj-$(CONFIG_SYNC) += sync.o sync_debug.o obj-$(CONFIG_SW_SYNC) += sw_sync.o diff --git a/drivers/staging/android/timed_gpio.c b/drivers/staging/android/timed_gpio.c deleted file mode 100644 index 914fd1005467..000000000000 --- a/drivers/staging/android/timed_gpio.c +++ /dev/null @@ -1,166 +0,0 @@ -/* drivers/misc/timed_gpio.c - * - * Copyright (C) 2008 Google, Inc. - * Author: Mike Lockwood - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "timed_output.h" -#include "timed_gpio.h" - -struct timed_gpio_data { - struct timed_output_dev dev; - struct hrtimer timer; - spinlock_t lock; - unsigned gpio; - int max_timeout; - u8 active_low; -}; - -static enum hrtimer_restart gpio_timer_func(struct hrtimer *timer) -{ - struct timed_gpio_data *data = - container_of(timer, struct timed_gpio_data, timer); - - gpio_direction_output(data->gpio, data->active_low ? 1 : 0); - return HRTIMER_NORESTART; -} - -static int gpio_get_time(struct timed_output_dev *dev) -{ - struct timed_gpio_data *data; - ktime_t t; - - data = container_of(dev, struct timed_gpio_data, dev); - - if (!hrtimer_active(&data->timer)) - return 0; - - t = hrtimer_get_remaining(&data->timer); - - return ktime_to_ms(t); -} - -static void gpio_enable(struct timed_output_dev *dev, int value) -{ - struct timed_gpio_data *data = - container_of(dev, struct timed_gpio_data, dev); - unsigned long flags; - - spin_lock_irqsave(&data->lock, flags); - - /* cancel previous timer and set GPIO according to value */ - hrtimer_cancel(&data->timer); - gpio_direction_output(data->gpio, data->active_low ? !value : !!value); - - if (value > 0) { - if (value > data->max_timeout) - value = data->max_timeout; - - hrtimer_start(&data->timer, - ktime_set(value / 1000, (value % 1000) * 1000000), - HRTIMER_MODE_REL); - } - - spin_unlock_irqrestore(&data->lock, flags); -} - -static int timed_gpio_probe(struct platform_device *pdev) -{ - struct timed_gpio_platform_data *pdata = pdev->dev.platform_data; - struct timed_gpio *cur_gpio; - struct timed_gpio_data *gpio_data, *gpio_dat; - int i, ret; - - if (!pdata) - return -EBUSY; - - gpio_data = devm_kcalloc(&pdev->dev, pdata->num_gpios, - sizeof(*gpio_data), GFP_KERNEL); - if (!gpio_data) - return -ENOMEM; - - for (i = 0; i < pdata->num_gpios; i++) { - cur_gpio = &pdata->gpios[i]; - gpio_dat = &gpio_data[i]; - - hrtimer_init(&gpio_dat->timer, CLOCK_MONOTONIC, - HRTIMER_MODE_REL); - gpio_dat->timer.function = gpio_timer_func; - spin_lock_init(&gpio_dat->lock); - - gpio_dat->dev.name = cur_gpio->name; - gpio_dat->dev.get_time = gpio_get_time; - gpio_dat->dev.enable = gpio_enable; - ret = gpio_request(cur_gpio->gpio, cur_gpio->name); - if (ret < 0) - goto err_out; - ret = timed_output_dev_register(&gpio_dat->dev); - if (ret < 0) { - gpio_free(cur_gpio->gpio); - goto err_out; - } - - gpio_dat->gpio = cur_gpio->gpio; - gpio_dat->max_timeout = cur_gpio->max_timeout; - gpio_dat->active_low = cur_gpio->active_low; - gpio_direction_output(gpio_dat->gpio, gpio_dat->active_low); - } - - platform_set_drvdata(pdev, gpio_data); - - return 0; - -err_out: - while (--i >= 0) { - timed_output_dev_unregister(&gpio_data[i].dev); - gpio_free(gpio_data[i].gpio); - } - - return ret; -} - -static int timed_gpio_remove(struct platform_device *pdev) -{ - struct timed_gpio_platform_data *pdata = pdev->dev.platform_data; - struct timed_gpio_data *gpio_data = platform_get_drvdata(pdev); - int i; - - for (i = 0; i < pdata->num_gpios; i++) { - timed_output_dev_unregister(&gpio_data[i].dev); - gpio_free(gpio_data[i].gpio); - } - - return 0; -} - -static struct platform_driver timed_gpio_driver = { - .probe = timed_gpio_probe, - .remove = timed_gpio_remove, - .driver = { - .name = TIMED_GPIO_NAME, - }, -}; - -module_platform_driver(timed_gpio_driver); - -MODULE_AUTHOR("Mike Lockwood "); -MODULE_DESCRIPTION("timed gpio driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/android/timed_gpio.h b/drivers/staging/android/timed_gpio.h deleted file mode 100644 index d29e169d7ebe..000000000000 --- a/drivers/staging/android/timed_gpio.h +++ /dev/null @@ -1,33 +0,0 @@ -/* include/linux/timed_gpio.h - * - * Copyright (C) 2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * -*/ - -#ifndef _LINUX_TIMED_GPIO_H -#define _LINUX_TIMED_GPIO_H - -#define TIMED_GPIO_NAME "timed-gpio" - -struct timed_gpio { - const char *name; - unsigned gpio; - int max_timeout; - u8 active_low; -}; - -struct timed_gpio_platform_data { - int num_gpios; - struct timed_gpio *gpios; -}; - -#endif diff --git a/drivers/staging/android/timed_output.c b/drivers/staging/android/timed_output.c deleted file mode 100644 index aff9cdb007e5..000000000000 --- a/drivers/staging/android/timed_output.c +++ /dev/null @@ -1,110 +0,0 @@ -/* drivers/misc/timed_output.c - * - * Copyright (C) 2009 Google, Inc. - * Author: Mike Lockwood - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#define pr_fmt(fmt) "timed_output: " fmt - -#include -#include -#include -#include -#include -#include - -#include "timed_output.h" - -static struct class *timed_output_class; -static atomic_t device_count; - -static ssize_t enable_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct timed_output_dev *tdev = dev_get_drvdata(dev); - int remaining = tdev->get_time(tdev); - - return sprintf(buf, "%d\n", remaining); -} - -static ssize_t enable_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t size) -{ - struct timed_output_dev *tdev = dev_get_drvdata(dev); - int value; - int rc; - - rc = kstrtoint(buf, 0, &value); - if (rc != 0) - return -EINVAL; - - tdev->enable(tdev, value); - - return size; -} -static DEVICE_ATTR_RW(enable); - -static struct attribute *timed_output_attrs[] = { - &dev_attr_enable.attr, - NULL, -}; -ATTRIBUTE_GROUPS(timed_output); - -static int create_timed_output_class(void) -{ - if (!timed_output_class) { - timed_output_class = class_create(THIS_MODULE, "timed_output"); - if (IS_ERR(timed_output_class)) - return PTR_ERR(timed_output_class); - atomic_set(&device_count, 0); - timed_output_class->dev_groups = timed_output_groups; - } - - return 0; -} - -int timed_output_dev_register(struct timed_output_dev *tdev) -{ - int ret; - - if (!tdev || !tdev->name || !tdev->enable || !tdev->get_time) - return -EINVAL; - - ret = create_timed_output_class(); - if (ret < 0) - return ret; - - tdev->index = atomic_inc_return(&device_count); - tdev->dev = device_create(timed_output_class, NULL, - MKDEV(0, tdev->index), NULL, "%s", tdev->name); - if (IS_ERR(tdev->dev)) - return PTR_ERR(tdev->dev); - - dev_set_drvdata(tdev->dev, tdev); - tdev->state = 0; - return 0; -} -EXPORT_SYMBOL_GPL(timed_output_dev_register); - -void timed_output_dev_unregister(struct timed_output_dev *tdev) -{ - tdev->enable(tdev, 0); - device_destroy(timed_output_class, MKDEV(0, tdev->index)); -} -EXPORT_SYMBOL_GPL(timed_output_dev_unregister); - -static int __init timed_output_init(void) -{ - return create_timed_output_class(); -} -device_initcall(timed_output_init); diff --git a/drivers/staging/android/timed_output.h b/drivers/staging/android/timed_output.h deleted file mode 100644 index 13d2ca51cbe8..000000000000 --- a/drivers/staging/android/timed_output.h +++ /dev/null @@ -1,37 +0,0 @@ -/* include/linux/timed_output.h - * - * Copyright (C) 2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * -*/ - -#ifndef _LINUX_TIMED_OUTPUT_H -#define _LINUX_TIMED_OUTPUT_H - -struct timed_output_dev { - const char *name; - - /* enable the output and set the timer */ - void (*enable)(struct timed_output_dev *sdev, int timeout); - - /* returns the current number of milliseconds remaining on the timer */ - int (*get_time)(struct timed_output_dev *sdev); - - /* private data */ - struct device *dev; - int index; - int state; -}; - -int timed_output_dev_register(struct timed_output_dev *dev); -void timed_output_dev_unregister(struct timed_output_dev *dev); - -#endif -- cgit v1.2.3 From 411059f701f0e8d23b5b5a94f9e43df7e32251f8 Mon Sep 17 00:00:00 2001 From: Ben Marsh Date: Mon, 28 Mar 2016 19:26:19 +0200 Subject: Staging: android: change memory allocation style in ion.c Chnages memory allocation style in order to silence a checkpatch.pl warning. Signed-off-by: Ben Marsh Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/ion/ion.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index 85365672c931..d4c6207ca2c1 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -184,7 +184,7 @@ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap, struct scatterlist *sg; int i, ret; - buffer = kzalloc(sizeof(struct ion_buffer), GFP_KERNEL); + buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); if (!buffer) return ERR_PTR(-ENOMEM); @@ -341,7 +341,7 @@ static struct ion_handle *ion_handle_create(struct ion_client *client, { struct ion_handle *handle; - handle = kzalloc(sizeof(struct ion_handle), GFP_KERNEL); + handle = kzalloc(sizeof(*handle), GFP_KERNEL); if (!handle) return ERR_PTR(-ENOMEM); kref_init(&handle->ref); @@ -827,7 +827,7 @@ struct ion_client *ion_client_create(struct ion_device *dev, } task_unlock(current->group_leader); - client = kzalloc(sizeof(struct ion_client), GFP_KERNEL); + client = kzalloc(sizeof(*client), GFP_KERNEL); if (!client) goto err_put_task_struct; @@ -1035,7 +1035,7 @@ static void ion_vm_open(struct vm_area_struct *vma) struct ion_buffer *buffer = vma->vm_private_data; struct ion_vma_list *vma_list; - vma_list = kmalloc(sizeof(struct ion_vma_list), GFP_KERNEL); + vma_list = kmalloc(sizeof(*vma_list), GFP_KERNEL); if (!vma_list) return; vma_list->vma = vma; @@ -1650,7 +1650,7 @@ struct ion_device *ion_device_create(long (*custom_ioctl) struct ion_device *idev; int ret; - idev = kzalloc(sizeof(struct ion_device), GFP_KERNEL); + idev = kzalloc(sizeof(*idev), GFP_KERNEL); if (!idev) return ERR_PTR(-ENOMEM); -- cgit v1.2.3 From 9f37d399f19f9efbcecafe647ba3cf3c9653bb05 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 30 Mar 2016 11:36:57 -0700 Subject: staging: comedi: amplc_pc263: tidy up digital output subdevice init For aesthetics, add some whitespace to the digital output subdevice initialization. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pc263.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index b1946ce6ecc1..13d8ed204fbe 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -80,14 +80,15 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; + /* Digital Output subdevice */ s = &dev->subdevices[0]; - /* digital output subdevice */ - s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE; - s->n_chan = 16; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = pc263_do_insn_bits; + s->type = COMEDI_SUBD_DO; + s->subdev_flags = SDF_WRITABLE; + s->n_chan = 16; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = pc263_do_insn_bits; + /* read initial relay state */ s->state = inb(dev->iobase) | (inb(dev->iobase + 1) << 8); -- cgit v1.2.3 From d69917a64ae78c27348164e7cabc03a838df3e40 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 30 Mar 2016 11:36:56 -0700 Subject: staging: comedi: amplc_pc263: tidy up comedi_driver definition For aesthetics, add some whitespace to the comedi_driver definition. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pc263.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index 13d8ed204fbe..eb447e5df2f3 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -96,13 +96,13 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) } static struct comedi_driver amplc_pc263_driver = { - .driver_name = "amplc_pc263", - .module = THIS_MODULE, - .attach = pc263_attach, - .detach = comedi_legacy_detach, - .board_name = &pc263_boards[0].name, - .offset = sizeof(struct pc263_board), - .num_names = ARRAY_SIZE(pc263_boards), + .driver_name = "amplc_pc263", + .module = THIS_MODULE, + .attach = pc263_attach, + .detach = comedi_legacy_detach, + .board_name = &pc263_boards[0].name, + .offset = sizeof(struct pc263_board), + .num_names = ARRAY_SIZE(pc263_boards), }; module_comedi_driver(amplc_pc263_driver); -- cgit v1.2.3 From 1b50167146139402be0924aab55062b391cb8956 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 30 Mar 2016 11:36:58 -0700 Subject: staging: comedi: amplc_pc263: define the register map For completeness, define the registers used by this driver and remove the magic numbers. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pc263.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index eb447e5df2f3..fc075ed7962e 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -37,10 +37,8 @@ The state of the outputs can be read. #include "../comedidev.h" /* PC263 registers */ - -/* - * Board descriptions for Amplicon PC263. - */ +#define PC263_DO_0_7_REG 0x00 +#define PC263_DO_8_15_REG 0x01 struct pc263_board { const char *name; @@ -58,8 +56,8 @@ static int pc263_do_insn_bits(struct comedi_device *dev, unsigned int *data) { if (comedi_dio_update_state(s, data)) { - outb(s->state & 0xff, dev->iobase); - outb((s->state >> 8) & 0xff, dev->iobase + 1); + outb(s->state & 0xff, dev->iobase + PC263_DO_0_7_REG); + outb((s->state >> 8) & 0xff, dev->iobase + PC263_DO_8_15_REG); } data[1] = s->state; @@ -90,7 +88,8 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->insn_bits = pc263_do_insn_bits; /* read initial relay state */ - s->state = inb(dev->iobase) | (inb(dev->iobase + 1) << 8); + s->state = inb(dev->iobase + PC263_DO_0_7_REG) | + (inb(dev->iobase + PC263_DO_8_15_REG) << 8); return 0; } -- cgit v1.2.3 From 05380cde47247daec0956fb818c63093a92d5585 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 30 Mar 2016 11:36:55 -0700 Subject: staging: comedi: amplc_pc263: fix block comments Fix the checkpatch.pl issues: WARNING: Block comments use * on subsequent lines Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pc263.c | 62 ++++++++++++++-------------- 1 file changed, 31 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index fc075ed7962e..58b0b6b1a693 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -1,37 +1,37 @@ /* - comedi/drivers/amplc_pc263.c - Driver for Amplicon PC263 and PCI263 relay boards. + * Driver for Amplicon PC263 relay board. + * + * Copyright (C) 2002 MEV Ltd. + * + * COMEDI - Linux Control and Measurement Device Interface + * Copyright (C) 2000 David A. Schleef + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ - Copyright (C) 2002 MEV Ltd. - - COMEDI - Linux Control and Measurement Device Interface - Copyright (C) 2000 David A. Schleef - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -*/ /* -Driver: amplc_pc263 -Description: Amplicon PC263 -Author: Ian Abbott -Devices: [Amplicon] PC263 (pc263) -Updated: Fri, 12 Apr 2013 15:19:36 +0100 -Status: works - -Configuration options: - [0] - I/O port base address - -The board appears as one subdevice, with 16 digital outputs, each -connected to a reed-relay. Relay contacts are closed when output is 1. -The state of the outputs can be read. -*/ + * Driver: amplc_pc263 + * Description: Amplicon PC263 + * Author: Ian Abbott + * Devices: [Amplicon] PC263 (pc263) + * Updated: Fri, 12 Apr 2013 15:19:36 +0100 + * Status: works + * + * Configuration options: + * [0] - I/O port base address + * + * The board appears as one subdevice, with 16 digital outputs, each + * connected to a reed-relay. Relay contacts are closed when output is 1. + * The state of the outputs can be read. + */ #include #include "../comedidev.h" -- cgit v1.2.3 From eecbf23476d33c79c9315277ed2b2e17ef34a955 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 30 Mar 2016 11:09:48 -0700 Subject: staging: comedi: amplc_dio200_common: Prefer 'unsigned int' to bare use of 'unsigned' Fix the checkpatch.pl issues. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200_common.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/amplc_dio200_common.c b/drivers/staging/comedi/drivers/amplc_dio200_common.c index d1539e798ffd..071d2fb4d7d0 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200_common.c +++ b/drivers/staging/comedi/drivers/amplc_dio200_common.c @@ -221,7 +221,7 @@ static void dio200_start_intr(struct comedi_device *dev, struct dio200_subdev_intr *subpriv = s->private; struct comedi_cmd *cmd = &s->async->cmd; unsigned int n; - unsigned isn_bits; + unsigned int isn_bits; /* Determine interrupt sources to enable. */ isn_bits = 0; @@ -284,9 +284,9 @@ static int dio200_handle_read_intr(struct comedi_device *dev, { const struct dio200_board *board = dev->board_ptr; struct dio200_subdev_intr *subpriv = s->private; - unsigned triggered; - unsigned intstat; - unsigned cur_enabled; + unsigned int triggered; + unsigned int intstat; + unsigned int cur_enabled; unsigned long flags; triggered = 0; @@ -439,7 +439,7 @@ static int dio200_subdev_intr_cmd(struct comedi_device *dev, static int dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int offset, - unsigned valid_isns) + unsigned int valid_isns) { const struct dio200_board *board = dev->board_ptr; struct dio200_subdev_intr *subpriv; -- cgit v1.2.3 From 6050b1cfc66c421546880c0219cbce9102800099 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 30 Mar 2016 11:09:49 -0700 Subject: staging: comedi: amplc_dio200_common: document spinlock definition Fix the checkpatch.pl issue: CHECK: spinlock_t definition without comment Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/amplc_dio200_common.c b/drivers/staging/comedi/drivers/amplc_dio200_common.c index 071d2fb4d7d0..f6e4e984235d 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200_common.c +++ b/drivers/staging/comedi/drivers/amplc_dio200_common.c @@ -101,7 +101,7 @@ struct dio200_subdev_8255 { }; struct dio200_subdev_intr { - spinlock_t spinlock; + spinlock_t spinlock; /* protects the 'active' flag */ unsigned int ofs; unsigned int valid_isns; unsigned int enabled_isns; -- cgit v1.2.3 From 61ac7ccfb5cbe59ee940f0a7b3ad4fd3e3ce8c37 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 30 Mar 2016 12:19:21 -0700 Subject: staging: comedi: amplc_pci230: Prefer using the BIT macro Fix the checkpatch.pl issues by using the BIT macro and defining some macros for the multi-bit fields. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci230.c | 141 ++++++++++++++------------ 1 file changed, 74 insertions(+), 67 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index cf5ac8aad236..5d0cb37c4e0e 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -237,47 +237,50 @@ /* * DACCON read-write values. */ -#define PCI230_DAC_OR_UNI (0 << 0) /* Output range unipolar */ -#define PCI230_DAC_OR_BIP (1 << 0) /* Output range bipolar */ -#define PCI230_DAC_OR_MASK (1 << 0) +#define PCI230_DAC_OR(x) (((x) & 0x1) << 0) +#define PCI230_DAC_OR_UNI PCI230_DAC_OR(0) /* Output unipolar */ +#define PCI230_DAC_OR_BIP PCI230_DAC_OR(1) /* Output bipolar */ +#define PCI230_DAC_OR_MASK PCI230_DAC_OR(1) /* * The following applies only if DAC FIFO support is enabled in the EXTFUNC * register (and only for PCI230+ hardware version 2 onwards). */ -#define PCI230P2_DAC_FIFO_EN (1 << 8) /* FIFO enable */ +#define PCI230P2_DAC_FIFO_EN BIT(8) /* FIFO enable */ /* * The following apply only if the DAC FIFO is enabled (and only for PCI230+ * hardware version 2 onwards). */ -#define PCI230P2_DAC_TRIG_NONE (0 << 2) /* No trigger */ -#define PCI230P2_DAC_TRIG_SW (1 << 2) /* Software trigger trigger */ -#define PCI230P2_DAC_TRIG_EXTP (2 << 2) /* EXTTRIG +ve edge trigger */ -#define PCI230P2_DAC_TRIG_EXTN (3 << 2) /* EXTTRIG -ve edge trigger */ -#define PCI230P2_DAC_TRIG_Z2CT0 (4 << 2) /* CT0-OUT +ve edge trigger */ -#define PCI230P2_DAC_TRIG_Z2CT1 (5 << 2) /* CT1-OUT +ve edge trigger */ -#define PCI230P2_DAC_TRIG_Z2CT2 (6 << 2) /* CT2-OUT +ve edge trigger */ -#define PCI230P2_DAC_TRIG_MASK (7 << 2) -#define PCI230P2_DAC_FIFO_WRAP (1 << 7) /* FIFO wraparound mode */ -#define PCI230P2_DAC_INT_FIFO_EMPTY (0 << 9) /* FIFO interrupt empty */ -#define PCI230P2_DAC_INT_FIFO_NEMPTY (1 << 9) -#define PCI230P2_DAC_INT_FIFO_NHALF (2 << 9) /* FIFO intr not half full */ -#define PCI230P2_DAC_INT_FIFO_HALF (3 << 9) -#define PCI230P2_DAC_INT_FIFO_NFULL (4 << 9) /* FIFO interrupt not full */ -#define PCI230P2_DAC_INT_FIFO_FULL (5 << 9) -#define PCI230P2_DAC_INT_FIFO_MASK (7 << 9) +#define PCI230P2_DAC_TRIG(x) (((x) & 0x7) << 2) +#define PCI230P2_DAC_TRIG_NONE PCI230P2_DAC_TRIG(0) /* none */ +#define PCI230P2_DAC_TRIG_SW PCI230P2_DAC_TRIG(1) /* soft trig */ +#define PCI230P2_DAC_TRIG_EXTP PCI230P2_DAC_TRIG(2) /* ext + edge */ +#define PCI230P2_DAC_TRIG_EXTN PCI230P2_DAC_TRIG(3) /* ext - edge */ +#define PCI230P2_DAC_TRIG_Z2CT0 PCI230P2_DAC_TRIG(4) /* Z2 CT0 out */ +#define PCI230P2_DAC_TRIG_Z2CT1 PCI230P2_DAC_TRIG(5) /* Z2 CT1 out */ +#define PCI230P2_DAC_TRIG_Z2CT2 PCI230P2_DAC_TRIG(6) /* Z2 CT2 out */ +#define PCI230P2_DAC_TRIG_MASK PCI230P2_DAC_TRIG(7) +#define PCI230P2_DAC_FIFO_WRAP BIT(7) /* FIFO wraparound mode */ +#define PCI230P2_DAC_INT_FIFO(x) (((x) & 7) << 9) +#define PCI230P2_DAC_INT_FIFO_EMPTY PCI230P2_DAC_INT_FIFO(0) /* empty */ +#define PCI230P2_DAC_INT_FIFO_NEMPTY PCI230P2_DAC_INT_FIFO(1) /* !empty */ +#define PCI230P2_DAC_INT_FIFO_NHALF PCI230P2_DAC_INT_FIFO(2) /* !half */ +#define PCI230P2_DAC_INT_FIFO_HALF PCI230P2_DAC_INT_FIFO(3) /* half */ +#define PCI230P2_DAC_INT_FIFO_NFULL PCI230P2_DAC_INT_FIFO(4) /* !full */ +#define PCI230P2_DAC_INT_FIFO_FULL PCI230P2_DAC_INT_FIFO(5) /* full */ +#define PCI230P2_DAC_INT_FIFO_MASK PCI230P2_DAC_INT_FIFO(7) /* * DACCON read-only values. */ -#define PCI230_DAC_BUSY (1 << 1) /* DAC busy. */ +#define PCI230_DAC_BUSY BIT(1) /* DAC busy. */ /* * The following apply only if the DAC FIFO is enabled (and only for PCI230+ * hardware version 2 onwards). */ -#define PCI230P2_DAC_FIFO_UNDERRUN_LATCHED (1 << 5) /* Underrun error */ -#define PCI230P2_DAC_FIFO_EMPTY (1 << 13) /* FIFO empty */ -#define PCI230P2_DAC_FIFO_FULL (1 << 14) /* FIFO full */ -#define PCI230P2_DAC_FIFO_HALF (1 << 15) /* FIFO half full */ +#define PCI230P2_DAC_FIFO_UNDERRUN_LATCHED BIT(5) /* Underrun error */ +#define PCI230P2_DAC_FIFO_EMPTY BIT(13) /* FIFO empty */ +#define PCI230P2_DAC_FIFO_FULL BIT(14) /* FIFO full */ +#define PCI230P2_DAC_FIFO_HALF BIT(15) /* FIFO half full */ /* * DACCON write-only, transient values. @@ -286,8 +289,8 @@ * The following apply only if the DAC FIFO is enabled (and only for PCI230+ * hardware version 2 onwards). */ -#define PCI230P2_DAC_FIFO_UNDERRUN_CLEAR (1 << 5) /* Clear underrun */ -#define PCI230P2_DAC_FIFO_RESET (1 << 12) /* FIFO reset */ +#define PCI230P2_DAC_FIFO_UNDERRUN_CLEAR BIT(5) /* Clear underrun */ +#define PCI230P2_DAC_FIFO_RESET BIT(12) /* FIFO reset */ /* * PCI230+ hardware version 2 DAC FIFO levels. @@ -304,44 +307,48 @@ /* * ADCCON read/write values. */ -#define PCI230_ADC_TRIG_NONE (0 << 0) /* No trigger */ -#define PCI230_ADC_TRIG_SW (1 << 0) /* Software trigger trigger */ -#define PCI230_ADC_TRIG_EXTP (2 << 0) /* EXTTRIG +ve edge trigger */ -#define PCI230_ADC_TRIG_EXTN (3 << 0) /* EXTTRIG -ve edge trigger */ -#define PCI230_ADC_TRIG_Z2CT0 (4 << 0) /* CT0-OUT +ve edge trigger */ -#define PCI230_ADC_TRIG_Z2CT1 (5 << 0) /* CT1-OUT +ve edge trigger */ -#define PCI230_ADC_TRIG_Z2CT2 (6 << 0) /* CT2-OUT +ve edge trigger */ -#define PCI230_ADC_TRIG_MASK (7 << 0) -#define PCI230_ADC_IR_UNI (0 << 3) /* Input range unipolar */ -#define PCI230_ADC_IR_BIP (1 << 3) /* Input range bipolar */ -#define PCI230_ADC_IR_MASK (1 << 3) -#define PCI230_ADC_IM_SE (0 << 4) /* Input mode single ended */ -#define PCI230_ADC_IM_DIF (1 << 4) /* Input mode differential */ -#define PCI230_ADC_IM_MASK (1 << 4) -#define PCI230_ADC_FIFO_EN (1 << 8) /* FIFO enable */ -#define PCI230_ADC_INT_FIFO_EMPTY (0 << 9) -#define PCI230_ADC_INT_FIFO_NEMPTY (1 << 9) /* FIFO interrupt not empty */ -#define PCI230_ADC_INT_FIFO_NHALF (2 << 9) -#define PCI230_ADC_INT_FIFO_HALF (3 << 9) /* FIFO interrupt half full */ -#define PCI230_ADC_INT_FIFO_NFULL (4 << 9) -#define PCI230_ADC_INT_FIFO_FULL (5 << 9) /* FIFO interrupt full */ -#define PCI230P_ADC_INT_FIFO_THRESH (7 << 9) /* FIFO interrupt threshold */ -#define PCI230_ADC_INT_FIFO_MASK (7 << 9) +#define PCI230_ADC_TRIG(x) (((x) & 0x7) << 0) +#define PCI230_ADC_TRIG_NONE PCI230_ADC_TRIG(0) /* none */ +#define PCI230_ADC_TRIG_SW PCI230_ADC_TRIG(1) /* soft trig */ +#define PCI230_ADC_TRIG_EXTP PCI230_ADC_TRIG(2) /* ext + edge */ +#define PCI230_ADC_TRIG_EXTN PCI230_ADC_TRIG(3) /* ext - edge */ +#define PCI230_ADC_TRIG_Z2CT0 PCI230_ADC_TRIG(4) /* Z2 CT0 out*/ +#define PCI230_ADC_TRIG_Z2CT1 PCI230_ADC_TRIG(5) /* Z2 CT1 out */ +#define PCI230_ADC_TRIG_Z2CT2 PCI230_ADC_TRIG(6) /* Z2 CT2 out */ +#define PCI230_ADC_TRIG_MASK PCI230_ADC_TRIG(7) +#define PCI230_ADC_IR(x) (((x) & 0x1) << 3) +#define PCI230_ADC_IR_UNI PCI230_ADC_IR(0) /* Input unipolar */ +#define PCI230_ADC_IR_BIP PCI230_ADC_IR(1) /* Input bipolar */ +#define PCI230_ADC_IR_MASK PCI230_ADC_IR(1) +#define PCI230_ADC_IM(x) (((x) & 0x1) << 4) +#define PCI230_ADC_IM_SE PCI230_ADC_IM(0) /* single ended */ +#define PCI230_ADC_IM_DIF PCI230_ADC_IM(1) /* differential */ +#define PCI230_ADC_IM_MASK PCI230_ADC_IM(1) +#define PCI230_ADC_FIFO_EN BIT(8) /* FIFO enable */ +#define PCI230_ADC_INT_FIFO(x) (((x) & 0x7) << 9) +#define PCI230_ADC_INT_FIFO_EMPTY PCI230_ADC_INT_FIFO(0) /* empty */ +#define PCI230_ADC_INT_FIFO_NEMPTY PCI230_ADC_INT_FIFO(1) /* !empty */ +#define PCI230_ADC_INT_FIFO_NHALF PCI230_ADC_INT_FIFO(2) /* !half */ +#define PCI230_ADC_INT_FIFO_HALF PCI230_ADC_INT_FIFO(3) /* half */ +#define PCI230_ADC_INT_FIFO_NFULL PCI230_ADC_INT_FIFO(4) /* !full */ +#define PCI230_ADC_INT_FIFO_FULL PCI230_ADC_INT_FIFO(5) /* full */ +#define PCI230P_ADC_INT_FIFO_THRESH PCI230_ADC_INT_FIFO(7) /* threshold */ +#define PCI230_ADC_INT_FIFO_MASK PCI230_ADC_INT_FIFO(7) /* * ADCCON write-only, transient values. */ -#define PCI230_ADC_FIFO_RESET (1 << 12) /* FIFO reset */ -#define PCI230_ADC_GLOB_RESET (1 << 13) /* Global reset */ +#define PCI230_ADC_FIFO_RESET BIT(12) /* FIFO reset */ +#define PCI230_ADC_GLOB_RESET BIT(13) /* Global reset */ /* * ADCCON read-only values. */ -#define PCI230_ADC_BUSY (1 << 15) /* ADC busy */ -#define PCI230_ADC_FIFO_EMPTY (1 << 12) /* FIFO empty */ -#define PCI230_ADC_FIFO_FULL (1 << 13) /* FIFO full */ -#define PCI230_ADC_FIFO_HALF (1 << 14) /* FIFO half full */ -#define PCI230_ADC_FIFO_FULL_LATCHED (1 << 5) /* FIFO overrun occurred */ +#define PCI230_ADC_BUSY BIT(15) /* ADC busy */ +#define PCI230_ADC_FIFO_EMPTY BIT(12) /* FIFO empty */ +#define PCI230_ADC_FIFO_FULL BIT(13) /* FIFO full */ +#define PCI230_ADC_FIFO_HALF BIT(14) /* FIFO half full */ +#define PCI230_ADC_FIFO_FULL_LATCHED BIT(5) /* FIFO overrun occurred */ /* * PCI230 ADC FIFO levels. @@ -353,10 +360,10 @@ * PCI230+ EXTFUNC values. */ /* Route EXTTRIG pin to external gate inputs. */ -#define PCI230P_EXTFUNC_GAT_EXTTRIG (1 << 0) +#define PCI230P_EXTFUNC_GAT_EXTTRIG BIT(0) /* PCI230+ hardware version 2 values. */ /* Allow DAC FIFO to be enabled. */ -#define PCI230P2_EXTFUNC_DACFIFO (1 << 1) +#define PCI230P2_EXTFUNC_DACFIFO BIT(1) /* * Counter/timer clock input configuration sources. @@ -402,20 +409,20 @@ static inline unsigned int pci230_gat_config(unsigned int chan, * Interrupt enables/status register values. */ #define PCI230_INT_DISABLE 0 -#define PCI230_INT_PPI_C0 (1 << 0) -#define PCI230_INT_PPI_C3 (1 << 1) -#define PCI230_INT_ADC (1 << 2) -#define PCI230_INT_ZCLK_CT1 (1 << 5) +#define PCI230_INT_PPI_C0 BIT(0) +#define PCI230_INT_PPI_C3 BIT(1) +#define PCI230_INT_ADC BIT(2) +#define PCI230_INT_ZCLK_CT1 BIT(5) /* For PCI230+ hardware version 2 when DAC FIFO enabled. */ -#define PCI230P2_INT_DAC (1 << 4) +#define PCI230P2_INT_DAC BIT(4) /* * (Potentially) shared resources and their owners */ enum { - RES_Z2CT0 = (1U << 0), /* Z2-CT0 */ - RES_Z2CT1 = (1U << 1), /* Z2-CT1 */ - RES_Z2CT2 = (1U << 2) /* Z2-CT2 */ + RES_Z2CT0 = BIT(0), /* Z2-CT0 */ + RES_Z2CT1 = BIT(1), /* Z2-CT1 */ + RES_Z2CT2 = BIT(2) /* Z2-CT2 */ }; enum { -- cgit v1.2.3 From e76415f47f9f4ec4f0289f8194eae0726dc27dfd Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 30 Mar 2016 12:19:22 -0700 Subject: staging: comedi: amplc_pci230: Prefer kernel type 'u64' over 'uint64_t' Fix the checkpatch.pl issues. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci230.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index 5d0cb37c4e0e..42945de31fe2 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -637,10 +637,10 @@ static void pci230_release_all_resources(struct comedi_device *dev, pci230_release_shared(dev, (unsigned char)~0, owner); } -static unsigned int pci230_divide_ns(uint64_t ns, unsigned int timebase, +static unsigned int pci230_divide_ns(u64 ns, unsigned int timebase, unsigned int flags) { - uint64_t div; + u64 div; unsigned int rem; div = ns; @@ -663,7 +663,7 @@ static unsigned int pci230_divide_ns(uint64_t ns, unsigned int timebase, * Given desired period in ns, returns the required internal clock source * and gets the initial count. */ -static unsigned int pci230_choose_clk_count(uint64_t ns, unsigned int *count, +static unsigned int pci230_choose_clk_count(u64 ns, unsigned int *count, unsigned int flags) { unsigned int clk_src, cnt; @@ -687,7 +687,7 @@ static void pci230_ns_to_single_timer(unsigned int *ns, unsigned int flags) } static void pci230_ct_setup_ns_mode(struct comedi_device *dev, unsigned int ct, - unsigned int mode, uint64_t ns, + unsigned int mode, u64 ns, unsigned int flags) { unsigned int clk_src; @@ -2250,7 +2250,7 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) zgat = pci230_gat_config(0, GAT_VCC); outb(zgat, dev->iobase + PCI230_ZGAT_SCE); pci230_ct_setup_ns_mode(dev, 0, I8254_MODE1, - ((uint64_t)cmd->convert_arg * + ((u64)cmd->convert_arg * cmd->scan_end_arg), CMDF_ROUND_UP); if (cmd->scan_begin_src == TRIG_TIMER) { -- cgit v1.2.3 From 9bc9e60e4f48b2917718d0dcf8a3cbb9f7687dd7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 30 Mar 2016 12:34:53 -0700 Subject: staging: comedi: c6xdigio: Prefer using the BIT macro Fix the checkpatch.pl issues. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/c6xdigio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/c6xdigio.c b/drivers/staging/comedi/drivers/c6xdigio.c index 1a109e30d8ff..8ee732571588 100644 --- a/drivers/staging/comedi/drivers/c6xdigio.c +++ b/drivers/staging/comedi/drivers/c6xdigio.c @@ -47,8 +47,8 @@ */ #define C6XDIGIO_DATA_REG 0x00 #define C6XDIGIO_DATA_CHAN(x) (((x) + 1) << 4) -#define C6XDIGIO_DATA_PWM (1 << 5) -#define C6XDIGIO_DATA_ENCODER (1 << 6) +#define C6XDIGIO_DATA_PWM BIT(5) +#define C6XDIGIO_DATA_ENCODER BIT(6) #define C6XDIGIO_STATUS_REG 0x01 #define C6XDIGIO_CTRL_REG 0x02 -- cgit v1.2.3 From f91852ce61339ca0ca557c7ce5838f3a774a1bf5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 30 Mar 2016 10:47:24 -0700 Subject: staging: comedi: drivers: tidy up insn_rw_emulate_bits() Tidy up this function and fix the checkpatch.pl issues: WARNING: Prefer 'unsigned int' to bare use of 'unsigned' Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index b63dd2ef78b5..e3bbc8f724ba 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -575,38 +575,35 @@ EXPORT_SYMBOL_GPL(comedi_handle_events); static int insn_rw_emulate_bits(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { - struct comedi_insn new_insn; + struct comedi_insn _insn; + unsigned int chan = CR_CHAN(insn->chanspec); + unsigned int base_chan = (chan < 32) ? 0 : chan; + unsigned int _data[2]; int ret; - static const unsigned channels_per_bitfield = 32; - - unsigned chan = CR_CHAN(insn->chanspec); - const unsigned base_bitfield_channel = - (chan < channels_per_bitfield) ? 0 : chan; - unsigned int new_data[2]; - memset(new_data, 0, sizeof(new_data)); - memset(&new_insn, 0, sizeof(new_insn)); - new_insn.insn = INSN_BITS; - new_insn.chanspec = base_bitfield_channel; - new_insn.n = 2; - new_insn.subdev = insn->subdev; + memset(_data, 0, sizeof(_data)); + memset(&_insn, 0, sizeof(_insn)); + _insn.insn = INSN_BITS; + _insn.chanspec = base_chan; + _insn.n = 2; + _insn.subdev = insn->subdev; if (insn->insn == INSN_WRITE) { if (!(s->subdev_flags & SDF_WRITABLE)) return -EINVAL; - new_data[0] = 1 << (chan - base_bitfield_channel); /* mask */ - new_data[1] = data[0] ? (1 << (chan - base_bitfield_channel)) - : 0; /* bits */ + _data[0] = 1 << (chan - base_chan); /* mask */ + _data[1] = data[0] ? (1 << (chan - base_chan)) : 0; /* bits */ } - ret = s->insn_bits(dev, s, &new_insn, new_data); + ret = s->insn_bits(dev, s, &_insn, _data); if (ret < 0) return ret; if (insn->insn == INSN_READ) - data[0] = (new_data[1] >> (chan - base_bitfield_channel)) & 1; + data[0] = (_data[1] >> (chan - base_chan)) & 1; return 1; } -- cgit v1.2.3 From 7be7cd10ade121cd5363c5f8790638b177b5e9dd Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 30 Mar 2016 10:47:25 -0700 Subject: staging: comedi: drivers: fix possible bug in comedi_handle_events() This function assumes that the async subdevice has a cancel() function. It looks like all the current comedi drivers implement a cancel() for the async subdevices except for the dt2814 analog input usbdevice. Fix comedi_handle_events() so it does not try to call a non-existent cancel() function. Add a dev_warn() to __comedi_device_postconfig_async() so that any new driver authors will be reminded to implement the cancel(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index e3bbc8f724ba..44511d729450 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -564,7 +564,7 @@ unsigned int comedi_handle_events(struct comedi_device *dev, if (events == 0) return events; - if (events & COMEDI_CB_CANCEL_MASK) + if ((events & COMEDI_CB_CANCEL_MASK) && s->cancel) s->cancel(dev, s); comedi_event(dev, s); @@ -625,6 +625,9 @@ static int __comedi_device_postconfig_async(struct comedi_device *dev, "async subdevices must have a do_cmdtest() function\n"); return -EINVAL; } + if (!s->cancel) + dev_warn(dev->class_dev, + "async subdevices should have a cancel() function\n"); async = kzalloc(sizeof(*async), GFP_KERNEL); if (!async) -- cgit v1.2.3 From db94bfad3b05c9a3cd5c151018db142b07486d02 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 30 Mar 2016 11:45:17 -0700 Subject: staging: comedi: amplc_pci263: fix block comments Fix the checkpatch.pl issues: WARNING: Block comments use * on subsequent lines Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci263.c | 60 +++++++++++++-------------- 1 file changed, 30 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/amplc_pci263.c b/drivers/staging/comedi/drivers/amplc_pci263.c index b6768aa90547..fa36bd5587d4 100644 --- a/drivers/staging/comedi/drivers/amplc_pci263.c +++ b/drivers/staging/comedi/drivers/amplc_pci263.c @@ -1,36 +1,36 @@ /* - comedi/drivers/amplc_pci263.c - Driver for Amplicon PCI263 relay board. + * Driver for Amplicon PCI263 relay board. + * + * Copyright (C) 2002 MEV Ltd. + * + * COMEDI - Linux Control and Measurement Device Interface + * Copyright (C) 2000 David A. Schleef + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ - Copyright (C) 2002 MEV Ltd. - - COMEDI - Linux Control and Measurement Device Interface - Copyright (C) 2000 David A. Schleef - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -*/ /* -Driver: amplc_pci263 -Description: Amplicon PCI263 -Author: Ian Abbott -Devices: [Amplicon] PCI263 (amplc_pci263) -Updated: Fri, 12 Apr 2013 15:19:36 +0100 -Status: works - -Configuration options: not applicable, uses PCI auto config - -The board appears as one subdevice, with 16 digital outputs, each -connected to a reed-relay. Relay contacts are closed when output is 1. -The state of the outputs can be read. -*/ + * Driver: amplc_pci263 + * Description: Amplicon PCI263 + * Author: Ian Abbott + * Devices: [Amplicon] PCI263 (amplc_pci263) + * Updated: Fri, 12 Apr 2013 15:19:36 +0100 + * Status: works + * + * Configuration options: not applicable, uses PCI auto config + * + * The board appears as one subdevice, with 16 digital outputs, each + * connected to a reed-relay. Relay contacts are closed when output is 1. + * The state of the outputs can be read. + */ #include -- cgit v1.2.3 From 1ee79c8ee88e74fdd778c024caf84d741a134409 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 30 Mar 2016 11:45:18 -0700 Subject: staging: comedi: amplc_pci263: tidy up digital output subdevice init For aesthetics, add some whitespace to the digital output subdevice initialization. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci263.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/amplc_pci263.c b/drivers/staging/comedi/drivers/amplc_pci263.c index fa36bd5587d4..c47f042465e7 100644 --- a/drivers/staging/comedi/drivers/amplc_pci263.c +++ b/drivers/staging/comedi/drivers/amplc_pci263.c @@ -67,14 +67,15 @@ static int pci263_auto_attach(struct comedi_device *dev, if (ret) return ret; + /* Digital Output subdevice */ s = &dev->subdevices[0]; - /* digital output subdevice */ - s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE; - s->n_chan = 16; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = pci263_do_insn_bits; + s->type = COMEDI_SUBD_DO; + s->subdev_flags = SDF_WRITABLE; + s->n_chan = 16; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = pci263_do_insn_bits; + /* read initial relay state */ s->state = inb(dev->iobase) | (inb(dev->iobase + 1) << 8); -- cgit v1.2.3 From 623211de9a3bfd0fabc81f8bff8c79fd9e4944ba Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 30 Mar 2016 11:45:19 -0700 Subject: staging: comedi: amplc_pci263: define the register map For completeness, define the registers used by this driver and remove the magic numbers. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci263.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/amplc_pci263.c b/drivers/staging/comedi/drivers/amplc_pci263.c index c47f042465e7..8d4069bc5716 100644 --- a/drivers/staging/comedi/drivers/amplc_pci263.c +++ b/drivers/staging/comedi/drivers/amplc_pci263.c @@ -36,14 +36,18 @@ #include "../comedi_pci.h" +/* PCI263 registers */ +#define PCI263_DO_0_7_REG 0x00 +#define PCI263_DO_8_15_REG 0x01 + static int pci263_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { if (comedi_dio_update_state(s, data)) { - outb(s->state & 0xff, dev->iobase); - outb((s->state >> 8) & 0xff, dev->iobase + 1); + outb(s->state & 0xff, dev->iobase + PCI263_DO_0_7_REG); + outb((s->state >> 8) & 0xff, dev->iobase + PCI263_DO_8_15_REG); } data[1] = s->state; @@ -77,7 +81,8 @@ static int pci263_auto_attach(struct comedi_device *dev, s->insn_bits = pci263_do_insn_bits; /* read initial relay state */ - s->state = inb(dev->iobase) | (inb(dev->iobase + 1) << 8); + s->state = inb(dev->iobase + PCI263_DO_0_7_REG) | + (inb(dev->iobase + PCI263_DO_8_15_REG) << 8); return 0; } -- cgit v1.2.3 From e078cb2a64fd588557ef2dec573622699a05d642 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 30 Mar 2016 12:00:29 -0700 Subject: staging: comedi: amplc_pci224: Prefer using the BIT macro Fix the checkpatch.pl issues by using the BIT macro and defining some macros for the multi-bit fields. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci224.c | 71 ++++++++++++++------------- 1 file changed, 38 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index cac011fdd375..2e6decf1b69d 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -132,48 +132,53 @@ * DACCON values. */ /* (r/w) Scan trigger. */ -#define PCI224_DACCON_TRIG_MASK (7 << 0) -#define PCI224_DACCON_TRIG_NONE (0 << 0) /* none */ -#define PCI224_DACCON_TRIG_SW (1 << 0) /* software trig */ -#define PCI224_DACCON_TRIG_EXTP (2 << 0) /* ext +ve edge */ -#define PCI224_DACCON_TRIG_EXTN (3 << 0) /* ext -ve edge */ -#define PCI224_DACCON_TRIG_Z2CT0 (4 << 0) /* Z2 CT0 out */ -#define PCI224_DACCON_TRIG_Z2CT1 (5 << 0) /* Z2 CT1 out */ -#define PCI224_DACCON_TRIG_Z2CT2 (6 << 0) /* Z2 CT2 out */ +#define PCI224_DACCON_TRIG(x) (((x) & 0x7) << 0) +#define PCI224_DACCON_TRIG_MASK PCI224_DACCON_TRIG(7) +#define PCI224_DACCON_TRIG_NONE PCI224_DACCON_TRIG(0) /* none */ +#define PCI224_DACCON_TRIG_SW PCI224_DACCON_TRIG(1) /* soft trig */ +#define PCI224_DACCON_TRIG_EXTP PCI224_DACCON_TRIG(2) /* ext + edge */ +#define PCI224_DACCON_TRIG_EXTN PCI224_DACCON_TRIG(3) /* ext - edge */ +#define PCI224_DACCON_TRIG_Z2CT0 PCI224_DACCON_TRIG(4) /* Z2 CT0 out */ +#define PCI224_DACCON_TRIG_Z2CT1 PCI224_DACCON_TRIG(5) /* Z2 CT1 out */ +#define PCI224_DACCON_TRIG_Z2CT2 PCI224_DACCON_TRIG(6) /* Z2 CT2 out */ /* (r/w) Polarity (PCI224 only, PCI234 always bipolar!). */ -#define PCI224_DACCON_POLAR_MASK (1 << 3) -#define PCI224_DACCON_POLAR_UNI (0 << 3) /* range [0,Vref] */ -#define PCI224_DACCON_POLAR_BI (1 << 3) /* range [-Vref,Vref] */ +#define PCI224_DACCON_POLAR(x) (((x) & 0x1) << 3) +#define PCI224_DACCON_POLAR_MASK PCI224_DACCON_POLAR(1) +#define PCI224_DACCON_POLAR_UNI PCI224_DACCON_POLAR(0) /* [0,+V] */ +#define PCI224_DACCON_POLAR_BI PCI224_DACCON_POLAR(1) /* [-V,+V] */ /* (r/w) Internal Vref (PCI224 only, when LK1 in position 1-2). */ -#define PCI224_DACCON_VREF_MASK (3 << 4) -#define PCI224_DACCON_VREF_1_25 (0 << 4) /* Vref = 1.25V */ -#define PCI224_DACCON_VREF_2_5 (1 << 4) /* Vref = 2.5V */ -#define PCI224_DACCON_VREF_5 (2 << 4) /* Vref = 5V */ -#define PCI224_DACCON_VREF_10 (3 << 4) /* Vref = 10V */ +#define PCI224_DACCON_VREF(x) (((x) & 0x3) << 4) +#define PCI224_DACCON_VREF_MASK PCI224_DACCON_VREF(3) +#define PCI224_DACCON_VREF_1_25 PCI224_DACCON_VREF(0) /* 1.25V */ +#define PCI224_DACCON_VREF_2_5 PCI224_DACCON_VREF(1) /* 2.5V */ +#define PCI224_DACCON_VREF_5 PCI224_DACCON_VREF(2) /* 5V */ +#define PCI224_DACCON_VREF_10 PCI224_DACCON_VREF(3) /* 10V */ /* (r/w) Wraparound mode enable (to play back stored waveform). */ -#define PCI224_DACCON_FIFOWRAP (1 << 7) +#define PCI224_DACCON_FIFOWRAP BIT(7) /* (r/w) FIFO enable. It MUST be set! */ -#define PCI224_DACCON_FIFOENAB (1 << 8) +#define PCI224_DACCON_FIFOENAB BIT(8) /* (r/w) FIFO interrupt trigger level (most values are not very useful). */ -#define PCI224_DACCON_FIFOINTR_MASK (7 << 9) -#define PCI224_DACCON_FIFOINTR_EMPTY (0 << 9) /* when empty */ -#define PCI224_DACCON_FIFOINTR_NEMPTY (1 << 9) /* when not empty */ -#define PCI224_DACCON_FIFOINTR_NHALF (2 << 9) /* when not half full */ -#define PCI224_DACCON_FIFOINTR_HALF (3 << 9) /* when half full */ -#define PCI224_DACCON_FIFOINTR_NFULL (4 << 9) /* when not full */ -#define PCI224_DACCON_FIFOINTR_FULL (5 << 9) /* when full */ +#define PCI224_DACCON_FIFOINTR(x) (((x) & 0x7) << 9) +#define PCI224_DACCON_FIFOINTR_MASK PCI224_DACCON_FIFOINTR(7) +#define PCI224_DACCON_FIFOINTR_EMPTY PCI224_DACCON_FIFOINTR(0) /* empty */ +#define PCI224_DACCON_FIFOINTR_NEMPTY PCI224_DACCON_FIFOINTR(1) /* !empty */ +#define PCI224_DACCON_FIFOINTR_NHALF PCI224_DACCON_FIFOINTR(2) /* !half */ +#define PCI224_DACCON_FIFOINTR_HALF PCI224_DACCON_FIFOINTR(3) /* half */ +#define PCI224_DACCON_FIFOINTR_NFULL PCI224_DACCON_FIFOINTR(4) /* !full */ +#define PCI224_DACCON_FIFOINTR_FULL PCI224_DACCON_FIFOINTR(5) /* full */ /* (r-o) FIFO fill level. */ -#define PCI224_DACCON_FIFOFL_MASK (7 << 12) -#define PCI224_DACCON_FIFOFL_EMPTY (1 << 12) /* 0 */ -#define PCI224_DACCON_FIFOFL_ONETOHALF (0 << 12) /* [1,2048] */ -#define PCI224_DACCON_FIFOFL_HALFTOFULL (4 << 12) /* [2049,4095] */ -#define PCI224_DACCON_FIFOFL_FULL (6 << 12) /* 4096 */ +#define PCI224_DACCON_FIFOFL(x) (((x) & 0x7) << 12) +#define PCI224_DACCON_FIFOFL_MASK PCI224_DACCON_FIFOFL(7) +#define PCI224_DACCON_FIFOFL_EMPTY PCI224_DACCON_FIFOFL(1) /* 0 */ +#define PCI224_DACCON_FIFOFL_ONETOHALF PCI224_DACCON_FIFOFL(0) /* 1-2048 */ +#define PCI224_DACCON_FIFOFL_HALFTOFULL PCI224_DACCON_FIFOFL(4) /* 2049-4095 */ +#define PCI224_DACCON_FIFOFL_FULL PCI224_DACCON_FIFOFL(6) /* 4096 */ /* (r-o) DAC busy flag. */ -#define PCI224_DACCON_BUSY (1 << 15) +#define PCI224_DACCON_BUSY BIT(15) /* (w-o) FIFO reset. */ -#define PCI224_DACCON_FIFORESET (1 << 12) +#define PCI224_DACCON_FIFORESET BIT(12) /* (w-o) Global reset (not sure what it does). */ -#define PCI224_DACCON_GLOBALRESET (1 << 13) +#define PCI224_DACCON_GLOBALRESET BIT(13) /* * DAC FIFO size. -- cgit v1.2.3 From d8bf4bee49728e31b1d225630c39714a6c42648c Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Mon, 28 Mar 2016 13:54:15 +0900 Subject: staging: dgnc: replace dgnc_offset_table with bit shift. the dgnc_offset_table has a same value with (1 << port). So I tried to replace dgnc_offset_table array with 1 << port. And also there are redundant assignments(tmp and current_port) inside while loop for checking uart port, and remove them. Signed-off-by: Daeseok Youn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_neo.c | 44 +++++++++++------------------------------ 1 file changed, 12 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dgnc/dgnc_neo.c b/drivers/staging/dgnc/dgnc_neo.c index d732e6e99408..6b57c441859d 100644 --- a/drivers/staging/dgnc/dgnc_neo.c +++ b/drivers/staging/dgnc/dgnc_neo.c @@ -77,9 +77,6 @@ struct board_ops dgnc_neo_ops = { .send_immediate_char = neo_send_immediate_char }; -static uint dgnc_offset_table[8] = { 0x01, 0x02, 0x04, 0x08, - 0x10, 0x20, 0x40, 0x80 }; - /* * This function allows calls to ensure that all outstanding * PCI writes have been completed, by doing a PCI read against @@ -923,9 +920,7 @@ static irqreturn_t neo_intr(int irq, void *voidbrd) struct dgnc_board *brd = voidbrd; struct channel_t *ch; int port = 0; - int type = 0; - int current_port; - u32 tmp; + int type; u32 uart_poll; unsigned long flags; unsigned long flags2; @@ -960,29 +955,12 @@ static irqreturn_t neo_intr(int irq, void *voidbrd) /* At this point, we have at least SOMETHING to service, dig further... */ - current_port = 0; - /* Loop on each port */ while ((uart_poll & 0xff) != 0) { - tmp = uart_poll; - - /* Check current port to see if it has interrupt pending */ - if ((tmp & dgnc_offset_table[current_port]) != 0) { - port = current_port; - type = tmp >> (8 + (port * 3)); - type &= 0x7; - } else { - current_port++; - continue; - } - - /* Remove this port + type from uart_poll */ - uart_poll &= ~(dgnc_offset_table[port]); + type = uart_poll >> (8 + (port * 3)); + type &= 0x7; - if (!type) { - /* If no type, just ignore it, and move onto next port */ - continue; - } + uart_poll &= ~(0x01 << port); /* Switch on type of interrupt we have */ switch (type) { @@ -994,7 +972,7 @@ static irqreturn_t neo_intr(int irq, void *voidbrd) /* Verify the port is in range. */ if (port >= brd->nasync) - continue; + break; ch = brd->channels[port]; neo_copy_data_from_uart_to_queue(ch); @@ -1004,14 +982,14 @@ static irqreturn_t neo_intr(int irq, void *voidbrd) dgnc_check_queue_flow_control(ch); spin_unlock_irqrestore(&ch->ch_lock, flags2); - continue; + break; case UART_17158_RX_LINE_STATUS: /* * RXRDY and RX LINE Status (logic OR of LSR[4:1]) */ neo_parse_lsr(brd, port); - continue; + break; case UART_17158_TXRDY: /* @@ -1027,14 +1005,14 @@ static irqreturn_t neo_intr(int irq, void *voidbrd) * it should be, I was getting things like RXDY too. Weird. */ neo_parse_isr(brd, port); - continue; + break; case UART_17158_MSR: /* * MSR or flow control was seen. */ neo_parse_isr(brd, port); - continue; + break; default: /* @@ -1043,8 +1021,10 @@ static irqreturn_t neo_intr(int irq, void *voidbrd) * these once and awhile. * Its harmless, just ignore it and move on. */ - continue; + break; } + + port++; } /* -- cgit v1.2.3 From a1115c9f7826143600d12f72cda7bb0be404c842 Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Tue, 29 Mar 2016 13:47:59 +0900 Subject: staging: dgnc: remove parenthesis around the CONST | remove parenthesis around the CONST | CONST. It will be also fixed checkpatch.pl warning about "Alignment should match open parenthesis" becasue parenthesis were removed by this patch. Signed-off-by: Daeseok Youn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_neo.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dgnc/dgnc_neo.c b/drivers/staging/dgnc/dgnc_neo.c index 6b57c441859d..ee7f2da7df48 100644 --- a/drivers/staging/dgnc/dgnc_neo.c +++ b/drivers/staging/dgnc/dgnc_neo.c @@ -114,8 +114,8 @@ static inline void neo_set_cts_flow_control(struct channel_t *ch) writeb(efr, &ch->ch_neo_uart->efr); /* Turn on table D, with 8 char hi/low watermarks */ - writeb((UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_4DELAY), - &ch->ch_neo_uart->fctr); + writeb(UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_4DELAY, + &ch->ch_neo_uart->fctr); /* Feed the UART our trigger levels */ writeb(8, &ch->ch_neo_uart->tfifo); @@ -149,8 +149,8 @@ static inline void neo_set_rts_flow_control(struct channel_t *ch) /* Turn on UART enhanced bits */ writeb(efr, &ch->ch_neo_uart->efr); - writeb((UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_4DELAY), - &ch->ch_neo_uart->fctr); + writeb(UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_4DELAY, + &ch->ch_neo_uart->fctr); ch->ch_r_watermark = 4; writeb(32, &ch->ch_neo_uart->rfifo); @@ -187,7 +187,7 @@ static inline void neo_set_ixon_flow_control(struct channel_t *ch) /* Turn on UART enhanced bits */ writeb(efr, &ch->ch_neo_uart->efr); - writeb((UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_8DELAY), + writeb(UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_8DELAY, &ch->ch_neo_uart->fctr); ch->ch_r_watermark = 4; @@ -226,8 +226,8 @@ static inline void neo_set_ixoff_flow_control(struct channel_t *ch) writeb(efr, &ch->ch_neo_uart->efr); /* Turn on table D, with 8 char hi/low watermarks */ - writeb((UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_8DELAY), - &ch->ch_neo_uart->fctr); + writeb(UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_8DELAY, + &ch->ch_neo_uart->fctr); writeb(8, &ch->ch_neo_uart->tfifo); ch->ch_t_tlevel = 8; @@ -267,8 +267,8 @@ static inline void neo_set_no_input_flow_control(struct channel_t *ch) writeb(efr, &ch->ch_neo_uart->efr); /* Turn on table D, with 8 char hi/low watermarks */ - writeb((UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_8DELAY), - &ch->ch_neo_uart->fctr); + writeb(UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_8DELAY, + &ch->ch_neo_uart->fctr); ch->ch_r_watermark = 0; @@ -305,8 +305,8 @@ static inline void neo_set_no_output_flow_control(struct channel_t *ch) writeb(efr, &ch->ch_neo_uart->efr); /* Turn on table D, with 8 char hi/low watermarks */ - writeb((UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_8DELAY), - &ch->ch_neo_uart->fctr); + writeb(UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_8DELAY, + &ch->ch_neo_uart->fctr); ch->ch_r_watermark = 0; @@ -1353,7 +1353,7 @@ static void neo_flush_uart_read(struct channel_t *ch) if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) return; - writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR), + writeb(UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR, &ch->ch_neo_uart->isr_fcr); neo_pci_posting_flush(ch->ch_bd); @@ -1628,7 +1628,7 @@ static void neo_uart_init(struct channel_t *ch) /* Clear out UART and FIFO */ readb(&ch->ch_neo_uart->txrx); - writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT), + writeb(UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT, &ch->ch_neo_uart->isr_fcr); readb(&ch->ch_neo_uart->lsr); readb(&ch->ch_neo_uart->msr); -- cgit v1.2.3 From ffe4f329460ded65b339522abcbdc7aa18021dc9 Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Tue, 29 Mar 2016 13:48:31 +0900 Subject: staging: dgnc: fix 'line over 80 characters' fix checkpatch.pl warning about 'line over 80 characters'. I just moved all line comment to above if statement. Signed-off-by: Daeseok Youn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_neo.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dgnc/dgnc_neo.c b/drivers/staging/dgnc/dgnc_neo.c index ee7f2da7df48..6105ccb99d34 100644 --- a/drivers/staging/dgnc/dgnc_neo.c +++ b/drivers/staging/dgnc/dgnc_neo.c @@ -1785,9 +1785,15 @@ static void neo_vpd(struct dgnc_board *brd) brd->vpd[(i * 2) + 1] = (a >> 8) & 0xff; } - if (((brd->vpd[0x08] != 0x82) /* long resource name tag */ - && (brd->vpd[0x10] != 0x82)) /* long resource name tag (PCI-66 files)*/ - || (brd->vpd[0x7F] != 0x78)) { /* small resource end tag */ + /* + * brd->vpd has different name tags by below index. + * 0x08 : long resource name tag + * 0x10 : long resource name tage (PCI-66 files) + * 0x7F : small resource end tag + */ + if (((brd->vpd[0x08] != 0x82) + && (brd->vpd[0x10] != 0x82)) + || (brd->vpd[0x7F] != 0x78)) { memset(brd->vpd, '\0', NEO_VPD_IMAGESIZE); } else { -- cgit v1.2.3 From 3996ae3482935fb531e522b3f23248a6581015a8 Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Tue, 29 Mar 2016 13:48:57 +0900 Subject: staging: dgnc: fix Logical continuations. fix checkpatch.pl warning about 'Logical continuations should be on the previous line' Signed-off-by: Daeseok Youn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_neo.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dgnc/dgnc_neo.c b/drivers/staging/dgnc/dgnc_neo.c index 6105ccb99d34..2da6a72fc61d 100644 --- a/drivers/staging/dgnc/dgnc_neo.c +++ b/drivers/staging/dgnc/dgnc_neo.c @@ -1791,9 +1791,9 @@ static void neo_vpd(struct dgnc_board *brd) * 0x10 : long resource name tage (PCI-66 files) * 0x7F : small resource end tag */ - if (((brd->vpd[0x08] != 0x82) - && (brd->vpd[0x10] != 0x82)) - || (brd->vpd[0x7F] != 0x78)) { + if (((brd->vpd[0x08] != 0x82) && + (brd->vpd[0x10] != 0x82)) || + (brd->vpd[0x7F] != 0x78)) { memset(brd->vpd, '\0', NEO_VPD_IMAGESIZE); } else { -- cgit v1.2.3 From 56e18f8cdf057a8c6e68906ff584cf655ea1e328 Mon Sep 17 00:00:00 2001 From: Clifton Barnes Date: Tue, 29 Mar 2016 18:12:40 -0400 Subject: staging: xgifb: fix block comments fix checkpatch.pl warning about 'Block comments use a trailing */ on a separate line' and 'Block comments use * on subsequent lines' Signed-off-by: Clifton Barnes Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_init.c | 13 ++-- drivers/staging/xgifb/vb_setmode.c | 3 +- drivers/staging/xgifb/vb_table.h | 135 ++++++++++++++++++++++--------------- 3 files changed, 88 insertions(+), 63 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 29da955493c1..062ece22ed84 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -355,7 +355,8 @@ static void XGINew_DDR2_DefaultRegister( unsigned long P3d4 = Port, P3c4 = Port - 0x10; /* keep following setting sequence, each setting in - * the same reg insert idle */ + * the same reg insert idle + */ xgifb_reg_set(P3d4, 0x82, 0x77); xgifb_reg_set(P3d4, 0x86, 0x00); xgifb_reg_get(P3d4, 0x86); /* Insert read command for delay */ @@ -700,11 +701,11 @@ static void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension, break; case XG42: /* - XG42 SR14 D[3] Reserve - D[2] = 1, Dual Channel - = 0, Single Channel - - It's Different from Other XG40 Series. + * XG42 SR14 D[3] Reserve + * D[2] = 1, Dual Channel + * = 0, Single Channel + * + * It's Different from Other XG40 Series. */ if (XGINew_CheckFrequence(pVBInfo) == 1) { /* DDRII, DDR2x */ pVBInfo->ram_bus = 32; /* 32 bits */ diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index cc1ad768918a..50c8ea4f5ab7 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -1992,7 +1992,8 @@ static void XGI_GetVBInfo(unsigned short ModeIdIndex, } /* LCD+TV can't support in slave mode - * (Force LCDA+TV->LCDB) */ + * (Force LCDA+TV->LCDB) + */ if ((tempbx & SetInSlaveMode) && (tempbx & XGI_SetCRT2ToLCDA)) { tempbx ^= (SetCRT2ToLCD | XGI_SetCRT2ToLCDA | SetCRT2ToDualEdge); diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index 45f2c992cd44..c801deb142f6 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -58,8 +58,9 @@ static const unsigned char XGI27_cr41[24][3] = { {0xC4, 0x40, 0x84}, /* 1 CR8A */ {0xC4, 0x40, 0x84}, /* 2 CR8B */ {0xB3, 0x13, 0xa4}, /* 3 CR40[7], - CR99[2:0], - CR45[3:0]*/ + * CR99[2:0], + * CR45[3:0] + */ {0xf0, 0xf5, 0xf0}, /* 4 CR59 */ {0x90, 0x90, 0x24}, /* 5 CR68 */ {0x77, 0x67, 0x44}, /* 6 CR69 */ @@ -101,9 +102,11 @@ const struct XGI_ExtStruct XGI330_EModeIDTable[] = { {0x38, 0x0a1b, 0x0508, 0x08, 0x00, 0x16}, {0x3a, 0x0e3b, 0x0609, 0x09, 0x00, 0x1e}, {0x3c, 0x0e3b, 0x070a, 0x0a, 0x00, 0x22}, /* mode 1600x1200 - add CRT2MODE [2003/10/07] */ + * add CRT2MODE [2003/10/07] + */ {0x3d, 0x0e7d, 0x070a, 0x0a, 0x00, 0x22}, /* mode 1600x1200 - add CRT2MODE */ + * add CRT2MODE + */ {0x40, 0x9a1c, 0x0000, 0x00, 0x04, 0x00}, {0x41, 0x9a1d, 0x0000, 0x00, 0x04, 0x00}, {0x43, 0x0a1c, 0x0306, 0x06, 0x05, 0x06}, @@ -129,7 +132,8 @@ const struct XGI_ExtStruct XGI330_EModeIDTable[] = { {0x64, 0x0a7f, 0x0508, 0x08, 0x00, 0x16}, {0x65, 0x0eff, 0x0609, 0x09, 0x00, 0x1e}, {0x66, 0x0eff, 0x070a, 0x0a, 0x00, 0x22}, /* mode 1600x1200 - add CRT2MODE */ + * add CRT2MODE + */ {0x68, 0x067b, 0x080b, 0x0b, 0x00, 0x29}, {0x69, 0x06fd, 0x080b, 0x0b, 0x00, 0x29}, {0x6b, 0x07ff, 0x080b, 0x0b, 0x00, 0x29}, @@ -223,38 +227,38 @@ const struct XGI_CRT1TableStruct XGI_CRT1Table[] = { 0x0D, 0x3E, 0xE0, 0x83, 0xDF, 0x0E, 0x90} }, /* 0xb */ { {0x65, 0x4F, 0x89, 0x57, 0x9F, 0x00, 0x01, 0x00, 0xFB, 0x1F, 0xE6, 0x8A, 0xDF, 0xFC, 0x10} }, /* 0xc */ - { {0x7B, 0x63, 0x9F, 0x6A, 0x93, 0x00, 0x05, 0x00, /* ; - 0D (800x600,56Hz) */ - 0x6F, 0xF0, 0x58, 0x8A, 0x57, 0x70, 0xA0} }, /* ; - (VCLK 36.0MHz) */ - { {0x7F, 0x63, 0x83, 0x6C, 0x1C, 0x00, 0x06, 0x00, /* ; - 0E (800x600,60Hz) */ - 0x72, 0xF0, 0x58, 0x8C, 0x57, 0x73, 0xA0} }, /* ; - (VCLK 40.0MHz) */ - { {0x7D, 0x63, 0x81, 0x6E, 0x1D, 0x00, 0x06, 0x00, /* ; - 0F (800x600,72Hz) */ - 0x98, 0xF0, 0x7C, 0x82, 0x57, 0x99, 0x80} }, /* ; - (VCLK 50.0MHz) */ - { {0x7F, 0x63, 0x83, 0x69, 0x13, 0x00, 0x06, 0x00, /* ; - 10 (800x600,75Hz) */ - 0x6F, 0xF0, 0x58, 0x8B, 0x57, 0x70, 0xA0} }, /* ; - (VCLK 49.5MHz) */ - { {0x7E, 0x63, 0x82, 0x6B, 0x13, 0x00, 0x06, 0x00, /* ; - 11 (800x600,85Hz) */ - 0x75, 0xF0, 0x58, 0x8B, 0x57, 0x76, 0xA0} }, /* ; - (VCLK 56.25MHz) */ - { {0x81, 0x63, 0x85, 0x6D, 0x18, 0x00, 0x06, 0x60, /* ; - 12 (800x600,100Hz) */ - 0x7A, 0xF0, 0x58, 0x8B, 0x57, 0x7B, 0xA0} }, /* ; - (VCLK 75.8MHz) */ - { {0x83, 0x63, 0x87, 0x6E, 0x19, 0x00, 0x06, 0x60, /* ; - 13 (800x600,120Hz) */ - 0x81, 0xF0, 0x58, 0x8B, 0x57, 0x82, 0xA0} }, /* ; - (VCLK 79.411MHz) */ - { {0x85, 0x63, 0x89, 0x6F, 0x1A, 0x00, 0x06, 0x60, /* ; - 14 (800x600,160Hz) */ - 0x91, 0xF0, 0x58, 0x8B, 0x57, 0x92, 0xA0} }, /* ; - (VCLK 105.822MHz) */ + /* 0D (800x600,56Hz) */ + { {0x7B, 0x63, 0x9F, 0x6A, 0x93, 0x00, 0x05, 0x00, + /* (VCLK 36.0MHz) */ + 0x6F, 0xF0, 0x58, 0x8A, 0x57, 0x70, 0xA0} }, + /* 0E (800x600,60Hz) */ + { {0x7F, 0x63, 0x83, 0x6C, 0x1C, 0x00, 0x06, 0x00, + /* (VCLK 40.0MHz) */ + 0x72, 0xF0, 0x58, 0x8C, 0x57, 0x73, 0xA0} }, + /* 0F (800x600,72Hz) */ + { {0x7D, 0x63, 0x81, 0x6E, 0x1D, 0x00, 0x06, 0x00, + /* (VCLK 50.0MHz) */ + 0x98, 0xF0, 0x7C, 0x82, 0x57, 0x99, 0x80} }, + /* 10 (800x600,75Hz) */ + { {0x7F, 0x63, 0x83, 0x69, 0x13, 0x00, 0x06, 0x00, + /* (VCLK 49.5MHz) */ + 0x6F, 0xF0, 0x58, 0x8B, 0x57, 0x70, 0xA0} }, + /* 11 (800x600,85Hz) */ + { {0x7E, 0x63, 0x82, 0x6B, 0x13, 0x00, 0x06, 0x00, + /* (VCLK 56.25MHz) */ + 0x75, 0xF0, 0x58, 0x8B, 0x57, 0x76, 0xA0} }, + /* 12 (800x600,100Hz) */ + { {0x81, 0x63, 0x85, 0x6D, 0x18, 0x00, 0x06, 0x60, + /* (VCLK 75.8MHz) */ + 0x7A, 0xF0, 0x58, 0x8B, 0x57, 0x7B, 0xA0} }, + /* 13 (800x600,120Hz) */ + { {0x83, 0x63, 0x87, 0x6E, 0x19, 0x00, 0x06, 0x60, + /* (VCLK 79.411MHz) */ + 0x81, 0xF0, 0x58, 0x8B, 0x57, 0x82, 0xA0} }, + /* 14 (800x600,160Hz) */ + { {0x85, 0x63, 0x89, 0x6F, 0x1A, 0x00, 0x06, 0x60, + /* (VCLK 105.822MHz) */ + 0x91, 0xF0, 0x58, 0x8B, 0x57, 0x92, 0xA0} }, { {0x99, 0x7F, 0x9D, 0x84, 0x1A, 0x00, 0x02, 0x00, 0x96, 0x1F, 0x7F, 0x83, 0x7F, 0x97, 0x10} }, /* 0x15 */ { {0xA3, 0x7F, 0x87, 0x86, 0x97, 0x00, 0x02, 0x00, @@ -388,7 +392,8 @@ static const struct SiS_LCDData XGI_ExtLCD1024x768Data[] = { static const struct SiS_LCDData XGI_CetLCD1024x768Data[] = { {1, 1, 1344, 806, 1344, 806}, /* ; 00 (320x200,320x400, - 640x200,640x400) */ + * 640x200,640x400) + */ {1, 1, 1344, 806, 1344, 806}, /* 01 (320x350,640x350) */ {1, 1, 1344, 806, 1344, 806}, /* 02 (360x400,720x400) */ {1, 1, 1344, 806, 1344, 806}, /* 03 (720x350) */ @@ -421,7 +426,8 @@ static const struct SiS_LCDData XGI_ExtLCD1280x1024Data[] = { static const struct SiS_LCDData XGI_CetLCD1280x1024Data[] = { {1, 1, 1688, 1066, 1688, 1066}, /* 00 (320x200,320x400, - 640x200,640x400) */ + * 640x200,640x400) + */ {1, 1, 1688, 1066, 1688, 1066}, /* 01 (320x350,640x350) */ {1, 1, 1688, 1066, 1688, 1066}, /* 02 (360x400,720x400) */ {1, 1, 1688, 1066, 1688, 1066}, /* 03 (720x350) */ @@ -434,7 +440,8 @@ static const struct SiS_LCDData XGI_CetLCD1280x1024Data[] = { static const struct SiS_LCDData xgifb_lcd_1400x1050[] = { {211, 100, 2100, 408, 1688, 1066}, /* 00 (320x200,320x400, - 640x200,640x400) */ + * 640x200,640x400) + */ {211, 64, 1536, 358, 1688, 1066}, /* 01 (320x350,640x350) */ {211, 100, 2100, 408, 1688, 1066}, /* 02 (360x400,720x400) */ {211, 64, 1536, 358, 1688, 1066}, /* 03 (720x350) */ @@ -442,13 +449,15 @@ static const struct SiS_LCDData xgifb_lcd_1400x1050[] = { {211, 72, 1008, 609, 1688, 1066}, /* 05 (800x600x60Hz) */ {211, 128, 1400, 776, 1688, 1066}, /* 06 (1024x768x60Hz) */ {1, 1, 1688, 1066, 1688, 1066}, /* 07 (1280x1024x60Hz - w/o Scaling) */ + * w/o Scaling) + */ {1, 1, 1688, 1066, 1688, 1066} /* 08 (1400x1050x60Hz) */ }; static const struct SiS_LCDData XGI_ExtLCD1600x1200Data[] = { {4, 1, 1620, 420, 2160, 1250}, /* 00 (320x200,320x400, - 640x200,640x400)*/ + * 640x200,640x400) + */ {27, 7, 1920, 375, 2160, 1250}, /* 01 (320x350,640x350) */ {4, 1, 1620, 420, 2160, 1250}, /* 02 (360x400,720x400)*/ {27, 7, 1920, 375, 2160, 1250}, /* 03 (720x350) */ @@ -462,7 +471,8 @@ static const struct SiS_LCDData XGI_ExtLCD1600x1200Data[] = { static const struct SiS_LCDData XGI_StLCD1600x1200Data[] = { {27, 4, 800, 500, 2160, 1250}, /* 00 (320x200,320x400, - 640x200,640x400) */ + * 640x200,640x400) + */ {27, 4, 800, 500, 2160, 1250}, /* 01 (320x350,640x350) */ {27, 4, 800, 500, 2160, 1250}, /* 02 (360x400,720x400) */ {27, 4, 800, 500, 2160, 1250}, /* 03 (720x350) */ @@ -489,7 +499,8 @@ static const struct SiS_LCDData XGI_NoScalingData[] = { static const struct SiS_LCDData XGI_ExtLCD1024x768x75Data[] = { {42, 25, 1536, 419, 1344, 806}, /* ; 00 (320x200,320x400, - 640x200,640x400) */ + * 640x200,640x400) + */ {48, 25, 1536, 369, 1344, 806}, /* ; 01 (320x350,640x350) */ {42, 25, 1536, 419, 1344, 806}, /* ; 02 (360x400,720x400) */ {48, 25, 1536, 369, 1344, 806}, /* ; 03 (720x350) */ @@ -500,7 +511,8 @@ static const struct SiS_LCDData XGI_ExtLCD1024x768x75Data[] = { static const struct SiS_LCDData XGI_CetLCD1024x768x75Data[] = { {1, 1, 1312, 800, 1312, 800}, /* ; 00 (320x200,320x400, - 640x200,640x400) */ + * 640x200,640x400) + */ {1, 1, 1312, 800, 1312, 800}, /* ; 01 (320x350,640x350) */ {1, 1, 1312, 800, 1312, 800}, /* ; 02 (360x400,720x400) */ {1, 1, 1312, 800, 1312, 800}, /* ; 03 (720x350) */ @@ -511,7 +523,8 @@ static const struct SiS_LCDData XGI_CetLCD1024x768x75Data[] = { static const struct SiS_LCDData xgifb_lcd_1280x1024x75[] = { {211, 60, 1024, 501, 1688, 1066}, /* ; 00 (320x200,320x400, - 640x200,640x400) */ + * 640x200,640x400) + */ {211, 60, 1024, 508, 1688, 1066}, /* ; 01 (320x350,640x350) */ {211, 60, 1024, 501, 1688, 1066}, /* ; 02 (360x400,720x400) */ {211, 60, 1024, 508, 1688, 1066}, /* ; 03 (720x350) */ @@ -525,7 +538,8 @@ static const struct SiS_LCDData xgifb_lcd_1280x1024x75[] = { static const struct SiS_LCDData XGI_NoScalingDatax75[] = { {1, 1, 800, 449, 800, 449}, /* ; 00 (320x200, 320x400, - 640x200, 640x400) */ + * 640x200, 640x400) + */ {1, 1, 800, 449, 800, 449}, /* ; 01 (320x350, 640x350) */ {1, 1, 900, 449, 900, 449}, /* ; 02 (360x400, 720x400) */ {1, 1, 900, 449, 900, 449}, /* ; 03 (720x350) */ @@ -732,7 +746,8 @@ static const struct XGI_LCDDesStruct XGI_StLCDDes1600x1200Data[] = { static const struct XGI330_LCDDataDesStruct2 XGI_NoScalingDesData[] = { {9, 657, 448, 405, 96, 2}, /* 00 (320x200,320x400, - 640x200,640x400) */ + * 640x200,640x400) + */ {9, 657, 448, 355, 96, 2}, /* 01 (320x350,640x350) */ {9, 657, 448, 405, 96, 2}, /* 02 (360x400,720x400) */ {9, 657, 448, 355, 96, 2}, /* 03 (720x350) */ @@ -818,7 +833,8 @@ static const struct XGI_LCDDesStruct XGI_CetLCDDes1280x1024x75Data[] = { /* Scaling LCD 75Hz */ static const struct XGI330_LCDDataDesStruct2 XGI_NoScalingDesDatax75[] = { {9, 657, 448, 405, 96, 2}, /* ; 00 (320x200,320x400, - 640x200,640x400) */ + * 640x200,640x400) + */ {9, 657, 448, 355, 96, 2}, /* ; 01 (320x350,640x350) */ {9, 738, 448, 405, 108, 2}, /* ; 02 (360x400,720x400) */ {9, 738, 448, 355, 108, 2}, /* ; 03 (720x350) */ @@ -873,7 +889,8 @@ static const struct SiS_TVData XGI_ExtNTSCData[] = { static const struct SiS_TVData XGI_St1HiTVData[] = { {1, 1, 892, 563, 690, 800, 0, 0, 0}, /* 00 (320x200,320x400, - 640x200,640x400) */ + * 640x200,640x400) + */ {1, 1, 892, 563, 690, 700, 0, 0, 0}, /* 01 (320x350,640x350) */ {1, 1, 1000, 563, 785, 800, 0, 0, 0}, /* 02 (360x400,720x400) */ {1, 1, 1000, 563, 785, 700, 0, 0, 0}, /* 03 (720x350) */ @@ -883,7 +900,8 @@ static const struct SiS_TVData XGI_St1HiTVData[] = { static const struct SiS_TVData XGI_St2HiTVData[] = { {3, 1, 840, 483, 1648, 960, 0x032, 0, 0}, /* 00 (320x200,320x400, - 640x200,640x400) */ + * 640x200,640x400) + */ {1, 1, 892, 563, 690, 700, 0, 0, 0}, /* 01 (320x350,640x350) */ {3, 1, 840, 483, 1648, 960, 0x032, 0, 0}, /* 02 (360x400,720x400) */ {1, 1, 1000, 563, 785, 700, 0, 0, 0}, /* 03 (720x350) */ @@ -893,7 +911,8 @@ static const struct SiS_TVData XGI_St2HiTVData[] = { static const struct SiS_TVData XGI_ExtHiTVData[] = { {6, 1, 840, 563, 1632, 960, 0, 0, 0}, /* 00 (320x200,320x400, - 640x200,640x400) */ + * 640x200,640x400) + */ {3, 1, 960, 563, 1632, 960, 0, 0, 0}, /* 01 (320x350,640x350) */ {3, 1, 840, 483, 1632, 960, 0, 0, 0}, /* 02 (360x400,720x400) */ {3, 1, 960, 563, 1632, 960, 0, 0, 0}, /* 03 (720x350) */ @@ -948,7 +967,8 @@ static const struct SiS_TVData XGI_StYPbPr525pData[] = { static const struct SiS_TVData XGI_ExtYPbPr750pData[] = { { 3, 1, 935, 470, 1130, 680, 50, 0, 0}, /* 00 (320x200,320x400, - 640x200,640x400) */ + * 640x200,640x400) + */ {24, 7, 935, 420, 1130, 680, 50, 0, 0}, /* 01 (320x350,640x350) */ { 3, 1, 935, 470, 1130, 680, 50, 0, 0}, /* 02 (360x400,720x400) */ {24, 7, 935, 420, 1130, 680, 50, 0, 0}, /* 03 (720x350) */ @@ -1269,7 +1289,8 @@ static const struct SiS_LVDSData XGI_LVDSNoScalingDatax75[] = { {1312, 800, 1312, 800}, /* ; 06 (1024x768x75Hz) */ {1688, 1066, 1688, 1066}, /* ; 07 (1280x1024x75Hz) */ {1688, 1066, 1688, 1066}, /* ; 08 (1400x1050x75Hz) - ;;[ycchen] 12/19/02 */ + * ;;[ycchen] 12/19/02 + */ {2160, 1250, 2160, 1250}, /* ; 09 (1600x1200x75Hz) */ {1688, 806, 1688, 806}, /* ; 0A (1280x768x75Hz) */ }; @@ -1364,7 +1385,8 @@ static const struct SiS_LVDSData XGI_LVDS1600x1200Des_1[] = { static const struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesData[] = { {0, 648, 448, 405, 96, 2}, /* 00 (320x200,320x400, - 640x200,640x400) */ + * 640x200,640x400) + */ {0, 648, 448, 355, 96, 2}, /* 01 (320x350,640x350) */ {0, 648, 448, 405, 96, 2}, /* 02 (360x400,720x400) */ {0, 648, 448, 355, 96, 2}, /* 03 (720x350) */ @@ -1435,7 +1457,8 @@ static const struct SiS_LVDSData XGI_LVDS1280x1024Des_2x75[] = { /* Scaling LCD 75Hz */ static const struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesDatax75[] = { {0, 648, 448, 405, 96, 2}, /* ; 00 (320x200,320x400, - 640x200,640x400) */ + * 640x200,640x400) + */ {0, 648, 448, 355, 96, 2}, /* ; 01 (320x350,640x350) */ {0, 729, 448, 405, 108, 2}, /* ; 02 (360x400,720x400) */ {0, 729, 448, 355, 108, 2}, /* ; 03 (720x350) */ -- cgit v1.2.3 From 81108182bba96fcc738ddc912e9fcbb5afe01ef0 Mon Sep 17 00:00:00 2001 From: Oleg Drokin Date: Wed, 30 Mar 2016 19:48:22 -0400 Subject: staging/lustre/obdclass: limit lu_site hash table size Allocating a big hash table using the formula for osd does not really work for clients. We will create new hash table for each mount on a single client which is a lot of memory more than expected. This patch limits the hash table up to 8M which has 524288 entries Signed-off-by: Li Dongyang Reviewed-on: http://review.whamcloud.com/18048 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-7689 Reviewed-by: Fan Yong Reviewed-by: Alex Zhuravlev Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/obdclass/lu_object.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/obdclass/lu_object.c b/drivers/staging/lustre/lustre/obdclass/lu_object.c index 65a4746c89ca..69fdcee0ac52 100644 --- a/drivers/staging/lustre/lustre/obdclass/lu_object.c +++ b/drivers/staging/lustre/lustre/obdclass/lu_object.c @@ -935,7 +935,7 @@ static void lu_dev_add_linkage(struct lu_site *s, struct lu_device *d) * Initialize site \a s, with \a d as the top level device. */ #define LU_SITE_BITS_MIN 12 -#define LU_SITE_BITS_MAX 24 +#define LU_SITE_BITS_MAX 19 /** * total 256 buckets, we don't want too many buckets because: * - consume too much memory -- cgit v1.2.3 From 616387e86d531d1d29173aabb8adefb20d316d96 Mon Sep 17 00:00:00 2001 From: Oleg Drokin Date: Wed, 30 Mar 2016 19:48:23 -0400 Subject: staging/lustre: Get rid of CFS_PAGE_MASK CFS_PAGE_MASK is the same as PAGE_MASK, so get rid of it. We are replacing it with PAGE_MASK instead of PAGE_CACHE_MASK because PAGE_CACHE_* stuff is apparently going away. Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- .../lustre/include/linux/libcfs/linux/linux-mem.h | 1 - .../lustre/lnet/libcfs/linux/linux-crypto.c | 2 +- drivers/staging/lustre/lnet/selftest/brw_test.c | 2 +- drivers/staging/lustre/lustre/llite/llite_mmap.c | 4 ++-- drivers/staging/lustre/lustre/llite/rw26.c | 8 ++++---- drivers/staging/lustre/lustre/llite/vvp_io.c | 6 +++--- drivers/staging/lustre/lustre/lmv/lmv_obd.c | 2 +- drivers/staging/lustre/lustre/obdclass/class_obd.c | 2 +- .../staging/lustre/lustre/obdecho/echo_client.c | 6 +++--- drivers/staging/lustre/lustre/osc/osc_cache.c | 4 ++-- drivers/staging/lustre/lustre/osc/osc_request.c | 24 +++++++++++----------- drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c | 2 +- drivers/staging/lustre/lustre/ptlrpc/sec_plain.c | 2 +- 13 files changed, 32 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h b/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h index 0f2fd79e5ec8..448379b2a01e 100644 --- a/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h +++ b/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h @@ -57,7 +57,6 @@ #include "../libcfs_cpu.h" #endif -#define CFS_PAGE_MASK (~((__u64)PAGE_CACHE_SIZE-1)) #define page_index(p) ((p)->index) #define memory_pressure_get() (current->flags & PF_MEMALLOC) diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c index 0715101c577c..84f9b7b47581 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c @@ -227,7 +227,7 @@ int cfs_crypto_hash_update_page(struct cfs_crypto_hash_desc *hdesc, struct scatterlist sl; sg_init_table(&sl, 1); - sg_set_page(&sl, page, len, offset & ~CFS_PAGE_MASK); + sg_set_page(&sl, page, len, offset & ~PAGE_MASK); ahash_request_set_crypt(req, &sl, NULL, sl.length); return crypto_ahash_update(req); diff --git a/drivers/staging/lustre/lnet/selftest/brw_test.c b/drivers/staging/lustre/lnet/selftest/brw_test.c index b33c35694eb1..1988cee36751 100644 --- a/drivers/staging/lustre/lnet/selftest/brw_test.c +++ b/drivers/staging/lustre/lnet/selftest/brw_test.c @@ -457,7 +457,7 @@ brw_server_handle(struct srpc_server_rpc *rpc) if (!(reqstmsg->msg_ses_feats & LST_FEAT_BULK_LEN)) { /* compat with old version */ - if (reqst->brw_len & ~CFS_PAGE_MASK) { + if (reqst->brw_len & ~PAGE_MASK) { reply->brw_status = EINVAL; return 0; } diff --git a/drivers/staging/lustre/lustre/llite/llite_mmap.c b/drivers/staging/lustre/lustre/llite/llite_mmap.c index 69445a9f2011..baccf9379ca7 100644 --- a/drivers/staging/lustre/lustre/llite/llite_mmap.c +++ b/drivers/staging/lustre/lustre/llite/llite_mmap.c @@ -57,10 +57,10 @@ void policy_from_vma(ldlm_policy_data_t *policy, struct vm_area_struct *vma, unsigned long addr, size_t count) { - policy->l_extent.start = ((addr - vma->vm_start) & CFS_PAGE_MASK) + + policy->l_extent.start = ((addr - vma->vm_start) & PAGE_MASK) + (vma->vm_pgoff << PAGE_CACHE_SHIFT); policy->l_extent.end = (policy->l_extent.start + count - 1) | - ~CFS_PAGE_MASK; + ~PAGE_MASK; } struct vm_area_struct *our_vma(struct mm_struct *mm, unsigned long addr, diff --git a/drivers/staging/lustre/lustre/llite/rw26.c b/drivers/staging/lustre/lustre/llite/rw26.c index 7a5db67bc680..3d7e64ee9824 100644 --- a/drivers/staging/lustre/lustre/llite/rw26.c +++ b/drivers/staging/lustre/lustre/llite/rw26.c @@ -376,7 +376,7 @@ static ssize_t ll_direct_IO_26(struct kiocb *iocb, struct iov_iter *iter, return -EBADF; /* FIXME: io smaller than PAGE_SIZE is broken on ia64 ??? */ - if ((file_offset & ~CFS_PAGE_MASK) || (count & ~CFS_PAGE_MASK)) + if ((file_offset & ~PAGE_MASK) || (count & ~PAGE_MASK)) return -EINVAL; CDEBUG(D_VFSTRACE, @@ -386,7 +386,7 @@ static ssize_t ll_direct_IO_26(struct kiocb *iocb, struct iov_iter *iter, MAX_DIO_SIZE >> PAGE_CACHE_SHIFT); /* Check that all user buffers are aligned as well */ - if (iov_iter_alignment(iter) & ~CFS_PAGE_MASK) + if (iov_iter_alignment(iter) & ~PAGE_MASK) return -EINVAL; env = cl_env_get(&refcheck); @@ -435,8 +435,8 @@ static ssize_t ll_direct_IO_26(struct kiocb *iocb, struct iov_iter *iter, size > (PAGE_CACHE_SIZE / sizeof(*pages)) * PAGE_CACHE_SIZE) { size = ((((size / 2) - 1) | - ~CFS_PAGE_MASK) + 1) & - CFS_PAGE_MASK; + ~PAGE_MASK) + 1) & + PAGE_MASK; CDEBUG(D_VFSTRACE, "DIO size now %lu\n", size); continue; diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c index fb0c26ee7ff3..984699a32c69 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_io.c +++ b/drivers/staging/lustre/lustre/llite/vvp_io.c @@ -234,8 +234,8 @@ static int vvp_mmap_locks(const struct lu_env *env, if (count == 0) continue; - count += addr & (~CFS_PAGE_MASK); - addr &= CFS_PAGE_MASK; + count += addr & (~PAGE_MASK); + addr &= PAGE_MASK; down_read(&mm->mmap_sem); while ((vma = our_vma(mm, addr, count)) != NULL) { @@ -1043,7 +1043,7 @@ static int vvp_io_commit_write(const struct lu_env *env, to = PAGE_CACHE_SIZE; need_clip = false; } else if (last_index == pg->cp_index) { - int size_to = i_size_read(inode) & ~CFS_PAGE_MASK; + int size_to = i_size_read(inode) & ~PAGE_MASK; if (to < size_to) to = size_to; diff --git a/drivers/staging/lustre/lustre/lmv/lmv_obd.c b/drivers/staging/lustre/lustre/lmv/lmv_obd.c index 0f776cf8a5aa..e3a721670ca1 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_obd.c +++ b/drivers/staging/lustre/lustre/lmv/lmv_obd.c @@ -2071,7 +2071,7 @@ static void lmv_adjust_dirpages(struct page **pages, int ncfspgs, int nlupgs) dp = (struct lu_dirpage *)((char *)dp + LU_PAGE_SIZE); /* Check if we've reached the end of the CFS_PAGE. */ - if (!((unsigned long)dp & ~CFS_PAGE_MASK)) + if (!((unsigned long)dp & ~PAGE_MASK)) break; /* Save the hash and flags of this lu_dirpage. */ diff --git a/drivers/staging/lustre/lustre/obdclass/class_obd.c b/drivers/staging/lustre/lustre/obdclass/class_obd.c index 1a938e1376f9..d9844ba8b9be 100644 --- a/drivers/staging/lustre/lustre/obdclass/class_obd.c +++ b/drivers/staging/lustre/lustre/obdclass/class_obd.c @@ -461,7 +461,7 @@ static int obd_init_checks(void) CWARN("LPD64 wrong length! strlen(%s)=%d != 2\n", buf, len); ret = -EINVAL; } - if ((u64val & ~CFS_PAGE_MASK) >= PAGE_CACHE_SIZE) { + if ((u64val & ~PAGE_MASK) >= PAGE_CACHE_SIZE) { CWARN("mask failed: u64val %llu >= %llu\n", u64val, (__u64)PAGE_CACHE_SIZE); ret = -EINVAL; diff --git a/drivers/staging/lustre/lustre/obdecho/echo_client.c b/drivers/staging/lustre/lustre/obdecho/echo_client.c index 64ffe243f870..33ce0c80e4b2 100644 --- a/drivers/staging/lustre/lustre/obdecho/echo_client.c +++ b/drivers/staging/lustre/lustre/obdecho/echo_client.c @@ -1119,7 +1119,7 @@ static int cl_echo_object_brw(struct echo_object *eco, int rw, u64 offset, int rc; int i; - LASSERT((offset & ~CFS_PAGE_MASK) == 0); + LASSERT((offset & ~PAGE_MASK) == 0); LASSERT(ed->ed_next); env = cl_env_get(&refcheck); if (IS_ERR(env)) @@ -1387,7 +1387,7 @@ static int echo_client_kbrw(struct echo_device *ed, int rw, struct obdo *oa, LASSERT(rw == OBD_BRW_WRITE || rw == OBD_BRW_READ); if (count <= 0 || - (count & (~CFS_PAGE_MASK)) != 0) + (count & (~PAGE_MASK)) != 0) return -EINVAL; /* XXX think again with misaligned I/O */ @@ -1470,7 +1470,7 @@ static int echo_client_prep_commit(const struct lu_env *env, u64 npages, tot_pages; int i, ret = 0, brw_flags = 0; - if (count <= 0 || (count & (~CFS_PAGE_MASK)) != 0) + if (count <= 0 || (count & (~PAGE_MASK)) != 0) return -EINVAL; npages = batch >> PAGE_CACHE_SHIFT; diff --git a/drivers/staging/lustre/lustre/osc/osc_cache.c b/drivers/staging/lustre/lustre/osc/osc_cache.c index 63363111380c..3cfd2b09f760 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cache.c +++ b/drivers/staging/lustre/lustre/osc/osc_cache.c @@ -877,7 +877,7 @@ int osc_extent_finish(const struct lu_env *env, struct osc_extent *ext, * span a whole chunk on the OST side, or our accounting goes * wrong. Should match the code in filter_grant_check. */ - int offset = oap->oap_page_off & ~CFS_PAGE_MASK; + int offset = oap->oap_page_off & ~PAGE_MASK; int count = oap->oap_count + (offset & (blocksize - 1)); int end = (offset + oap->oap_count) & (blocksize - 1); @@ -2238,7 +2238,7 @@ int osc_prep_async_page(struct osc_object *osc, struct osc_page *ops, oap->oap_page = page; oap->oap_obj_off = offset; - LASSERT(!(offset & ~CFS_PAGE_MASK)); + LASSERT(!(offset & ~PAGE_MASK)); if (!client_is_remote(exp) && capable(CFS_CAP_SYS_RESOURCE)) oap->oap_brw_flags = OBD_BRW_NOQUOTA; diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c index ec0287feb3ce..850d5dd49831 100644 --- a/drivers/staging/lustre/lustre/osc/osc_request.c +++ b/drivers/staging/lustre/lustre/osc/osc_request.c @@ -1082,7 +1082,7 @@ static void handle_short_read(int nob_read, u32 page_count, if (pga[i]->count > nob_read) { /* EOF inside this page */ ptr = kmap(pga[i]->pg) + - (pga[i]->off & ~CFS_PAGE_MASK); + (pga[i]->off & ~PAGE_MASK); memset(ptr + nob_read, 0, pga[i]->count - nob_read); kunmap(pga[i]->pg); page_count--; @@ -1097,7 +1097,7 @@ static void handle_short_read(int nob_read, u32 page_count, /* zero remaining pages */ while (page_count-- > 0) { - ptr = kmap(pga[i]->pg) + (pga[i]->off & ~CFS_PAGE_MASK); + ptr = kmap(pga[i]->pg) + (pga[i]->off & ~PAGE_MASK); memset(ptr, 0, pga[i]->count); kunmap(pga[i]->pg); i++; @@ -1188,20 +1188,20 @@ static u32 osc_checksum_bulk(int nob, u32 pg_count, if (i == 0 && opc == OST_READ && OBD_FAIL_CHECK(OBD_FAIL_OSC_CHECKSUM_RECEIVE)) { unsigned char *ptr = kmap(pga[i]->pg); - int off = pga[i]->off & ~CFS_PAGE_MASK; + int off = pga[i]->off & ~PAGE_MASK; memcpy(ptr + off, "bad1", min(4, nob)); kunmap(pga[i]->pg); } cfs_crypto_hash_update_page(hdesc, pga[i]->pg, - pga[i]->off & ~CFS_PAGE_MASK, + pga[i]->off & ~PAGE_MASK, count); CDEBUG(D_PAGE, "page %p map %p index %lu flags %lx count %u priv %0lx: off %d\n", pga[i]->pg, pga[i]->pg->mapping, pga[i]->pg->index, (long)pga[i]->pg->flags, page_count(pga[i]->pg), page_private(pga[i]->pg), - (int)(pga[i]->off & ~CFS_PAGE_MASK)); + (int)(pga[i]->off & ~PAGE_MASK)); nob -= pga[i]->count; pg_count--; @@ -1309,7 +1309,7 @@ static int osc_brw_prep_request(int cmd, struct client_obd *cli, pg_prev = pga[0]; for (requested_nob = i = 0; i < page_count; i++, niobuf++) { struct brw_page *pg = pga[i]; - int poff = pg->off & ~CFS_PAGE_MASK; + int poff = pg->off & ~PAGE_MASK; LASSERT(pg->count > 0); /* make sure there is no gap in the middle of page array */ @@ -2227,8 +2227,8 @@ int osc_enqueue_base(struct obd_export *exp, struct ldlm_res_id *res_id, /* Filesystem lock extents are extended to page boundaries so that * dealing with the page cache is a little smoother. */ - policy->l_extent.start -= policy->l_extent.start & ~CFS_PAGE_MASK; - policy->l_extent.end |= ~CFS_PAGE_MASK; + policy->l_extent.start -= policy->l_extent.start & ~PAGE_MASK; + policy->l_extent.end |= ~PAGE_MASK; /* * kms is not valid when either object is completely fresh (so that no @@ -2378,8 +2378,8 @@ int osc_match_base(struct obd_export *exp, struct ldlm_res_id *res_id, /* Filesystem lock extents are extended to page boundaries so that * dealing with the page cache is a little smoother */ - policy->l_extent.start -= policy->l_extent.start & ~CFS_PAGE_MASK; - policy->l_extent.end |= ~CFS_PAGE_MASK; + policy->l_extent.start -= policy->l_extent.start & ~PAGE_MASK; + policy->l_extent.end |= ~PAGE_MASK; /* Next, search for already existing extent locks that will cover us */ /* If we're trying to read, we also search for an existing PW lock. The @@ -2784,7 +2784,7 @@ out: goto skip_locking; policy.l_extent.start = fm_key->fiemap.fm_start & - CFS_PAGE_MASK; + PAGE_MASK; if (OBD_OBJECT_EOF - fm_key->fiemap.fm_length <= fm_key->fiemap.fm_start + PAGE_CACHE_SIZE - 1) @@ -2792,7 +2792,7 @@ out: else policy.l_extent.end = (fm_key->fiemap.fm_start + fm_key->fiemap.fm_length + - PAGE_CACHE_SIZE - 1) & CFS_PAGE_MASK; + PAGE_CACHE_SIZE - 1) & PAGE_MASK; ostid_build_res_name(&fm_key->oa.o_oi, &res_id); mode = ldlm_lock_match(exp->exp_obd->obd_namespace, diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c b/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c index 54a0c1ff7b20..33d141149afd 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c +++ b/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c @@ -527,7 +527,7 @@ int sptlrpc_get_bulk_checksum(struct ptlrpc_bulk_desc *desc, __u8 alg, for (i = 0; i < desc->bd_iov_count; i++) { cfs_crypto_hash_update_page(hdesc, desc->bd_iov[i].kiov_page, - desc->bd_iov[i].kiov_offset & ~CFS_PAGE_MASK, + desc->bd_iov[i].kiov_offset & ~PAGE_MASK, desc->bd_iov[i].kiov_len); } diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c b/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c index 6276bf59c3aa..37c9f4c453de 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c +++ b/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c @@ -162,7 +162,7 @@ static void corrupt_bulk_data(struct ptlrpc_bulk_desc *desc) continue; ptr = kmap(desc->bd_iov[i].kiov_page); - off = desc->bd_iov[i].kiov_offset & ~CFS_PAGE_MASK; + off = desc->bd_iov[i].kiov_offset & ~PAGE_MASK; ptr[off] ^= 0x1; kunmap(desc->bd_iov[i].kiov_page); return; -- cgit v1.2.3 From a7d516d6e9b5ac2db87f5b98c67e599f95d3e512 Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Wed, 30 Mar 2016 19:48:24 -0400 Subject: staging/lustre: merge lclient/*.c into llite/ Separate lclient was necessary to be shared between different client implementations, make no sense to have them separate in Linux kernel. Signed-off-by: John L. Hammond Based-on: http://review.whamcloud.com/10171 Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/lclient/glimpse.c | 270 ----- drivers/staging/lustre/lustre/lclient/lcommon_cl.c | 1203 ------------------- .../staging/lustre/lustre/lclient/lcommon_misc.c | 200 ---- drivers/staging/lustre/lustre/llite/Makefile | 2 +- drivers/staging/lustre/lustre/llite/glimpse.c | 273 +++++ drivers/staging/lustre/lustre/llite/lcommon_cl.c | 1209 ++++++++++++++++++++ drivers/staging/lustre/lustre/llite/lcommon_misc.c | 200 ++++ 7 files changed, 1683 insertions(+), 1674 deletions(-) delete mode 100644 drivers/staging/lustre/lustre/lclient/glimpse.c delete mode 100644 drivers/staging/lustre/lustre/lclient/lcommon_cl.c delete mode 100644 drivers/staging/lustre/lustre/lclient/lcommon_misc.c create mode 100644 drivers/staging/lustre/lustre/llite/glimpse.c create mode 100644 drivers/staging/lustre/lustre/llite/lcommon_cl.c create mode 100644 drivers/staging/lustre/lustre/llite/lcommon_misc.c (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/lclient/glimpse.c b/drivers/staging/lustre/lustre/lclient/glimpse.c deleted file mode 100644 index c4e8a0878ac8..000000000000 --- a/drivers/staging/lustre/lustre/lclient/glimpse.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * GPL HEADER END - */ -/* - * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. - * Use is subject to license terms. - * - * Copyright (c) 2011, 2012, Intel Corporation. - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - * - * glimpse code shared between vvp and liblustre (and other Lustre clients in - * the future). - * - * Author: Nikita Danilov - * Author: Oleg Drokin - */ - -#include "../../include/linux/libcfs/libcfs.h" -#include "../include/obd_class.h" -#include "../include/obd_support.h" -#include "../include/obd.h" - -#include "../include/lustre_dlm.h" -#include "../include/lustre_lite.h" -#include "../include/lustre_mdc.h" -#include -#include - -#include "../include/cl_object.h" -#include "../include/lclient.h" -#include "../llite/llite_internal.h" - -static const struct cl_lock_descr whole_file = { - .cld_start = 0, - .cld_end = CL_PAGE_EOF, - .cld_mode = CLM_READ -}; - -/* - * Check whether file has possible unwriten pages. - * - * \retval 1 file is mmap-ed or has dirty pages - * 0 otherwise - */ -blkcnt_t dirty_cnt(struct inode *inode) -{ - blkcnt_t cnt = 0; - struct ccc_object *vob = cl_inode2ccc(inode); - void *results[1]; - - if (inode->i_mapping) - cnt += radix_tree_gang_lookup_tag(&inode->i_mapping->page_tree, - results, 0, 1, - PAGECACHE_TAG_DIRTY); - if (cnt == 0 && atomic_read(&vob->cob_mmap_cnt) > 0) - cnt = 1; - - return (cnt > 0) ? 1 : 0; -} - -int cl_glimpse_lock(const struct lu_env *env, struct cl_io *io, - struct inode *inode, struct cl_object *clob, int agl) -{ - struct cl_lock_descr *descr = &ccc_env_info(env)->cti_descr; - struct cl_inode_info *lli = cl_i2info(inode); - const struct lu_fid *fid = lu_object_fid(&clob->co_lu); - struct ccc_io *cio = ccc_env_io(env); - struct cl_lock *lock; - int result; - - result = 0; - if (!(lli->lli_flags & LLIF_MDS_SIZE_LOCK)) { - CDEBUG(D_DLMTRACE, "Glimpsing inode "DFID"\n", PFID(fid)); - if (lli->lli_has_smd) { - /* NOTE: this looks like DLM lock request, but it may - * not be one. Due to CEF_ASYNC flag (translated - * to LDLM_FL_HAS_INTENT by osc), this is - * glimpse request, that won't revoke any - * conflicting DLM locks held. Instead, - * ll_glimpse_callback() will be called on each - * client holding a DLM lock against this file, - * and resulting size will be returned for each - * stripe. DLM lock on [0, EOF] is acquired only - * if there were no conflicting locks. If there - * were conflicting locks, enqueuing or waiting - * fails with -ENAVAIL, but valid inode - * attributes are returned anyway. - */ - *descr = whole_file; - descr->cld_obj = clob; - descr->cld_mode = CLM_PHANTOM; - descr->cld_enq_flags = CEF_ASYNC | CEF_MUST; - if (agl) - descr->cld_enq_flags |= CEF_AGL; - cio->cui_glimpse = 1; - /* - * CEF_ASYNC is used because glimpse sub-locks cannot - * deadlock (because they never conflict with other - * locks) and, hence, can be enqueued out-of-order. - * - * CEF_MUST protects glimpse lock from conversion into - * a lockless mode. - */ - lock = cl_lock_request(env, io, descr, "glimpse", - current); - cio->cui_glimpse = 0; - - if (!lock) - return 0; - - if (IS_ERR(lock)) - return PTR_ERR(lock); - - LASSERT(agl == 0); - result = cl_wait(env, lock); - if (result == 0) { - cl_merge_lvb(env, inode); - if (cl_isize_read(inode) > 0 && - inode->i_blocks == 0) { - /* - * LU-417: Add dirty pages block count - * lest i_blocks reports 0, some "cp" or - * "tar" may think it's a completely - * sparse file and skip it. - */ - inode->i_blocks = dirty_cnt(inode); - } - cl_unuse(env, lock); - } - cl_lock_release(env, lock, "glimpse", current); - } else { - CDEBUG(D_DLMTRACE, "No objects for inode\n"); - cl_merge_lvb(env, inode); - } - } - - return result; -} - -static int cl_io_get(struct inode *inode, struct lu_env **envout, - struct cl_io **ioout, int *refcheck) -{ - struct lu_env *env; - struct cl_io *io; - struct cl_inode_info *lli = cl_i2info(inode); - struct cl_object *clob = lli->lli_clob; - int result; - - if (S_ISREG(cl_inode_mode(inode))) { - env = cl_env_get(refcheck); - if (!IS_ERR(env)) { - io = ccc_env_thread_io(env); - io->ci_obj = clob; - *envout = env; - *ioout = io; - result = 1; - } else - result = PTR_ERR(env); - } else - result = 0; - return result; -} - -int cl_glimpse_size0(struct inode *inode, int agl) -{ - /* - * We don't need ast_flags argument to cl_glimpse_size(), because - * osc_lock_enqueue() takes care of the possible deadlock that said - * argument was introduced to avoid. - */ - /* - * XXX but note that ll_file_seek() passes LDLM_FL_BLOCK_NOWAIT to - * cl_glimpse_size(), which doesn't make sense: glimpse locks are not - * blocking anyway. - */ - struct lu_env *env = NULL; - struct cl_io *io = NULL; - int result; - int refcheck; - - result = cl_io_get(inode, &env, &io, &refcheck); - if (result > 0) { -again: - io->ci_verify_layout = 1; - result = cl_io_init(env, io, CIT_MISC, io->ci_obj); - if (result > 0) - /* - * nothing to do for this io. This currently happens - * when stripe sub-object's are not yet created. - */ - result = io->ci_result; - else if (result == 0) - result = cl_glimpse_lock(env, io, inode, io->ci_obj, - agl); - - OBD_FAIL_TIMEOUT(OBD_FAIL_GLIMPSE_DELAY, 2); - cl_io_fini(env, io); - if (unlikely(io->ci_need_restart)) - goto again; - cl_env_put(env, &refcheck); - } - return result; -} - -int cl_local_size(struct inode *inode) -{ - struct lu_env *env = NULL; - struct cl_io *io = NULL; - struct ccc_thread_info *cti; - struct cl_object *clob; - struct cl_lock_descr *descr; - struct cl_lock *lock; - int result; - int refcheck; - - if (!cl_i2info(inode)->lli_has_smd) - return 0; - - result = cl_io_get(inode, &env, &io, &refcheck); - if (result <= 0) - return result; - - clob = io->ci_obj; - result = cl_io_init(env, io, CIT_MISC, clob); - if (result > 0) - result = io->ci_result; - else if (result == 0) { - cti = ccc_env_info(env); - descr = &cti->cti_descr; - - *descr = whole_file; - descr->cld_obj = clob; - lock = cl_lock_peek(env, io, descr, "localsize", current); - if (lock) { - cl_merge_lvb(env, inode); - cl_unuse(env, lock); - cl_lock_release(env, lock, "localsize", current); - result = 0; - } else - result = -ENODATA; - } - cl_io_fini(env, io); - cl_env_put(env, &refcheck); - return result; -} diff --git a/drivers/staging/lustre/lustre/lclient/lcommon_cl.c b/drivers/staging/lustre/lustre/lclient/lcommon_cl.c deleted file mode 100644 index aced41ab93a1..000000000000 --- a/drivers/staging/lustre/lustre/lclient/lcommon_cl.c +++ /dev/null @@ -1,1203 +0,0 @@ -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * GPL HEADER END - */ -/* - * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. - * Use is subject to license terms. - * - * Copyright (c) 2011, 2015, Intel Corporation. - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - * - * cl code shared between vvp and liblustre (and other Lustre clients in the - * future). - * - * Author: Nikita Danilov - */ - -#define DEBUG_SUBSYSTEM S_LLITE - -#include "../../include/linux/libcfs/libcfs.h" -# include -# include -# include -# include -# include -# include -# include - -#include "../include/obd.h" -#include "../include/obd_support.h" -#include "../include/lustre_fid.h" -#include "../include/lustre_lite.h" -#include "../include/lustre_dlm.h" -#include "../include/lustre_ver.h" -#include "../include/lustre_mdc.h" -#include "../include/cl_object.h" - -#include "../include/lclient.h" - -#include "../llite/llite_internal.h" - -static const struct cl_req_operations ccc_req_ops; - -/* - * ccc_ prefix stands for "Common Client Code". - */ - -static struct kmem_cache *ccc_lock_kmem; -static struct kmem_cache *ccc_object_kmem; -static struct kmem_cache *ccc_thread_kmem; -static struct kmem_cache *ccc_session_kmem; -static struct kmem_cache *ccc_req_kmem; - -static struct lu_kmem_descr ccc_caches[] = { - { - .ckd_cache = &ccc_lock_kmem, - .ckd_name = "ccc_lock_kmem", - .ckd_size = sizeof(struct ccc_lock) - }, - { - .ckd_cache = &ccc_object_kmem, - .ckd_name = "ccc_object_kmem", - .ckd_size = sizeof(struct ccc_object) - }, - { - .ckd_cache = &ccc_thread_kmem, - .ckd_name = "ccc_thread_kmem", - .ckd_size = sizeof(struct ccc_thread_info), - }, - { - .ckd_cache = &ccc_session_kmem, - .ckd_name = "ccc_session_kmem", - .ckd_size = sizeof(struct ccc_session) - }, - { - .ckd_cache = &ccc_req_kmem, - .ckd_name = "ccc_req_kmem", - .ckd_size = sizeof(struct ccc_req) - }, - { - .ckd_cache = NULL - } -}; - -/***************************************************************************** - * - * Vvp device and device type functions. - * - */ - -void *ccc_key_init(const struct lu_context *ctx, struct lu_context_key *key) -{ - struct ccc_thread_info *info; - - info = kmem_cache_zalloc(ccc_thread_kmem, GFP_NOFS); - if (!info) - info = ERR_PTR(-ENOMEM); - return info; -} - -void ccc_key_fini(const struct lu_context *ctx, - struct lu_context_key *key, void *data) -{ - struct ccc_thread_info *info = data; - - kmem_cache_free(ccc_thread_kmem, info); -} - -void *ccc_session_key_init(const struct lu_context *ctx, - struct lu_context_key *key) -{ - struct ccc_session *session; - - session = kmem_cache_zalloc(ccc_session_kmem, GFP_NOFS); - if (!session) - session = ERR_PTR(-ENOMEM); - return session; -} - -void ccc_session_key_fini(const struct lu_context *ctx, - struct lu_context_key *key, void *data) -{ - struct ccc_session *session = data; - - kmem_cache_free(ccc_session_kmem, session); -} - -struct lu_context_key ccc_key = { - .lct_tags = LCT_CL_THREAD, - .lct_init = ccc_key_init, - .lct_fini = ccc_key_fini -}; - -struct lu_context_key ccc_session_key = { - .lct_tags = LCT_SESSION, - .lct_init = ccc_session_key_init, - .lct_fini = ccc_session_key_fini -}; - -/* type constructor/destructor: ccc_type_{init,fini,start,stop}(). */ -/* LU_TYPE_INIT_FINI(ccc, &ccc_key, &ccc_session_key); */ - -int ccc_device_init(const struct lu_env *env, struct lu_device *d, - const char *name, struct lu_device *next) -{ - struct ccc_device *vdv; - int rc; - - vdv = lu2ccc_dev(d); - vdv->cdv_next = lu2cl_dev(next); - - LASSERT(d->ld_site && next->ld_type); - next->ld_site = d->ld_site; - rc = next->ld_type->ldt_ops->ldto_device_init( - env, next, next->ld_type->ldt_name, NULL); - if (rc == 0) { - lu_device_get(next); - lu_ref_add(&next->ld_reference, "lu-stack", &lu_site_init); - } - return rc; -} - -struct lu_device *ccc_device_fini(const struct lu_env *env, - struct lu_device *d) -{ - return cl2lu_dev(lu2ccc_dev(d)->cdv_next); -} - -struct lu_device *ccc_device_alloc(const struct lu_env *env, - struct lu_device_type *t, - struct lustre_cfg *cfg, - const struct lu_device_operations *luops, - const struct cl_device_operations *clops) -{ - struct ccc_device *vdv; - struct lu_device *lud; - struct cl_site *site; - int rc; - - vdv = kzalloc(sizeof(*vdv), GFP_NOFS); - if (!vdv) - return ERR_PTR(-ENOMEM); - - lud = &vdv->cdv_cl.cd_lu_dev; - cl_device_init(&vdv->cdv_cl, t); - ccc2lu_dev(vdv)->ld_ops = luops; - vdv->cdv_cl.cd_ops = clops; - - site = kzalloc(sizeof(*site), GFP_NOFS); - if (site) { - rc = cl_site_init(site, &vdv->cdv_cl); - if (rc == 0) - rc = lu_site_init_finish(&site->cs_lu); - else { - LASSERT(!lud->ld_site); - CERROR("Cannot init lu_site, rc %d.\n", rc); - kfree(site); - } - } else - rc = -ENOMEM; - if (rc != 0) { - ccc_device_free(env, lud); - lud = ERR_PTR(rc); - } - return lud; -} - -struct lu_device *ccc_device_free(const struct lu_env *env, - struct lu_device *d) -{ - struct ccc_device *vdv = lu2ccc_dev(d); - struct cl_site *site = lu2cl_site(d->ld_site); - struct lu_device *next = cl2lu_dev(vdv->cdv_next); - - if (d->ld_site) { - cl_site_fini(site); - kfree(site); - } - cl_device_fini(lu2cl_dev(d)); - kfree(vdv); - return next; -} - -int ccc_req_init(const struct lu_env *env, struct cl_device *dev, - struct cl_req *req) -{ - struct ccc_req *vrq; - int result; - - vrq = kmem_cache_zalloc(ccc_req_kmem, GFP_NOFS); - if (vrq) { - cl_req_slice_add(req, &vrq->crq_cl, dev, &ccc_req_ops); - result = 0; - } else - result = -ENOMEM; - return result; -} - -/** - * An `emergency' environment used by ccc_inode_fini() when cl_env_get() - * fails. Access to this environment is serialized by ccc_inode_fini_guard - * mutex. - */ -static struct lu_env *ccc_inode_fini_env; - -/** - * A mutex serializing calls to slp_inode_fini() under extreme memory - * pressure, when environments cannot be allocated. - */ -static DEFINE_MUTEX(ccc_inode_fini_guard); -static int dummy_refcheck; - -int ccc_global_init(struct lu_device_type *device_type) -{ - int result; - - result = lu_kmem_init(ccc_caches); - if (result) - return result; - - result = lu_device_type_init(device_type); - if (result) - goto out_kmem; - - ccc_inode_fini_env = cl_env_alloc(&dummy_refcheck, - LCT_REMEMBER|LCT_NOREF); - if (IS_ERR(ccc_inode_fini_env)) { - result = PTR_ERR(ccc_inode_fini_env); - goto out_device; - } - - ccc_inode_fini_env->le_ctx.lc_cookie = 0x4; - return 0; -out_device: - lu_device_type_fini(device_type); -out_kmem: - lu_kmem_fini(ccc_caches); - return result; -} - -void ccc_global_fini(struct lu_device_type *device_type) -{ - if (ccc_inode_fini_env) { - cl_env_put(ccc_inode_fini_env, &dummy_refcheck); - ccc_inode_fini_env = NULL; - } - lu_device_type_fini(device_type); - lu_kmem_fini(ccc_caches); -} - -/***************************************************************************** - * - * Object operations. - * - */ - -struct lu_object *ccc_object_alloc(const struct lu_env *env, - const struct lu_object_header *unused, - struct lu_device *dev, - const struct cl_object_operations *clops, - const struct lu_object_operations *luops) -{ - struct ccc_object *vob; - struct lu_object *obj; - - vob = kmem_cache_zalloc(ccc_object_kmem, GFP_NOFS); - if (vob) { - struct cl_object_header *hdr; - - obj = ccc2lu(vob); - hdr = &vob->cob_header; - cl_object_header_init(hdr); - lu_object_init(obj, &hdr->coh_lu, dev); - lu_object_add_top(&hdr->coh_lu, obj); - - vob->cob_cl.co_ops = clops; - obj->lo_ops = luops; - } else - obj = NULL; - return obj; -} - -int ccc_object_init0(const struct lu_env *env, - struct ccc_object *vob, - const struct cl_object_conf *conf) -{ - vob->cob_inode = conf->coc_inode; - vob->cob_transient_pages = 0; - cl_object_page_init(&vob->cob_cl, sizeof(struct ccc_page)); - return 0; -} - -int ccc_object_init(const struct lu_env *env, struct lu_object *obj, - const struct lu_object_conf *conf) -{ - struct ccc_device *dev = lu2ccc_dev(obj->lo_dev); - struct ccc_object *vob = lu2ccc(obj); - struct lu_object *below; - struct lu_device *under; - int result; - - under = &dev->cdv_next->cd_lu_dev; - below = under->ld_ops->ldo_object_alloc(env, obj->lo_header, under); - if (below) { - const struct cl_object_conf *cconf; - - cconf = lu2cl_conf(conf); - INIT_LIST_HEAD(&vob->cob_pending_list); - lu_object_add(obj, below); - result = ccc_object_init0(env, vob, cconf); - } else - result = -ENOMEM; - return result; -} - -void ccc_object_free(const struct lu_env *env, struct lu_object *obj) -{ - struct ccc_object *vob = lu2ccc(obj); - - lu_object_fini(obj); - lu_object_header_fini(obj->lo_header); - kmem_cache_free(ccc_object_kmem, vob); -} - -int ccc_lock_init(const struct lu_env *env, - struct cl_object *obj, struct cl_lock *lock, - const struct cl_io *unused, - const struct cl_lock_operations *lkops) -{ - struct ccc_lock *clk; - int result; - - CLOBINVRNT(env, obj, ccc_object_invariant(obj)); - - clk = kmem_cache_zalloc(ccc_lock_kmem, GFP_NOFS); - if (clk) { - cl_lock_slice_add(lock, &clk->clk_cl, obj, lkops); - result = 0; - } else - result = -ENOMEM; - return result; -} - -int ccc_object_glimpse(const struct lu_env *env, - const struct cl_object *obj, struct ost_lvb *lvb) -{ - struct inode *inode = ccc_object_inode(obj); - - lvb->lvb_mtime = cl_inode_mtime(inode); - lvb->lvb_atime = cl_inode_atime(inode); - lvb->lvb_ctime = cl_inode_ctime(inode); - /* - * LU-417: Add dirty pages block count lest i_blocks reports 0, some - * "cp" or "tar" on remote node may think it's a completely sparse file - * and skip it. - */ - if (lvb->lvb_size > 0 && lvb->lvb_blocks == 0) - lvb->lvb_blocks = dirty_cnt(inode); - return 0; -} - -static void ccc_object_size_lock(struct cl_object *obj) -{ - struct inode *inode = ccc_object_inode(obj); - - ll_inode_size_lock(inode); - cl_object_attr_lock(obj); -} - -static void ccc_object_size_unlock(struct cl_object *obj) -{ - struct inode *inode = ccc_object_inode(obj); - - cl_object_attr_unlock(obj); - ll_inode_size_unlock(inode); -} - -/***************************************************************************** - * - * Page operations. - * - */ - -struct page *ccc_page_vmpage(const struct lu_env *env, - const struct cl_page_slice *slice) -{ - return cl2vm_page(slice); -} - -int ccc_page_is_under_lock(const struct lu_env *env, - const struct cl_page_slice *slice, - struct cl_io *io) -{ - struct ccc_io *cio = ccc_env_io(env); - struct cl_lock_descr *desc = &ccc_env_info(env)->cti_descr; - struct cl_page *page = slice->cpl_page; - - int result; - - if (io->ci_type == CIT_READ || io->ci_type == CIT_WRITE || - io->ci_type == CIT_FAULT) { - if (cio->cui_fd->fd_flags & LL_FILE_GROUP_LOCKED) - result = -EBUSY; - else { - desc->cld_start = page->cp_index; - desc->cld_end = page->cp_index; - desc->cld_obj = page->cp_obj; - desc->cld_mode = CLM_READ; - result = cl_queue_match(&io->ci_lockset.cls_done, - desc) ? -EBUSY : 0; - } - } else - result = 0; - return result; -} - -int ccc_fail(const struct lu_env *env, const struct cl_page_slice *slice) -{ - /* - * Cached read? - */ - LBUG(); - return 0; -} - -int ccc_transient_page_prep(const struct lu_env *env, - const struct cl_page_slice *slice, - struct cl_io *unused) -{ - /* transient page should always be sent. */ - return 0; -} - -/***************************************************************************** - * - * Lock operations. - * - */ - -void ccc_lock_delete(const struct lu_env *env, - const struct cl_lock_slice *slice) -{ - CLOBINVRNT(env, slice->cls_obj, ccc_object_invariant(slice->cls_obj)); -} - -void ccc_lock_fini(const struct lu_env *env, struct cl_lock_slice *slice) -{ - struct ccc_lock *clk = cl2ccc_lock(slice); - - kmem_cache_free(ccc_lock_kmem, clk); -} - -int ccc_lock_enqueue(const struct lu_env *env, - const struct cl_lock_slice *slice, - struct cl_io *unused, __u32 enqflags) -{ - CLOBINVRNT(env, slice->cls_obj, ccc_object_invariant(slice->cls_obj)); - return 0; -} - -int ccc_lock_use(const struct lu_env *env, const struct cl_lock_slice *slice) -{ - CLOBINVRNT(env, slice->cls_obj, ccc_object_invariant(slice->cls_obj)); - return 0; -} - -int ccc_lock_unuse(const struct lu_env *env, const struct cl_lock_slice *slice) -{ - CLOBINVRNT(env, slice->cls_obj, ccc_object_invariant(slice->cls_obj)); - return 0; -} - -int ccc_lock_wait(const struct lu_env *env, const struct cl_lock_slice *slice) -{ - CLOBINVRNT(env, slice->cls_obj, ccc_object_invariant(slice->cls_obj)); - return 0; -} - -/** - * Implementation of cl_lock_operations::clo_fits_into() methods for ccc - * layer. This function is executed every time io finds an existing lock in - * the lock cache while creating new lock. This function has to decide whether - * cached lock "fits" into io. - * - * \param slice lock to be checked - * \param io IO that wants a lock. - * - * \see lov_lock_fits_into(). - */ -int ccc_lock_fits_into(const struct lu_env *env, - const struct cl_lock_slice *slice, - const struct cl_lock_descr *need, - const struct cl_io *io) -{ - const struct cl_lock *lock = slice->cls_lock; - const struct cl_lock_descr *descr = &lock->cll_descr; - const struct ccc_io *cio = ccc_env_io(env); - int result; - - /* - * Work around DLM peculiarity: it assumes that glimpse - * (LDLM_FL_HAS_INTENT) lock is always LCK_PR, and returns reads lock - * when asked for LCK_PW lock with LDLM_FL_HAS_INTENT flag set. Make - * sure that glimpse doesn't get CLM_WRITE top-lock, so that it - * doesn't enqueue CLM_WRITE sub-locks. - */ - if (cio->cui_glimpse) - result = descr->cld_mode != CLM_WRITE; - - /* - * Also, don't match incomplete write locks for read, otherwise read - * would enqueue missing sub-locks in the write mode. - */ - else if (need->cld_mode != descr->cld_mode) - result = lock->cll_state >= CLS_ENQUEUED; - else - result = 1; - return result; -} - -/** - * Implements cl_lock_operations::clo_state() method for ccc layer, invoked - * whenever lock state changes. Transfers object attributes, that might be - * updated as a result of lock acquiring into inode. - */ -void ccc_lock_state(const struct lu_env *env, - const struct cl_lock_slice *slice, - enum cl_lock_state state) -{ - struct cl_lock *lock = slice->cls_lock; - - /* - * Refresh inode attributes when the lock is moving into CLS_HELD - * state, and only when this is a result of real enqueue, rather than - * of finding lock in the cache. - */ - if (state == CLS_HELD && lock->cll_state < CLS_HELD) { - struct cl_object *obj; - struct inode *inode; - - obj = slice->cls_obj; - inode = ccc_object_inode(obj); - - /* vmtruncate() sets the i_size - * under both a DLM lock and the - * ll_inode_size_lock(). If we don't get the - * ll_inode_size_lock() here we can match the DLM lock and - * reset i_size. generic_file_write can then trust the - * stale i_size when doing appending writes and effectively - * cancel the result of the truncate. Getting the - * ll_inode_size_lock() after the enqueue maintains the DLM - * -> ll_inode_size_lock() acquiring order. - */ - if (lock->cll_descr.cld_start == 0 && - lock->cll_descr.cld_end == CL_PAGE_EOF) - cl_merge_lvb(env, inode); - } -} - -/***************************************************************************** - * - * io operations. - * - */ - -int ccc_io_one_lock_index(const struct lu_env *env, struct cl_io *io, - __u32 enqflags, enum cl_lock_mode mode, - pgoff_t start, pgoff_t end) -{ - struct ccc_io *cio = ccc_env_io(env); - struct cl_lock_descr *descr = &cio->cui_link.cill_descr; - struct cl_object *obj = io->ci_obj; - - CLOBINVRNT(env, obj, ccc_object_invariant(obj)); - - CDEBUG(D_VFSTRACE, "lock: %d [%lu, %lu]\n", mode, start, end); - - memset(&cio->cui_link, 0, sizeof(cio->cui_link)); - - if (cio->cui_fd && (cio->cui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) { - descr->cld_mode = CLM_GROUP; - descr->cld_gid = cio->cui_fd->fd_grouplock.cg_gid; - } else { - descr->cld_mode = mode; - } - descr->cld_obj = obj; - descr->cld_start = start; - descr->cld_end = end; - descr->cld_enq_flags = enqflags; - - cl_io_lock_add(env, io, &cio->cui_link); - return 0; -} - -void ccc_io_update_iov(const struct lu_env *env, - struct ccc_io *cio, struct cl_io *io) -{ - size_t size = io->u.ci_rw.crw_count; - - if (!cl_is_normalio(env, io) || !cio->cui_iter) - return; - - iov_iter_truncate(cio->cui_iter, size); -} - -int ccc_io_one_lock(const struct lu_env *env, struct cl_io *io, - __u32 enqflags, enum cl_lock_mode mode, - loff_t start, loff_t end) -{ - struct cl_object *obj = io->ci_obj; - - return ccc_io_one_lock_index(env, io, enqflags, mode, - cl_index(obj, start), cl_index(obj, end)); -} - -void ccc_io_end(const struct lu_env *env, const struct cl_io_slice *ios) -{ - CLOBINVRNT(env, ios->cis_io->ci_obj, - ccc_object_invariant(ios->cis_io->ci_obj)); -} - -void ccc_io_advance(const struct lu_env *env, - const struct cl_io_slice *ios, - size_t nob) -{ - struct ccc_io *cio = cl2ccc_io(env, ios); - struct cl_io *io = ios->cis_io; - struct cl_object *obj = ios->cis_io->ci_obj; - - CLOBINVRNT(env, obj, ccc_object_invariant(obj)); - - if (!cl_is_normalio(env, io)) - return; - - iov_iter_reexpand(cio->cui_iter, cio->cui_tot_count -= nob); -} - -/** - * Helper function that if necessary adjusts file size (inode->i_size), when - * position at the offset \a pos is accessed. File size can be arbitrary stale - * on a Lustre client, but client at least knows KMS. If accessed area is - * inside [0, KMS], set file size to KMS, otherwise glimpse file size. - * - * Locking: cl_isize_lock is used to serialize changes to inode size and to - * protect consistency between inode size and cl_object - * attributes. cl_object_size_lock() protects consistency between cl_attr's of - * top-object and sub-objects. - */ -int ccc_prep_size(const struct lu_env *env, struct cl_object *obj, - struct cl_io *io, loff_t start, size_t count, int *exceed) -{ - struct cl_attr *attr = ccc_env_thread_attr(env); - struct inode *inode = ccc_object_inode(obj); - loff_t pos = start + count - 1; - loff_t kms; - int result; - - /* - * Consistency guarantees: following possibilities exist for the - * relation between region being accessed and real file size at this - * moment: - * - * (A): the region is completely inside of the file; - * - * (B-x): x bytes of region are inside of the file, the rest is - * outside; - * - * (C): the region is completely outside of the file. - * - * This classification is stable under DLM lock already acquired by - * the caller, because to change the class, other client has to take - * DLM lock conflicting with our lock. Also, any updates to ->i_size - * by other threads on this client are serialized by - * ll_inode_size_lock(). This guarantees that short reads are handled - * correctly in the face of concurrent writes and truncates. - */ - ccc_object_size_lock(obj); - result = cl_object_attr_get(env, obj, attr); - if (result == 0) { - kms = attr->cat_kms; - if (pos > kms) { - /* - * A glimpse is necessary to determine whether we - * return a short read (B) or some zeroes at the end - * of the buffer (C) - */ - ccc_object_size_unlock(obj); - result = cl_glimpse_lock(env, io, inode, obj, 0); - if (result == 0 && exceed) { - /* If objective page index exceed end-of-file - * page index, return directly. Do not expect - * kernel will check such case correctly. - * linux-2.6.18-128.1.1 miss to do that. - * --bug 17336 - */ - loff_t size = cl_isize_read(inode); - loff_t cur_index = start >> PAGE_CACHE_SHIFT; - loff_t size_index = (size - 1) >> - PAGE_CACHE_SHIFT; - - if ((size == 0 && cur_index != 0) || - size_index < cur_index) - *exceed = 1; - } - return result; - } - /* - * region is within kms and, hence, within real file - * size (A). We need to increase i_size to cover the - * read region so that generic_file_read() will do its - * job, but that doesn't mean the kms size is - * _correct_, it is only the _minimum_ size. If - * someone does a stat they will get the correct size - * which will always be >= the kms value here. - * b=11081 - */ - if (cl_isize_read(inode) < kms) { - cl_isize_write_nolock(inode, kms); - CDEBUG(D_VFSTRACE, - DFID" updating i_size %llu\n", - PFID(lu_object_fid(&obj->co_lu)), - (__u64)cl_isize_read(inode)); - - } - } - ccc_object_size_unlock(obj); - return result; -} - -/***************************************************************************** - * - * Transfer operations. - * - */ - -void ccc_req_completion(const struct lu_env *env, - const struct cl_req_slice *slice, int ioret) -{ - struct ccc_req *vrq; - - if (ioret > 0) - cl_stats_tally(slice->crs_dev, slice->crs_req->crq_type, ioret); - - vrq = cl2ccc_req(slice); - kmem_cache_free(ccc_req_kmem, vrq); -} - -/** - * Implementation of struct cl_req_operations::cro_attr_set() for ccc - * layer. ccc is responsible for - * - * - o_[mac]time - * - * - o_mode - * - * - o_parent_seq - * - * - o_[ug]id - * - * - o_parent_oid - * - * - o_parent_ver - * - * - o_ioepoch, - * - */ -void ccc_req_attr_set(const struct lu_env *env, - const struct cl_req_slice *slice, - const struct cl_object *obj, - struct cl_req_attr *attr, u64 flags) -{ - struct inode *inode; - struct obdo *oa; - u32 valid_flags; - - oa = attr->cra_oa; - inode = ccc_object_inode(obj); - valid_flags = OBD_MD_FLTYPE; - - if (slice->crs_req->crq_type == CRT_WRITE) { - if (flags & OBD_MD_FLEPOCH) { - oa->o_valid |= OBD_MD_FLEPOCH; - oa->o_ioepoch = cl_i2info(inode)->lli_ioepoch; - valid_flags |= OBD_MD_FLMTIME | OBD_MD_FLCTIME | - OBD_MD_FLUID | OBD_MD_FLGID; - } - } - obdo_from_inode(oa, inode, valid_flags & flags); - obdo_set_parent_fid(oa, &cl_i2info(inode)->lli_fid); - memcpy(attr->cra_jobid, cl_i2info(inode)->lli_jobid, - JOBSTATS_JOBID_SIZE); -} - -static const struct cl_req_operations ccc_req_ops = { - .cro_attr_set = ccc_req_attr_set, - .cro_completion = ccc_req_completion -}; - -int cl_setattr_ost(struct inode *inode, const struct iattr *attr) -{ - struct lu_env *env; - struct cl_io *io; - int result; - int refcheck; - - env = cl_env_get(&refcheck); - if (IS_ERR(env)) - return PTR_ERR(env); - - io = ccc_env_thread_io(env); - io->ci_obj = cl_i2info(inode)->lli_clob; - - io->u.ci_setattr.sa_attr.lvb_atime = LTIME_S(attr->ia_atime); - io->u.ci_setattr.sa_attr.lvb_mtime = LTIME_S(attr->ia_mtime); - io->u.ci_setattr.sa_attr.lvb_ctime = LTIME_S(attr->ia_ctime); - io->u.ci_setattr.sa_attr.lvb_size = attr->ia_size; - io->u.ci_setattr.sa_valid = attr->ia_valid; - -again: - if (cl_io_init(env, io, CIT_SETATTR, io->ci_obj) == 0) { - struct ccc_io *cio = ccc_env_io(env); - - if (attr->ia_valid & ATTR_FILE) - /* populate the file descriptor for ftruncate to honor - * group lock - see LU-787 - */ - cio->cui_fd = cl_iattr2fd(inode, attr); - - result = cl_io_loop(env, io); - } else { - result = io->ci_result; - } - cl_io_fini(env, io); - if (unlikely(io->ci_need_restart)) - goto again; - /* HSM import case: file is released, cannot be restored - * no need to fail except if restore registration failed - * with -ENODATA - */ - if (result == -ENODATA && io->ci_restore_needed && - io->ci_result != -ENODATA) - result = 0; - cl_env_put(env, &refcheck); - return result; -} - -/***************************************************************************** - * - * Type conversions. - * - */ - -struct lu_device *ccc2lu_dev(struct ccc_device *vdv) -{ - return &vdv->cdv_cl.cd_lu_dev; -} - -struct ccc_device *lu2ccc_dev(const struct lu_device *d) -{ - return container_of0(d, struct ccc_device, cdv_cl.cd_lu_dev); -} - -struct ccc_device *cl2ccc_dev(const struct cl_device *d) -{ - return container_of0(d, struct ccc_device, cdv_cl); -} - -struct lu_object *ccc2lu(struct ccc_object *vob) -{ - return &vob->cob_cl.co_lu; -} - -struct ccc_object *lu2ccc(const struct lu_object *obj) -{ - return container_of0(obj, struct ccc_object, cob_cl.co_lu); -} - -struct ccc_object *cl2ccc(const struct cl_object *obj) -{ - return container_of0(obj, struct ccc_object, cob_cl); -} - -struct ccc_lock *cl2ccc_lock(const struct cl_lock_slice *slice) -{ - return container_of(slice, struct ccc_lock, clk_cl); -} - -struct ccc_io *cl2ccc_io(const struct lu_env *env, - const struct cl_io_slice *slice) -{ - struct ccc_io *cio; - - cio = container_of(slice, struct ccc_io, cui_cl); - LASSERT(cio == ccc_env_io(env)); - return cio; -} - -struct ccc_req *cl2ccc_req(const struct cl_req_slice *slice) -{ - return container_of0(slice, struct ccc_req, crq_cl); -} - -struct page *cl2vm_page(const struct cl_page_slice *slice) -{ - return cl2ccc_page(slice)->cpg_page; -} - -/***************************************************************************** - * - * Accessors. - * - */ -int ccc_object_invariant(const struct cl_object *obj) -{ - struct inode *inode = ccc_object_inode(obj); - struct cl_inode_info *lli = cl_i2info(inode); - - return (S_ISREG(cl_inode_mode(inode)) || - /* i_mode of unlinked inode is zeroed. */ - cl_inode_mode(inode) == 0) && lli->lli_clob == obj; -} - -struct inode *ccc_object_inode(const struct cl_object *obj) -{ - return cl2ccc(obj)->cob_inode; -} - -/** - * Initialize or update CLIO structures for regular files when new - * meta-data arrives from the server. - * - * \param inode regular file inode - * \param md new file metadata from MDS - * - allocates cl_object if necessary, - * - updated layout, if object was already here. - */ -int cl_file_inode_init(struct inode *inode, struct lustre_md *md) -{ - struct lu_env *env; - struct cl_inode_info *lli; - struct cl_object *clob; - struct lu_site *site; - struct lu_fid *fid; - struct cl_object_conf conf = { - .coc_inode = inode, - .u = { - .coc_md = md - } - }; - int result = 0; - int refcheck; - - LASSERT(md->body->valid & OBD_MD_FLID); - LASSERT(S_ISREG(cl_inode_mode(inode))); - - env = cl_env_get(&refcheck); - if (IS_ERR(env)) - return PTR_ERR(env); - - site = cl_i2sbi(inode)->ll_site; - lli = cl_i2info(inode); - fid = &lli->lli_fid; - LASSERT(fid_is_sane(fid)); - - if (!lli->lli_clob) { - /* clob is slave of inode, empty lli_clob means for new inode, - * there is no clob in cache with the given fid, so it is - * unnecessary to perform lookup-alloc-lookup-insert, just - * alloc and insert directly. - */ - LASSERT(inode->i_state & I_NEW); - conf.coc_lu.loc_flags = LOC_F_NEW; - clob = cl_object_find(env, lu2cl_dev(site->ls_top_dev), - fid, &conf); - if (!IS_ERR(clob)) { - /* - * No locking is necessary, as new inode is - * locked by I_NEW bit. - */ - lli->lli_clob = clob; - lli->lli_has_smd = lsm_has_objects(md->lsm); - lu_object_ref_add(&clob->co_lu, "inode", inode); - } else - result = PTR_ERR(clob); - } else { - result = cl_conf_set(env, lli->lli_clob, &conf); - } - - cl_env_put(env, &refcheck); - - if (result != 0) - CERROR("Failure to initialize cl object "DFID": %d\n", - PFID(fid), result); - return result; -} - -/** - * Wait for others drop their references of the object at first, then we drop - * the last one, which will lead to the object be destroyed immediately. - * Must be called after cl_object_kill() against this object. - * - * The reason we want to do this is: destroying top object will wait for sub - * objects being destroyed first, so we can't let bottom layer (e.g. from ASTs) - * to initiate top object destroying which may deadlock. See bz22520. - */ -static void cl_object_put_last(struct lu_env *env, struct cl_object *obj) -{ - struct lu_object_header *header = obj->co_lu.lo_header; - wait_queue_t waiter; - - if (unlikely(atomic_read(&header->loh_ref) != 1)) { - struct lu_site *site = obj->co_lu.lo_dev->ld_site; - struct lu_site_bkt_data *bkt; - - bkt = lu_site_bkt_from_fid(site, &header->loh_fid); - - init_waitqueue_entry(&waiter, current); - add_wait_queue(&bkt->lsb_marche_funebre, &waiter); - - while (1) { - set_current_state(TASK_UNINTERRUPTIBLE); - if (atomic_read(&header->loh_ref) == 1) - break; - schedule(); - } - - set_current_state(TASK_RUNNING); - remove_wait_queue(&bkt->lsb_marche_funebre, &waiter); - } - - cl_object_put(env, obj); -} - -void cl_inode_fini(struct inode *inode) -{ - struct lu_env *env; - struct cl_inode_info *lli = cl_i2info(inode); - struct cl_object *clob = lli->lli_clob; - int refcheck; - int emergency; - - if (clob) { - void *cookie; - - cookie = cl_env_reenter(); - env = cl_env_get(&refcheck); - emergency = IS_ERR(env); - if (emergency) { - mutex_lock(&ccc_inode_fini_guard); - LASSERT(ccc_inode_fini_env); - cl_env_implant(ccc_inode_fini_env, &refcheck); - env = ccc_inode_fini_env; - } - /* - * cl_object cache is a slave to inode cache (which, in turn - * is a slave to dentry cache), don't keep cl_object in memory - * when its master is evicted. - */ - cl_object_kill(env, clob); - lu_object_ref_del(&clob->co_lu, "inode", inode); - cl_object_put_last(env, clob); - lli->lli_clob = NULL; - if (emergency) { - cl_env_unplant(ccc_inode_fini_env, &refcheck); - mutex_unlock(&ccc_inode_fini_guard); - } else - cl_env_put(env, &refcheck); - cl_env_reexit(cookie); - } -} - -/** - * return IF_* type for given lu_dirent entry. - * IF_* flag shld be converted to particular OS file type in - * platform llite module. - */ -__u16 ll_dirent_type_get(struct lu_dirent *ent) -{ - __u16 type = 0; - struct luda_type *lt; - int len = 0; - - if (le32_to_cpu(ent->lde_attrs) & LUDA_TYPE) { - const unsigned align = sizeof(struct luda_type) - 1; - - len = le16_to_cpu(ent->lde_namelen); - len = (len + align) & ~align; - lt = (void *)ent->lde_name + len; - type = IFTODT(le16_to_cpu(lt->lt_type)); - } - return type; -} - -/** - * build inode number from passed @fid - */ -__u64 cl_fid_build_ino(const struct lu_fid *fid, int api32) -{ - if (BITS_PER_LONG == 32 || api32) - return fid_flatten32(fid); - else - return fid_flatten(fid); -} - -/** - * build inode generation from passed @fid. If our FID overflows the 32-bit - * inode number then return a non-zero generation to distinguish them. - */ -__u32 cl_fid_build_gen(const struct lu_fid *fid) -{ - __u32 gen; - - if (fid_is_igif(fid)) { - gen = lu_igif_gen(fid); - return gen; - } - - gen = fid_flatten(fid) >> 32; - return gen; -} - -/* lsm is unreliable after hsm implementation as layout can be changed at - * any time. This is only to support old, non-clio-ized interfaces. It will - * cause deadlock if clio operations are called with this extra layout refcount - * because in case the layout changed during the IO, ll_layout_refresh() will - * have to wait for the refcount to become zero to destroy the older layout. - * - * Notice that the lsm returned by this function may not be valid unless called - * inside layout lock - MDS_INODELOCK_LAYOUT. - */ -struct lov_stripe_md *ccc_inode_lsm_get(struct inode *inode) -{ - return lov_lsm_get(cl_i2info(inode)->lli_clob); -} - -inline void ccc_inode_lsm_put(struct inode *inode, struct lov_stripe_md *lsm) -{ - lov_lsm_put(cl_i2info(inode)->lli_clob, lsm); -} diff --git a/drivers/staging/lustre/lustre/lclient/lcommon_misc.c b/drivers/staging/lustre/lustre/lclient/lcommon_misc.c deleted file mode 100644 index d80bcedd78d1..000000000000 --- a/drivers/staging/lustre/lustre/lclient/lcommon_misc.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * GPL HEADER END - */ -/* - * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. - * Use is subject to license terms. - * - * Copyright (c) 2011, 2012, Intel Corporation. - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - * - * cl code shared between vvp and liblustre (and other Lustre clients in the - * future). - * - */ -#include "../include/obd_class.h" -#include "../include/obd_support.h" -#include "../include/obd.h" -#include "../include/cl_object.h" -#include "../include/lclient.h" - -#include "../include/lustre_lite.h" - -/* Initialize the default and maximum LOV EA and cookie sizes. This allows - * us to make MDS RPCs with large enough reply buffers to hold the - * maximum-sized (= maximum striped) EA and cookie without having to - * calculate this (via a call into the LOV + OSCs) each time we make an RPC. - */ -int cl_init_ea_size(struct obd_export *md_exp, struct obd_export *dt_exp) -{ - struct lov_stripe_md lsm = { .lsm_magic = LOV_MAGIC_V3 }; - __u32 valsize = sizeof(struct lov_desc); - int rc, easize, def_easize, cookiesize; - struct lov_desc desc; - __u16 stripes, def_stripes; - - rc = obd_get_info(NULL, dt_exp, sizeof(KEY_LOVDESC), KEY_LOVDESC, - &valsize, &desc, NULL); - if (rc) - return rc; - - stripes = min_t(__u32, desc.ld_tgt_count, LOV_MAX_STRIPE_COUNT); - lsm.lsm_stripe_count = stripes; - easize = obd_size_diskmd(dt_exp, &lsm); - - def_stripes = min_t(__u32, desc.ld_default_stripe_count, - LOV_MAX_STRIPE_COUNT); - lsm.lsm_stripe_count = def_stripes; - def_easize = obd_size_diskmd(dt_exp, &lsm); - - cookiesize = stripes * sizeof(struct llog_cookie); - - /* default cookiesize is 0 because from 2.4 server doesn't send - * llog cookies to client. - */ - CDEBUG(D_HA, - "updating def/max_easize: %d/%d def/max_cookiesize: 0/%d\n", - def_easize, easize, cookiesize); - - rc = md_init_ea_size(md_exp, easize, def_easize, cookiesize, 0); - return rc; -} - -/** - * This function is used as an upcall-callback hooked by liblustre and llite - * clients into obd_notify() listeners chain to handle notifications about - * change of import connect_flags. See llu_fsswop_mount() and - * lustre_common_fill_super(). - */ -int cl_ocd_update(struct obd_device *host, - struct obd_device *watched, - enum obd_notify_event ev, void *owner, void *data) -{ - struct lustre_client_ocd *lco; - struct client_obd *cli; - __u64 flags; - int result; - - if (!strcmp(watched->obd_type->typ_name, LUSTRE_OSC_NAME)) { - cli = &watched->u.cli; - lco = owner; - flags = cli->cl_import->imp_connect_data.ocd_connect_flags; - CDEBUG(D_SUPER, "Changing connect_flags: %#llx -> %#llx\n", - lco->lco_flags, flags); - mutex_lock(&lco->lco_lock); - lco->lco_flags &= flags; - /* for each osc event update ea size */ - if (lco->lco_dt_exp) - cl_init_ea_size(lco->lco_md_exp, lco->lco_dt_exp); - - mutex_unlock(&lco->lco_lock); - result = 0; - } else { - CERROR("unexpected notification from %s %s!\n", - watched->obd_type->typ_name, - watched->obd_name); - result = -EINVAL; - } - return result; -} - -#define GROUPLOCK_SCOPE "grouplock" - -int cl_get_grouplock(struct cl_object *obj, unsigned long gid, int nonblock, - struct ccc_grouplock *cg) -{ - struct lu_env *env; - struct cl_io *io; - struct cl_lock *lock; - struct cl_lock_descr *descr; - __u32 enqflags; - int refcheck; - int rc; - - env = cl_env_get(&refcheck); - if (IS_ERR(env)) - return PTR_ERR(env); - - io = ccc_env_thread_io(env); - io->ci_obj = obj; - io->ci_ignore_layout = 1; - - rc = cl_io_init(env, io, CIT_MISC, io->ci_obj); - if (rc) { - /* Does not make sense to take GL for released layout */ - if (rc > 0) - rc = -ENOTSUPP; - cl_env_put(env, &refcheck); - return rc; - } - - descr = &ccc_env_info(env)->cti_descr; - descr->cld_obj = obj; - descr->cld_start = 0; - descr->cld_end = CL_PAGE_EOF; - descr->cld_gid = gid; - descr->cld_mode = CLM_GROUP; - - enqflags = CEF_MUST | (nonblock ? CEF_NONBLOCK : 0); - descr->cld_enq_flags = enqflags; - - lock = cl_lock_request(env, io, descr, GROUPLOCK_SCOPE, current); - if (IS_ERR(lock)) { - cl_io_fini(env, io); - cl_env_put(env, &refcheck); - return PTR_ERR(lock); - } - - cg->cg_env = cl_env_get(&refcheck); - cg->cg_io = io; - cg->cg_lock = lock; - cg->cg_gid = gid; - LASSERT(cg->cg_env == env); - - cl_env_unplant(env, &refcheck); - return 0; -} - -void cl_put_grouplock(struct ccc_grouplock *cg) -{ - struct lu_env *env = cg->cg_env; - struct cl_io *io = cg->cg_io; - struct cl_lock *lock = cg->cg_lock; - int refcheck; - - LASSERT(cg->cg_env); - LASSERT(cg->cg_gid); - - cl_env_implant(env, &refcheck); - cl_env_put(env, &refcheck); - - cl_unuse(env, lock); - cl_lock_release(env, lock, GROUPLOCK_SCOPE, current); - cl_io_fini(env, io); - cl_env_put(env, NULL); -} diff --git a/drivers/staging/lustre/lustre/llite/Makefile b/drivers/staging/lustre/lustre/llite/Makefile index 9ac29e718da3..24085e2624b4 100644 --- a/drivers/staging/lustre/lustre/llite/Makefile +++ b/drivers/staging/lustre/lustre/llite/Makefile @@ -4,7 +4,7 @@ lustre-y := dcache.o dir.o file.o llite_close.o llite_lib.o llite_nfs.o \ rw.o namei.o symlink.o llite_mmap.o \ xattr.o xattr_cache.o remote_perm.o llite_rmtacl.o \ rw26.o super25.o statahead.o \ - ../lclient/glimpse.o ../lclient/lcommon_cl.o ../lclient/lcommon_misc.o \ + glimpse.o lcommon_cl.o lcommon_misc.o \ vvp_dev.o vvp_page.o vvp_lock.o vvp_io.o vvp_object.o lproc_llite.o llite_lloop-y := lloop.o diff --git a/drivers/staging/lustre/lustre/llite/glimpse.c b/drivers/staging/lustre/lustre/llite/glimpse.c new file mode 100644 index 000000000000..f235f3557e2a --- /dev/null +++ b/drivers/staging/lustre/lustre/llite/glimpse.c @@ -0,0 +1,273 @@ +/* + * GPL HEADER START + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 only, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 for more details (a copy is included + * in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; If not, see + * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + * GPL HEADER END + */ +/* + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Use is subject to license terms. + * + * Copyright (c) 2011, 2012, Intel Corporation. + */ +/* + * This file is part of Lustre, http://www.lustre.org/ + * Lustre is a trademark of Sun Microsystems, Inc. + * + * glimpse code shared between vvp and liblustre (and other Lustre clients in + * the future). + * + * Author: Nikita Danilov + * Author: Oleg Drokin + */ + +#include "../../include/linux/libcfs/libcfs.h" +#include "../include/obd_class.h" +#include "../include/obd_support.h" +#include "../include/obd.h" + +#include "../include/lustre_dlm.h" +#include "../include/lustre_lite.h" +#include "../include/lustre_mdc.h" +#include +#include + +#include "../include/cl_object.h" +#include "../include/lclient.h" +#include "../llite/llite_internal.h" + +static const struct cl_lock_descr whole_file = { + .cld_start = 0, + .cld_end = CL_PAGE_EOF, + .cld_mode = CLM_READ +}; + +/* + * Check whether file has possible unwriten pages. + * + * \retval 1 file is mmap-ed or has dirty pages + * 0 otherwise + */ +blkcnt_t dirty_cnt(struct inode *inode) +{ + blkcnt_t cnt = 0; + struct ccc_object *vob = cl_inode2ccc(inode); + void *results[1]; + + if (inode->i_mapping) + cnt += radix_tree_gang_lookup_tag(&inode->i_mapping->page_tree, + results, 0, 1, + PAGECACHE_TAG_DIRTY); + if (cnt == 0 && atomic_read(&vob->cob_mmap_cnt) > 0) + cnt = 1; + + return (cnt > 0) ? 1 : 0; +} + +int cl_glimpse_lock(const struct lu_env *env, struct cl_io *io, + struct inode *inode, struct cl_object *clob, int agl) +{ + struct cl_lock_descr *descr = &ccc_env_info(env)->cti_descr; + struct cl_inode_info *lli = cl_i2info(inode); + const struct lu_fid *fid = lu_object_fid(&clob->co_lu); + struct ccc_io *cio = ccc_env_io(env); + struct cl_lock *lock; + int result; + + result = 0; + if (!(lli->lli_flags & LLIF_MDS_SIZE_LOCK)) { + CDEBUG(D_DLMTRACE, "Glimpsing inode " DFID "\n", PFID(fid)); + if (lli->lli_has_smd) { + /* NOTE: this looks like DLM lock request, but it may + * not be one. Due to CEF_ASYNC flag (translated + * to LDLM_FL_HAS_INTENT by osc), this is + * glimpse request, that won't revoke any + * conflicting DLM locks held. Instead, + * ll_glimpse_callback() will be called on each + * client holding a DLM lock against this file, + * and resulting size will be returned for each + * stripe. DLM lock on [0, EOF] is acquired only + * if there were no conflicting locks. If there + * were conflicting locks, enqueuing or waiting + * fails with -ENAVAIL, but valid inode + * attributes are returned anyway. + */ + *descr = whole_file; + descr->cld_obj = clob; + descr->cld_mode = CLM_PHANTOM; + descr->cld_enq_flags = CEF_ASYNC | CEF_MUST; + if (agl) + descr->cld_enq_flags |= CEF_AGL; + cio->cui_glimpse = 1; + /* + * CEF_ASYNC is used because glimpse sub-locks cannot + * deadlock (because they never conflict with other + * locks) and, hence, can be enqueued out-of-order. + * + * CEF_MUST protects glimpse lock from conversion into + * a lockless mode. + */ + lock = cl_lock_request(env, io, descr, "glimpse", + current); + cio->cui_glimpse = 0; + + if (!lock) + return 0; + + if (IS_ERR(lock)) + return PTR_ERR(lock); + + LASSERT(agl == 0); + result = cl_wait(env, lock); + if (result == 0) { + cl_merge_lvb(env, inode); + if (cl_isize_read(inode) > 0 && + inode->i_blocks == 0) { + /* + * LU-417: Add dirty pages block count + * lest i_blocks reports 0, some "cp" or + * "tar" may think it's a completely + * sparse file and skip it. + */ + inode->i_blocks = dirty_cnt(inode); + } + cl_unuse(env, lock); + } + cl_lock_release(env, lock, "glimpse", current); + } else { + CDEBUG(D_DLMTRACE, "No objects for inode\n"); + cl_merge_lvb(env, inode); + } + } + + return result; +} + +static int cl_io_get(struct inode *inode, struct lu_env **envout, + struct cl_io **ioout, int *refcheck) +{ + struct lu_env *env; + struct cl_io *io; + struct cl_inode_info *lli = cl_i2info(inode); + struct cl_object *clob = lli->lli_clob; + int result; + + if (S_ISREG(cl_inode_mode(inode))) { + env = cl_env_get(refcheck); + if (!IS_ERR(env)) { + io = ccc_env_thread_io(env); + io->ci_obj = clob; + *envout = env; + *ioout = io; + result = 1; + } else { + result = PTR_ERR(env); + } + } else { + result = 0; + } + return result; +} + +int cl_glimpse_size0(struct inode *inode, int agl) +{ + /* + * We don't need ast_flags argument to cl_glimpse_size(), because + * osc_lock_enqueue() takes care of the possible deadlock that said + * argument was introduced to avoid. + */ + /* + * XXX but note that ll_file_seek() passes LDLM_FL_BLOCK_NOWAIT to + * cl_glimpse_size(), which doesn't make sense: glimpse locks are not + * blocking anyway. + */ + struct lu_env *env = NULL; + struct cl_io *io = NULL; + int result; + int refcheck; + + result = cl_io_get(inode, &env, &io, &refcheck); + if (result > 0) { +again: + io->ci_verify_layout = 1; + result = cl_io_init(env, io, CIT_MISC, io->ci_obj); + if (result > 0) + /* + * nothing to do for this io. This currently happens + * when stripe sub-object's are not yet created. + */ + result = io->ci_result; + else if (result == 0) + result = cl_glimpse_lock(env, io, inode, io->ci_obj, + agl); + + OBD_FAIL_TIMEOUT(OBD_FAIL_GLIMPSE_DELAY, 2); + cl_io_fini(env, io); + if (unlikely(io->ci_need_restart)) + goto again; + cl_env_put(env, &refcheck); + } + return result; +} + +int cl_local_size(struct inode *inode) +{ + struct lu_env *env = NULL; + struct cl_io *io = NULL; + struct ccc_thread_info *cti; + struct cl_object *clob; + struct cl_lock_descr *descr; + struct cl_lock *lock; + int result; + int refcheck; + + if (!cl_i2info(inode)->lli_has_smd) + return 0; + + result = cl_io_get(inode, &env, &io, &refcheck); + if (result <= 0) + return result; + + clob = io->ci_obj; + result = cl_io_init(env, io, CIT_MISC, clob); + if (result > 0) { + result = io->ci_result; + } else if (result == 0) { + cti = ccc_env_info(env); + descr = &cti->cti_descr; + + *descr = whole_file; + descr->cld_obj = clob; + lock = cl_lock_peek(env, io, descr, "localsize", current); + if (lock) { + cl_merge_lvb(env, inode); + cl_unuse(env, lock); + cl_lock_release(env, lock, "localsize", current); + result = 0; + } else { + result = -ENODATA; + } + } + cl_io_fini(env, io); + cl_env_put(env, &refcheck); + return result; +} diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c b/drivers/staging/lustre/lustre/llite/lcommon_cl.c new file mode 100644 index 000000000000..065b0f20e95d --- /dev/null +++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c @@ -0,0 +1,1209 @@ +/* + * GPL HEADER START + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 only, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 for more details (a copy is included + * in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; If not, see + * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + * GPL HEADER END + */ +/* + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Use is subject to license terms. + * + * Copyright (c) 2011, 2015, Intel Corporation. + */ +/* + * This file is part of Lustre, http://www.lustre.org/ + * Lustre is a trademark of Sun Microsystems, Inc. + * + * cl code shared between vvp and liblustre (and other Lustre clients in the + * future). + * + * Author: Nikita Danilov + */ + +#define DEBUG_SUBSYSTEM S_LLITE + +#include "../../include/linux/libcfs/libcfs.h" +# include +# include +# include +# include +# include +# include +# include + +#include "../include/obd.h" +#include "../include/obd_support.h" +#include "../include/lustre_fid.h" +#include "../include/lustre_lite.h" +#include "../include/lustre_dlm.h" +#include "../include/lustre_ver.h" +#include "../include/lustre_mdc.h" +#include "../include/cl_object.h" + +#include "../include/lclient.h" + +#include "../llite/llite_internal.h" + +static const struct cl_req_operations ccc_req_ops; + +/* + * ccc_ prefix stands for "Common Client Code". + */ + +static struct kmem_cache *ccc_lock_kmem; +static struct kmem_cache *ccc_object_kmem; +static struct kmem_cache *ccc_thread_kmem; +static struct kmem_cache *ccc_session_kmem; +static struct kmem_cache *ccc_req_kmem; + +static struct lu_kmem_descr ccc_caches[] = { + { + .ckd_cache = &ccc_lock_kmem, + .ckd_name = "ccc_lock_kmem", + .ckd_size = sizeof(struct ccc_lock) + }, + { + .ckd_cache = &ccc_object_kmem, + .ckd_name = "ccc_object_kmem", + .ckd_size = sizeof(struct ccc_object) + }, + { + .ckd_cache = &ccc_thread_kmem, + .ckd_name = "ccc_thread_kmem", + .ckd_size = sizeof(struct ccc_thread_info), + }, + { + .ckd_cache = &ccc_session_kmem, + .ckd_name = "ccc_session_kmem", + .ckd_size = sizeof(struct ccc_session) + }, + { + .ckd_cache = &ccc_req_kmem, + .ckd_name = "ccc_req_kmem", + .ckd_size = sizeof(struct ccc_req) + }, + { + .ckd_cache = NULL + } +}; + +/***************************************************************************** + * + * Vvp device and device type functions. + * + */ + +void *ccc_key_init(const struct lu_context *ctx, struct lu_context_key *key) +{ + struct ccc_thread_info *info; + + info = kmem_cache_zalloc(ccc_thread_kmem, GFP_NOFS); + if (!info) + info = ERR_PTR(-ENOMEM); + return info; +} + +void ccc_key_fini(const struct lu_context *ctx, + struct lu_context_key *key, void *data) +{ + struct ccc_thread_info *info = data; + + kmem_cache_free(ccc_thread_kmem, info); +} + +void *ccc_session_key_init(const struct lu_context *ctx, + struct lu_context_key *key) +{ + struct ccc_session *session; + + session = kmem_cache_zalloc(ccc_session_kmem, GFP_NOFS); + if (!session) + session = ERR_PTR(-ENOMEM); + return session; +} + +void ccc_session_key_fini(const struct lu_context *ctx, + struct lu_context_key *key, void *data) +{ + struct ccc_session *session = data; + + kmem_cache_free(ccc_session_kmem, session); +} + +struct lu_context_key ccc_key = { + .lct_tags = LCT_CL_THREAD, + .lct_init = ccc_key_init, + .lct_fini = ccc_key_fini +}; + +struct lu_context_key ccc_session_key = { + .lct_tags = LCT_SESSION, + .lct_init = ccc_session_key_init, + .lct_fini = ccc_session_key_fini +}; + +/* type constructor/destructor: ccc_type_{init,fini,start,stop}(). */ +/* LU_TYPE_INIT_FINI(ccc, &ccc_key, &ccc_session_key); */ + +int ccc_device_init(const struct lu_env *env, struct lu_device *d, + const char *name, struct lu_device *next) +{ + struct ccc_device *vdv; + int rc; + + vdv = lu2ccc_dev(d); + vdv->cdv_next = lu2cl_dev(next); + + LASSERT(d->ld_site && next->ld_type); + next->ld_site = d->ld_site; + rc = next->ld_type->ldt_ops->ldto_device_init( + env, next, next->ld_type->ldt_name, NULL); + if (rc == 0) { + lu_device_get(next); + lu_ref_add(&next->ld_reference, "lu-stack", &lu_site_init); + } + return rc; +} + +struct lu_device *ccc_device_fini(const struct lu_env *env, + struct lu_device *d) +{ + return cl2lu_dev(lu2ccc_dev(d)->cdv_next); +} + +struct lu_device *ccc_device_alloc(const struct lu_env *env, + struct lu_device_type *t, + struct lustre_cfg *cfg, + const struct lu_device_operations *luops, + const struct cl_device_operations *clops) +{ + struct ccc_device *vdv; + struct lu_device *lud; + struct cl_site *site; + int rc; + + vdv = kzalloc(sizeof(*vdv), GFP_NOFS); + if (!vdv) + return ERR_PTR(-ENOMEM); + + lud = &vdv->cdv_cl.cd_lu_dev; + cl_device_init(&vdv->cdv_cl, t); + ccc2lu_dev(vdv)->ld_ops = luops; + vdv->cdv_cl.cd_ops = clops; + + site = kzalloc(sizeof(*site), GFP_NOFS); + if (site) { + rc = cl_site_init(site, &vdv->cdv_cl); + if (rc == 0) { + rc = lu_site_init_finish(&site->cs_lu); + } else { + LASSERT(!lud->ld_site); + CERROR("Cannot init lu_site, rc %d.\n", rc); + kfree(site); + } + } else { + rc = -ENOMEM; + } + if (rc != 0) { + ccc_device_free(env, lud); + lud = ERR_PTR(rc); + } + return lud; +} + +struct lu_device *ccc_device_free(const struct lu_env *env, + struct lu_device *d) +{ + struct ccc_device *vdv = lu2ccc_dev(d); + struct cl_site *site = lu2cl_site(d->ld_site); + struct lu_device *next = cl2lu_dev(vdv->cdv_next); + + if (d->ld_site) { + cl_site_fini(site); + kfree(site); + } + cl_device_fini(lu2cl_dev(d)); + kfree(vdv); + return next; +} + +int ccc_req_init(const struct lu_env *env, struct cl_device *dev, + struct cl_req *req) +{ + struct ccc_req *vrq; + int result; + + vrq = kmem_cache_zalloc(ccc_req_kmem, GFP_NOFS); + if (vrq) { + cl_req_slice_add(req, &vrq->crq_cl, dev, &ccc_req_ops); + result = 0; + } else { + result = -ENOMEM; + } + return result; +} + +/** + * An `emergency' environment used by ccc_inode_fini() when cl_env_get() + * fails. Access to this environment is serialized by ccc_inode_fini_guard + * mutex. + */ +static struct lu_env *ccc_inode_fini_env; + +/** + * A mutex serializing calls to slp_inode_fini() under extreme memory + * pressure, when environments cannot be allocated. + */ +static DEFINE_MUTEX(ccc_inode_fini_guard); +static int dummy_refcheck; + +int ccc_global_init(struct lu_device_type *device_type) +{ + int result; + + result = lu_kmem_init(ccc_caches); + if (result) + return result; + + result = lu_device_type_init(device_type); + if (result) + goto out_kmem; + + ccc_inode_fini_env = cl_env_alloc(&dummy_refcheck, + LCT_REMEMBER | LCT_NOREF); + if (IS_ERR(ccc_inode_fini_env)) { + result = PTR_ERR(ccc_inode_fini_env); + goto out_device; + } + + ccc_inode_fini_env->le_ctx.lc_cookie = 0x4; + return 0; +out_device: + lu_device_type_fini(device_type); +out_kmem: + lu_kmem_fini(ccc_caches); + return result; +} + +void ccc_global_fini(struct lu_device_type *device_type) +{ + if (ccc_inode_fini_env) { + cl_env_put(ccc_inode_fini_env, &dummy_refcheck); + ccc_inode_fini_env = NULL; + } + lu_device_type_fini(device_type); + lu_kmem_fini(ccc_caches); +} + +/***************************************************************************** + * + * Object operations. + * + */ + +struct lu_object *ccc_object_alloc(const struct lu_env *env, + const struct lu_object_header *unused, + struct lu_device *dev, + const struct cl_object_operations *clops, + const struct lu_object_operations *luops) +{ + struct ccc_object *vob; + struct lu_object *obj; + + vob = kmem_cache_zalloc(ccc_object_kmem, GFP_NOFS); + if (vob) { + struct cl_object_header *hdr; + + obj = ccc2lu(vob); + hdr = &vob->cob_header; + cl_object_header_init(hdr); + lu_object_init(obj, &hdr->coh_lu, dev); + lu_object_add_top(&hdr->coh_lu, obj); + + vob->cob_cl.co_ops = clops; + obj->lo_ops = luops; + } else { + obj = NULL; + } + return obj; +} + +int ccc_object_init0(const struct lu_env *env, + struct ccc_object *vob, + const struct cl_object_conf *conf) +{ + vob->cob_inode = conf->coc_inode; + vob->cob_transient_pages = 0; + cl_object_page_init(&vob->cob_cl, sizeof(struct ccc_page)); + return 0; +} + +int ccc_object_init(const struct lu_env *env, struct lu_object *obj, + const struct lu_object_conf *conf) +{ + struct ccc_device *dev = lu2ccc_dev(obj->lo_dev); + struct ccc_object *vob = lu2ccc(obj); + struct lu_object *below; + struct lu_device *under; + int result; + + under = &dev->cdv_next->cd_lu_dev; + below = under->ld_ops->ldo_object_alloc(env, obj->lo_header, under); + if (below) { + const struct cl_object_conf *cconf; + + cconf = lu2cl_conf(conf); + INIT_LIST_HEAD(&vob->cob_pending_list); + lu_object_add(obj, below); + result = ccc_object_init0(env, vob, cconf); + } else { + result = -ENOMEM; + } + return result; +} + +void ccc_object_free(const struct lu_env *env, struct lu_object *obj) +{ + struct ccc_object *vob = lu2ccc(obj); + + lu_object_fini(obj); + lu_object_header_fini(obj->lo_header); + kmem_cache_free(ccc_object_kmem, vob); +} + +int ccc_lock_init(const struct lu_env *env, + struct cl_object *obj, struct cl_lock *lock, + const struct cl_io *unused, + const struct cl_lock_operations *lkops) +{ + struct ccc_lock *clk; + int result; + + CLOBINVRNT(env, obj, ccc_object_invariant(obj)); + + clk = kmem_cache_zalloc(ccc_lock_kmem, GFP_NOFS); + if (clk) { + cl_lock_slice_add(lock, &clk->clk_cl, obj, lkops); + result = 0; + } else { + result = -ENOMEM; + } + return result; +} + +int ccc_object_glimpse(const struct lu_env *env, + const struct cl_object *obj, struct ost_lvb *lvb) +{ + struct inode *inode = ccc_object_inode(obj); + + lvb->lvb_mtime = cl_inode_mtime(inode); + lvb->lvb_atime = cl_inode_atime(inode); + lvb->lvb_ctime = cl_inode_ctime(inode); + /* + * LU-417: Add dirty pages block count lest i_blocks reports 0, some + * "cp" or "tar" on remote node may think it's a completely sparse file + * and skip it. + */ + if (lvb->lvb_size > 0 && lvb->lvb_blocks == 0) + lvb->lvb_blocks = dirty_cnt(inode); + return 0; +} + +static void ccc_object_size_lock(struct cl_object *obj) +{ + struct inode *inode = ccc_object_inode(obj); + + ll_inode_size_lock(inode); + cl_object_attr_lock(obj); +} + +static void ccc_object_size_unlock(struct cl_object *obj) +{ + struct inode *inode = ccc_object_inode(obj); + + cl_object_attr_unlock(obj); + ll_inode_size_unlock(inode); +} + +/***************************************************************************** + * + * Page operations. + * + */ + +struct page *ccc_page_vmpage(const struct lu_env *env, + const struct cl_page_slice *slice) +{ + return cl2vm_page(slice); +} + +int ccc_page_is_under_lock(const struct lu_env *env, + const struct cl_page_slice *slice, + struct cl_io *io) +{ + struct ccc_io *cio = ccc_env_io(env); + struct cl_lock_descr *desc = &ccc_env_info(env)->cti_descr; + struct cl_page *page = slice->cpl_page; + + int result; + + if (io->ci_type == CIT_READ || io->ci_type == CIT_WRITE || + io->ci_type == CIT_FAULT) { + if (cio->cui_fd->fd_flags & LL_FILE_GROUP_LOCKED) { + result = -EBUSY; + } else { + desc->cld_start = page->cp_index; + desc->cld_end = page->cp_index; + desc->cld_obj = page->cp_obj; + desc->cld_mode = CLM_READ; + result = cl_queue_match(&io->ci_lockset.cls_done, + desc) ? -EBUSY : 0; + } + } else { + result = 0; + } + return result; +} + +int ccc_fail(const struct lu_env *env, const struct cl_page_slice *slice) +{ + /* + * Cached read? + */ + LBUG(); + return 0; +} + +int ccc_transient_page_prep(const struct lu_env *env, + const struct cl_page_slice *slice, + struct cl_io *unused) +{ + /* transient page should always be sent. */ + return 0; +} + +/***************************************************************************** + * + * Lock operations. + * + */ + +void ccc_lock_delete(const struct lu_env *env, + const struct cl_lock_slice *slice) +{ + CLOBINVRNT(env, slice->cls_obj, ccc_object_invariant(slice->cls_obj)); +} + +void ccc_lock_fini(const struct lu_env *env, struct cl_lock_slice *slice) +{ + struct ccc_lock *clk = cl2ccc_lock(slice); + + kmem_cache_free(ccc_lock_kmem, clk); +} + +int ccc_lock_enqueue(const struct lu_env *env, + const struct cl_lock_slice *slice, + struct cl_io *unused, __u32 enqflags) +{ + CLOBINVRNT(env, slice->cls_obj, ccc_object_invariant(slice->cls_obj)); + return 0; +} + +int ccc_lock_use(const struct lu_env *env, const struct cl_lock_slice *slice) +{ + CLOBINVRNT(env, slice->cls_obj, ccc_object_invariant(slice->cls_obj)); + return 0; +} + +int ccc_lock_unuse(const struct lu_env *env, const struct cl_lock_slice *slice) +{ + CLOBINVRNT(env, slice->cls_obj, ccc_object_invariant(slice->cls_obj)); + return 0; +} + +int ccc_lock_wait(const struct lu_env *env, const struct cl_lock_slice *slice) +{ + CLOBINVRNT(env, slice->cls_obj, ccc_object_invariant(slice->cls_obj)); + return 0; +} + +/** + * Implementation of cl_lock_operations::clo_fits_into() methods for ccc + * layer. This function is executed every time io finds an existing lock in + * the lock cache while creating new lock. This function has to decide whether + * cached lock "fits" into io. + * + * \param slice lock to be checked + * \param io IO that wants a lock. + * + * \see lov_lock_fits_into(). + */ +int ccc_lock_fits_into(const struct lu_env *env, + const struct cl_lock_slice *slice, + const struct cl_lock_descr *need, + const struct cl_io *io) +{ + const struct cl_lock *lock = slice->cls_lock; + const struct cl_lock_descr *descr = &lock->cll_descr; + const struct ccc_io *cio = ccc_env_io(env); + int result; + + /* + * Work around DLM peculiarity: it assumes that glimpse + * (LDLM_FL_HAS_INTENT) lock is always LCK_PR, and returns reads lock + * when asked for LCK_PW lock with LDLM_FL_HAS_INTENT flag set. Make + * sure that glimpse doesn't get CLM_WRITE top-lock, so that it + * doesn't enqueue CLM_WRITE sub-locks. + */ + if (cio->cui_glimpse) + result = descr->cld_mode != CLM_WRITE; + + /* + * Also, don't match incomplete write locks for read, otherwise read + * would enqueue missing sub-locks in the write mode. + */ + else if (need->cld_mode != descr->cld_mode) + result = lock->cll_state >= CLS_ENQUEUED; + else + result = 1; + return result; +} + +/** + * Implements cl_lock_operations::clo_state() method for ccc layer, invoked + * whenever lock state changes. Transfers object attributes, that might be + * updated as a result of lock acquiring into inode. + */ +void ccc_lock_state(const struct lu_env *env, + const struct cl_lock_slice *slice, + enum cl_lock_state state) +{ + struct cl_lock *lock = slice->cls_lock; + + /* + * Refresh inode attributes when the lock is moving into CLS_HELD + * state, and only when this is a result of real enqueue, rather than + * of finding lock in the cache. + */ + if (state == CLS_HELD && lock->cll_state < CLS_HELD) { + struct cl_object *obj; + struct inode *inode; + + obj = slice->cls_obj; + inode = ccc_object_inode(obj); + + /* vmtruncate() sets the i_size + * under both a DLM lock and the + * ll_inode_size_lock(). If we don't get the + * ll_inode_size_lock() here we can match the DLM lock and + * reset i_size. generic_file_write can then trust the + * stale i_size when doing appending writes and effectively + * cancel the result of the truncate. Getting the + * ll_inode_size_lock() after the enqueue maintains the DLM + * -> ll_inode_size_lock() acquiring order. + */ + if (lock->cll_descr.cld_start == 0 && + lock->cll_descr.cld_end == CL_PAGE_EOF) + cl_merge_lvb(env, inode); + } +} + +/***************************************************************************** + * + * io operations. + * + */ + +int ccc_io_one_lock_index(const struct lu_env *env, struct cl_io *io, + __u32 enqflags, enum cl_lock_mode mode, + pgoff_t start, pgoff_t end) +{ + struct ccc_io *cio = ccc_env_io(env); + struct cl_lock_descr *descr = &cio->cui_link.cill_descr; + struct cl_object *obj = io->ci_obj; + + CLOBINVRNT(env, obj, ccc_object_invariant(obj)); + + CDEBUG(D_VFSTRACE, "lock: %d [%lu, %lu]\n", mode, start, end); + + memset(&cio->cui_link, 0, sizeof(cio->cui_link)); + + if (cio->cui_fd && (cio->cui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) { + descr->cld_mode = CLM_GROUP; + descr->cld_gid = cio->cui_fd->fd_grouplock.cg_gid; + } else { + descr->cld_mode = mode; + } + descr->cld_obj = obj; + descr->cld_start = start; + descr->cld_end = end; + descr->cld_enq_flags = enqflags; + + cl_io_lock_add(env, io, &cio->cui_link); + return 0; +} + +void ccc_io_update_iov(const struct lu_env *env, + struct ccc_io *cio, struct cl_io *io) +{ + size_t size = io->u.ci_rw.crw_count; + + if (!cl_is_normalio(env, io) || !cio->cui_iter) + return; + + iov_iter_truncate(cio->cui_iter, size); +} + +int ccc_io_one_lock(const struct lu_env *env, struct cl_io *io, + __u32 enqflags, enum cl_lock_mode mode, + loff_t start, loff_t end) +{ + struct cl_object *obj = io->ci_obj; + + return ccc_io_one_lock_index(env, io, enqflags, mode, + cl_index(obj, start), cl_index(obj, end)); +} + +void ccc_io_end(const struct lu_env *env, const struct cl_io_slice *ios) +{ + CLOBINVRNT(env, ios->cis_io->ci_obj, + ccc_object_invariant(ios->cis_io->ci_obj)); +} + +void ccc_io_advance(const struct lu_env *env, + const struct cl_io_slice *ios, + size_t nob) +{ + struct ccc_io *cio = cl2ccc_io(env, ios); + struct cl_io *io = ios->cis_io; + struct cl_object *obj = ios->cis_io->ci_obj; + + CLOBINVRNT(env, obj, ccc_object_invariant(obj)); + + if (!cl_is_normalio(env, io)) + return; + + iov_iter_reexpand(cio->cui_iter, cio->cui_tot_count -= nob); +} + +/** + * Helper function that if necessary adjusts file size (inode->i_size), when + * position at the offset \a pos is accessed. File size can be arbitrary stale + * on a Lustre client, but client at least knows KMS. If accessed area is + * inside [0, KMS], set file size to KMS, otherwise glimpse file size. + * + * Locking: cl_isize_lock is used to serialize changes to inode size and to + * protect consistency between inode size and cl_object + * attributes. cl_object_size_lock() protects consistency between cl_attr's of + * top-object and sub-objects. + */ +int ccc_prep_size(const struct lu_env *env, struct cl_object *obj, + struct cl_io *io, loff_t start, size_t count, int *exceed) +{ + struct cl_attr *attr = ccc_env_thread_attr(env); + struct inode *inode = ccc_object_inode(obj); + loff_t pos = start + count - 1; + loff_t kms; + int result; + + /* + * Consistency guarantees: following possibilities exist for the + * relation between region being accessed and real file size at this + * moment: + * + * (A): the region is completely inside of the file; + * + * (B-x): x bytes of region are inside of the file, the rest is + * outside; + * + * (C): the region is completely outside of the file. + * + * This classification is stable under DLM lock already acquired by + * the caller, because to change the class, other client has to take + * DLM lock conflicting with our lock. Also, any updates to ->i_size + * by other threads on this client are serialized by + * ll_inode_size_lock(). This guarantees that short reads are handled + * correctly in the face of concurrent writes and truncates. + */ + ccc_object_size_lock(obj); + result = cl_object_attr_get(env, obj, attr); + if (result == 0) { + kms = attr->cat_kms; + if (pos > kms) { + /* + * A glimpse is necessary to determine whether we + * return a short read (B) or some zeroes at the end + * of the buffer (C) + */ + ccc_object_size_unlock(obj); + result = cl_glimpse_lock(env, io, inode, obj, 0); + if (result == 0 && exceed) { + /* If objective page index exceed end-of-file + * page index, return directly. Do not expect + * kernel will check such case correctly. + * linux-2.6.18-128.1.1 miss to do that. + * --bug 17336 + */ + loff_t size = cl_isize_read(inode); + loff_t cur_index = start >> PAGE_CACHE_SHIFT; + loff_t size_index = (size - 1) >> + PAGE_CACHE_SHIFT; + + if ((size == 0 && cur_index != 0) || + size_index < cur_index) + *exceed = 1; + } + return result; + } + /* + * region is within kms and, hence, within real file + * size (A). We need to increase i_size to cover the + * read region so that generic_file_read() will do its + * job, but that doesn't mean the kms size is + * _correct_, it is only the _minimum_ size. If + * someone does a stat they will get the correct size + * which will always be >= the kms value here. + * b=11081 + */ + if (cl_isize_read(inode) < kms) { + cl_isize_write_nolock(inode, kms); + CDEBUG(D_VFSTRACE, DFID " updating i_size %llu\n", + PFID(lu_object_fid(&obj->co_lu)), + (__u64)cl_isize_read(inode)); + } + } + ccc_object_size_unlock(obj); + return result; +} + +/***************************************************************************** + * + * Transfer operations. + * + */ + +void ccc_req_completion(const struct lu_env *env, + const struct cl_req_slice *slice, int ioret) +{ + struct ccc_req *vrq; + + if (ioret > 0) + cl_stats_tally(slice->crs_dev, slice->crs_req->crq_type, ioret); + + vrq = cl2ccc_req(slice); + kmem_cache_free(ccc_req_kmem, vrq); +} + +/** + * Implementation of struct cl_req_operations::cro_attr_set() for ccc + * layer. ccc is responsible for + * + * - o_[mac]time + * + * - o_mode + * + * - o_parent_seq + * + * - o_[ug]id + * + * - o_parent_oid + * + * - o_parent_ver + * + * - o_ioepoch, + * + */ +void ccc_req_attr_set(const struct lu_env *env, + const struct cl_req_slice *slice, + const struct cl_object *obj, + struct cl_req_attr *attr, u64 flags) +{ + struct inode *inode; + struct obdo *oa; + u32 valid_flags; + + oa = attr->cra_oa; + inode = ccc_object_inode(obj); + valid_flags = OBD_MD_FLTYPE; + + if (slice->crs_req->crq_type == CRT_WRITE) { + if (flags & OBD_MD_FLEPOCH) { + oa->o_valid |= OBD_MD_FLEPOCH; + oa->o_ioepoch = cl_i2info(inode)->lli_ioepoch; + valid_flags |= OBD_MD_FLMTIME | OBD_MD_FLCTIME | + OBD_MD_FLUID | OBD_MD_FLGID; + } + } + obdo_from_inode(oa, inode, valid_flags & flags); + obdo_set_parent_fid(oa, &cl_i2info(inode)->lli_fid); + memcpy(attr->cra_jobid, cl_i2info(inode)->lli_jobid, + JOBSTATS_JOBID_SIZE); +} + +static const struct cl_req_operations ccc_req_ops = { + .cro_attr_set = ccc_req_attr_set, + .cro_completion = ccc_req_completion +}; + +int cl_setattr_ost(struct inode *inode, const struct iattr *attr) +{ + struct lu_env *env; + struct cl_io *io; + int result; + int refcheck; + + env = cl_env_get(&refcheck); + if (IS_ERR(env)) + return PTR_ERR(env); + + io = ccc_env_thread_io(env); + io->ci_obj = cl_i2info(inode)->lli_clob; + + io->u.ci_setattr.sa_attr.lvb_atime = LTIME_S(attr->ia_atime); + io->u.ci_setattr.sa_attr.lvb_mtime = LTIME_S(attr->ia_mtime); + io->u.ci_setattr.sa_attr.lvb_ctime = LTIME_S(attr->ia_ctime); + io->u.ci_setattr.sa_attr.lvb_size = attr->ia_size; + io->u.ci_setattr.sa_valid = attr->ia_valid; + +again: + if (cl_io_init(env, io, CIT_SETATTR, io->ci_obj) == 0) { + struct ccc_io *cio = ccc_env_io(env); + + if (attr->ia_valid & ATTR_FILE) + /* populate the file descriptor for ftruncate to honor + * group lock - see LU-787 + */ + cio->cui_fd = cl_iattr2fd(inode, attr); + + result = cl_io_loop(env, io); + } else { + result = io->ci_result; + } + cl_io_fini(env, io); + if (unlikely(io->ci_need_restart)) + goto again; + /* HSM import case: file is released, cannot be restored + * no need to fail except if restore registration failed + * with -ENODATA + */ + if (result == -ENODATA && io->ci_restore_needed && + io->ci_result != -ENODATA) + result = 0; + cl_env_put(env, &refcheck); + return result; +} + +/***************************************************************************** + * + * Type conversions. + * + */ + +struct lu_device *ccc2lu_dev(struct ccc_device *vdv) +{ + return &vdv->cdv_cl.cd_lu_dev; +} + +struct ccc_device *lu2ccc_dev(const struct lu_device *d) +{ + return container_of0(d, struct ccc_device, cdv_cl.cd_lu_dev); +} + +struct ccc_device *cl2ccc_dev(const struct cl_device *d) +{ + return container_of0(d, struct ccc_device, cdv_cl); +} + +struct lu_object *ccc2lu(struct ccc_object *vob) +{ + return &vob->cob_cl.co_lu; +} + +struct ccc_object *lu2ccc(const struct lu_object *obj) +{ + return container_of0(obj, struct ccc_object, cob_cl.co_lu); +} + +struct ccc_object *cl2ccc(const struct cl_object *obj) +{ + return container_of0(obj, struct ccc_object, cob_cl); +} + +struct ccc_lock *cl2ccc_lock(const struct cl_lock_slice *slice) +{ + return container_of(slice, struct ccc_lock, clk_cl); +} + +struct ccc_io *cl2ccc_io(const struct lu_env *env, + const struct cl_io_slice *slice) +{ + struct ccc_io *cio; + + cio = container_of(slice, struct ccc_io, cui_cl); + LASSERT(cio == ccc_env_io(env)); + return cio; +} + +struct ccc_req *cl2ccc_req(const struct cl_req_slice *slice) +{ + return container_of0(slice, struct ccc_req, crq_cl); +} + +struct page *cl2vm_page(const struct cl_page_slice *slice) +{ + return cl2ccc_page(slice)->cpg_page; +} + +/***************************************************************************** + * + * Accessors. + * + */ +int ccc_object_invariant(const struct cl_object *obj) +{ + struct inode *inode = ccc_object_inode(obj); + struct cl_inode_info *lli = cl_i2info(inode); + + return (S_ISREG(cl_inode_mode(inode)) || + /* i_mode of unlinked inode is zeroed. */ + cl_inode_mode(inode) == 0) && lli->lli_clob == obj; +} + +struct inode *ccc_object_inode(const struct cl_object *obj) +{ + return cl2ccc(obj)->cob_inode; +} + +/** + * Initialize or update CLIO structures for regular files when new + * meta-data arrives from the server. + * + * \param inode regular file inode + * \param md new file metadata from MDS + * - allocates cl_object if necessary, + * - updated layout, if object was already here. + */ +int cl_file_inode_init(struct inode *inode, struct lustre_md *md) +{ + struct lu_env *env; + struct cl_inode_info *lli; + struct cl_object *clob; + struct lu_site *site; + struct lu_fid *fid; + struct cl_object_conf conf = { + .coc_inode = inode, + .u = { + .coc_md = md + } + }; + int result = 0; + int refcheck; + + LASSERT(md->body->valid & OBD_MD_FLID); + LASSERT(S_ISREG(cl_inode_mode(inode))); + + env = cl_env_get(&refcheck); + if (IS_ERR(env)) + return PTR_ERR(env); + + site = cl_i2sbi(inode)->ll_site; + lli = cl_i2info(inode); + fid = &lli->lli_fid; + LASSERT(fid_is_sane(fid)); + + if (!lli->lli_clob) { + /* clob is slave of inode, empty lli_clob means for new inode, + * there is no clob in cache with the given fid, so it is + * unnecessary to perform lookup-alloc-lookup-insert, just + * alloc and insert directly. + */ + LASSERT(inode->i_state & I_NEW); + conf.coc_lu.loc_flags = LOC_F_NEW; + clob = cl_object_find(env, lu2cl_dev(site->ls_top_dev), + fid, &conf); + if (!IS_ERR(clob)) { + /* + * No locking is necessary, as new inode is + * locked by I_NEW bit. + */ + lli->lli_clob = clob; + lli->lli_has_smd = lsm_has_objects(md->lsm); + lu_object_ref_add(&clob->co_lu, "inode", inode); + } else { + result = PTR_ERR(clob); + } + } else { + result = cl_conf_set(env, lli->lli_clob, &conf); + } + + cl_env_put(env, &refcheck); + + if (result != 0) + CERROR("Failure to initialize cl object " DFID ": %d\n", + PFID(fid), result); + return result; +} + +/** + * Wait for others drop their references of the object at first, then we drop + * the last one, which will lead to the object be destroyed immediately. + * Must be called after cl_object_kill() against this object. + * + * The reason we want to do this is: destroying top object will wait for sub + * objects being destroyed first, so we can't let bottom layer (e.g. from ASTs) + * to initiate top object destroying which may deadlock. See bz22520. + */ +static void cl_object_put_last(struct lu_env *env, struct cl_object *obj) +{ + struct lu_object_header *header = obj->co_lu.lo_header; + wait_queue_t waiter; + + if (unlikely(atomic_read(&header->loh_ref) != 1)) { + struct lu_site *site = obj->co_lu.lo_dev->ld_site; + struct lu_site_bkt_data *bkt; + + bkt = lu_site_bkt_from_fid(site, &header->loh_fid); + + init_waitqueue_entry(&waiter, current); + add_wait_queue(&bkt->lsb_marche_funebre, &waiter); + + while (1) { + set_current_state(TASK_UNINTERRUPTIBLE); + if (atomic_read(&header->loh_ref) == 1) + break; + schedule(); + } + + set_current_state(TASK_RUNNING); + remove_wait_queue(&bkt->lsb_marche_funebre, &waiter); + } + + cl_object_put(env, obj); +} + +void cl_inode_fini(struct inode *inode) +{ + struct lu_env *env; + struct cl_inode_info *lli = cl_i2info(inode); + struct cl_object *clob = lli->lli_clob; + int refcheck; + int emergency; + + if (clob) { + void *cookie; + + cookie = cl_env_reenter(); + env = cl_env_get(&refcheck); + emergency = IS_ERR(env); + if (emergency) { + mutex_lock(&ccc_inode_fini_guard); + LASSERT(ccc_inode_fini_env); + cl_env_implant(ccc_inode_fini_env, &refcheck); + env = ccc_inode_fini_env; + } + /* + * cl_object cache is a slave to inode cache (which, in turn + * is a slave to dentry cache), don't keep cl_object in memory + * when its master is evicted. + */ + cl_object_kill(env, clob); + lu_object_ref_del(&clob->co_lu, "inode", inode); + cl_object_put_last(env, clob); + lli->lli_clob = NULL; + if (emergency) { + cl_env_unplant(ccc_inode_fini_env, &refcheck); + mutex_unlock(&ccc_inode_fini_guard); + } else { + cl_env_put(env, &refcheck); + } + cl_env_reexit(cookie); + } +} + +/** + * return IF_* type for given lu_dirent entry. + * IF_* flag shld be converted to particular OS file type in + * platform llite module. + */ +__u16 ll_dirent_type_get(struct lu_dirent *ent) +{ + __u16 type = 0; + struct luda_type *lt; + int len = 0; + + if (le32_to_cpu(ent->lde_attrs) & LUDA_TYPE) { + const unsigned int align = sizeof(struct luda_type) - 1; + + len = le16_to_cpu(ent->lde_namelen); + len = (len + align) & ~align; + lt = (void *)ent->lde_name + len; + type = IFTODT(le16_to_cpu(lt->lt_type)); + } + return type; +} + +/** + * build inode number from passed @fid + */ +__u64 cl_fid_build_ino(const struct lu_fid *fid, int api32) +{ + if (BITS_PER_LONG == 32 || api32) + return fid_flatten32(fid); + else + return fid_flatten(fid); +} + +/** + * build inode generation from passed @fid. If our FID overflows the 32-bit + * inode number then return a non-zero generation to distinguish them. + */ +__u32 cl_fid_build_gen(const struct lu_fid *fid) +{ + __u32 gen; + + if (fid_is_igif(fid)) { + gen = lu_igif_gen(fid); + return gen; + } + + gen = fid_flatten(fid) >> 32; + return gen; +} + +/* lsm is unreliable after hsm implementation as layout can be changed at + * any time. This is only to support old, non-clio-ized interfaces. It will + * cause deadlock if clio operations are called with this extra layout refcount + * because in case the layout changed during the IO, ll_layout_refresh() will + * have to wait for the refcount to become zero to destroy the older layout. + * + * Notice that the lsm returned by this function may not be valid unless called + * inside layout lock - MDS_INODELOCK_LAYOUT. + */ +struct lov_stripe_md *ccc_inode_lsm_get(struct inode *inode) +{ + return lov_lsm_get(cl_i2info(inode)->lli_clob); +} + +inline void ccc_inode_lsm_put(struct inode *inode, struct lov_stripe_md *lsm) +{ + lov_lsm_put(cl_i2info(inode)->lli_clob, lsm); +} diff --git a/drivers/staging/lustre/lustre/llite/lcommon_misc.c b/drivers/staging/lustre/lustre/llite/lcommon_misc.c new file mode 100644 index 000000000000..d80bcedd78d1 --- /dev/null +++ b/drivers/staging/lustre/lustre/llite/lcommon_misc.c @@ -0,0 +1,200 @@ +/* + * GPL HEADER START + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 only, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 for more details (a copy is included + * in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; If not, see + * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + * GPL HEADER END + */ +/* + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Use is subject to license terms. + * + * Copyright (c) 2011, 2012, Intel Corporation. + */ +/* + * This file is part of Lustre, http://www.lustre.org/ + * Lustre is a trademark of Sun Microsystems, Inc. + * + * cl code shared between vvp and liblustre (and other Lustre clients in the + * future). + * + */ +#include "../include/obd_class.h" +#include "../include/obd_support.h" +#include "../include/obd.h" +#include "../include/cl_object.h" +#include "../include/lclient.h" + +#include "../include/lustre_lite.h" + +/* Initialize the default and maximum LOV EA and cookie sizes. This allows + * us to make MDS RPCs with large enough reply buffers to hold the + * maximum-sized (= maximum striped) EA and cookie without having to + * calculate this (via a call into the LOV + OSCs) each time we make an RPC. + */ +int cl_init_ea_size(struct obd_export *md_exp, struct obd_export *dt_exp) +{ + struct lov_stripe_md lsm = { .lsm_magic = LOV_MAGIC_V3 }; + __u32 valsize = sizeof(struct lov_desc); + int rc, easize, def_easize, cookiesize; + struct lov_desc desc; + __u16 stripes, def_stripes; + + rc = obd_get_info(NULL, dt_exp, sizeof(KEY_LOVDESC), KEY_LOVDESC, + &valsize, &desc, NULL); + if (rc) + return rc; + + stripes = min_t(__u32, desc.ld_tgt_count, LOV_MAX_STRIPE_COUNT); + lsm.lsm_stripe_count = stripes; + easize = obd_size_diskmd(dt_exp, &lsm); + + def_stripes = min_t(__u32, desc.ld_default_stripe_count, + LOV_MAX_STRIPE_COUNT); + lsm.lsm_stripe_count = def_stripes; + def_easize = obd_size_diskmd(dt_exp, &lsm); + + cookiesize = stripes * sizeof(struct llog_cookie); + + /* default cookiesize is 0 because from 2.4 server doesn't send + * llog cookies to client. + */ + CDEBUG(D_HA, + "updating def/max_easize: %d/%d def/max_cookiesize: 0/%d\n", + def_easize, easize, cookiesize); + + rc = md_init_ea_size(md_exp, easize, def_easize, cookiesize, 0); + return rc; +} + +/** + * This function is used as an upcall-callback hooked by liblustre and llite + * clients into obd_notify() listeners chain to handle notifications about + * change of import connect_flags. See llu_fsswop_mount() and + * lustre_common_fill_super(). + */ +int cl_ocd_update(struct obd_device *host, + struct obd_device *watched, + enum obd_notify_event ev, void *owner, void *data) +{ + struct lustre_client_ocd *lco; + struct client_obd *cli; + __u64 flags; + int result; + + if (!strcmp(watched->obd_type->typ_name, LUSTRE_OSC_NAME)) { + cli = &watched->u.cli; + lco = owner; + flags = cli->cl_import->imp_connect_data.ocd_connect_flags; + CDEBUG(D_SUPER, "Changing connect_flags: %#llx -> %#llx\n", + lco->lco_flags, flags); + mutex_lock(&lco->lco_lock); + lco->lco_flags &= flags; + /* for each osc event update ea size */ + if (lco->lco_dt_exp) + cl_init_ea_size(lco->lco_md_exp, lco->lco_dt_exp); + + mutex_unlock(&lco->lco_lock); + result = 0; + } else { + CERROR("unexpected notification from %s %s!\n", + watched->obd_type->typ_name, + watched->obd_name); + result = -EINVAL; + } + return result; +} + +#define GROUPLOCK_SCOPE "grouplock" + +int cl_get_grouplock(struct cl_object *obj, unsigned long gid, int nonblock, + struct ccc_grouplock *cg) +{ + struct lu_env *env; + struct cl_io *io; + struct cl_lock *lock; + struct cl_lock_descr *descr; + __u32 enqflags; + int refcheck; + int rc; + + env = cl_env_get(&refcheck); + if (IS_ERR(env)) + return PTR_ERR(env); + + io = ccc_env_thread_io(env); + io->ci_obj = obj; + io->ci_ignore_layout = 1; + + rc = cl_io_init(env, io, CIT_MISC, io->ci_obj); + if (rc) { + /* Does not make sense to take GL for released layout */ + if (rc > 0) + rc = -ENOTSUPP; + cl_env_put(env, &refcheck); + return rc; + } + + descr = &ccc_env_info(env)->cti_descr; + descr->cld_obj = obj; + descr->cld_start = 0; + descr->cld_end = CL_PAGE_EOF; + descr->cld_gid = gid; + descr->cld_mode = CLM_GROUP; + + enqflags = CEF_MUST | (nonblock ? CEF_NONBLOCK : 0); + descr->cld_enq_flags = enqflags; + + lock = cl_lock_request(env, io, descr, GROUPLOCK_SCOPE, current); + if (IS_ERR(lock)) { + cl_io_fini(env, io); + cl_env_put(env, &refcheck); + return PTR_ERR(lock); + } + + cg->cg_env = cl_env_get(&refcheck); + cg->cg_io = io; + cg->cg_lock = lock; + cg->cg_gid = gid; + LASSERT(cg->cg_env == env); + + cl_env_unplant(env, &refcheck); + return 0; +} + +void cl_put_grouplock(struct ccc_grouplock *cg) +{ + struct lu_env *env = cg->cg_env; + struct cl_io *io = cg->cg_io; + struct cl_lock *lock = cg->cg_lock; + int refcheck; + + LASSERT(cg->cg_env); + LASSERT(cg->cg_gid); + + cl_env_implant(env, &refcheck); + cl_env_put(env, &refcheck); + + cl_unuse(env, lock); + cl_lock_release(env, lock, GROUPLOCK_SCOPE, current); + cl_io_fini(env, io); + cl_env_put(env, NULL); +} -- cgit v1.2.3 From 26f98e82e7ef3e1ecad0a0b83020dd19fc9ff822 Mon Sep 17 00:00:00 2001 From: Jinshan Xiong Date: Wed, 30 Mar 2016 19:48:25 -0400 Subject: staging/lustre: Reintroduce global env list This reverts a patch that was merged before lustre client was introduced into the stagign tree, so it's not in the history. The performance dropped a lot when memory reclaim process kicked in as ll_releasepage() was called to destroy lustre pages. It turned out that big overhead to allocate cl_env and keys on the fly so we have to revert this patch. The original problem for the reverted patch would be solved in a follow on patch instead. Signed-off-by: Jinshan Xiong Reviewed-on: http://review.whamcloud.com/7888 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-3321 Reviewed-by: Niu Yawei Reviewed-by: Lai Siyao Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/cl_object.h | 1 + drivers/staging/lustre/lustre/llite/lcommon_misc.c | 3 +- drivers/staging/lustre/lustre/llite/llite_lib.c | 2 + drivers/staging/lustre/lustre/obdclass/cl_object.c | 90 ++++++++++++++++++++-- drivers/staging/lustre/lustre/obdclass/lu_object.c | 2 + 5 files changed, 92 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h index fb971ded5a1b..e611f790285a 100644 --- a/drivers/staging/lustre/lustre/include/cl_object.h +++ b/drivers/staging/lustre/lustre/include/cl_object.h @@ -3241,6 +3241,7 @@ void *cl_env_reenter(void); void cl_env_reexit(void *cookie); void cl_env_implant(struct lu_env *env, int *refcheck); void cl_env_unplant(struct lu_env *env, int *refcheck); +unsigned int cl_env_cache_purge(unsigned int nr); /** @} cl_env */ diff --git a/drivers/staging/lustre/lustre/llite/lcommon_misc.c b/drivers/staging/lustre/lustre/llite/lcommon_misc.c index d80bcedd78d1..f68c3687b1d9 100644 --- a/drivers/staging/lustre/lustre/llite/lcommon_misc.c +++ b/drivers/staging/lustre/lustre/llite/lcommon_misc.c @@ -146,10 +146,11 @@ int cl_get_grouplock(struct cl_object *obj, unsigned long gid, int nonblock, rc = cl_io_init(env, io, CIT_MISC, io->ci_obj); if (rc) { + cl_io_fini(env, io); + cl_env_put(env, &refcheck); /* Does not make sense to take GL for released layout */ if (rc > 0) rc = -ENOTSUPP; - cl_env_put(env, &refcheck); return rc; } diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index 6d6bb33e3655..673d31e044dd 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -999,6 +999,8 @@ void ll_put_super(struct super_block *sb) lustre_common_put_super(sb); + cl_env_cache_purge(~0); + module_put(THIS_MODULE); } /* client_put_super */ diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c index 43e299d4d416..0772706dbffc 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_object.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c @@ -492,6 +492,13 @@ EXPORT_SYMBOL(cl_site_stats_print); * bz20044, bz22683. */ +static LIST_HEAD(cl_envs); +static unsigned int cl_envs_cached_nr; +static unsigned int cl_envs_cached_max = 128; /* XXX: prototype: arbitrary limit + * for now. + */ +static DEFINE_SPINLOCK(cl_envs_guard); + struct cl_env { void *ce_magic; struct lu_env ce_lu; @@ -697,6 +704,39 @@ static void cl_env_fini(struct cl_env *cle) kmem_cache_free(cl_env_kmem, cle); } +static struct lu_env *cl_env_obtain(void *debug) +{ + struct cl_env *cle; + struct lu_env *env; + + spin_lock(&cl_envs_guard); + LASSERT(equi(cl_envs_cached_nr == 0, list_empty(&cl_envs))); + if (cl_envs_cached_nr > 0) { + int rc; + + cle = container_of(cl_envs.next, struct cl_env, ce_linkage); + list_del_init(&cle->ce_linkage); + cl_envs_cached_nr--; + spin_unlock(&cl_envs_guard); + + env = &cle->ce_lu; + rc = lu_env_refill(env); + if (rc == 0) { + cl_env_init0(cle, debug); + lu_context_enter(&env->le_ctx); + lu_context_enter(&cle->ce_ses); + } else { + cl_env_fini(cle); + env = ERR_PTR(rc); + } + } else { + spin_unlock(&cl_envs_guard); + env = cl_env_new(lu_context_tags_default, + lu_session_tags_default, debug); + } + return env; +} + static inline struct cl_env *cl_env_container(struct lu_env *env) { return container_of(env, struct cl_env, ce_lu); @@ -727,6 +767,8 @@ static struct lu_env *cl_env_peek(int *refcheck) * Returns lu_env: if there already is an environment associated with the * current thread, it is returned, otherwise, new environment is allocated. * + * Allocations are amortized through the global cache of environments. + * * \param refcheck pointer to a counter used to detect environment leaks. In * the usual case cl_env_get() and cl_env_put() are called in the same lexical * scope and pointer to the same integer is passed as \a refcheck. This is @@ -740,10 +782,7 @@ struct lu_env *cl_env_get(int *refcheck) env = cl_env_peek(refcheck); if (!env) { - env = cl_env_new(lu_context_tags_default, - lu_session_tags_default, - __builtin_return_address(0)); - + env = cl_env_obtain(__builtin_return_address(0)); if (!IS_ERR(env)) { struct cl_env *cle; @@ -786,6 +825,32 @@ static void cl_env_exit(struct cl_env *cle) lu_context_exit(&cle->ce_ses); } +/** + * Finalizes and frees a given number of cached environments. This is done to + * (1) free some memory (not currently hooked into VM), or (2) release + * references to modules. + */ +unsigned int cl_env_cache_purge(unsigned int nr) +{ + struct cl_env *cle; + + spin_lock(&cl_envs_guard); + for (; !list_empty(&cl_envs) && nr > 0; --nr) { + cle = container_of(cl_envs.next, struct cl_env, ce_linkage); + list_del_init(&cle->ce_linkage); + LASSERT(cl_envs_cached_nr > 0); + cl_envs_cached_nr--; + spin_unlock(&cl_envs_guard); + + cl_env_fini(cle); + spin_lock(&cl_envs_guard); + } + LASSERT(equi(cl_envs_cached_nr == 0, list_empty(&cl_envs))); + spin_unlock(&cl_envs_guard); + return nr; +} +EXPORT_SYMBOL(cl_env_cache_purge); + /** * Release an environment. * @@ -808,7 +873,22 @@ void cl_env_put(struct lu_env *env, int *refcheck) cl_env_detach(cle); cle->ce_debug = NULL; cl_env_exit(cle); - cl_env_fini(cle); + /* + * Don't bother to take a lock here. + * + * Return environment to the cache only when it was allocated + * with the standard tags. + */ + if (cl_envs_cached_nr < cl_envs_cached_max && + (env->le_ctx.lc_tags & ~LCT_HAS_EXIT) == LCT_CL_THREAD && + (env->le_ses->lc_tags & ~LCT_HAS_EXIT) == LCT_SESSION) { + spin_lock(&cl_envs_guard); + list_add(&cle->ce_linkage, &cl_envs); + cl_envs_cached_nr++; + spin_unlock(&cl_envs_guard); + } else { + cl_env_fini(cle); + } } } EXPORT_SYMBOL(cl_env_put); diff --git a/drivers/staging/lustre/lustre/obdclass/lu_object.c b/drivers/staging/lustre/lustre/obdclass/lu_object.c index 69fdcee0ac52..770d5bd742d8 100644 --- a/drivers/staging/lustre/lustre/obdclass/lu_object.c +++ b/drivers/staging/lustre/lustre/obdclass/lu_object.c @@ -55,6 +55,7 @@ #include "../include/lustre_disk.h" #include "../include/lustre_fid.h" #include "../include/lu_object.h" +#include "../include/cl_object.h" #include "../include/lu_ref.h" #include @@ -1468,6 +1469,7 @@ void lu_context_key_quiesce(struct lu_context_key *key) /* * XXX layering violation. */ + cl_env_cache_purge(~0); key->lct_tags |= LCT_QUIESCENT; /* * XXX memory barrier has to go here. -- cgit v1.2.3 From 5196e42c372fc33551c836d9d6d0a0883b4d2d19 Mon Sep 17 00:00:00 2001 From: Jinshan Xiong Date: Wed, 30 Mar 2016 19:48:26 -0400 Subject: staging/lustre/osc: Adjustment on osc LRU for performance Add and discard pages from LRU in batch. Signed-off-by: Jinshan Xiong Reviewed-on: http://review.whamcloud.com/7890 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-3321 Reviewed-by: Niu Yawei Reviewed-by: Lai Siyao Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/llite_lib.c | 5 +- drivers/staging/lustre/lustre/osc/lproc_osc.c | 2 +- drivers/staging/lustre/lustre/osc/osc_cache.c | 2 + .../staging/lustre/lustre/osc/osc_cl_internal.h | 26 +- drivers/staging/lustre/lustre/osc/osc_internal.h | 3 +- drivers/staging/lustre/lustre/osc/osc_io.c | 51 ++++ drivers/staging/lustre/lustre/osc/osc_page.c | 301 +++++++++++---------- drivers/staging/lustre/lustre/osc/osc_request.c | 2 +- 8 files changed, 235 insertions(+), 157 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index 673d31e044dd..a4401f297d1c 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -85,10 +85,7 @@ static struct ll_sb_info *ll_init_sbi(struct super_block *sb) si_meminfo(&si); pages = si.totalram - si.totalhigh; - if (pages >> (20 - PAGE_CACHE_SHIFT) < 512) - lru_page_max = pages / 2; - else - lru_page_max = (pages / 4) * 3; + lru_page_max = pages / 2; /* initialize lru data */ atomic_set(&sbi->ll_cache.ccc_users, 0); diff --git a/drivers/staging/lustre/lustre/osc/lproc_osc.c b/drivers/staging/lustre/lustre/osc/lproc_osc.c index 57c43c506ef2..3eff12c073d3 100644 --- a/drivers/staging/lustre/lustre/osc/lproc_osc.c +++ b/drivers/staging/lustre/lustre/osc/lproc_osc.c @@ -223,7 +223,7 @@ static ssize_t osc_cached_mb_seq_write(struct file *file, rc = atomic_read(&cli->cl_lru_in_list) - pages_number; if (rc > 0) - (void)osc_lru_shrink(cli, rc); + (void)osc_lru_shrink(cli, rc, true); return count; } diff --git a/drivers/staging/lustre/lustre/osc/osc_cache.c b/drivers/staging/lustre/lustre/osc/osc_cache.c index 3cfd2b09f760..6196c3bc2da7 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cache.c +++ b/drivers/staging/lustre/lustre/osc/osc_cache.c @@ -856,6 +856,8 @@ int osc_extent_finish(const struct lu_env *env, struct osc_extent *ext, ext->oe_rc = rc ?: ext->oe_nr_pages; EASSERT(ergo(rc == 0, ext->oe_state == OES_RPC), ext); + + osc_lru_add_batch(cli, &ext->oe_pages); list_for_each_entry_safe(oap, tmp, &ext->oe_pages, oap_pending_item) { list_del_init(&oap->oap_rpc_item); list_del_init(&oap->oap_pending_item); diff --git a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h index d55d04d0428b..f5168486e1d9 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h +++ b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h @@ -77,6 +77,8 @@ struct osc_io { */ struct osc_extent *oi_trunc; + int oi_lru_reserved; + struct obd_info oi_info; struct obdo oi_oa; struct osc_async_cbargs { @@ -100,7 +102,7 @@ struct osc_session { struct osc_io os_io; }; -#define OTI_PVEC_SIZE 64 +#define OTI_PVEC_SIZE 256 struct osc_thread_info { struct ldlm_res_id oti_resname; ldlm_policy_data_t oti_policy; @@ -369,18 +371,15 @@ struct osc_page { * Set if the page must be transferred with OBD_BRW_SRVLOCK. */ ops_srvlock:1; - union { - /** - * lru page list. ops_inflight and ops_lru are exclusive so - * that they can share the same data. - */ - struct list_head ops_lru; - /** - * Linkage into a per-osc_object list of pages in flight. For - * debugging. - */ - struct list_head ops_inflight; - }; + /** + * lru page list. See osc_lru_{del|use}() in osc_page.c for usage. + */ + struct list_head ops_lru; + /** + * Linkage into a per-osc_object list of pages in flight. For + * debugging. + */ + struct list_head ops_inflight; /** * Thread that submitted this page for transfer. For debugging. */ @@ -432,6 +431,7 @@ void osc_index2policy (ldlm_policy_data_t *policy, const struct cl_object *obj, int osc_lvb_print (const struct lu_env *env, void *cookie, lu_printer_t p, const struct ost_lvb *lvb); +void osc_lru_add_batch(struct client_obd *cli, struct list_head *list); void osc_page_submit(const struct lu_env *env, struct osc_page *opg, enum cl_req_type crt, int brw_flags); int osc_cancel_async_page(const struct lu_env *env, struct osc_page *ops); diff --git a/drivers/staging/lustre/lustre/osc/osc_internal.h b/drivers/staging/lustre/lustre/osc/osc_internal.h index ea695c2099ee..ec12962d8dcc 100644 --- a/drivers/staging/lustre/lustre/osc/osc_internal.h +++ b/drivers/staging/lustre/lustre/osc/osc_internal.h @@ -130,7 +130,8 @@ int osc_sync_base(struct obd_export *exp, struct obd_info *oinfo, int osc_process_config_base(struct obd_device *obd, struct lustre_cfg *cfg); int osc_build_rpc(const struct lu_env *env, struct client_obd *cli, struct list_head *ext_list, int cmd); -int osc_lru_shrink(struct client_obd *cli, int target); +int osc_lru_shrink(struct client_obd *cli, int target, bool force); +int osc_lru_reclaim(struct client_obd *cli); extern spinlock_t osc_ast_guard; diff --git a/drivers/staging/lustre/lustre/osc/osc_io.c b/drivers/staging/lustre/lustre/osc/osc_io.c index 6bd0a45d8b06..a0fa5339c4d3 100644 --- a/drivers/staging/lustre/lustre/osc/osc_io.c +++ b/drivers/staging/lustre/lustre/osc/osc_io.c @@ -308,6 +308,55 @@ static int osc_io_commit_write(const struct lu_env *env, return 0; } +static int osc_io_rw_iter_init(const struct lu_env *env, + const struct cl_io_slice *ios) +{ + struct cl_io *io = ios->cis_io; + struct osc_io *oio = osc_env_io(env); + struct osc_object *osc = cl2osc(ios->cis_obj); + struct client_obd *cli = osc_cli(osc); + unsigned long c; + unsigned int npages; + unsigned int max_pages; + + if (cl_io_is_append(io)) + return 0; + + npages = io->u.ci_rw.crw_count >> PAGE_CACHE_SHIFT; + if (io->u.ci_rw.crw_pos & ~PAGE_MASK) + ++npages; + + max_pages = cli->cl_max_pages_per_rpc * cli->cl_max_rpcs_in_flight; + if (npages > max_pages) + npages = max_pages; + + c = atomic_read(cli->cl_lru_left); + if (c < npages && osc_lru_reclaim(cli) > 0) + c = atomic_read(cli->cl_lru_left); + while (c >= npages) { + if (c == atomic_cmpxchg(cli->cl_lru_left, c, c - npages)) { + oio->oi_lru_reserved = npages; + break; + } + c = atomic_read(cli->cl_lru_left); + } + + return 0; +} + +static void osc_io_rw_iter_fini(const struct lu_env *env, + const struct cl_io_slice *ios) +{ + struct osc_io *oio = osc_env_io(env); + struct osc_object *osc = cl2osc(ios->cis_obj); + struct client_obd *cli = osc_cli(osc); + + if (oio->oi_lru_reserved > 0) { + atomic_add(oio->oi_lru_reserved, cli->cl_lru_left); + oio->oi_lru_reserved = 0; + } +} + static int osc_io_fault_start(const struct lu_env *env, const struct cl_io_slice *ios) { @@ -650,6 +699,8 @@ static const struct cl_io_operations osc_io_ops = { .cio_fini = osc_io_fini }, [CIT_WRITE] = { + .cio_iter_init = osc_io_rw_iter_init, + .cio_iter_fini = osc_io_rw_iter_fini, .cio_start = osc_io_write_start, .cio_end = osc_io_end, .cio_fini = osc_io_fini diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c index d720b1a1c18c..a60b783a761e 100644 --- a/drivers/staging/lustre/lustre/osc/osc_page.c +++ b/drivers/staging/lustre/lustre/osc/osc_page.c @@ -42,8 +42,8 @@ #include "osc_cl_internal.h" -static void osc_lru_del(struct client_obd *cli, struct osc_page *opg, bool del); -static void osc_lru_add(struct client_obd *cli, struct osc_page *opg); +static void osc_lru_del(struct client_obd *cli, struct osc_page *opg); +static void osc_lru_use(struct client_obd *cli, struct osc_page *opg); static int osc_lru_reserve(const struct lu_env *env, struct osc_object *obj, struct osc_page *opg); @@ -104,10 +104,7 @@ static void osc_page_transfer_add(const struct lu_env *env, { struct osc_object *obj = cl2osc(opg->ops_cl.cpl_obj); - /* ops_lru and ops_inflight share the same field, so take it from LRU - * first and then use it as inflight. - */ - osc_lru_del(osc_cli(obj), opg, false); + osc_lru_use(osc_cli(obj), opg); spin_lock(&obj->oo_seatbelt); list_add(&opg->ops_inflight, &obj->oo_inflight[crt]); @@ -222,21 +219,15 @@ static void osc_page_completion_read(const struct lu_env *env, int ioret) { struct osc_page *opg = cl2osc_page(slice); - struct osc_object *obj = cl2osc(opg->ops_cl.cpl_obj); if (likely(opg->ops_lock)) osc_page_putref_lock(env, opg); - osc_lru_add(osc_cli(obj), opg); } static void osc_page_completion_write(const struct lu_env *env, const struct cl_page_slice *slice, int ioret) { - struct osc_page *opg = cl2osc_page(slice); - struct osc_object *obj = cl2osc(slice->cpl_obj); - - osc_lru_add(osc_cli(obj), opg); } static int osc_page_fail(const struct lu_env *env, @@ -334,7 +325,7 @@ static void osc_page_delete(const struct lu_env *env, } spin_unlock(&obj->oo_seatbelt); - osc_lru_del(osc_cli(obj), opg, true); + osc_lru_del(osc_cli(obj), opg); } static void osc_page_clip(const struct lu_env *env, @@ -483,13 +474,12 @@ void osc_page_submit(const struct lu_env *env, struct osc_page *opg, */ static DECLARE_WAIT_QUEUE_HEAD(osc_lru_waitq); -static atomic_t osc_lru_waiters = ATOMIC_INIT(0); /* LRU pages are freed in batch mode. OSC should at least free this * number of pages to avoid running out of LRU budget, and.. */ static const int lru_shrink_min = 2 << (20 - PAGE_CACHE_SHIFT); /* 2M */ /* free this number at most otherwise it will take too long time to finish. */ -static const int lru_shrink_max = 32 << (20 - PAGE_CACHE_SHIFT); /* 32M */ +static const int lru_shrink_max = 8 << (20 - PAGE_CACHE_SHIFT); /* 8M */ /* Check if we can free LRU slots from this OSC. If there exists LRU waiters, * we should free slots aggressively. In this way, slots are freed in a steady @@ -500,62 +490,127 @@ static const int lru_shrink_max = 32 << (20 - PAGE_CACHE_SHIFT); /* 32M */ static int osc_cache_too_much(struct client_obd *cli) { struct cl_client_cache *cache = cli->cl_cache; - int pages = atomic_read(&cli->cl_lru_in_list) >> 1; + int pages = atomic_read(&cli->cl_lru_in_list); + unsigned long budget; - if (atomic_read(&osc_lru_waiters) > 0 && - atomic_read(cli->cl_lru_left) < lru_shrink_max) - /* drop lru pages aggressively */ - return min(pages, lru_shrink_max); + budget = cache->ccc_lru_max / atomic_read(&cache->ccc_users); /* if it's going to run out LRU slots, we should free some, but not * too much to maintain fairness among OSCs. */ if (atomic_read(cli->cl_lru_left) < cache->ccc_lru_max >> 4) { - unsigned long tmp; + if (pages >= budget) + return lru_shrink_max; + else if (pages >= budget / 2) + return lru_shrink_min; + } else if (pages >= budget * 2) + return lru_shrink_min; + return 0; +} - tmp = cache->ccc_lru_max / atomic_read(&cache->ccc_users); - if (pages > tmp) - return min(pages, lru_shrink_max); +void osc_lru_add_batch(struct client_obd *cli, struct list_head *plist) +{ + LIST_HEAD(lru); + struct osc_async_page *oap; + int npages = 0; + + list_for_each_entry(oap, plist, oap_pending_item) { + struct osc_page *opg = oap2osc_page(oap); + + if (!opg->ops_in_lru) + continue; - return pages > lru_shrink_min ? lru_shrink_min : 0; + ++npages; + LASSERT(list_empty(&opg->ops_lru)); + list_add(&opg->ops_lru, &lru); } - return 0; + if (npages > 0) { + client_obd_list_lock(&cli->cl_lru_list_lock); + list_splice_tail(&lru, &cli->cl_lru_list); + atomic_sub(npages, &cli->cl_lru_busy); + atomic_add(npages, &cli->cl_lru_in_list); + client_obd_list_unlock(&cli->cl_lru_list_lock); + + /* XXX: May set force to be true for better performance */ + osc_lru_shrink(cli, osc_cache_too_much(cli), false); + } } -/* Return how many pages are not discarded in @pvec. */ -static int discard_pagevec(const struct lu_env *env, struct cl_io *io, - struct cl_page **pvec, int max_index) +static void __osc_lru_del(struct client_obd *cli, struct osc_page *opg) +{ + LASSERT(atomic_read(&cli->cl_lru_in_list) > 0); + list_del_init(&opg->ops_lru); + atomic_dec(&cli->cl_lru_in_list); +} + +/** + * Page is being destroyed. The page may be not in LRU list, if the transfer + * has never finished(error occurred). + */ +static void osc_lru_del(struct client_obd *cli, struct osc_page *opg) +{ + if (opg->ops_in_lru) { + client_obd_list_lock(&cli->cl_lru_list_lock); + if (!list_empty(&opg->ops_lru)) { + __osc_lru_del(cli, opg); + } else { + LASSERT(atomic_read(&cli->cl_lru_busy) > 0); + atomic_dec(&cli->cl_lru_busy); + } + client_obd_list_unlock(&cli->cl_lru_list_lock); + + atomic_inc(cli->cl_lru_left); + /* this is a great place to release more LRU pages if + * this osc occupies too many LRU pages and kernel is + * stealing one of them. + */ + if (!memory_pressure_get()) + osc_lru_shrink(cli, osc_cache_too_much(cli), false); + wake_up(&osc_lru_waitq); + } else { + LASSERT(list_empty(&opg->ops_lru)); + } +} + +/** + * Delete page from LRUlist for redirty. + */ +static void osc_lru_use(struct client_obd *cli, struct osc_page *opg) +{ + /* If page is being transferred for the first time, + * ops_lru should be empty + */ + if (opg->ops_in_lru && !list_empty(&opg->ops_lru)) { + client_obd_list_lock(&cli->cl_lru_list_lock); + __osc_lru_del(cli, opg); + client_obd_list_unlock(&cli->cl_lru_list_lock); + atomic_inc(&cli->cl_lru_busy); + } +} + +static void discard_pagevec(const struct lu_env *env, struct cl_io *io, + struct cl_page **pvec, int max_index) { - int count; int i; - for (count = 0, i = 0; i < max_index; i++) { + for (i = 0; i < max_index; i++) { struct cl_page *page = pvec[i]; - if (cl_page_own_try(env, io, page) == 0) { - /* free LRU page only if nobody is using it. - * This check is necessary to avoid freeing the pages - * having already been removed from LRU and pinned - * for IO. - */ - if (!cl_page_in_use(page)) { - cl_page_unmap(env, io, page); - cl_page_discard(env, io, page); - ++count; - } - cl_page_disown(env, io, page); - } + LASSERT(cl_page_is_owned(page, io)); + cl_page_unmap(env, io, page); + cl_page_discard(env, io, page); + cl_page_disown(env, io, page); cl_page_put(env, page); + pvec[i] = NULL; } - return max_index - count; } /** * Drop @target of pages from LRU at most. */ -int osc_lru_shrink(struct client_obd *cli, int target) +int osc_lru_shrink(struct client_obd *cli, int target, bool force) { struct cl_env_nest nest; struct lu_env *env; @@ -573,18 +628,32 @@ int osc_lru_shrink(struct client_obd *cli, int target) if (atomic_read(&cli->cl_lru_in_list) == 0 || target <= 0) return 0; + if (!force) { + if (atomic_read(&cli->cl_lru_shrinkers) > 0) + return -EBUSY; + + if (atomic_inc_return(&cli->cl_lru_shrinkers) > 1) { + atomic_dec(&cli->cl_lru_shrinkers); + return -EBUSY; + } + } else { + atomic_inc(&cli->cl_lru_shrinkers); + } + env = cl_env_nested_get(&nest); - if (IS_ERR(env)) - return PTR_ERR(env); + if (IS_ERR(env)) { + rc = PTR_ERR(env); + goto out; + } pvec = osc_env_info(env)->oti_pvec; io = &osc_env_info(env)->oti_io; client_obd_list_lock(&cli->cl_lru_list_lock); - atomic_inc(&cli->cl_lru_shrinkers); maxscan = min(target << 1, atomic_read(&cli->cl_lru_in_list)); list_for_each_entry_safe(opg, temp, &cli->cl_lru_list, ops_lru) { struct cl_page *page; + bool will_free = false; if (--maxscan < 0) break; @@ -603,7 +672,7 @@ int osc_lru_shrink(struct client_obd *cli, int target) client_obd_list_unlock(&cli->cl_lru_list_lock); if (clobj) { - count -= discard_pagevec(env, io, pvec, index); + discard_pagevec(env, io, pvec, index); index = 0; cl_io_fini(env, io); @@ -625,98 +694,56 @@ int osc_lru_shrink(struct client_obd *cli, int target) continue; } - /* move this page to the end of list as it will be discarded - * soon. The page will be finally removed from LRU list in - * osc_page_delete(). - */ - list_move_tail(&opg->ops_lru, &cli->cl_lru_list); + if (cl_page_own_try(env, io, page) == 0) { + if (!cl_page_in_use_noref(page)) { + /* remove it from lru list earlier to avoid + * lock contention + */ + __osc_lru_del(cli, opg); + opg->ops_in_lru = 0; /* will be discarded */ + + cl_page_get(page); + will_free = true; + } else { + cl_page_disown(env, io, page); + } + } - /* it's okay to grab a refcount here w/o holding lock because - * it has to grab cl_lru_list_lock to delete the page. - */ - cl_page_get(page); - pvec[index++] = page; - if (++count >= target) - break; + if (!will_free) { + list_move_tail(&opg->ops_lru, &cli->cl_lru_list); + continue; + } + /* Don't discard and free the page with cl_lru_list held */ + pvec[index++] = page; if (unlikely(index == OTI_PVEC_SIZE)) { client_obd_list_unlock(&cli->cl_lru_list_lock); - count -= discard_pagevec(env, io, pvec, index); + discard_pagevec(env, io, pvec, index); index = 0; client_obd_list_lock(&cli->cl_lru_list_lock); } + + if (++count >= target) + break; } client_obd_list_unlock(&cli->cl_lru_list_lock); if (clobj) { - count -= discard_pagevec(env, io, pvec, index); + discard_pagevec(env, io, pvec, index); cl_io_fini(env, io); cl_object_put(env, clobj); } cl_env_nested_put(&nest, env); +out: atomic_dec(&cli->cl_lru_shrinkers); - return count > 0 ? count : rc; -} - -static void osc_lru_add(struct client_obd *cli, struct osc_page *opg) -{ - bool wakeup = false; - - if (!opg->ops_in_lru) - return; - - atomic_dec(&cli->cl_lru_busy); - client_obd_list_lock(&cli->cl_lru_list_lock); - if (list_empty(&opg->ops_lru)) { - list_move_tail(&opg->ops_lru, &cli->cl_lru_list); - atomic_inc_return(&cli->cl_lru_in_list); - wakeup = atomic_read(&osc_lru_waiters) > 0; - } - client_obd_list_unlock(&cli->cl_lru_list_lock); - - if (wakeup) { - osc_lru_shrink(cli, osc_cache_too_much(cli)); + if (count > 0) { + atomic_add(count, cli->cl_lru_left); wake_up_all(&osc_lru_waitq); } -} - -/* delete page from LRUlist. The page can be deleted from LRUlist for two - * reasons: redirtied or deleted from page cache. - */ -static void osc_lru_del(struct client_obd *cli, struct osc_page *opg, bool del) -{ - if (opg->ops_in_lru) { - client_obd_list_lock(&cli->cl_lru_list_lock); - if (!list_empty(&opg->ops_lru)) { - LASSERT(atomic_read(&cli->cl_lru_in_list) > 0); - list_del_init(&opg->ops_lru); - atomic_dec(&cli->cl_lru_in_list); - if (!del) - atomic_inc(&cli->cl_lru_busy); - } else if (del) { - LASSERT(atomic_read(&cli->cl_lru_busy) > 0); - atomic_dec(&cli->cl_lru_busy); - } - client_obd_list_unlock(&cli->cl_lru_list_lock); - if (del) { - atomic_inc(cli->cl_lru_left); - /* this is a great place to release more LRU pages if - * this osc occupies too many LRU pages and kernel is - * stealing one of them. - * cl_lru_shrinkers is to avoid recursive call in case - * we're already in the context of osc_lru_shrink(). - */ - if (atomic_read(&cli->cl_lru_shrinkers) == 0 && - !memory_pressure_get()) - osc_lru_shrink(cli, osc_cache_too_much(cli)); - wake_up(&osc_lru_waitq); - } - } else { - LASSERT(list_empty(&opg->ops_lru)); - } + return count > 0 ? count : rc; } static inline int max_to_shrink(struct client_obd *cli) @@ -724,16 +751,19 @@ static inline int max_to_shrink(struct client_obd *cli) return min(atomic_read(&cli->cl_lru_in_list) >> 1, lru_shrink_max); } -static int osc_lru_reclaim(struct client_obd *cli) +int osc_lru_reclaim(struct client_obd *cli) { struct cl_client_cache *cache = cli->cl_cache; int max_scans; - int rc; + int rc = 0; LASSERT(cache); - rc = osc_lru_shrink(cli, lru_shrink_min); + rc = osc_lru_shrink(cli, lru_shrink_min, false); if (rc != 0) { + if (rc == -EBUSY) + rc = 0; + CDEBUG(D_CACHE, "%s: Free %d pages from own LRU: %p.\n", cli->cl_import->imp_obd->obd_name, rc, cli); return rc; @@ -764,10 +794,10 @@ static int osc_lru_reclaim(struct client_obd *cli) atomic_read(&cli->cl_lru_busy)); list_move_tail(&cli->cl_lru_osc, &cache->ccc_lru); - if (atomic_read(&cli->cl_lru_in_list) > 0) { + if (osc_cache_too_much(cli) > 0) { spin_unlock(&cache->ccc_lru_lock); - rc = osc_lru_shrink(cli, max_to_shrink(cli)); + rc = osc_lru_shrink(cli, osc_cache_too_much(cli), true); spin_lock(&cache->ccc_lru_lock); if (rc != 0) break; @@ -784,15 +814,20 @@ static int osc_lru_reserve(const struct lu_env *env, struct osc_object *obj, struct osc_page *opg) { struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL); + struct osc_io *oio = osc_env_io(env); struct client_obd *cli = osc_cli(obj); int rc = 0; if (!cli->cl_cache) /* shall not be in LRU */ return 0; + if (oio->oi_lru_reserved > 0) { + --oio->oi_lru_reserved; + goto out; + } + LASSERT(atomic_read(cli->cl_lru_left) >= 0); while (!atomic_add_unless(cli->cl_lru_left, -1, 0)) { - int gen; /* run out of LRU spaces, try to drop some by itself */ rc = osc_lru_reclaim(cli); @@ -803,23 +838,15 @@ static int osc_lru_reserve(const struct lu_env *env, struct osc_object *obj, cond_resched(); - /* slowest case, all of caching pages are busy, notifying - * other OSCs that we're lack of LRU slots. - */ - atomic_inc(&osc_lru_waiters); - - gen = atomic_read(&cli->cl_lru_in_list); rc = l_wait_event(osc_lru_waitq, - atomic_read(cli->cl_lru_left) > 0 || - (atomic_read(&cli->cl_lru_in_list) > 0 && - gen != atomic_read(&cli->cl_lru_in_list)), + atomic_read(cli->cl_lru_left) > 0, &lwi); - atomic_dec(&osc_lru_waiters); if (rc < 0) break; } +out: if (rc >= 0) { atomic_inc(&cli->cl_lru_busy); opg->ops_in_lru = 1; diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c index 850d5dd49831..6dadda4da5b4 100644 --- a/drivers/staging/lustre/lustre/osc/osc_request.c +++ b/drivers/staging/lustre/lustre/osc/osc_request.c @@ -2910,7 +2910,7 @@ static int osc_set_info_async(const struct lu_env *env, struct obd_export *exp, int nr = atomic_read(&cli->cl_lru_in_list) >> 1; int target = *(int *)val; - nr = osc_lru_shrink(cli, min(nr, target)); + nr = osc_lru_shrink(cli, min(nr, target), true); *(int *)val -= nr; return 0; } -- cgit v1.2.3 From 2579d8d01759aae407d3645be5125f8dd436757c Mon Sep 17 00:00:00 2001 From: Jinshan Xiong Date: Wed, 30 Mar 2016 19:48:27 -0400 Subject: staging/lustre/osc: to drop LRU pages with cl_lru_work This way we can drop it async. Signed-off-by: Jinshan Xiong Reviewed-on: http://review.whamcloud.com/7891 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-3321 Reviewed-by: Lai Siyao Reviewed-by: Bobi Jam Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/obd.h | 1 + drivers/staging/lustre/lustre/llite/lproc_llite.c | 9 ++++- drivers/staging/lustre/lustre/osc/lproc_osc.c | 12 +++++- .../staging/lustre/lustre/osc/osc_cl_internal.h | 1 + drivers/staging/lustre/lustre/osc/osc_internal.h | 3 +- drivers/staging/lustre/lustre/osc/osc_page.c | 45 ++++++++++++++-------- drivers/staging/lustre/lustre/osc/osc_request.c | 23 ++++++++++- drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c | 16 ++++++-- 8 files changed, 85 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/include/obd.h b/drivers/staging/lustre/lustre/include/obd.h index 4a0f2e8b19f6..26182ca8f518 100644 --- a/drivers/staging/lustre/lustre/include/obd.h +++ b/drivers/staging/lustre/lustre/include/obd.h @@ -364,6 +364,7 @@ struct client_obd { /* ptlrpc work for writeback in ptlrpcd context */ void *cl_writeback_work; + void *cl_lru_work; /* hash tables for osc_quota_info */ struct cfs_hash *cl_quota_hash[MAXQUOTAS]; }; diff --git a/drivers/staging/lustre/lustre/llite/lproc_llite.c b/drivers/staging/lustre/lustre/llite/lproc_llite.c index 45941a6600fe..9e8e61a730b7 100644 --- a/drivers/staging/lustre/lustre/llite/lproc_llite.c +++ b/drivers/staging/lustre/lustre/llite/lproc_llite.c @@ -393,6 +393,8 @@ static ssize_t ll_max_cached_mb_seq_write(struct file *file, struct super_block *sb = ((struct seq_file *)file->private_data)->private; struct ll_sb_info *sbi = ll_s2sbi(sb); struct cl_client_cache *cache = &sbi->ll_cache; + struct lu_env *env; + int refcheck; int mult, rc, pages_number; int diff = 0; int nrpages = 0; @@ -430,6 +432,10 @@ static ssize_t ll_max_cached_mb_seq_write(struct file *file, goto out; } + env = cl_env_get(&refcheck); + if (IS_ERR(env)) + return 0; + diff = -diff; while (diff > 0) { int tmp; @@ -461,13 +467,14 @@ static ssize_t ll_max_cached_mb_seq_write(struct file *file, /* difficult - have to ask OSCs to drop LRU slots. */ tmp = diff << 1; - rc = obd_set_info_async(NULL, sbi->ll_dt_exp, + rc = obd_set_info_async(env, sbi->ll_dt_exp, sizeof(KEY_CACHE_LRU_SHRINK), KEY_CACHE_LRU_SHRINK, sizeof(tmp), &tmp, NULL); if (rc < 0) break; } + cl_env_put(env, &refcheck); out: if (rc >= 0) { diff --git a/drivers/staging/lustre/lustre/osc/lproc_osc.c b/drivers/staging/lustre/lustre/osc/lproc_osc.c index 3eff12c073d3..e6e2029289f9 100644 --- a/drivers/staging/lustre/lustre/osc/lproc_osc.c +++ b/drivers/staging/lustre/lustre/osc/lproc_osc.c @@ -222,8 +222,16 @@ static ssize_t osc_cached_mb_seq_write(struct file *file, return -ERANGE; rc = atomic_read(&cli->cl_lru_in_list) - pages_number; - if (rc > 0) - (void)osc_lru_shrink(cli, rc, true); + if (rc > 0) { + struct lu_env *env; + int refcheck; + + env = cl_env_get(&refcheck); + if (!IS_ERR(env)) { + (void)osc_lru_shrink(env, cli, rc, true); + cl_env_put(env, &refcheck); + } + } return count; } diff --git a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h index f5168486e1d9..b6325f5c3542 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h +++ b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h @@ -457,6 +457,7 @@ int osc_cache_wait_range(const struct lu_env *env, struct osc_object *obj, pgoff_t start, pgoff_t end); void osc_io_unplug(const struct lu_env *env, struct client_obd *cli, struct osc_object *osc); +int lru_queue_work(const struct lu_env *env, void *data); void osc_object_set_contended (struct osc_object *obj); void osc_object_clear_contended(struct osc_object *obj); diff --git a/drivers/staging/lustre/lustre/osc/osc_internal.h b/drivers/staging/lustre/lustre/osc/osc_internal.h index ec12962d8dcc..b3b15d4c99e3 100644 --- a/drivers/staging/lustre/lustre/osc/osc_internal.h +++ b/drivers/staging/lustre/lustre/osc/osc_internal.h @@ -130,7 +130,8 @@ int osc_sync_base(struct obd_export *exp, struct obd_info *oinfo, int osc_process_config_base(struct obd_device *obd, struct lustre_cfg *cfg); int osc_build_rpc(const struct lu_env *env, struct client_obd *cli, struct list_head *ext_list, int cmd); -int osc_lru_shrink(struct client_obd *cli, int target, bool force); +int osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, + int target, bool force); int osc_lru_reclaim(struct client_obd *cli); extern spinlock_t osc_ast_guard; diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c index a60b783a761e..f0a9870846d7 100644 --- a/drivers/staging/lustre/lustre/osc/osc_page.c +++ b/drivers/staging/lustre/lustre/osc/osc_page.c @@ -508,6 +508,18 @@ static int osc_cache_too_much(struct client_obd *cli) return 0; } +int lru_queue_work(const struct lu_env *env, void *data) +{ + struct client_obd *cli = data; + + CDEBUG(D_CACHE, "Run LRU work for client obd %p.\n", cli); + + if (osc_cache_too_much(cli)) + osc_lru_shrink(env, cli, lru_shrink_max, true); + + return 0; +} + void osc_lru_add_batch(struct client_obd *cli, struct list_head *plist) { LIST_HEAD(lru); @@ -533,7 +545,8 @@ void osc_lru_add_batch(struct client_obd *cli, struct list_head *plist) client_obd_list_unlock(&cli->cl_lru_list_lock); /* XXX: May set force to be true for better performance */ - osc_lru_shrink(cli, osc_cache_too_much(cli), false); + if (osc_cache_too_much(cli)) + (void)ptlrpcd_queue_work(cli->cl_lru_work); } } @@ -566,7 +579,7 @@ static void osc_lru_del(struct client_obd *cli, struct osc_page *opg) * stealing one of them. */ if (!memory_pressure_get()) - osc_lru_shrink(cli, osc_cache_too_much(cli), false); + (void)ptlrpcd_queue_work(cli->cl_lru_work); wake_up(&osc_lru_waitq); } else { LASSERT(list_empty(&opg->ops_lru)); @@ -610,10 +623,9 @@ static void discard_pagevec(const struct lu_env *env, struct cl_io *io, /** * Drop @target of pages from LRU at most. */ -int osc_lru_shrink(struct client_obd *cli, int target, bool force) +int osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, + int target, bool force) { - struct cl_env_nest nest; - struct lu_env *env; struct cl_io *io; struct cl_object *clobj = NULL; struct cl_page **pvec; @@ -640,12 +652,6 @@ int osc_lru_shrink(struct client_obd *cli, int target, bool force) atomic_inc(&cli->cl_lru_shrinkers); } - env = cl_env_nested_get(&nest); - if (IS_ERR(env)) { - rc = PTR_ERR(env); - goto out; - } - pvec = osc_env_info(env)->oti_pvec; io = &osc_env_info(env)->oti_io; @@ -735,9 +741,7 @@ int osc_lru_shrink(struct client_obd *cli, int target, bool force) cl_io_fini(env, io); cl_object_put(env, clobj); } - cl_env_nested_put(&nest, env); -out: atomic_dec(&cli->cl_lru_shrinkers); if (count > 0) { atomic_add(count, cli->cl_lru_left); @@ -753,20 +757,26 @@ static inline int max_to_shrink(struct client_obd *cli) int osc_lru_reclaim(struct client_obd *cli) { + struct cl_env_nest nest; + struct lu_env *env; struct cl_client_cache *cache = cli->cl_cache; int max_scans; int rc = 0; LASSERT(cache); - rc = osc_lru_shrink(cli, lru_shrink_min, false); + env = cl_env_nested_get(&nest); + if (IS_ERR(env)) + return 0; + + rc = osc_lru_shrink(env, cli, osc_cache_too_much(cli), false); if (rc != 0) { if (rc == -EBUSY) rc = 0; CDEBUG(D_CACHE, "%s: Free %d pages from own LRU: %p.\n", cli->cl_import->imp_obd->obd_name, rc, cli); - return rc; + goto out; } CDEBUG(D_CACHE, "%s: cli %p no free slots, pages: %d, busy: %d.\n", @@ -797,7 +807,8 @@ int osc_lru_reclaim(struct client_obd *cli) if (osc_cache_too_much(cli) > 0) { spin_unlock(&cache->ccc_lru_lock); - rc = osc_lru_shrink(cli, osc_cache_too_much(cli), true); + rc = osc_lru_shrink(env, cli, osc_cache_too_much(cli), + true); spin_lock(&cache->ccc_lru_lock); if (rc != 0) break; @@ -805,6 +816,8 @@ int osc_lru_reclaim(struct client_obd *cli) } spin_unlock(&cache->ccc_lru_lock); +out: + cl_env_nested_put(&nest, env); CDEBUG(D_CACHE, "%s: cli %p freed %d pages.\n", cli->cl_import->imp_obd->obd_name, cli, rc); return rc; diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c index 6dadda4da5b4..c055511b321a 100644 --- a/drivers/staging/lustre/lustre/osc/osc_request.c +++ b/drivers/staging/lustre/lustre/osc/osc_request.c @@ -2910,7 +2910,7 @@ static int osc_set_info_async(const struct lu_env *env, struct obd_export *exp, int nr = atomic_read(&cli->cl_lru_in_list) >> 1; int target = *(int *)val; - nr = osc_lru_shrink(cli, min(nr, target), true); + nr = osc_lru_shrink(env, cli, min(nr, target), true); *(int *)val -= nr; return 0; } @@ -3167,6 +3167,14 @@ int osc_setup(struct obd_device *obd, struct lustre_cfg *lcfg) } cli->cl_writeback_work = handler; + handler = ptlrpcd_alloc_work(cli->cl_import, lru_queue_work, cli); + if (IS_ERR(handler)) { + rc = PTR_ERR(handler); + goto out_ptlrpcd_work; + } + + cli->cl_lru_work = handler; + rc = osc_quota_setup(obd); if (rc) goto out_ptlrpcd_work; @@ -3199,7 +3207,14 @@ int osc_setup(struct obd_device *obd, struct lustre_cfg *lcfg) return rc; out_ptlrpcd_work: - ptlrpcd_destroy_work(handler); + if (cli->cl_writeback_work) { + ptlrpcd_destroy_work(cli->cl_writeback_work); + cli->cl_writeback_work = NULL; + } + if (cli->cl_lru_work) { + ptlrpcd_destroy_work(cli->cl_lru_work); + cli->cl_lru_work = NULL; + } out_client_setup: client_obd_cleanup(obd); out_ptlrpcd: @@ -3238,6 +3253,10 @@ static int osc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) ptlrpcd_destroy_work(cli->cl_writeback_work); cli->cl_writeback_work = NULL; } + if (cli->cl_lru_work) { + ptlrpcd_destroy_work(cli->cl_lru_work); + cli->cl_lru_work = NULL; + } obd_cleanup_client_import(obd); ptlrpc_lprocfs_unregister_obd(obd); lprocfs_obd_cleanup(obd); diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c index db003f5da09e..dbc3376328cd 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c +++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c @@ -387,7 +387,8 @@ static int ptlrpcd(void *arg) { struct ptlrpcd_ctl *pc = arg; struct ptlrpc_request_set *set; - struct lu_env env = { .le_ses = NULL }; + struct lu_context ses = { 0 }; + struct lu_env env = { .le_ses = &ses }; int rc = 0; int exit = 0; @@ -416,6 +417,13 @@ static int ptlrpcd(void *arg) */ rc = lu_context_init(&env.le_ctx, LCT_CL_THREAD|LCT_REMEMBER|LCT_NOREF); + if (rc == 0) { + rc = lu_context_init(env.le_ses, + LCT_SESSION | LCT_REMEMBER | LCT_NOREF); + if (rc != 0) + lu_context_fini(&env.le_ctx); + } + if (rc != 0) goto failed; @@ -436,9 +444,10 @@ static int ptlrpcd(void *arg) ptlrpc_expired_set, set); lu_context_enter(&env.le_ctx); - l_wait_event(set->set_waitq, - ptlrpcd_check(&env, pc), &lwi); + lu_context_enter(env.le_ses); + l_wait_event(set->set_waitq, ptlrpcd_check(&env, pc), &lwi); lu_context_exit(&env.le_ctx); + lu_context_exit(env.le_ses); /* * Abort inflight rpcs for forced stop case. @@ -461,6 +470,7 @@ static int ptlrpcd(void *arg) if (!list_empty(&set->set_requests)) ptlrpc_set_wait(set); lu_context_fini(&env.le_ctx); + lu_context_fini(env.le_ses); complete(&pc->pc_finishing); -- cgit v1.2.3 From d9d47901dfbec3f7e057c4d31ecbe39c8eaec991 Mon Sep 17 00:00:00 2001 From: Jinshan Xiong Date: Wed, 30 Mar 2016 19:48:28 -0400 Subject: staging/lustre/clio: collapse layer of cl_page Move radix tree to osc layer to for performance improvement. Signed-off-by: Jinshan Xiong Reviewed-on: http://review.whamcloud.com/7892 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-3321 Reviewed-by: Lai Siyao Reviewed-by: Bobi Jam Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/cl_object.h | 36 +-- drivers/staging/lustre/lustre/llite/rw.c | 2 +- drivers/staging/lustre/lustre/llite/rw26.c | 4 - drivers/staging/lustre/lustre/llite/vvp_dev.c | 47 +-- drivers/staging/lustre/lustre/llite/vvp_io.c | 1 - drivers/staging/lustre/lustre/llite/vvp_object.c | 13 + drivers/staging/lustre/lustre/llite/vvp_page.c | 36 +-- drivers/staging/lustre/lustre/lov/lov_object.c | 9 +- drivers/staging/lustre/lustre/lov/lov_page.c | 29 +- drivers/staging/lustre/lustre/obdclass/cl_io.c | 1 + drivers/staging/lustre/lustre/obdclass/cl_lock.c | 131 +------- drivers/staging/lustre/lustre/obdclass/cl_object.c | 47 +-- drivers/staging/lustre/lustre/obdclass/cl_page.c | 354 ++------------------- drivers/staging/lustre/lustre/osc/osc_cache.c | 207 +++++++++++- .../staging/lustre/lustre/osc/osc_cl_internal.h | 27 +- drivers/staging/lustre/lustre/osc/osc_io.c | 14 +- drivers/staging/lustre/lustre/osc/osc_lock.c | 10 +- drivers/staging/lustre/lustre/osc/osc_object.c | 2 + drivers/staging/lustre/lustre/osc/osc_page.c | 28 +- 19 files changed, 394 insertions(+), 604 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h index e611f790285a..5daf68815949 100644 --- a/drivers/staging/lustre/lustre/include/cl_object.h +++ b/drivers/staging/lustre/lustre/include/cl_object.h @@ -388,6 +388,12 @@ struct cl_object_operations { */ int (*coo_glimpse)(const struct lu_env *env, const struct cl_object *obj, struct ost_lvb *lvb); + /** + * Object prune method. Called when the layout is going to change on + * this object, therefore each layer has to clean up their cache, + * mainly pages and locks. + */ + int (*coo_prune)(const struct lu_env *env, struct cl_object *obj); }; /** @@ -403,15 +409,9 @@ struct cl_object_header { * mostly useless otherwise. */ /** @{ */ - /** Lock protecting page tree. */ - spinlock_t coh_page_guard; /** Lock protecting lock list. */ spinlock_t coh_lock_guard; /** @} locks */ - /** Radix tree of cl_page's, cached for this object. */ - struct radix_tree_root coh_tree; - /** # of pages in radix tree. */ - unsigned long coh_pages; /** List of cl_lock's granted for this object. */ struct list_head coh_locks; @@ -896,14 +896,6 @@ struct cl_page_operations { */ void (*cpo_export)(const struct lu_env *env, const struct cl_page_slice *slice, int uptodate); - /** - * Unmaps page from the user space (if it is mapped). - * - * \see cl_page_unmap() - * \see vvp_page_unmap() - */ - int (*cpo_unmap)(const struct lu_env *env, - const struct cl_page_slice *slice, struct cl_io *io); /** * Checks whether underlying VM page is locked (in the suitable * sense). Used for assertions. @@ -2794,19 +2786,13 @@ enum { }; /* callback of cl_page_gang_lookup() */ -typedef int (*cl_page_gang_cb_t) (const struct lu_env *, struct cl_io *, - struct cl_page *, void *); -int cl_page_gang_lookup(const struct lu_env *env, struct cl_object *obj, - struct cl_io *io, pgoff_t start, pgoff_t end, - cl_page_gang_cb_t cb, void *cbdata); -struct cl_page *cl_page_lookup(struct cl_object_header *hdr, pgoff_t index); struct cl_page *cl_page_find(const struct lu_env *env, struct cl_object *obj, pgoff_t idx, struct page *vmpage, enum cl_page_type type); -struct cl_page *cl_page_find_sub(const struct lu_env *env, - struct cl_object *obj, - pgoff_t idx, struct page *vmpage, - struct cl_page *parent); +struct cl_page *cl_page_alloc(const struct lu_env *env, + struct cl_object *o, pgoff_t ind, + struct page *vmpage, + enum cl_page_type type); void cl_page_get(struct cl_page *page); void cl_page_put(const struct lu_env *env, struct cl_page *page); void cl_page_print(const struct lu_env *env, void *cookie, lu_printer_t printer, @@ -2872,8 +2858,6 @@ int cl_page_flush(const struct lu_env *env, struct cl_io *io, void cl_page_discard(const struct lu_env *env, struct cl_io *io, struct cl_page *pg); void cl_page_delete(const struct lu_env *env, struct cl_page *pg); -int cl_page_unmap(const struct lu_env *env, struct cl_io *io, - struct cl_page *pg); int cl_page_is_vmlocked(const struct lu_env *env, const struct cl_page *pg); void cl_page_export(const struct lu_env *env, struct cl_page *pg, int uptodate); int cl_page_is_under_lock(const struct lu_env *env, struct cl_io *io, diff --git a/drivers/staging/lustre/lustre/llite/rw.c b/drivers/staging/lustre/lustre/llite/rw.c index 34614acf3f8e..01b8365c1dda 100644 --- a/drivers/staging/lustre/lustre/llite/rw.c +++ b/drivers/staging/lustre/lustre/llite/rw.c @@ -442,7 +442,7 @@ static int cl_read_ahead_page(const struct lu_env *env, struct cl_io *io, cl_page_list_add(queue, page); rc = 1; } else { - cl_page_delete(env, page); + cl_page_discard(env, io, page); rc = -ENOLCK; } } else { diff --git a/drivers/staging/lustre/lustre/llite/rw26.c b/drivers/staging/lustre/lustre/llite/rw26.c index 3d7e64ee9824..b5335de216be 100644 --- a/drivers/staging/lustre/lustre/llite/rw26.c +++ b/drivers/staging/lustre/lustre/llite/rw26.c @@ -95,11 +95,7 @@ static void ll_invalidatepage(struct page *vmpage, unsigned int offset, if (obj) { page = cl_vmpage_page(vmpage, obj); if (page) { - lu_ref_add(&page->cp_reference, - "delete", vmpage); cl_page_delete(env, page); - lu_ref_del(&page->cp_reference, - "delete", vmpage); cl_page_put(env, page); } } else diff --git a/drivers/staging/lustre/lustre/llite/vvp_dev.c b/drivers/staging/lustre/lustre/llite/vvp_dev.c index 282b70b776da..29d24c98d259 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_dev.c +++ b/drivers/staging/lustre/lustre/llite/vvp_dev.c @@ -36,6 +36,7 @@ * cl_device and cl_device_type implementation for VVP layer. * * Author: Nikita Danilov + * Author: Jinshan Xiong */ #define DEBUG_SUBSYSTEM S_LLITE @@ -356,23 +357,18 @@ static loff_t vvp_pgcache_find(const struct lu_env *env, return ~0ULL; clob = vvp_pgcache_obj(env, dev, &id); if (clob) { - struct cl_object_header *hdr; - int nr; - struct cl_page *pg; + struct inode *inode = ccc_object_inode(clob); + struct page *vmpage; + int nr; - /* got an object. Find next page. */ - hdr = cl_object_header(clob); - - spin_lock(&hdr->coh_page_guard); - nr = radix_tree_gang_lookup(&hdr->coh_tree, - (void **)&pg, - id.vpi_index, 1); + nr = find_get_pages_contig(inode->i_mapping, + id.vpi_index, 1, &vmpage); if (nr > 0) { - id.vpi_index = pg->cp_index; + id.vpi_index = vmpage->index; /* Cant support over 16T file */ - nr = !(pg->cp_index > 0xffffffff); + nr = !(vmpage->index > 0xffffffff); + page_cache_release(vmpage); } - spin_unlock(&hdr->coh_page_guard); lu_object_ref_del(&clob->co_lu, "dump", current); cl_object_put(env, clob); @@ -431,8 +427,6 @@ static int vvp_pgcache_show(struct seq_file *f, void *v) struct ll_sb_info *sbi; struct cl_object *clob; struct lu_env *env; - struct cl_page *page; - struct cl_object_header *hdr; struct vvp_pgcache_id id; int refcheck; int result; @@ -444,14 +438,23 @@ static int vvp_pgcache_show(struct seq_file *f, void *v) sbi = f->private; clob = vvp_pgcache_obj(env, &sbi->ll_cl->cd_lu_dev, &id); if (clob) { - hdr = cl_object_header(clob); - - spin_lock(&hdr->coh_page_guard); - page = cl_page_lookup(hdr, id.vpi_index); - spin_unlock(&hdr->coh_page_guard); + struct inode *inode = ccc_object_inode(clob); + struct cl_page *page = NULL; + struct page *vmpage; + + result = find_get_pages_contig(inode->i_mapping, + id.vpi_index, 1, + &vmpage); + if (result > 0) { + lock_page(vmpage); + page = cl_vmpage_page(vmpage, clob); + unlock_page(vmpage); + + page_cache_release(vmpage); + } - seq_printf(f, "%8x@"DFID": ", - id.vpi_index, PFID(&hdr->coh_lu.loh_fid)); + seq_printf(f, "%8x@" DFID ": ", id.vpi_index, + PFID(lu_object_fid(&clob->co_lu))); if (page) { vvp_pgcache_page_show(env, f, page); cl_page_put(env, page); diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c index 984699a32c69..ffe301b6f453 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_io.c +++ b/drivers/staging/lustre/lustre/llite/vvp_io.c @@ -763,7 +763,6 @@ static int vvp_io_fault_start(const struct lu_env *env, vmpage = NULL; if (result < 0) { - cl_page_unmap(env, io, page); cl_page_discard(env, io, page); cl_page_disown(env, io, page); diff --git a/drivers/staging/lustre/lustre/llite/vvp_object.c b/drivers/staging/lustre/lustre/llite/vvp_object.c index 03c887d8ed83..b9a1d01a9bd3 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_object.c +++ b/drivers/staging/lustre/lustre/llite/vvp_object.c @@ -165,6 +165,18 @@ static int vvp_conf_set(const struct lu_env *env, struct cl_object *obj, return 0; } +static int vvp_prune(const struct lu_env *env, struct cl_object *obj) +{ + struct inode *inode = ccc_object_inode(obj); + int rc; + + rc = cl_sync_file_range(inode, 0, OBD_OBJECT_EOF, CL_FSYNC_ALL, 1); + if (rc == 0) + truncate_inode_pages(inode->i_mapping, 0); + + return rc; +} + static const struct cl_object_operations vvp_ops = { .coo_page_init = vvp_page_init, .coo_lock_init = vvp_lock_init, @@ -172,6 +184,7 @@ static const struct cl_object_operations vvp_ops = { .coo_attr_get = vvp_attr_get, .coo_attr_set = vvp_attr_set, .coo_conf_set = vvp_conf_set, + .coo_prune = vvp_prune, .coo_glimpse = ccc_object_glimpse }; diff --git a/drivers/staging/lustre/lustre/llite/vvp_page.c b/drivers/staging/lustre/lustre/llite/vvp_page.c index 850bae734075..11e609ebbe3e 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_page.c +++ b/drivers/staging/lustre/lustre/llite/vvp_page.c @@ -138,6 +138,7 @@ static void vvp_page_discard(const struct lu_env *env, struct page *vmpage = cl2vm_page(slice); struct address_space *mapping; struct ccc_page *cpg = cl2ccc_page(slice); + __u64 offset; LASSERT(vmpage); LASSERT(PageLocked(vmpage)); @@ -147,6 +148,9 @@ static void vvp_page_discard(const struct lu_env *env, if (cpg->cpg_defer_uptodate && !cpg->cpg_ra_used) ll_ra_stats_inc(mapping, RA_STAT_DISCARDED); + offset = vmpage->index << PAGE_SHIFT; + ll_teardown_mmaps(vmpage->mapping, offset, offset + PAGE_SIZE); + /* * truncate_complete_page() calls * a_ops->invalidatepage()->cl_page_delete()->vvp_page_delete(). @@ -154,37 +158,26 @@ static void vvp_page_discard(const struct lu_env *env, truncate_complete_page(mapping, vmpage); } -static int vvp_page_unmap(const struct lu_env *env, - const struct cl_page_slice *slice, - struct cl_io *unused) -{ - struct page *vmpage = cl2vm_page(slice); - __u64 offset; - - LASSERT(vmpage); - LASSERT(PageLocked(vmpage)); - - offset = vmpage->index << PAGE_CACHE_SHIFT; - - /* - * XXX is it safe to call this with the page lock held? - */ - ll_teardown_mmaps(vmpage->mapping, offset, offset + PAGE_CACHE_SIZE); - return 0; -} - static void vvp_page_delete(const struct lu_env *env, const struct cl_page_slice *slice) { struct page *vmpage = cl2vm_page(slice); struct inode *inode = vmpage->mapping->host; struct cl_object *obj = slice->cpl_obj; + struct cl_page *page = slice->cpl_page; + int refc; LASSERT(PageLocked(vmpage)); - LASSERT((struct cl_page *)vmpage->private == slice->cpl_page); + LASSERT((struct cl_page *)vmpage->private == page); LASSERT(inode == ccc_object_inode(obj)); vvp_write_complete(cl2ccc(obj), cl2ccc_page(slice)); + + /* Drop the reference count held in vvp_page_init */ + refc = atomic_dec_return(&page->cp_ref); + LASSERTF(refc >= 1, "page = %p, refc = %d\n", page, refc); + + ClearPageUptodate(vmpage); ClearPagePrivate(vmpage); vmpage->private = 0; /* @@ -404,7 +397,6 @@ static const struct cl_page_operations vvp_page_ops = { .cpo_vmpage = ccc_page_vmpage, .cpo_discard = vvp_page_discard, .cpo_delete = vvp_page_delete, - .cpo_unmap = vvp_page_unmap, .cpo_export = vvp_page_export, .cpo_is_vmlocked = vvp_page_is_vmlocked, .cpo_fini = vvp_page_fini, @@ -541,6 +533,8 @@ int vvp_page_init(const struct lu_env *env, struct cl_object *obj, INIT_LIST_HEAD(&cpg->cpg_pending_linkage); if (page->cp_type == CPT_CACHEABLE) { + /* in cache, decref in vvp_page_delete */ + atomic_inc(&page->cp_ref); SetPagePrivate(vmpage); vmpage->private = (unsigned long)page; cl_page_slice_add(page, &cpg->cpg_cl, obj, &vvp_page_ops); diff --git a/drivers/staging/lustre/lustre/lov/lov_object.c b/drivers/staging/lustre/lustre/lov/lov_object.c index 1f8ed95a6d89..5d8a2b64ce21 100644 --- a/drivers/staging/lustre/lustre/lov/lov_object.c +++ b/drivers/staging/lustre/lustre/lov/lov_object.c @@ -287,7 +287,7 @@ static int lov_delete_empty(const struct lu_env *env, struct lov_object *lov, lov_layout_wait(env, lov); - cl_object_prune(env, &lov->lo_cl); + cl_locks_prune(env, &lov->lo_cl, 0); return 0; } @@ -364,7 +364,7 @@ static int lov_delete_raid0(const struct lu_env *env, struct lov_object *lov, } } } - cl_object_prune(env, &lov->lo_cl); + cl_locks_prune(env, &lov->lo_cl, 0); return 0; } @@ -666,7 +666,6 @@ static int lov_layout_change(const struct lu_env *unused, const struct lov_layout_operations *old_ops; const struct lov_layout_operations *new_ops; - struct cl_object_header *hdr = cl_object_header(&lov->lo_cl); void *cookie; struct lu_env *env; int refcheck; @@ -691,13 +690,13 @@ static int lov_layout_change(const struct lu_env *unused, old_ops = &lov_dispatch[lov->lo_type]; new_ops = &lov_dispatch[llt]; + cl_object_prune(env, &lov->lo_cl); + result = old_ops->llo_delete(env, lov, &lov->u); if (result == 0) { old_ops->llo_fini(env, lov, &lov->u); LASSERT(atomic_read(&lov->lo_active_ios) == 0); - LASSERT(!hdr->coh_tree.rnode); - LASSERT(hdr->coh_pages == 0); lov->lo_type = LLT_EMPTY; result = new_ops->llo_init(env, diff --git a/drivers/staging/lustre/lustre/lov/lov_page.c b/drivers/staging/lustre/lustre/lov/lov_page.c index fdcaf8047ad8..9728da245a68 100644 --- a/drivers/staging/lustre/lustre/lov/lov_page.c +++ b/drivers/staging/lustre/lustre/lov/lov_page.c @@ -36,6 +36,7 @@ * Implementation of cl_page for LOV layer. * * Author: Nikita Danilov + * Author: Jinshan Xiong */ #define DEBUG_SUBSYSTEM S_LOV @@ -179,31 +180,21 @@ int lov_page_init_raid0(const struct lu_env *env, struct cl_object *obj, cl_page_slice_add(page, &lpg->lps_cl, obj, &lov_page_ops); sub = lov_sub_get(env, lio, stripe); - if (IS_ERR(sub)) { - rc = PTR_ERR(sub); - goto out; - } + if (IS_ERR(sub)) + return PTR_ERR(sub); subobj = lovsub2cl(r0->lo_sub[stripe]); - subpage = cl_page_find_sub(sub->sub_env, subobj, - cl_index(subobj, suboff), vmpage, page); - lov_sub_put(sub); - if (IS_ERR(subpage)) { - rc = PTR_ERR(subpage); - goto out; - } - - if (likely(subpage->cp_parent == page)) { - lu_ref_add(&subpage->cp_reference, "lov", page); + subpage = cl_page_alloc(sub->sub_env, subobj, cl_index(subobj, suboff), + vmpage, page->cp_type); + if (!IS_ERR(subpage)) { + subpage->cp_parent = page; + page->cp_child = subpage; lpg->lps_invalid = 0; - rc = 0; } else { - CL_PAGE_DEBUG(D_ERROR, env, page, "parent page\n"); - CL_PAGE_DEBUG(D_ERROR, env, subpage, "child page\n"); - LASSERT(0); + rc = PTR_ERR(subpage); } + lov_sub_put(sub); -out: return rc; } diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c index f5128b4f176f..cf9428428d06 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_io.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c @@ -36,6 +36,7 @@ * Client IO. * * Author: Nikita Danilov + * Author: Jinshan Xiong */ #define DEBUG_SUBSYSTEM S_CLASS diff --git a/drivers/staging/lustre/lustre/obdclass/cl_lock.c b/drivers/staging/lustre/lustre/obdclass/cl_lock.c index f952c1cb0761..32ecc5ad0a3e 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_lock.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_lock.c @@ -36,6 +36,7 @@ * Client Extent Lock. * * Author: Nikita Danilov + * Author: Jinshan Xiong */ #define DEBUG_SUBSYSTEM S_CLASS @@ -1815,128 +1816,6 @@ struct cl_lock *cl_lock_at_pgoff(const struct lu_env *env, } EXPORT_SYMBOL(cl_lock_at_pgoff); -/** - * Calculate the page offset at the layer of @lock. - * At the time of this writing, @page is top page and @lock is sub lock. - */ -static pgoff_t pgoff_at_lock(struct cl_page *page, struct cl_lock *lock) -{ - struct lu_device_type *dtype; - const struct cl_page_slice *slice; - - dtype = lock->cll_descr.cld_obj->co_lu.lo_dev->ld_type; - slice = cl_page_at(page, dtype); - return slice->cpl_page->cp_index; -} - -/** - * Check if page @page is covered by an extra lock or discard it. - */ -static int check_and_discard_cb(const struct lu_env *env, struct cl_io *io, - struct cl_page *page, void *cbdata) -{ - struct cl_thread_info *info = cl_env_info(env); - struct cl_lock *lock = cbdata; - pgoff_t index = pgoff_at_lock(page, lock); - - if (index >= info->clt_fn_index) { - struct cl_lock *tmp; - - /* refresh non-overlapped index */ - tmp = cl_lock_at_pgoff(env, lock->cll_descr.cld_obj, index, - lock, 1, 0); - if (tmp) { - /* Cache the first-non-overlapped index so as to skip - * all pages within [index, clt_fn_index). This - * is safe because if tmp lock is canceled, it will - * discard these pages. - */ - info->clt_fn_index = tmp->cll_descr.cld_end + 1; - if (tmp->cll_descr.cld_end == CL_PAGE_EOF) - info->clt_fn_index = CL_PAGE_EOF; - cl_lock_put(env, tmp); - } else if (cl_page_own(env, io, page) == 0) { - /* discard the page */ - cl_page_unmap(env, io, page); - cl_page_discard(env, io, page); - cl_page_disown(env, io, page); - } else { - LASSERT(page->cp_state == CPS_FREEING); - } - } - - info->clt_next_index = index + 1; - return CLP_GANG_OKAY; -} - -static int discard_cb(const struct lu_env *env, struct cl_io *io, - struct cl_page *page, void *cbdata) -{ - struct cl_thread_info *info = cl_env_info(env); - struct cl_lock *lock = cbdata; - - LASSERT(lock->cll_descr.cld_mode >= CLM_WRITE); - KLASSERT(ergo(page->cp_type == CPT_CACHEABLE, - !PageWriteback(cl_page_vmpage(env, page)))); - KLASSERT(ergo(page->cp_type == CPT_CACHEABLE, - !PageDirty(cl_page_vmpage(env, page)))); - - info->clt_next_index = pgoff_at_lock(page, lock) + 1; - if (cl_page_own(env, io, page) == 0) { - /* discard the page */ - cl_page_unmap(env, io, page); - cl_page_discard(env, io, page); - cl_page_disown(env, io, page); - } else { - LASSERT(page->cp_state == CPS_FREEING); - } - - return CLP_GANG_OKAY; -} - -/** - * Discard pages protected by the given lock. This function traverses radix - * tree to find all covering pages and discard them. If a page is being covered - * by other locks, it should remain in cache. - * - * If error happens on any step, the process continues anyway (the reasoning - * behind this being that lock cancellation cannot be delayed indefinitely). - */ -int cl_lock_discard_pages(const struct lu_env *env, struct cl_lock *lock) -{ - struct cl_thread_info *info = cl_env_info(env); - struct cl_io *io = &info->clt_io; - struct cl_lock_descr *descr = &lock->cll_descr; - cl_page_gang_cb_t cb; - int res; - int result; - - LINVRNT(cl_lock_invariant(env, lock)); - - io->ci_obj = cl_object_top(descr->cld_obj); - io->ci_ignore_layout = 1; - result = cl_io_init(env, io, CIT_MISC, io->ci_obj); - if (result != 0) - goto out; - - cb = descr->cld_mode == CLM_READ ? check_and_discard_cb : discard_cb; - info->clt_fn_index = info->clt_next_index = descr->cld_start; - do { - res = cl_page_gang_lookup(env, descr->cld_obj, io, - info->clt_next_index, descr->cld_end, - cb, (void *)lock); - if (info->clt_next_index > descr->cld_end) - break; - - if (res == CLP_GANG_RESCHED) - cond_resched(); - } while (res != CLP_GANG_OKAY); -out: - cl_io_fini(env, io); - return result; -} -EXPORT_SYMBOL(cl_lock_discard_pages); - /** * Eliminate all locks for a given object. * @@ -1951,12 +1830,6 @@ void cl_locks_prune(const struct lu_env *env, struct cl_object *obj, int cancel) struct cl_lock *lock; head = cl_object_header(obj); - /* - * If locks are destroyed without cancellation, all pages must be - * already destroyed (as otherwise they will be left unprotected). - */ - LASSERT(ergo(!cancel, - !head->coh_tree.rnode && head->coh_pages == 0)); spin_lock(&head->coh_lock_guard); while (!list_empty(&head->coh_locks)) { @@ -2095,8 +1968,8 @@ void cl_lock_hold_add(const struct lu_env *env, struct cl_lock *lock, LINVRNT(cl_lock_invariant(env, lock)); LASSERT(lock->cll_state != CLS_FREEING); - cl_lock_hold_mod(env, lock, 1); cl_lock_get(lock); + cl_lock_hold_mod(env, lock, 1); lu_ref_add(&lock->cll_holders, scope, source); lu_ref_add(&lock->cll_reference, scope, source); } diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c index 0772706dbffc..65b640223e8f 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_object.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c @@ -36,6 +36,7 @@ * Client Lustre Object. * * Author: Nikita Danilov + * Author: Jinshan Xiong */ /* @@ -43,7 +44,6 @@ * * i_mutex * PG_locked - * ->coh_page_guard * ->coh_lock_guard * ->coh_attr_guard * ->ls_guard @@ -63,8 +63,6 @@ static struct kmem_cache *cl_env_kmem; -/** Lock class of cl_object_header::coh_page_guard */ -static struct lock_class_key cl_page_guard_class; /** Lock class of cl_object_header::coh_lock_guard */ static struct lock_class_key cl_lock_guard_class; /** Lock class of cl_object_header::coh_attr_guard */ @@ -81,15 +79,10 @@ int cl_object_header_init(struct cl_object_header *h) result = lu_object_header_init(&h->coh_lu); if (result == 0) { - spin_lock_init(&h->coh_page_guard); spin_lock_init(&h->coh_lock_guard); spin_lock_init(&h->coh_attr_guard); - lockdep_set_class(&h->coh_page_guard, &cl_page_guard_class); lockdep_set_class(&h->coh_lock_guard, &cl_lock_guard_class); lockdep_set_class(&h->coh_attr_guard, &cl_attr_guard_class); - h->coh_pages = 0; - /* XXX hard coded GFP_* mask. */ - INIT_RADIX_TREE(&h->coh_tree, GFP_ATOMIC); INIT_LIST_HEAD(&h->coh_locks); h->coh_page_bufsize = ALIGN(sizeof(struct cl_page), 8); } @@ -314,6 +307,32 @@ int cl_conf_set(const struct lu_env *env, struct cl_object *obj, } EXPORT_SYMBOL(cl_conf_set); +/** + * Prunes caches of pages and locks for this object. + */ +void cl_object_prune(const struct lu_env *env, struct cl_object *obj) +{ + struct lu_object_header *top; + struct cl_object *o; + int result; + + top = obj->co_lu.lo_header; + result = 0; + list_for_each_entry(o, &top->loh_layers, co_lu.lo_linkage) { + if (o->co_ops->coo_prune) { + result = o->co_ops->coo_prune(env, o); + if (result != 0) + break; + } + } + + /* TODO: pruning locks will be moved into layers after cl_lock + * simplification is done + */ + cl_locks_prune(env, obj, 1); +} +EXPORT_SYMBOL(cl_object_prune); + /** * Helper function removing all object locks, and marking object for * deletion. All object pages must have been deleted at this point. @@ -326,8 +345,6 @@ void cl_object_kill(const struct lu_env *env, struct cl_object *obj) struct cl_object_header *hdr; hdr = cl_object_header(obj); - LASSERT(!hdr->coh_tree.rnode); - LASSERT(hdr->coh_pages == 0); set_bit(LU_OBJECT_HEARD_BANSHEE, &hdr->coh_lu.loh_flags); /* @@ -341,16 +358,6 @@ void cl_object_kill(const struct lu_env *env, struct cl_object *obj) } EXPORT_SYMBOL(cl_object_kill); -/** - * Prunes caches of pages and locks for this object. - */ -void cl_object_prune(const struct lu_env *env, struct cl_object *obj) -{ - cl_pages_prune(env, obj); - cl_locks_prune(env, obj, 1); -} -EXPORT_SYMBOL(cl_object_prune); - void cache_stats_init(struct cache_stats *cs, const char *name) { int i; diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c index 231a2f26c693..816983678a03 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_page.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c @@ -36,6 +36,7 @@ * Client Lustre Page. * * Author: Nikita Danilov + * Author: Jinshan Xiong */ #define DEBUG_SUBSYSTEM S_CLASS @@ -48,8 +49,7 @@ #include "../include/cl_object.h" #include "cl_internal.h" -static void cl_page_delete0(const struct lu_env *env, struct cl_page *pg, - int radix); +static void cl_page_delete0(const struct lu_env *env, struct cl_page *pg); # define PASSERT(env, page, expr) \ do { \ @@ -79,8 +79,7 @@ static struct cl_page *cl_page_top_trusted(struct cl_page *page) * * This function can be used to obtain initial reference to previously * unreferenced cached object. It can be called only if concurrent page - * reclamation is somehow prevented, e.g., by locking page radix-tree - * (cl_object_header::hdr->coh_page_guard), or by keeping a lock on a VM page, + * reclamation is somehow prevented, e.g., by keeping a lock on a VM page, * associated with \a page. * * Use with care! Not exported. @@ -114,132 +113,6 @@ cl_page_at_trusted(const struct cl_page *page, return NULL; } -/** - * Returns a page with given index in the given object, or NULL if no page is - * found. Acquires a reference on \a page. - * - * Locking: called under cl_object_header::coh_page_guard spin-lock. - */ -struct cl_page *cl_page_lookup(struct cl_object_header *hdr, pgoff_t index) -{ - struct cl_page *page; - - assert_spin_locked(&hdr->coh_page_guard); - - page = radix_tree_lookup(&hdr->coh_tree, index); - if (page) - cl_page_get_trust(page); - return page; -} -EXPORT_SYMBOL(cl_page_lookup); - -/** - * Returns a list of pages by a given [start, end] of \a obj. - * - * \param resched If not NULL, then we give up before hogging CPU for too - * long and set *resched = 1, in that case caller should implement a retry - * logic. - * - * Gang tree lookup (radix_tree_gang_lookup()) optimization is absolutely - * crucial in the face of [offset, EOF] locks. - * - * Return at least one page in @queue unless there is no covered page. - */ -int cl_page_gang_lookup(const struct lu_env *env, struct cl_object *obj, - struct cl_io *io, pgoff_t start, pgoff_t end, - cl_page_gang_cb_t cb, void *cbdata) -{ - struct cl_object_header *hdr; - struct cl_page *page; - struct cl_page **pvec; - const struct cl_page_slice *slice; - const struct lu_device_type *dtype; - pgoff_t idx; - unsigned int nr; - unsigned int i; - unsigned int j; - int res = CLP_GANG_OKAY; - int tree_lock = 1; - - idx = start; - hdr = cl_object_header(obj); - pvec = cl_env_info(env)->clt_pvec; - dtype = cl_object_top(obj)->co_lu.lo_dev->ld_type; - spin_lock(&hdr->coh_page_guard); - while ((nr = radix_tree_gang_lookup(&hdr->coh_tree, (void **)pvec, - idx, CLT_PVEC_SIZE)) > 0) { - int end_of_region = 0; - - idx = pvec[nr - 1]->cp_index + 1; - for (i = 0, j = 0; i < nr; ++i) { - page = pvec[i]; - pvec[i] = NULL; - - LASSERT(page->cp_type == CPT_CACHEABLE); - if (page->cp_index > end) { - end_of_region = 1; - break; - } - if (page->cp_state == CPS_FREEING) - continue; - - slice = cl_page_at_trusted(page, dtype); - /* - * Pages for lsm-less file has no underneath sub-page - * for osc, in case of ... - */ - PASSERT(env, page, slice); - - page = slice->cpl_page; - /* - * Can safely call cl_page_get_trust() under - * radix-tree spin-lock. - * - * XXX not true, because @page is from object another - * than @hdr and protected by different tree lock. - */ - cl_page_get_trust(page); - lu_ref_add_atomic(&page->cp_reference, - "gang_lookup", current); - pvec[j++] = page; - } - - /* - * Here a delicate locking dance is performed. Current thread - * holds a reference to a page, but has to own it before it - * can be placed into queue. Owning implies waiting, so - * radix-tree lock is to be released. After a wait one has to - * check that pages weren't truncated (cl_page_own() returns - * error in the latter case). - */ - spin_unlock(&hdr->coh_page_guard); - tree_lock = 0; - - for (i = 0; i < j; ++i) { - page = pvec[i]; - if (res == CLP_GANG_OKAY) - res = (*cb)(env, io, page, cbdata); - lu_ref_del(&page->cp_reference, - "gang_lookup", current); - cl_page_put(env, page); - } - if (nr < CLT_PVEC_SIZE || end_of_region) - break; - - if (res == CLP_GANG_OKAY && need_resched()) - res = CLP_GANG_RESCHED; - if (res != CLP_GANG_OKAY) - break; - - spin_lock(&hdr->coh_page_guard); - tree_lock = 1; - } - if (tree_lock) - spin_unlock(&hdr->coh_page_guard); - return res; -} -EXPORT_SYMBOL(cl_page_gang_lookup); - static void cl_page_free(const struct lu_env *env, struct cl_page *page) { struct cl_object *obj = page->cp_obj; @@ -276,10 +149,10 @@ static inline void cl_page_state_set_trust(struct cl_page *page, *(enum cl_page_state *)&page->cp_state = state; } -static struct cl_page *cl_page_alloc(const struct lu_env *env, - struct cl_object *o, pgoff_t ind, - struct page *vmpage, - enum cl_page_type type) +struct cl_page *cl_page_alloc(const struct lu_env *env, + struct cl_object *o, pgoff_t ind, + struct page *vmpage, + enum cl_page_type type) { struct cl_page *page; struct lu_object_header *head; @@ -289,8 +162,6 @@ static struct cl_page *cl_page_alloc(const struct lu_env *env, int result = 0; atomic_set(&page->cp_ref, 1); - if (type == CPT_CACHEABLE) /* for radix tree */ - atomic_inc(&page->cp_ref); page->cp_obj = o; cl_object_get(o); lu_object_ref_add_at(&o->co_lu, &page->cp_obj_ref, "cl_page", @@ -309,7 +180,7 @@ static struct cl_page *cl_page_alloc(const struct lu_env *env, result = o->co_ops->coo_page_init(env, o, page, vmpage); if (result != 0) { - cl_page_delete0(env, page, 0); + cl_page_delete0(env, page); cl_page_free(env, page); page = ERR_PTR(result); break; @@ -321,6 +192,7 @@ static struct cl_page *cl_page_alloc(const struct lu_env *env, } return page; } +EXPORT_SYMBOL(cl_page_alloc); /** * Returns a cl_page with index \a idx at the object \a o, and associated with @@ -333,16 +205,13 @@ static struct cl_page *cl_page_alloc(const struct lu_env *env, * * \see cl_object_find(), cl_lock_find() */ -static struct cl_page *cl_page_find0(const struct lu_env *env, - struct cl_object *o, - pgoff_t idx, struct page *vmpage, - enum cl_page_type type, - struct cl_page *parent) +struct cl_page *cl_page_find(const struct lu_env *env, + struct cl_object *o, + pgoff_t idx, struct page *vmpage, + enum cl_page_type type) { struct cl_page *page = NULL; - struct cl_page *ghost = NULL; struct cl_object_header *hdr; - int err; LASSERT(type == CPT_CACHEABLE || type == CPT_TRANSIENT); might_sleep(); @@ -368,90 +237,19 @@ static struct cl_page *cl_page_find0(const struct lu_env *env, * reference on it. */ page = cl_vmpage_page(vmpage, o); - PINVRNT(env, page, - ergo(page, - cl_page_vmpage(env, page) == vmpage && - (void *)radix_tree_lookup(&hdr->coh_tree, - idx) == page)); - } - if (page) - return page; + if (page) + return page; + } /* allocate and initialize cl_page */ page = cl_page_alloc(env, o, idx, vmpage, type); - if (IS_ERR(page)) - return page; - - if (type == CPT_TRANSIENT) { - if (parent) { - LASSERT(!page->cp_parent); - page->cp_parent = parent; - parent->cp_child = page; - } - return page; - } - - /* - * XXX optimization: use radix_tree_preload() here, and change tree - * gfp mask to GFP_KERNEL in cl_object_header_init(). - */ - spin_lock(&hdr->coh_page_guard); - err = radix_tree_insert(&hdr->coh_tree, idx, page); - if (err != 0) { - ghost = page; - /* - * Noted by Jay: a lock on \a vmpage protects cl_page_find() - * from this race, but - * - * 0. it's better to have cl_page interface "locally - * consistent" so that its correctness can be reasoned - * about without appealing to the (obscure world of) VM - * locking. - * - * 1. handling this race allows ->coh_tree to remain - * consistent even when VM locking is somehow busted, - * which is very useful during diagnosing and debugging. - */ - page = ERR_PTR(err); - CL_PAGE_DEBUG(D_ERROR, env, ghost, - "fail to insert into radix tree: %d\n", err); - } else { - if (parent) { - LASSERT(!page->cp_parent); - page->cp_parent = parent; - parent->cp_child = page; - } - hdr->coh_pages++; - } - spin_unlock(&hdr->coh_page_guard); - - if (unlikely(ghost)) { - cl_page_delete0(env, ghost, 0); - cl_page_free(env, ghost); - } return page; } - -struct cl_page *cl_page_find(const struct lu_env *env, struct cl_object *o, - pgoff_t idx, struct page *vmpage, - enum cl_page_type type) -{ - return cl_page_find0(env, o, idx, vmpage, type, NULL); -} EXPORT_SYMBOL(cl_page_find); -struct cl_page *cl_page_find_sub(const struct lu_env *env, struct cl_object *o, - pgoff_t idx, struct page *vmpage, - struct cl_page *parent) -{ - return cl_page_find0(env, o, idx, vmpage, parent->cp_type, parent); -} -EXPORT_SYMBOL(cl_page_find_sub); - static inline int cl_page_invariant(const struct cl_page *pg) { - struct cl_object_header *header; struct cl_page *parent; struct cl_page *child; struct cl_io *owner; @@ -461,7 +259,6 @@ static inline int cl_page_invariant(const struct cl_page *pg) */ LINVRNT(cl_page_is_vmlocked(NULL, pg)); - header = cl_object_header(pg->cp_obj); parent = pg->cp_parent; child = pg->cp_child; owner = pg->cp_owner; @@ -473,15 +270,7 @@ static inline int cl_page_invariant(const struct cl_page *pg) ergo(parent, pg->cp_obj != parent->cp_obj) && ergo(owner && parent, parent->cp_owner == pg->cp_owner->ci_parent) && - ergo(owner && child, child->cp_owner->ci_parent == owner) && - /* - * Either page is early in initialization (has neither child - * nor parent yet), or it is in the object radix tree. - */ - ergo(pg->cp_state < CPS_FREEING && pg->cp_type == CPT_CACHEABLE, - (void *)radix_tree_lookup(&header->coh_tree, - pg->cp_index) == pg || - (!child && !parent)); + ergo(owner && child, child->cp_owner->ci_parent == owner); } static void cl_page_state_set0(const struct lu_env *env, @@ -1001,11 +790,8 @@ EXPORT_SYMBOL(cl_page_discard); * pages, e.g,. in a error handling cl_page_find()->cl_page_delete0() * path. Doesn't check page invariant. */ -static void cl_page_delete0(const struct lu_env *env, struct cl_page *pg, - int radix) +static void cl_page_delete0(const struct lu_env *env, struct cl_page *pg) { - struct cl_page *tmp = pg; - PASSERT(env, pg, pg == cl_page_top(pg)); PASSERT(env, pg, pg->cp_state != CPS_FREEING); @@ -1014,41 +800,11 @@ static void cl_page_delete0(const struct lu_env *env, struct cl_page *pg, */ cl_page_owner_clear(pg); - /* - * unexport the page firstly before freeing it so that - * the page content is considered to be invalid. - * We have to do this because a CPS_FREEING cl_page may - * be NOT under the protection of a cl_lock. - * Afterwards, if this page is found by other threads, then this - * page will be forced to reread. - */ - cl_page_export(env, pg, 0); cl_page_state_set0(env, pg, CPS_FREEING); - CL_PAGE_INVOID(env, pg, CL_PAGE_OP(cpo_delete), - (const struct lu_env *, const struct cl_page_slice *)); - - if (tmp->cp_type == CPT_CACHEABLE) { - if (!radix) - /* !radix means that @pg is not yet in the radix tree, - * skip removing it. - */ - tmp = pg->cp_child; - for (; tmp; tmp = tmp->cp_child) { - void *value; - struct cl_object_header *hdr; - - hdr = cl_object_header(tmp->cp_obj); - spin_lock(&hdr->coh_page_guard); - value = radix_tree_delete(&hdr->coh_tree, - tmp->cp_index); - PASSERT(env, tmp, value == tmp); - PASSERT(env, tmp, hdr->coh_pages > 0); - hdr->coh_pages--; - spin_unlock(&hdr->coh_page_guard); - cl_page_put(env, tmp); - } - } + CL_PAGE_INVOID_REVERSE(env, pg, CL_PAGE_OP(cpo_delete), + (const struct lu_env *, + const struct cl_page_slice *)); } /** @@ -1079,29 +835,10 @@ static void cl_page_delete0(const struct lu_env *env, struct cl_page *pg, void cl_page_delete(const struct lu_env *env, struct cl_page *pg) { PINVRNT(env, pg, cl_page_invariant(pg)); - cl_page_delete0(env, pg, 1); + cl_page_delete0(env, pg); } EXPORT_SYMBOL(cl_page_delete); -/** - * Unmaps page from user virtual memory. - * - * Calls cl_page_operations::cpo_unmap() through all layers top-to-bottom. The - * layer responsible for VM interaction has to unmap page from user space - * virtual memory. - * - * \see cl_page_operations::cpo_unmap() - */ -int cl_page_unmap(const struct lu_env *env, - struct cl_io *io, struct cl_page *pg) -{ - PINVRNT(env, pg, cl_page_is_owned(pg, io)); - PINVRNT(env, pg, cl_page_invariant(pg)); - - return cl_page_invoke(env, io, pg, CL_PAGE_OP(cpo_unmap)); -} -EXPORT_SYMBOL(cl_page_unmap); - /** * Marks page up-to-date. * @@ -1359,53 +1096,6 @@ int cl_page_is_under_lock(const struct lu_env *env, struct cl_io *io, } EXPORT_SYMBOL(cl_page_is_under_lock); -static int page_prune_cb(const struct lu_env *env, struct cl_io *io, - struct cl_page *page, void *cbdata) -{ - cl_page_own(env, io, page); - cl_page_unmap(env, io, page); - cl_page_discard(env, io, page); - cl_page_disown(env, io, page); - return CLP_GANG_OKAY; -} - -/** - * Purges all cached pages belonging to the object \a obj. - */ -int cl_pages_prune(const struct lu_env *env, struct cl_object *clobj) -{ - struct cl_thread_info *info; - struct cl_object *obj = cl_object_top(clobj); - struct cl_io *io; - int result; - - info = cl_env_info(env); - io = &info->clt_io; - - /* - * initialize the io. This is ugly since we never do IO in this - * function, we just make cl_page_list functions happy. -jay - */ - io->ci_obj = obj; - io->ci_ignore_layout = 1; - result = cl_io_init(env, io, CIT_MISC, obj); - if (result != 0) { - cl_io_fini(env, io); - return io->ci_result; - } - - do { - result = cl_page_gang_lookup(env, obj, io, 0, CL_PAGE_EOF, - page_prune_cb, NULL); - if (result == CLP_GANG_RESCHED) - cond_resched(); - } while (result != CLP_GANG_OKAY); - - cl_io_fini(env, io); - return result; -} -EXPORT_SYMBOL(cl_pages_prune); - /** * Tells transfer engine that only part of a page is to be transmitted. * diff --git a/drivers/staging/lustre/lustre/osc/osc_cache.c b/drivers/staging/lustre/lustre/osc/osc_cache.c index 6196c3bc2da7..c9d4e3ca6caa 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cache.c +++ b/drivers/staging/lustre/lustre/osc/osc_cache.c @@ -1015,7 +1015,6 @@ static int osc_extent_truncate(struct osc_extent *ext, pgoff_t trunc_index, lu_ref_add(&page->cp_reference, "truncate", current); if (cl_page_own(env, io, page) == 0) { - cl_page_unmap(env, io, page); cl_page_discard(env, io, page); cl_page_disown(env, io, page); } else { @@ -2136,8 +2135,7 @@ static void osc_check_rpcs(const struct lu_env *env, struct client_obd *cli) cl_object_get(obj); client_obd_list_unlock(&cli->cl_loi_list_lock); - lu_object_ref_add_at(&obj->co_lu, &link, "check", - current); + lu_object_ref_add_at(&obj->co_lu, &link, "check", current); /* attempt some read/write balancing by alternating between * reads and writes in an object. The makes_rpc checks here @@ -2180,8 +2178,7 @@ static void osc_check_rpcs(const struct lu_env *env, struct client_obd *cli) osc_object_unlock(osc); osc_list_maint(cli, osc); - lu_object_ref_del_at(&obj->co_lu, &link, "check", - current); + lu_object_ref_del_at(&obj->co_lu, &link, "check", current); cl_object_put(env, obj); client_obd_list_lock(&cli->cl_loi_list_lock); @@ -2994,4 +2991,204 @@ int osc_cache_writeback_range(const struct lu_env *env, struct osc_object *obj, return result; } +/** + * Returns a list of pages by a given [start, end] of \a obj. + * + * \param resched If not NULL, then we give up before hogging CPU for too + * long and set *resched = 1, in that case caller should implement a retry + * logic. + * + * Gang tree lookup (radix_tree_gang_lookup()) optimization is absolutely + * crucial in the face of [offset, EOF] locks. + * + * Return at least one page in @queue unless there is no covered page. + */ +int osc_page_gang_lookup(const struct lu_env *env, struct cl_io *io, + struct osc_object *osc, pgoff_t start, pgoff_t end, + osc_page_gang_cbt cb, void *cbdata) +{ + struct osc_page *ops; + void **pvec; + pgoff_t idx; + unsigned int nr; + unsigned int i; + unsigned int j; + int res = CLP_GANG_OKAY; + bool tree_lock = true; + + idx = start; + pvec = osc_env_info(env)->oti_pvec; + spin_lock(&osc->oo_tree_lock); + while ((nr = radix_tree_gang_lookup(&osc->oo_tree, pvec, + idx, OTI_PVEC_SIZE)) > 0) { + struct cl_page *page; + bool end_of_region = false; + + for (i = 0, j = 0; i < nr; ++i) { + ops = pvec[i]; + pvec[i] = NULL; + + idx = osc_index(ops); + if (idx > end) { + end_of_region = true; + break; + } + + page = cl_page_top(ops->ops_cl.cpl_page); + LASSERT(page->cp_type == CPT_CACHEABLE); + if (page->cp_state == CPS_FREEING) + continue; + + cl_page_get(page); + lu_ref_add_atomic(&page->cp_reference, + "gang_lookup", current); + pvec[j++] = ops; + } + ++idx; + + /* + * Here a delicate locking dance is performed. Current thread + * holds a reference to a page, but has to own it before it + * can be placed into queue. Owning implies waiting, so + * radix-tree lock is to be released. After a wait one has to + * check that pages weren't truncated (cl_page_own() returns + * error in the latter case). + */ + spin_unlock(&osc->oo_tree_lock); + tree_lock = false; + + for (i = 0; i < j; ++i) { + ops = pvec[i]; + if (res == CLP_GANG_OKAY) + res = (*cb)(env, io, ops, cbdata); + + page = cl_page_top(ops->ops_cl.cpl_page); + lu_ref_del(&page->cp_reference, "gang_lookup", current); + cl_page_put(env, page); + } + if (nr < OTI_PVEC_SIZE || end_of_region) + break; + + if (res == CLP_GANG_OKAY && need_resched()) + res = CLP_GANG_RESCHED; + if (res != CLP_GANG_OKAY) + break; + + spin_lock(&osc->oo_tree_lock); + tree_lock = true; + } + if (tree_lock) + spin_unlock(&osc->oo_tree_lock); + return res; +} + +/** + * Check if page @page is covered by an extra lock or discard it. + */ +static int check_and_discard_cb(const struct lu_env *env, struct cl_io *io, + struct osc_page *ops, void *cbdata) +{ + struct osc_thread_info *info = osc_env_info(env); + struct cl_lock *lock = cbdata; + pgoff_t index; + + index = osc_index(ops); + if (index >= info->oti_fn_index) { + struct cl_lock *tmp; + struct cl_page *page = cl_page_top(ops->ops_cl.cpl_page); + + /* refresh non-overlapped index */ + tmp = cl_lock_at_pgoff(env, lock->cll_descr.cld_obj, index, + lock, 1, 0); + if (tmp) { + /* Cache the first-non-overlapped index so as to skip + * all pages within [index, oti_fn_index). This + * is safe because if tmp lock is canceled, it will + * discard these pages. + */ + info->oti_fn_index = tmp->cll_descr.cld_end + 1; + if (tmp->cll_descr.cld_end == CL_PAGE_EOF) + info->oti_fn_index = CL_PAGE_EOF; + cl_lock_put(env, tmp); + } else if (cl_page_own(env, io, page) == 0) { + /* discard the page */ + cl_page_discard(env, io, page); + cl_page_disown(env, io, page); + } else { + LASSERT(page->cp_state == CPS_FREEING); + } + } + + info->oti_next_index = index + 1; + return CLP_GANG_OKAY; +} + +static int discard_cb(const struct lu_env *env, struct cl_io *io, + struct osc_page *ops, void *cbdata) +{ + struct osc_thread_info *info = osc_env_info(env); + struct cl_lock *lock = cbdata; + struct cl_page *page = cl_page_top(ops->ops_cl.cpl_page); + + LASSERT(lock->cll_descr.cld_mode >= CLM_WRITE); + KLASSERT(ergo(page->cp_type == CPT_CACHEABLE, + !PageWriteback(cl_page_vmpage(env, page)))); + KLASSERT(ergo(page->cp_type == CPT_CACHEABLE, + !PageDirty(cl_page_vmpage(env, page)))); + + /* page is top page. */ + info->oti_next_index = osc_index(ops) + 1; + if (cl_page_own(env, io, page) == 0) { + /* discard the page */ + cl_page_discard(env, io, page); + cl_page_disown(env, io, page); + } else { + LASSERT(page->cp_state == CPS_FREEING); + } + + return CLP_GANG_OKAY; +} + +/** + * Discard pages protected by the given lock. This function traverses radix + * tree to find all covering pages and discard them. If a page is being covered + * by other locks, it should remain in cache. + * + * If error happens on any step, the process continues anyway (the reasoning + * behind this being that lock cancellation cannot be delayed indefinitely). + */ +int osc_lock_discard_pages(const struct lu_env *env, struct osc_lock *ols) +{ + struct osc_thread_info *info = osc_env_info(env); + struct cl_io *io = &info->oti_io; + struct cl_object *osc = ols->ols_cl.cls_obj; + struct cl_lock *lock = ols->ols_cl.cls_lock; + struct cl_lock_descr *descr = &lock->cll_descr; + osc_page_gang_cbt cb; + int res; + int result; + + io->ci_obj = cl_object_top(osc); + io->ci_ignore_layout = 1; + result = cl_io_init(env, io, CIT_MISC, io->ci_obj); + if (result != 0) + goto out; + + cb = descr->cld_mode == CLM_READ ? check_and_discard_cb : discard_cb; + info->oti_fn_index = info->oti_next_index = descr->cld_start; + do { + res = osc_page_gang_lookup(env, io, cl2osc(osc), + info->oti_next_index, descr->cld_end, + cb, (void *)lock); + if (info->oti_next_index > descr->cld_end) + break; + + if (res == CLP_GANG_RESCHED) + cond_resched(); + } while (res != CLP_GANG_OKAY); +out: + cl_io_fini(env, io); + return result; +} + /** @} osc */ diff --git a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h index b6325f5c3542..e70f06ccd095 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h +++ b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h @@ -111,7 +111,12 @@ struct osc_thread_info { struct lustre_handle oti_handle; struct cl_page_list oti_plist; struct cl_io oti_io; - struct cl_page *oti_pvec[OTI_PVEC_SIZE]; + void *oti_pvec[OTI_PVEC_SIZE]; + /** + * Fields used by cl_lock_discard_pages(). + */ + pgoff_t oti_next_index; + pgoff_t oti_fn_index; /* first non-overlapped index */ }; struct osc_object { @@ -161,6 +166,13 @@ struct osc_object { * oo_{read|write}_pages soon. */ spinlock_t oo_lock; + + /** + * Radix tree for caching pages + */ + struct radix_tree_root oo_tree; + spinlock_t oo_tree_lock; + unsigned long oo_npages; }; static inline void osc_object_lock(struct osc_object *obj) @@ -569,6 +581,11 @@ static inline struct osc_page *oap2osc_page(struct osc_async_page *oap) return (struct osc_page *)container_of(oap, struct osc_page, ops_oap); } +static inline pgoff_t osc_index(struct osc_page *opg) +{ + return opg->ops_cl.cpl_page->cp_index; +} + static inline struct osc_lock *cl2osc_lock(const struct cl_lock_slice *slice) { LINVRNT(osc_is_object(&slice->cls_obj->co_lu)); @@ -691,6 +708,14 @@ int osc_extent_finish(const struct lu_env *env, struct osc_extent *ext, int sent, int rc); void osc_extent_release(const struct lu_env *env, struct osc_extent *ext); +int osc_lock_discard_pages(const struct lu_env *env, struct osc_lock *lock); + +typedef int (*osc_page_gang_cbt)(const struct lu_env *, struct cl_io *, + struct osc_page *, void *); +int osc_page_gang_lookup(const struct lu_env *env, struct cl_io *io, + struct osc_object *osc, pgoff_t start, pgoff_t end, + osc_page_gang_cbt cb, void *cbdata); + /** @} osc */ #endif /* OSC_CL_INTERNAL_H */ diff --git a/drivers/staging/lustre/lustre/osc/osc_io.c b/drivers/staging/lustre/lustre/osc/osc_io.c index a0fa5339c4d3..1536d31fd108 100644 --- a/drivers/staging/lustre/lustre/osc/osc_io.c +++ b/drivers/staging/lustre/lustre/osc/osc_io.c @@ -391,18 +391,13 @@ static int osc_async_upcall(void *a, int rc) * Checks that there are no pages being written in the extent being truncated. */ static int trunc_check_cb(const struct lu_env *env, struct cl_io *io, - struct cl_page *page, void *cbdata) + struct osc_page *ops, void *cbdata) { - const struct cl_page_slice *slice; - struct osc_page *ops; + struct cl_page *page = ops->ops_cl.cpl_page; struct osc_async_page *oap; __u64 start = *(__u64 *)cbdata; - slice = cl_page_at(page, &osc_device_type); - LASSERT(slice); - ops = cl2osc_page(slice); oap = &ops->ops_oap; - if (oap->oap_cmd & OBD_BRW_WRITE && !list_empty(&oap->oap_pending_item)) CL_PAGE_DEBUG(D_ERROR, env, page, "exists %llu/%s.\n", @@ -434,8 +429,9 @@ static void osc_trunc_check(const struct lu_env *env, struct cl_io *io, /* * Complain if there are pages in the truncated region. */ - cl_page_gang_lookup(env, clob, io, start + partial, CL_PAGE_EOF, - trunc_check_cb, (void *)&size); + osc_page_gang_lookup(env, io, cl2osc(clob), + start + partial, CL_PAGE_EOF, + trunc_check_cb, (void *)&size); } static int osc_io_setattr_start(const struct lu_env *env, diff --git a/drivers/staging/lustre/lustre/osc/osc_lock.c b/drivers/staging/lustre/lustre/osc/osc_lock.c index 013df9787f3e..3a8a6d129377 100644 --- a/drivers/staging/lustre/lustre/osc/osc_lock.c +++ b/drivers/staging/lustre/lustre/osc/osc_lock.c @@ -36,6 +36,7 @@ * Implementation of cl_lock for OSC layer. * * Author: Nikita Danilov + * Author: Jinshan Xiong */ #define DEBUG_SUBSYSTEM S_OSC @@ -897,11 +898,8 @@ static int osc_ldlm_glimpse_ast(struct ldlm_lock *dlmlock, void *data) static unsigned long osc_lock_weigh(const struct lu_env *env, const struct cl_lock_slice *slice) { - /* - * don't need to grab coh_page_guard since we don't care the exact # - * of pages.. - */ - return cl_object_header(slice->cls_obj)->coh_pages; + /* TODO: check how many pages are covered by this lock */ + return cl2osc(slice->cls_obj)->oo_npages; } static void osc_lock_build_einfo(const struct lu_env *env, @@ -1276,7 +1274,7 @@ static int osc_lock_flush(struct osc_lock *ols, int discard) result = 0; } - rc = cl_lock_discard_pages(env, lock); + rc = osc_lock_discard_pages(env, ols); if (result == 0 && rc < 0) result = rc; diff --git a/drivers/staging/lustre/lustre/osc/osc_object.c b/drivers/staging/lustre/lustre/osc/osc_object.c index 9d474fcdd9a7..2d2d39a82982 100644 --- a/drivers/staging/lustre/lustre/osc/osc_object.c +++ b/drivers/staging/lustre/lustre/osc/osc_object.c @@ -36,6 +36,7 @@ * Implementation of cl_object for OSC layer. * * Author: Nikita Danilov + * Author: Jinshan Xiong */ #define DEBUG_SUBSYSTEM S_OSC @@ -94,6 +95,7 @@ static int osc_object_init(const struct lu_env *env, struct lu_object *obj, atomic_set(&osc->oo_nr_reads, 0); atomic_set(&osc->oo_nr_writes, 0); spin_lock_init(&osc->oo_lock); + spin_lock_init(&osc->oo_tree_lock); cl_object_page_init(lu2cl(obj), sizeof(struct osc_page)); diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c index f0a9870846d7..91ff6070a28d 100644 --- a/drivers/staging/lustre/lustre/osc/osc_page.c +++ b/drivers/staging/lustre/lustre/osc/osc_page.c @@ -36,6 +36,7 @@ * Implementation of cl_page for OSC layer. * * Author: Nikita Danilov + * Author: Jinshan Xiong */ #define DEBUG_SUBSYSTEM S_OSC @@ -326,6 +327,18 @@ static void osc_page_delete(const struct lu_env *env, spin_unlock(&obj->oo_seatbelt); osc_lru_del(osc_cli(obj), opg); + + if (slice->cpl_page->cp_type == CPT_CACHEABLE) { + void *value; + + spin_lock(&obj->oo_tree_lock); + value = radix_tree_delete(&obj->oo_tree, osc_index(opg)); + if (value) + --obj->oo_npages; + spin_unlock(&obj->oo_tree_lock); + + LASSERT(ergo(value, value == opg)); + } } static void osc_page_clip(const struct lu_env *env, @@ -422,8 +435,18 @@ int osc_page_init(const struct lu_env *env, struct cl_object *obj, INIT_LIST_HEAD(&opg->ops_lru); /* reserve an LRU space for this page */ - if (page->cp_type == CPT_CACHEABLE && result == 0) + if (page->cp_type == CPT_CACHEABLE && result == 0) { result = osc_lru_reserve(env, osc, opg); + if (result == 0) { + spin_lock(&osc->oo_tree_lock); + result = radix_tree_insert(&osc->oo_tree, + page->cp_index, opg); + if (result == 0) + ++osc->oo_npages; + spin_unlock(&osc->oo_tree_lock); + LASSERT(result == 0); + } + } return result; } @@ -611,7 +634,6 @@ static void discard_pagevec(const struct lu_env *env, struct cl_io *io, struct cl_page *page = pvec[i]; LASSERT(cl_page_is_owned(page, io)); - cl_page_unmap(env, io, page); cl_page_discard(env, io, page); cl_page_disown(env, io, page); cl_page_put(env, page); @@ -652,7 +674,7 @@ int osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, atomic_inc(&cli->cl_lru_shrinkers); } - pvec = osc_env_info(env)->oti_pvec; + pvec = (struct cl_page **)osc_env_info(env)->oti_pvec; io = &osc_env_info(env)->oti_io; client_obd_list_lock(&cli->cl_lru_list_lock); -- cgit v1.2.3 From 3c361c1c6f64a675ced590df4a68956020de4a93 Mon Sep 17 00:00:00 2001 From: Jinshan Xiong Date: Wed, 30 Mar 2016 19:48:29 -0400 Subject: staging/lustre/obdclass: Add a preallocated percpu cl_env This change adds support for a single preallocated cl_env per CPU which can be used in circumstances where reschedule is not possible. Currently this interface is only used by the ll_releasepage function. Signed-off-by: Jinshan Xiong Signed-off-by: Prakash Surya Reviewed-on: http://review.whamcloud.com/8174 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-3321 Reviewed-by: Lai Siyao Reviewed-by: Bobi Jam Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/cl_object.h | 12 +++ drivers/staging/lustre/lustre/llite/rw26.c | 54 +++++++---- drivers/staging/lustre/lustre/obdclass/cl_lock.c | 1 - drivers/staging/lustre/lustre/obdclass/cl_object.c | 107 +++++++++++++++++++++ drivers/staging/lustre/lustre/obdclass/cl_page.c | 1 - 5 files changed, 152 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h index 5daf68815949..e8455dc1ce5d 100644 --- a/drivers/staging/lustre/lustre/include/cl_object.h +++ b/drivers/staging/lustre/lustre/include/cl_object.h @@ -2773,6 +2773,16 @@ static inline void *cl_object_page_slice(struct cl_object *clob, return (void *)((char *)page + clob->co_slice_off); } +/** + * Return refcount of cl_object. + */ +static inline int cl_object_refc(struct cl_object *clob) +{ + struct lu_object_header *header = clob->co_lu.lo_header; + + return atomic_read(&header->loh_ref); +} + /** @} cl_object */ /** \defgroup cl_page cl_page @@ -3226,6 +3236,8 @@ void cl_env_reexit(void *cookie); void cl_env_implant(struct lu_env *env, int *refcheck); void cl_env_unplant(struct lu_env *env, int *refcheck); unsigned int cl_env_cache_purge(unsigned int nr); +struct lu_env *cl_env_percpu_get(void); +void cl_env_percpu_put(struct lu_env *env); /** @} cl_env */ diff --git a/drivers/staging/lustre/lustre/llite/rw26.c b/drivers/staging/lustre/lustre/llite/rw26.c index b5335de216be..cc49c21cfb8c 100644 --- a/drivers/staging/lustre/lustre/llite/rw26.c +++ b/drivers/staging/lustre/lustre/llite/rw26.c @@ -107,12 +107,12 @@ static void ll_invalidatepage(struct page *vmpage, unsigned int offset, static int ll_releasepage(struct page *vmpage, gfp_t gfp_mask) { - struct cl_env_nest nest; struct lu_env *env; + void *cookie; struct cl_object *obj; struct cl_page *page; struct address_space *mapping; - int result; + int result = 0; LASSERT(PageLocked(vmpage)); if (PageWriteback(vmpage) || PageDirty(vmpage)) @@ -126,30 +126,42 @@ static int ll_releasepage(struct page *vmpage, gfp_t gfp_mask) if (!obj) return 1; - /* 1 for page allocator, 1 for cl_page and 1 for page cache */ + /* 1 for caller, 1 for cl_page and 1 for page cache */ if (page_count(vmpage) > 3) return 0; - /* TODO: determine what gfp should be used by @gfp_mask. */ - env = cl_env_nested_get(&nest); - if (IS_ERR(env)) - /* If we can't allocate an env we won't call cl_page_put() - * later on which further means it's impossible to drop - * page refcount by cl_page, so ask kernel to not free - * this page. - */ - return 0; - page = cl_vmpage_page(vmpage, obj); - result = !page; - if (page) { - if (!cl_page_in_use(page)) { - result = 1; - cl_page_delete(env, page); - } - cl_page_put(env, page); + if (!page) + return 1; + + cookie = cl_env_reenter(); + env = cl_env_percpu_get(); + LASSERT(!IS_ERR(env)); + + if (!cl_page_in_use(page)) { + result = 1; + cl_page_delete(env, page); } - cl_env_nested_put(&nest, env); + + /* To use percpu env array, the call path can not be rescheduled; + * otherwise percpu array will be messed if ll_releaspage() called + * again on the same CPU. + * + * If this page holds the last refc of cl_object, the following + * call path may cause reschedule: + * cl_page_put -> cl_page_free -> cl_object_put -> + * lu_object_put -> lu_object_free -> lov_delete_raid0 -> + * cl_locks_prune. + * + * However, the kernel can't get rid of this inode until all pages have + * been cleaned up. Now that we hold page lock here, it's pretty safe + * that we won't get into object delete path. + */ + LASSERT(cl_object_refc(obj) > 1); + cl_page_put(env, page); + + cl_env_percpu_put(env); + cl_env_reexit(cookie); return result; } diff --git a/drivers/staging/lustre/lustre/obdclass/cl_lock.c b/drivers/staging/lustre/lustre/obdclass/cl_lock.c index 32ecc5ad0a3e..fe8059a0ce5d 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_lock.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_lock.c @@ -255,7 +255,6 @@ static void cl_lock_free(const struct lu_env *env, struct cl_lock *lock) LINVRNT(!cl_lock_is_mutexed(lock)); cl_lock_trace(D_DLMTRACE, env, "free lock", lock); - might_sleep(); while (!list_empty(&lock->cll_layers)) { struct cl_lock_slice *slice; diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c index 65b640223e8f..fa9b083915d9 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_object.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c @@ -390,6 +390,8 @@ static int cache_stats_print(const struct cache_stats *cs, return 0; } +static void cl_env_percpu_refill(void); + /** * Initialize client site. * @@ -409,6 +411,7 @@ int cl_site_init(struct cl_site *s, struct cl_device *d) atomic_set(&s->cs_pages_state[0], 0); for (i = 0; i < ARRAY_SIZE(s->cs_locks_state); ++i) atomic_set(&s->cs_locks_state[i], 0); + cl_env_percpu_refill(); } return result; } @@ -1001,6 +1004,104 @@ void cl_lvb2attr(struct cl_attr *attr, const struct ost_lvb *lvb) } EXPORT_SYMBOL(cl_lvb2attr); +static struct cl_env cl_env_percpu[NR_CPUS]; + +static int cl_env_percpu_init(void) +{ + struct cl_env *cle; + int tags = LCT_REMEMBER | LCT_NOREF; + int i, j; + int rc = 0; + + for_each_possible_cpu(i) { + struct lu_env *env; + + cle = &cl_env_percpu[i]; + env = &cle->ce_lu; + + INIT_LIST_HEAD(&cle->ce_linkage); + cle->ce_magic = &cl_env_init0; + rc = lu_env_init(env, LCT_CL_THREAD | tags); + if (rc == 0) { + rc = lu_context_init(&cle->ce_ses, LCT_SESSION | tags); + if (rc == 0) { + lu_context_enter(&cle->ce_ses); + env->le_ses = &cle->ce_ses; + } else { + lu_env_fini(env); + } + } + if (rc != 0) + break; + } + if (rc != 0) { + /* Indices 0 to i (excluding i) were correctly initialized, + * thus we must uninitialize up to i, the rest are undefined. + */ + for (j = 0; j < i; j++) { + cle = &cl_env_percpu[i]; + lu_context_exit(&cle->ce_ses); + lu_context_fini(&cle->ce_ses); + lu_env_fini(&cle->ce_lu); + } + } + + return rc; +} + +static void cl_env_percpu_fini(void) +{ + int i; + + for_each_possible_cpu(i) { + struct cl_env *cle = &cl_env_percpu[i]; + + lu_context_exit(&cle->ce_ses); + lu_context_fini(&cle->ce_ses); + lu_env_fini(&cle->ce_lu); + } +} + +static void cl_env_percpu_refill(void) +{ + int i; + + for_each_possible_cpu(i) + lu_env_refill(&cl_env_percpu[i].ce_lu); +} + +void cl_env_percpu_put(struct lu_env *env) +{ + struct cl_env *cle; + int cpu; + + cpu = smp_processor_id(); + cle = cl_env_container(env); + LASSERT(cle == &cl_env_percpu[cpu]); + + cle->ce_ref--; + LASSERT(cle->ce_ref == 0); + + CL_ENV_DEC(busy); + cl_env_detach(cle); + cle->ce_debug = NULL; + + put_cpu(); +} +EXPORT_SYMBOL(cl_env_percpu_put); + +struct lu_env *cl_env_percpu_get() +{ + struct cl_env *cle; + + cle = &cl_env_percpu[get_cpu()]; + cl_env_init0(cle, __builtin_return_address(0)); + + cl_env_attach(cle); + return &cle->ce_lu; +} +EXPORT_SYMBOL(cl_env_percpu_get); + /***************************************************************************** * * Temporary prototype thing: mirror obd-devices into cl devices. @@ -1154,6 +1255,11 @@ int cl_global_init(void) if (result) goto out_lock; + result = cl_env_percpu_init(); + if (result) + /* no cl_env_percpu_fini on error */ + goto out_lock; + return 0; out_lock: cl_lock_fini(); @@ -1171,6 +1277,7 @@ out_store: */ void cl_global_fini(void) { + cl_env_percpu_fini(); cl_lock_fini(); cl_page_fini(); lu_context_key_degister(&cl_key); diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c index 816983678a03..bab8a74b78ae 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_page.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c @@ -123,7 +123,6 @@ static void cl_page_free(const struct lu_env *env, struct cl_page *page) PASSERT(env, page, !page->cp_parent); PASSERT(env, page, page->cp_state == CPS_FREEING); - might_sleep(); while (!list_empty(&page->cp_layers)) { struct cl_page_slice *slice; -- cgit v1.2.3 From 77605e41a26f22343db90d6434970a1800e5e8b5 Mon Sep 17 00:00:00 2001 From: Jinshan Xiong Date: Wed, 30 Mar 2016 19:48:30 -0400 Subject: staging/lustre/clio: add pages into writeback cache in batches in ll_write_end(), instead of adding the page into writeback cache directly, it will be held in a page list. After enough pages have been collected, issue them all with cio_commit_async(). Signed-off-by: Jinshan Xiong Reviewed-on: http://review.whamcloud.com/7893 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-3321 Reviewed-by: Bobi Jam Reviewed-by: Lai Siyao Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/cl_object.h | 77 ++-- drivers/staging/lustre/lustre/include/lclient.h | 6 + drivers/staging/lustre/lustre/llite/file.c | 11 +- .../staging/lustre/lustre/llite/llite_internal.h | 8 +- drivers/staging/lustre/lustre/llite/rw.c | 186 ++------ drivers/staging/lustre/lustre/llite/rw26.c | 210 +++++++-- drivers/staging/lustre/lustre/llite/vvp_internal.h | 10 +- drivers/staging/lustre/lustre/llite/vvp_io.c | 490 +++++++++++---------- .../staging/lustre/lustre/lov/lov_cl_internal.h | 2 + drivers/staging/lustre/lustre/lov/lov_io.c | 219 ++++----- drivers/staging/lustre/lustre/lov/lov_page.c | 28 -- drivers/staging/lustre/lustre/obdclass/cl_io.c | 108 ++--- drivers/staging/lustre/lustre/obdclass/cl_page.c | 38 -- .../staging/lustre/lustre/obdecho/echo_client.c | 25 +- drivers/staging/lustre/lustre/osc/osc_cache.c | 14 +- .../staging/lustre/lustre/osc/osc_cl_internal.h | 2 + drivers/staging/lustre/lustre/osc/osc_internal.h | 6 + drivers/staging/lustre/lustre/osc/osc_io.c | 160 ++++--- drivers/staging/lustre/lustre/osc/osc_page.c | 32 +- drivers/staging/lustre/lustre/osc/osc_request.c | 56 ++- 20 files changed, 792 insertions(+), 896 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h index e8455dc1ce5d..c3865ec49769 100644 --- a/drivers/staging/lustre/lustre/include/cl_object.h +++ b/drivers/staging/lustre/lustre/include/cl_object.h @@ -1019,26 +1019,6 @@ struct cl_page_operations { */ int (*cpo_make_ready)(const struct lu_env *env, const struct cl_page_slice *slice); - /** - * Announce that this page is to be written out - * opportunistically, that is, page is dirty, it is not - * necessary to start write-out transfer right now, but - * eventually page has to be written out. - * - * Main caller of this is the write path (see - * vvp_io_commit_write()), using this method to build a - * "transfer cache" from which large transfers are then - * constructed by the req-formation engine. - * - * \todo XXX it would make sense to add page-age tracking - * semantics here, and to oblige the req-formation engine to - * send the page out not later than it is too old. - * - * \see cl_page_cache_add() - */ - int (*cpo_cache_add)(const struct lu_env *env, - const struct cl_page_slice *slice, - struct cl_io *io); } io[CRT_NR]; /** * Tell transfer engine that only [to, from] part of a page should be @@ -2023,6 +2003,8 @@ struct cl_io_slice { struct list_head cis_linkage; }; +typedef void (*cl_commit_cbt)(const struct lu_env *, struct cl_io *, + struct cl_page *); /** * Per-layer io operations. * \see vvp_io_ops, lov_io_ops, lovsub_io_ops, osc_io_ops @@ -2106,7 +2088,7 @@ struct cl_io_operations { void (*cio_fini)(const struct lu_env *env, const struct cl_io_slice *slice); } op[CIT_OP_NR]; - struct { + /** * Submit pages from \a queue->c2_qin for IO, and move * successfully submitted pages into \a queue->c2_qout. Return @@ -2119,7 +2101,15 @@ struct cl_io_operations { const struct cl_io_slice *slice, enum cl_req_type crt, struct cl_2queue *queue); - } req_op[CRT_NR]; + /** + * Queue async page for write. + * The difference between cio_submit and cio_queue is that + * cio_submit is for urgent request. + */ + int (*cio_commit_async)(const struct lu_env *env, + const struct cl_io_slice *slice, + struct cl_page_list *queue, int from, int to, + cl_commit_cbt cb); /** * Read missing page. * @@ -2131,31 +2121,6 @@ struct cl_io_operations { int (*cio_read_page)(const struct lu_env *env, const struct cl_io_slice *slice, const struct cl_page_slice *page); - /** - * Prepare write of a \a page. Called bottom-to-top by a top-level - * cl_io_operations::op[CIT_WRITE]::cio_start() to prepare page for - * get data from user-level buffer. - * - * \pre io->ci_type == CIT_WRITE - * - * \see vvp_io_prepare_write(), lov_io_prepare_write(), - * osc_io_prepare_write(). - */ - int (*cio_prepare_write)(const struct lu_env *env, - const struct cl_io_slice *slice, - const struct cl_page_slice *page, - unsigned from, unsigned to); - /** - * - * \pre io->ci_type == CIT_WRITE - * - * \see vvp_io_commit_write(), lov_io_commit_write(), - * osc_io_commit_write(). - */ - int (*cio_commit_write)(const struct lu_env *env, - const struct cl_io_slice *slice, - const struct cl_page_slice *page, - unsigned from, unsigned to); /** * Optional debugging helper. Print given io slice. */ @@ -3044,15 +3009,14 @@ int cl_io_lock_alloc_add(const struct lu_env *env, struct cl_io *io, struct cl_lock_descr *descr); int cl_io_read_page(const struct lu_env *env, struct cl_io *io, struct cl_page *page); -int cl_io_prepare_write(const struct lu_env *env, struct cl_io *io, - struct cl_page *page, unsigned from, unsigned to); -int cl_io_commit_write(const struct lu_env *env, struct cl_io *io, - struct cl_page *page, unsigned from, unsigned to); int cl_io_submit_rw(const struct lu_env *env, struct cl_io *io, enum cl_req_type iot, struct cl_2queue *queue); int cl_io_submit_sync(const struct lu_env *env, struct cl_io *io, enum cl_req_type iot, struct cl_2queue *queue, long timeout); +int cl_io_commit_async(const struct lu_env *env, struct cl_io *io, + struct cl_page_list *queue, int from, int to, + cl_commit_cbt cb); int cl_io_is_going(const struct lu_env *env); /** @@ -3108,6 +3072,12 @@ static inline struct cl_page *cl_page_list_last(struct cl_page_list *plist) return list_entry(plist->pl_pages.prev, struct cl_page, cp_batch); } +static inline struct cl_page *cl_page_list_first(struct cl_page_list *plist) +{ + LASSERT(plist->pl_nr > 0); + return list_entry(plist->pl_pages.next, struct cl_page, cp_batch); +} + /** * Iterate over pages in a page list. */ @@ -3124,9 +3094,14 @@ void cl_page_list_init(struct cl_page_list *plist); void cl_page_list_add(struct cl_page_list *plist, struct cl_page *page); void cl_page_list_move(struct cl_page_list *dst, struct cl_page_list *src, struct cl_page *page); +void cl_page_list_move_head(struct cl_page_list *dst, struct cl_page_list *src, + struct cl_page *page); void cl_page_list_splice(struct cl_page_list *list, struct cl_page_list *head); +void cl_page_list_del(const struct lu_env *env, struct cl_page_list *plist, + struct cl_page *page); void cl_page_list_disown(const struct lu_env *env, struct cl_io *io, struct cl_page_list *plist); +void cl_page_list_fini(const struct lu_env *env, struct cl_page_list *plist); void cl_2queue_init(struct cl_2queue *queue); void cl_2queue_disown(const struct lu_env *env, diff --git a/drivers/staging/lustre/lustre/include/lclient.h b/drivers/staging/lustre/lustre/include/lclient.h index 5d839a9f789f..6c3a30af0727 100644 --- a/drivers/staging/lustre/lustre/include/lclient.h +++ b/drivers/staging/lustre/lustre/include/lclient.h @@ -91,6 +91,12 @@ struct ccc_io { struct { enum ccc_setattr_lock_type cui_local_lock; } setattr; + struct { + struct cl_page_list cui_queue; + unsigned long cui_written; + int cui_from; + int cui_to; + } write; } u; /** * True iff io is processing glimpse right now. diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index cf619af3caf5..127fff6ebe44 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -1120,6 +1120,9 @@ ll_file_io_generic(const struct lu_env *env, struct vvp_io_args *args, struct cl_io *io; ssize_t result; + CDEBUG(D_VFSTRACE, "file: %s, type: %d ppos: %llu, count: %zd\n", + file->f_path.dentry->d_name.name, iot, *ppos, count); + restart: io = ccc_env_thread_io(env); ll_io_init(io, file, iot == CIT_WRITE); @@ -1144,9 +1147,8 @@ restart: goto out; } write_mutex_locked = 1; - } else if (iot == CIT_READ) { - down_read(&lli->lli_trunc_sem); } + down_read(&lli->lli_trunc_sem); break; case IO_SPLICE: vio->u.splice.cui_pipe = args->u.splice.via_pipe; @@ -1157,10 +1159,10 @@ restart: LBUG(); } result = cl_io_loop(env, io); + if (args->via_io_subtype == IO_NORMAL) + up_read(&lli->lli_trunc_sem); if (write_mutex_locked) mutex_unlock(&lli->lli_write_mutex); - else if (args->via_io_subtype == IO_NORMAL && iot == CIT_READ) - up_read(&lli->lli_trunc_sem); } else { /* cl_io_rw_init() handled IO */ result = io->ci_result; @@ -1197,6 +1199,7 @@ out: fd->fd_write_failed = true; } } + CDEBUG(D_VFSTRACE, "iot: %d, result: %zd\n", iot, result); return result; } diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index 3e1572cb457b..08fe0ea5ee8f 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -697,8 +697,6 @@ int ll_md_blocking_ast(struct ldlm_lock *, struct ldlm_lock_desc *, struct dentry *ll_splice_alias(struct inode *inode, struct dentry *de); /* llite/rw.c */ -int ll_prepare_write(struct file *, struct page *, unsigned from, unsigned to); -int ll_commit_write(struct file *, struct page *, unsigned from, unsigned to); int ll_writepage(struct page *page, struct writeback_control *wbc); int ll_writepages(struct address_space *, struct writeback_control *wbc); int ll_readpage(struct file *file, struct page *page); @@ -706,6 +704,9 @@ void ll_readahead_init(struct inode *inode, struct ll_readahead_state *ras); int ll_readahead(const struct lu_env *env, struct cl_io *io, struct ll_readahead_state *ras, struct address_space *mapping, struct cl_page_list *queue, int flags); +int vvp_io_write_commit(const struct lu_env *env, struct cl_io *io); +struct ll_cl_context *ll_cl_init(struct file *file, struct page *vmpage); +void ll_cl_fini(struct ll_cl_context *lcc); extern const struct address_space_operations ll_aops; @@ -1476,4 +1477,7 @@ int ll_layout_restore(struct inode *inode); int ll_xattr_init(void); void ll_xattr_fini(void); +int ll_page_sync_io(const struct lu_env *env, struct cl_io *io, + struct cl_page *page, enum cl_req_type crt); + #endif /* LLITE_INTERNAL_H */ diff --git a/drivers/staging/lustre/lustre/llite/rw.c b/drivers/staging/lustre/lustre/llite/rw.c index 01b8365c1dda..dcccdecbad00 100644 --- a/drivers/staging/lustre/lustre/llite/rw.c +++ b/drivers/staging/lustre/lustre/llite/rw.c @@ -63,7 +63,7 @@ * Finalizes cl-data before exiting typical address_space operation. Dual to * ll_cl_init(). */ -static void ll_cl_fini(struct ll_cl_context *lcc) +void ll_cl_fini(struct ll_cl_context *lcc) { struct lu_env *env = lcc->lcc_env; struct cl_io *io = lcc->lcc_io; @@ -84,8 +84,7 @@ static void ll_cl_fini(struct ll_cl_context *lcc) * Initializes common cl-data at the typical address_space operation entry * point. */ -static struct ll_cl_context *ll_cl_init(struct file *file, - struct page *vmpage, int create) +struct ll_cl_context *ll_cl_init(struct file *file, struct page *vmpage) { struct ll_cl_context *lcc; struct lu_env *env; @@ -96,7 +95,7 @@ static struct ll_cl_context *ll_cl_init(struct file *file, int refcheck; int result = 0; - clob = ll_i2info(vmpage->mapping->host)->lli_clob; + clob = ll_i2info(file_inode(file))->lli_clob; LASSERT(clob); env = cl_env_get(&refcheck); @@ -111,62 +110,18 @@ static struct ll_cl_context *ll_cl_init(struct file *file, cio = ccc_env_io(env); io = cio->cui_cl.cis_io; - if (!io && create) { - struct inode *inode = vmpage->mapping->host; - loff_t pos; + lcc->lcc_io = io; + if (!io) { + struct inode *inode = file_inode(file); - if (inode_trylock(inode)) { - inode_unlock((inode)); + CERROR("%s: " DFID " no active IO, please file a ticket.\n", + ll_get_fsname(inode->i_sb, NULL, 0), + PFID(ll_inode2fid(inode))); + dump_stack(); - /* this is too bad. Someone is trying to write the - * page w/o holding inode mutex. This means we can - * add dirty pages into cache during truncate - */ - CERROR("Proc %s is dirtying page w/o inode lock, this will break truncate\n", - current->comm); - dump_stack(); - LBUG(); - return ERR_PTR(-EIO); - } - - /* - * Loop-back driver calls ->prepare_write(). - * methods directly, bypassing file system ->write() operation, - * so cl_io has to be created here. - */ - io = ccc_env_thread_io(env); - ll_io_init(io, file, 1); - - /* No lock at all for this kind of IO - we can't do it because - * we have held page lock, it would cause deadlock. - * XXX: This causes poor performance to loop device - One page - * per RPC. - * In order to get better performance, users should use - * lloop driver instead. - */ - io->ci_lockreq = CILR_NEVER; - - pos = vmpage->index << PAGE_CACHE_SHIFT; - - /* Create a temp IO to serve write. */ - result = cl_io_rw_init(env, io, CIT_WRITE, pos, PAGE_CACHE_SIZE); - if (result == 0) { - cio->cui_fd = LUSTRE_FPRIVATE(file); - cio->cui_iter = NULL; - result = cl_io_iter_init(env, io); - if (result == 0) { - result = cl_io_lock(env, io); - if (result == 0) - result = cl_io_start(env, io); - } - } else - result = io->ci_result; - } - - lcc->lcc_io = io; - if (!io) result = -EIO; - if (result == 0) { + } + if (result == 0 && vmpage) { struct cl_page *page; LASSERT(io->ci_state == CIS_IO_GOING); @@ -185,99 +140,9 @@ static struct ll_cl_context *ll_cl_init(struct file *file, lcc = ERR_PTR(result); } - CDEBUG(D_VFSTRACE, "%lu@"DFID" -> %d %p %p\n", - vmpage->index, PFID(lu_object_fid(&clob->co_lu)), result, - env, io); return lcc; } -static struct ll_cl_context *ll_cl_get(void) -{ - struct ll_cl_context *lcc; - struct lu_env *env; - int refcheck; - - env = cl_env_get(&refcheck); - LASSERT(!IS_ERR(env)); - lcc = &vvp_env_info(env)->vti_io_ctx; - LASSERT(env == lcc->lcc_env); - LASSERT(current == lcc->lcc_cookie); - cl_env_put(env, &refcheck); - - /* env has got in ll_cl_init, so it is still usable. */ - return lcc; -} - -/** - * ->prepare_write() address space operation called by generic_file_write() - * for every page during write. - */ -int ll_prepare_write(struct file *file, struct page *vmpage, unsigned from, - unsigned to) -{ - struct ll_cl_context *lcc; - int result; - - lcc = ll_cl_init(file, vmpage, 1); - if (!IS_ERR(lcc)) { - struct lu_env *env = lcc->lcc_env; - struct cl_io *io = lcc->lcc_io; - struct cl_page *page = lcc->lcc_page; - - cl_page_assume(env, io, page); - - result = cl_io_prepare_write(env, io, page, from, to); - if (result == 0) { - /* - * Add a reference, so that page is not evicted from - * the cache until ->commit_write() is called. - */ - cl_page_get(page); - lu_ref_add(&page->cp_reference, "prepare_write", - current); - } else { - cl_page_unassume(env, io, page); - ll_cl_fini(lcc); - } - /* returning 0 in prepare assumes commit must be called - * afterwards - */ - } else { - result = PTR_ERR(lcc); - } - return result; -} - -int ll_commit_write(struct file *file, struct page *vmpage, unsigned from, - unsigned to) -{ - struct ll_cl_context *lcc; - struct lu_env *env; - struct cl_io *io; - struct cl_page *page; - int result = 0; - - lcc = ll_cl_get(); - env = lcc->lcc_env; - page = lcc->lcc_page; - io = lcc->lcc_io; - - LASSERT(cl_page_is_owned(page, io)); - LASSERT(from <= to); - if (from != to) /* handle short write case. */ - result = cl_io_commit_write(env, io, page, from, to); - if (cl_page_is_owned(page, io)) - cl_page_unassume(env, io, page); - - /* - * Release reference acquired by ll_prepare_write(). - */ - lu_ref_del(&page->cp_reference, "prepare_write", current); - cl_page_put(env, page); - ll_cl_fini(lcc); - return result; -} - static void ll_ra_stats_inc_sbi(struct ll_sb_info *sbi, enum ra_stat which); /** @@ -1251,7 +1116,7 @@ int ll_readpage(struct file *file, struct page *vmpage) struct ll_cl_context *lcc; int result; - lcc = ll_cl_init(file, vmpage, 0); + lcc = ll_cl_init(file, vmpage); if (!IS_ERR(lcc)) { struct lu_env *env = lcc->lcc_env; struct cl_io *io = lcc->lcc_io; @@ -1273,3 +1138,28 @@ int ll_readpage(struct file *file, struct page *vmpage) } return result; } + +int ll_page_sync_io(const struct lu_env *env, struct cl_io *io, + struct cl_page *page, enum cl_req_type crt) +{ + struct cl_2queue *queue; + int result; + + LASSERT(io->ci_type == CIT_READ || io->ci_type == CIT_WRITE); + + queue = &io->ci_queue; + cl_2queue_init_page(queue, page); + + result = cl_io_submit_sync(env, io, crt, queue, 0); + LASSERT(cl_page_is_owned(page, io)); + + if (crt == CRT_READ) + /* + * in CRT_WRITE case page is left locked even in case of + * error. + */ + cl_page_list_disown(env, io, &queue->c2_qin); + cl_2queue_fini(env, queue); + + return result; +} diff --git a/drivers/staging/lustre/lustre/llite/rw26.c b/drivers/staging/lustre/lustre/llite/rw26.c index cc49c21cfb8c..e8d29e1fb691 100644 --- a/drivers/staging/lustre/lustre/llite/rw26.c +++ b/drivers/staging/lustre/lustre/llite/rw26.c @@ -462,57 +462,211 @@ out: inode_unlock(inode); if (tot_bytes > 0) { - if (iov_iter_rw(iter) == WRITE) { - struct lov_stripe_md *lsm; - - lsm = ccc_inode_lsm_get(inode); - LASSERT(lsm); - lov_stripe_lock(lsm); - obd_adjust_kms(ll_i2dtexp(inode), lsm, file_offset, 0); - lov_stripe_unlock(lsm); - ccc_inode_lsm_put(inode, lsm); - } + struct ccc_io *cio = ccc_env_io(env); + + /* no commit async for direct IO */ + cio->u.write.cui_written += tot_bytes; } cl_env_put(env, &refcheck); return tot_bytes ? : result; } +/** + * Prepare partially written-to page for a write. + */ +static int ll_prepare_partial_page(const struct lu_env *env, struct cl_io *io, + struct cl_page *pg) +{ + struct cl_object *obj = io->ci_obj; + struct cl_attr *attr = ccc_env_thread_attr(env); + loff_t offset = cl_offset(obj, pg->cp_index); + int result; + + cl_object_attr_lock(obj); + result = cl_object_attr_get(env, obj, attr); + cl_object_attr_unlock(obj); + if (result == 0) { + struct ccc_page *cp; + + cp = cl2ccc_page(cl_page_at(pg, &vvp_device_type)); + + /* + * If are writing to a new page, no need to read old data. + * The extent locking will have updated the KMS, and for our + * purposes here we can treat it like i_size. + */ + if (attr->cat_kms <= offset) { + char *kaddr = kmap_atomic(cp->cpg_page); + + memset(kaddr, 0, cl_page_size(obj)); + kunmap_atomic(kaddr); + } else if (cp->cpg_defer_uptodate) { + cp->cpg_ra_used = 1; + } else { + result = ll_page_sync_io(env, io, pg, CRT_READ); + } + } + return result; +} + static int ll_write_begin(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, struct page **pagep, void **fsdata) { + struct ll_cl_context *lcc; + struct lu_env *env; + struct cl_io *io; + struct cl_page *page; + struct cl_object *clob = ll_i2info(mapping->host)->lli_clob; pgoff_t index = pos >> PAGE_CACHE_SHIFT; - struct page *page; - int rc; - unsigned from = pos & (PAGE_CACHE_SIZE - 1); + struct page *vmpage = NULL; + unsigned int from = pos & (PAGE_CACHE_SIZE - 1); + unsigned int to = from + len; + int result = 0; - page = grab_cache_page_write_begin(mapping, index, flags); - if (!page) - return -ENOMEM; + CDEBUG(D_VFSTRACE, "Writing %lu of %d to %d bytes\n", index, from, len); + + lcc = ll_cl_init(file, NULL); + if (IS_ERR(lcc)) { + result = PTR_ERR(lcc); + goto out; + } + + env = lcc->lcc_env; + io = lcc->lcc_io; + + /* To avoid deadlock, try to lock page first. */ + vmpage = grab_cache_page_nowait(mapping, index); + if (unlikely(!vmpage || PageDirty(vmpage))) { + struct ccc_io *cio = ccc_env_io(env); + struct cl_page_list *plist = &cio->u.write.cui_queue; + + /* if the page is already in dirty cache, we have to commit + * the pages right now; otherwise, it may cause deadlock + * because it holds page lock of a dirty page and request for + * more grants. It's okay for the dirty page to be the first + * one in commit page list, though. + */ + if (vmpage && PageDirty(vmpage) && plist->pl_nr > 0) { + unlock_page(vmpage); + page_cache_release(vmpage); + vmpage = NULL; + } - *pagep = page; + /* commit pages and then wait for page lock */ + result = vvp_io_write_commit(env, io); + if (result < 0) + goto out; - rc = ll_prepare_write(file, page, from, from + len); - if (rc) { - unlock_page(page); - page_cache_release(page); + if (!vmpage) { + vmpage = grab_cache_page_write_begin(mapping, index, + flags); + if (!vmpage) { + result = -ENOMEM; + goto out; + } + } } - return rc; + + page = cl_page_find(env, clob, vmpage->index, vmpage, CPT_CACHEABLE); + if (IS_ERR(page)) { + result = PTR_ERR(page); + goto out; + } + + lcc->lcc_page = page; + lu_ref_add(&page->cp_reference, "cl_io", io); + + cl_page_assume(env, io, page); + if (!PageUptodate(vmpage)) { + /* + * We're completely overwriting an existing page, + * so _don't_ set it up to date until commit_write + */ + if (from == 0 && to == PAGE_SIZE) { + CL_PAGE_HEADER(D_PAGE, env, page, "full page write\n"); + POISON_PAGE(vmpage, 0x11); + } else { + /* TODO: can be optimized at OSC layer to check if it + * is a lockless IO. In that case, it's not necessary + * to read the data. + */ + result = ll_prepare_partial_page(env, io, page); + if (result == 0) + SetPageUptodate(vmpage); + } + } + if (result < 0) + cl_page_unassume(env, io, page); +out: + if (result < 0) { + if (vmpage) { + unlock_page(vmpage); + page_cache_release(vmpage); + } + if (!IS_ERR(lcc)) + ll_cl_fini(lcc); + } else { + *pagep = vmpage; + *fsdata = lcc; + } + return result; } static int ll_write_end(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned copied, - struct page *page, void *fsdata) + struct page *vmpage, void *fsdata) { + struct ll_cl_context *lcc = fsdata; + struct lu_env *env; + struct cl_io *io; + struct ccc_io *cio; + struct cl_page *page; unsigned from = pos & (PAGE_CACHE_SIZE - 1); - int rc; + bool unplug = false; + int result = 0; + + page_cache_release(vmpage); + + env = lcc->lcc_env; + page = lcc->lcc_page; + io = lcc->lcc_io; + cio = ccc_env_io(env); + + LASSERT(cl_page_is_owned(page, io)); + if (copied > 0) { + struct cl_page_list *plist = &cio->u.write.cui_queue; + + lcc->lcc_page = NULL; /* page will be queued */ + + /* Add it into write queue */ + cl_page_list_add(plist, page); + if (plist->pl_nr == 1) /* first page */ + cio->u.write.cui_from = from; + else + LASSERT(from == 0); + cio->u.write.cui_to = from + copied; + + /* We may have one full RPC, commit it soon */ + if (plist->pl_nr >= PTLRPC_MAX_BRW_PAGES) + unplug = true; + + CL_PAGE_DEBUG(D_VFSTRACE, env, page, + "queued page: %d.\n", plist->pl_nr); + } else { + cl_page_disown(env, io, page); + + /* page list is not contiguous now, commit it now */ + unplug = true; + } - rc = ll_commit_write(file, page, from, from + copied); - unlock_page(page); - page_cache_release(page); + if (unplug || + file->f_flags & O_SYNC || IS_SYNC(file_inode(file))) + result = vvp_io_write_commit(env, io); - return rc ?: copied; + ll_cl_fini(lcc); + return result >= 0 ? copied : result; } #ifdef CONFIG_MIGRATION diff --git a/drivers/staging/lustre/lustre/llite/vvp_internal.h b/drivers/staging/lustre/lustre/llite/vvp_internal.h index bb393378c9bb..9abde114ba16 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_internal.h +++ b/drivers/staging/lustre/lustre/llite/vvp_internal.h @@ -44,17 +44,15 @@ #include "../include/cl_object.h" #include "llite_internal.h" -int vvp_io_init(const struct lu_env *env, - struct cl_object *obj, struct cl_io *io); -int vvp_lock_init(const struct lu_env *env, - struct cl_object *obj, struct cl_lock *lock, - const struct cl_io *io); +int vvp_io_init(const struct lu_env *env, struct cl_object *obj, + struct cl_io *io); +int vvp_lock_init(const struct lu_env *env, struct cl_object *obj, + struct cl_lock *lock, const struct cl_io *io); int vvp_page_init(const struct lu_env *env, struct cl_object *obj, struct cl_page *page, struct page *vmpage); struct lu_object *vvp_object_alloc(const struct lu_env *env, const struct lu_object_header *hdr, struct lu_device *dev); - struct ccc_object *cl_inode2ccc(struct inode *inode); extern const struct file_operations vvp_dump_pgcache_file_ops; diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c index ffe301b6f453..f4a1384730fa 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_io.c +++ b/drivers/staging/lustre/lustre/llite/vvp_io.c @@ -101,6 +101,27 @@ static bool can_populate_pages(const struct lu_env *env, struct cl_io *io, * */ +static int vvp_io_write_iter_init(const struct lu_env *env, + const struct cl_io_slice *ios) +{ + struct ccc_io *cio = cl2ccc_io(env, ios); + + cl_page_list_init(&cio->u.write.cui_queue); + cio->u.write.cui_written = 0; + cio->u.write.cui_from = 0; + cio->u.write.cui_to = PAGE_SIZE; + + return 0; +} + +static void vvp_io_write_iter_fini(const struct lu_env *env, + const struct cl_io_slice *ios) +{ + struct ccc_io *cio = cl2ccc_io(env, ios); + + LASSERT(cio->u.write.cui_queue.pl_nr == 0); +} + static int vvp_io_fault_iter_init(const struct lu_env *env, const struct cl_io_slice *ios) { @@ -563,6 +584,183 @@ static void vvp_io_read_fini(const struct lu_env *env, const struct cl_io_slice vvp_io_fini(env, ios); } +static int vvp_io_commit_sync(const struct lu_env *env, struct cl_io *io, + struct cl_page_list *plist, int from, int to) +{ + struct cl_2queue *queue = &io->ci_queue; + struct cl_page *page; + unsigned int bytes = 0; + int rc = 0; + + if (plist->pl_nr == 0) + return 0; + + if (from != 0) { + page = cl_page_list_first(plist); + cl_page_clip(env, page, from, + plist->pl_nr == 1 ? to : PAGE_SIZE); + } + if (to != PAGE_SIZE && plist->pl_nr > 1) { + page = cl_page_list_last(plist); + cl_page_clip(env, page, 0, to); + } + + cl_2queue_init(queue); + cl_page_list_splice(plist, &queue->c2_qin); + rc = cl_io_submit_sync(env, io, CRT_WRITE, queue, 0); + + /* plist is not sorted any more */ + cl_page_list_splice(&queue->c2_qin, plist); + cl_page_list_splice(&queue->c2_qout, plist); + cl_2queue_fini(env, queue); + + if (rc == 0) { + /* calculate bytes */ + bytes = plist->pl_nr << PAGE_SHIFT; + bytes -= from + PAGE_SIZE - to; + + while (plist->pl_nr > 0) { + page = cl_page_list_first(plist); + cl_page_list_del(env, plist, page); + + cl_page_clip(env, page, 0, PAGE_SIZE); + + SetPageUptodate(cl_page_vmpage(env, page)); + cl_page_disown(env, io, page); + + /* held in ll_cl_init() */ + lu_ref_del(&page->cp_reference, "cl_io", io); + cl_page_put(env, page); + } + } + + return bytes > 0 ? bytes : rc; +} + +static void write_commit_callback(const struct lu_env *env, struct cl_io *io, + struct cl_page *page) +{ + const struct cl_page_slice *slice; + struct ccc_page *cp; + struct page *vmpage; + + slice = cl_page_at(page, &vvp_device_type); + cp = cl2ccc_page(slice); + vmpage = cp->cpg_page; + + SetPageUptodate(vmpage); + set_page_dirty(vmpage); + vvp_write_pending(cl2ccc(slice->cpl_obj), cp); + + cl_page_disown(env, io, page); + + /* held in ll_cl_init() */ + lu_ref_del(&page->cp_reference, "cl_io", io); + cl_page_put(env, page); +} + +/* make sure the page list is contiguous */ +static bool page_list_sanity_check(struct cl_page_list *plist) +{ + struct cl_page *page; + pgoff_t index = CL_PAGE_EOF; + + cl_page_list_for_each(page, plist) { + if (index == CL_PAGE_EOF) { + index = page->cp_index; + continue; + } + + ++index; + if (index == page->cp_index) + continue; + + return false; + } + return true; +} + +/* Return how many bytes have queued or written */ +int vvp_io_write_commit(const struct lu_env *env, struct cl_io *io) +{ + struct cl_object *obj = io->ci_obj; + struct inode *inode = ccc_object_inode(obj); + struct ccc_io *cio = ccc_env_io(env); + struct cl_page_list *queue = &cio->u.write.cui_queue; + struct cl_page *page; + int rc = 0; + int bytes = 0; + unsigned int npages = cio->u.write.cui_queue.pl_nr; + + if (npages == 0) + return 0; + + CDEBUG(D_VFSTRACE, "commit async pages: %d, from %d, to %d\n", + npages, cio->u.write.cui_from, cio->u.write.cui_to); + + LASSERT(page_list_sanity_check(queue)); + + /* submit IO with async write */ + rc = cl_io_commit_async(env, io, queue, + cio->u.write.cui_from, cio->u.write.cui_to, + write_commit_callback); + npages -= queue->pl_nr; /* already committed pages */ + if (npages > 0) { + /* calculate how many bytes were written */ + bytes = npages << PAGE_SHIFT; + + /* first page */ + bytes -= cio->u.write.cui_from; + if (queue->pl_nr == 0) /* last page */ + bytes -= PAGE_SIZE - cio->u.write.cui_to; + LASSERTF(bytes > 0, "bytes = %d, pages = %d\n", bytes, npages); + + cio->u.write.cui_written += bytes; + + CDEBUG(D_VFSTRACE, "Committed %d pages %d bytes, tot: %ld\n", + npages, bytes, cio->u.write.cui_written); + + /* the first page must have been written. */ + cio->u.write.cui_from = 0; + } + LASSERT(page_list_sanity_check(queue)); + LASSERT(ergo(rc == 0, queue->pl_nr == 0)); + + /* out of quota, try sync write */ + if (rc == -EDQUOT && !cl_io_is_mkwrite(io)) { + rc = vvp_io_commit_sync(env, io, queue, + cio->u.write.cui_from, + cio->u.write.cui_to); + if (rc > 0) { + cio->u.write.cui_written += rc; + rc = 0; + } + } + + /* update inode size */ + ll_merge_lvb(env, inode); + + /* Now the pages in queue were failed to commit, discard them + * unless they were dirtied before. + */ + while (queue->pl_nr > 0) { + page = cl_page_list_first(queue); + cl_page_list_del(env, queue, page); + + if (!PageDirty(cl_page_vmpage(env, page))) + cl_page_discard(env, io, page); + + cl_page_disown(env, io, page); + + /* held in ll_cl_init() */ + lu_ref_del(&page->cp_reference, "cl_io", io); + cl_page_put(env, page); + } + cl_page_list_fini(env, queue); + + return rc; +} + static int vvp_io_write_start(const struct lu_env *env, const struct cl_io_slice *ios) { @@ -596,9 +794,24 @@ static int vvp_io_write_start(const struct lu_env *env, result = generic_file_write_iter(cio->cui_iocb, cio->cui_iter); if (result > 0) { + result = vvp_io_write_commit(env, io); + if (cio->u.write.cui_written > 0) { + result = cio->u.write.cui_written; + io->ci_nob += result; + + CDEBUG(D_VFSTRACE, "write: nob %zd, result: %zd\n", + io->ci_nob, result); + } + } + if (result > 0) { + struct ll_inode_info *lli = ll_i2info(inode); + + spin_lock(&lli->lli_lock); + lli->lli_flags |= LLIF_DATA_MODIFIED; + spin_unlock(&lli->lli_lock); + if (result < cnt) io->ci_continue = 0; - io->ci_nob += result; ll_rw_stats_tally(ll_i2sbi(inode), current->pid, cio->cui_fd, pos, result, WRITE); result = 0; @@ -645,6 +858,21 @@ static int vvp_io_kernel_fault(struct vvp_fault_io *cfio) return -EINVAL; } +static void mkwrite_commit_callback(const struct lu_env *env, struct cl_io *io, + struct cl_page *page) +{ + const struct cl_page_slice *slice; + struct ccc_page *cp; + struct page *vmpage; + + slice = cl_page_at(page, &vvp_device_type); + cp = cl2ccc_page(slice); + vmpage = cp->cpg_page; + + set_page_dirty(vmpage); + vvp_write_pending(cl2ccc(slice->cpl_obj), cp); +} + static int vvp_io_fault_start(const struct lu_env *env, const struct cl_io_slice *ios) { @@ -659,7 +887,7 @@ static int vvp_io_fault_start(const struct lu_env *env, struct page *vmpage = NULL; struct cl_page *page; loff_t size; - pgoff_t last; /* last page in a file data region */ + pgoff_t last_index; if (fio->ft_executable && inode->i_mtime.tv_sec != vio->u.fault.ft_mtime) @@ -705,15 +933,15 @@ static int vvp_io_fault_start(const struct lu_env *env, goto out; } + last_index = cl_index(obj, size - 1); + if (fio->ft_mkwrite) { - pgoff_t last_index; /* * Capture the size while holding the lli_trunc_sem from above * we want to make sure that we complete the mkwrite action * while holding this lock. We need to make sure that we are * not past the end of the file. */ - last_index = cl_index(obj, size - 1); if (last_index < fio->ft_index) { CDEBUG(D_PAGE, "llite: mkwrite and truncate race happened: %p: 0x%lx 0x%lx\n", @@ -745,21 +973,28 @@ static int vvp_io_fault_start(const struct lu_env *env, */ if (fio->ft_mkwrite) { wait_on_page_writeback(vmpage); - if (set_page_dirty(vmpage)) { - struct ccc_page *cp; + if (!PageDirty(vmpage)) { + struct cl_page_list *plist = &io->ci_queue.c2_qin; + int to = PAGE_SIZE; /* vvp_page_assume() calls wait_on_page_writeback(). */ cl_page_assume(env, io, page); - cp = cl2ccc_page(cl_page_at(page, &vvp_device_type)); - vvp_write_pending(cl2ccc(obj), cp); + cl_page_list_init(plist); + cl_page_list_add(plist, page); + + /* size fixup */ + if (last_index == page->cp_index) + to = size & ~PAGE_MASK; /* Do not set Dirty bit here so that in case IO is * started before the page is really made dirty, we * still have chance to detect it. */ - result = cl_page_cache_add(env, io, page, CRT_WRITE); + result = cl_io_commit_async(env, io, plist, 0, to, + mkwrite_commit_callback); LASSERT(cl_page_is_owned(page, io)); + cl_page_list_fini(env, plist); vmpage = NULL; if (result < 0) { @@ -777,15 +1012,14 @@ static int vvp_io_fault_start(const struct lu_env *env, } } - last = cl_index(obj, size - 1); /* * The ft_index is only used in the case of * a mkwrite action. We need to check * our assertions are correct, since * we should have caught this above */ - LASSERT(!fio->ft_mkwrite || fio->ft_index <= last); - if (fio->ft_index == last) + LASSERT(!fio->ft_mkwrite || fio->ft_index <= last_index); + if (fio->ft_index == last_index) /* * Last page is mapped partially. */ @@ -865,234 +1099,6 @@ static int vvp_io_read_page(const struct lu_env *env, return 0; } -static int vvp_page_sync_io(const struct lu_env *env, struct cl_io *io, - struct cl_page *page, struct ccc_page *cp, - enum cl_req_type crt) -{ - struct cl_2queue *queue; - int result; - - LASSERT(io->ci_type == CIT_READ || io->ci_type == CIT_WRITE); - - queue = &io->ci_queue; - cl_2queue_init_page(queue, page); - - result = cl_io_submit_sync(env, io, crt, queue, 0); - LASSERT(cl_page_is_owned(page, io)); - - if (crt == CRT_READ) - /* - * in CRT_WRITE case page is left locked even in case of - * error. - */ - cl_page_list_disown(env, io, &queue->c2_qin); - cl_2queue_fini(env, queue); - - return result; -} - -/** - * Prepare partially written-to page for a write. - */ -static int vvp_io_prepare_partial(const struct lu_env *env, struct cl_io *io, - struct cl_object *obj, struct cl_page *pg, - struct ccc_page *cp, - unsigned from, unsigned to) -{ - struct cl_attr *attr = ccc_env_thread_attr(env); - loff_t offset = cl_offset(obj, pg->cp_index); - int result; - - cl_object_attr_lock(obj); - result = cl_object_attr_get(env, obj, attr); - cl_object_attr_unlock(obj); - if (result == 0) { - /* - * If are writing to a new page, no need to read old data. - * The extent locking will have updated the KMS, and for our - * purposes here we can treat it like i_size. - */ - if (attr->cat_kms <= offset) { - char *kaddr = kmap_atomic(cp->cpg_page); - - memset(kaddr, 0, cl_page_size(obj)); - kunmap_atomic(kaddr); - } else if (cp->cpg_defer_uptodate) - cp->cpg_ra_used = 1; - else - result = vvp_page_sync_io(env, io, pg, cp, CRT_READ); - /* - * In older implementations, obdo_refresh_inode is called here - * to update the inode because the write might modify the - * object info at OST. However, this has been proven useless, - * since LVB functions will be called when user space program - * tries to retrieve inode attribute. Also, see bug 15909 for - * details. -jay - */ - if (result == 0) - cl_page_export(env, pg, 1); - } - return result; -} - -static int vvp_io_prepare_write(const struct lu_env *env, - const struct cl_io_slice *ios, - const struct cl_page_slice *slice, - unsigned from, unsigned to) -{ - struct cl_object *obj = slice->cpl_obj; - struct ccc_page *cp = cl2ccc_page(slice); - struct cl_page *pg = slice->cpl_page; - struct page *vmpage = cp->cpg_page; - - int result; - - LINVRNT(cl_page_is_vmlocked(env, pg)); - LASSERT(vmpage->mapping->host == ccc_object_inode(obj)); - - result = 0; - - CL_PAGE_HEADER(D_PAGE, env, pg, "preparing: [%d, %d]\n", from, to); - if (!PageUptodate(vmpage)) { - /* - * We're completely overwriting an existing page, so _don't_ - * set it up to date until commit_write - */ - if (from == 0 && to == PAGE_CACHE_SIZE) { - CL_PAGE_HEADER(D_PAGE, env, pg, "full page write\n"); - POISON_PAGE(page, 0x11); - } else - result = vvp_io_prepare_partial(env, ios->cis_io, obj, - pg, cp, from, to); - } else - CL_PAGE_HEADER(D_PAGE, env, pg, "uptodate\n"); - return result; -} - -static int vvp_io_commit_write(const struct lu_env *env, - const struct cl_io_slice *ios, - const struct cl_page_slice *slice, - unsigned from, unsigned to) -{ - struct cl_object *obj = slice->cpl_obj; - struct cl_io *io = ios->cis_io; - struct ccc_page *cp = cl2ccc_page(slice); - struct cl_page *pg = slice->cpl_page; - struct inode *inode = ccc_object_inode(obj); - struct ll_sb_info *sbi = ll_i2sbi(inode); - struct ll_inode_info *lli = ll_i2info(inode); - struct page *vmpage = cp->cpg_page; - - int result; - int tallyop; - loff_t size; - - LINVRNT(cl_page_is_vmlocked(env, pg)); - LASSERT(vmpage->mapping->host == inode); - - LU_OBJECT_HEADER(D_INODE, env, &obj->co_lu, "committing page write\n"); - CL_PAGE_HEADER(D_PAGE, env, pg, "committing: [%d, %d]\n", from, to); - - /* - * queue a write for some time in the future the first time we - * dirty the page. - * - * This is different from what other file systems do: they usually - * just mark page (and some of its buffers) dirty and rely on - * balance_dirty_pages() to start a write-back. Lustre wants write-back - * to be started earlier for the following reasons: - * - * (1) with a large number of clients we need to limit the amount - * of cached data on the clients a lot; - * - * (2) large compute jobs generally want compute-only then io-only - * and the IO should complete as quickly as possible; - * - * (3) IO is batched up to the RPC size and is async until the - * client max cache is hit - * (/sys/fs/lustre/osc/OSC.../max_dirty_mb) - * - */ - if (!PageDirty(vmpage)) { - tallyop = LPROC_LL_DIRTY_MISSES; - result = cl_page_cache_add(env, io, pg, CRT_WRITE); - if (result == 0) { - /* page was added into cache successfully. */ - set_page_dirty(vmpage); - vvp_write_pending(cl2ccc(obj), cp); - } else if (result == -EDQUOT) { - pgoff_t last_index = i_size_read(inode) >> PAGE_CACHE_SHIFT; - bool need_clip = true; - - /* - * Client ran out of disk space grant. Possible - * strategies are: - * - * (a) do a sync write, renewing grant; - * - * (b) stop writing on this stripe, switch to the - * next one. - * - * (b) is a part of "parallel io" design that is the - * ultimate goal. (a) is what "old" client did, and - * what the new code continues to do for the time - * being. - */ - if (last_index > pg->cp_index) { - to = PAGE_CACHE_SIZE; - need_clip = false; - } else if (last_index == pg->cp_index) { - int size_to = i_size_read(inode) & ~PAGE_MASK; - - if (to < size_to) - to = size_to; - } - if (need_clip) - cl_page_clip(env, pg, 0, to); - result = vvp_page_sync_io(env, io, pg, cp, CRT_WRITE); - if (result) - CERROR("Write page %lu of inode %p failed %d\n", - pg->cp_index, inode, result); - } - } else { - tallyop = LPROC_LL_DIRTY_HITS; - result = 0; - } - ll_stats_ops_tally(sbi, tallyop, 1); - - /* Inode should be marked DIRTY even if no new page was marked DIRTY - * because page could have been not flushed between 2 modifications. - * It is important the file is marked DIRTY as soon as the I/O is done - * Indeed, when cache is flushed, file could be already closed and it - * is too late to warn the MDT. - * It is acceptable that file is marked DIRTY even if I/O is dropped - * for some reasons before being flushed to OST. - */ - if (result == 0) { - spin_lock(&lli->lli_lock); - lli->lli_flags |= LLIF_DATA_MODIFIED; - spin_unlock(&lli->lli_lock); - } - - size = cl_offset(obj, pg->cp_index) + to; - - ll_inode_size_lock(inode); - if (result == 0) { - if (size > i_size_read(inode)) { - cl_isize_write_nolock(inode, size); - CDEBUG(D_VFSTRACE, DFID" updating i_size %lu\n", - PFID(lu_object_fid(&obj->co_lu)), - (unsigned long)size); - } - cl_page_export(env, pg, 1); - } else { - if (size > i_size_read(inode)) - cl_page_discard(env, io, pg); - } - ll_inode_size_unlock(inode); - return result; -} - static const struct cl_io_operations vvp_io_ops = { .op = { [CIT_READ] = { @@ -1103,6 +1109,8 @@ static const struct cl_io_operations vvp_io_ops = { }, [CIT_WRITE] = { .cio_fini = vvp_io_fini, + .cio_iter_init = vvp_io_write_iter_init, + .cio_iter_fini = vvp_io_write_iter_fini, .cio_lock = vvp_io_write_lock, .cio_start = vvp_io_write_start, .cio_advance = ccc_io_advance @@ -1130,8 +1138,6 @@ static const struct cl_io_operations vvp_io_ops = { } }, .cio_read_page = vvp_io_read_page, - .cio_prepare_write = vvp_io_prepare_write, - .cio_commit_write = vvp_io_commit_write }; int vvp_io_init(const struct lu_env *env, struct cl_object *obj, diff --git a/drivers/staging/lustre/lustre/lov/lov_cl_internal.h b/drivers/staging/lustre/lustre/lov/lov_cl_internal.h index 7dd3162b51e9..3d568fc62adc 100644 --- a/drivers/staging/lustre/lustre/lov/lov_cl_internal.h +++ b/drivers/staging/lustre/lustre/lov/lov_cl_internal.h @@ -444,8 +444,10 @@ struct lov_thread_info { struct cl_lock_descr lti_ldescr; struct ost_lvb lti_lvb; struct cl_2queue lti_cl2q; + struct cl_page_list lti_plist; struct cl_lock_closure lti_closure; wait_queue_t lti_waiter; + struct cl_attr lti_attr; }; /** diff --git a/drivers/staging/lustre/lustre/lov/lov_io.c b/drivers/staging/lustre/lustre/lov/lov_io.c index 4296aacd84fc..c60649032e59 100644 --- a/drivers/staging/lustre/lustre/lov/lov_io.c +++ b/drivers/staging/lustre/lustre/lov/lov_io.c @@ -543,13 +543,6 @@ static void lov_io_unlock(const struct lu_env *env, LASSERT(rc == 0); } -static struct cl_page_list *lov_io_submit_qin(struct lov_device *ld, - struct cl_page_list *qin, - int idx, int alloc) -{ - return alloc ? &qin[idx] : &ld->ld_emrg[idx]->emrg_page_list; -} - /** * lov implementation of cl_operations::cio_submit() method. It takes a list * of pages in \a queue, splits it into per-stripe sub-lists, invokes @@ -569,25 +562,17 @@ static int lov_io_submit(const struct lu_env *env, const struct cl_io_slice *ios, enum cl_req_type crt, struct cl_2queue *queue) { - struct lov_io *lio = cl2lov_io(env, ios); - struct lov_object *obj = lio->lis_object; - struct lov_device *ld = lu2lov_dev(lov2cl(obj)->co_lu.lo_dev); - struct cl_page_list *qin = &queue->c2_qin; - struct cl_2queue *cl2q = &lov_env_info(env)->lti_cl2q; - struct cl_page_list *stripes_qin = NULL; + struct cl_page_list *qin = &queue->c2_qin; + struct lov_io *lio = cl2lov_io(env, ios); + struct lov_io_sub *sub; + struct cl_page_list *plist = &lov_env_info(env)->lti_plist; struct cl_page *page; - struct cl_page *tmp; int stripe; -#define QIN(stripe) lov_io_submit_qin(ld, stripes_qin, stripe, alloc) - int rc = 0; - int alloc = - !(current->flags & PF_MEMALLOC); if (lio->lis_active_subios == 1) { int idx = lio->lis_single_subio_index; - struct lov_io_sub *sub; LASSERT(idx < lio->lis_nr_subios); sub = lov_sub_get(env, lio, idx); @@ -600,119 +585,120 @@ static int lov_io_submit(const struct lu_env *env, } LASSERT(lio->lis_subs); - if (alloc) { - stripes_qin = - libcfs_kvzalloc(sizeof(*stripes_qin) * - lio->lis_nr_subios, - GFP_NOFS); - if (!stripes_qin) - return -ENOMEM; - - for (stripe = 0; stripe < lio->lis_nr_subios; stripe++) - cl_page_list_init(&stripes_qin[stripe]); - } else { - /* - * If we get here, it means pageout & swap doesn't help. - * In order to not make things worse, even don't try to - * allocate the memory with __GFP_NOWARN. -jay - */ - mutex_lock(&ld->ld_mutex); - lio->lis_mem_frozen = 1; - } - cl_2queue_init(cl2q); - cl_page_list_for_each_safe(page, tmp, qin) { - stripe = lov_page_stripe(page); - cl_page_list_move(QIN(stripe), qin, page); - } + cl_page_list_init(plist); + while (qin->pl_nr > 0) { + struct cl_2queue *cl2q = &lov_env_info(env)->lti_cl2q; - for (stripe = 0; stripe < lio->lis_nr_subios; stripe++) { - struct lov_io_sub *sub; - struct cl_page_list *sub_qin = QIN(stripe); + cl_2queue_init(cl2q); - if (list_empty(&sub_qin->pl_pages)) - continue; + page = cl_page_list_first(qin); + cl_page_list_move(&cl2q->c2_qin, qin, page); + + stripe = lov_page_stripe(page); + while (qin->pl_nr > 0) { + page = cl_page_list_first(qin); + if (stripe != lov_page_stripe(page)) + break; + + cl_page_list_move(&cl2q->c2_qin, qin, page); + } - cl_page_list_splice(sub_qin, &cl2q->c2_qin); sub = lov_sub_get(env, lio, stripe); if (!IS_ERR(sub)) { rc = cl_io_submit_rw(sub->sub_env, sub->sub_io, crt, cl2q); lov_sub_put(sub); - } else + } else { rc = PTR_ERR(sub); - cl_page_list_splice(&cl2q->c2_qin, &queue->c2_qin); + } + + cl_page_list_splice(&cl2q->c2_qin, plist); cl_page_list_splice(&cl2q->c2_qout, &queue->c2_qout); + cl_2queue_fini(env, cl2q); + if (rc != 0) break; } - for (stripe = 0; stripe < lio->lis_nr_subios; stripe++) { - struct cl_page_list *sub_qin = QIN(stripe); + cl_page_list_splice(plist, qin); + cl_page_list_fini(env, plist); - if (list_empty(&sub_qin->pl_pages)) - continue; + return rc; +} + +static int lov_io_commit_async(const struct lu_env *env, + const struct cl_io_slice *ios, + struct cl_page_list *queue, int from, int to, + cl_commit_cbt cb) +{ + struct cl_page_list *plist = &lov_env_info(env)->lti_plist; + struct lov_io *lio = cl2lov_io(env, ios); + struct lov_io_sub *sub; + struct cl_page *page; + int rc = 0; - cl_page_list_splice(sub_qin, qin); + if (lio->lis_active_subios == 1) { + int idx = lio->lis_single_subio_index; + + LASSERT(idx < lio->lis_nr_subios); + sub = lov_sub_get(env, lio, idx); + LASSERT(!IS_ERR(sub)); + LASSERT(sub->sub_io == &lio->lis_single_subio); + rc = cl_io_commit_async(sub->sub_env, sub->sub_io, queue, + from, to, cb); + lov_sub_put(sub); + return rc; } - if (alloc) { - kvfree(stripes_qin); - } else { - int i; + LASSERT(lio->lis_subs); - for (i = 0; i < lio->lis_nr_subios; i++) { - struct cl_io *cio = lio->lis_subs[i].sub_io; + cl_page_list_init(plist); + while (queue->pl_nr > 0) { + int stripe_to = to; + int stripe; - if (cio && cio == &ld->ld_emrg[i]->emrg_subio) - lov_io_sub_fini(env, lio, &lio->lis_subs[i]); + LASSERT(plist->pl_nr == 0); + page = cl_page_list_first(queue); + cl_page_list_move(plist, queue, page); + + stripe = lov_page_stripe(page); + while (queue->pl_nr > 0) { + page = cl_page_list_first(queue); + if (stripe != lov_page_stripe(page)) + break; + + cl_page_list_move(plist, queue, page); } - lio->lis_mem_frozen = 0; - mutex_unlock(&ld->ld_mutex); - } - return rc; -#undef QIN -} + if (queue->pl_nr > 0) /* still has more pages */ + stripe_to = PAGE_SIZE; -static int lov_io_prepare_write(const struct lu_env *env, - const struct cl_io_slice *ios, - const struct cl_page_slice *slice, - unsigned from, unsigned to) -{ - struct lov_io *lio = cl2lov_io(env, ios); - struct cl_page *sub_page = lov_sub_page(slice); - struct lov_io_sub *sub; - int result; + sub = lov_sub_get(env, lio, stripe); + if (!IS_ERR(sub)) { + rc = cl_io_commit_async(sub->sub_env, sub->sub_io, + plist, from, stripe_to, cb); + lov_sub_put(sub); + } else { + rc = PTR_ERR(sub); + break; + } - sub = lov_page_subio(env, lio, slice); - if (!IS_ERR(sub)) { - result = cl_io_prepare_write(sub->sub_env, sub->sub_io, - sub_page, from, to); - lov_sub_put(sub); - } else - result = PTR_ERR(sub); - return result; -} + if (plist->pl_nr > 0) /* short write */ + break; -static int lov_io_commit_write(const struct lu_env *env, - const struct cl_io_slice *ios, - const struct cl_page_slice *slice, - unsigned from, unsigned to) -{ - struct lov_io *lio = cl2lov_io(env, ios); - struct cl_page *sub_page = lov_sub_page(slice); - struct lov_io_sub *sub; - int result; + from = 0; + } - sub = lov_page_subio(env, lio, slice); - if (!IS_ERR(sub)) { - result = cl_io_commit_write(sub->sub_env, sub->sub_io, - sub_page, from, to); - lov_sub_put(sub); - } else - result = PTR_ERR(sub); - return result; + /* for error case, add the page back into the qin list */ + LASSERT(ergo(rc == 0, plist->pl_nr == 0)); + while (plist->pl_nr > 0) { + /* error occurred, add the uncommitted pages back into queue */ + page = cl_page_list_last(plist); + cl_page_list_move_head(queue, plist, page); + } + + return rc; } static int lov_io_fault_start(const struct lu_env *env, @@ -803,16 +789,8 @@ static const struct cl_io_operations lov_io_ops = { .cio_fini = lov_io_fini } }, - .req_op = { - [CRT_READ] = { - .cio_submit = lov_io_submit - }, - [CRT_WRITE] = { - .cio_submit = lov_io_submit - } - }, - .cio_prepare_write = lov_io_prepare_write, - .cio_commit_write = lov_io_commit_write + .cio_submit = lov_io_submit, + .cio_commit_async = lov_io_commit_async, }; /***************************************************************************** @@ -880,15 +858,8 @@ static const struct cl_io_operations lov_empty_io_ops = { .cio_fini = lov_empty_io_fini } }, - .req_op = { - [CRT_READ] = { - .cio_submit = LOV_EMPTY_IMPOSSIBLE - }, - [CRT_WRITE] = { - .cio_submit = LOV_EMPTY_IMPOSSIBLE - } - }, - .cio_commit_write = LOV_EMPTY_IMPOSSIBLE + .cio_submit = LOV_EMPTY_IMPOSSIBLE, + .cio_commit_async = LOV_EMPTY_IMPOSSIBLE }; int lov_io_init_raid0(const struct lu_env *env, struct cl_object *obj, diff --git a/drivers/staging/lustre/lustre/lov/lov_page.c b/drivers/staging/lustre/lustre/lov/lov_page.c index 9728da245a68..5d9b355fc608 100644 --- a/drivers/staging/lustre/lustre/lov/lov_page.c +++ b/drivers/staging/lustre/lustre/lov/lov_page.c @@ -105,29 +105,6 @@ static void lov_page_assume(const struct lu_env *env, lov_page_own(env, slice, io, 0); } -static int lov_page_cache_add(const struct lu_env *env, - const struct cl_page_slice *slice, - struct cl_io *io) -{ - struct lov_io *lio = lov_env_io(env); - struct lov_io_sub *sub; - int rc = 0; - - LINVRNT(lov_page_invariant(slice)); - LINVRNT(!cl2lov_page(slice)->lps_invalid); - - sub = lov_page_subio(env, lio, slice); - if (!IS_ERR(sub)) { - rc = cl_page_cache_add(sub->sub_env, sub->sub_io, - slice->cpl_page->cp_child, CRT_WRITE); - lov_sub_put(sub); - } else { - rc = PTR_ERR(sub); - CL_PAGE_DEBUG(D_ERROR, env, slice->cpl_page, "rc = %d\n", rc); - } - return rc; -} - static int lov_page_print(const struct lu_env *env, const struct cl_page_slice *slice, void *cookie, lu_printer_t printer) @@ -141,11 +118,6 @@ static const struct cl_page_operations lov_page_ops = { .cpo_fini = lov_page_fini, .cpo_own = lov_page_own, .cpo_assume = lov_page_assume, - .io = { - [CRT_WRITE] = { - .cpo_cache_add = lov_page_cache_add - } - }, .cpo_print = lov_page_print }; diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c index cf9428428d06..9b3c5c1f26e3 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_io.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c @@ -782,77 +782,29 @@ int cl_io_read_page(const struct lu_env *env, struct cl_io *io, EXPORT_SYMBOL(cl_io_read_page); /** - * Called by write io to prepare page to receive data from user buffer. + * Commit a list of contiguous pages into writeback cache. * - * \see cl_io_operations::cio_prepare_write() + * \returns 0 if all pages committed, or errcode if error occurred. + * \see cl_io_operations::cio_commit_async() */ -int cl_io_prepare_write(const struct lu_env *env, struct cl_io *io, - struct cl_page *page, unsigned from, unsigned to) +int cl_io_commit_async(const struct lu_env *env, struct cl_io *io, + struct cl_page_list *queue, int from, int to, + cl_commit_cbt cb) { const struct cl_io_slice *scan; int result = 0; - LINVRNT(io->ci_type == CIT_WRITE); - LINVRNT(cl_page_is_owned(page, io)); - LINVRNT(io->ci_state == CIS_IO_GOING || io->ci_state == CIS_LOCKED); - LINVRNT(cl_io_invariant(io)); - LASSERT(cl_page_in_io(page, io)); - - cl_io_for_each_reverse(scan, io) { - if (scan->cis_iop->cio_prepare_write) { - const struct cl_page_slice *slice; - - slice = cl_io_slice_page(scan, page); - result = scan->cis_iop->cio_prepare_write(env, scan, - slice, - from, to); - if (result != 0) - break; - } - } - return result; -} -EXPORT_SYMBOL(cl_io_prepare_write); - -/** - * Called by write io after user data were copied into a page. - * - * \see cl_io_operations::cio_commit_write() - */ -int cl_io_commit_write(const struct lu_env *env, struct cl_io *io, - struct cl_page *page, unsigned from, unsigned to) -{ - const struct cl_io_slice *scan; - int result = 0; - - LINVRNT(io->ci_type == CIT_WRITE); - LINVRNT(io->ci_state == CIS_IO_GOING || io->ci_state == CIS_LOCKED); - LINVRNT(cl_io_invariant(io)); - /* - * XXX Uh... not nice. Top level cl_io_commit_write() call (vvp->lov) - * already called cl_page_cache_add(), moving page into CPS_CACHED - * state. Better (and more general) way of dealing with such situation - * is needed. - */ - LASSERT(cl_page_is_owned(page, io) || page->cp_parent); - LASSERT(cl_page_in_io(page, io)); - cl_io_for_each(scan, io) { - if (scan->cis_iop->cio_commit_write) { - const struct cl_page_slice *slice; - - slice = cl_io_slice_page(scan, page); - result = scan->cis_iop->cio_commit_write(env, scan, - slice, - from, to); - if (result != 0) - break; - } + if (!scan->cis_iop->cio_commit_async) + continue; + result = scan->cis_iop->cio_commit_async(env, scan, queue, + from, to, cb); + if (result != 0) + break; } - LINVRNT(result <= 0); return result; } -EXPORT_SYMBOL(cl_io_commit_write); +EXPORT_SYMBOL(cl_io_commit_async); /** * Submits a list of pages for immediate io. @@ -870,13 +822,10 @@ int cl_io_submit_rw(const struct lu_env *env, struct cl_io *io, const struct cl_io_slice *scan; int result = 0; - LINVRNT(crt < ARRAY_SIZE(scan->cis_iop->req_op)); - cl_io_for_each(scan, io) { - if (!scan->cis_iop->req_op[crt].cio_submit) + if (!scan->cis_iop->cio_submit) continue; - result = scan->cis_iop->req_op[crt].cio_submit(env, scan, crt, - queue); + result = scan->cis_iop->cio_submit(env, scan, crt, queue); if (result != 0) break; } @@ -1073,8 +1022,8 @@ EXPORT_SYMBOL(cl_page_list_add); /** * Removes a page from a page list. */ -static void cl_page_list_del(const struct lu_env *env, - struct cl_page_list *plist, struct cl_page *page) +void cl_page_list_del(const struct lu_env *env, struct cl_page_list *plist, + struct cl_page *page) { LASSERT(plist->pl_nr > 0); LINVRNT(plist->pl_owner == current); @@ -1087,6 +1036,7 @@ static void cl_page_list_del(const struct lu_env *env, lu_ref_del_at(&page->cp_reference, &page->cp_queue_ref, "queue", plist); cl_page_put(env, page); } +EXPORT_SYMBOL(cl_page_list_del); /** * Moves a page from one page list to another. @@ -1106,6 +1056,24 @@ void cl_page_list_move(struct cl_page_list *dst, struct cl_page_list *src, } EXPORT_SYMBOL(cl_page_list_move); +/** + * Moves a page from one page list to the head of another list. + */ +void cl_page_list_move_head(struct cl_page_list *dst, struct cl_page_list *src, + struct cl_page *page) +{ + LASSERT(src->pl_nr > 0); + LINVRNT(dst->pl_owner == current); + LINVRNT(src->pl_owner == current); + + list_move(&page->cp_batch, &dst->pl_pages); + --src->pl_nr; + ++dst->pl_nr; + lu_ref_set_at(&page->cp_reference, &page->cp_queue_ref, "queue", + src, dst); +} +EXPORT_SYMBOL(cl_page_list_move_head); + /** * splice the cl_page_list, just as list head does */ @@ -1163,8 +1131,7 @@ EXPORT_SYMBOL(cl_page_list_disown); /** * Releases pages from queue. */ -static void cl_page_list_fini(const struct lu_env *env, - struct cl_page_list *plist) +void cl_page_list_fini(const struct lu_env *env, struct cl_page_list *plist) { struct cl_page *page; struct cl_page *temp; @@ -1175,6 +1142,7 @@ static void cl_page_list_fini(const struct lu_env *env, cl_page_list_del(env, plist, page); LASSERT(plist->pl_nr == 0); } +EXPORT_SYMBOL(cl_page_list_fini); /** * Assumes all pages in a queue. diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c index bab8a74b78ae..0844a97c3258 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_page.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c @@ -1011,44 +1011,6 @@ int cl_page_make_ready(const struct lu_env *env, struct cl_page *pg, } EXPORT_SYMBOL(cl_page_make_ready); -/** - * Notify layers that high level io decided to place this page into a cache - * for future transfer. - * - * The layer implementing transfer engine (osc) has to register this page in - * its queues. - * - * \pre cl_page_is_owned(pg, io) - * \post cl_page_is_owned(pg, io) - * - * \see cl_page_operations::cpo_cache_add() - */ -int cl_page_cache_add(const struct lu_env *env, struct cl_io *io, - struct cl_page *pg, enum cl_req_type crt) -{ - const struct cl_page_slice *scan; - int result = 0; - - PINVRNT(env, pg, crt < CRT_NR); - PINVRNT(env, pg, cl_page_is_owned(pg, io)); - PINVRNT(env, pg, cl_page_invariant(pg)); - - if (crt >= CRT_NR) - return -EINVAL; - - list_for_each_entry(scan, &pg->cp_layers, cpl_linkage) { - if (!scan->cpl_ops->io[crt].cpo_cache_add) - continue; - - result = scan->cpl_ops->io[crt].cpo_cache_add(env, scan, io); - if (result != 0) - break; - } - CL_PAGE_HEADER(D_TRACE, env, pg, "%d %d\n", crt, result); - return result; -} -EXPORT_SYMBOL(cl_page_cache_add); - /** * Called if a pge is being written back by kernel's intention. * diff --git a/drivers/staging/lustre/lustre/obdecho/echo_client.c b/drivers/staging/lustre/lustre/obdecho/echo_client.c index 33ce0c80e4b2..6c205f9cad9f 100644 --- a/drivers/staging/lustre/lustre/obdecho/echo_client.c +++ b/drivers/staging/lustre/lustre/obdecho/echo_client.c @@ -1085,22 +1085,17 @@ static int cl_echo_cancel0(struct lu_env *env, struct echo_device *ed, return 0; } -static int cl_echo_async_brw(const struct lu_env *env, struct cl_io *io, - enum cl_req_type unused, struct cl_2queue *queue) +static void echo_commit_callback(const struct lu_env *env, struct cl_io *io, + struct cl_page *page) { - struct cl_page *clp; - struct cl_page *temp; - int result = 0; + struct echo_thread_info *info; + struct cl_2queue *queue; - cl_page_list_for_each_safe(clp, temp, &queue->c2_qin) { - int rc; + info = echo_env_info(env); + LASSERT(io == &info->eti_io); - rc = cl_page_cache_add(env, io, clp, CRT_WRITE); - if (rc == 0) - continue; - result = result ?: rc; - } - return result; + queue = &info->eti_queue; + cl_page_list_add(&queue->c2_qout, page); } static int cl_echo_object_brw(struct echo_object *eco, int rw, u64 offset, @@ -1179,7 +1174,9 @@ static int cl_echo_object_brw(struct echo_object *eco, int rw, u64 offset, async = async && (typ == CRT_WRITE); if (async) - rc = cl_echo_async_brw(env, io, typ, queue); + rc = cl_io_commit_async(env, io, &queue->c2_qin, + 0, PAGE_SIZE, + echo_commit_callback); else rc = cl_io_submit_sync(env, io, typ, queue, 0); CDEBUG(D_INFO, "echo_client %s write returns %d\n", diff --git a/drivers/staging/lustre/lustre/osc/osc_cache.c b/drivers/staging/lustre/lustre/osc/osc_cache.c index c9d4e3ca6caa..3be4b1f11767 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cache.c +++ b/drivers/staging/lustre/lustre/osc/osc_cache.c @@ -879,10 +879,9 @@ int osc_extent_finish(const struct lu_env *env, struct osc_extent *ext, * span a whole chunk on the OST side, or our accounting goes * wrong. Should match the code in filter_grant_check. */ - int offset = oap->oap_page_off & ~PAGE_MASK; - int count = oap->oap_count + (offset & (blocksize - 1)); - int end = (offset + oap->oap_count) & (blocksize - 1); - + int offset = last_off & ~PAGE_MASK; + int count = last_count + (offset & (blocksize - 1)); + int end = (offset + last_count) & (blocksize - 1); if (end) count += blocksize - end; @@ -3131,14 +3130,13 @@ static int discard_cb(const struct lu_env *env, struct cl_io *io, struct cl_page *page = cl_page_top(ops->ops_cl.cpl_page); LASSERT(lock->cll_descr.cld_mode >= CLM_WRITE); - KLASSERT(ergo(page->cp_type == CPT_CACHEABLE, - !PageWriteback(cl_page_vmpage(env, page)))); - KLASSERT(ergo(page->cp_type == CPT_CACHEABLE, - !PageDirty(cl_page_vmpage(env, page)))); /* page is top page. */ info->oti_next_index = osc_index(ops) + 1; if (cl_page_own(env, io, page) == 0) { + KLASSERT(ergo(page->cp_type == CPT_CACHEABLE, + !PageDirty(cl_page_vmpage(env, page)))); + /* discard the page */ cl_page_discard(env, io, page); cl_page_disown(env, io, page); diff --git a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h index e70f06ccd095..0e06bedeb0dd 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h +++ b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h @@ -453,6 +453,8 @@ int osc_prep_async_page(struct osc_object *osc, struct osc_page *ops, struct page *page, loff_t offset); int osc_queue_async_io(const struct lu_env *env, struct cl_io *io, struct osc_page *ops); +int osc_page_cache_add(const struct lu_env *env, + const struct cl_page_slice *slice, struct cl_io *io); int osc_teardown_async_page(const struct lu_env *env, struct osc_object *obj, struct osc_page *ops); int osc_flush_async_page(const struct lu_env *env, struct cl_io *io, diff --git a/drivers/staging/lustre/lustre/osc/osc_internal.h b/drivers/staging/lustre/lustre/osc/osc_internal.h index b3b15d4c99e3..906225c520d6 100644 --- a/drivers/staging/lustre/lustre/osc/osc_internal.h +++ b/drivers/staging/lustre/lustre/osc/osc_internal.h @@ -83,6 +83,12 @@ struct osc_async_page { #define oap_count oap_brw_page.count #define oap_brw_flags oap_brw_page.flag +static inline struct osc_async_page *brw_page2oap(struct brw_page *pga) +{ + return (struct osc_async_page *)container_of(pga, struct osc_async_page, + oap_brw_page); +} + struct osc_cache_waiter { struct list_head ocw_entry; wait_queue_head_t ocw_waitq; diff --git a/drivers/staging/lustre/lustre/osc/osc_io.c b/drivers/staging/lustre/lustre/osc/osc_io.c index 1536d31fd108..e9e18a1085e2 100644 --- a/drivers/staging/lustre/lustre/osc/osc_io.c +++ b/drivers/staging/lustre/lustre/osc/osc_io.c @@ -185,6 +185,13 @@ static int osc_io_submit(const struct lu_env *env, return qout->pl_nr > 0 ? 0 : result; } +/** + * This is called when a page is accessed within file in a way that creates + * new page, if one were missing (i.e., if there were a hole at that place in + * the file, or accessed page is beyond the current file size). + * + * Expand stripe KMS if necessary. + */ static void osc_page_touch_at(const struct lu_env *env, struct cl_object *obj, pgoff_t idx, unsigned to) { @@ -208,7 +215,8 @@ static void osc_page_touch_at(const struct lu_env *env, kms > loi->loi_kms ? "" : "not ", loi->loi_kms, kms, loi->loi_lvb.lvb_size); - valid = 0; + attr->cat_mtime = attr->cat_ctime = LTIME_S(CURRENT_TIME); + valid = CAT_MTIME | CAT_CTIME; if (kms > loi->loi_kms) { attr->cat_kms = kms; valid |= CAT_KMS; @@ -221,91 +229,83 @@ static void osc_page_touch_at(const struct lu_env *env, cl_object_attr_unlock(obj); } -/** - * This is called when a page is accessed within file in a way that creates - * new page, if one were missing (i.e., if there were a hole at that place in - * the file, or accessed page is beyond the current file size). Examples: - * ->commit_write() and ->nopage() methods. - * - * Expand stripe KMS if necessary. - */ -static void osc_page_touch(const struct lu_env *env, - struct osc_page *opage, unsigned to) -{ - struct cl_page *page = opage->ops_cl.cpl_page; - struct cl_object *obj = opage->ops_cl.cpl_obj; - - osc_page_touch_at(env, obj, page->cp_index, to); -} - -/** - * Implements cl_io_operations::cio_prepare_write() method for osc layer. - * - * \retval -EIO transfer initiated against this osc will most likely fail - * \retval 0 transfer initiated against this osc will most likely succeed. - * - * The reason for this check is to immediately return an error to the caller - * in the case of a deactivated import. Note, that import can be deactivated - * later, while pages, dirtied by this IO, are still in the cache, but this is - * irrelevant, because that would still return an error to the application (if - * it does fsync), but many applications don't do fsync because of performance - * issues, and we wanted to return an -EIO at write time to notify the - * application. - */ -static int osc_io_prepare_write(const struct lu_env *env, - const struct cl_io_slice *ios, - const struct cl_page_slice *slice, - unsigned from, unsigned to) +static int osc_io_commit_async(const struct lu_env *env, + const struct cl_io_slice *ios, + struct cl_page_list *qin, int from, int to, + cl_commit_cbt cb) { - struct osc_device *dev = lu2osc_dev(slice->cpl_obj->co_lu.lo_dev); - struct obd_import *imp = class_exp2cliimp(dev->od_exp); + struct cl_io *io = ios->cis_io; struct osc_io *oio = cl2osc_io(env, ios); + struct osc_object *osc = cl2osc(ios->cis_obj); + struct cl_page *page; + struct cl_page *last_page; + struct osc_page *opg; int result = 0; + LASSERT(qin->pl_nr > 0); + + /* Handle partial page cases */ + last_page = cl_page_list_last(qin); + if (oio->oi_lockless) { + page = cl_page_list_first(qin); + if (page == last_page) { + cl_page_clip(env, page, from, to); + } else { + if (from != 0) + cl_page_clip(env, page, from, PAGE_SIZE); + if (to != PAGE_SIZE) + cl_page_clip(env, last_page, 0, to); + } + } + /* - * This implements OBD_BRW_CHECK logic from old client. + * NOTE: here @page is a top-level page. This is done to avoid + * creation of sub-page-list. */ + while (qin->pl_nr > 0) { + struct osc_async_page *oap; - if (!imp || imp->imp_invalid) - result = -EIO; - if (result == 0 && oio->oi_lockless) - /* this page contains `invalid' data, but who cares? - * nobody can access the invalid data. - * in osc_io_commit_write(), we're going to write exact - * [from, to) bytes of this page to OST. -jay - */ - cl_page_export(env, slice->cpl_page, 1); + page = cl_page_list_first(qin); + opg = osc_cl_page_osc(page); + oap = &opg->ops_oap; - return result; -} + if (!list_empty(&oap->oap_rpc_item)) { + CDEBUG(D_CACHE, "Busy oap %p page %p for submit.\n", + oap, opg); + result = -EBUSY; + break; + } -static int osc_io_commit_write(const struct lu_env *env, - const struct cl_io_slice *ios, - const struct cl_page_slice *slice, - unsigned from, unsigned to) -{ - struct osc_io *oio = cl2osc_io(env, ios); - struct osc_page *opg = cl2osc_page(slice); - struct osc_object *obj = cl2osc(opg->ops_cl.cpl_obj); - struct osc_async_page *oap = &opg->ops_oap; + /* The page may be already in dirty cache. */ + if (list_empty(&oap->oap_pending_item)) { + result = osc_page_cache_add(env, &opg->ops_cl, io); + if (result != 0) + break; + } - LASSERT(to > 0); - /* - * XXX instead of calling osc_page_touch() here and in - * osc_io_fault_start() it might be more logical to introduce - * cl_page_touch() method, that generic cl_io_commit_write() and page - * fault code calls. - */ - osc_page_touch(env, cl2osc_page(slice), to); - if (!client_is_remote(osc_export(obj)) && - capable(CFS_CAP_SYS_RESOURCE)) - oap->oap_brw_flags |= OBD_BRW_NOQUOTA; + osc_page_touch_at(env, osc2cl(osc), + opg->ops_cl.cpl_page->cp_index, + page == last_page ? to : PAGE_SIZE); - if (oio->oi_lockless) - /* see osc_io_prepare_write() for lockless io handling. */ - cl_page_clip(env, slice->cpl_page, from, to); + cl_page_list_del(env, qin, page); - return 0; + (*cb)(env, io, page); + /* Can't access page any more. Page can be in transfer and + * complete at any time. + */ + } + + /* for sync write, kernel will wait for this page to be flushed before + * osc_io_end() is called, so release it earlier. + * for mkwrite(), it's known there is no further pages. + */ + if (cl_io_is_sync_write(io) && oio->oi_active) { + osc_extent_release(env, oio->oi_active); + oio->oi_active = NULL; + } + + CDEBUG(D_INFO, "%d %d\n", qin->pl_nr, result); + return result; } static int osc_io_rw_iter_init(const struct lu_env *env, @@ -719,16 +719,8 @@ static const struct cl_io_operations osc_io_ops = { .cio_fini = osc_io_fini } }, - .req_op = { - [CRT_READ] = { - .cio_submit = osc_io_submit - }, - [CRT_WRITE] = { - .cio_submit = osc_io_submit - } - }, - .cio_prepare_write = osc_io_prepare_write, - .cio_commit_write = osc_io_commit_write + .cio_submit = osc_io_submit, + .cio_commit_async = osc_io_commit_async }; /***************************************************************************** diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c index 91ff6070a28d..eff3b4b3b2b3 100644 --- a/drivers/staging/lustre/lustre/osc/osc_page.c +++ b/drivers/staging/lustre/lustre/osc/osc_page.c @@ -89,8 +89,8 @@ static void osc_page_transfer_put(const struct lu_env *env, struct cl_page *page = cl_page_top(opg->ops_cl.cpl_page); if (opg->ops_transfer_pinned) { - lu_ref_del(&page->cp_reference, "transfer", page); opg->ops_transfer_pinned = 0; + lu_ref_del(&page->cp_reference, "transfer", page); cl_page_put(env, page); } } @@ -113,11 +113,9 @@ static void osc_page_transfer_add(const struct lu_env *env, spin_unlock(&obj->oo_seatbelt); } -static int osc_page_cache_add(const struct lu_env *env, - const struct cl_page_slice *slice, - struct cl_io *io) +int osc_page_cache_add(const struct lu_env *env, + const struct cl_page_slice *slice, struct cl_io *io) { - struct osc_io *oio = osc_env_io(env); struct osc_page *opg = cl2osc_page(slice); int result; @@ -130,17 +128,6 @@ static int osc_page_cache_add(const struct lu_env *env, else osc_page_transfer_add(env, opg, CRT_WRITE); - /* for sync write, kernel will wait for this page to be flushed before - * osc_io_end() is called, so release it earlier. - * for mkwrite(), it's known there is no further pages. - */ - if (cl_io_is_sync_write(io) || cl_io_is_mkwrite(io)) { - if (oio->oi_active) { - osc_extent_release(env, oio->oi_active); - oio->oi_active = NULL; - } - } - return result; } @@ -231,17 +218,6 @@ static void osc_page_completion_write(const struct lu_env *env, { } -static int osc_page_fail(const struct lu_env *env, - const struct cl_page_slice *slice, - struct cl_io *unused) -{ - /* - * Cached read? - */ - LBUG(); - return 0; -} - static const char *osc_list(struct list_head *head) { return list_empty(head) ? "-" : "+"; @@ -393,11 +369,9 @@ static const struct cl_page_operations osc_page_ops = { .cpo_disown = osc_page_disown, .io = { [CRT_READ] = { - .cpo_cache_add = osc_page_fail, .cpo_completion = osc_page_completion_read }, [CRT_WRITE] = { - .cpo_cache_add = osc_page_cache_add, .cpo_completion = osc_page_completion_write } }, diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c index c055511b321a..1ff497f05b2f 100644 --- a/drivers/staging/lustre/lustre/osc/osc_request.c +++ b/drivers/staging/lustre/lustre/osc/osc_request.c @@ -1734,7 +1734,6 @@ static int brw_interpret(const struct lu_env *env, struct osc_brw_async_args *aa = data; struct osc_extent *ext; struct osc_extent *tmp; - struct cl_object *obj = NULL; struct client_obd *cli = aa->aa_cli; rc = osc_brw_fini_request(req, rc); @@ -1763,24 +1762,17 @@ static int brw_interpret(const struct lu_env *env, rc = -EIO; } - list_for_each_entry_safe(ext, tmp, &aa->aa_exts, oe_link) { - if (!obj && rc == 0) { - obj = osc2cl(ext->oe_obj); - cl_object_get(obj); - } - - list_del_init(&ext->oe_link); - osc_extent_finish(env, ext, 1, rc); - } - LASSERT(list_empty(&aa->aa_exts)); - LASSERT(list_empty(&aa->aa_oaps)); - - if (obj) { + if (rc == 0) { struct obdo *oa = aa->aa_oa; struct cl_attr *attr = &osc_env_info(env)->oti_attr; unsigned long valid = 0; + struct cl_object *obj; + struct osc_async_page *last; + + last = brw_page2oap(aa->aa_ppga[aa->aa_page_count - 1]); + obj = osc2cl(last->oap_obj); - LASSERT(rc == 0); + cl_object_attr_lock(obj); if (oa->o_valid & OBD_MD_FLBLOCKS) { attr->cat_blocks = oa->o_blocks; valid |= CAT_BLOCKS; @@ -1797,15 +1789,39 @@ static int brw_interpret(const struct lu_env *env, attr->cat_ctime = oa->o_ctime; valid |= CAT_CTIME; } - if (valid != 0) { - cl_object_attr_lock(obj); - cl_object_attr_set(env, obj, attr, valid); - cl_object_attr_unlock(obj); + + if (lustre_msg_get_opc(req->rq_reqmsg) == OST_WRITE) { + struct lov_oinfo *loi = cl2osc(obj)->oo_oinfo; + loff_t last_off = last->oap_count + last->oap_obj_off; + + /* Change file size if this is an out of quota or + * direct IO write and it extends the file size + */ + if (loi->loi_lvb.lvb_size < last_off) { + attr->cat_size = last_off; + valid |= CAT_SIZE; + } + /* Extend KMS if it's not a lockless write */ + if (loi->loi_kms < last_off && + oap2osc_page(last)->ops_srvlock == 0) { + attr->cat_kms = last_off; + valid |= CAT_KMS; + } } - cl_object_put(env, obj); + + if (valid != 0) + cl_object_attr_set(env, obj, attr, valid); + cl_object_attr_unlock(obj); } kmem_cache_free(obdo_cachep, aa->aa_oa); + list_for_each_entry_safe(ext, tmp, &aa->aa_exts, oe_link) { + list_del_init(&ext->oe_link); + osc_extent_finish(env, ext, 1, rc); + } + LASSERT(list_empty(&aa->aa_exts)); + LASSERT(list_empty(&aa->aa_oaps)); + cl_req_completion(env, aa->aa_clerq, rc < 0 ? rc : req->rq_bulk->bd_nob_transferred); osc_release_ppga(aa->aa_ppga, aa->aa_page_count); -- cgit v1.2.3 From f56b355ca8ae0a2312da094630790b923b00d8b4 Mon Sep 17 00:00:00 2001 From: Jinshan Xiong Date: Wed, 30 Mar 2016 19:48:31 -0400 Subject: staging/lustre/osc: add weight function for DLM lock Use weigh_ast to decide if a lock covers any pages. In recovery, weigh_ast will be used to decide if a DLM read lock covers any locked pages, or it will be canceled instead being recovered. The problem with the original implementation is that it attached each osc_page to an osc_lock also changed lock state to add every pages for readahead. Signed-off-by: Jinshan Xiong Reviewed-on: http://review.whamcloud.com/7894 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-3321 Reviewed-by: Bobi Jam Reviewed-by: Lai Siyao Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/ldlm/ldlm_request.c | 9 +- .../staging/lustre/lustre/osc/osc_cl_internal.h | 20 ---- drivers/staging/lustre/lustre/osc/osc_internal.h | 3 +- drivers/staging/lustre/lustre/osc/osc_lock.c | 113 +++++++++++++++------ drivers/staging/lustre/lustre/osc/osc_page.c | 78 +------------- drivers/staging/lustre/lustre/osc/osc_request.c | 5 +- 6 files changed, 89 insertions(+), 139 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c index c7904a96f9af..d5968e01edd8 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c @@ -1139,10 +1139,10 @@ static ldlm_policy_res_t ldlm_cancel_no_wait_policy(struct ldlm_namespace *ns, ldlm_policy_res_t result = LDLM_POLICY_CANCEL_LOCK; ldlm_cancel_for_recovery cb = ns->ns_cancel_for_recovery; - lock_res_and_lock(lock); - /* don't check added & count since we want to process all locks - * from unused list + * from unused list. + * It's fine to not take lock to access lock->l_resource since + * the lock has already been granted so it won't change. */ switch (lock->l_resource->lr_type) { case LDLM_EXTENT: @@ -1151,11 +1151,12 @@ static ldlm_policy_res_t ldlm_cancel_no_wait_policy(struct ldlm_namespace *ns, break; default: result = LDLM_POLICY_SKIP_LOCK; + lock_res_and_lock(lock); lock->l_flags |= LDLM_FL_SKIPPED; + unlock_res_and_lock(lock); break; } - unlock_res_and_lock(lock); return result; } diff --git a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h index 0e06bedeb0dd..cf87043ce4b8 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h +++ b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h @@ -274,16 +274,6 @@ struct osc_lock { struct ldlm_enqueue_info ols_einfo; enum osc_lock_state ols_state; - /** - * How many pages are using this lock for io, currently only used by - * read-ahead. If non-zero, the underlying dlm lock won't be cancelled - * during recovery to avoid deadlock. see bz16774. - * - * \see osc_page::ops_lock - * \see osc_page_addref_lock(), osc_page_putref_lock() - */ - atomic_t ols_pageref; - /** * true, if ldlm_lock_addref() was called against * osc_lock::ols_lock. This is used for sanity checking. @@ -400,16 +390,6 @@ struct osc_page { * Submit time - the time when the page is starting RPC. For debugging. */ unsigned long ops_submit_time; - - /** - * A lock of which we hold a reference covers this page. Only used by - * read-ahead: for a readahead page, we hold it's covering lock to - * prevent it from being canceled during recovery. - * - * \see osc_lock::ols_pageref - * \see osc_page_addref_lock(), osc_page_putref_lock(). - */ - struct cl_lock *ops_lock; }; extern struct kmem_cache *osc_lock_kmem; diff --git a/drivers/staging/lustre/lustre/osc/osc_internal.h b/drivers/staging/lustre/lustre/osc/osc_internal.h index 906225c520d6..b7fb01ad60a6 100644 --- a/drivers/staging/lustre/lustre/osc/osc_internal.h +++ b/drivers/staging/lustre/lustre/osc/osc_internal.h @@ -141,6 +141,7 @@ int osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, int osc_lru_reclaim(struct client_obd *cli); extern spinlock_t osc_ast_guard; +unsigned long osc_ldlm_weigh_ast(struct ldlm_lock *dlmlock); int osc_setup(struct obd_device *obd, struct lustre_cfg *lcfg); @@ -181,8 +182,6 @@ static inline struct osc_device *obd2osc_dev(const struct obd_device *d) return container_of0(d->obd_lu_dev, struct osc_device, od_cl.cd_lu_dev); } -int osc_dlm_lock_pageref(struct ldlm_lock *dlm); - extern struct kmem_cache *osc_quota_kmem; struct osc_quota_info { /** linkage for quota hash table */ diff --git a/drivers/staging/lustre/lustre/osc/osc_lock.c b/drivers/staging/lustre/lustre/osc/osc_lock.c index 3a8a6d129377..978b6ea67107 100644 --- a/drivers/staging/lustre/lustre/osc/osc_lock.c +++ b/drivers/staging/lustre/lustre/osc/osc_lock.c @@ -51,8 +51,6 @@ * @{ */ -#define _PAGEREF_MAGIC (-10000000) - /***************************************************************************** * * Type conversions. @@ -248,8 +246,6 @@ static void osc_lock_fini(const struct lu_env *env, */ osc_lock_unhold(ols); LASSERT(!ols->ols_lock); - LASSERT(atomic_read(&ols->ols_pageref) == 0 || - atomic_read(&ols->ols_pageref) == _PAGEREF_MAGIC); kmem_cache_free(osc_lock_kmem, ols); } @@ -895,11 +891,88 @@ static int osc_ldlm_glimpse_ast(struct ldlm_lock *dlmlock, void *data) return result; } -static unsigned long osc_lock_weigh(const struct lu_env *env, - const struct cl_lock_slice *slice) +static int weigh_cb(const struct lu_env *env, struct cl_io *io, + struct osc_page *ops, void *cbdata) { - /* TODO: check how many pages are covered by this lock */ - return cl2osc(slice->cls_obj)->oo_npages; + struct cl_page *page = ops->ops_cl.cpl_page; + + if (cl_page_is_vmlocked(env, page)) { + (*(unsigned long *)cbdata)++; + return CLP_GANG_ABORT; + } + + return CLP_GANG_OKAY; +} + +static unsigned long osc_lock_weight(const struct lu_env *env, + const struct osc_lock *ols) +{ + struct cl_io *io = &osc_env_info(env)->oti_io; + struct cl_lock_descr *descr = &ols->ols_cl.cls_lock->cll_descr; + struct cl_object *obj = ols->ols_cl.cls_obj; + unsigned long npages = 0; + int result; + + io->ci_obj = cl_object_top(obj); + io->ci_ignore_layout = 1; + result = cl_io_init(env, io, CIT_MISC, io->ci_obj); + if (result != 0) + return result; + + do { + result = osc_page_gang_lookup(env, io, cl2osc(obj), + descr->cld_start, descr->cld_end, + weigh_cb, (void *)&npages); + if (result == CLP_GANG_ABORT) + break; + if (result == CLP_GANG_RESCHED) + cond_resched(); + } while (result != CLP_GANG_OKAY); + cl_io_fini(env, io); + + return npages; +} + +/** + * Get the weight of dlm lock for early cancellation. + */ +unsigned long osc_ldlm_weigh_ast(struct ldlm_lock *dlmlock) +{ + struct cl_env_nest nest; + struct lu_env *env; + struct osc_lock *lock; + unsigned long weight; + + might_sleep(); + /* + * osc_ldlm_weigh_ast has a complex context since it might be called + * because of lock canceling, or from user's input. We have to make + * a new environment for it. Probably it is implementation safe to use + * the upper context because cl_lock_put don't modify environment + * variables. But just in case .. + */ + env = cl_env_nested_get(&nest); + if (IS_ERR(env)) + /* Mostly because lack of memory, do not eliminate this lock */ + return 1; + + LASSERT(dlmlock->l_resource->lr_type == LDLM_EXTENT); + lock = osc_ast_data_get(dlmlock); + if (!lock) { + /* cl_lock was destroyed because of memory pressure. + * It is much reasonable to assign this type of lock + * a lower cost. + */ + weight = 0; + goto out; + } + + weight = osc_lock_weight(env, lock); + osc_ast_data_put(env, lock); + +out: + cl_env_nested_put(&nest, env); + return weight; } static void osc_lock_build_einfo(const struct lu_env *env, @@ -1468,7 +1541,6 @@ static const struct cl_lock_operations osc_lock_ops = { .clo_delete = osc_lock_delete, .clo_state = osc_lock_state, .clo_cancel = osc_lock_cancel, - .clo_weigh = osc_lock_weigh, .clo_print = osc_lock_print, .clo_fits_into = osc_lock_fits_into, }; @@ -1570,7 +1642,6 @@ int osc_lock_init(const struct lu_env *env, __u32 enqflags = lock->cll_descr.cld_enq_flags; osc_lock_build_einfo(env, lock, clk, &clk->ols_einfo); - atomic_set(&clk->ols_pageref, 0); clk->ols_state = OLS_NEW; clk->ols_flags = osc_enq2ldlm_flags(enqflags); @@ -1597,26 +1668,4 @@ int osc_lock_init(const struct lu_env *env, return result; } -int osc_dlm_lock_pageref(struct ldlm_lock *dlm) -{ - struct osc_lock *olock; - int rc = 0; - - spin_lock(&osc_ast_guard); - olock = dlm->l_ast_data; - /* - * there's a very rare race with osc_page_addref_lock(), but that - * doesn't matter because in the worst case we don't cancel a lock - * which we actually can, that's no harm. - */ - if (olock && - atomic_add_return(_PAGEREF_MAGIC, - &olock->ols_pageref) != _PAGEREF_MAGIC) { - atomic_sub(_PAGEREF_MAGIC, &olock->ols_pageref); - rc = 1; - } - spin_unlock(&osc_ast_guard); - return rc; -} - /** @} osc */ diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c index eff3b4b3b2b3..8dc62fa04300 100644 --- a/drivers/staging/lustre/lustre/osc/osc_page.c +++ b/drivers/staging/lustre/lustre/osc/osc_page.c @@ -67,10 +67,6 @@ static int osc_page_protected(const struct lu_env *env, static void osc_page_fini(const struct lu_env *env, struct cl_page_slice *slice) { - struct osc_page *opg = cl2osc_page(slice); - - CDEBUG(D_TRACE, "%p\n", opg); - LASSERT(!opg->ops_lock); } static void osc_page_transfer_get(struct osc_page *opg, const char *label) @@ -139,42 +135,6 @@ void osc_index2policy(ldlm_policy_data_t *policy, const struct cl_object *obj, policy->l_extent.end = cl_offset(obj, end + 1) - 1; } -static int osc_page_addref_lock(const struct lu_env *env, - struct osc_page *opg, - struct cl_lock *lock) -{ - struct osc_lock *olock; - int rc; - - LASSERT(!opg->ops_lock); - - olock = osc_lock_at(lock); - if (atomic_inc_return(&olock->ols_pageref) <= 0) { - atomic_dec(&olock->ols_pageref); - rc = -ENODATA; - } else { - cl_lock_get(lock); - opg->ops_lock = lock; - rc = 0; - } - return rc; -} - -static void osc_page_putref_lock(const struct lu_env *env, - struct osc_page *opg) -{ - struct cl_lock *lock = opg->ops_lock; - struct osc_lock *olock; - - LASSERT(lock); - olock = osc_lock_at(lock); - - atomic_dec(&olock->ols_pageref); - opg->ops_lock = NULL; - - cl_lock_put(env, lock); -} - static int osc_page_is_under_lock(const struct lu_env *env, const struct cl_page_slice *slice, struct cl_io *unused) @@ -185,39 +145,12 @@ static int osc_page_is_under_lock(const struct lu_env *env, lock = cl_lock_at_page(env, slice->cpl_obj, slice->cpl_page, NULL, 1, 0); if (lock) { - if (osc_page_addref_lock(env, cl2osc_page(slice), lock) == 0) - result = -EBUSY; cl_lock_put(env, lock); + result = -EBUSY; } return result; } -static void osc_page_disown(const struct lu_env *env, - const struct cl_page_slice *slice, - struct cl_io *io) -{ - struct osc_page *opg = cl2osc_page(slice); - - if (unlikely(opg->ops_lock)) - osc_page_putref_lock(env, opg); -} - -static void osc_page_completion_read(const struct lu_env *env, - const struct cl_page_slice *slice, - int ioret) -{ - struct osc_page *opg = cl2osc_page(slice); - - if (likely(opg->ops_lock)) - osc_page_putref_lock(env, opg); -} - -static void osc_page_completion_write(const struct lu_env *env, - const struct cl_page_slice *slice, - int ioret) -{ -} - static const char *osc_list(struct list_head *head) { return list_empty(head) ? "-" : "+"; @@ -366,15 +299,6 @@ static const struct cl_page_operations osc_page_ops = { .cpo_print = osc_page_print, .cpo_delete = osc_page_delete, .cpo_is_under_lock = osc_page_is_under_lock, - .cpo_disown = osc_page_disown, - .io = { - [CRT_READ] = { - .cpo_completion = osc_page_completion_read - }, - [CRT_WRITE] = { - .cpo_completion = osc_page_completion_write - } - }, .cpo_clip = osc_page_clip, .cpo_cancel = osc_page_cancel, .cpo_flush = osc_page_flush diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c index 1ff497f05b2f..1e378e6c1a70 100644 --- a/drivers/staging/lustre/lustre/osc/osc_request.c +++ b/drivers/staging/lustre/lustre/osc/osc_request.c @@ -3131,8 +3131,6 @@ static int osc_import_event(struct obd_device *obd, */ static int osc_cancel_for_recovery(struct ldlm_lock *lock) { - check_res_locked(lock->l_resource); - /* * Cancel all unused extent lock in granted mode LCK_PR or LCK_CR. * @@ -3141,8 +3139,7 @@ static int osc_cancel_for_recovery(struct ldlm_lock *lock) */ if (lock->l_resource->lr_type == LDLM_EXTENT && (lock->l_granted_mode == LCK_PR || - lock->l_granted_mode == LCK_CR) && - (osc_dlm_lock_pageref(lock) == 0)) + lock->l_granted_mode == LCK_CR) && osc_ldlm_weigh_ast(lock) == 0) return 1; return 0; -- cgit v1.2.3 From 7addf402c1171e875109bb1567171c4c3f8f8229 Mon Sep 17 00:00:00 2001 From: Jinshan Xiong Date: Wed, 30 Mar 2016 19:48:32 -0400 Subject: staging/lustre/clio: remove stackable cl_page completely >From now on, cl_page becomes one to one mapping of vmpage. Signed-off-by: Jinshan Xiong Reviewed-on: http://review.whamcloud.com/7895 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-3321 Reviewed-by: Bobi Jam Reviewed-by: Lai Siyao Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/cl_object.h | 43 ++--- drivers/staging/lustre/lustre/include/lclient.h | 7 +- drivers/staging/lustre/lustre/llite/lcommon_cl.c | 12 +- .../staging/lustre/lustre/llite/llite_internal.h | 4 + drivers/staging/lustre/lustre/llite/rw.c | 7 +- drivers/staging/lustre/lustre/llite/rw26.c | 35 +--- drivers/staging/lustre/lustre/llite/vvp_internal.h | 2 +- drivers/staging/lustre/lustre/llite/vvp_io.c | 45 +++-- drivers/staging/lustre/lustre/llite/vvp_page.c | 23 +-- .../staging/lustre/lustre/lov/lov_cl_internal.h | 14 +- drivers/staging/lustre/lustre/lov/lov_io.c | 8 +- drivers/staging/lustre/lustre/lov/lov_object.c | 32 +++- drivers/staging/lustre/lustre/lov/lov_page.c | 104 +++------- drivers/staging/lustre/lustre/lov/lovsub_page.c | 2 +- drivers/staging/lustre/lustre/obdclass/cl_io.c | 63 +----- drivers/staging/lustre/lustre/obdclass/cl_object.c | 4 +- drivers/staging/lustre/lustre/obdclass/cl_page.c | 213 +++++---------------- .../staging/lustre/lustre/obdecho/echo_client.c | 22 +-- drivers/staging/lustre/lustre/osc/osc_cache.c | 59 +++--- .../staging/lustre/lustre/osc/osc_cl_internal.h | 12 +- drivers/staging/lustre/lustre/osc/osc_io.c | 41 ++-- drivers/staging/lustre/lustre/osc/osc_page.c | 33 ++-- 22 files changed, 257 insertions(+), 528 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h index c3865ec49769..5b65854834f5 100644 --- a/drivers/staging/lustre/lustre/include/cl_object.h +++ b/drivers/staging/lustre/lustre/include/cl_object.h @@ -322,7 +322,7 @@ struct cl_object_operations { * to be used instead of newly created. */ int (*coo_page_init)(const struct lu_env *env, struct cl_object *obj, - struct cl_page *page, struct page *vmpage); + struct cl_page *page, pgoff_t index); /** * Initialize lock slice for this layer. Called top-to-bottom through * every object layer when a new cl_lock is instantiated. Layer @@ -460,10 +460,6 @@ struct cl_object_header { co_lu.lo_linkage) /** @} cl_object */ -#ifndef pgoff_t -#define pgoff_t unsigned long -#endif - #define CL_PAGE_EOF ((pgoff_t)~0ull) /** \addtogroup cl_page cl_page @@ -727,16 +723,10 @@ struct cl_page { atomic_t cp_ref; /** An object this page is a part of. Immutable after creation. */ struct cl_object *cp_obj; - /** Logical page index within the object. Immutable after creation. */ - pgoff_t cp_index; /** List of slices. Immutable after creation. */ struct list_head cp_layers; - /** Parent page, NULL for top-level page. Immutable after creation. */ - struct cl_page *cp_parent; - /** Lower-layer page. NULL for bottommost page. Immutable after - * creation. - */ - struct cl_page *cp_child; + /** vmpage */ + struct page *cp_vmpage; /** * Page state. This field is const to avoid accidental update, it is * modified only internally within cl_page.c. Protected by a VM lock. @@ -791,6 +781,7 @@ struct cl_page { */ struct cl_page_slice { struct cl_page *cpl_page; + pgoff_t cpl_index; /** * Object slice corresponding to this page slice. Immutable after * creation. @@ -845,11 +836,6 @@ struct cl_page_operations { * provided by the topmost layer, see cl_page_disown0() as an example. */ - /** - * \return the underlying VM page. Optional. - */ - struct page *(*cpo_vmpage)(const struct lu_env *env, - const struct cl_page_slice *slice); /** * Called when \a io acquires this page into the exclusive * ownership. When this method returns, it is guaranteed that the is @@ -1102,6 +1088,12 @@ static inline int __page_in_use(const struct cl_page *page, int refc) #define cl_page_in_use(pg) __page_in_use(pg, 1) #define cl_page_in_use_noref(pg) __page_in_use(pg, 0) +static inline struct page *cl_page_vmpage(struct cl_page *page) +{ + LASSERT(page->cp_vmpage); + return page->cp_vmpage; +} + /** @} cl_page */ /** \addtogroup cl_lock cl_lock @@ -2729,7 +2721,7 @@ static inline int cl_object_same(struct cl_object *o0, struct cl_object *o1) static inline void cl_object_page_init(struct cl_object *clob, int size) { clob->co_slice_off = cl_object_header(clob)->coh_page_bufsize; - cl_object_header(clob)->coh_page_bufsize += ALIGN(size, 8); + cl_object_header(clob)->coh_page_bufsize += cfs_size_round(size); } static inline void *cl_object_page_slice(struct cl_object *clob, @@ -2774,9 +2766,7 @@ void cl_page_print(const struct lu_env *env, void *cookie, lu_printer_t printer, const struct cl_page *pg); void cl_page_header_print(const struct lu_env *env, void *cookie, lu_printer_t printer, const struct cl_page *pg); -struct page *cl_page_vmpage(const struct lu_env *env, struct cl_page *page); struct cl_page *cl_vmpage_page(struct page *vmpage, struct cl_object *obj); -struct cl_page *cl_page_top(struct cl_page *page); const struct cl_page_slice *cl_page_at(const struct cl_page *page, const struct lu_device_type *dtype); @@ -2868,17 +2858,6 @@ struct cl_lock *cl_lock_at_pgoff(const struct lu_env *env, struct cl_object *obj, pgoff_t index, struct cl_lock *except, int pending, int canceld); -static inline struct cl_lock *cl_lock_at_page(const struct lu_env *env, - struct cl_object *obj, - struct cl_page *page, - struct cl_lock *except, - int pending, int canceld) -{ - LASSERT(cl_object_header(obj) == cl_object_header(page->cp_obj)); - return cl_lock_at_pgoff(env, obj, page->cp_index, except, - pending, canceld); -} - const struct cl_lock_slice *cl_lock_at(const struct cl_lock *lock, const struct lu_device_type *dtype); diff --git a/drivers/staging/lustre/lustre/include/lclient.h b/drivers/staging/lustre/lustre/include/lclient.h index 6c3a30af0727..c91fb0151a52 100644 --- a/drivers/staging/lustre/lustre/include/lclient.h +++ b/drivers/staging/lustre/lustre/include/lclient.h @@ -238,6 +238,11 @@ static inline struct ccc_page *cl2ccc_page(const struct cl_page_slice *slice) return container_of(slice, struct ccc_page, cpg_cl); } +static inline pgoff_t ccc_index(struct ccc_page *ccc) +{ + return ccc->cpg_cl.cpl_index; +} + struct ccc_device { struct cl_device cdv_cl; struct super_block *cdv_sb; @@ -294,8 +299,6 @@ int ccc_lock_init(const struct lu_env *env, struct cl_object *obj, const struct cl_lock_operations *lkops); int ccc_object_glimpse(const struct lu_env *env, const struct cl_object *obj, struct ost_lvb *lvb); -struct page *ccc_page_vmpage(const struct lu_env *env, - const struct cl_page_slice *slice); int ccc_page_is_under_lock(const struct lu_env *env, const struct cl_page_slice *slice, struct cl_io *io); int ccc_fail(const struct lu_env *env, const struct cl_page_slice *slice); diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c b/drivers/staging/lustre/lustre/llite/lcommon_cl.c index 065b0f20e95d..55fa0da80b81 100644 --- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c +++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c @@ -336,6 +336,8 @@ struct lu_object *ccc_object_alloc(const struct lu_env *env, obj = ccc2lu(vob); hdr = &vob->cob_header; cl_object_header_init(hdr); + hdr->coh_page_bufsize = cfs_size_round(sizeof(struct cl_page)); + lu_object_init(obj, &hdr->coh_lu, dev); lu_object_add_top(&hdr->coh_lu, obj); @@ -450,12 +452,6 @@ static void ccc_object_size_unlock(struct cl_object *obj) * */ -struct page *ccc_page_vmpage(const struct lu_env *env, - const struct cl_page_slice *slice) -{ - return cl2vm_page(slice); -} - int ccc_page_is_under_lock(const struct lu_env *env, const struct cl_page_slice *slice, struct cl_io *io) @@ -471,8 +467,8 @@ int ccc_page_is_under_lock(const struct lu_env *env, if (cio->cui_fd->fd_flags & LL_FILE_GROUP_LOCKED) { result = -EBUSY; } else { - desc->cld_start = page->cp_index; - desc->cld_end = page->cp_index; + desc->cld_start = ccc_index(cl2ccc_page(slice)); + desc->cld_end = ccc_index(cl2ccc_page(slice)); desc->cld_obj = page->cp_obj; desc->cld_mode = CLM_READ; result = cl_queue_match(&io->ci_lockset.cls_done, diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index 08fe0ea5ee8f..bc831472b3ed 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -982,6 +982,10 @@ static inline void ll_invalidate_page(struct page *vmpage) if (!mapping) return; + /* + * truncate_complete_page() calls + * a_ops->invalidatepage()->cl_page_delete()->vvp_page_delete(). + */ ll_teardown_mmaps(mapping, offset, offset + PAGE_CACHE_SIZE); truncate_complete_page(mapping, vmpage); } diff --git a/drivers/staging/lustre/lustre/llite/rw.c b/drivers/staging/lustre/lustre/llite/rw.c index dcccdecbad00..b1375f1719e7 100644 --- a/drivers/staging/lustre/lustre/llite/rw.c +++ b/drivers/staging/lustre/lustre/llite/rw.c @@ -290,15 +290,16 @@ void ll_ra_read_ex(struct file *f, struct ll_ra_read *rar) static int cl_read_ahead_page(const struct lu_env *env, struct cl_io *io, struct cl_page_list *queue, struct cl_page *page, - struct page *vmpage) + struct cl_object *clob) { + struct page *vmpage = page->cp_vmpage; struct ccc_page *cp; int rc; rc = 0; cl_page_assume(env, io, page); lu_ref_add(&page->cp_reference, "ra", current); - cp = cl2ccc_page(cl_page_at(page, &vvp_device_type)); + cp = cl2ccc_page(cl_object_page_slice(clob, page)); if (!cp->cpg_defer_uptodate && !PageUptodate(vmpage)) { rc = cl_page_is_under_lock(env, io, page); if (rc == -EBUSY) { @@ -348,7 +349,7 @@ static int ll_read_ahead_page(const struct lu_env *env, struct cl_io *io, vmpage, CPT_CACHEABLE); if (!IS_ERR(page)) { rc = cl_read_ahead_page(env, io, queue, - page, vmpage); + page, clob); if (rc == -ENOLCK) { which = RA_STAT_FAILED_MATCH; msg = "lock match failed"; diff --git a/drivers/staging/lustre/lustre/llite/rw26.c b/drivers/staging/lustre/lustre/llite/rw26.c index e8d29e1fb691..e2fea8c7a4fe 100644 --- a/drivers/staging/lustre/lustre/llite/rw26.c +++ b/drivers/staging/lustre/lustre/llite/rw26.c @@ -165,28 +165,6 @@ static int ll_releasepage(struct page *vmpage, gfp_t gfp_mask) return result; } -static int ll_set_page_dirty(struct page *vmpage) -{ -#if 0 - struct cl_page *page = vvp_vmpage_page_transient(vmpage); - struct vvp_object *obj = cl_inode2vvp(vmpage->mapping->host); - struct vvp_page *cpg; - - /* - * XXX should page method be called here? - */ - LASSERT(&obj->co_cl == page->cp_obj); - cpg = cl2vvp_page(cl_page_at(page, &vvp_device_type)); - /* - * XXX cannot do much here, because page is possibly not locked: - * sys_munmap()->... - * ->unmap_page_range()->zap_pte_range()->set_page_dirty(). - */ - vvp_write_pending(obj, cpg); -#endif - return __set_page_dirty_nobuffers(vmpage); -} - #define MAX_DIRECTIO_SIZE (2*1024*1024*1024UL) static inline int ll_get_user_pages(int rw, unsigned long user_addr, @@ -274,7 +252,7 @@ ssize_t ll_direct_rw_pages(const struct lu_env *env, struct cl_io *io, * write directly */ if (clp->cp_type == CPT_CACHEABLE) { - struct page *vmpage = cl_page_vmpage(env, clp); + struct page *vmpage = cl_page_vmpage(clp); struct page *src_page; struct page *dst_page; void *src; @@ -478,19 +456,16 @@ out: static int ll_prepare_partial_page(const struct lu_env *env, struct cl_io *io, struct cl_page *pg) { - struct cl_object *obj = io->ci_obj; struct cl_attr *attr = ccc_env_thread_attr(env); - loff_t offset = cl_offset(obj, pg->cp_index); + struct cl_object *obj = io->ci_obj; + struct ccc_page *cp = cl_object_page_slice(obj, pg); + loff_t offset = cl_offset(obj, ccc_index(cp)); int result; cl_object_attr_lock(obj); result = cl_object_attr_get(env, obj, attr); cl_object_attr_unlock(obj); if (result == 0) { - struct ccc_page *cp; - - cp = cl2ccc_page(cl_page_at(pg, &vvp_device_type)); - /* * If are writing to a new page, no need to read old data. * The extent locking will have updated the KMS, and for our @@ -685,7 +660,7 @@ const struct address_space_operations ll_aops = { .direct_IO = ll_direct_IO_26, .writepage = ll_writepage, .writepages = ll_writepages, - .set_page_dirty = ll_set_page_dirty, + .set_page_dirty = __set_page_dirty_nobuffers, .write_begin = ll_write_begin, .write_end = ll_write_end, .invalidatepage = ll_invalidatepage, diff --git a/drivers/staging/lustre/lustre/llite/vvp_internal.h b/drivers/staging/lustre/lustre/llite/vvp_internal.h index 9abde114ba16..aa06f4031311 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_internal.h +++ b/drivers/staging/lustre/lustre/llite/vvp_internal.h @@ -49,7 +49,7 @@ int vvp_io_init(const struct lu_env *env, struct cl_object *obj, int vvp_lock_init(const struct lu_env *env, struct cl_object *obj, struct cl_lock *lock, const struct cl_io *io); int vvp_page_init(const struct lu_env *env, struct cl_object *obj, - struct cl_page *page, struct page *vmpage); + struct cl_page *page, pgoff_t index); struct lu_object *vvp_object_alloc(const struct lu_env *env, const struct lu_object_header *hdr, struct lu_device *dev); diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c index f4a1384730fa..ac9d615b78d9 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_io.c +++ b/drivers/staging/lustre/lustre/llite/vvp_io.c @@ -625,7 +625,7 @@ static int vvp_io_commit_sync(const struct lu_env *env, struct cl_io *io, cl_page_clip(env, page, 0, PAGE_SIZE); - SetPageUptodate(cl_page_vmpage(env, page)); + SetPageUptodate(cl_page_vmpage(page)); cl_page_disown(env, io, page); /* held in ll_cl_init() */ @@ -640,17 +640,15 @@ static int vvp_io_commit_sync(const struct lu_env *env, struct cl_io *io, static void write_commit_callback(const struct lu_env *env, struct cl_io *io, struct cl_page *page) { - const struct cl_page_slice *slice; struct ccc_page *cp; - struct page *vmpage; - - slice = cl_page_at(page, &vvp_device_type); - cp = cl2ccc_page(slice); - vmpage = cp->cpg_page; + struct page *vmpage = page->cp_vmpage; + struct cl_object *clob = cl_io_top(io)->ci_obj; SetPageUptodate(vmpage); set_page_dirty(vmpage); - vvp_write_pending(cl2ccc(slice->cpl_obj), cp); + + cp = cl2ccc_page(cl_object_page_slice(clob, page)); + vvp_write_pending(cl2ccc(clob), cp); cl_page_disown(env, io, page); @@ -660,19 +658,22 @@ static void write_commit_callback(const struct lu_env *env, struct cl_io *io, } /* make sure the page list is contiguous */ -static bool page_list_sanity_check(struct cl_page_list *plist) +static bool page_list_sanity_check(struct cl_object *obj, + struct cl_page_list *plist) { struct cl_page *page; pgoff_t index = CL_PAGE_EOF; cl_page_list_for_each(page, plist) { + struct ccc_page *cp = cl_object_page_slice(obj, page); + if (index == CL_PAGE_EOF) { - index = page->cp_index; + index = ccc_index(cp); continue; } ++index; - if (index == page->cp_index) + if (index == ccc_index(cp)) continue; return false; @@ -698,7 +699,7 @@ int vvp_io_write_commit(const struct lu_env *env, struct cl_io *io) CDEBUG(D_VFSTRACE, "commit async pages: %d, from %d, to %d\n", npages, cio->u.write.cui_from, cio->u.write.cui_to); - LASSERT(page_list_sanity_check(queue)); + LASSERT(page_list_sanity_check(obj, queue)); /* submit IO with async write */ rc = cl_io_commit_async(env, io, queue, @@ -723,7 +724,7 @@ int vvp_io_write_commit(const struct lu_env *env, struct cl_io *io) /* the first page must have been written. */ cio->u.write.cui_from = 0; } - LASSERT(page_list_sanity_check(queue)); + LASSERT(page_list_sanity_check(obj, queue)); LASSERT(ergo(rc == 0, queue->pl_nr == 0)); /* out of quota, try sync write */ @@ -747,7 +748,7 @@ int vvp_io_write_commit(const struct lu_env *env, struct cl_io *io) page = cl_page_list_first(queue); cl_page_list_del(env, queue, page); - if (!PageDirty(cl_page_vmpage(env, page))) + if (!PageDirty(cl_page_vmpage(page))) cl_page_discard(env, io, page); cl_page_disown(env, io, page); @@ -861,16 +862,13 @@ static int vvp_io_kernel_fault(struct vvp_fault_io *cfio) static void mkwrite_commit_callback(const struct lu_env *env, struct cl_io *io, struct cl_page *page) { - const struct cl_page_slice *slice; struct ccc_page *cp; - struct page *vmpage; + struct cl_object *clob = cl_io_top(io)->ci_obj; - slice = cl_page_at(page, &vvp_device_type); - cp = cl2ccc_page(slice); - vmpage = cp->cpg_page; + set_page_dirty(page->cp_vmpage); - set_page_dirty(vmpage); - vvp_write_pending(cl2ccc(slice->cpl_obj), cp); + cp = cl2ccc_page(cl_object_page_slice(clob, page)); + vvp_write_pending(cl2ccc(clob), cp); } static int vvp_io_fault_start(const struct lu_env *env, @@ -975,6 +973,7 @@ static int vvp_io_fault_start(const struct lu_env *env, wait_on_page_writeback(vmpage); if (!PageDirty(vmpage)) { struct cl_page_list *plist = &io->ci_queue.c2_qin; + struct ccc_page *cp = cl_object_page_slice(obj, page); int to = PAGE_SIZE; /* vvp_page_assume() calls wait_on_page_writeback(). */ @@ -984,7 +983,7 @@ static int vvp_io_fault_start(const struct lu_env *env, cl_page_list_add(plist, page); /* size fixup */ - if (last_index == page->cp_index) + if (last_index == ccc_index(cp)) to = size & ~PAGE_MASK; /* Do not set Dirty bit here so that in case IO is @@ -1069,7 +1068,7 @@ static int vvp_io_read_page(const struct lu_env *env, if (sbi->ll_ra_info.ra_max_pages_per_file && sbi->ll_ra_info.ra_max_pages) - ras_update(sbi, inode, ras, page->cp_index, + ras_update(sbi, inode, ras, ccc_index(cp), cp->cpg_defer_uptodate); /* Sanity check whether the page is protected by a lock. */ diff --git a/drivers/staging/lustre/lustre/llite/vvp_page.c b/drivers/staging/lustre/lustre/llite/vvp_page.c index 11e609ebbe3e..d9f13c31091a 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_page.c +++ b/drivers/staging/lustre/lustre/llite/vvp_page.c @@ -136,26 +136,15 @@ static void vvp_page_discard(const struct lu_env *env, struct cl_io *unused) { struct page *vmpage = cl2vm_page(slice); - struct address_space *mapping; struct ccc_page *cpg = cl2ccc_page(slice); - __u64 offset; LASSERT(vmpage); LASSERT(PageLocked(vmpage)); - mapping = vmpage->mapping; - if (cpg->cpg_defer_uptodate && !cpg->cpg_ra_used) - ll_ra_stats_inc(mapping, RA_STAT_DISCARDED); - - offset = vmpage->index << PAGE_SHIFT; - ll_teardown_mmaps(vmpage->mapping, offset, offset + PAGE_SIZE); + ll_ra_stats_inc(vmpage->mapping, RA_STAT_DISCARDED); - /* - * truncate_complete_page() calls - * a_ops->invalidatepage()->cl_page_delete()->vvp_page_delete(). - */ - truncate_complete_page(mapping, vmpage); + ll_invalidate_page(vmpage); } static void vvp_page_delete(const struct lu_env *env, @@ -269,7 +258,7 @@ static void vvp_page_completion_read(const struct lu_env *env, { struct ccc_page *cp = cl2ccc_page(slice); struct page *vmpage = cp->cpg_page; - struct cl_page *page = cl_page_top(slice->cpl_page); + struct cl_page *page = slice->cpl_page; struct inode *inode = ccc_object_inode(page->cp_obj); LASSERT(PageLocked(vmpage)); @@ -394,7 +383,6 @@ static const struct cl_page_operations vvp_page_ops = { .cpo_assume = vvp_page_assume, .cpo_unassume = vvp_page_unassume, .cpo_disown = vvp_page_disown, - .cpo_vmpage = ccc_page_vmpage, .cpo_discard = vvp_page_discard, .cpo_delete = vvp_page_delete, .cpo_export = vvp_page_export, @@ -504,7 +492,6 @@ static const struct cl_page_operations vvp_transient_page_ops = { .cpo_unassume = vvp_transient_page_unassume, .cpo_disown = vvp_transient_page_disown, .cpo_discard = vvp_transient_page_discard, - .cpo_vmpage = ccc_page_vmpage, .cpo_fini = vvp_transient_page_fini, .cpo_is_vmlocked = vvp_transient_page_is_vmlocked, .cpo_print = vvp_page_print, @@ -522,12 +509,14 @@ static const struct cl_page_operations vvp_transient_page_ops = { }; int vvp_page_init(const struct lu_env *env, struct cl_object *obj, - struct cl_page *page, struct page *vmpage) + struct cl_page *page, pgoff_t index) { struct ccc_page *cpg = cl_object_page_slice(obj, page); + struct page *vmpage = page->cp_vmpage; CLOBINVRNT(env, obj, ccc_object_invariant(obj)); + cpg->cpg_cl.cpl_index = index; cpg->cpg_page = vmpage; page_cache_get(vmpage); diff --git a/drivers/staging/lustre/lustre/lov/lov_cl_internal.h b/drivers/staging/lustre/lustre/lov/lov_cl_internal.h index 3d568fc62adc..b8e2315d5216 100644 --- a/drivers/staging/lustre/lustre/lov/lov_cl_internal.h +++ b/drivers/staging/lustre/lustre/lov/lov_cl_internal.h @@ -613,14 +613,13 @@ int lov_sublock_modify(const struct lu_env *env, struct lov_lock *lov, const struct cl_lock_descr *d, int idx); int lov_page_init(const struct lu_env *env, struct cl_object *ob, - struct cl_page *page, struct page *vmpage); + struct cl_page *page, pgoff_t index); int lovsub_page_init(const struct lu_env *env, struct cl_object *ob, - struct cl_page *page, struct page *vmpage); - + struct cl_page *page, pgoff_t index); int lov_page_init_empty(const struct lu_env *env, struct cl_object *obj, - struct cl_page *page, struct page *vmpage); + struct cl_page *page, pgoff_t index); int lov_page_init_raid0(const struct lu_env *env, struct cl_object *obj, - struct cl_page *page, struct page *vmpage); + struct cl_page *page, pgoff_t index); struct lu_object *lov_object_alloc(const struct lu_env *env, const struct lu_object_header *hdr, struct lu_device *dev); @@ -791,11 +790,6 @@ static inline struct lovsub_req *cl2lovsub_req(const struct cl_req_slice *slice) return container_of0(slice, struct lovsub_req, lsrq_cl); } -static inline struct cl_page *lov_sub_page(const struct cl_page_slice *slice) -{ - return slice->cpl_page->cp_child; -} - static inline struct lov_io *cl2lov_io(const struct lu_env *env, const struct cl_io_slice *ios) { diff --git a/drivers/staging/lustre/lustre/lov/lov_io.c b/drivers/staging/lustre/lustre/lov/lov_io.c index c60649032e59..e5b2cfc5b662 100644 --- a/drivers/staging/lustre/lustre/lov/lov_io.c +++ b/drivers/staging/lustre/lustre/lov/lov_io.c @@ -248,10 +248,12 @@ void lov_sub_put(struct lov_io_sub *sub) static int lov_page_stripe(const struct cl_page *page) { struct lovsub_object *subobj; + const struct cl_page_slice *slice; - subobj = lu2lovsub( - lu_object_locate(page->cp_child->cp_obj->co_lu.lo_header, - &lovsub_device_type)); + slice = cl_page_at(page, &lovsub_device_type); + LASSERT(slice->cpl_obj); + + subobj = cl2lovsub(slice->cpl_obj); return subobj->lso_index; } diff --git a/drivers/staging/lustre/lustre/lov/lov_object.c b/drivers/staging/lustre/lustre/lov/lov_object.c index 5d8a2b64ce21..0159b6f1e5c3 100644 --- a/drivers/staging/lustre/lustre/lov/lov_object.c +++ b/drivers/staging/lustre/lustre/lov/lov_object.c @@ -67,7 +67,7 @@ struct lov_layout_operations { int (*llo_print)(const struct lu_env *env, void *cookie, lu_printer_t p, const struct lu_object *o); int (*llo_page_init)(const struct lu_env *env, struct cl_object *obj, - struct cl_page *page, struct page *vmpage); + struct cl_page *page, pgoff_t index); int (*llo_lock_init)(const struct lu_env *env, struct cl_object *obj, struct cl_lock *lock, const struct cl_io *io); @@ -193,6 +193,18 @@ static int lov_init_sub(const struct lu_env *env, struct lov_object *lov, return result; } +static int lov_page_slice_fixup(struct lov_object *lov, + struct cl_object *stripe) +{ + struct cl_object_header *hdr = cl_object_header(&lov->lo_cl); + struct cl_object *o; + + cl_object_for_each(o, stripe) + o->co_slice_off += hdr->coh_page_bufsize; + + return cl_object_header(stripe)->coh_page_bufsize; +} + static int lov_init_raid0(const struct lu_env *env, struct lov_device *dev, struct lov_object *lov, const struct cl_object_conf *conf, @@ -222,6 +234,8 @@ static int lov_init_raid0(const struct lu_env *env, r0->lo_sub = libcfs_kvzalloc(r0->lo_nr * sizeof(r0->lo_sub[0]), GFP_NOFS); if (r0->lo_sub) { + int psz = 0; + result = 0; subconf->coc_inode = conf->coc_inode; spin_lock_init(&r0->lo_sub_lock); @@ -254,11 +268,21 @@ static int lov_init_raid0(const struct lu_env *env, if (result == -EAGAIN) { /* try again */ --i; result = 0; + continue; } } else { result = PTR_ERR(stripe); } + + if (result == 0) { + int sz = lov_page_slice_fixup(lov, stripe); + + LASSERT(ergo(psz > 0, psz == sz)); + psz = sz; + } } + if (result == 0) + cl_object_header(&lov->lo_cl)->coh_page_bufsize += psz; } else result = -ENOMEM; out: @@ -824,10 +848,10 @@ static int lov_object_print(const struct lu_env *env, void *cookie, } int lov_page_init(const struct lu_env *env, struct cl_object *obj, - struct cl_page *page, struct page *vmpage) + struct cl_page *page, pgoff_t index) { - return LOV_2DISPATCH_NOLOCK(cl2lov(obj), - llo_page_init, env, obj, page, vmpage); + return LOV_2DISPATCH_NOLOCK(cl2lov(obj), llo_page_init, env, obj, page, + index); } /** diff --git a/drivers/staging/lustre/lustre/lov/lov_page.c b/drivers/staging/lustre/lustre/lov/lov_page.c index 5d9b355fc608..0c508bd0f8ad 100644 --- a/drivers/staging/lustre/lustre/lov/lov_page.c +++ b/drivers/staging/lustre/lustre/lov/lov_page.c @@ -52,59 +52,6 @@ * Lov page operations. * */ - -static int lov_page_invariant(const struct cl_page_slice *slice) -{ - const struct cl_page *page = slice->cpl_page; - const struct cl_page *sub = lov_sub_page(slice); - - return ergo(sub, - page->cp_child == sub && - sub->cp_parent == page && - page->cp_state == sub->cp_state); -} - -static void lov_page_fini(const struct lu_env *env, - struct cl_page_slice *slice) -{ - struct cl_page *sub = lov_sub_page(slice); - - LINVRNT(lov_page_invariant(slice)); - - if (sub) { - LASSERT(sub->cp_state == CPS_FREEING); - lu_ref_del(&sub->cp_reference, "lov", sub->cp_parent); - sub->cp_parent = NULL; - slice->cpl_page->cp_child = NULL; - cl_page_put(env, sub); - } -} - -static int lov_page_own(const struct lu_env *env, - const struct cl_page_slice *slice, struct cl_io *io, - int nonblock) -{ - struct lov_io *lio = lov_env_io(env); - struct lov_io_sub *sub; - - LINVRNT(lov_page_invariant(slice)); - LINVRNT(!cl2lov_page(slice)->lps_invalid); - - sub = lov_page_subio(env, lio, slice); - if (!IS_ERR(sub)) { - lov_sub_page(slice)->cp_owner = sub->sub_io; - lov_sub_put(sub); - } else - LBUG(); /* Arrgh */ - return 0; -} - -static void lov_page_assume(const struct lu_env *env, - const struct cl_page_slice *slice, struct cl_io *io) -{ - lov_page_own(env, slice, io, 0); -} - static int lov_page_print(const struct lu_env *env, const struct cl_page_slice *slice, void *cookie, lu_printer_t printer) @@ -115,26 +62,17 @@ static int lov_page_print(const struct lu_env *env, } static const struct cl_page_operations lov_page_ops = { - .cpo_fini = lov_page_fini, - .cpo_own = lov_page_own, - .cpo_assume = lov_page_assume, .cpo_print = lov_page_print }; -static void lov_empty_page_fini(const struct lu_env *env, - struct cl_page_slice *slice) -{ - LASSERT(!slice->cpl_page->cp_child); -} - int lov_page_init_raid0(const struct lu_env *env, struct cl_object *obj, - struct cl_page *page, struct page *vmpage) + struct cl_page *page, pgoff_t index) { struct lov_object *loo = cl2lov(obj); struct lov_layout_raid0 *r0 = lov_r0(loo); struct lov_io *lio = lov_env_io(env); - struct cl_page *subpage; struct cl_object *subobj; + struct cl_object *o; struct lov_io_sub *sub; struct lov_page *lpg = cl_object_page_slice(obj, page); loff_t offset; @@ -142,13 +80,12 @@ int lov_page_init_raid0(const struct lu_env *env, struct cl_object *obj, int stripe; int rc; - offset = cl_offset(obj, page->cp_index); + offset = cl_offset(obj, index); stripe = lov_stripe_number(loo->lo_lsm, offset); LASSERT(stripe < r0->lo_nr); rc = lov_stripe_offset(loo->lo_lsm, offset, stripe, &suboff); LASSERT(rc == 0); - lpg->lps_invalid = 1; cl_page_slice_add(page, &lpg->lps_cl, obj, &lov_page_ops); sub = lov_sub_get(env, lio, stripe); @@ -156,35 +93,44 @@ int lov_page_init_raid0(const struct lu_env *env, struct cl_object *obj, return PTR_ERR(sub); subobj = lovsub2cl(r0->lo_sub[stripe]); - subpage = cl_page_alloc(sub->sub_env, subobj, cl_index(subobj, suboff), - vmpage, page->cp_type); - if (!IS_ERR(subpage)) { - subpage->cp_parent = page; - page->cp_child = subpage; - lpg->lps_invalid = 0; - } else { - rc = PTR_ERR(subpage); + list_for_each_entry(o, &subobj->co_lu.lo_header->loh_layers, + co_lu.lo_linkage) { + if (o->co_ops->coo_page_init) { + rc = o->co_ops->coo_page_init(sub->sub_env, o, page, + cl_index(subobj, suboff)); + if (rc != 0) + break; + } } lov_sub_put(sub); return rc; } +static int lov_page_empty_print(const struct lu_env *env, + const struct cl_page_slice *slice, + void *cookie, lu_printer_t printer) +{ + struct lov_page *lp = cl2lov_page(slice); + + return (*printer)(env, cookie, LUSTRE_LOV_NAME "-page@%p, empty.\n", + lp); +} + static const struct cl_page_operations lov_empty_page_ops = { - .cpo_fini = lov_empty_page_fini, - .cpo_print = lov_page_print + .cpo_print = lov_page_empty_print }; int lov_page_init_empty(const struct lu_env *env, struct cl_object *obj, - struct cl_page *page, struct page *vmpage) + struct cl_page *page, pgoff_t index) { struct lov_page *lpg = cl_object_page_slice(obj, page); void *addr; cl_page_slice_add(page, &lpg->lps_cl, obj, &lov_empty_page_ops); - addr = kmap(vmpage); + addr = kmap(page->cp_vmpage); memset(addr, 0, cl_page_size(obj)); - kunmap(vmpage); + kunmap(page->cp_vmpage); cl_page_export(env, page, 1); return 0; } diff --git a/drivers/staging/lustre/lustre/lov/lovsub_page.c b/drivers/staging/lustre/lustre/lov/lovsub_page.c index 2d945532b78e..fb4c0ccee30c 100644 --- a/drivers/staging/lustre/lustre/lov/lovsub_page.c +++ b/drivers/staging/lustre/lustre/lov/lovsub_page.c @@ -60,7 +60,7 @@ static const struct cl_page_operations lovsub_page_ops = { }; int lovsub_page_init(const struct lu_env *env, struct cl_object *obj, - struct cl_page *page, struct page *unused) + struct cl_page *page, pgoff_t ind) { struct lovsub_page *lsb = cl_object_page_slice(obj, page); diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c index 9b3c5c1f26e3..86591ceac9c1 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_io.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c @@ -692,42 +692,6 @@ cl_io_slice_page(const struct cl_io_slice *ios, struct cl_page *page) return slice; } -/** - * True iff \a page is within \a io range. - */ -static int cl_page_in_io(const struct cl_page *page, const struct cl_io *io) -{ - int result = 1; - loff_t start; - loff_t end; - pgoff_t idx; - - idx = page->cp_index; - switch (io->ci_type) { - case CIT_READ: - case CIT_WRITE: - /* - * check that [start, end) and [pos, pos + count) extents - * overlap. - */ - if (!cl_io_is_append(io)) { - const struct cl_io_rw_common *crw = &(io->u.ci_rw); - - start = cl_offset(page->cp_obj, idx); - end = cl_offset(page->cp_obj, idx + 1); - result = crw->crw_pos < end && - start < crw->crw_pos + crw->crw_count; - } - break; - case CIT_FAULT: - result = io->u.ci_fault.ft_index == idx; - break; - default: - LBUG(); - } - return result; -} - /** * Called by read io, when page has to be read from the server. * @@ -743,7 +707,6 @@ int cl_io_read_page(const struct lu_env *env, struct cl_io *io, LINVRNT(io->ci_type == CIT_READ || io->ci_type == CIT_FAULT); LINVRNT(cl_page_is_owned(page, io)); LINVRNT(io->ci_state == CIS_IO_GOING || io->ci_state == CIS_LOCKED); - LINVRNT(cl_page_in_io(page, io)); LINVRNT(cl_io_invariant(io)); queue = &io->ci_queue; @@ -893,7 +856,6 @@ static int cl_io_cancel(const struct lu_env *env, struct cl_io *io, cl_page_list_for_each(page, queue) { int rc; - LINVRNT(cl_page_in_io(page, io)); rc = cl_page_cancel(env, page); result = result ?: rc; } @@ -1229,7 +1191,7 @@ EXPORT_SYMBOL(cl_2queue_init_page); /** * Returns top-level io. * - * \see cl_object_top(), cl_page_top(). + * \see cl_object_top() */ struct cl_io *cl_io_top(struct cl_io *io) { @@ -1292,19 +1254,14 @@ static int cl_req_init(const struct lu_env *env, struct cl_req *req, int result; result = 0; - page = cl_page_top(page); - do { - list_for_each_entry(slice, &page->cp_layers, cpl_linkage) { - dev = lu2cl_dev(slice->cpl_obj->co_lu.lo_dev); - if (dev->cd_ops->cdo_req_init) { - result = dev->cd_ops->cdo_req_init(env, - dev, req); - if (result != 0) - break; - } + list_for_each_entry(slice, &page->cp_layers, cpl_linkage) { + dev = lu2cl_dev(slice->cpl_obj->co_lu.lo_dev); + if (dev->cd_ops->cdo_req_init) { + result = dev->cd_ops->cdo_req_init(env, dev, req); + if (result != 0) + break; } - page = page->cp_child; - } while (page && result == 0); + } return result; } @@ -1375,8 +1332,6 @@ void cl_req_page_add(const struct lu_env *env, struct cl_req_obj *rqo; int i; - page = cl_page_top(page); - LASSERT(list_empty(&page->cp_flight)); LASSERT(!page->cp_req); @@ -1407,8 +1362,6 @@ void cl_req_page_done(const struct lu_env *env, struct cl_page *page) { struct cl_req *req = page->cp_req; - page = cl_page_top(page); - LASSERT(!list_empty(&page->cp_flight)); LASSERT(req->crq_nrpages > 0); diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c index fa9b083915d9..72e6333220ea 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_object.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c @@ -84,7 +84,7 @@ int cl_object_header_init(struct cl_object_header *h) lockdep_set_class(&h->coh_lock_guard, &cl_lock_guard_class); lockdep_set_class(&h->coh_attr_guard, &cl_attr_guard_class); INIT_LIST_HEAD(&h->coh_locks); - h->coh_page_bufsize = ALIGN(sizeof(struct cl_page), 8); + h->coh_page_bufsize = 0; } return result; } @@ -138,7 +138,7 @@ EXPORT_SYMBOL(cl_object_get); /** * Returns the top-object for a given \a o. * - * \see cl_page_top(), cl_io_top() + * \see cl_io_top() */ struct cl_object *cl_object_top(struct cl_object *o) { diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c index 0844a97c3258..cb156739b254 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_page.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c @@ -62,18 +62,6 @@ static void cl_page_delete0(const struct lu_env *env, struct cl_page *pg); # define PINVRNT(env, page, exp) \ ((void)sizeof(env), (void)sizeof(page), (void)sizeof !!(exp)) -/** - * Internal version of cl_page_top, it should be called if the page is - * known to be not freed, says with page referenced, or radix tree lock held, - * or page owned. - */ -static struct cl_page *cl_page_top_trusted(struct cl_page *page) -{ - while (page->cp_parent) - page = page->cp_parent; - return page; -} - /** * Internal version of cl_page_get(). * @@ -102,14 +90,10 @@ cl_page_at_trusted(const struct cl_page *page, { const struct cl_page_slice *slice; - page = cl_page_top_trusted((struct cl_page *)page); - do { - list_for_each_entry(slice, &page->cp_layers, cpl_linkage) { - if (slice->cpl_obj->co_lu.lo_dev->ld_type == dtype) - return slice; - } - page = page->cp_child; - } while (page); + list_for_each_entry(slice, &page->cp_layers, cpl_linkage) { + if (slice->cpl_obj->co_lu.lo_dev->ld_type == dtype) + return slice; + } return NULL; } @@ -120,7 +104,6 @@ static void cl_page_free(const struct lu_env *env, struct cl_page *page) PASSERT(env, page, list_empty(&page->cp_batch)); PASSERT(env, page, !page->cp_owner); PASSERT(env, page, !page->cp_req); - PASSERT(env, page, !page->cp_parent); PASSERT(env, page, page->cp_state == CPS_FREEING); while (!list_empty(&page->cp_layers)) { @@ -129,7 +112,8 @@ static void cl_page_free(const struct lu_env *env, struct cl_page *page) slice = list_entry(page->cp_layers.next, struct cl_page_slice, cpl_linkage); list_del_init(page->cp_layers.next); - slice->cpl_ops->cpo_fini(env, slice); + if (unlikely(slice->cpl_ops->cpo_fini)) + slice->cpl_ops->cpo_fini(env, slice); } lu_object_ref_del_at(&obj->co_lu, &page->cp_obj_ref, "cl_page", page); cl_object_put(env, obj); @@ -165,7 +149,7 @@ struct cl_page *cl_page_alloc(const struct lu_env *env, cl_object_get(o); lu_object_ref_add_at(&o->co_lu, &page->cp_obj_ref, "cl_page", page); - page->cp_index = ind; + page->cp_vmpage = vmpage; cl_page_state_set_trust(page, CPS_CACHED); page->cp_type = type; INIT_LIST_HEAD(&page->cp_layers); @@ -176,8 +160,8 @@ struct cl_page *cl_page_alloc(const struct lu_env *env, head = o->co_lu.lo_header; list_for_each_entry(o, &head->loh_layers, co_lu.lo_linkage) { if (o->co_ops->coo_page_init) { - result = o->co_ops->coo_page_init(env, o, - page, vmpage); + result = o->co_ops->coo_page_init(env, o, page, + ind); if (result != 0) { cl_page_delete0(env, page); cl_page_free(env, page); @@ -249,27 +233,12 @@ EXPORT_SYMBOL(cl_page_find); static inline int cl_page_invariant(const struct cl_page *pg) { - struct cl_page *parent; - struct cl_page *child; - struct cl_io *owner; - /* * Page invariant is protected by a VM lock. */ LINVRNT(cl_page_is_vmlocked(NULL, pg)); - parent = pg->cp_parent; - child = pg->cp_child; - owner = pg->cp_owner; - - return cl_page_in_use(pg) && - ergo(parent, parent->cp_child == pg) && - ergo(child, child->cp_parent == pg) && - ergo(child, pg->cp_obj != child->cp_obj) && - ergo(parent, pg->cp_obj != parent->cp_obj) && - ergo(owner && parent, - parent->cp_owner == pg->cp_owner->ci_parent) && - ergo(owner && child, child->cp_owner->ci_parent == owner); + return cl_page_in_use_noref(pg); } static void cl_page_state_set0(const struct lu_env *env, @@ -322,13 +291,9 @@ static void cl_page_state_set0(const struct lu_env *env, old = page->cp_state; PASSERT(env, page, allowed_transitions[old][state]); CL_PAGE_HEADER(D_TRACE, env, page, "%d -> %d\n", old, state); - for (; page; page = page->cp_child) { - PASSERT(env, page, page->cp_state == old); - PASSERT(env, page, - equi(state == CPS_OWNED, page->cp_owner)); - - cl_page_state_set_trust(page, state); - } + PASSERT(env, page, page->cp_state == old); + PASSERT(env, page, equi(state == CPS_OWNED, page->cp_owner)); + cl_page_state_set_trust(page, state); } static void cl_page_state_set(const struct lu_env *env, @@ -362,8 +327,6 @@ EXPORT_SYMBOL(cl_page_get); */ void cl_page_put(const struct lu_env *env, struct cl_page *page) { - PASSERT(env, page, atomic_read(&page->cp_ref) > !!page->cp_parent); - CL_PAGE_HEADER(D_TRACE, env, page, "%d\n", atomic_read(&page->cp_ref)); @@ -382,35 +345,11 @@ void cl_page_put(const struct lu_env *env, struct cl_page *page) } EXPORT_SYMBOL(cl_page_put); -/** - * Returns a VM page associated with a given cl_page. - */ -struct page *cl_page_vmpage(const struct lu_env *env, struct cl_page *page) -{ - const struct cl_page_slice *slice; - - /* - * Find uppermost layer with ->cpo_vmpage() method, and return its - * result. - */ - page = cl_page_top(page); - do { - list_for_each_entry(slice, &page->cp_layers, cpl_linkage) { - if (slice->cpl_ops->cpo_vmpage) - return slice->cpl_ops->cpo_vmpage(env, slice); - } - page = page->cp_child; - } while (page); - LBUG(); /* ->cpo_vmpage() has to be defined somewhere in the stack */ -} -EXPORT_SYMBOL(cl_page_vmpage); - /** * Returns a cl_page associated with a VM page, and given cl_object. */ struct cl_page *cl_vmpage_page(struct page *vmpage, struct cl_object *obj) { - struct cl_page *top; struct cl_page *page; KLASSERT(PageLocked(vmpage)); @@ -421,36 +360,15 @@ struct cl_page *cl_vmpage_page(struct page *vmpage, struct cl_object *obj) * bottom-to-top pass. */ - /* - * This loop assumes that ->private points to the top-most page. This - * can be rectified easily. - */ - top = (struct cl_page *)vmpage->private; - if (!top) - return NULL; - - for (page = top; page; page = page->cp_child) { - if (cl_object_same(page->cp_obj, obj)) { - cl_page_get_trust(page); - break; - } + page = (struct cl_page *)vmpage->private; + if (page) { + cl_page_get_trust(page); + LASSERT(page->cp_type == CPT_CACHEABLE); } - LASSERT(ergo(page, page->cp_type == CPT_CACHEABLE)); return page; } EXPORT_SYMBOL(cl_vmpage_page); -/** - * Returns the top-page for a given page. - * - * \see cl_object_top(), cl_io_top() - */ -struct cl_page *cl_page_top(struct cl_page *page) -{ - return cl_page_top_trusted(page); -} -EXPORT_SYMBOL(cl_page_top); - const struct cl_page_slice *cl_page_at(const struct cl_page *page, const struct lu_device_type *dtype) { @@ -470,21 +388,14 @@ EXPORT_SYMBOL(cl_page_at); int (*__method)_proto; \ \ __result = 0; \ - __page = cl_page_top(__page); \ - do { \ - list_for_each_entry(__scan, &__page->cp_layers, \ - cpl_linkage) { \ - __method = *(void **)((char *)__scan->cpl_ops + \ - __op); \ - if (__method) { \ - __result = (*__method)(__env, __scan, \ - ## __VA_ARGS__); \ - if (__result != 0) \ - break; \ - } \ - } \ - __page = __page->cp_child; \ - } while (__page && __result == 0); \ + list_for_each_entry(__scan, &__page->cp_layers, cpl_linkage) { \ + __method = *(void **)((char *)__scan->cpl_ops + __op); \ + if (__method) { \ + __result = (*__method)(__env, __scan, ## __VA_ARGS__); \ + if (__result != 0) \ + break; \ + } \ + } \ if (__result > 0) \ __result = 0; \ __result; \ @@ -498,18 +409,11 @@ do { \ ptrdiff_t __op = (_op); \ void (*__method)_proto; \ \ - __page = cl_page_top(__page); \ - do { \ - list_for_each_entry(__scan, &__page->cp_layers, \ - cpl_linkage) { \ - __method = *(void **)((char *)__scan->cpl_ops + \ - __op); \ - if (__method) \ - (*__method)(__env, __scan, \ - ## __VA_ARGS__); \ - } \ - __page = __page->cp_child; \ - } while (__page); \ + list_for_each_entry(__scan, &__page->cp_layers, cpl_linkage) { \ + __method = *(void **)((char *)__scan->cpl_ops + __op); \ + if (__method) \ + (*__method)(__env, __scan, ## __VA_ARGS__); \ + } \ } while (0) #define CL_PAGE_INVOID_REVERSE(_env, _page, _op, _proto, ...) \ @@ -520,20 +424,11 @@ do { \ ptrdiff_t __op = (_op); \ void (*__method)_proto; \ \ - /* get to the bottom page. */ \ - while (__page->cp_child) \ - __page = __page->cp_child; \ - do { \ - list_for_each_entry_reverse(__scan, &__page->cp_layers, \ - cpl_linkage) { \ - __method = *(void **)((char *)__scan->cpl_ops + \ - __op); \ - if (__method) \ - (*__method)(__env, __scan, \ - ## __VA_ARGS__); \ - } \ - __page = __page->cp_parent; \ - } while (__page); \ + list_for_each_entry_reverse(__scan, &__page->cp_layers, cpl_linkage) { \ + __method = *(void **)((char *)__scan->cpl_ops + __op); \ + if (__method) \ + (*__method)(__env, __scan, ## __VA_ARGS__); \ + } \ } while (0) static int cl_page_invoke(const struct lu_env *env, @@ -559,20 +454,17 @@ static void cl_page_invoid(const struct lu_env *env, static void cl_page_owner_clear(struct cl_page *page) { - for (page = cl_page_top(page); page; page = page->cp_child) { - if (page->cp_owner) { - LASSERT(page->cp_owner->ci_owned_nr > 0); - page->cp_owner->ci_owned_nr--; - page->cp_owner = NULL; - page->cp_task = NULL; - } + if (page->cp_owner) { + LASSERT(page->cp_owner->ci_owned_nr > 0); + page->cp_owner->ci_owned_nr--; + page->cp_owner = NULL; + page->cp_task = NULL; } } static void cl_page_owner_set(struct cl_page *page) { - for (page = cl_page_top(page); page; page = page->cp_child) - page->cp_owner->ci_owned_nr++; + page->cp_owner->ci_owned_nr++; } void cl_page_disown0(const struct lu_env *env, @@ -603,8 +495,9 @@ void cl_page_disown0(const struct lu_env *env, */ int cl_page_is_owned(const struct cl_page *pg, const struct cl_io *io) { + struct cl_io *top = cl_io_top((struct cl_io *)io); LINVRNT(cl_object_same(pg->cp_obj, io->ci_obj)); - return pg->cp_state == CPS_OWNED && pg->cp_owner == io; + return pg->cp_state == CPS_OWNED && pg->cp_owner == top; } EXPORT_SYMBOL(cl_page_is_owned); @@ -635,7 +528,6 @@ static int cl_page_own0(const struct lu_env *env, struct cl_io *io, PINVRNT(env, pg, !cl_page_is_owned(pg, io)); - pg = cl_page_top(pg); io = cl_io_top(io); if (pg->cp_state == CPS_FREEING) { @@ -649,7 +541,7 @@ static int cl_page_own0(const struct lu_env *env, struct cl_io *io, if (result == 0) { PASSERT(env, pg, !pg->cp_owner); PASSERT(env, pg, !pg->cp_req); - pg->cp_owner = io; + pg->cp_owner = cl_io_top(io); pg->cp_task = current; cl_page_owner_set(pg); if (pg->cp_state != CPS_FREEING) { @@ -702,12 +594,11 @@ void cl_page_assume(const struct lu_env *env, { PINVRNT(env, pg, cl_object_same(pg->cp_obj, io->ci_obj)); - pg = cl_page_top(pg); io = cl_io_top(io); cl_page_invoid(env, io, pg, CL_PAGE_OP(cpo_assume)); PASSERT(env, pg, !pg->cp_owner); - pg->cp_owner = io; + pg->cp_owner = cl_io_top(io); pg->cp_task = current; cl_page_owner_set(pg); cl_page_state_set(env, pg, CPS_OWNED); @@ -731,7 +622,6 @@ void cl_page_unassume(const struct lu_env *env, PINVRNT(env, pg, cl_page_is_owned(pg, io)); PINVRNT(env, pg, cl_page_invariant(pg)); - pg = cl_page_top(pg); io = cl_io_top(io); cl_page_owner_clear(pg); cl_page_state_set(env, pg, CPS_CACHED); @@ -758,7 +648,6 @@ void cl_page_disown(const struct lu_env *env, { PINVRNT(env, pg, cl_page_is_owned(pg, io)); - pg = cl_page_top(pg); io = cl_io_top(io); cl_page_disown0(env, io, pg); } @@ -791,7 +680,6 @@ EXPORT_SYMBOL(cl_page_discard); */ static void cl_page_delete0(const struct lu_env *env, struct cl_page *pg) { - PASSERT(env, pg, pg == cl_page_top(pg)); PASSERT(env, pg, pg->cp_state != CPS_FREEING); /* @@ -825,7 +713,6 @@ static void cl_page_delete0(const struct lu_env *env, struct cl_page *pg) * Once page reaches cl_page_state::CPS_FREEING, all remaining references will * drain after some time, at which point page will be recycled. * - * \pre pg == cl_page_top(pg) * \pre VM page is locked * \post pg->cp_state == CPS_FREEING * @@ -865,7 +752,6 @@ int cl_page_is_vmlocked(const struct lu_env *env, const struct cl_page *pg) int result; const struct cl_page_slice *slice; - pg = cl_page_top_trusted((struct cl_page *)pg); slice = container_of(pg->cp_layers.next, const struct cl_page_slice, cpl_linkage); PASSERT(env, pg, slice->cpl_ops->cpo_is_vmlocked); @@ -1082,9 +968,8 @@ void cl_page_header_print(const struct lu_env *env, void *cookie, lu_printer_t printer, const struct cl_page *pg) { (*printer)(env, cookie, - "page@%p[%d %p:%lu ^%p_%p %d %d %d %p %p %#x]\n", + "page@%p[%d %p %d %d %d %p %p %#x]\n", pg, atomic_read(&pg->cp_ref), pg->cp_obj, - pg->cp_index, pg->cp_parent, pg->cp_child, pg->cp_state, pg->cp_error, pg->cp_type, pg->cp_owner, pg->cp_req, pg->cp_flags); } @@ -1096,11 +981,7 @@ EXPORT_SYMBOL(cl_page_header_print); void cl_page_print(const struct lu_env *env, void *cookie, lu_printer_t printer, const struct cl_page *pg) { - struct cl_page *scan; - - for (scan = cl_page_top((struct cl_page *)pg); scan; - scan = scan->cp_child) - cl_page_header_print(env, cookie, printer, scan); + cl_page_header_print(env, cookie, printer, pg); CL_PAGE_INVOKE(env, (struct cl_page *)pg, CL_PAGE_OP(cpo_print), (const struct lu_env *env, const struct cl_page_slice *slice, diff --git a/drivers/staging/lustre/lustre/obdecho/echo_client.c b/drivers/staging/lustre/lustre/obdecho/echo_client.c index 6c205f9cad9f..db56081330e9 100644 --- a/drivers/staging/lustre/lustre/obdecho/echo_client.c +++ b/drivers/staging/lustre/lustre/obdecho/echo_client.c @@ -81,7 +81,6 @@ struct echo_object_conf { struct echo_page { struct cl_page_slice ep_cl; struct mutex ep_lock; - struct page *ep_vmpage; }; struct echo_lock { @@ -219,12 +218,6 @@ static struct lu_kmem_descr echo_caches[] = { * * @{ */ -static struct page *echo_page_vmpage(const struct lu_env *env, - const struct cl_page_slice *slice) -{ - return cl2echo_page(slice)->ep_vmpage; -} - static int echo_page_own(const struct lu_env *env, const struct cl_page_slice *slice, struct cl_io *io, int nonblock) @@ -273,12 +266,10 @@ static void echo_page_completion(const struct lu_env *env, static void echo_page_fini(const struct lu_env *env, struct cl_page_slice *slice) { - struct echo_page *ep = cl2echo_page(slice); struct echo_object *eco = cl2echo_obj(slice->cpl_obj); - struct page *vmpage = ep->ep_vmpage; atomic_dec(&eco->eo_npages); - page_cache_release(vmpage); + page_cache_release(slice->cpl_page->cp_vmpage); } static int echo_page_prep(const struct lu_env *env, @@ -295,7 +286,8 @@ static int echo_page_print(const struct lu_env *env, struct echo_page *ep = cl2echo_page(slice); (*printer)(env, cookie, LUSTRE_ECHO_CLIENT_NAME"-page@%p %d vm@%p\n", - ep, mutex_is_locked(&ep->ep_lock), ep->ep_vmpage); + ep, mutex_is_locked(&ep->ep_lock), + slice->cpl_page->cp_vmpage); return 0; } @@ -303,7 +295,6 @@ static const struct cl_page_operations echo_page_ops = { .cpo_own = echo_page_own, .cpo_disown = echo_page_disown, .cpo_discard = echo_page_discard, - .cpo_vmpage = echo_page_vmpage, .cpo_fini = echo_page_fini, .cpo_print = echo_page_print, .cpo_is_vmlocked = echo_page_is_vmlocked, @@ -367,13 +358,12 @@ static struct cl_lock_operations echo_lock_ops = { * @{ */ static int echo_page_init(const struct lu_env *env, struct cl_object *obj, - struct cl_page *page, struct page *vmpage) + struct cl_page *page, pgoff_t index) { struct echo_page *ep = cl_object_page_slice(obj, page); struct echo_object *eco = cl2echo_obj(obj); - ep->ep_vmpage = vmpage; - page_cache_get(vmpage); + page_cache_get(page->cp_vmpage); mutex_init(&ep->ep_lock); cl_page_slice_add(page, &ep->ep_cl, obj, &echo_page_ops); atomic_inc(&eco->eo_npages); @@ -568,6 +558,8 @@ static struct lu_object *echo_object_alloc(const struct lu_env *env, obj = &echo_obj2cl(eco)->co_lu; cl_object_header_init(hdr); + hdr->coh_page_bufsize = cfs_size_round(sizeof(struct cl_page)); + lu_object_init(obj, &hdr->coh_lu, dev); lu_object_add_top(&hdr->coh_lu, obj); diff --git a/drivers/staging/lustre/lustre/osc/osc_cache.c b/drivers/staging/lustre/lustre/osc/osc_cache.c index 3be4b1f11767..7460793324d6 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cache.c +++ b/drivers/staging/lustre/lustre/osc/osc_cache.c @@ -276,7 +276,7 @@ static int osc_extent_sanity_check0(struct osc_extent *ext, page_count = 0; list_for_each_entry(oap, &ext->oe_pages, oap_pending_item) { - pgoff_t index = oap2cl_page(oap)->cp_index; + pgoff_t index = osc_index(oap2osc(oap)); ++page_count; if (index > ext->oe_end || index < ext->oe_start) { rc = 110; @@ -991,19 +991,19 @@ static int osc_extent_truncate(struct osc_extent *ext, pgoff_t trunc_index, /* discard all pages with index greater then trunc_index */ list_for_each_entry_safe(oap, tmp, &ext->oe_pages, oap_pending_item) { - struct cl_page *sub = oap2cl_page(oap); - struct cl_page *page = cl_page_top(sub); + pgoff_t index = osc_index(oap2osc(oap)); + struct cl_page *page = oap2cl_page(oap); LASSERT(list_empty(&oap->oap_rpc_item)); /* only discard the pages with their index greater than * trunc_index, and ... */ - if (sub->cp_index < trunc_index || - (sub->cp_index == trunc_index && partial)) { + if (index < trunc_index || + (index == trunc_index && partial)) { /* accounting how many pages remaining in the chunk * so that we can calculate grants correctly. */ - if (sub->cp_index >> ppc_bits == trunc_chunk) + if (index >> ppc_bits == trunc_chunk) ++pages_in_chunk; continue; } @@ -1256,7 +1256,7 @@ static int osc_make_ready(const struct lu_env *env, struct osc_async_page *oap, int cmd) { struct osc_page *opg = oap2osc_page(oap); - struct cl_page *page = cl_page_top(oap2cl_page(oap)); + struct cl_page *page = oap2cl_page(oap); int result; LASSERT(cmd == OBD_BRW_WRITE); /* no cached reads */ @@ -1271,7 +1271,7 @@ static int osc_refresh_count(const struct lu_env *env, struct osc_async_page *oap, int cmd) { struct osc_page *opg = oap2osc_page(oap); - struct cl_page *page = oap2cl_page(oap); + pgoff_t index = osc_index(oap2osc(oap)); struct cl_object *obj; struct cl_attr *attr = &osc_env_info(env)->oti_attr; @@ -1288,10 +1288,10 @@ static int osc_refresh_count(const struct lu_env *env, if (result < 0) return result; kms = attr->cat_kms; - if (cl_offset(obj, page->cp_index) >= kms) + if (cl_offset(obj, index) >= kms) /* catch race with truncate */ return 0; - else if (cl_offset(obj, page->cp_index + 1) > kms) + else if (cl_offset(obj, index + 1) > kms) /* catch sub-page write at end of file */ return kms % PAGE_CACHE_SIZE; else @@ -1302,7 +1302,7 @@ static int osc_completion(const struct lu_env *env, struct osc_async_page *oap, int cmd, int rc) { struct osc_page *opg = oap2osc_page(oap); - struct cl_page *page = cl_page_top(oap2cl_page(oap)); + struct cl_page *page = oap2cl_page(oap); struct osc_object *obj = cl2osc(opg->ops_cl.cpl_obj); enum cl_req_type crt; int srvlock; @@ -2313,7 +2313,7 @@ int osc_queue_async_io(const struct lu_env *env, struct cl_io *io, OSC_IO_DEBUG(osc, "oap %p page %p added for cmd %d\n", oap, oap->oap_page, oap->oap_cmd & OBD_BRW_RWMASK); - index = oap2cl_page(oap)->cp_index; + index = osc_index(oap2osc(oap)); /* Add this page into extent by the following steps: * 1. if there exists an active extent for this IO, mostly this page @@ -2425,21 +2425,21 @@ int osc_teardown_async_page(const struct lu_env *env, LASSERT(oap->oap_magic == OAP_MAGIC); CDEBUG(D_INFO, "teardown oap %p page %p at index %lu.\n", - oap, ops, oap2cl_page(oap)->cp_index); + oap, ops, osc_index(oap2osc(oap))); osc_object_lock(obj); if (!list_empty(&oap->oap_rpc_item)) { CDEBUG(D_CACHE, "oap %p is not in cache.\n", oap); rc = -EBUSY; } else if (!list_empty(&oap->oap_pending_item)) { - ext = osc_extent_lookup(obj, oap2cl_page(oap)->cp_index); + ext = osc_extent_lookup(obj, osc_index(oap2osc(oap))); /* only truncated pages are allowed to be taken out. * See osc_extent_truncate() and osc_cache_truncate_start() * for details. */ if (ext && ext->oe_state != OES_TRUNC) { OSC_EXTENT_DUMP(D_ERROR, ext, "trunc at %lu.\n", - oap2cl_page(oap)->cp_index); + osc_index(oap2osc(oap))); rc = -EBUSY; } } @@ -2462,7 +2462,7 @@ int osc_flush_async_page(const struct lu_env *env, struct cl_io *io, struct osc_extent *ext = NULL; struct osc_object *obj = cl2osc(ops->ops_cl.cpl_obj); struct cl_page *cp = ops->ops_cl.cpl_page; - pgoff_t index = cp->cp_index; + pgoff_t index = osc_index(ops); struct osc_async_page *oap = &ops->ops_oap; bool unplug = false; int rc = 0; @@ -2477,8 +2477,7 @@ int osc_flush_async_page(const struct lu_env *env, struct cl_io *io, switch (ext->oe_state) { case OES_RPC: case OES_LOCK_DONE: - CL_PAGE_DEBUG(D_ERROR, env, cl_page_top(cp), - "flush an in-rpc page?\n"); + CL_PAGE_DEBUG(D_ERROR, env, cp, "flush an in-rpc page?\n"); LASSERT(0); break; case OES_LOCKING: @@ -2504,7 +2503,7 @@ int osc_flush_async_page(const struct lu_env *env, struct cl_io *io, break; } - rc = cl_page_prep(env, io, cl_page_top(cp), CRT_WRITE); + rc = cl_page_prep(env, io, cp, CRT_WRITE); if (rc) goto out; @@ -2548,7 +2547,7 @@ int osc_cancel_async_page(const struct lu_env *env, struct osc_page *ops) struct osc_extent *ext; struct osc_extent *found = NULL; struct list_head *plist; - pgoff_t index = oap2cl_page(oap)->cp_index; + pgoff_t index = osc_index(ops); int rc = -EBUSY; int cmd; @@ -2611,12 +2610,12 @@ int osc_queue_sync_pages(const struct lu_env *env, struct osc_object *obj, pgoff_t end = 0; list_for_each_entry(oap, list, oap_pending_item) { - struct cl_page *cp = oap2cl_page(oap); + pgoff_t index = osc_index(oap2osc(oap)); - if (cp->cp_index > end) - end = cp->cp_index; - if (cp->cp_index < start) - start = cp->cp_index; + if (index > end) + end = index; + if (index < start) + start = index; ++page_count; mppr <<= (page_count > mppr); } @@ -3033,7 +3032,7 @@ int osc_page_gang_lookup(const struct lu_env *env, struct cl_io *io, break; } - page = cl_page_top(ops->ops_cl.cpl_page); + page = ops->ops_cl.cpl_page; LASSERT(page->cp_type == CPT_CACHEABLE); if (page->cp_state == CPS_FREEING) continue; @@ -3061,7 +3060,7 @@ int osc_page_gang_lookup(const struct lu_env *env, struct cl_io *io, if (res == CLP_GANG_OKAY) res = (*cb)(env, io, ops, cbdata); - page = cl_page_top(ops->ops_cl.cpl_page); + page = ops->ops_cl.cpl_page; lu_ref_del(&page->cp_reference, "gang_lookup", current); cl_page_put(env, page); } @@ -3094,7 +3093,7 @@ static int check_and_discard_cb(const struct lu_env *env, struct cl_io *io, index = osc_index(ops); if (index >= info->oti_fn_index) { struct cl_lock *tmp; - struct cl_page *page = cl_page_top(ops->ops_cl.cpl_page); + struct cl_page *page = ops->ops_cl.cpl_page; /* refresh non-overlapped index */ tmp = cl_lock_at_pgoff(env, lock->cll_descr.cld_obj, index, @@ -3127,7 +3126,7 @@ static int discard_cb(const struct lu_env *env, struct cl_io *io, { struct osc_thread_info *info = osc_env_info(env); struct cl_lock *lock = cbdata; - struct cl_page *page = cl_page_top(ops->ops_cl.cpl_page); + struct cl_page *page = ops->ops_cl.cpl_page; LASSERT(lock->cll_descr.cld_mode >= CLM_WRITE); @@ -3135,7 +3134,7 @@ static int discard_cb(const struct lu_env *env, struct cl_io *io, info->oti_next_index = osc_index(ops) + 1; if (cl_page_own(env, io, page) == 0) { KLASSERT(ergo(page->cp_type == CPT_CACHEABLE, - !PageDirty(cl_page_vmpage(env, page)))); + !PageDirty(cl_page_vmpage(page)))); /* discard the page */ cl_page_discard(env, io, page); diff --git a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h index cf87043ce4b8..89552d73c497 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h +++ b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h @@ -416,7 +416,7 @@ struct lu_object *osc_object_alloc(const struct lu_env *env, const struct lu_object_header *hdr, struct lu_device *dev); int osc_page_init(const struct lu_env *env, struct cl_object *obj, - struct cl_page *page, struct page *vmpage); + struct cl_page *page, pgoff_t ind); void osc_index2policy (ldlm_policy_data_t *policy, const struct cl_object *obj, pgoff_t start, pgoff_t end); @@ -553,6 +553,11 @@ static inline struct osc_page *oap2osc(struct osc_async_page *oap) return container_of0(oap, struct osc_page, ops_oap); } +static inline pgoff_t osc_index(struct osc_page *opg) +{ + return opg->ops_cl.cpl_index; +} + static inline struct cl_page *oap2cl_page(struct osc_async_page *oap) { return oap2osc(oap)->ops_cl.cpl_page; @@ -563,11 +568,6 @@ static inline struct osc_page *oap2osc_page(struct osc_async_page *oap) return (struct osc_page *)container_of(oap, struct osc_page, ops_oap); } -static inline pgoff_t osc_index(struct osc_page *opg) -{ - return opg->ops_cl.cpl_page->cp_index; -} - static inline struct osc_lock *cl2osc_lock(const struct cl_lock_slice *slice) { LINVRNT(osc_is_object(&slice->cls_obj->co_lu)); diff --git a/drivers/staging/lustre/lustre/osc/osc_io.c b/drivers/staging/lustre/lustre/osc/osc_io.c index e9e18a1085e2..1ae8a227ad3d 100644 --- a/drivers/staging/lustre/lustre/osc/osc_io.c +++ b/drivers/staging/lustre/lustre/osc/osc_io.c @@ -68,11 +68,15 @@ static struct osc_io *cl2osc_io(const struct lu_env *env, return oio; } -static struct osc_page *osc_cl_page_osc(struct cl_page *page) +static struct osc_page *osc_cl_page_osc(struct cl_page *page, + struct osc_object *osc) { const struct cl_page_slice *slice; - slice = cl_page_at(page, &osc_device_type); + if (osc) + slice = cl_object_page_slice(&osc->oo_cl, page); + else + slice = cl_page_at(page, &osc_device_type); LASSERT(slice); return cl2osc_page(slice); @@ -137,7 +141,7 @@ static int osc_io_submit(const struct lu_env *env, io = page->cp_owner; LASSERT(io); - opg = osc_cl_page_osc(page); + opg = osc_cl_page_osc(page, osc); oap = &opg->ops_oap; LASSERT(osc == oap->oap_obj); @@ -258,15 +262,11 @@ static int osc_io_commit_async(const struct lu_env *env, } } - /* - * NOTE: here @page is a top-level page. This is done to avoid - * creation of sub-page-list. - */ while (qin->pl_nr > 0) { struct osc_async_page *oap; page = cl_page_list_first(qin); - opg = osc_cl_page_osc(page); + opg = osc_cl_page_osc(page, osc); oap = &opg->ops_oap; if (!list_empty(&oap->oap_rpc_item)) { @@ -283,8 +283,7 @@ static int osc_io_commit_async(const struct lu_env *env, break; } - osc_page_touch_at(env, osc2cl(osc), - opg->ops_cl.cpl_page->cp_index, + osc_page_touch_at(env, osc2cl(osc), osc_index(opg), page == last_page ? to : PAGE_SIZE); cl_page_list_del(env, qin, page); @@ -403,14 +402,9 @@ static int trunc_check_cb(const struct lu_env *env, struct cl_io *io, CL_PAGE_DEBUG(D_ERROR, env, page, "exists %llu/%s.\n", start, current->comm); - { - struct page *vmpage = cl_page_vmpage(env, page); - - if (PageLocked(vmpage)) - CDEBUG(D_CACHE, "page %p index %lu locked for %d.\n", - ops, page->cp_index, - (oap->oap_cmd & OBD_BRW_RWMASK)); - } + if (PageLocked(page->cp_vmpage)) + CDEBUG(D_CACHE, "page %p index %lu locked for %d.\n", + ops, osc_index(ops), oap->oap_cmd & OBD_BRW_RWMASK); return CLP_GANG_OKAY; } @@ -788,18 +782,21 @@ static void osc_req_attr_set(const struct lu_env *env, oa->o_valid |= OBD_MD_FLID; } if (flags & OBD_MD_FLHANDLE) { + struct cl_object *subobj; + clerq = slice->crs_req; LASSERT(!list_empty(&clerq->crq_pages)); apage = container_of(clerq->crq_pages.next, struct cl_page, cp_flight); - opg = osc_cl_page_osc(apage); - apage = opg->ops_cl.cpl_page; /* now apage is a sub-page */ - lock = cl_lock_at_page(env, apage->cp_obj, apage, NULL, 1, 1); + opg = osc_cl_page_osc(apage, NULL); + subobj = opg->ops_cl.cpl_obj; + lock = cl_lock_at_pgoff(env, subobj, osc_index(opg), + NULL, 1, 1); if (!lock) { struct cl_object_header *head; struct cl_lock *scan; - head = cl_object_header(apage->cp_obj); + head = cl_object_header(subobj); list_for_each_entry(scan, &head->coh_locks, cll_linkage) CL_LOCK_DEBUG(D_ERROR, env, scan, "no cover page!\n"); diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c index 8dc62fa04300..3e0a8c3f4844 100644 --- a/drivers/staging/lustre/lustre/osc/osc_page.c +++ b/drivers/staging/lustre/lustre/osc/osc_page.c @@ -64,14 +64,9 @@ static int osc_page_protected(const struct lu_env *env, * Page operations. * */ -static void osc_page_fini(const struct lu_env *env, - struct cl_page_slice *slice) -{ -} - static void osc_page_transfer_get(struct osc_page *opg, const char *label) { - struct cl_page *page = cl_page_top(opg->ops_cl.cpl_page); + struct cl_page *page = opg->ops_cl.cpl_page; LASSERT(!opg->ops_transfer_pinned); cl_page_get(page); @@ -82,7 +77,7 @@ static void osc_page_transfer_get(struct osc_page *opg, const char *label) static void osc_page_transfer_put(const struct lu_env *env, struct osc_page *opg) { - struct cl_page *page = cl_page_top(opg->ops_cl.cpl_page); + struct cl_page *page = opg->ops_cl.cpl_page; if (opg->ops_transfer_pinned) { opg->ops_transfer_pinned = 0; @@ -139,11 +134,12 @@ static int osc_page_is_under_lock(const struct lu_env *env, const struct cl_page_slice *slice, struct cl_io *unused) { + struct osc_page *opg = cl2osc_page(slice); struct cl_lock *lock; int result = -ENODATA; - lock = cl_lock_at_page(env, slice->cpl_obj, slice->cpl_page, - NULL, 1, 0); + lock = cl_lock_at_pgoff(env, slice->cpl_obj, osc_index(opg), + NULL, 1, 0); if (lock) { cl_lock_put(env, lock); result = -EBUSY; @@ -173,8 +169,8 @@ static int osc_page_print(const struct lu_env *env, struct osc_object *obj = cl2osc(slice->cpl_obj); struct client_obd *cli = &osc_export(obj)->exp_obd->u.cli; - return (*printer)(env, cookie, LUSTRE_OSC_NAME "-page@%p: 1< %#x %d %u %s %s > 2< %llu %u %u %#x %#x | %p %p %p > 3< %s %p %d %lu %d > 4< %d %d %d %lu %s | %s %s %s %s > 5< %s %s %s %s | %d %s | %d %s %s>\n", - opg, + return (*printer)(env, cookie, LUSTRE_OSC_NAME "-page@%p %lu: 1< %#x %d %u %s %s > 2< %llu %u %u %#x %#x | %p %p %p > 3< %s %p %d %lu %d > 4< %d %d %d %lu %s | %s %s %s %s > 5< %s %s %s %s | %d %s | %d %s %s>\n", + opg, osc_index(opg), /* 1 */ oap->oap_magic, oap->oap_cmd, oap->oap_interrupted, @@ -222,7 +218,7 @@ static void osc_page_delete(const struct lu_env *env, osc_page_transfer_put(env, opg); rc = osc_teardown_async_page(env, obj, opg); if (rc) { - CL_PAGE_DEBUG(D_ERROR, env, cl_page_top(slice->cpl_page), + CL_PAGE_DEBUG(D_ERROR, env, slice->cpl_page, "Trying to teardown failed: %d\n", rc); LASSERT(0); } @@ -295,7 +291,6 @@ static int osc_page_flush(const struct lu_env *env, } static const struct cl_page_operations osc_page_ops = { - .cpo_fini = osc_page_fini, .cpo_print = osc_page_print, .cpo_delete = osc_page_delete, .cpo_is_under_lock = osc_page_is_under_lock, @@ -305,7 +300,7 @@ static const struct cl_page_operations osc_page_ops = { }; int osc_page_init(const struct lu_env *env, struct cl_object *obj, - struct cl_page *page, struct page *vmpage) + struct cl_page *page, pgoff_t index) { struct osc_object *osc = cl2osc(obj); struct osc_page *opg = cl_object_page_slice(obj, page); @@ -313,9 +308,10 @@ int osc_page_init(const struct lu_env *env, struct cl_object *obj, opg->ops_from = 0; opg->ops_to = PAGE_CACHE_SIZE; + opg->ops_cl.cpl_index = index; - result = osc_prep_async_page(osc, opg, vmpage, - cl_offset(obj, page->cp_index)); + result = osc_prep_async_page(osc, opg, page->cp_vmpage, + cl_offset(obj, index)); if (result == 0) { struct osc_io *oio = osc_env_io(env); @@ -337,8 +333,7 @@ int osc_page_init(const struct lu_env *env, struct cl_object *obj, result = osc_lru_reserve(env, osc, opg); if (result == 0) { spin_lock(&osc->oo_tree_lock); - result = radix_tree_insert(&osc->oo_tree, - page->cp_index, opg); + result = radix_tree_insert(&osc->oo_tree, index, opg); if (result == 0) ++osc->oo_npages; spin_unlock(&osc->oo_tree_lock); @@ -584,7 +579,7 @@ int osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, if (--maxscan < 0) break; - page = cl_page_top(opg->ops_cl.cpl_page); + page = opg->ops_cl.cpl_page; if (cl_page_in_use_noref(page)) { list_move_tail(&opg->ops_lru, &cli->cl_lru_list); continue; -- cgit v1.2.3 From fd7444fecaa0c4516d68fdbedf570b8bded60bc1 Mon Sep 17 00:00:00 2001 From: Jinshan Xiong Date: Wed, 30 Mar 2016 19:48:33 -0400 Subject: staging/lustre/clio: optimize read ahead code It used to check each page in the readahead window is covered by a lock underneath, now cpo_page_is_under_lock() provides @max_index to help decide the maximum ra window. @max_index can be modified by OSC to extend the maximum lock region, to align stripe boundary at LOV, and to make sure the readahead region at least covers read region at LLITE layer. After this is done, usually readahead code calls cpo_page_is_under_lock() for each stripe. Signed-off-by: Jinshan Xiong Reviewed-on: http://review.whamcloud.com/8523 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-3321 Reviewed-by: Andreas Dilger Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/cl_object.h | 6 +- drivers/staging/lustre/lustre/include/lclient.h | 2 - drivers/staging/lustre/lustre/llite/lcommon_cl.c | 28 ------ .../staging/lustre/lustre/llite/llite_internal.h | 7 +- drivers/staging/lustre/lustre/llite/lproc_llite.c | 1 + drivers/staging/lustre/lustre/llite/rw.c | 103 ++++++++++++++------- drivers/staging/lustre/lustre/llite/vvp_io.c | 23 +---- drivers/staging/lustre/lustre/llite/vvp_page.c | 26 ++++-- .../staging/lustre/lustre/lov/lov_cl_internal.h | 1 + drivers/staging/lustre/lustre/lov/lov_internal.h | 2 + drivers/staging/lustre/lustre/lov/lov_io.c | 2 +- drivers/staging/lustre/lustre/lov/lov_offset.c | 13 +++ drivers/staging/lustre/lustre/lov/lov_page.c | 60 ++++++++++-- drivers/staging/lustre/lustre/lov/lovsub_page.c | 4 +- drivers/staging/lustre/lustre/obdclass/cl_io.c | 2 +- drivers/staging/lustre/lustre/obdclass/cl_page.c | 39 ++++++-- .../staging/lustre/lustre/obdecho/echo_client.c | 2 +- drivers/staging/lustre/lustre/osc/osc_page.c | 10 +- 18 files changed, 208 insertions(+), 123 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h index 5b65854834f5..69b40f50df70 100644 --- a/drivers/staging/lustre/lustre/include/cl_object.h +++ b/drivers/staging/lustre/lustre/include/cl_object.h @@ -935,7 +935,7 @@ struct cl_page_operations { */ int (*cpo_is_under_lock)(const struct lu_env *env, const struct cl_page_slice *slice, - struct cl_io *io); + struct cl_io *io, pgoff_t *max); /** * Optional debugging helper. Prints given page slice. @@ -2674,7 +2674,7 @@ static inline void cl_device_fini(struct cl_device *d) } void cl_page_slice_add(struct cl_page *page, struct cl_page_slice *slice, - struct cl_object *obj, + struct cl_object *obj, pgoff_t index, const struct cl_page_operations *ops); void cl_lock_slice_add(struct cl_lock *lock, struct cl_lock_slice *slice, struct cl_object *obj, @@ -2826,7 +2826,7 @@ void cl_page_delete(const struct lu_env *env, struct cl_page *pg); int cl_page_is_vmlocked(const struct lu_env *env, const struct cl_page *pg); void cl_page_export(const struct lu_env *env, struct cl_page *pg, int uptodate); int cl_page_is_under_lock(const struct lu_env *env, struct cl_io *io, - struct cl_page *page); + struct cl_page *page, pgoff_t *max_index); loff_t cl_offset(const struct cl_object *obj, pgoff_t idx); pgoff_t cl_index(const struct cl_object *obj, loff_t offset); int cl_page_size(const struct cl_object *obj); diff --git a/drivers/staging/lustre/lustre/include/lclient.h b/drivers/staging/lustre/lustre/include/lclient.h index c91fb0151a52..a8c8788ebc07 100644 --- a/drivers/staging/lustre/lustre/include/lclient.h +++ b/drivers/staging/lustre/lustre/include/lclient.h @@ -299,8 +299,6 @@ int ccc_lock_init(const struct lu_env *env, struct cl_object *obj, const struct cl_lock_operations *lkops); int ccc_object_glimpse(const struct lu_env *env, const struct cl_object *obj, struct ost_lvb *lvb); -int ccc_page_is_under_lock(const struct lu_env *env, - const struct cl_page_slice *slice, struct cl_io *io); int ccc_fail(const struct lu_env *env, const struct cl_page_slice *slice); int ccc_transient_page_prep(const struct lu_env *env, const struct cl_page_slice *slice, diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c b/drivers/staging/lustre/lustre/llite/lcommon_cl.c index 55fa0da80b81..e34d8323944d 100644 --- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c +++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c @@ -452,34 +452,6 @@ static void ccc_object_size_unlock(struct cl_object *obj) * */ -int ccc_page_is_under_lock(const struct lu_env *env, - const struct cl_page_slice *slice, - struct cl_io *io) -{ - struct ccc_io *cio = ccc_env_io(env); - struct cl_lock_descr *desc = &ccc_env_info(env)->cti_descr; - struct cl_page *page = slice->cpl_page; - - int result; - - if (io->ci_type == CIT_READ || io->ci_type == CIT_WRITE || - io->ci_type == CIT_FAULT) { - if (cio->cui_fd->fd_flags & LL_FILE_GROUP_LOCKED) { - result = -EBUSY; - } else { - desc->cld_start = ccc_index(cl2ccc_page(slice)); - desc->cld_end = ccc_index(cl2ccc_page(slice)); - desc->cld_obj = page->cp_obj; - desc->cld_mode = CLM_READ; - result = cl_queue_match(&io->ci_lockset.cls_done, - desc) ? -EBUSY : 0; - } - } else { - result = 0; - } - return result; -} - int ccc_fail(const struct lu_env *env, const struct cl_page_slice *slice) { /* diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index bc831472b3ed..cd691734f242 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -328,6 +328,7 @@ enum ra_stat { RA_STAT_EOF, RA_STAT_MAX_IN_FLIGHT, RA_STAT_WRONG_GRAB_PAGE, + RA_STAT_FAILED_REACH_END, _NR_RA_STAT, }; @@ -702,8 +703,8 @@ int ll_writepages(struct address_space *, struct writeback_control *wbc); int ll_readpage(struct file *file, struct page *page); void ll_readahead_init(struct inode *inode, struct ll_readahead_state *ras); int ll_readahead(const struct lu_env *env, struct cl_io *io, - struct ll_readahead_state *ras, struct address_space *mapping, - struct cl_page_list *queue, int flags); + struct cl_page_list *queue, struct ll_readahead_state *ras, + bool hit); int vvp_io_write_commit(const struct lu_env *env, struct cl_io *io); struct ll_cl_context *ll_cl_init(struct file *file, struct page *vmpage); void ll_cl_fini(struct ll_cl_context *lcc); @@ -1074,7 +1075,7 @@ void ras_update(struct ll_sb_info *sbi, struct inode *inode, struct ll_readahead_state *ras, unsigned long index, unsigned hit); void ll_ra_count_put(struct ll_sb_info *sbi, unsigned long len); -void ll_ra_stats_inc(struct address_space *mapping, enum ra_stat which); +void ll_ra_stats_inc(struct inode *inode, enum ra_stat which); /* llite/llite_rmtacl.c */ #ifdef CONFIG_FS_POSIX_ACL diff --git a/drivers/staging/lustre/lustre/llite/lproc_llite.c b/drivers/staging/lustre/lustre/llite/lproc_llite.c index 9e8e61a730b7..091144fa97dd 100644 --- a/drivers/staging/lustre/lustre/llite/lproc_llite.c +++ b/drivers/staging/lustre/lustre/llite/lproc_llite.c @@ -960,6 +960,7 @@ static const char *ra_stat_string[] = { [RA_STAT_EOF] = "read-ahead to EOF", [RA_STAT_MAX_IN_FLIGHT] = "hit max r-a issue", [RA_STAT_WRONG_GRAB_PAGE] = "wrong page from grab_cache_page", + [RA_STAT_FAILED_REACH_END] = "failed to reach end" }; int ldebugfs_register_mountpoint(struct dentry *parent, diff --git a/drivers/staging/lustre/lustre/llite/rw.c b/drivers/staging/lustre/lustre/llite/rw.c index b1375f1719e7..ad15058c2ddb 100644 --- a/drivers/staging/lustre/lustre/llite/rw.c +++ b/drivers/staging/lustre/lustre/llite/rw.c @@ -166,7 +166,7 @@ static void ll_ra_stats_inc_sbi(struct ll_sb_info *sbi, enum ra_stat which); */ static unsigned long ll_ra_count_get(struct ll_sb_info *sbi, struct ra_io_arg *ria, - unsigned long pages) + unsigned long pages, unsigned long min) { struct ll_ra_info *ra = &sbi->ll_ra_info; long ret; @@ -206,6 +206,11 @@ static unsigned long ll_ra_count_get(struct ll_sb_info *sbi, } out: + if (ret < min) { + /* override ra limit for maximum performance */ + atomic_add(min - ret, &ra->ra_cur_pages); + ret = min; + } return ret; } @@ -222,9 +227,9 @@ static void ll_ra_stats_inc_sbi(struct ll_sb_info *sbi, enum ra_stat which) lprocfs_counter_incr(sbi->ll_ra_stats, which); } -void ll_ra_stats_inc(struct address_space *mapping, enum ra_stat which) +void ll_ra_stats_inc(struct inode *inode, enum ra_stat which) { - struct ll_sb_info *sbi = ll_i2sbi(mapping->host); + struct ll_sb_info *sbi = ll_i2sbi(inode); ll_ra_stats_inc_sbi(sbi, which); } @@ -290,7 +295,7 @@ void ll_ra_read_ex(struct file *f, struct ll_ra_read *rar) static int cl_read_ahead_page(const struct lu_env *env, struct cl_io *io, struct cl_page_list *queue, struct cl_page *page, - struct cl_object *clob) + struct cl_object *clob, pgoff_t *max_index) { struct page *vmpage = page->cp_vmpage; struct ccc_page *cp; @@ -301,8 +306,11 @@ static int cl_read_ahead_page(const struct lu_env *env, struct cl_io *io, lu_ref_add(&page->cp_reference, "ra", current); cp = cl2ccc_page(cl_object_page_slice(clob, page)); if (!cp->cpg_defer_uptodate && !PageUptodate(vmpage)) { - rc = cl_page_is_under_lock(env, io, page); - if (rc == -EBUSY) { + CDEBUG(D_READA, "page index %lu, max_index: %lu\n", + ccc_index(cp), *max_index); + if (*max_index == 0 || ccc_index(cp) > *max_index) + rc = cl_page_is_under_lock(env, io, page, max_index); + if (rc == 0) { cp->cpg_defer_uptodate = 1; cp->cpg_ra_used = 0; cl_page_list_add(queue, page); @@ -332,24 +340,25 @@ static int cl_read_ahead_page(const struct lu_env *env, struct cl_io *io, */ static int ll_read_ahead_page(const struct lu_env *env, struct cl_io *io, struct cl_page_list *queue, - pgoff_t index, struct address_space *mapping) + pgoff_t index, pgoff_t *max_index) { + struct cl_object *clob = io->ci_obj; + struct inode *inode = ccc_object_inode(clob); struct page *vmpage; - struct cl_object *clob = ll_i2info(mapping->host)->lli_clob; struct cl_page *page; enum ra_stat which = _NR_RA_STAT; /* keep gcc happy */ int rc = 0; const char *msg = NULL; - vmpage = grab_cache_page_nowait(mapping, index); + vmpage = grab_cache_page_nowait(inode->i_mapping, index); if (vmpage) { /* Check if vmpage was truncated or reclaimed */ - if (vmpage->mapping == mapping) { + if (vmpage->mapping == inode->i_mapping) { page = cl_page_find(env, clob, vmpage->index, vmpage, CPT_CACHEABLE); if (!IS_ERR(page)) { rc = cl_read_ahead_page(env, io, queue, - page, clob); + page, clob, max_index); if (rc == -ENOLCK) { which = RA_STAT_FAILED_MATCH; msg = "lock match failed"; @@ -370,7 +379,7 @@ static int ll_read_ahead_page(const struct lu_env *env, struct cl_io *io, msg = "g_c_p_n failed"; } if (msg) { - ll_ra_stats_inc(mapping, which); + ll_ra_stats_inc(inode, which); CDEBUG(D_READA, "%s\n", msg); } return rc; @@ -482,11 +491,12 @@ static int ll_read_ahead_pages(const struct lu_env *env, struct cl_io *io, struct cl_page_list *queue, struct ra_io_arg *ria, unsigned long *reserved_pages, - struct address_space *mapping, unsigned long *ra_end) { - int rc, count = 0, stride_ria; - unsigned long page_idx; + int rc, count = 0; + bool stride_ria; + pgoff_t page_idx; + pgoff_t max_index = 0; LASSERT(ria); RIA_DEBUG(ria); @@ -497,7 +507,7 @@ static int ll_read_ahead_pages(const struct lu_env *env, if (ras_inside_ra_window(page_idx, ria)) { /* If the page is inside the read-ahead window*/ rc = ll_read_ahead_page(env, io, queue, - page_idx, mapping); + page_idx, &max_index); if (rc == 1) { (*reserved_pages)--; count++; @@ -532,25 +542,23 @@ static int ll_read_ahead_pages(const struct lu_env *env, } int ll_readahead(const struct lu_env *env, struct cl_io *io, - struct ll_readahead_state *ras, struct address_space *mapping, - struct cl_page_list *queue, int flags) + struct cl_page_list *queue, struct ll_readahead_state *ras, + bool hit) { struct vvp_io *vio = vvp_env_io(env); struct vvp_thread_info *vti = vvp_env_info(env); struct cl_attr *attr = ccc_env_thread_attr(env); unsigned long start = 0, end = 0, reserved; - unsigned long ra_end, len; + unsigned long ra_end, len, mlen = 0; struct inode *inode; struct ll_ra_read *bead; struct ra_io_arg *ria = &vti->vti_ria; - struct ll_inode_info *lli; struct cl_object *clob; int ret = 0; __u64 kms; - inode = mapping->host; - lli = ll_i2info(inode); - clob = lli->lli_clob; + clob = io->ci_obj; + inode = ccc_object_inode(clob); memset(ria, 0, sizeof(*ria)); @@ -562,7 +570,7 @@ int ll_readahead(const struct lu_env *env, struct cl_io *io, return ret; kms = attr->cat_kms; if (kms == 0) { - ll_ra_stats_inc(mapping, RA_STAT_ZERO_LEN); + ll_ra_stats_inc(inode, RA_STAT_ZERO_LEN); return 0; } @@ -621,29 +629,48 @@ int ll_readahead(const struct lu_env *env, struct cl_io *io, spin_unlock(&ras->ras_lock); if (end == 0) { - ll_ra_stats_inc(mapping, RA_STAT_ZERO_WINDOW); + ll_ra_stats_inc(inode, RA_STAT_ZERO_WINDOW); return 0; } len = ria_page_count(ria); - if (len == 0) + if (len == 0) { + ll_ra_stats_inc(inode, RA_STAT_ZERO_WINDOW); return 0; + } + + CDEBUG(D_READA, DFID ": ria: %lu/%lu, bead: %lu/%lu, hit: %d\n", + PFID(lu_object_fid(&clob->co_lu)), + ria->ria_start, ria->ria_end, + !bead ? 0 : bead->lrr_start, + !bead ? 0 : bead->lrr_count, + hit); + + /* at least to extend the readahead window to cover current read */ + if (!hit && bead && + bead->lrr_start + bead->lrr_count > ria->ria_start) { + /* to the end of current read window. */ + mlen = bead->lrr_start + bead->lrr_count - ria->ria_start; + /* trim to RPC boundary */ + start = ria->ria_start & (PTLRPC_MAX_BRW_PAGES - 1); + mlen = min(mlen, PTLRPC_MAX_BRW_PAGES - start); + } - reserved = ll_ra_count_get(ll_i2sbi(inode), ria, len); + reserved = ll_ra_count_get(ll_i2sbi(inode), ria, len, mlen); if (reserved < len) - ll_ra_stats_inc(mapping, RA_STAT_MAX_IN_FLIGHT); + ll_ra_stats_inc(inode, RA_STAT_MAX_IN_FLIGHT); - CDEBUG(D_READA, "reserved page %lu ra_cur %d ra_max %lu\n", reserved, + CDEBUG(D_READA, "reserved pages %lu/%lu/%lu, ra_cur %d, ra_max %lu\n", + reserved, len, mlen, atomic_read(&ll_i2sbi(inode)->ll_ra_info.ra_cur_pages), ll_i2sbi(inode)->ll_ra_info.ra_max_pages); - ret = ll_read_ahead_pages(env, io, queue, - ria, &reserved, mapping, &ra_end); + ret = ll_read_ahead_pages(env, io, queue, ria, &reserved, &ra_end); if (reserved != 0) ll_ra_count_put(ll_i2sbi(inode), reserved); if (ra_end == end + 1 && ra_end == (kms >> PAGE_CACHE_SHIFT)) - ll_ra_stats_inc(mapping, RA_STAT_EOF); + ll_ra_stats_inc(inode, RA_STAT_EOF); /* if we didn't get to the end of the region we reserved from * the ras we need to go back and update the ras so that the @@ -655,6 +682,7 @@ int ll_readahead(const struct lu_env *env, struct cl_io *io, ra_end, end, ria->ria_end); if (ra_end != end + 1) { + ll_ra_stats_inc(inode, RA_STAT_FAILED_REACH_END); spin_lock(&ras->ras_lock); if (ra_end < ras->ras_next_readahead && index_in_window(ra_end, ras->ras_window_start, 0, @@ -925,15 +953,18 @@ void ras_update(struct ll_sb_info *sbi, struct inode *inode, ras->ras_last_readpage = index; ras_set_start(inode, ras, index); - if (stride_io_mode(ras)) + if (stride_io_mode(ras)) { /* Since stride readahead is sensitive to the offset * of read-ahead, so we use original offset here, * instead of ras_window_start, which is RPC aligned */ ras->ras_next_readahead = max(index, ras->ras_next_readahead); - else - ras->ras_next_readahead = max(ras->ras_window_start, - ras->ras_next_readahead); + } else { + if (ras->ras_next_readahead < ras->ras_window_start) + ras->ras_next_readahead = ras->ras_window_start; + if (!hit) + ras->ras_next_readahead = index + 1; + } RAS_CDEBUG(ras); /* Trigger RA in the mmap case where ras_consecutive_requests diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c index ac9d615b78d9..18127d3dc493 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_io.c +++ b/drivers/staging/lustre/lustre/llite/vvp_io.c @@ -1052,35 +1052,19 @@ static int vvp_io_read_page(const struct lu_env *env, const struct cl_page_slice *slice) { struct cl_io *io = ios->cis_io; - struct cl_object *obj = slice->cpl_obj; struct ccc_page *cp = cl2ccc_page(slice); struct cl_page *page = slice->cpl_page; - struct inode *inode = ccc_object_inode(obj); + struct inode *inode = ccc_object_inode(slice->cpl_obj); struct ll_sb_info *sbi = ll_i2sbi(inode); struct ll_file_data *fd = cl2ccc_io(env, ios)->cui_fd; struct ll_readahead_state *ras = &fd->fd_ras; - struct page *vmpage = cp->cpg_page; struct cl_2queue *queue = &io->ci_queue; - int rc; - - CLOBINVRNT(env, obj, ccc_object_invariant(obj)); - LASSERT(slice->cpl_obj == obj); if (sbi->ll_ra_info.ra_max_pages_per_file && sbi->ll_ra_info.ra_max_pages) ras_update(sbi, inode, ras, ccc_index(cp), cp->cpg_defer_uptodate); - /* Sanity check whether the page is protected by a lock. */ - rc = cl_page_is_under_lock(env, io, page); - if (rc != -EBUSY) { - CL_PAGE_HEADER(D_WARNING, env, page, "%s: %d\n", - rc == -ENODATA ? "without a lock" : - "match failed", rc); - if (rc != -ENODATA) - return rc; - } - if (cp->cpg_defer_uptodate) { cp->cpg_ra_used = 1; cl_page_export(env, page, 1); @@ -1089,11 +1073,12 @@ static int vvp_io_read_page(const struct lu_env *env, * Add page into the queue even when it is marked uptodate above. * this will unlock it automatically as part of cl_page_list_disown(). */ + cl_page_list_add(&queue->c2_qin, page); if (sbi->ll_ra_info.ra_max_pages_per_file && sbi->ll_ra_info.ra_max_pages) - ll_readahead(env, io, ras, - vmpage->mapping, &queue->c2_qin, fd->fd_flags); + ll_readahead(env, io, &queue->c2_qin, ras, + cp->cpg_defer_uptodate); return 0; } diff --git a/drivers/staging/lustre/lustre/llite/vvp_page.c b/drivers/staging/lustre/lustre/llite/vvp_page.c index d9f13c31091a..3c6b72398d62 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_page.c +++ b/drivers/staging/lustre/lustre/llite/vvp_page.c @@ -142,7 +142,7 @@ static void vvp_page_discard(const struct lu_env *env, LASSERT(PageLocked(vmpage)); if (cpg->cpg_defer_uptodate && !cpg->cpg_ra_used) - ll_ra_stats_inc(vmpage->mapping, RA_STAT_DISCARDED); + ll_ra_stats_inc(vmpage->mapping->host, RA_STAT_DISCARDED); ll_invalidate_page(vmpage); } @@ -357,6 +357,20 @@ static int vvp_page_make_ready(const struct lu_env *env, return result; } +static int vvp_page_is_under_lock(const struct lu_env *env, + const struct cl_page_slice *slice, + struct cl_io *io, pgoff_t *max_index) +{ + if (io->ci_type == CIT_READ || io->ci_type == CIT_WRITE || + io->ci_type == CIT_FAULT) { + struct ccc_io *cio = ccc_env_io(env); + + if (unlikely(cio->cui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) + *max_index = CL_PAGE_EOF; + } + return 0; +} + static int vvp_page_print(const struct lu_env *env, const struct cl_page_slice *slice, void *cookie, lu_printer_t printer) @@ -389,7 +403,7 @@ static const struct cl_page_operations vvp_page_ops = { .cpo_is_vmlocked = vvp_page_is_vmlocked, .cpo_fini = vvp_page_fini, .cpo_print = vvp_page_print, - .cpo_is_under_lock = ccc_page_is_under_lock, + .cpo_is_under_lock = vvp_page_is_under_lock, .io = { [CRT_READ] = { .cpo_prep = vvp_page_prep_read, @@ -495,7 +509,7 @@ static const struct cl_page_operations vvp_transient_page_ops = { .cpo_fini = vvp_transient_page_fini, .cpo_is_vmlocked = vvp_transient_page_is_vmlocked, .cpo_print = vvp_page_print, - .cpo_is_under_lock = ccc_page_is_under_lock, + .cpo_is_under_lock = vvp_page_is_under_lock, .io = { [CRT_READ] = { .cpo_prep = ccc_transient_page_prep, @@ -516,7 +530,6 @@ int vvp_page_init(const struct lu_env *env, struct cl_object *obj, CLOBINVRNT(env, obj, ccc_object_invariant(obj)); - cpg->cpg_cl.cpl_index = index; cpg->cpg_page = vmpage; page_cache_get(vmpage); @@ -526,12 +539,13 @@ int vvp_page_init(const struct lu_env *env, struct cl_object *obj, atomic_inc(&page->cp_ref); SetPagePrivate(vmpage); vmpage->private = (unsigned long)page; - cl_page_slice_add(page, &cpg->cpg_cl, obj, &vvp_page_ops); + cl_page_slice_add(page, &cpg->cpg_cl, obj, index, + &vvp_page_ops); } else { struct ccc_object *clobj = cl2ccc(obj); LASSERT(!inode_trylock(clobj->cob_inode)); - cl_page_slice_add(page, &cpg->cpg_cl, obj, + cl_page_slice_add(page, &cpg->cpg_cl, obj, index, &vvp_transient_page_ops); clobj->cob_transient_pages++; } diff --git a/drivers/staging/lustre/lustre/lov/lov_cl_internal.h b/drivers/staging/lustre/lustre/lov/lov_cl_internal.h index b8e2315d5216..9b3d13bf2a46 100644 --- a/drivers/staging/lustre/lustre/lov/lov_cl_internal.h +++ b/drivers/staging/lustre/lustre/lov/lov_cl_internal.h @@ -632,6 +632,7 @@ struct lov_lock_link *lov_lock_link_find(const struct lu_env *env, struct lovsub_lock *sub); struct lov_io_sub *lov_page_subio(const struct lu_env *env, struct lov_io *lio, const struct cl_page_slice *slice); +int lov_page_stripe(const struct cl_page *page); #define lov_foreach_target(lov, var) \ for (var = 0; var < lov_targets_nr(lov); ++var) diff --git a/drivers/staging/lustre/lustre/lov/lov_internal.h b/drivers/staging/lustre/lustre/lov/lov_internal.h index 590f9326af37..9985855c4e06 100644 --- a/drivers/staging/lustre/lustre/lov/lov_internal.h +++ b/drivers/staging/lustre/lustre/lov/lov_internal.h @@ -146,6 +146,8 @@ int lov_stripe_intersects(struct lov_stripe_md *lsm, int stripeno, u64 start, u64 end, u64 *obd_start, u64 *obd_end); int lov_stripe_number(struct lov_stripe_md *lsm, u64 lov_off); +pgoff_t lov_stripe_pgoff(struct lov_stripe_md *lsm, pgoff_t stripe_index, + int stripe); /* lov_qos.c */ #define LOV_USES_ASSIGNED_STRIPE 0 diff --git a/drivers/staging/lustre/lustre/lov/lov_io.c b/drivers/staging/lustre/lustre/lov/lov_io.c index e5b2cfc5b662..ba79955f54bb 100644 --- a/drivers/staging/lustre/lustre/lov/lov_io.c +++ b/drivers/staging/lustre/lustre/lov/lov_io.c @@ -245,7 +245,7 @@ void lov_sub_put(struct lov_io_sub *sub) * */ -static int lov_page_stripe(const struct cl_page *page) +int lov_page_stripe(const struct cl_page *page) { struct lovsub_object *subobj; const struct cl_page_slice *slice; diff --git a/drivers/staging/lustre/lustre/lov/lov_offset.c b/drivers/staging/lustre/lustre/lov/lov_offset.c index ae83eb0f6f36..cb7b51617498 100644 --- a/drivers/staging/lustre/lustre/lov/lov_offset.c +++ b/drivers/staging/lustre/lustre/lov/lov_offset.c @@ -66,6 +66,19 @@ u64 lov_stripe_size(struct lov_stripe_md *lsm, u64 ost_size, int stripeno) return lov_size; } +/** + * Compute file level page index by stripe level page offset + */ +pgoff_t lov_stripe_pgoff(struct lov_stripe_md *lsm, pgoff_t stripe_index, + int stripe) +{ + loff_t offset; + + offset = lov_stripe_size(lsm, stripe_index << PAGE_CACHE_SHIFT, + stripe); + return offset >> PAGE_CACHE_SHIFT; +} + /* we have an offset in file backed by an lov and want to find out where * that offset lands in our given stripe of the file. for the easy * case where the offset is within the stripe, we just have to scale the diff --git a/drivers/staging/lustre/lustre/lov/lov_page.c b/drivers/staging/lustre/lustre/lov/lov_page.c index 0c508bd0f8ad..9634c13a574d 100644 --- a/drivers/staging/lustre/lustre/lov/lov_page.c +++ b/drivers/staging/lustre/lustre/lov/lov_page.c @@ -52,17 +52,57 @@ * Lov page operations. * */ -static int lov_page_print(const struct lu_env *env, - const struct cl_page_slice *slice, - void *cookie, lu_printer_t printer) + +/** + * Adjust the stripe index by layout of raid0. @max_index is the maximum + * page index covered by an underlying DLM lock. + * This function converts max_index from stripe level to file level, and make + * sure it's not beyond one stripe. + */ +static int lov_raid0_page_is_under_lock(const struct lu_env *env, + const struct cl_page_slice *slice, + struct cl_io *unused, + pgoff_t *max_index) +{ + struct lov_object *loo = cl2lov(slice->cpl_obj); + struct lov_layout_raid0 *r0 = lov_r0(loo); + pgoff_t index = *max_index; + unsigned int pps; /* pages per stripe */ + + CDEBUG(D_READA, "*max_index = %lu, nr = %d\n", index, r0->lo_nr); + if (index == 0) /* the page is not covered by any lock */ + return 0; + + if (r0->lo_nr == 1) /* single stripe file */ + return 0; + + /* max_index is stripe level, convert it into file level */ + if (index != CL_PAGE_EOF) { + int stripeno = lov_page_stripe(slice->cpl_page); + *max_index = lov_stripe_pgoff(loo->lo_lsm, index, stripeno); + } + + /* calculate the end of current stripe */ + pps = loo->lo_lsm->lsm_stripe_size >> PAGE_CACHE_SHIFT; + index = ((slice->cpl_index + pps) & ~(pps - 1)) - 1; + + /* never exceed the end of the stripe */ + *max_index = min_t(pgoff_t, *max_index, index); + return 0; +} + +static int lov_raid0_page_print(const struct lu_env *env, + const struct cl_page_slice *slice, + void *cookie, lu_printer_t printer) { struct lov_page *lp = cl2lov_page(slice); - return (*printer)(env, cookie, LUSTRE_LOV_NAME"-page@%p\n", lp); + return (*printer)(env, cookie, LUSTRE_LOV_NAME "-page@%p, raid0\n", lp); } -static const struct cl_page_operations lov_page_ops = { - .cpo_print = lov_page_print +static const struct cl_page_operations lov_raid0_page_ops = { + .cpo_is_under_lock = lov_raid0_page_is_under_lock, + .cpo_print = lov_raid0_page_print }; int lov_page_init_raid0(const struct lu_env *env, struct cl_object *obj, @@ -86,7 +126,7 @@ int lov_page_init_raid0(const struct lu_env *env, struct cl_object *obj, rc = lov_stripe_offset(loo->lo_lsm, offset, stripe, &suboff); LASSERT(rc == 0); - cl_page_slice_add(page, &lpg->lps_cl, obj, &lov_page_ops); + cl_page_slice_add(page, &lpg->lps_cl, obj, index, &lov_raid0_page_ops); sub = lov_sub_get(env, lio, stripe); if (IS_ERR(sub)) @@ -107,7 +147,7 @@ int lov_page_init_raid0(const struct lu_env *env, struct cl_object *obj, return rc; } -static int lov_page_empty_print(const struct lu_env *env, +static int lov_empty_page_print(const struct lu_env *env, const struct cl_page_slice *slice, void *cookie, lu_printer_t printer) { @@ -118,7 +158,7 @@ static int lov_page_empty_print(const struct lu_env *env, } static const struct cl_page_operations lov_empty_page_ops = { - .cpo_print = lov_page_empty_print + .cpo_print = lov_empty_page_print }; int lov_page_init_empty(const struct lu_env *env, struct cl_object *obj, @@ -127,7 +167,7 @@ int lov_page_init_empty(const struct lu_env *env, struct cl_object *obj, struct lov_page *lpg = cl_object_page_slice(obj, page); void *addr; - cl_page_slice_add(page, &lpg->lps_cl, obj, &lov_empty_page_ops); + cl_page_slice_add(page, &lpg->lps_cl, obj, index, &lov_empty_page_ops); addr = kmap(page->cp_vmpage); memset(addr, 0, cl_page_size(obj)); kunmap(page->cp_vmpage); diff --git a/drivers/staging/lustre/lustre/lov/lovsub_page.c b/drivers/staging/lustre/lustre/lov/lovsub_page.c index fb4c0ccee30c..9badedcce2bf 100644 --- a/drivers/staging/lustre/lustre/lov/lovsub_page.c +++ b/drivers/staging/lustre/lustre/lov/lovsub_page.c @@ -60,11 +60,11 @@ static const struct cl_page_operations lovsub_page_ops = { }; int lovsub_page_init(const struct lu_env *env, struct cl_object *obj, - struct cl_page *page, pgoff_t ind) + struct cl_page *page, pgoff_t index) { struct lovsub_page *lsb = cl_object_page_slice(obj, page); - cl_page_slice_add(page, &lsb->lsb_cl, obj, &lovsub_page_ops); + cl_page_slice_add(page, &lsb->lsb_cl, obj, index, &lovsub_page_ops); return 0; } diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c index 86591ceac9c1..65d6cee5232b 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_io.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c @@ -733,7 +733,7 @@ int cl_io_read_page(const struct lu_env *env, struct cl_io *io, break; } } - if (result == 0) + if (result == 0 && queue->c2_qin.pl_nr > 0) result = cl_io_submit_rw(env, io, CRT_READ, queue); /* * Unlock unsent pages in case of error. diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c index cb156739b254..506a9f94e5ba 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_page.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c @@ -401,6 +401,30 @@ EXPORT_SYMBOL(cl_page_at); __result; \ }) +#define CL_PAGE_INVOKE_REVERSE(_env, _page, _op, _proto, ...) \ +({ \ + const struct lu_env *__env = (_env); \ + struct cl_page *__page = (_page); \ + const struct cl_page_slice *__scan; \ + int __result; \ + ptrdiff_t __op = (_op); \ + int (*__method)_proto; \ + \ + __result = 0; \ + list_for_each_entry_reverse(__scan, &__page->cp_layers, \ + cpl_linkage) { \ + __method = *(void **)((char *)__scan->cpl_ops + __op); \ + if (__method) { \ + __result = (*__method)(__env, __scan, ## __VA_ARGS__); \ + if (__result != 0) \ + break; \ + } \ + } \ + if (__result > 0) \ + __result = 0; \ + __result; \ +}) + #define CL_PAGE_INVOID(_env, _page, _op, _proto, ...) \ do { \ const struct lu_env *__env = (_env); \ @@ -928,17 +952,17 @@ EXPORT_SYMBOL(cl_page_flush); * \see cl_page_operations::cpo_is_under_lock() */ int cl_page_is_under_lock(const struct lu_env *env, struct cl_io *io, - struct cl_page *page) + struct cl_page *page, pgoff_t *max_index) { int rc; PINVRNT(env, page, cl_page_invariant(page)); - rc = CL_PAGE_INVOKE(env, page, CL_PAGE_OP(cpo_is_under_lock), - (const struct lu_env *, - const struct cl_page_slice *, struct cl_io *), - io); - PASSERT(env, page, rc != 0); + rc = CL_PAGE_INVOKE_REVERSE(env, page, CL_PAGE_OP(cpo_is_under_lock), + (const struct lu_env *, + const struct cl_page_slice *, + struct cl_io *, pgoff_t *), + io, max_index); return rc; } EXPORT_SYMBOL(cl_page_is_under_lock); @@ -1041,11 +1065,12 @@ EXPORT_SYMBOL(cl_page_size); * \see cl_lock_slice_add(), cl_req_slice_add(), cl_io_slice_add() */ void cl_page_slice_add(struct cl_page *page, struct cl_page_slice *slice, - struct cl_object *obj, + struct cl_object *obj, pgoff_t index, const struct cl_page_operations *ops) { list_add_tail(&slice->cpl_linkage, &page->cp_layers); slice->cpl_obj = obj; + slice->cpl_index = index; slice->cpl_ops = ops; slice->cpl_page = page; } diff --git a/drivers/staging/lustre/lustre/obdecho/echo_client.c b/drivers/staging/lustre/lustre/obdecho/echo_client.c index db56081330e9..0d84d04c12de 100644 --- a/drivers/staging/lustre/lustre/obdecho/echo_client.c +++ b/drivers/staging/lustre/lustre/obdecho/echo_client.c @@ -365,7 +365,7 @@ static int echo_page_init(const struct lu_env *env, struct cl_object *obj, page_cache_get(page->cp_vmpage); mutex_init(&ep->ep_lock); - cl_page_slice_add(page, &ep->ep_cl, obj, &echo_page_ops); + cl_page_slice_add(page, &ep->ep_cl, obj, index, &echo_page_ops); atomic_inc(&eco->eo_npages); return 0; } diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c index 3e0a8c3f4844..e02dd33b637c 100644 --- a/drivers/staging/lustre/lustre/osc/osc_page.c +++ b/drivers/staging/lustre/lustre/osc/osc_page.c @@ -132,17 +132,19 @@ void osc_index2policy(ldlm_policy_data_t *policy, const struct cl_object *obj, static int osc_page_is_under_lock(const struct lu_env *env, const struct cl_page_slice *slice, - struct cl_io *unused) + struct cl_io *unused, pgoff_t *max_index) { struct osc_page *opg = cl2osc_page(slice); struct cl_lock *lock; int result = -ENODATA; + *max_index = 0; lock = cl_lock_at_pgoff(env, slice->cpl_obj, osc_index(opg), NULL, 1, 0); if (lock) { + *max_index = lock->cll_descr.cld_end; cl_lock_put(env, lock); - result = -EBUSY; + result = 0; } return result; } @@ -308,7 +310,6 @@ int osc_page_init(const struct lu_env *env, struct cl_object *obj, opg->ops_from = 0; opg->ops_to = PAGE_CACHE_SIZE; - opg->ops_cl.cpl_index = index; result = osc_prep_async_page(osc, opg, page->cp_vmpage, cl_offset(obj, index)); @@ -316,7 +317,8 @@ int osc_page_init(const struct lu_env *env, struct cl_object *obj, struct osc_io *oio = osc_env_io(env); opg->ops_srvlock = osc_io_srvlock(oio); - cl_page_slice_add(page, &opg->ops_cl, obj, &osc_page_ops); + cl_page_slice_add(page, &opg->ops_cl, obj, index, + &osc_page_ops); } /* * Cannot assert osc_page_protected() here as read-ahead -- cgit v1.2.3 From d2995737bb6da9fcb9f84bf820322e351df2813b Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Wed, 30 Mar 2016 19:48:34 -0400 Subject: staging/lustre/llite: remove lli_lvb In struct ll_inode_info remove the struct ost_lvb lli_lvb member and replace it with obd_time lli_{a,m,c}time. Rename ll_merge_lvb() to ll_merge_attr(). Remove cl_merge_lvb() and replace calls to it with calls to ll_merge_attr(). Signed-off-by: John L. Hammond Reviewed-on: http://review.whamcloud.com/12849 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-2675 Reviewed-by: Bobi Jam Reviewed-by: Lai Siyao Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/file.c | 65 ++++++++++++---------- drivers/staging/lustre/lustre/llite/glimpse.c | 6 +- drivers/staging/lustre/lustre/llite/lcommon_cl.c | 2 +- .../staging/lustre/lustre/llite/llite_internal.h | 11 ++-- drivers/staging/lustre/lustre/llite/llite_lib.c | 6 +- drivers/staging/lustre/lustre/llite/vvp_io.c | 2 +- 6 files changed, 48 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index 127fff6ebe44..8fc9da00278e 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -994,50 +994,57 @@ int ll_inode_getattr(struct inode *inode, struct obdo *obdo, return rc; } -int ll_merge_lvb(const struct lu_env *env, struct inode *inode) +int ll_merge_attr(const struct lu_env *env, struct inode *inode) { struct ll_inode_info *lli = ll_i2info(inode); struct cl_object *obj = lli->lli_clob; struct cl_attr *attr = ccc_env_thread_attr(env); - struct ost_lvb lvb; + s64 atime; + s64 mtime; + s64 ctime; int rc = 0; ll_inode_size_lock(inode); + /* merge timestamps the most recently obtained from mds with * timestamps obtained from osts */ - LTIME_S(inode->i_atime) = lli->lli_lvb.lvb_atime; - LTIME_S(inode->i_mtime) = lli->lli_lvb.lvb_mtime; - LTIME_S(inode->i_ctime) = lli->lli_lvb.lvb_ctime; + LTIME_S(inode->i_atime) = lli->lli_atime; + LTIME_S(inode->i_mtime) = lli->lli_mtime; + LTIME_S(inode->i_ctime) = lli->lli_ctime; - lvb.lvb_size = i_size_read(inode); - lvb.lvb_blocks = inode->i_blocks; - lvb.lvb_mtime = LTIME_S(inode->i_mtime); - lvb.lvb_atime = LTIME_S(inode->i_atime); - lvb.lvb_ctime = LTIME_S(inode->i_ctime); + mtime = LTIME_S(inode->i_mtime); + atime = LTIME_S(inode->i_atime); + ctime = LTIME_S(inode->i_ctime); cl_object_attr_lock(obj); rc = cl_object_attr_get(env, obj, attr); cl_object_attr_unlock(obj); - if (rc == 0) { - if (lvb.lvb_atime < attr->cat_atime) - lvb.lvb_atime = attr->cat_atime; - if (lvb.lvb_ctime < attr->cat_ctime) - lvb.lvb_ctime = attr->cat_ctime; - if (lvb.lvb_mtime < attr->cat_mtime) - lvb.lvb_mtime = attr->cat_mtime; + if (rc != 0) + goto out_size_unlock; - CDEBUG(D_VFSTRACE, DFID " updating i_size %llu\n", - PFID(&lli->lli_fid), attr->cat_size); - cl_isize_write_nolock(inode, attr->cat_size); + if (atime < attr->cat_atime) + atime = attr->cat_atime; - inode->i_blocks = attr->cat_blocks; + if (ctime < attr->cat_ctime) + ctime = attr->cat_ctime; - LTIME_S(inode->i_mtime) = lvb.lvb_mtime; - LTIME_S(inode->i_atime) = lvb.lvb_atime; - LTIME_S(inode->i_ctime) = lvb.lvb_ctime; - } + if (mtime < attr->cat_mtime) + mtime = attr->cat_mtime; + + CDEBUG(D_VFSTRACE, DFID " updating i_size %llu\n", + PFID(&lli->lli_fid), attr->cat_size); + + cl_isize_write_nolock(inode, attr->cat_size); + + inode->i_blocks = attr->cat_blocks; + + LTIME_S(inode->i_mtime) = mtime; + LTIME_S(inode->i_atime) = atime; + LTIME_S(inode->i_ctime) = ctime; + +out_size_unlock: ll_inode_size_unlock(inode); return rc; @@ -1936,7 +1943,7 @@ int ll_hsm_release(struct inode *inode) goto out; } - ll_merge_lvb(env, inode); + ll_merge_attr(env, inode); cl_env_nested_put(&nest, env); /* Release the file. @@ -3001,9 +3008,9 @@ static int ll_inode_revalidate(struct dentry *dentry, __u64 ibits) /* if object isn't regular file, don't validate size */ if (!S_ISREG(inode->i_mode)) { - LTIME_S(inode->i_atime) = ll_i2info(inode)->lli_lvb.lvb_atime; - LTIME_S(inode->i_mtime) = ll_i2info(inode)->lli_lvb.lvb_mtime; - LTIME_S(inode->i_ctime) = ll_i2info(inode)->lli_lvb.lvb_ctime; + LTIME_S(inode->i_atime) = ll_i2info(inode)->lli_atime; + LTIME_S(inode->i_mtime) = ll_i2info(inode)->lli_mtime; + LTIME_S(inode->i_ctime) = ll_i2info(inode)->lli_ctime; } else { /* In case of restore, the MDT has the right size and has * already send it back without granting the layout lock, diff --git a/drivers/staging/lustre/lustre/llite/glimpse.c b/drivers/staging/lustre/lustre/llite/glimpse.c index f235f3557e2a..88bc7c9918e5 100644 --- a/drivers/staging/lustre/lustre/llite/glimpse.c +++ b/drivers/staging/lustre/lustre/llite/glimpse.c @@ -139,7 +139,7 @@ int cl_glimpse_lock(const struct lu_env *env, struct cl_io *io, LASSERT(agl == 0); result = cl_wait(env, lock); if (result == 0) { - cl_merge_lvb(env, inode); + ll_merge_attr(env, inode); if (cl_isize_read(inode) > 0 && inode->i_blocks == 0) { /* @@ -155,7 +155,7 @@ int cl_glimpse_lock(const struct lu_env *env, struct cl_io *io, cl_lock_release(env, lock, "glimpse", current); } else { CDEBUG(D_DLMTRACE, "No objects for inode\n"); - cl_merge_lvb(env, inode); + ll_merge_attr(env, inode); } } @@ -259,7 +259,7 @@ int cl_local_size(struct inode *inode) descr->cld_obj = clob; lock = cl_lock_peek(env, io, descr, "localsize", current); if (lock) { - cl_merge_lvb(env, inode); + ll_merge_attr(env, inode); cl_unuse(env, lock); cl_lock_release(env, lock, "localsize", current); result = 0; diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c b/drivers/staging/lustre/lustre/llite/lcommon_cl.c index e34d8323944d..4871d0feeb1c 100644 --- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c +++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c @@ -591,7 +591,7 @@ void ccc_lock_state(const struct lu_env *env, */ if (lock->cll_descr.cld_start == 0 && lock->cll_descr.cld_end == CL_PAGE_EOF) - cl_merge_lvb(env, inode); + ll_merge_attr(env, inode); } } diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index cd691734f242..c1d747a1e962 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -161,7 +161,9 @@ struct ll_inode_info { struct inode lli_vfs_inode; /* the most recent timestamps obtained from mds */ - struct ost_lvb lli_lvb; + s64 lli_atime; + s64 lli_mtime; + s64 lli_ctime; spinlock_t lli_agl_lock; /* Try to make the d::member and f::member are aligned. Before using @@ -752,7 +754,7 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump, int ll_dir_getstripe(struct inode *inode, struct lov_mds_md **lmmp, int *lmm_size, struct ptlrpc_request **request); int ll_fsync(struct file *file, loff_t start, loff_t end, int data); -int ll_merge_lvb(const struct lu_env *env, struct inode *inode); +int ll_merge_attr(const struct lu_env *env, struct inode *inode); int ll_fid2path(struct inode *inode, void __user *arg); int ll_data_version(struct inode *inode, __u64 *data_version, int extent_lock); int ll_hsm_release(struct inode *inode); @@ -1319,11 +1321,6 @@ static inline void cl_isize_write(struct inode *inode, loff_t kms) #define cl_isize_read(inode) i_size_read(inode) -static inline int cl_merge_lvb(const struct lu_env *env, struct inode *inode) -{ - return ll_merge_lvb(env, inode); -} - #define cl_inode_atime(inode) LTIME_S((inode)->i_atime) #define cl_inode_ctime(inode) LTIME_S((inode)->i_ctime) #define cl_inode_mtime(inode) LTIME_S((inode)->i_mtime) diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index a4401f297d1c..0b4e0dbfc130 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -1551,7 +1551,7 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md) if (body->valid & OBD_MD_FLATIME) { if (body->atime > LTIME_S(inode->i_atime)) LTIME_S(inode->i_atime) = body->atime; - lli->lli_lvb.lvb_atime = body->atime; + lli->lli_atime = body->atime; } if (body->valid & OBD_MD_FLMTIME) { if (body->mtime > LTIME_S(inode->i_mtime)) { @@ -1560,12 +1560,12 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md) body->mtime); LTIME_S(inode->i_mtime) = body->mtime; } - lli->lli_lvb.lvb_mtime = body->mtime; + lli->lli_mtime = body->mtime; } if (body->valid & OBD_MD_FLCTIME) { if (body->ctime > LTIME_S(inode->i_ctime)) LTIME_S(inode->i_ctime) = body->ctime; - lli->lli_lvb.lvb_ctime = body->ctime; + lli->lli_ctime = body->ctime; } if (body->valid & OBD_MD_FLMODE) inode->i_mode = (inode->i_mode & S_IFMT)|(body->mode & ~S_IFMT); diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c index 18127d3dc493..c7db318b8ece 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_io.c +++ b/drivers/staging/lustre/lustre/llite/vvp_io.c @@ -739,7 +739,7 @@ int vvp_io_write_commit(const struct lu_env *env, struct cl_io *io) } /* update inode size */ - ll_merge_lvb(env, inode); + ll_merge_attr(env, inode); /* Now the pages in queue were failed to commit, discard them * unless they were dirtied before. -- cgit v1.2.3 From 019e93516dcfc98efda51ccb8f7e0e758fda8ded Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Wed, 30 Mar 2016 19:48:35 -0400 Subject: staging/lustre/lmv: remove lmv_init_{lock,unlock}() In struct lmv_obd rename the init_mutex member to lmv_init_mutex. Remove the compat macros lmv_init_{lock,unlock}() and use mutex_{lock,unlock}(&lmv->lmv_init_mutex) instead. Signed-off-by: John L. Hammond Reviewed-on: http://review.whamcloud.com/12115 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-2675 Reviewed-by: Bob Glossman Reviewed-by: James Simmons Reviewed-by: Dmitry Eremin Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/obd.h | 2 +- drivers/staging/lustre/lustre/lmv/lmv_internal.h | 3 --- drivers/staging/lustre/lustre/lmv/lmv_obd.c | 24 ++++++++++++------------ 3 files changed, 13 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/include/obd.h b/drivers/staging/lustre/lustre/include/obd.h index 26182ca8f518..15c514c9d0ca 100644 --- a/drivers/staging/lustre/lustre/include/obd.h +++ b/drivers/staging/lustre/lustre/include/obd.h @@ -512,7 +512,7 @@ struct lmv_obd { struct obd_uuid cluuid; struct obd_export *exp; - struct mutex init_mutex; + struct mutex lmv_init_mutex; int connected; int max_easize; int max_def_easize; diff --git a/drivers/staging/lustre/lustre/lmv/lmv_internal.h b/drivers/staging/lustre/lustre/lmv/lmv_internal.h index 8a0087190e23..7007e4c48035 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_internal.h +++ b/drivers/staging/lustre/lustre/lmv/lmv_internal.h @@ -42,9 +42,6 @@ #define LMV_MAX_TGT_COUNT 128 -#define lmv_init_lock(lmv) mutex_lock(&lmv->init_mutex) -#define lmv_init_unlock(lmv) mutex_unlock(&lmv->init_mutex) - #define LL_IT2STR(it) \ ((it) ? ldlm_it2str((it)->it_op) : "0") diff --git a/drivers/staging/lustre/lustre/lmv/lmv_obd.c b/drivers/staging/lustre/lustre/lmv/lmv_obd.c index e3a721670ca1..8bd2dc577bf8 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_obd.c +++ b/drivers/staging/lustre/lustre/lmv/lmv_obd.c @@ -425,7 +425,7 @@ static int lmv_add_target(struct obd_device *obd, struct obd_uuid *uuidp, CDEBUG(D_CONFIG, "Target uuid: %s. index %d\n", uuidp->uuid, index); - lmv_init_lock(lmv); + mutex_lock(&lmv->lmv_init_mutex); if (lmv->desc.ld_tgt_count == 0) { struct obd_device *mdc_obd; @@ -433,7 +433,7 @@ static int lmv_add_target(struct obd_device *obd, struct obd_uuid *uuidp, mdc_obd = class_find_client_obd(uuidp, LUSTRE_MDC_NAME, &obd->obd_uuid); if (!mdc_obd) { - lmv_init_unlock(lmv); + mutex_unlock(&lmv->lmv_init_mutex); CERROR("%s: Target %s not attached: rc = %d\n", obd->obd_name, uuidp->uuid, -EINVAL); return -EINVAL; @@ -445,7 +445,7 @@ static int lmv_add_target(struct obd_device *obd, struct obd_uuid *uuidp, CERROR("%s: UUID %s already assigned at LOV target index %d: rc = %d\n", obd->obd_name, obd_uuid2str(&tgt->ltd_uuid), index, -EEXIST); - lmv_init_unlock(lmv); + mutex_unlock(&lmv->lmv_init_mutex); return -EEXIST; } @@ -459,7 +459,7 @@ static int lmv_add_target(struct obd_device *obd, struct obd_uuid *uuidp, newsize <<= 1; newtgts = kcalloc(newsize, sizeof(*newtgts), GFP_NOFS); if (!newtgts) { - lmv_init_unlock(lmv); + mutex_unlock(&lmv->lmv_init_mutex); return -ENOMEM; } @@ -481,7 +481,7 @@ static int lmv_add_target(struct obd_device *obd, struct obd_uuid *uuidp, tgt = kzalloc(sizeof(*tgt), GFP_NOFS); if (!tgt) { - lmv_init_unlock(lmv); + mutex_unlock(&lmv->lmv_init_mutex); return -ENOMEM; } @@ -507,7 +507,7 @@ static int lmv_add_target(struct obd_device *obd, struct obd_uuid *uuidp, } } - lmv_init_unlock(lmv); + mutex_unlock(&lmv->lmv_init_mutex); return rc; } @@ -522,14 +522,14 @@ int lmv_check_connect(struct obd_device *obd) if (lmv->connected) return 0; - lmv_init_lock(lmv); + mutex_lock(&lmv->lmv_init_mutex); if (lmv->connected) { - lmv_init_unlock(lmv); + mutex_unlock(&lmv->lmv_init_mutex); return 0; } if (lmv->desc.ld_tgt_count == 0) { - lmv_init_unlock(lmv); + mutex_unlock(&lmv->lmv_init_mutex); CERROR("%s: no targets configured.\n", obd->obd_name); return -EINVAL; } @@ -551,7 +551,7 @@ int lmv_check_connect(struct obd_device *obd) lmv->connected = 1; easize = lmv_get_easize(lmv); lmv_init_ea_size(obd->obd_self_export, easize, 0, 0, 0); - lmv_init_unlock(lmv); + mutex_unlock(&lmv->lmv_init_mutex); return 0; out_disc: @@ -572,7 +572,7 @@ int lmv_check_connect(struct obd_device *obd) } } class_disconnect(lmv->exp); - lmv_init_unlock(lmv); + mutex_unlock(&lmv->lmv_init_mutex); return rc; } @@ -1269,7 +1269,7 @@ static int lmv_setup(struct obd_device *obd, struct lustre_cfg *lcfg) lmv->lmv_placement = PLACEMENT_CHAR_POLICY; spin_lock_init(&lmv->lmv_lock); - mutex_init(&lmv->init_mutex); + mutex_init(&lmv->lmv_init_mutex); lprocfs_lmv_init_vars(&lvars); -- cgit v1.2.3 From 7d53d8f426cacdb7352e91957721b4a9962b222a Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Wed, 30 Mar 2016 19:48:36 -0400 Subject: staging/lustre/obd: remove struct client_obd_lock Remove the definition of struct client_obd_lock and the functions client_obd_list_{init,lock,unlock,done}(). Use spinlock_t for the cl_{loi,lru}_list_lock members of struct client_obd and call spin_{lock,unlock}() directly. Signed-off-by: John L. Hammond Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/fld/fld_request.c | 14 ++--- drivers/staging/lustre/lustre/include/linux/obd.h | 67 ---------------------- drivers/staging/lustre/lustre/include/obd.h | 9 +-- drivers/staging/lustre/lustre/ldlm/ldlm_lib.c | 4 +- drivers/staging/lustre/lustre/mdc/lproc_mdc.c | 8 +-- drivers/staging/lustre/lustre/mdc/mdc_lib.c | 18 +++--- drivers/staging/lustre/lustre/osc/lproc_osc.c | 38 ++++++------ drivers/staging/lustre/lustre/osc/osc_cache.c | 50 ++++++++-------- .../staging/lustre/lustre/osc/osc_cl_internal.h | 2 +- drivers/staging/lustre/lustre/osc/osc_page.c | 24 ++++---- drivers/staging/lustre/lustre/osc/osc_request.c | 46 +++++++-------- 11 files changed, 105 insertions(+), 175 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/fld/fld_request.c b/drivers/staging/lustre/lustre/fld/fld_request.c index a3d122d85c8d..2dfdb51445df 100644 --- a/drivers/staging/lustre/lustre/fld/fld_request.c +++ b/drivers/staging/lustre/lustre/fld/fld_request.c @@ -64,9 +64,9 @@ static int fld_req_avail(struct client_obd *cli, struct mdc_cache_waiter *mcw) { int rc; - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); rc = list_empty(&mcw->mcw_entry); - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); return rc; }; @@ -75,15 +75,15 @@ static void fld_enter_request(struct client_obd *cli) struct mdc_cache_waiter mcw; struct l_wait_info lwi = { 0 }; - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); if (cli->cl_r_in_flight >= cli->cl_max_rpcs_in_flight) { list_add_tail(&mcw.mcw_entry, &cli->cl_cache_waiters); init_waitqueue_head(&mcw.mcw_waitq); - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); l_wait_event(mcw.mcw_waitq, fld_req_avail(cli, &mcw), &lwi); } else { cli->cl_r_in_flight++; - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); } } @@ -92,7 +92,7 @@ static void fld_exit_request(struct client_obd *cli) struct list_head *l, *tmp; struct mdc_cache_waiter *mcw; - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); cli->cl_r_in_flight--; list_for_each_safe(l, tmp, &cli->cl_cache_waiters) { @@ -106,7 +106,7 @@ static void fld_exit_request(struct client_obd *cli) cli->cl_r_in_flight++; wake_up(&mcw->mcw_waitq); } - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); } static int fld_rrb_hash(struct lu_client_fld *fld, u64 seq) diff --git a/drivers/staging/lustre/lustre/include/linux/obd.h b/drivers/staging/lustre/lustre/include/linux/obd.h index 3907bf4ce07c..e1063e828229 100644 --- a/drivers/staging/lustre/lustre/include/linux/obd.h +++ b/drivers/staging/lustre/lustre/include/linux/obd.h @@ -55,71 +55,4 @@ struct ll_iattr { unsigned int ia_attr_flags; }; -#define CLIENT_OBD_LIST_LOCK_DEBUG 1 - -struct client_obd_lock { - spinlock_t lock; - - unsigned long time; - struct task_struct *task; - const char *func; - int line; -}; - -static inline void __client_obd_list_lock(struct client_obd_lock *lock, - const char *func, int line) -{ - unsigned long cur = jiffies; - - while (1) { - if (spin_trylock(&lock->lock)) { - LASSERT(!lock->task); - lock->task = current; - lock->func = func; - lock->line = line; - lock->time = jiffies; - break; - } - - if (time_before(cur + 5 * HZ, jiffies) && - time_before(lock->time + 5 * HZ, jiffies)) { - struct task_struct *task = lock->task; - - if (!task) - continue; - - LCONSOLE_WARN("%s:%d: lock %p was acquired by <%s:%d:%s:%d> for %lu seconds.\n", - current->comm, current->pid, - lock, task->comm, task->pid, - lock->func, lock->line, - (jiffies - lock->time) / HZ); - LCONSOLE_WARN("====== for current process =====\n"); - dump_stack(); - LCONSOLE_WARN("====== end =======\n"); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(1000 * HZ); - } - cpu_relax(); - } -} - -#define client_obd_list_lock(lock) \ - __client_obd_list_lock(lock, __func__, __LINE__) - -static inline void client_obd_list_unlock(struct client_obd_lock *lock) -{ - LASSERT(lock->task); - lock->task = NULL; - lock->time = jiffies; - spin_unlock(&lock->lock); -} - -static inline void client_obd_list_lock_init(struct client_obd_lock *lock) -{ - spin_lock_init(&lock->lock); -} - -static inline void client_obd_list_lock_done(struct client_obd_lock *lock) -{} - #endif /* __LINUX_OBD_H */ diff --git a/drivers/staging/lustre/lustre/include/obd.h b/drivers/staging/lustre/lustre/include/obd.h index 15c514c9d0ca..84cc001e152e 100644 --- a/drivers/staging/lustre/lustre/include/obd.h +++ b/drivers/staging/lustre/lustre/include/obd.h @@ -37,6 +37,7 @@ #ifndef __OBD_H #define __OBD_H +#include #include "linux/obd.h" #define IOC_OSC_TYPE 'h' @@ -293,14 +294,10 @@ struct client_obd { * blocking everywhere, but we don't want to slow down fast-path of * our main platform.) * - * Exact type of ->cl_loi_list_lock is defined in arch/obd.h together - * with client_obd_list_{un,}lock() and - * client_obd_list_lock_{init,done}() functions. - * * NB by Jinshan: though field names are still _loi_, but actually * osc_object{}s are in the list. */ - struct client_obd_lock cl_loi_list_lock; + spinlock_t cl_loi_list_lock; struct list_head cl_loi_ready_list; struct list_head cl_loi_hp_ready_list; struct list_head cl_loi_write_list; @@ -327,7 +324,7 @@ struct client_obd { atomic_t cl_lru_shrinkers; atomic_t cl_lru_in_list; struct list_head cl_lru_list; /* lru page list */ - struct client_obd_lock cl_lru_list_lock; /* page list protector */ + spinlock_t cl_lru_list_lock; /* page list protector */ /* number of in flight destroy rpcs is limited to max_rpcs_in_flight */ atomic_t cl_destroy_in_flight; diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c index b586d5a88d00..b497ce4f844a 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c @@ -314,7 +314,7 @@ int client_obd_setup(struct obd_device *obddev, struct lustre_cfg *lcfg) INIT_LIST_HEAD(&cli->cl_loi_hp_ready_list); INIT_LIST_HEAD(&cli->cl_loi_write_list); INIT_LIST_HEAD(&cli->cl_loi_read_list); - client_obd_list_lock_init(&cli->cl_loi_list_lock); + spin_lock_init(&cli->cl_loi_list_lock); atomic_set(&cli->cl_pending_w_pages, 0); atomic_set(&cli->cl_pending_r_pages, 0); cli->cl_r_in_flight = 0; @@ -333,7 +333,7 @@ int client_obd_setup(struct obd_device *obddev, struct lustre_cfg *lcfg) atomic_set(&cli->cl_lru_busy, 0); atomic_set(&cli->cl_lru_in_list, 0); INIT_LIST_HEAD(&cli->cl_lru_list); - client_obd_list_lock_init(&cli->cl_lru_list_lock); + spin_lock_init(&cli->cl_lru_list_lock); init_waitqueue_head(&cli->cl_destroy_waitq); atomic_set(&cli->cl_destroy_in_flight, 0); diff --git a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c index 38f267a60f59..5c7a15dd7bd2 100644 --- a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c +++ b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c @@ -49,9 +49,9 @@ static ssize_t max_rpcs_in_flight_show(struct kobject *kobj, obd_kobj); struct client_obd *cli = &dev->u.cli; - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); len = sprintf(buf, "%u\n", cli->cl_max_rpcs_in_flight); - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); return len; } @@ -74,9 +74,9 @@ static ssize_t max_rpcs_in_flight_store(struct kobject *kobj, if (val < 1 || val > MDC_MAX_RIF_MAX) return -ERANGE; - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); cli->cl_max_rpcs_in_flight = val; - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); return count; } diff --git a/drivers/staging/lustre/lustre/mdc/mdc_lib.c b/drivers/staging/lustre/lustre/mdc/mdc_lib.c index b3bfdcb73670..bd29eb7db4f0 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_lib.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_lib.c @@ -481,9 +481,9 @@ static int mdc_req_avail(struct client_obd *cli, struct mdc_cache_waiter *mcw) { int rc; - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); rc = list_empty(&mcw->mcw_entry); - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); return rc; }; @@ -497,23 +497,23 @@ int mdc_enter_request(struct client_obd *cli) struct mdc_cache_waiter mcw; struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL); - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); if (cli->cl_r_in_flight >= cli->cl_max_rpcs_in_flight) { list_add_tail(&mcw.mcw_entry, &cli->cl_cache_waiters); init_waitqueue_head(&mcw.mcw_waitq); - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); rc = l_wait_event(mcw.mcw_waitq, mdc_req_avail(cli, &mcw), &lwi); if (rc) { - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); if (list_empty(&mcw.mcw_entry)) cli->cl_r_in_flight--; list_del_init(&mcw.mcw_entry); - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); } } else { cli->cl_r_in_flight++; - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); } return rc; } @@ -523,7 +523,7 @@ void mdc_exit_request(struct client_obd *cli) struct list_head *l, *tmp; struct mdc_cache_waiter *mcw; - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); cli->cl_r_in_flight--; list_for_each_safe(l, tmp, &cli->cl_cache_waiters) { if (cli->cl_r_in_flight >= cli->cl_max_rpcs_in_flight) { @@ -538,5 +538,5 @@ void mdc_exit_request(struct client_obd *cli) } /* Empty waiting list? Decrease reqs in-flight number */ - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); } diff --git a/drivers/staging/lustre/lustre/osc/lproc_osc.c b/drivers/staging/lustre/lustre/osc/lproc_osc.c index e6e2029289f9..911e5054a9c4 100644 --- a/drivers/staging/lustre/lustre/osc/lproc_osc.c +++ b/drivers/staging/lustre/lustre/osc/lproc_osc.c @@ -121,9 +121,9 @@ static ssize_t max_rpcs_in_flight_store(struct kobject *kobj, atomic_add(added, &osc_pool_req_count); } - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); cli->cl_max_rpcs_in_flight = val; - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); return count; } @@ -139,9 +139,9 @@ static ssize_t max_dirty_mb_show(struct kobject *kobj, long val; int mult; - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); val = cli->cl_dirty_max; - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); mult = 1 << 20; return lprocfs_read_frac_helper(buf, PAGE_SIZE, val, mult); @@ -169,10 +169,10 @@ static ssize_t max_dirty_mb_store(struct kobject *kobj, pages_number > totalram_pages / 4) /* 1/4 of RAM */ return -ERANGE; - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); cli->cl_dirty_max = (u32)(pages_number << PAGE_CACHE_SHIFT); osc_wake_cache_waiters(cli); - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); return count; } @@ -247,9 +247,9 @@ static ssize_t cur_dirty_bytes_show(struct kobject *kobj, struct client_obd *cli = &dev->u.cli; int len; - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); len = sprintf(buf, "%lu\n", cli->cl_dirty); - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); return len; } @@ -264,9 +264,9 @@ static ssize_t cur_grant_bytes_show(struct kobject *kobj, struct client_obd *cli = &dev->u.cli; int len; - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); len = sprintf(buf, "%lu\n", cli->cl_avail_grant); - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); return len; } @@ -287,12 +287,12 @@ static ssize_t cur_grant_bytes_store(struct kobject *kobj, return rc; /* this is only for shrinking grant */ - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); if (val >= cli->cl_avail_grant) { - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); return -EINVAL; } - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); if (cli->cl_import->imp_state == LUSTRE_IMP_FULL) rc = osc_shrink_grant_to_target(cli, val); @@ -311,9 +311,9 @@ static ssize_t cur_lost_grant_bytes_show(struct kobject *kobj, struct client_obd *cli = &dev->u.cli; int len; - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); len = sprintf(buf, "%lu\n", cli->cl_lost_grant); - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); return len; } @@ -585,9 +585,9 @@ static ssize_t max_pages_per_rpc_store(struct kobject *kobj, if (val == 0 || val > ocd->ocd_brw_size >> PAGE_CACHE_SHIFT) { return -ERANGE; } - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); cli->cl_max_pages_per_rpc = val; - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); return count; } @@ -631,7 +631,7 @@ static int osc_rpc_stats_seq_show(struct seq_file *seq, void *v) ktime_get_real_ts64(&now); - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); seq_printf(seq, "snapshot_time: %llu.%9lu (secs.usecs)\n", (s64)now.tv_sec, (unsigned long)now.tv_nsec); @@ -715,7 +715,7 @@ static int osc_rpc_stats_seq_show(struct seq_file *seq, void *v) break; } - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); return 0; } diff --git a/drivers/staging/lustre/lustre/osc/osc_cache.c b/drivers/staging/lustre/lustre/osc/osc_cache.c index 7460793324d6..c5106592b3e4 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cache.c +++ b/drivers/staging/lustre/lustre/osc/osc_cache.c @@ -1373,7 +1373,7 @@ static int osc_completion(const struct lu_env *env, struct osc_async_page *oap, static void osc_consume_write_grant(struct client_obd *cli, struct brw_page *pga) { - assert_spin_locked(&cli->cl_loi_list_lock.lock); + assert_spin_locked(&cli->cl_loi_list_lock); LASSERT(!(pga->flag & OBD_BRW_FROM_GRANT)); atomic_inc(&obd_dirty_pages); cli->cl_dirty += PAGE_CACHE_SIZE; @@ -1389,7 +1389,7 @@ static void osc_consume_write_grant(struct client_obd *cli, static void osc_release_write_grant(struct client_obd *cli, struct brw_page *pga) { - assert_spin_locked(&cli->cl_loi_list_lock.lock); + assert_spin_locked(&cli->cl_loi_list_lock); if (!(pga->flag & OBD_BRW_FROM_GRANT)) { return; } @@ -1408,7 +1408,7 @@ static void osc_release_write_grant(struct client_obd *cli, * To avoid sleeping with object lock held, it's good for us allocate enough * grants before entering into critical section. * - * client_obd_list_lock held by caller + * spin_lock held by caller */ static int osc_reserve_grant(struct client_obd *cli, unsigned int bytes) { @@ -1442,11 +1442,11 @@ static void __osc_unreserve_grant(struct client_obd *cli, static void osc_unreserve_grant(struct client_obd *cli, unsigned int reserved, unsigned int unused) { - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); __osc_unreserve_grant(cli, reserved, unused); if (unused > 0) osc_wake_cache_waiters(cli); - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); } /** @@ -1467,7 +1467,7 @@ static void osc_free_grant(struct client_obd *cli, unsigned int nr_pages, { int grant = (1 << cli->cl_chunkbits) + cli->cl_extent_tax; - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); atomic_sub(nr_pages, &obd_dirty_pages); cli->cl_dirty -= nr_pages << PAGE_CACHE_SHIFT; cli->cl_lost_grant += lost_grant; @@ -1479,7 +1479,7 @@ static void osc_free_grant(struct client_obd *cli, unsigned int nr_pages, cli->cl_avail_grant += grant; } osc_wake_cache_waiters(cli); - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); CDEBUG(D_CACHE, "lost %u grant: %lu avail: %lu dirty: %lu\n", lost_grant, cli->cl_lost_grant, cli->cl_avail_grant, cli->cl_dirty); @@ -1491,9 +1491,9 @@ static void osc_free_grant(struct client_obd *cli, unsigned int nr_pages, */ static void osc_exit_cache(struct client_obd *cli, struct osc_async_page *oap) { - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); osc_release_write_grant(cli, &oap->oap_brw_page); - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); } /** @@ -1532,9 +1532,9 @@ static int ocw_granted(struct client_obd *cli, struct osc_cache_waiter *ocw) { int rc; - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); rc = list_empty(&ocw->ocw_entry); - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); return rc; } @@ -1556,7 +1556,7 @@ static int osc_enter_cache(const struct lu_env *env, struct client_obd *cli, OSC_DUMP_GRANT(cli, "need:%d.\n", bytes); - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); /* force the caller to try sync io. this can jump the list * of queued writes and create a discontiguous rpc stream @@ -1587,7 +1587,7 @@ static int osc_enter_cache(const struct lu_env *env, struct client_obd *cli, while (cli->cl_dirty > 0 || cli->cl_w_in_flight > 0) { list_add_tail(&ocw.ocw_entry, &cli->cl_cache_waiters); ocw.ocw_rc = 0; - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); osc_io_unplug_async(env, cli, NULL); @@ -1596,7 +1596,7 @@ static int osc_enter_cache(const struct lu_env *env, struct client_obd *cli, rc = l_wait_event(ocw.ocw_waitq, ocw_granted(cli, &ocw), &lwi); - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); /* l_wait_event is interrupted by signal */ if (rc < 0) { @@ -1615,7 +1615,7 @@ static int osc_enter_cache(const struct lu_env *env, struct client_obd *cli, } } out: - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); OSC_DUMP_GRANT(cli, "returned %d.\n", rc); return rc; } @@ -1776,9 +1776,9 @@ static int osc_list_maint(struct client_obd *cli, struct osc_object *osc) { int is_ready; - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); is_ready = __osc_list_maint(cli, osc); - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); return is_ready; } @@ -1829,10 +1829,10 @@ static void osc_ap_completion(const struct lu_env *env, struct client_obd *cli, oap->oap_interrupted = 0; if (oap->oap_cmd & OBD_BRW_WRITE && xid > 0) { - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); osc_process_ar(&cli->cl_ar, xid, rc); osc_process_ar(&loi->loi_ar, xid, rc); - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); } rc = osc_completion(env, oap, oap->oap_cmd, rc); @@ -2133,7 +2133,7 @@ static void osc_check_rpcs(const struct lu_env *env, struct client_obd *cli) } cl_object_get(obj); - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); lu_object_ref_add_at(&obj->co_lu, &link, "check", current); /* attempt some read/write balancing by alternating between @@ -2180,7 +2180,7 @@ static void osc_check_rpcs(const struct lu_env *env, struct client_obd *cli) lu_object_ref_del_at(&obj->co_lu, &link, "check", current); cl_object_put(env, obj); - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); } } @@ -2197,9 +2197,9 @@ static int osc_io_unplug0(const struct lu_env *env, struct client_obd *cli, * potential stack overrun problem. LU-2859 */ atomic_inc(&cli->cl_lru_shrinkers); - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); osc_check_rpcs(env, cli); - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); atomic_dec(&cli->cl_lru_shrinkers); } else { CDEBUG(D_CACHE, "Queue writeback work for client %p.\n", cli); @@ -2332,9 +2332,9 @@ int osc_queue_async_io(const struct lu_env *env, struct cl_io *io, grants = 0; /* it doesn't need any grant to dirty this page */ - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); rc = osc_enter_cache_try(cli, oap, grants, 0); - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); if (rc == 0) { /* try failed */ grants = 0; need_release = 1; diff --git a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h index 89552d73c497..bb34b53aead6 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h +++ b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h @@ -608,7 +608,7 @@ enum osc_extent_state { * * LOCKING ORDER * ============= - * page lock -> client_obd_list_lock -> object lock(osc_object::oo_lock) + * page lock -> cl_loi_list_lock -> object lock(osc_object::oo_lock) */ struct osc_extent { /** red-black tree node */ diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c index e02dd33b637c..5b313519637c 100644 --- a/drivers/staging/lustre/lustre/osc/osc_page.c +++ b/drivers/staging/lustre/lustre/osc/osc_page.c @@ -456,11 +456,11 @@ void osc_lru_add_batch(struct client_obd *cli, struct list_head *plist) } if (npages > 0) { - client_obd_list_lock(&cli->cl_lru_list_lock); + spin_lock(&cli->cl_lru_list_lock); list_splice_tail(&lru, &cli->cl_lru_list); atomic_sub(npages, &cli->cl_lru_busy); atomic_add(npages, &cli->cl_lru_in_list); - client_obd_list_unlock(&cli->cl_lru_list_lock); + spin_unlock(&cli->cl_lru_list_lock); /* XXX: May set force to be true for better performance */ if (osc_cache_too_much(cli)) @@ -482,14 +482,14 @@ static void __osc_lru_del(struct client_obd *cli, struct osc_page *opg) static void osc_lru_del(struct client_obd *cli, struct osc_page *opg) { if (opg->ops_in_lru) { - client_obd_list_lock(&cli->cl_lru_list_lock); + spin_lock(&cli->cl_lru_list_lock); if (!list_empty(&opg->ops_lru)) { __osc_lru_del(cli, opg); } else { LASSERT(atomic_read(&cli->cl_lru_busy) > 0); atomic_dec(&cli->cl_lru_busy); } - client_obd_list_unlock(&cli->cl_lru_list_lock); + spin_unlock(&cli->cl_lru_list_lock); atomic_inc(cli->cl_lru_left); /* this is a great place to release more LRU pages if @@ -513,9 +513,9 @@ static void osc_lru_use(struct client_obd *cli, struct osc_page *opg) * ops_lru should be empty */ if (opg->ops_in_lru && !list_empty(&opg->ops_lru)) { - client_obd_list_lock(&cli->cl_lru_list_lock); + spin_lock(&cli->cl_lru_list_lock); __osc_lru_del(cli, opg); - client_obd_list_unlock(&cli->cl_lru_list_lock); + spin_unlock(&cli->cl_lru_list_lock); atomic_inc(&cli->cl_lru_busy); } } @@ -572,7 +572,7 @@ int osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, pvec = (struct cl_page **)osc_env_info(env)->oti_pvec; io = &osc_env_info(env)->oti_io; - client_obd_list_lock(&cli->cl_lru_list_lock); + spin_lock(&cli->cl_lru_list_lock); maxscan = min(target << 1, atomic_read(&cli->cl_lru_in_list)); list_for_each_entry_safe(opg, temp, &cli->cl_lru_list, ops_lru) { struct cl_page *page; @@ -592,7 +592,7 @@ int osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, struct cl_object *tmp = page->cp_obj; cl_object_get(tmp); - client_obd_list_unlock(&cli->cl_lru_list_lock); + spin_unlock(&cli->cl_lru_list_lock); if (clobj) { discard_pagevec(env, io, pvec, index); @@ -608,7 +608,7 @@ int osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, io->ci_ignore_layout = 1; rc = cl_io_init(env, io, CIT_MISC, clobj); - client_obd_list_lock(&cli->cl_lru_list_lock); + spin_lock(&cli->cl_lru_list_lock); if (rc != 0) break; @@ -640,17 +640,17 @@ int osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, /* Don't discard and free the page with cl_lru_list held */ pvec[index++] = page; if (unlikely(index == OTI_PVEC_SIZE)) { - client_obd_list_unlock(&cli->cl_lru_list_lock); + spin_unlock(&cli->cl_lru_list_lock); discard_pagevec(env, io, pvec, index); index = 0; - client_obd_list_lock(&cli->cl_lru_list_lock); + spin_lock(&cli->cl_lru_list_lock); } if (++count >= target) break; } - client_obd_list_unlock(&cli->cl_lru_list_lock); + spin_unlock(&cli->cl_lru_list_lock); if (clobj) { discard_pagevec(env, io, pvec, index); diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c index 1e378e6c1a70..372bd26b07c8 100644 --- a/drivers/staging/lustre/lustre/osc/osc_request.c +++ b/drivers/staging/lustre/lustre/osc/osc_request.c @@ -801,7 +801,7 @@ static void osc_announce_cached(struct client_obd *cli, struct obdo *oa, LASSERT(!(oa->o_valid & bits)); oa->o_valid |= bits; - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); oa->o_dirty = cli->cl_dirty; if (unlikely(cli->cl_dirty - cli->cl_dirty_transit > cli->cl_dirty_max)) { @@ -833,7 +833,7 @@ static void osc_announce_cached(struct client_obd *cli, struct obdo *oa, oa->o_grant = cli->cl_avail_grant + cli->cl_reserved_grant; oa->o_dropped = cli->cl_lost_grant; cli->cl_lost_grant = 0; - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); CDEBUG(D_CACHE, "dirty: %llu undirty: %u dropped %u grant: %llu\n", oa->o_dirty, oa->o_undirty, oa->o_dropped, oa->o_grant); @@ -849,9 +849,9 @@ void osc_update_next_shrink(struct client_obd *cli) static void __osc_update_grant(struct client_obd *cli, u64 grant) { - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); cli->cl_avail_grant += grant; - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); } static void osc_update_grant(struct client_obd *cli, struct ost_body *body) @@ -889,10 +889,10 @@ out: static void osc_shrink_grant_local(struct client_obd *cli, struct obdo *oa) { - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); oa->o_grant = cli->cl_avail_grant / 4; cli->cl_avail_grant -= oa->o_grant; - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); if (!(oa->o_valid & OBD_MD_FLFLAGS)) { oa->o_valid |= OBD_MD_FLFLAGS; oa->o_flags = 0; @@ -911,10 +911,10 @@ static int osc_shrink_grant(struct client_obd *cli) __u64 target_bytes = (cli->cl_max_rpcs_in_flight + 1) * (cli->cl_max_pages_per_rpc << PAGE_CACHE_SHIFT); - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); if (cli->cl_avail_grant <= target_bytes) target_bytes = cli->cl_max_pages_per_rpc << PAGE_CACHE_SHIFT; - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); return osc_shrink_grant_to_target(cli, target_bytes); } @@ -924,7 +924,7 @@ int osc_shrink_grant_to_target(struct client_obd *cli, __u64 target_bytes) int rc = 0; struct ost_body *body; - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); /* Don't shrink if we are already above or below the desired limit * We don't want to shrink below a single RPC, as that will negatively * impact block allocation and long-term performance. @@ -933,10 +933,10 @@ int osc_shrink_grant_to_target(struct client_obd *cli, __u64 target_bytes) target_bytes = cli->cl_max_pages_per_rpc << PAGE_CACHE_SHIFT; if (target_bytes >= cli->cl_avail_grant) { - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); return 0; } - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); body = kzalloc(sizeof(*body), GFP_NOFS); if (!body) @@ -944,10 +944,10 @@ int osc_shrink_grant_to_target(struct client_obd *cli, __u64 target_bytes) osc_announce_cached(cli, &body->oa, 0); - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); body->oa.o_grant = cli->cl_avail_grant - target_bytes; cli->cl_avail_grant = target_bytes; - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); if (!(body->oa.o_valid & OBD_MD_FLFLAGS)) { body->oa.o_valid |= OBD_MD_FLFLAGS; body->oa.o_flags = 0; @@ -1035,7 +1035,7 @@ static void osc_init_grant(struct client_obd *cli, struct obd_connect_data *ocd) * race is tolerable here: if we're evicted, but imp_state already * left EVICTED state, then cl_dirty must be 0 already. */ - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); if (cli->cl_import->imp_state == LUSTRE_IMP_EVICTED) cli->cl_avail_grant = ocd->ocd_grant; else @@ -1053,7 +1053,7 @@ static void osc_init_grant(struct client_obd *cli, struct obd_connect_data *ocd) /* determine the appropriate chunk size used by osc_extent. */ cli->cl_chunkbits = max_t(int, PAGE_CACHE_SHIFT, ocd->ocd_blocksize); - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); CDEBUG(D_CACHE, "%s, setting cl_avail_grant: %ld cl_lost_grant: %ld chunk bits: %d\n", cli->cl_import->imp_obd->obd_name, @@ -1827,7 +1827,7 @@ static int brw_interpret(const struct lu_env *env, osc_release_ppga(aa->aa_ppga, aa->aa_page_count); ptlrpc_lprocfs_brw(req, req->rq_bulk->bd_nob_transferred); - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); /* We need to decrement before osc_ap_completion->osc_wake_cache_waiters * is called so we know whether to go to sync BRWs or wait for more * RPCs to complete @@ -1837,7 +1837,7 @@ static int brw_interpret(const struct lu_env *env, else cli->cl_r_in_flight--; osc_wake_cache_waiters(cli); - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); osc_io_unplug(env, cli, NULL); return rc; @@ -2005,7 +2005,7 @@ int osc_build_rpc(const struct lu_env *env, struct client_obd *cli, if (tmp) tmp->oap_request = ptlrpc_request_addref(req); - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); starting_offset >>= PAGE_CACHE_SHIFT; if (cmd == OBD_BRW_READ) { cli->cl_r_in_flight++; @@ -2020,7 +2020,7 @@ int osc_build_rpc(const struct lu_env *env, struct client_obd *cli, lprocfs_oh_tally_log2(&cli->cl_write_offset_hist, starting_offset + 1); } - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); DEBUG_REQ(D_INODE, req, "%d pages, aa %p. now %dr/%dw in flight", page_count, aa, cli->cl_r_in_flight, @@ -3005,12 +3005,12 @@ static int osc_reconnect(const struct lu_env *env, if (data && (data->ocd_connect_flags & OBD_CONNECT_GRANT)) { long lost_grant; - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); data->ocd_grant = (cli->cl_avail_grant + cli->cl_dirty) ?: 2 * cli_brw_size(obd); lost_grant = cli->cl_lost_grant; cli->cl_lost_grant = 0; - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); CDEBUG(D_RPCTRACE, "ocd_connect_flags: %#llx ocd_version: %d ocd_grant: %d, lost: %ld.\n", data->ocd_connect_flags, @@ -3060,10 +3060,10 @@ static int osc_import_event(struct obd_device *obd, switch (event) { case IMP_EVENT_DISCON: { cli = &obd->u.cli; - client_obd_list_lock(&cli->cl_loi_list_lock); + spin_lock(&cli->cl_loi_list_lock); cli->cl_avail_grant = 0; cli->cl_lost_grant = 0; - client_obd_list_unlock(&cli->cl_loi_list_lock); + spin_unlock(&cli->cl_loi_list_lock); break; } case IMP_EVENT_INACTIVE: { -- cgit v1.2.3 From 1929c433854c7673fd2d983ef8cf15cf13306d5c Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Wed, 30 Mar 2016 19:48:37 -0400 Subject: staging/lustre/llite: remove some cl wrappers In llite remove the wrapper functions and macros: cl_i2info() cl_i2sbi() cl_iattr2fd() cl_inode_info cl_inode_mode() cl_inode_{a,m,c}time() cl_isize_{read,write,write_nolock}() Signed-off-by: John L. Hammond Reviewed-on: http://review.whamcloud.com/12850 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-2675 Reviewed-by: James Simmons Reviewed-by: Lai Siyao Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/dir.c | 2 +- drivers/staging/lustre/lustre/llite/file.c | 8 ++-- drivers/staging/lustre/lustre/llite/glimpse.c | 10 ++--- drivers/staging/lustre/lustre/llite/lcommon_cl.c | 45 +++++++++++----------- .../staging/lustre/lustre/llite/llite_internal.h | 32 --------------- drivers/staging/lustre/lustre/llite/llite_lib.c | 2 +- drivers/staging/lustre/lustre/llite/vvp_object.c | 4 +- 7 files changed, 35 insertions(+), 68 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c index 4e0a3e583330..2ca4b0ef82ad 100644 --- a/drivers/staging/lustre/lustre/llite/dir.c +++ b/drivers/staging/lustre/lustre/llite/dir.c @@ -191,7 +191,7 @@ static int ll_dir_filler(void *_hash, struct page *page0) body = req_capsule_server_get(&request->rq_pill, &RMF_MDT_BODY); /* Checked by mdc_readpage() */ if (body->valid & OBD_MD_FLSIZE) - cl_isize_write(inode, body->size); + i_size_write(inode, body->size); nrdpgs = (request->rq_bulk->bd_nob_transferred+PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT; diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index 8fc9da00278e..c3c258f93817 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -1036,7 +1036,7 @@ int ll_merge_attr(const struct lu_env *env, struct inode *inode) CDEBUG(D_VFSTRACE, DFID " updating i_size %llu\n", PFID(&lli->lli_fid), attr->cat_size); - cl_isize_write_nolock(inode, attr->cat_size); + i_size_write(inode, attr->cat_size); inode->i_blocks = attr->cat_blocks; @@ -1592,7 +1592,7 @@ ll_get_grouplock(struct inode *inode, struct file *file, unsigned long arg) LASSERT(!fd->fd_grouplock.cg_lock); spin_unlock(&lli->lli_lock); - rc = cl_get_grouplock(cl_i2info(inode)->lli_clob, + rc = cl_get_grouplock(ll_i2info(inode)->lli_clob, arg, (file->f_flags & O_NONBLOCK), &grouplock); if (rc) return rc; @@ -2614,7 +2614,7 @@ int cl_sync_file_range(struct inode *inode, loff_t start, loff_t end, return PTR_ERR(env); io = ccc_env_thread_io(env); - io->ci_obj = cl_i2info(inode)->lli_clob; + io->ci_obj = ll_i2info(inode)->lli_clob; io->ci_ignore_layout = ignore_layout; /* initialize parameters for sync */ @@ -3629,7 +3629,7 @@ int ll_layout_restore(struct inode *inode) sizeof(hur->hur_user_item[0].hui_fid)); hur->hur_user_item[0].hui_extent.length = -1; hur->hur_request.hr_itemcount = 1; - rc = obd_iocontrol(LL_IOC_HSM_REQUEST, cl_i2sbi(inode)->ll_md_exp, + rc = obd_iocontrol(LL_IOC_HSM_REQUEST, ll_i2sbi(inode)->ll_md_exp, len, hur, NULL); kfree(hur); return rc; diff --git a/drivers/staging/lustre/lustre/llite/glimpse.c b/drivers/staging/lustre/lustre/llite/glimpse.c index 88bc7c9918e5..9b0e2ec0cf05 100644 --- a/drivers/staging/lustre/lustre/llite/glimpse.c +++ b/drivers/staging/lustre/lustre/llite/glimpse.c @@ -87,7 +87,7 @@ int cl_glimpse_lock(const struct lu_env *env, struct cl_io *io, struct inode *inode, struct cl_object *clob, int agl) { struct cl_lock_descr *descr = &ccc_env_info(env)->cti_descr; - struct cl_inode_info *lli = cl_i2info(inode); + struct ll_inode_info *lli = ll_i2info(inode); const struct lu_fid *fid = lu_object_fid(&clob->co_lu); struct ccc_io *cio = ccc_env_io(env); struct cl_lock *lock; @@ -140,7 +140,7 @@ int cl_glimpse_lock(const struct lu_env *env, struct cl_io *io, result = cl_wait(env, lock); if (result == 0) { ll_merge_attr(env, inode); - if (cl_isize_read(inode) > 0 && + if (i_size_read(inode) > 0 && inode->i_blocks == 0) { /* * LU-417: Add dirty pages block count @@ -167,11 +167,11 @@ static int cl_io_get(struct inode *inode, struct lu_env **envout, { struct lu_env *env; struct cl_io *io; - struct cl_inode_info *lli = cl_i2info(inode); + struct ll_inode_info *lli = ll_i2info(inode); struct cl_object *clob = lli->lli_clob; int result; - if (S_ISREG(cl_inode_mode(inode))) { + if (S_ISREG(inode->i_mode)) { env = cl_env_get(refcheck); if (!IS_ERR(env)) { io = ccc_env_thread_io(env); @@ -240,7 +240,7 @@ int cl_local_size(struct inode *inode) int result; int refcheck; - if (!cl_i2info(inode)->lli_has_smd) + if (!ll_i2info(inode)->lli_has_smd) return 0; result = cl_io_get(inode, &env, &io, &refcheck); diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c b/drivers/staging/lustre/lustre/llite/lcommon_cl.c index 4871d0feeb1c..fde96d374f49 100644 --- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c +++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c @@ -417,9 +417,9 @@ int ccc_object_glimpse(const struct lu_env *env, { struct inode *inode = ccc_object_inode(obj); - lvb->lvb_mtime = cl_inode_mtime(inode); - lvb->lvb_atime = cl_inode_atime(inode); - lvb->lvb_ctime = cl_inode_ctime(inode); + lvb->lvb_mtime = LTIME_S(inode->i_mtime); + lvb->lvb_atime = LTIME_S(inode->i_atime); + lvb->lvb_ctime = LTIME_S(inode->i_ctime); /* * LU-417: Add dirty pages block count lest i_blocks reports 0, some * "cp" or "tar" on remote node may think it's a completely sparse file @@ -731,7 +731,7 @@ int ccc_prep_size(const struct lu_env *env, struct cl_object *obj, * linux-2.6.18-128.1.1 miss to do that. * --bug 17336 */ - loff_t size = cl_isize_read(inode); + loff_t size = i_size_read(inode); loff_t cur_index = start >> PAGE_CACHE_SHIFT; loff_t size_index = (size - 1) >> PAGE_CACHE_SHIFT; @@ -752,11 +752,11 @@ int ccc_prep_size(const struct lu_env *env, struct cl_object *obj, * which will always be >= the kms value here. * b=11081 */ - if (cl_isize_read(inode) < kms) { - cl_isize_write_nolock(inode, kms); + if (i_size_read(inode) < kms) { + i_size_write(inode, kms); CDEBUG(D_VFSTRACE, DFID " updating i_size %llu\n", PFID(lu_object_fid(&obj->co_lu)), - (__u64)cl_isize_read(inode)); + (__u64)i_size_read(inode)); } } ccc_object_size_unlock(obj); @@ -816,14 +816,14 @@ void ccc_req_attr_set(const struct lu_env *env, if (slice->crs_req->crq_type == CRT_WRITE) { if (flags & OBD_MD_FLEPOCH) { oa->o_valid |= OBD_MD_FLEPOCH; - oa->o_ioepoch = cl_i2info(inode)->lli_ioepoch; + oa->o_ioepoch = ll_i2info(inode)->lli_ioepoch; valid_flags |= OBD_MD_FLMTIME | OBD_MD_FLCTIME | OBD_MD_FLUID | OBD_MD_FLGID; } } obdo_from_inode(oa, inode, valid_flags & flags); - obdo_set_parent_fid(oa, &cl_i2info(inode)->lli_fid); - memcpy(attr->cra_jobid, cl_i2info(inode)->lli_jobid, + obdo_set_parent_fid(oa, &ll_i2info(inode)->lli_fid); + memcpy(attr->cra_jobid, ll_i2info(inode)->lli_jobid, JOBSTATS_JOBID_SIZE); } @@ -844,7 +844,7 @@ int cl_setattr_ost(struct inode *inode, const struct iattr *attr) return PTR_ERR(env); io = ccc_env_thread_io(env); - io->ci_obj = cl_i2info(inode)->lli_clob; + io->ci_obj = ll_i2info(inode)->lli_clob; io->u.ci_setattr.sa_attr.lvb_atime = LTIME_S(attr->ia_atime); io->u.ci_setattr.sa_attr.lvb_mtime = LTIME_S(attr->ia_mtime); @@ -860,7 +860,7 @@ again: /* populate the file descriptor for ftruncate to honor * group lock - see LU-787 */ - cio->cui_fd = cl_iattr2fd(inode, attr); + cio->cui_fd = LUSTRE_FPRIVATE(attr->ia_file); result = cl_io_loop(env, io); } else { @@ -949,11 +949,10 @@ struct page *cl2vm_page(const struct cl_page_slice *slice) int ccc_object_invariant(const struct cl_object *obj) { struct inode *inode = ccc_object_inode(obj); - struct cl_inode_info *lli = cl_i2info(inode); + struct ll_inode_info *lli = ll_i2info(inode); - return (S_ISREG(cl_inode_mode(inode)) || - /* i_mode of unlinked inode is zeroed. */ - cl_inode_mode(inode) == 0) && lli->lli_clob == obj; + return (S_ISREG(inode->i_mode) || inode->i_mode == 0) && + lli->lli_clob == obj; } struct inode *ccc_object_inode(const struct cl_object *obj) @@ -973,7 +972,7 @@ struct inode *ccc_object_inode(const struct cl_object *obj) int cl_file_inode_init(struct inode *inode, struct lustre_md *md) { struct lu_env *env; - struct cl_inode_info *lli; + struct ll_inode_info *lli; struct cl_object *clob; struct lu_site *site; struct lu_fid *fid; @@ -987,14 +986,14 @@ int cl_file_inode_init(struct inode *inode, struct lustre_md *md) int refcheck; LASSERT(md->body->valid & OBD_MD_FLID); - LASSERT(S_ISREG(cl_inode_mode(inode))); + LASSERT(S_ISREG(inode->i_mode)); env = cl_env_get(&refcheck); if (IS_ERR(env)) return PTR_ERR(env); - site = cl_i2sbi(inode)->ll_site; - lli = cl_i2info(inode); + site = ll_i2sbi(inode)->ll_site; + lli = ll_i2info(inode); fid = &lli->lli_fid; LASSERT(fid_is_sane(fid)); @@ -1071,7 +1070,7 @@ static void cl_object_put_last(struct lu_env *env, struct cl_object *obj) void cl_inode_fini(struct inode *inode) { struct lu_env *env; - struct cl_inode_info *lli = cl_i2info(inode); + struct ll_inode_info *lli = ll_i2info(inode); struct cl_object *clob = lli->lli_clob; int refcheck; int emergency; @@ -1168,10 +1167,10 @@ __u32 cl_fid_build_gen(const struct lu_fid *fid) */ struct lov_stripe_md *ccc_inode_lsm_get(struct inode *inode) { - return lov_lsm_get(cl_i2info(inode)->lli_clob); + return lov_lsm_get(ll_i2info(inode)->lli_clob); } inline void ccc_inode_lsm_put(struct inode *inode, struct lov_stripe_md *lsm) { - lov_lsm_put(cl_i2info(inode)->lli_clob, lsm); + lov_lsm_put(ll_i2info(inode)->lli_clob, lsm); } diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index c1d747a1e962..ffed507da069 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -1293,38 +1293,6 @@ typedef enum llioc_iter (*llioc_callback_t)(struct inode *inode, void *ll_iocontrol_register(llioc_callback_t cb, int count, unsigned int *cmd); void ll_iocontrol_unregister(void *magic); -/* lclient compat stuff */ -#define cl_inode_info ll_inode_info -#define cl_i2info(info) ll_i2info(info) -#define cl_inode_mode(inode) ((inode)->i_mode) -#define cl_i2sbi ll_i2sbi - -static inline struct ll_file_data *cl_iattr2fd(struct inode *inode, - const struct iattr *attr) -{ - LASSERT(attr->ia_valid & ATTR_FILE); - return LUSTRE_FPRIVATE(attr->ia_file); -} - -static inline void cl_isize_write_nolock(struct inode *inode, loff_t kms) -{ - LASSERT(mutex_is_locked(&ll_i2info(inode)->lli_size_mutex)); - i_size_write(inode, kms); -} - -static inline void cl_isize_write(struct inode *inode, loff_t kms) -{ - ll_inode_size_lock(inode); - i_size_write(inode, kms); - ll_inode_size_unlock(inode); -} - -#define cl_isize_read(inode) i_size_read(inode) - -#define cl_inode_atime(inode) LTIME_S((inode)->i_atime) -#define cl_inode_ctime(inode) LTIME_S((inode)->i_ctime) -#define cl_inode_mtime(inode) LTIME_S((inode)->i_mtime) - int cl_sync_file_range(struct inode *inode, loff_t start, loff_t end, enum cl_fsync_mode mode, int ignore_layout); diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index 0b4e0dbfc130..041d22150973 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -1698,7 +1698,7 @@ void ll_read_inode2(struct inode *inode, void *opaque) void ll_delete_inode(struct inode *inode) { - struct cl_inode_info *lli = cl_i2info(inode); + struct ll_inode_info *lli = ll_i2info(inode); if (S_ISREG(inode->i_mode) && lli->lli_clob) /* discard all dirty pages before truncating them, required by diff --git a/drivers/staging/lustre/lustre/llite/vvp_object.c b/drivers/staging/lustre/lustre/llite/vvp_object.c index b9a1d01a9bd3..d03eb2b59de7 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_object.c +++ b/drivers/staging/lustre/lustre/llite/vvp_object.c @@ -112,7 +112,7 @@ static int vvp_attr_set(const struct lu_env *env, struct cl_object *obj, if (valid & CAT_CTIME) inode->i_ctime.tv_sec = attr->cat_ctime; if (0 && valid & CAT_SIZE) - cl_isize_write_nolock(inode, attr->cat_size); + i_size_write(inode, attr->cat_size); /* not currently necessary */ if (0 && valid & (CAT_UID|CAT_GID|CAT_SIZE)) mark_inode_dirty(inode); @@ -196,7 +196,7 @@ static const struct lu_object_operations vvp_lu_obj_ops = { struct ccc_object *cl_inode2ccc(struct inode *inode) { - struct cl_inode_info *lli = cl_i2info(inode); + struct ll_inode_info *lli = ll_i2info(inode); struct cl_object *obj = lli->lli_clob; struct lu_object *lu; -- cgit v1.2.3 From bb41292b4c4e956b5b776970d28630f04c4dd609 Mon Sep 17 00:00:00 2001 From: Oleg Drokin Date: Wed, 30 Mar 2016 19:48:38 -0400 Subject: staging/lustre: Remove struct ll_iattr This was a compat code from the time it had ia_attr_flags. Instead convert all the cryptic callers that did ((struct ll_iattr *)&op_data->op_attr)->ia_attr_flags into direct access to op_data->op_attr_flags This also makes lustre/include/linux/obd.h not needed anymore, so remove it. Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/linux/obd.h | 58 ----------------------- drivers/staging/lustre/lustre/include/obd.h | 2 +- drivers/staging/lustre/lustre/llite/file.c | 4 +- drivers/staging/lustre/lustre/llite/llite_lib.c | 2 +- drivers/staging/lustre/lustre/mdc/mdc_lib.c | 3 +- drivers/staging/lustre/lustre/obdclass/obdo.c | 3 +- 6 files changed, 6 insertions(+), 66 deletions(-) delete mode 100644 drivers/staging/lustre/lustre/include/linux/obd.h (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/include/linux/obd.h b/drivers/staging/lustre/lustre/include/linux/obd.h deleted file mode 100644 index e1063e828229..000000000000 --- a/drivers/staging/lustre/lustre/include/linux/obd.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * GPL HEADER END - */ -/* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. - * Use is subject to license terms. - * - * Copyright (c) 2011, 2012, Intel Corporation. - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - */ - -#ifndef __LINUX_OBD_H -#define __LINUX_OBD_H - -#ifndef __OBD_H -#error Do not #include this file directly. #include instead -#endif - -#include "../obd_support.h" - -#include -#include -#include /* for struct task_struct, for current.h */ -#include - -#include "../lustre_intent.h" - -struct ll_iattr { - struct iattr iattr; - unsigned int ia_attr_flags; -}; - -#endif /* __LINUX_OBD_H */ diff --git a/drivers/staging/lustre/lustre/include/obd.h b/drivers/staging/lustre/lustre/include/obd.h index 84cc001e152e..ded7b106ac8a 100644 --- a/drivers/staging/lustre/lustre/include/obd.h +++ b/drivers/staging/lustre/lustre/include/obd.h @@ -38,7 +38,6 @@ #define __OBD_H #include -#include "linux/obd.h" #define IOC_OSC_TYPE 'h' #define IOC_OSC_MIN_NR 20 @@ -55,6 +54,7 @@ #include "lustre_export.h" #include "lustre_fid.h" #include "lustre_fld.h" +#include "lustre_intent.h" #define MAX_OBD_DEVICES 8192 diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index c3c258f93817..bf2a5ee1e687 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -45,6 +45,7 @@ #include "../include/lustre_lite.h" #include #include +#include #include "llite_internal.h" #include "../include/lustre/ll_fiemap.h" @@ -87,8 +88,7 @@ void ll_pack_inode2opdata(struct inode *inode, struct md_op_data *op_data, op_data->op_attr.ia_ctime = inode->i_ctime; op_data->op_attr.ia_size = i_size_read(inode); op_data->op_attr_blocks = inode->i_blocks; - ((struct ll_iattr *)&op_data->op_attr)->ia_attr_flags = - ll_inode_to_ext_flags(inode->i_flags); + op_data->op_attr_flags = ll_inode_to_ext_flags(inode->i_flags); op_data->op_ioepoch = ll_i2info(inode)->lli_ioepoch; if (fh) op_data->op_handle = *fh; diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index 041d22150973..0f01cfc14b72 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -1771,7 +1771,7 @@ int ll_iocontrol(struct inode *inode, struct file *file, if (IS_ERR(op_data)) return PTR_ERR(op_data); - ((struct ll_iattr *)&op_data->op_attr)->ia_attr_flags = flags; + op_data->op_attr_flags = flags; op_data->op_attr.ia_valid |= ATTR_ATTR_FLAG; rc = md_setattr(sbi->ll_md_exp, op_data, NULL, 0, NULL, 0, &req, NULL); diff --git a/drivers/staging/lustre/lustre/mdc/mdc_lib.c b/drivers/staging/lustre/lustre/mdc/mdc_lib.c index bd29eb7db4f0..be0acf7feee3 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_lib.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_lib.c @@ -279,8 +279,7 @@ static void mdc_setattr_pack_rec(struct mdt_rec_setattr *rec, rec->sa_atime = LTIME_S(op_data->op_attr.ia_atime); rec->sa_mtime = LTIME_S(op_data->op_attr.ia_mtime); rec->sa_ctime = LTIME_S(op_data->op_attr.ia_ctime); - rec->sa_attr_flags = - ((struct ll_iattr *)&op_data->op_attr)->ia_attr_flags; + rec->sa_attr_flags = op_data->op_attr_flags; if ((op_data->op_attr.ia_valid & ATTR_GID) && in_group_p(op_data->op_attr.ia_gid)) rec->sa_suppgid = diff --git a/drivers/staging/lustre/lustre/obdclass/obdo.c b/drivers/staging/lustre/lustre/obdclass/obdo.c index e6436cb4ac62..748e33f017d5 100644 --- a/drivers/staging/lustre/lustre/obdclass/obdo.c +++ b/drivers/staging/lustre/lustre/obdclass/obdo.c @@ -185,8 +185,7 @@ void md_from_obdo(struct md_op_data *op_data, struct obdo *oa, u32 valid) op_data->op_attr.ia_valid |= ATTR_BLOCKS; } if (valid & OBD_MD_FLFLAGS) { - ((struct ll_iattr *)&op_data->op_attr)->ia_attr_flags = - oa->o_flags; + op_data->op_attr_flags = oa->o_flags; op_data->op_attr.ia_valid |= ATTR_ATTR_FLAG; } } -- cgit v1.2.3 From e5c4e635c36354c0f4aa6a00b1787d15ee689528 Mon Sep 17 00:00:00 2001 From: Jinshan Xiong Date: Wed, 30 Mar 2016 19:48:39 -0400 Subject: staging/lustre/clio: generalize cl_sync_io To make cl_sync_io interfaces not just wait for pages, but to be a generic synchronization mechanism. Also remove cl_io_cancel that became not used. Signed-off-by: Jinshan Xiong Reviewed-on: http://review.whamcloud.com/8656 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-4198 Reviewed-by: Bobi Jam Reviewed-by: Lai Siyao Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/cl_object.h | 13 ++-- drivers/staging/lustre/lustre/obdclass/cl_io.c | 74 +++++++++++------------ drivers/staging/lustre/lustre/obdclass/cl_page.c | 2 +- 3 files changed, 44 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h index 69b40f50df70..91261b1972af 100644 --- a/drivers/staging/lustre/lustre/include/cl_object.h +++ b/drivers/staging/lustre/lustre/include/cl_object.h @@ -3125,13 +3125,18 @@ struct cl_sync_io { atomic_t csi_barrier; /** completion to be signaled when transfer is complete. */ wait_queue_head_t csi_waitq; + /** callback to invoke when this IO is finished */ + void (*csi_end_io)(const struct lu_env *, + struct cl_sync_io *); }; -void cl_sync_io_init(struct cl_sync_io *anchor, int nrpages); -int cl_sync_io_wait(const struct lu_env *env, struct cl_io *io, - struct cl_page_list *queue, struct cl_sync_io *anchor, +void cl_sync_io_init(struct cl_sync_io *anchor, int nr, + void (*end)(const struct lu_env *, struct cl_sync_io *)); +int cl_sync_io_wait(const struct lu_env *env, struct cl_sync_io *anchor, long timeout); -void cl_sync_io_note(struct cl_sync_io *anchor, int ioret); +void cl_sync_io_note(const struct lu_env *env, struct cl_sync_io *anchor, + int ioret); +void cl_sync_io_end(const struct lu_env *env, struct cl_sync_io *anchor); /** @} cl_sync_io */ diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c index 65d6cee5232b..6a8dd9faafca 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_io.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c @@ -800,6 +800,9 @@ int cl_io_submit_rw(const struct lu_env *env, struct cl_io *io, } EXPORT_SYMBOL(cl_io_submit_rw); +static void cl_page_list_assume(const struct lu_env *env, + struct cl_io *io, struct cl_page_list *plist); + /** * Submit a sync_io and wait for the IO to be finished, or error happens. * If \a timeout is zero, it means to wait for the IO unconditionally. @@ -817,7 +820,7 @@ int cl_io_submit_sync(const struct lu_env *env, struct cl_io *io, pg->cp_sync_io = anchor; } - cl_sync_io_init(anchor, queue->c2_qin.pl_nr); + cl_sync_io_init(anchor, queue->c2_qin.pl_nr, &cl_sync_io_end); rc = cl_io_submit_rw(env, io, iot, queue); if (rc == 0) { /* @@ -828,12 +831,12 @@ int cl_io_submit_sync(const struct lu_env *env, struct cl_io *io, */ cl_page_list_for_each(pg, &queue->c2_qin) { pg->cp_sync_io = NULL; - cl_sync_io_note(anchor, 1); + cl_sync_io_note(env, anchor, 1); } /* wait for the IO to be finished. */ - rc = cl_sync_io_wait(env, io, &queue->c2_qout, - anchor, timeout); + rc = cl_sync_io_wait(env, anchor, timeout); + cl_page_list_assume(env, io, &queue->c2_qout); } else { LASSERT(list_empty(&queue->c2_qout.pl_pages)); cl_page_list_for_each(pg, &queue->c2_qin) @@ -843,25 +846,6 @@ int cl_io_submit_sync(const struct lu_env *env, struct cl_io *io, } EXPORT_SYMBOL(cl_io_submit_sync); -/** - * Cancel an IO which has been submitted by cl_io_submit_rw. - */ -static int cl_io_cancel(const struct lu_env *env, struct cl_io *io, - struct cl_page_list *queue) -{ - struct cl_page *page; - int result = 0; - - CERROR("Canceling ongoing page transmission\n"); - cl_page_list_for_each(page, queue) { - int rc; - - rc = cl_page_cancel(env, page); - result = result ?: rc; - } - return result; -} - /** * Main io loop. * @@ -1433,25 +1417,38 @@ void cl_req_attr_set(const struct lu_env *env, struct cl_req *req, } EXPORT_SYMBOL(cl_req_attr_set); +/* cl_sync_io_callback assumes the caller must call cl_sync_io_wait() to + * wait for the IO to finish. + */ +void cl_sync_io_end(const struct lu_env *env, struct cl_sync_io *anchor) +{ + wake_up_all(&anchor->csi_waitq); + + /* it's safe to nuke or reuse anchor now */ + atomic_set(&anchor->csi_barrier, 0); +} +EXPORT_SYMBOL(cl_sync_io_end); /** - * Initialize synchronous io wait anchor, for transfer of \a nrpages pages. + * Initialize synchronous io wait anchor */ -void cl_sync_io_init(struct cl_sync_io *anchor, int nrpages) +void cl_sync_io_init(struct cl_sync_io *anchor, int nr, + void (*end)(const struct lu_env *, struct cl_sync_io *)) { init_waitqueue_head(&anchor->csi_waitq); - atomic_set(&anchor->csi_sync_nr, nrpages); - atomic_set(&anchor->csi_barrier, nrpages > 0); + atomic_set(&anchor->csi_sync_nr, nr); + atomic_set(&anchor->csi_barrier, nr > 0); anchor->csi_sync_rc = 0; + anchor->csi_end_io = end; + LASSERT(end); } EXPORT_SYMBOL(cl_sync_io_init); /** - * Wait until all transfer completes. Transfer completion routine has to call - * cl_sync_io_note() for every page. + * Wait until all IO completes. Transfer completion routine has to call + * cl_sync_io_note() for every entity. */ -int cl_sync_io_wait(const struct lu_env *env, struct cl_io *io, - struct cl_page_list *queue, struct cl_sync_io *anchor, +int cl_sync_io_wait(const struct lu_env *env, struct cl_sync_io *anchor, long timeout) { struct l_wait_info lwi = LWI_TIMEOUT_INTR(cfs_time_seconds(timeout), @@ -1464,11 +1461,9 @@ int cl_sync_io_wait(const struct lu_env *env, struct cl_io *io, atomic_read(&anchor->csi_sync_nr) == 0, &lwi); if (rc < 0) { - CERROR("SYNC IO failed with error: %d, try to cancel %d remaining pages\n", + CERROR("IO failed: %d, still wait for %d remaining entries\n", rc, atomic_read(&anchor->csi_sync_nr)); - (void)cl_io_cancel(env, io, queue); - lwi = (struct l_wait_info) { 0 }; (void)l_wait_event(anchor->csi_waitq, atomic_read(&anchor->csi_sync_nr) == 0, @@ -1477,14 +1472,12 @@ int cl_sync_io_wait(const struct lu_env *env, struct cl_io *io, rc = anchor->csi_sync_rc; } LASSERT(atomic_read(&anchor->csi_sync_nr) == 0); - cl_page_list_assume(env, io, queue); /* wait until cl_sync_io_note() has done wakeup */ while (unlikely(atomic_read(&anchor->csi_barrier) != 0)) { cpu_relax(); } - POISON(anchor, 0x5a, sizeof(*anchor)); return rc; } EXPORT_SYMBOL(cl_sync_io_wait); @@ -1492,7 +1485,8 @@ EXPORT_SYMBOL(cl_sync_io_wait); /** * Indicate that transfer of a single page completed. */ -void cl_sync_io_note(struct cl_sync_io *anchor, int ioret) +void cl_sync_io_note(const struct lu_env *env, struct cl_sync_io *anchor, + int ioret) { if (anchor->csi_sync_rc == 0 && ioret < 0) anchor->csi_sync_rc = ioret; @@ -1503,9 +1497,9 @@ void cl_sync_io_note(struct cl_sync_io *anchor, int ioret) */ LASSERT(atomic_read(&anchor->csi_sync_nr) > 0); if (atomic_dec_and_test(&anchor->csi_sync_nr)) { - wake_up_all(&anchor->csi_waitq); - /* it's safe to nuke or reuse anchor now */ - atomic_set(&anchor->csi_barrier, 0); + LASSERT(anchor->csi_end_io); + anchor->csi_end_io(env, anchor); + /* Can't access anchor any more */ } } EXPORT_SYMBOL(cl_sync_io_note); diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c index 506a9f94e5ba..ad7f0aec605b 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_page.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c @@ -887,7 +887,7 @@ void cl_page_completion(const struct lu_env *env, cl_page_put(env, pg); if (anchor) - cl_sync_io_note(anchor, ioret); + cl_sync_io_note(env, anchor, ioret); } EXPORT_SYMBOL(cl_page_completion); -- cgit v1.2.3 From 06563b5606da7635b1fd5d121e7bd6d221e23db4 Mon Sep 17 00:00:00 2001 From: Jinshan Xiong Date: Wed, 30 Mar 2016 19:48:40 -0400 Subject: staging/lustre/clio: cl_lock simplification In this patch, the cl_lock cache is eliminated. cl_lock is turned into a cacheless data container for the requirements of locks to complete the IO. cl_lock is created before I/O starts and destroyed when the I/O is complete. cl_lock depends on LDLM lock to fulfill lock semantics. LDLM lock is attached to cl_lock at OSC layer. LDLM lock is still cacheable. Two major methods are supported for cl_lock: clo_enqueue and clo_cancel. A cl_lock is enqueued by cl_lock_request(), which will call clo_enqueue() methods for each layer to enqueue the lock. At the LOV layer, if a cl_lock consists of multiple sub cl_locks, each sub locks will be enqueued correspondingly. At OSC layer, the lock enqueue request will tend to reuse cached LDLM lock; otherwise a new LDLM lock will have to be requested from OST side. cl_lock_cancel() must be called to release a cl_lock after use. clo_cancel() method will be called for each layer to release the resource held by this lock. At OSC layer, the reference count of LDLM lock, which is held at clo_enqueue time, is released. LDLM lock can only be canceled if there is no cl_lock using it. Signed-off-by: Bobi Jam Signed-off-by: Jinshan Xiong Reviewed-on: http://review.whamcloud.com/10858 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-3259 Reviewed-by: John L. Hammond Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/cl_object.h | 590 +----- drivers/staging/lustre/lustre/include/lclient.h | 26 +- .../lustre/lustre/include/lustre/lustre_idl.h | 2 + drivers/staging/lustre/lustre/include/lustre_dlm.h | 1 + drivers/staging/lustre/lustre/ldlm/ldlm_lib.c | 1 + drivers/staging/lustre/lustre/ldlm/ldlm_lock.c | 3 +- drivers/staging/lustre/lustre/ldlm/ldlm_request.c | 16 +- drivers/staging/lustre/lustre/ldlm/ldlm_resource.c | 1 + drivers/staging/lustre/lustre/llite/glimpse.c | 49 +- drivers/staging/lustre/lustre/llite/lcommon_cl.c | 107 +- drivers/staging/lustre/lustre/llite/lcommon_misc.c | 14 +- drivers/staging/lustre/lustre/llite/rw26.c | 3 +- drivers/staging/lustre/lustre/llite/vvp_io.c | 19 +- drivers/staging/lustre/lustre/llite/vvp_lock.c | 25 +- drivers/staging/lustre/lustre/llite/vvp_object.c | 12 +- .../staging/lustre/lustre/lov/lov_cl_internal.h | 75 +- drivers/staging/lustre/lustre/lov/lov_dev.c | 5 +- drivers/staging/lustre/lustre/lov/lov_lock.c | 996 +--------- drivers/staging/lustre/lustre/lov/lov_object.c | 13 +- drivers/staging/lustre/lustre/lov/lovsub_lock.c | 383 ---- drivers/staging/lustre/lustre/obdclass/cl_io.c | 168 +- drivers/staging/lustre/lustre/obdclass/cl_lock.c | 2026 ++------------------ drivers/staging/lustre/lustre/obdclass/cl_object.c | 64 +- drivers/staging/lustre/lustre/obdclass/cl_page.c | 9 - .../staging/lustre/lustre/obdecho/echo_client.c | 60 +- drivers/staging/lustre/lustre/osc/osc_cache.c | 110 +- .../staging/lustre/lustre/osc/osc_cl_internal.h | 62 +- drivers/staging/lustre/lustre/osc/osc_internal.h | 10 +- drivers/staging/lustre/lustre/osc/osc_io.c | 41 +- drivers/staging/lustre/lustre/osc/osc_lock.c | 1618 ++++++---------- drivers/staging/lustre/lustre/osc/osc_object.c | 33 +- drivers/staging/lustre/lustre/osc/osc_page.c | 14 +- drivers/staging/lustre/lustre/osc/osc_request.c | 207 +- 33 files changed, 1203 insertions(+), 5560 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h index 91261b1972af..8f9512ef3942 100644 --- a/drivers/staging/lustre/lustre/include/cl_object.h +++ b/drivers/staging/lustre/lustre/include/cl_object.h @@ -82,7 +82,6 @@ * - i_mutex * - PG_locked * - cl_object_header::coh_page_guard - * - cl_object_header::coh_lock_guard * - lu_site::ls_guard * * See the top comment in cl_object.c for the description of overall locking and @@ -404,16 +403,6 @@ struct cl_object_header { * here. */ struct lu_object_header coh_lu; - /** \name locks - * \todo XXX move locks below to the separate cache-lines, they are - * mostly useless otherwise. - */ - /** @{ */ - /** Lock protecting lock list. */ - spinlock_t coh_lock_guard; - /** @} locks */ - /** List of cl_lock's granted for this object. */ - struct list_head coh_locks; /** * Parent object. It is assumed that an object has a well-defined @@ -795,16 +784,9 @@ struct cl_page_slice { /** * Lock mode. For the client extent locks. * - * \warning: cl_lock_mode_match() assumes particular ordering here. * \ingroup cl_lock */ enum cl_lock_mode { - /** - * Mode of a lock that protects no data, and exists only as a - * placeholder. This is used for `glimpse' requests. A phantom lock - * might get promoted to real lock at some point. - */ - CLM_PHANTOM, CLM_READ, CLM_WRITE, CLM_GROUP @@ -1114,12 +1096,6 @@ static inline struct page *cl_page_vmpage(struct cl_page *page) * (struct cl_lock) and a list of layers (struct cl_lock_slice), linked to * cl_lock::cll_layers list through cl_lock_slice::cls_linkage. * - * All locks for a given object are linked into cl_object_header::coh_locks - * list (protected by cl_object_header::coh_lock_guard spin-lock) through - * cl_lock::cll_linkage. Currently this list is not sorted in any way. We can - * sort it in starting lock offset, or use altogether different data structure - * like a tree. - * * Typical cl_lock consists of the two layers: * * - vvp_lock (vvp specific data), and @@ -1320,289 +1296,21 @@ struct cl_lock_descr { __u32 cld_enq_flags; }; -#define DDESCR "%s(%d):[%lu, %lu]" +#define DDESCR "%s(%d):[%lu, %lu]:%x" #define PDESCR(descr) \ cl_lock_mode_name((descr)->cld_mode), (descr)->cld_mode, \ - (descr)->cld_start, (descr)->cld_end + (descr)->cld_start, (descr)->cld_end, (descr)->cld_enq_flags const char *cl_lock_mode_name(const enum cl_lock_mode mode); -/** - * Lock state-machine states. - * - * \htmlonly - *
- *
- * Possible state transitions:
- *
- *	      +------------------>NEW
- *	      |		    |
- *	      |		    | cl_enqueue_try()
- *	      |		    |
- *	      |    cl_unuse_try()  V
- *	      |  +--------------QUEUING (*)
- *	      |  |		 |
- *	      |  |		 | cl_enqueue_try()
- *	      |  |		 |
- *	      |  | cl_unuse_try()  V
- *    sub-lock  |  +-------------ENQUEUED (*)
- *    canceled  |  |		 |
- *	      |  |		 | cl_wait_try()
- *	      |  |		 |
- *	      |  |		(R)
- *	      |  |		 |
- *	      |  |		 V
- *	      |  |		HELD<---------+
- *	      |  |		 |	    |
- *	      |  |		 |	    | cl_use_try()
- *	      |  |  cl_unuse_try() |	    |
- *	      |  |		 |	    |
- *	      |  |		 V	 ---+
- *	      |  +------------>INTRANSIT (D) <--+
- *	      |		    |	    |
- *	      |     cl_unuse_try() |	    | cached lock found
- *	      |		    |	    | cl_use_try()
- *	      |		    |	    |
- *	      |		    V	    |
- *	      +------------------CACHED---------+
- *				   |
- *				  (C)
- *				   |
- *				   V
- *				FREEING
- *
- * Legend:
- *
- *	 In states marked with (*) transition to the same state (i.e., a loop
- *	 in the diagram) is possible.
- *
- *	 (R) is the point where Receive call-back is invoked: it allows layers
- *	 to handle arrival of lock reply.
- *
- *	 (C) is the point where Cancellation call-back is invoked.
- *
- *	 (D) is the transit state which means the lock is changing.
- *
- *	 Transition to FREEING state is possible from any other state in the
- *	 diagram in case of unrecoverable error.
- * 
- * \endhtmlonly - * - * These states are for individual cl_lock object. Top-lock and its sub-locks - * can be in the different states. Another way to say this is that we have - * nested state-machines. - * - * Separate QUEUING and ENQUEUED states are needed to support non-blocking - * operation for locks with multiple sub-locks. Imagine lock on a file F, that - * intersects 3 stripes S0, S1, and S2. To enqueue F client has to send - * enqueue to S0, wait for its completion, then send enqueue for S1, wait for - * its completion and at last enqueue lock for S2, and wait for its - * completion. In that case, top-lock is in QUEUING state while S0, S1 are - * handled, and is in ENQUEUED state after enqueue to S2 has been sent (note - * that in this case, sub-locks move from state to state, and top-lock remains - * in the same state). - */ -enum cl_lock_state { - /** - * Lock that wasn't yet enqueued - */ - CLS_NEW, - /** - * Enqueue is in progress, blocking for some intermediate interaction - * with the other side. - */ - CLS_QUEUING, - /** - * Lock is fully enqueued, waiting for server to reply when it is - * granted. - */ - CLS_ENQUEUED, - /** - * Lock granted, actively used by some IO. - */ - CLS_HELD, - /** - * This state is used to mark the lock is being used, or unused. - * We need this state because the lock may have several sublocks, - * so it's impossible to have an atomic way to bring all sublocks - * into CLS_HELD state at use case, or all sublocks to CLS_CACHED - * at unuse case. - * If a thread is referring to a lock, and it sees the lock is in this - * state, it must wait for the lock. - * See state diagram for details. - */ - CLS_INTRANSIT, - /** - * Lock granted, not used. - */ - CLS_CACHED, - /** - * Lock is being destroyed. - */ - CLS_FREEING, - CLS_NR -}; - -enum cl_lock_flags { - /** - * lock has been cancelled. This flag is never cleared once set (by - * cl_lock_cancel0()). - */ - CLF_CANCELLED = 1 << 0, - /** cancellation is pending for this lock. */ - CLF_CANCELPEND = 1 << 1, - /** destruction is pending for this lock. */ - CLF_DOOMED = 1 << 2, - /** from enqueue RPC reply upcall. */ - CLF_FROM_UPCALL = 1 << 3, -}; - -/** - * Lock closure. - * - * Lock closure is a collection of locks (both top-locks and sub-locks) that - * might be updated in a result of an operation on a certain lock (which lock - * this is a closure of). - * - * Closures are needed to guarantee dead-lock freedom in the presence of - * - * - nested state-machines (top-lock state-machine composed of sub-lock - * state-machines), and - * - * - shared sub-locks. - * - * Specifically, many operations, such as lock enqueue, wait, unlock, - * etc. start from a top-lock, and then operate on a sub-locks of this - * top-lock, holding a top-lock mutex. When sub-lock state changes as a result - * of such operation, this change has to be propagated to all top-locks that - * share this sub-lock. Obviously, no natural lock ordering (e.g., - * top-to-bottom or bottom-to-top) captures this scenario, so try-locking has - * to be used. Lock closure systematizes this try-and-repeat logic. - */ -struct cl_lock_closure { - /** - * Lock that is mutexed when closure construction is started. When - * closure in is `wait' mode (cl_lock_closure::clc_wait), mutex on - * origin is released before waiting. - */ - struct cl_lock *clc_origin; - /** - * List of enclosed locks, so far. Locks are linked here through - * cl_lock::cll_inclosure. - */ - struct list_head clc_list; - /** - * True iff closure is in a `wait' mode. This determines what - * cl_lock_enclosure() does when a lock L to be added to the closure - * is currently mutexed by some other thread. - * - * If cl_lock_closure::clc_wait is not set, then closure construction - * fails with CLO_REPEAT immediately. - * - * In wait mode, cl_lock_enclosure() waits until next attempt to build - * a closure might succeed. To this end it releases an origin mutex - * (cl_lock_closure::clc_origin), that has to be the only lock mutex - * owned by the current thread, and then waits on L mutex (by grabbing - * it and immediately releasing), before returning CLO_REPEAT to the - * caller. - */ - int clc_wait; - /** Number of locks in the closure. */ - int clc_nr; -}; - /** * Layered client lock. */ struct cl_lock { - /** Reference counter. */ - atomic_t cll_ref; /** List of slices. Immutable after creation. */ struct list_head cll_layers; - /** - * Linkage into cl_lock::cll_descr::cld_obj::coh_locks list. Protected - * by cl_lock::cll_descr::cld_obj::coh_lock_guard. - */ - struct list_head cll_linkage; - /** - * Parameters of this lock. Protected by - * cl_lock::cll_descr::cld_obj::coh_lock_guard nested within - * cl_lock::cll_guard. Modified only on lock creation and in - * cl_lock_modify(). - */ + /** lock attribute, extent, cl_object, etc. */ struct cl_lock_descr cll_descr; - /** Protected by cl_lock::cll_guard. */ - enum cl_lock_state cll_state; - /** signals state changes. */ - wait_queue_head_t cll_wq; - /** - * Recursive lock, most fields in cl_lock{} are protected by this. - * - * Locking rules: this mutex is never held across network - * communication, except when lock is being canceled. - * - * Lock ordering: a mutex of a sub-lock is taken first, then a mutex - * on a top-lock. Other direction is implemented through a - * try-lock-repeat loop. Mutices of unrelated locks can be taken only - * by try-locking. - * - * \see osc_lock_enqueue_wait(), lov_lock_cancel(), lov_sublock_wait(). - */ - struct mutex cll_guard; - struct task_struct *cll_guarder; - int cll_depth; - - /** - * the owner for INTRANSIT state - */ - struct task_struct *cll_intransit_owner; - int cll_error; - /** - * Number of holds on a lock. A hold prevents a lock from being - * canceled and destroyed. Protected by cl_lock::cll_guard. - * - * \see cl_lock_hold(), cl_lock_unhold(), cl_lock_release() - */ - int cll_holds; - /** - * Number of lock users. Valid in cl_lock_state::CLS_HELD state - * only. Lock user pins lock in CLS_HELD state. Protected by - * cl_lock::cll_guard. - * - * \see cl_wait(), cl_unuse(). - */ - int cll_users; - /** - * Flag bit-mask. Values from enum cl_lock_flags. Updates are - * protected by cl_lock::cll_guard. - */ - unsigned long cll_flags; - /** - * A linkage into a list of locks in a closure. - * - * \see cl_lock_closure - */ - struct list_head cll_inclosure; - /** - * Confict lock at queuing time. - */ - struct cl_lock *cll_conflict; - /** - * A list of references to this lock, for debugging. - */ - struct lu_ref cll_reference; - /** - * A list of holds on this lock, for debugging. - */ - struct lu_ref cll_holders; - /** - * A reference for cl_lock::cll_descr::cld_obj. For debugging. - */ - struct lu_ref_link cll_obj_ref; -#ifdef CONFIG_LOCKDEP - /* "dep_map" name is assumed by lockdep.h macros. */ - struct lockdep_map dep_map; -#endif }; /** @@ -1621,171 +1329,33 @@ struct cl_lock_slice { struct list_head cls_linkage; }; -/** - * Possible (non-error) return values of ->clo_{enqueue,wait,unlock}(). - * - * NOTE: lov_subresult() depends on ordering here. - */ -enum cl_lock_transition { - /** operation cannot be completed immediately. Wait for state change. */ - CLO_WAIT = 1, - /** operation had to release lock mutex, restart. */ - CLO_REPEAT = 2, - /** lower layer re-enqueued. */ - CLO_REENQUEUED = 3, -}; - /** * * \see vvp_lock_ops, lov_lock_ops, lovsub_lock_ops, osc_lock_ops */ struct cl_lock_operations { - /** - * \name statemachine - * - * State machine transitions. These 3 methods are called to transfer - * lock from one state to another, as described in the commentary - * above enum #cl_lock_state. - * - * \retval 0 this layer has nothing more to do to before - * transition to the target state happens; - * - * \retval CLO_REPEAT method had to release and re-acquire cl_lock - * mutex, repeat invocation of transition method - * across all layers; - * - * \retval CLO_WAIT this layer cannot move to the target state - * immediately, as it has to wait for certain event - * (e.g., the communication with the server). It - * is guaranteed, that when the state transfer - * becomes possible, cl_lock::cll_wq wait-queue - * is signaled. Caller can wait for this event by - * calling cl_lock_state_wait(); - * - * \retval -ve failure, abort state transition, move the lock - * into cl_lock_state::CLS_FREEING state, and set - * cl_lock::cll_error. - * - * Once all layers voted to agree to transition (by returning 0), lock - * is moved into corresponding target state. All state transition - * methods are optional. - */ /** @{ */ /** * Attempts to enqueue the lock. Called top-to-bottom. * + * \retval 0 this layer has enqueued the lock successfully + * \retval >0 this layer has enqueued the lock, but need to wait on + * @anchor for resources + * \retval -ve failure + * * \see ccc_lock_enqueue(), lov_lock_enqueue(), lovsub_lock_enqueue(), * \see osc_lock_enqueue() */ int (*clo_enqueue)(const struct lu_env *env, const struct cl_lock_slice *slice, - struct cl_io *io, __u32 enqflags); - /** - * Attempts to wait for enqueue result. Called top-to-bottom. - * - * \see ccc_lock_wait(), lov_lock_wait(), osc_lock_wait() - */ - int (*clo_wait)(const struct lu_env *env, - const struct cl_lock_slice *slice); - /** - * Attempts to unlock the lock. Called bottom-to-top. In addition to - * usual return values of lock state-machine methods, this can return - * -ESTALE to indicate that lock cannot be returned to the cache, and - * has to be re-initialized. - * unuse is a one-shot operation, so it must NOT return CLO_WAIT. - * - * \see ccc_lock_unuse(), lov_lock_unuse(), osc_lock_unuse() - */ - int (*clo_unuse)(const struct lu_env *env, - const struct cl_lock_slice *slice); - /** - * Notifies layer that cached lock is started being used. - * - * \pre lock->cll_state == CLS_CACHED - * - * \see lov_lock_use(), osc_lock_use() - */ - int (*clo_use)(const struct lu_env *env, - const struct cl_lock_slice *slice); - /** @} statemachine */ - /** - * A method invoked when lock state is changed (as a result of state - * transition). This is used, for example, to track when the state of - * a sub-lock changes, to propagate this change to the corresponding - * top-lock. Optional - * - * \see lovsub_lock_state() - */ - void (*clo_state)(const struct lu_env *env, - const struct cl_lock_slice *slice, - enum cl_lock_state st); - /** - * Returns true, iff given lock is suitable for the given io, idea - * being, that there are certain "unsafe" locks, e.g., ones acquired - * for O_APPEND writes, that we don't want to re-use for a normal - * write, to avoid the danger of cascading evictions. Optional. Runs - * under cl_object_header::coh_lock_guard. - * - * XXX this should take more information about lock needed by - * io. Probably lock description or something similar. - * - * \see lov_fits_into() - */ - int (*clo_fits_into)(const struct lu_env *env, - const struct cl_lock_slice *slice, - const struct cl_lock_descr *need, - const struct cl_io *io); - /** - * \name ast - * Asynchronous System Traps. All of then are optional, all are - * executed bottom-to-top. - */ - /** @{ */ - + struct cl_io *io, struct cl_sync_io *anchor); /** - * Cancellation callback. Cancel a lock voluntarily, or under - * the request of server. + * Cancel a lock, release its DLM lock ref, while does not cancel the + * DLM lock */ void (*clo_cancel)(const struct lu_env *env, const struct cl_lock_slice *slice); - /** - * Lock weighting ast. Executed to estimate how precious this lock - * is. The sum of results across all layers is used to determine - * whether lock worth keeping in cache given present memory usage. - * - * \see osc_lock_weigh(), vvp_lock_weigh(), lovsub_lock_weigh(). - */ - unsigned long (*clo_weigh)(const struct lu_env *env, - const struct cl_lock_slice *slice); - /** @} ast */ - - /** - * \see lovsub_lock_closure() - */ - int (*clo_closure)(const struct lu_env *env, - const struct cl_lock_slice *slice, - struct cl_lock_closure *closure); - /** - * Executed bottom-to-top when lock description changes (e.g., as a - * result of server granting more generous lock than was requested). - * - * \see lovsub_lock_modify() - */ - int (*clo_modify)(const struct lu_env *env, - const struct cl_lock_slice *slice, - const struct cl_lock_descr *updated); - /** - * Notifies layers (bottom-to-top) that lock is going to be - * destroyed. Responsibility of layers is to prevent new references on - * this lock from being acquired once this method returns. - * - * This can be called multiple times due to the races. - * - * \see cl_lock_delete() - * \see osc_lock_delete(), lovsub_lock_delete() - */ - void (*clo_delete)(const struct lu_env *env, - const struct cl_lock_slice *slice); + /** @} */ /** * Destructor. Frees resources and the slice. * @@ -2164,10 +1734,14 @@ enum cl_enq_flags { * for async glimpse lock. */ CEF_AGL = 0x00000020, + /** + * enqueue a lock to test DLM lock existence. + */ + CEF_PEEK = 0x00000040, /** * mask of enq_flags. */ - CEF_MASK = 0x0000003f, + CEF_MASK = 0x0000007f, }; /** @@ -2177,12 +1751,12 @@ enum cl_enq_flags { struct cl_io_lock_link { /** linkage into one of cl_lockset lists. */ struct list_head cill_linkage; - struct cl_lock_descr cill_descr; - struct cl_lock *cill_lock; + struct cl_lock cill_lock; /** optional destructor */ void (*cill_fini)(const struct lu_env *env, struct cl_io_lock_link *link); }; +#define cill_descr cill_lock.cll_descr /** * Lock-set represents a collection of locks, that io needs at a @@ -2216,8 +1790,6 @@ struct cl_io_lock_link { struct cl_lockset { /** locks to be acquired. */ struct list_head cls_todo; - /** locks currently being processed. */ - struct list_head cls_curr; /** locks acquired. */ struct list_head cls_done; }; @@ -2581,9 +2153,7 @@ struct cl_site { * and top-locks (and top-pages) are accounted here. */ struct cache_stats cs_pages; - struct cache_stats cs_locks; atomic_t cs_pages_state[CPS_NR]; - atomic_t cs_locks_state[CLS_NR]; }; int cl_site_init(struct cl_site *s, struct cl_device *top); @@ -2707,7 +2277,7 @@ int cl_object_glimpse(const struct lu_env *env, struct cl_object *obj, struct ost_lvb *lvb); int cl_conf_set(const struct lu_env *env, struct cl_object *obj, const struct cl_object_conf *conf); -void cl_object_prune(const struct lu_env *env, struct cl_object *obj); +int cl_object_prune(const struct lu_env *env, struct cl_object *obj); void cl_object_kill(const struct lu_env *env, struct cl_object *obj); /** @@ -2845,121 +2415,17 @@ void cl_lock_descr_print(const struct lu_env *env, void *cookie, * @{ */ -struct cl_lock *cl_lock_hold(const struct lu_env *env, const struct cl_io *io, - const struct cl_lock_descr *need, - const char *scope, const void *source); -struct cl_lock *cl_lock_peek(const struct lu_env *env, const struct cl_io *io, - const struct cl_lock_descr *need, - const char *scope, const void *source); -struct cl_lock *cl_lock_request(const struct lu_env *env, struct cl_io *io, - const struct cl_lock_descr *need, - const char *scope, const void *source); -struct cl_lock *cl_lock_at_pgoff(const struct lu_env *env, - struct cl_object *obj, pgoff_t index, - struct cl_lock *except, int pending, - int canceld); +int cl_lock_request(const struct lu_env *env, struct cl_io *io, + struct cl_lock *lock); +int cl_lock_init(const struct lu_env *env, struct cl_lock *lock, + const struct cl_io *io); +void cl_lock_fini(const struct lu_env *env, struct cl_lock *lock); const struct cl_lock_slice *cl_lock_at(const struct cl_lock *lock, const struct lu_device_type *dtype); - -void cl_lock_get(struct cl_lock *lock); -void cl_lock_get_trust(struct cl_lock *lock); -void cl_lock_put(const struct lu_env *env, struct cl_lock *lock); -void cl_lock_hold_add(const struct lu_env *env, struct cl_lock *lock, - const char *scope, const void *source); -void cl_lock_hold_release(const struct lu_env *env, struct cl_lock *lock, - const char *scope, const void *source); -void cl_lock_unhold(const struct lu_env *env, struct cl_lock *lock, - const char *scope, const void *source); -void cl_lock_release(const struct lu_env *env, struct cl_lock *lock, - const char *scope, const void *source); -void cl_lock_user_add(const struct lu_env *env, struct cl_lock *lock); -void cl_lock_user_del(const struct lu_env *env, struct cl_lock *lock); - -int cl_lock_is_intransit(struct cl_lock *lock); - -int cl_lock_enqueue_wait(const struct lu_env *env, struct cl_lock *lock, - int keep_mutex); - -/** \name statemachine statemachine - * Interface to lock state machine consists of 3 parts: - * - * - "try" functions that attempt to effect a state transition. If state - * transition is not possible right now (e.g., if it has to wait for some - * asynchronous event to occur), these functions return - * cl_lock_transition::CLO_WAIT. - * - * - "non-try" functions that implement synchronous blocking interface on - * top of non-blocking "try" functions. These functions repeatedly call - * corresponding "try" versions, and if state transition is not possible - * immediately, wait for lock state change. - * - * - methods from cl_lock_operations, called by "try" functions. Lock can - * be advanced to the target state only when all layers voted that they - * are ready for this transition. "Try" functions call methods under lock - * mutex. If a layer had to release a mutex, it re-acquires it and returns - * cl_lock_transition::CLO_REPEAT, causing "try" function to call all - * layers again. - * - * TRY NON-TRY METHOD FINAL STATE - * - * cl_enqueue_try() cl_enqueue() cl_lock_operations::clo_enqueue() CLS_ENQUEUED - * - * cl_wait_try() cl_wait() cl_lock_operations::clo_wait() CLS_HELD - * - * cl_unuse_try() cl_unuse() cl_lock_operations::clo_unuse() CLS_CACHED - * - * cl_use_try() NONE cl_lock_operations::clo_use() CLS_HELD - * - * @{ - */ - -int cl_wait(const struct lu_env *env, struct cl_lock *lock); -void cl_unuse(const struct lu_env *env, struct cl_lock *lock); -int cl_enqueue_try(const struct lu_env *env, struct cl_lock *lock, - struct cl_io *io, __u32 flags); -int cl_unuse_try(const struct lu_env *env, struct cl_lock *lock); -int cl_wait_try(const struct lu_env *env, struct cl_lock *lock); -int cl_use_try(const struct lu_env *env, struct cl_lock *lock, int atomic); - -/** @} statemachine */ - -void cl_lock_signal(const struct lu_env *env, struct cl_lock *lock); -int cl_lock_state_wait(const struct lu_env *env, struct cl_lock *lock); -void cl_lock_state_set(const struct lu_env *env, struct cl_lock *lock, - enum cl_lock_state state); -int cl_queue_match(const struct list_head *queue, - const struct cl_lock_descr *need); - -void cl_lock_mutex_get(const struct lu_env *env, struct cl_lock *lock); -void cl_lock_mutex_put(const struct lu_env *env, struct cl_lock *lock); -int cl_lock_is_mutexed(struct cl_lock *lock); -int cl_lock_nr_mutexed(const struct lu_env *env); -int cl_lock_discard_pages(const struct lu_env *env, struct cl_lock *lock); -int cl_lock_ext_match(const struct cl_lock_descr *has, - const struct cl_lock_descr *need); -int cl_lock_descr_match(const struct cl_lock_descr *has, - const struct cl_lock_descr *need); -int cl_lock_mode_match(enum cl_lock_mode has, enum cl_lock_mode need); -int cl_lock_modify(const struct lu_env *env, struct cl_lock *lock, - const struct cl_lock_descr *desc); - -void cl_lock_closure_init(const struct lu_env *env, - struct cl_lock_closure *closure, - struct cl_lock *origin, int wait); -void cl_lock_closure_fini(struct cl_lock_closure *closure); -int cl_lock_closure_build(const struct lu_env *env, struct cl_lock *lock, - struct cl_lock_closure *closure); -void cl_lock_disclosure(const struct lu_env *env, - struct cl_lock_closure *closure); -int cl_lock_enclosure(const struct lu_env *env, struct cl_lock *lock, - struct cl_lock_closure *closure); - +void cl_lock_release(const struct lu_env *env, struct cl_lock *lock); +int cl_lock_enqueue(const struct lu_env *env, struct cl_io *io, + struct cl_lock *lock, struct cl_sync_io *anchor); void cl_lock_cancel(const struct lu_env *env, struct cl_lock *lock); -void cl_lock_delete(const struct lu_env *env, struct cl_lock *lock); -void cl_lock_error(const struct lu_env *env, struct cl_lock *lock, int error); -void cl_locks_prune(const struct lu_env *env, struct cl_object *obj, int wait); - -unsigned long cl_lock_weigh(const struct lu_env *env, struct cl_lock *lock); /** @} cl_lock */ diff --git a/drivers/staging/lustre/lustre/include/lclient.h b/drivers/staging/lustre/lustre/include/lclient.h index a8c8788ebc07..82af8aeb7212 100644 --- a/drivers/staging/lustre/lustre/include/lclient.h +++ b/drivers/staging/lustre/lustre/include/lclient.h @@ -98,10 +98,6 @@ struct ccc_io { int cui_to; } write; } u; - /** - * True iff io is processing glimpse right now. - */ - int cui_glimpse; /** * Layout version when this IO is initialized */ @@ -123,6 +119,7 @@ extern struct lu_context_key ccc_key; extern struct lu_context_key ccc_session_key; struct ccc_thread_info { + struct cl_lock cti_lock; struct cl_lock_descr cti_descr; struct cl_io cti_io; struct cl_attr cti_attr; @@ -137,6 +134,14 @@ static inline struct ccc_thread_info *ccc_env_info(const struct lu_env *env) return info; } +static inline struct cl_lock *ccc_env_lock(const struct lu_env *env) +{ + struct cl_lock *lock = &ccc_env_info(env)->cti_lock; + + memset(lock, 0, sizeof(*lock)); + return lock; +} + static inline struct cl_attr *ccc_env_thread_attr(const struct lu_env *env) { struct cl_attr *attr = &ccc_env_info(env)->cti_attr; @@ -308,18 +313,7 @@ void ccc_lock_delete(const struct lu_env *env, void ccc_lock_fini(const struct lu_env *env, struct cl_lock_slice *slice); int ccc_lock_enqueue(const struct lu_env *env, const struct cl_lock_slice *slice, - struct cl_io *io, __u32 enqflags); -int ccc_lock_use(const struct lu_env *env, const struct cl_lock_slice *slice); -int ccc_lock_unuse(const struct lu_env *env, const struct cl_lock_slice *slice); -int ccc_lock_wait(const struct lu_env *env, const struct cl_lock_slice *slice); -int ccc_lock_fits_into(const struct lu_env *env, - const struct cl_lock_slice *slice, - const struct cl_lock_descr *need, - const struct cl_io *io); -void ccc_lock_state(const struct lu_env *env, - const struct cl_lock_slice *slice, - enum cl_lock_state state); - + struct cl_io *io, struct cl_sync_io *anchor); int ccc_io_one_lock_index(const struct lu_env *env, struct cl_io *io, __u32 enqflags, enum cl_lock_mode mode, pgoff_t start, pgoff_t end); diff --git a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h index da8bc6eadd13..4318511de0c9 100644 --- a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h +++ b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h @@ -2582,6 +2582,8 @@ struct ldlm_extent { __u64 gid; }; +#define LDLM_GID_ANY ((__u64)-1) + static inline int ldlm_extent_overlap(struct ldlm_extent *ex1, struct ldlm_extent *ex2) { diff --git a/drivers/staging/lustre/lustre/include/lustre_dlm.h b/drivers/staging/lustre/lustre/include/lustre_dlm.h index 8b0364f71129..b1abdc28b261 100644 --- a/drivers/staging/lustre/lustre/include/lustre_dlm.h +++ b/drivers/staging/lustre/lustre/include/lustre_dlm.h @@ -71,6 +71,7 @@ struct obd_device; */ enum ldlm_error { ELDLM_OK = 0, + ELDLM_LOCK_MATCHED = 1, ELDLM_LOCK_CHANGED = 300, ELDLM_LOCK_ABORTED = 301, diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c index b497ce4f844a..7fedbec43ebf 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c @@ -748,6 +748,7 @@ int ldlm_error2errno(enum ldlm_error error) switch (error) { case ELDLM_OK: + case ELDLM_LOCK_MATCHED: result = 0; break; case ELDLM_LOCK_CHANGED: diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c index ecd65a7a3dc9..27a051b085b5 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c @@ -657,7 +657,7 @@ void ldlm_lock_addref(struct lustre_handle *lockh, __u32 mode) struct ldlm_lock *lock; lock = ldlm_handle2lock(lockh); - LASSERT(lock); + LASSERTF(lock, "Non-existing lock: %llx\n", lockh->cookie); ldlm_lock_addref_internal(lock, mode); LDLM_LOCK_PUT(lock); } @@ -1092,6 +1092,7 @@ static struct ldlm_lock *search_queue(struct list_head *queue, if (unlikely(match == LCK_GROUP) && lock->l_resource->lr_type == LDLM_EXTENT && + policy->l_extent.gid != LDLM_GID_ANY && lock->l_policy_data.l_extent.gid != policy->l_extent.gid) continue; diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c index d5968e01edd8..42925ac3331c 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c @@ -347,7 +347,6 @@ int ldlm_cli_enqueue_fini(struct obd_export *exp, struct ptlrpc_request *req, struct ldlm_lock *lock; struct ldlm_reply *reply; int cleanup_phase = 1; - int size = 0; lock = ldlm_handle2lock(lockh); /* ldlm_cli_enqueue is holding a reference on this lock. */ @@ -375,8 +374,8 @@ int ldlm_cli_enqueue_fini(struct obd_export *exp, struct ptlrpc_request *req, goto cleanup; } - if (lvb_len != 0) { - LASSERT(lvb); + if (lvb_len > 0) { + int size = 0; size = req_capsule_get_size(&req->rq_pill, &RMF_DLM_LVB, RCL_SERVER); @@ -390,12 +389,13 @@ int ldlm_cli_enqueue_fini(struct obd_export *exp, struct ptlrpc_request *req, rc = -EINVAL; goto cleanup; } + lvb_len = size; } if (rc == ELDLM_LOCK_ABORTED) { - if (lvb_len != 0) + if (lvb_len > 0 && lvb) rc = ldlm_fill_lvb(lock, &req->rq_pill, RCL_SERVER, - lvb, size); + lvb, lvb_len); if (rc == 0) rc = ELDLM_LOCK_ABORTED; goto cleanup; @@ -489,7 +489,7 @@ int ldlm_cli_enqueue_fini(struct obd_export *exp, struct ptlrpc_request *req, /* If the lock has already been granted by a completion AST, don't * clobber the LVB with an older one. */ - if (lvb_len != 0) { + if (lvb_len > 0) { /* We must lock or a racing completion might update lvb without * letting us know and we'll clobber the correct value. * Cannot unlock after the check either, as that still leaves @@ -498,7 +498,7 @@ int ldlm_cli_enqueue_fini(struct obd_export *exp, struct ptlrpc_request *req, lock_res_and_lock(lock); if (lock->l_req_mode != lock->l_granted_mode) rc = ldlm_fill_lvb(lock, &req->rq_pill, RCL_SERVER, - lock->l_lvb_data, size); + lock->l_lvb_data, lvb_len); unlock_res_and_lock(lock); if (rc < 0) { cleanup_phase = 1; @@ -518,7 +518,7 @@ int ldlm_cli_enqueue_fini(struct obd_export *exp, struct ptlrpc_request *req, } } - if (lvb_len && lvb) { + if (lvb_len > 0 && lvb) { /* Copy the LVB here, and not earlier, because the completion * AST (if any) can override what we got in the reply */ diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c index 9dede87ad0a3..242a6640bff6 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c @@ -1400,3 +1400,4 @@ void ldlm_resource_dump(int level, struct ldlm_resource *res) LDLM_DEBUG_LIMIT(level, lock, "###"); } } +EXPORT_SYMBOL(ldlm_resource_dump); diff --git a/drivers/staging/lustre/lustre/llite/glimpse.c b/drivers/staging/lustre/lustre/llite/glimpse.c index 9b0e2ec0cf05..0759dfc1995a 100644 --- a/drivers/staging/lustre/lustre/llite/glimpse.c +++ b/drivers/staging/lustre/lustre/llite/glimpse.c @@ -86,17 +86,17 @@ blkcnt_t dirty_cnt(struct inode *inode) int cl_glimpse_lock(const struct lu_env *env, struct cl_io *io, struct inode *inode, struct cl_object *clob, int agl) { - struct cl_lock_descr *descr = &ccc_env_info(env)->cti_descr; struct ll_inode_info *lli = ll_i2info(inode); const struct lu_fid *fid = lu_object_fid(&clob->co_lu); - struct ccc_io *cio = ccc_env_io(env); - struct cl_lock *lock; int result; result = 0; if (!(lli->lli_flags & LLIF_MDS_SIZE_LOCK)) { CDEBUG(D_DLMTRACE, "Glimpsing inode " DFID "\n", PFID(fid)); if (lli->lli_has_smd) { + struct cl_lock *lock = ccc_env_lock(env); + struct cl_lock_descr *descr = &lock->cll_descr; + /* NOTE: this looks like DLM lock request, but it may * not be one. Due to CEF_ASYNC flag (translated * to LDLM_FL_HAS_INTENT by osc), this is @@ -113,11 +113,10 @@ int cl_glimpse_lock(const struct lu_env *env, struct cl_io *io, */ *descr = whole_file; descr->cld_obj = clob; - descr->cld_mode = CLM_PHANTOM; + descr->cld_mode = CLM_READ; descr->cld_enq_flags = CEF_ASYNC | CEF_MUST; if (agl) descr->cld_enq_flags |= CEF_AGL; - cio->cui_glimpse = 1; /* * CEF_ASYNC is used because glimpse sub-locks cannot * deadlock (because they never conflict with other @@ -126,19 +125,11 @@ int cl_glimpse_lock(const struct lu_env *env, struct cl_io *io, * CEF_MUST protects glimpse lock from conversion into * a lockless mode. */ - lock = cl_lock_request(env, io, descr, "glimpse", - current); - cio->cui_glimpse = 0; - - if (!lock) - return 0; + result = cl_lock_request(env, io, lock); + if (result < 0) + return result; - if (IS_ERR(lock)) - return PTR_ERR(lock); - - LASSERT(agl == 0); - result = cl_wait(env, lock); - if (result == 0) { + if (!agl) { ll_merge_attr(env, inode); if (i_size_read(inode) > 0 && inode->i_blocks == 0) { @@ -150,9 +141,8 @@ int cl_glimpse_lock(const struct lu_env *env, struct cl_io *io, */ inode->i_blocks = dirty_cnt(inode); } - cl_unuse(env, lock); } - cl_lock_release(env, lock, "glimpse", current); + cl_lock_release(env, lock); } else { CDEBUG(D_DLMTRACE, "No objects for inode\n"); ll_merge_attr(env, inode); @@ -233,10 +223,7 @@ int cl_local_size(struct inode *inode) { struct lu_env *env = NULL; struct cl_io *io = NULL; - struct ccc_thread_info *cti; struct cl_object *clob; - struct cl_lock_descr *descr; - struct cl_lock *lock; int result; int refcheck; @@ -252,19 +239,15 @@ int cl_local_size(struct inode *inode) if (result > 0) { result = io->ci_result; } else if (result == 0) { - cti = ccc_env_info(env); - descr = &cti->cti_descr; + struct cl_lock *lock = ccc_env_lock(env); - *descr = whole_file; - descr->cld_obj = clob; - lock = cl_lock_peek(env, io, descr, "localsize", current); - if (lock) { + lock->cll_descr = whole_file; + lock->cll_descr.cld_enq_flags = CEF_PEEK; + lock->cll_descr.cld_obj = clob; + result = cl_lock_request(env, io, lock); + if (result == 0) { ll_merge_attr(env, inode); - cl_unuse(env, lock); - cl_lock_release(env, lock, "localsize", current); - result = 0; - } else { - result = -ENODATA; + cl_lock_release(env, lock); } } cl_io_fini(env, io); diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c b/drivers/staging/lustre/lustre/llite/lcommon_cl.c index fde96d374f49..b339d1bfc5c4 100644 --- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c +++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c @@ -475,12 +475,6 @@ int ccc_transient_page_prep(const struct lu_env *env, * */ -void ccc_lock_delete(const struct lu_env *env, - const struct cl_lock_slice *slice) -{ - CLOBINVRNT(env, slice->cls_obj, ccc_object_invariant(slice->cls_obj)); -} - void ccc_lock_fini(const struct lu_env *env, struct cl_lock_slice *slice) { struct ccc_lock *clk = cl2ccc_lock(slice); @@ -490,111 +484,12 @@ void ccc_lock_fini(const struct lu_env *env, struct cl_lock_slice *slice) int ccc_lock_enqueue(const struct lu_env *env, const struct cl_lock_slice *slice, - struct cl_io *unused, __u32 enqflags) -{ - CLOBINVRNT(env, slice->cls_obj, ccc_object_invariant(slice->cls_obj)); - return 0; -} - -int ccc_lock_use(const struct lu_env *env, const struct cl_lock_slice *slice) -{ - CLOBINVRNT(env, slice->cls_obj, ccc_object_invariant(slice->cls_obj)); - return 0; -} - -int ccc_lock_unuse(const struct lu_env *env, const struct cl_lock_slice *slice) + struct cl_io *unused, struct cl_sync_io *anchor) { CLOBINVRNT(env, slice->cls_obj, ccc_object_invariant(slice->cls_obj)); return 0; } -int ccc_lock_wait(const struct lu_env *env, const struct cl_lock_slice *slice) -{ - CLOBINVRNT(env, slice->cls_obj, ccc_object_invariant(slice->cls_obj)); - return 0; -} - -/** - * Implementation of cl_lock_operations::clo_fits_into() methods for ccc - * layer. This function is executed every time io finds an existing lock in - * the lock cache while creating new lock. This function has to decide whether - * cached lock "fits" into io. - * - * \param slice lock to be checked - * \param io IO that wants a lock. - * - * \see lov_lock_fits_into(). - */ -int ccc_lock_fits_into(const struct lu_env *env, - const struct cl_lock_slice *slice, - const struct cl_lock_descr *need, - const struct cl_io *io) -{ - const struct cl_lock *lock = slice->cls_lock; - const struct cl_lock_descr *descr = &lock->cll_descr; - const struct ccc_io *cio = ccc_env_io(env); - int result; - - /* - * Work around DLM peculiarity: it assumes that glimpse - * (LDLM_FL_HAS_INTENT) lock is always LCK_PR, and returns reads lock - * when asked for LCK_PW lock with LDLM_FL_HAS_INTENT flag set. Make - * sure that glimpse doesn't get CLM_WRITE top-lock, so that it - * doesn't enqueue CLM_WRITE sub-locks. - */ - if (cio->cui_glimpse) - result = descr->cld_mode != CLM_WRITE; - - /* - * Also, don't match incomplete write locks for read, otherwise read - * would enqueue missing sub-locks in the write mode. - */ - else if (need->cld_mode != descr->cld_mode) - result = lock->cll_state >= CLS_ENQUEUED; - else - result = 1; - return result; -} - -/** - * Implements cl_lock_operations::clo_state() method for ccc layer, invoked - * whenever lock state changes. Transfers object attributes, that might be - * updated as a result of lock acquiring into inode. - */ -void ccc_lock_state(const struct lu_env *env, - const struct cl_lock_slice *slice, - enum cl_lock_state state) -{ - struct cl_lock *lock = slice->cls_lock; - - /* - * Refresh inode attributes when the lock is moving into CLS_HELD - * state, and only when this is a result of real enqueue, rather than - * of finding lock in the cache. - */ - if (state == CLS_HELD && lock->cll_state < CLS_HELD) { - struct cl_object *obj; - struct inode *inode; - - obj = slice->cls_obj; - inode = ccc_object_inode(obj); - - /* vmtruncate() sets the i_size - * under both a DLM lock and the - * ll_inode_size_lock(). If we don't get the - * ll_inode_size_lock() here we can match the DLM lock and - * reset i_size. generic_file_write can then trust the - * stale i_size when doing appending writes and effectively - * cancel the result of the truncate. Getting the - * ll_inode_size_lock() after the enqueue maintains the DLM - * -> ll_inode_size_lock() acquiring order. - */ - if (lock->cll_descr.cld_start == 0 && - lock->cll_descr.cld_end == CL_PAGE_EOF) - ll_merge_attr(env, inode); - } -} - /***************************************************************************** * * io operations. diff --git a/drivers/staging/lustre/lustre/llite/lcommon_misc.c b/drivers/staging/lustre/lustre/llite/lcommon_misc.c index f68c3687b1d9..4c12e219ffcc 100644 --- a/drivers/staging/lustre/lustre/llite/lcommon_misc.c +++ b/drivers/staging/lustre/lustre/llite/lcommon_misc.c @@ -145,7 +145,7 @@ int cl_get_grouplock(struct cl_object *obj, unsigned long gid, int nonblock, io->ci_ignore_layout = 1; rc = cl_io_init(env, io, CIT_MISC, io->ci_obj); - if (rc) { + if (rc != 0) { cl_io_fini(env, io); cl_env_put(env, &refcheck); /* Does not make sense to take GL for released layout */ @@ -154,7 +154,8 @@ int cl_get_grouplock(struct cl_object *obj, unsigned long gid, int nonblock, return rc; } - descr = &ccc_env_info(env)->cti_descr; + lock = ccc_env_lock(env); + descr = &lock->cll_descr; descr->cld_obj = obj; descr->cld_start = 0; descr->cld_end = CL_PAGE_EOF; @@ -164,11 +165,11 @@ int cl_get_grouplock(struct cl_object *obj, unsigned long gid, int nonblock, enqflags = CEF_MUST | (nonblock ? CEF_NONBLOCK : 0); descr->cld_enq_flags = enqflags; - lock = cl_lock_request(env, io, descr, GROUPLOCK_SCOPE, current); - if (IS_ERR(lock)) { + rc = cl_lock_request(env, io, lock); + if (rc < 0) { cl_io_fini(env, io); cl_env_put(env, &refcheck); - return PTR_ERR(lock); + return rc; } cg->cg_env = cl_env_get(&refcheck); @@ -194,8 +195,7 @@ void cl_put_grouplock(struct ccc_grouplock *cg) cl_env_implant(env, &refcheck); cl_env_put(env, &refcheck); - cl_unuse(env, lock); - cl_lock_release(env, lock, GROUPLOCK_SCOPE, current); + cl_lock_release(env, lock); cl_io_fini(env, io); cl_env_put(env, NULL); } diff --git a/drivers/staging/lustre/lustre/llite/rw26.c b/drivers/staging/lustre/lustre/llite/rw26.c index e2fea8c7a4fe..50d8289afe06 100644 --- a/drivers/staging/lustre/lustre/llite/rw26.c +++ b/drivers/staging/lustre/lustre/llite/rw26.c @@ -150,8 +150,7 @@ static int ll_releasepage(struct page *vmpage, gfp_t gfp_mask) * If this page holds the last refc of cl_object, the following * call path may cause reschedule: * cl_page_put -> cl_page_free -> cl_object_put -> - * lu_object_put -> lu_object_free -> lov_delete_raid0 -> - * cl_locks_prune. + * lu_object_put -> lu_object_free -> lov_delete_raid0. * * However, the kernel can't get rid of this inode until all pages have * been cleaned up. Now that we hold page lock here, it's pretty safe diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c index c7db318b8ece..fb6f93225b99 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_io.c +++ b/drivers/staging/lustre/lustre/llite/vvp_io.c @@ -233,7 +233,7 @@ static int vvp_mmap_locks(const struct lu_env *env, ldlm_policy_data_t policy; unsigned long addr; ssize_t count; - int result; + int result = 0; struct iov_iter i; struct iovec iov; @@ -265,10 +265,10 @@ static int vvp_mmap_locks(const struct lu_env *env, if (ll_file_nolock(vma->vm_file)) { /* - * For no lock case, a lockless lock will be - * generated. + * For no lock case is not allowed for mmap */ - flags = CEF_NEVER; + result = -EINVAL; + break; } /* @@ -290,10 +290,8 @@ static int vvp_mmap_locks(const struct lu_env *env, descr->cld_mode, descr->cld_start, descr->cld_end); - if (result < 0) { - up_read(&mm->mmap_sem); - return result; - } + if (result < 0) + break; if (vma->vm_end - addr >= count) break; @@ -302,8 +300,10 @@ static int vvp_mmap_locks(const struct lu_env *env, addr = vma->vm_end; } up_read(&mm->mmap_sem); + if (result < 0) + break; } - return 0; + return result; } static int vvp_io_rw_lock(const struct lu_env *env, struct cl_io *io, @@ -781,6 +781,7 @@ static int vvp_io_write_start(const struct lu_env *env, * PARALLEL IO This has to be changed for parallel IO doing * out-of-order writes. */ + ll_merge_attr(env, inode); pos = io->u.ci_wr.wr.crw_pos = i_size_read(inode); cio->cui_iocb->ki_pos = pos; } else { diff --git a/drivers/staging/lustre/lustre/llite/vvp_lock.c b/drivers/staging/lustre/lustre/llite/vvp_lock.c index ff0948043c7a..8c505a6052b2 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_lock.c +++ b/drivers/staging/lustre/lustre/llite/vvp_lock.c @@ -51,32 +51,9 @@ * */ -/** - * Estimates lock value for the purpose of managing the lock cache during - * memory shortages. - * - * Locks for memory mapped files are almost infinitely precious, others are - * junk. "Mapped locks" are heavy, but not infinitely heavy, so that they are - * ordered within themselves by weights assigned from other layers. - */ -static unsigned long vvp_lock_weigh(const struct lu_env *env, - const struct cl_lock_slice *slice) -{ - struct ccc_object *cob = cl2ccc(slice->cls_obj); - - return atomic_read(&cob->cob_mmap_cnt) > 0 ? ~0UL >> 2 : 0; -} - static const struct cl_lock_operations vvp_lock_ops = { - .clo_delete = ccc_lock_delete, .clo_fini = ccc_lock_fini, - .clo_enqueue = ccc_lock_enqueue, - .clo_wait = ccc_lock_wait, - .clo_use = ccc_lock_use, - .clo_unuse = ccc_lock_unuse, - .clo_fits_into = ccc_lock_fits_into, - .clo_state = ccc_lock_state, - .clo_weigh = vvp_lock_weigh + .clo_enqueue = ccc_lock_enqueue }; int vvp_lock_init(const struct lu_env *env, struct cl_object *obj, diff --git a/drivers/staging/lustre/lustre/llite/vvp_object.c b/drivers/staging/lustre/lustre/llite/vvp_object.c index d03eb2b59de7..34210dbc8cd2 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_object.c +++ b/drivers/staging/lustre/lustre/llite/vvp_object.c @@ -170,11 +170,15 @@ static int vvp_prune(const struct lu_env *env, struct cl_object *obj) struct inode *inode = ccc_object_inode(obj); int rc; - rc = cl_sync_file_range(inode, 0, OBD_OBJECT_EOF, CL_FSYNC_ALL, 1); - if (rc == 0) - truncate_inode_pages(inode->i_mapping, 0); + rc = cl_sync_file_range(inode, 0, OBD_OBJECT_EOF, CL_FSYNC_LOCAL, 1); + if (rc < 0) { + CDEBUG(D_VFSTRACE, DFID ": writeback failed: %d\n", + PFID(lu_object_fid(&obj->co_lu)), rc); + return rc; + } - return rc; + truncate_inode_pages(inode->i_mapping, 0); + return 0; } static const struct cl_object_operations vvp_ops = { diff --git a/drivers/staging/lustre/lustre/lov/lov_cl_internal.h b/drivers/staging/lustre/lustre/lov/lov_cl_internal.h index 9b3d13bf2a46..dfe41a82bdd2 100644 --- a/drivers/staging/lustre/lustre/lov/lov_cl_internal.h +++ b/drivers/staging/lustre/lustre/lov/lov_cl_internal.h @@ -280,25 +280,18 @@ struct lov_object { struct task_struct *lo_owner; }; -/** - * Flags that top-lock can set on each of its sub-locks. - */ -enum lov_sub_flags { - /** Top-lock acquired a hold (cl_lock_hold()) on a sub-lock. */ - LSF_HELD = 1 << 0 -}; - /** * State lov_lock keeps for each sub-lock. */ struct lov_lock_sub { /** sub-lock itself */ - struct lovsub_lock *sub_lock; - /** An array of per-sub-lock flags, taken from enum lov_sub_flags */ - unsigned sub_flags; + struct cl_lock sub_lock; + /** Set if the sublock has ever been enqueued, meaning it may + * hold resources of underlying layers + */ + unsigned int sub_is_enqueued:1, + sub_initialized:1; int sub_stripe; - struct cl_lock_descr sub_descr; - struct cl_lock_descr sub_got; }; /** @@ -308,59 +301,8 @@ struct lov_lock { struct cl_lock_slice lls_cl; /** Number of sub-locks in this lock */ int lls_nr; - /** - * Number of existing sub-locks. - */ - unsigned lls_nr_filled; - /** - * Set when sub-lock was canceled, while top-lock was being - * used, or unused. - */ - unsigned int lls_cancel_race:1; - /** - * An array of sub-locks - * - * There are two issues with managing sub-locks: - * - * - sub-locks are concurrently canceled, and - * - * - sub-locks are shared with other top-locks. - * - * To manage cancellation, top-lock acquires a hold on a sublock - * (lov_sublock_adopt()) when the latter is inserted into - * lov_lock::lls_sub[]. This hold is released (lov_sublock_release()) - * when top-lock is going into CLS_CACHED state or destroyed. Hold - * prevents sub-lock from cancellation. - * - * Sub-lock sharing means, among other things, that top-lock that is - * in the process of creation (i.e., not yet inserted into lock list) - * is already accessible to other threads once at least one of its - * sub-locks is created, see lov_lock_sub_init(). - * - * Sub-lock can be in one of the following states: - * - * - doesn't exist, lov_lock::lls_sub[]::sub_lock == NULL. Such - * sub-lock was either never created (top-lock is in CLS_NEW - * state), or it was created, then canceled, then destroyed - * (lov_lock_unlink() cleared sub-lock pointer in the top-lock). - * - * - sub-lock exists and is on - * hold. (lov_lock::lls_sub[]::sub_flags & LSF_HELD). This is a - * normal state of a sub-lock in CLS_HELD and CLS_CACHED states - * of a top-lock. - * - * - sub-lock exists, but is not held by the top-lock. This - * happens after top-lock released a hold on sub-locks before - * going into cache (lov_lock_unuse()). - * - * \todo To support wide-striping, array has to be replaced with a set - * of queues to avoid scanning. - */ - struct lov_lock_sub *lls_sub; - /** - * Original description with which lock was enqueued. - */ - struct cl_lock_descr lls_orig; + /** sublock array */ + struct lov_lock_sub lls_sub[0]; }; struct lov_page { @@ -445,7 +387,6 @@ struct lov_thread_info { struct ost_lvb lti_lvb; struct cl_2queue lti_cl2q; struct cl_page_list lti_plist; - struct cl_lock_closure lti_closure; wait_queue_t lti_waiter; struct cl_attr lti_attr; }; diff --git a/drivers/staging/lustre/lustre/lov/lov_dev.c b/drivers/staging/lustre/lustre/lov/lov_dev.c index 532ef87dfb44..dccc63496982 100644 --- a/drivers/staging/lustre/lustre/lov/lov_dev.c +++ b/drivers/staging/lustre/lustre/lov/lov_dev.c @@ -143,9 +143,7 @@ static void *lov_key_init(const struct lu_context *ctx, struct lov_thread_info *info; info = kmem_cache_zalloc(lov_thread_kmem, GFP_NOFS); - if (info) - INIT_LIST_HEAD(&info->lti_closure.clc_list); - else + if (!info) info = ERR_PTR(-ENOMEM); return info; } @@ -155,7 +153,6 @@ static void lov_key_fini(const struct lu_context *ctx, { struct lov_thread_info *info = data; - LINVRNT(list_empty(&info->lti_closure.clc_list)); kmem_cache_free(lov_thread_kmem, info); } diff --git a/drivers/staging/lustre/lustre/lov/lov_lock.c b/drivers/staging/lustre/lustre/lov/lov_lock.c index ae854bc25dbe..1b203d18c6e9 100644 --- a/drivers/staging/lustre/lustre/lov/lov_lock.c +++ b/drivers/staging/lustre/lustre/lov/lov_lock.c @@ -46,11 +46,6 @@ * @{ */ -static struct cl_lock_closure *lov_closure_get(const struct lu_env *env, - struct cl_lock *parent); - -static int lov_lock_unuse(const struct lu_env *env, - const struct cl_lock_slice *slice); /***************************************************************************** * * Lov lock operations. @@ -58,7 +53,7 @@ static int lov_lock_unuse(const struct lu_env *env, */ static struct lov_sublock_env *lov_sublock_env_get(const struct lu_env *env, - struct cl_lock *parent, + const struct cl_lock *parent, struct lov_lock_sub *lls) { struct lov_sublock_env *subenv; @@ -100,184 +95,25 @@ static void lov_sublock_env_put(struct lov_sublock_env *subenv) lov_sub_put(subenv->lse_sub); } -static void lov_sublock_adopt(const struct lu_env *env, struct lov_lock *lck, - struct cl_lock *sublock, int idx, - struct lov_lock_link *link) +static int lov_sublock_init(const struct lu_env *env, + const struct cl_lock *parent, + struct lov_lock_sub *lls) { - struct lovsub_lock *lsl; - struct cl_lock *parent = lck->lls_cl.cls_lock; - int rc; - - LASSERT(cl_lock_is_mutexed(parent)); - LASSERT(cl_lock_is_mutexed(sublock)); - - lsl = cl2sub_lock(sublock); - /* - * check that sub-lock doesn't have lock link to this top-lock. - */ - LASSERT(!lov_lock_link_find(env, lck, lsl)); - LASSERT(idx < lck->lls_nr); - - lck->lls_sub[idx].sub_lock = lsl; - lck->lls_nr_filled++; - LASSERT(lck->lls_nr_filled <= lck->lls_nr); - list_add_tail(&link->lll_list, &lsl->lss_parents); - link->lll_idx = idx; - link->lll_super = lck; - cl_lock_get(parent); - lu_ref_add(&parent->cll_reference, "lov-child", sublock); - lck->lls_sub[idx].sub_flags |= LSF_HELD; - cl_lock_user_add(env, sublock); - - rc = lov_sublock_modify(env, lck, lsl, &sublock->cll_descr, idx); - LASSERT(rc == 0); /* there is no way this can fail, currently */ -} - -static struct cl_lock *lov_sublock_alloc(const struct lu_env *env, - const struct cl_io *io, - struct lov_lock *lck, - int idx, struct lov_lock_link **out) -{ - struct cl_lock *sublock; - struct cl_lock *parent; - struct lov_lock_link *link; - - LASSERT(idx < lck->lls_nr); - - link = kmem_cache_zalloc(lov_lock_link_kmem, GFP_NOFS); - if (link) { - struct lov_sublock_env *subenv; - struct lov_lock_sub *lls; - struct cl_lock_descr *descr; - - parent = lck->lls_cl.cls_lock; - lls = &lck->lls_sub[idx]; - descr = &lls->sub_got; - - subenv = lov_sublock_env_get(env, parent, lls); - if (!IS_ERR(subenv)) { - /* CAVEAT: Don't try to add a field in lov_lock_sub - * to remember the subio. This is because lock is able - * to be cached, but this is not true for IO. This - * further means a sublock might be referenced in - * different io context. -jay - */ - - sublock = cl_lock_hold(subenv->lse_env, subenv->lse_io, - descr, "lov-parent", parent); - lov_sublock_env_put(subenv); - } else { - /* error occurs. */ - sublock = (void *)subenv; - } - - if (!IS_ERR(sublock)) - *out = link; - else - kmem_cache_free(lov_lock_link_kmem, link); - } else - sublock = ERR_PTR(-ENOMEM); - return sublock; -} - -static void lov_sublock_unlock(const struct lu_env *env, - struct lovsub_lock *lsl, - struct cl_lock_closure *closure, - struct lov_sublock_env *subenv) -{ - lov_sublock_env_put(subenv); - lsl->lss_active = NULL; - cl_lock_disclosure(env, closure); -} - -static int lov_sublock_lock(const struct lu_env *env, - struct lov_lock *lck, - struct lov_lock_sub *lls, - struct cl_lock_closure *closure, - struct lov_sublock_env **lsep) -{ - struct lovsub_lock *sublock; - struct cl_lock *child; - int result = 0; - - LASSERT(list_empty(&closure->clc_list)); - - sublock = lls->sub_lock; - child = sublock->lss_cl.cls_lock; - result = cl_lock_closure_build(env, child, closure); - if (result == 0) { - struct cl_lock *parent = closure->clc_origin; - - LASSERT(cl_lock_is_mutexed(child)); - sublock->lss_active = parent; - - if (unlikely((child->cll_state == CLS_FREEING) || - (child->cll_flags & CLF_CANCELLED))) { - struct lov_lock_link *link; - /* - * we could race with lock deletion which temporarily - * put the lock in freeing state, bug 19080. - */ - LASSERT(!(lls->sub_flags & LSF_HELD)); - - link = lov_lock_link_find(env, lck, sublock); - LASSERT(link); - lov_lock_unlink(env, link, sublock); - lov_sublock_unlock(env, sublock, closure, NULL); - lck->lls_cancel_race = 1; - result = CLO_REPEAT; - } else if (lsep) { - struct lov_sublock_env *subenv; + struct lov_sublock_env *subenv; + int result; - subenv = lov_sublock_env_get(env, parent, lls); - if (IS_ERR(subenv)) { - lov_sublock_unlock(env, sublock, - closure, NULL); - result = PTR_ERR(subenv); - } else { - *lsep = subenv; - } - } + subenv = lov_sublock_env_get(env, parent, lls); + if (!IS_ERR(subenv)) { + result = cl_lock_init(subenv->lse_env, &lls->sub_lock, + subenv->lse_io); + lov_sublock_env_put(subenv); + } else { + /* error occurs. */ + result = PTR_ERR(subenv); } return result; } -/** - * Updates the result of a top-lock operation from a result of sub-lock - * sub-operations. Top-operations like lov_lock_{enqueue,use,unuse}() iterate - * over sub-locks and lov_subresult() is used to calculate return value of a - * top-operation. To this end, possible return values of sub-operations are - * ordered as - * - * - 0 success - * - CLO_WAIT wait for event - * - CLO_REPEAT repeat top-operation - * - -ne fundamental error - * - * Top-level return code can only go down through this list. CLO_REPEAT - * overwrites CLO_WAIT, because lock mutex was released and sleeping condition - * has to be rechecked by the upper layer. - */ -static int lov_subresult(int result, int rc) -{ - int result_rank; - int rc_rank; - - LASSERTF(result <= 0 || result == CLO_REPEAT || result == CLO_WAIT, - "result = %d\n", result); - LASSERTF(rc <= 0 || rc == CLO_REPEAT || rc == CLO_WAIT, - "rc = %d\n", rc); - CLASSERT(CLO_WAIT < CLO_REPEAT); - - /* calculate ranks in the ordering above */ - result_rank = result < 0 ? 1 + CLO_REPEAT : result; - rc_rank = rc < 0 ? 1 + CLO_REPEAT : rc; - - if (result_rank < rc_rank) - result = rc; - return result; -} - /** * Creates sub-locks for a given lov_lock for the first time. * @@ -286,8 +122,9 @@ static int lov_subresult(int result, int rc) * fact that top-lock (that is being created) can be accessed concurrently * through already created sub-locks (possibly shared with other top-locks). */ -static int lov_lock_sub_init(const struct lu_env *env, - struct lov_lock *lck, const struct cl_io *io) +static struct lov_lock *lov_lock_sub_init(const struct lu_env *env, + const struct cl_object *obj, + struct cl_lock *lock) { int result = 0; int i; @@ -297,241 +134,86 @@ static int lov_lock_sub_init(const struct lu_env *env, u64 file_start; u64 file_end; - struct lov_object *loo = cl2lov(lck->lls_cl.cls_obj); + struct lov_object *loo = cl2lov(obj); struct lov_layout_raid0 *r0 = lov_r0(loo); - struct cl_lock *parent = lck->lls_cl.cls_lock; + struct lov_lock *lovlck; - lck->lls_orig = parent->cll_descr; - file_start = cl_offset(lov2cl(loo), parent->cll_descr.cld_start); - file_end = cl_offset(lov2cl(loo), parent->cll_descr.cld_end + 1) - 1; + file_start = cl_offset(lov2cl(loo), lock->cll_descr.cld_start); + file_end = cl_offset(lov2cl(loo), lock->cll_descr.cld_end + 1) - 1; for (i = 0, nr = 0; i < r0->lo_nr; i++) { /* * XXX for wide striping smarter algorithm is desirable, * breaking out of the loop, early. */ - if (likely(r0->lo_sub[i]) && + if (likely(r0->lo_sub[i]) && /* spare layout */ lov_stripe_intersects(loo->lo_lsm, i, file_start, file_end, &start, &end)) nr++; } LASSERT(nr > 0); - lck->lls_sub = libcfs_kvzalloc(nr * sizeof(lck->lls_sub[0]), GFP_NOFS); - if (!lck->lls_sub) - return -ENOMEM; + lovlck = libcfs_kvzalloc(offsetof(struct lov_lock, lls_sub[nr]), + GFP_NOFS); + if (!lovlck) + return ERR_PTR(-ENOMEM); - lck->lls_nr = nr; - /* - * First, fill in sub-lock descriptions in - * lck->lls_sub[].sub_descr. They are used by lov_sublock_alloc() - * (called below in this function, and by lov_lock_enqueue()) to - * create sub-locks. At this moment, no other thread can access - * top-lock. - */ + lovlck->lls_nr = nr; for (i = 0, nr = 0; i < r0->lo_nr; ++i) { if (likely(r0->lo_sub[i]) && lov_stripe_intersects(loo->lo_lsm, i, file_start, file_end, &start, &end)) { + struct lov_lock_sub *lls = &lovlck->lls_sub[nr]; struct cl_lock_descr *descr; - descr = &lck->lls_sub[nr].sub_descr; + descr = &lls->sub_lock.cll_descr; LASSERT(!descr->cld_obj); descr->cld_obj = lovsub2cl(r0->lo_sub[i]); descr->cld_start = cl_index(descr->cld_obj, start); descr->cld_end = cl_index(descr->cld_obj, end); - descr->cld_mode = parent->cll_descr.cld_mode; - descr->cld_gid = parent->cll_descr.cld_gid; - descr->cld_enq_flags = parent->cll_descr.cld_enq_flags; - /* XXX has no effect */ - lck->lls_sub[nr].sub_got = *descr; - lck->lls_sub[nr].sub_stripe = i; + descr->cld_mode = lock->cll_descr.cld_mode; + descr->cld_gid = lock->cll_descr.cld_gid; + descr->cld_enq_flags = lock->cll_descr.cld_enq_flags; + lls->sub_stripe = i; + + /* initialize sub lock */ + result = lov_sublock_init(env, lock, lls); + if (result < 0) + break; + + lls->sub_initialized = 1; nr++; } } - LASSERT(nr == lck->lls_nr); - - /* - * Some sub-locks can be missing at this point. This is not a problem, - * because enqueue will create them anyway. Main duty of this function - * is to fill in sub-lock descriptions in a race free manner. - */ - return result; -} + LASSERT(ergo(result == 0, nr == lovlck->lls_nr)); -static int lov_sublock_release(const struct lu_env *env, struct lov_lock *lck, - int i, int deluser, int rc) -{ - struct cl_lock *parent = lck->lls_cl.cls_lock; - - LASSERT(cl_lock_is_mutexed(parent)); - - if (lck->lls_sub[i].sub_flags & LSF_HELD) { - struct cl_lock *sublock; - int dying; - - sublock = lck->lls_sub[i].sub_lock->lss_cl.cls_lock; - LASSERT(cl_lock_is_mutexed(sublock)); + if (result != 0) { + for (i = 0; i < nr; ++i) { + if (!lovlck->lls_sub[i].sub_initialized) + break; - lck->lls_sub[i].sub_flags &= ~LSF_HELD; - if (deluser) - cl_lock_user_del(env, sublock); - /* - * If the last hold is released, and cancellation is pending - * for a sub-lock, release parent mutex, to avoid keeping it - * while sub-lock is being paged out. - */ - dying = (sublock->cll_descr.cld_mode == CLM_PHANTOM || - sublock->cll_descr.cld_mode == CLM_GROUP || - (sublock->cll_flags & (CLF_CANCELPEND|CLF_DOOMED))) && - sublock->cll_holds == 1; - if (dying) - cl_lock_mutex_put(env, parent); - cl_lock_unhold(env, sublock, "lov-parent", parent); - if (dying) { - cl_lock_mutex_get(env, parent); - rc = lov_subresult(rc, CLO_REPEAT); + cl_lock_fini(env, &lovlck->lls_sub[i].sub_lock); } - /* - * From now on lck->lls_sub[i].sub_lock is a "weak" pointer, - * not backed by a reference on a - * sub-lock. lovsub_lock_delete() will clear - * lck->lls_sub[i].sub_lock under semaphores, just before - * sub-lock is destroyed. - */ + kvfree(lovlck); + lovlck = ERR_PTR(result); } - return rc; -} - -static void lov_sublock_hold(const struct lu_env *env, struct lov_lock *lck, - int i) -{ - struct cl_lock *parent = lck->lls_cl.cls_lock; - - LASSERT(cl_lock_is_mutexed(parent)); - - if (!(lck->lls_sub[i].sub_flags & LSF_HELD)) { - struct cl_lock *sublock; - - sublock = lck->lls_sub[i].sub_lock->lss_cl.cls_lock; - LASSERT(cl_lock_is_mutexed(sublock)); - LASSERT(sublock->cll_state != CLS_FREEING); - lck->lls_sub[i].sub_flags |= LSF_HELD; - - cl_lock_get_trust(sublock); - cl_lock_hold_add(env, sublock, "lov-parent", parent); - cl_lock_user_add(env, sublock); - cl_lock_put(env, sublock); - } + return lovlck; } static void lov_lock_fini(const struct lu_env *env, struct cl_lock_slice *slice) { - struct lov_lock *lck; + struct lov_lock *lovlck; int i; - lck = cl2lov_lock(slice); - LASSERT(lck->lls_nr_filled == 0); - if (lck->lls_sub) { - for (i = 0; i < lck->lls_nr; ++i) - /* - * No sub-locks exists at this point, as sub-lock has - * a reference on its parent. - */ - LASSERT(!lck->lls_sub[i].sub_lock); - kvfree(lck->lls_sub); + lovlck = cl2lov_lock(slice); + for (i = 0; i < lovlck->lls_nr; ++i) { + LASSERT(!lovlck->lls_sub[i].sub_is_enqueued); + if (lovlck->lls_sub[i].sub_initialized) + cl_lock_fini(env, &lovlck->lls_sub[i].sub_lock); } - kmem_cache_free(lov_lock_kmem, lck); -} - -static int lov_lock_enqueue_wait(const struct lu_env *env, - struct lov_lock *lck, - struct cl_lock *sublock) -{ - struct cl_lock *lock = lck->lls_cl.cls_lock; - int result; - - LASSERT(cl_lock_is_mutexed(lock)); - - cl_lock_mutex_put(env, lock); - result = cl_lock_enqueue_wait(env, sublock, 0); - cl_lock_mutex_get(env, lock); - return result ?: CLO_REPEAT; -} - -/** - * Tries to advance a state machine of a given sub-lock toward enqueuing of - * the top-lock. - * - * \retval 0 if state-transition can proceed - * \retval -ve otherwise. - */ -static int lov_lock_enqueue_one(const struct lu_env *env, struct lov_lock *lck, - struct cl_lock *sublock, - struct cl_io *io, __u32 enqflags, int last) -{ - int result; - - /* first, try to enqueue a sub-lock ... */ - result = cl_enqueue_try(env, sublock, io, enqflags); - if ((sublock->cll_state == CLS_ENQUEUED) && !(enqflags & CEF_AGL)) { - /* if it is enqueued, try to `wait' on it---maybe it's already - * granted - */ - result = cl_wait_try(env, sublock); - if (result == CLO_REENQUEUED) - result = CLO_WAIT; - } - /* - * If CEF_ASYNC flag is set, then all sub-locks can be enqueued in - * parallel, otherwise---enqueue has to wait until sub-lock is granted - * before proceeding to the next one. - */ - if ((result == CLO_WAIT) && (sublock->cll_state <= CLS_HELD) && - (enqflags & CEF_ASYNC) && (!last || (enqflags & CEF_AGL))) - result = 0; - return result; -} - -/** - * Helper function for lov_lock_enqueue() that creates missing sub-lock. - */ -static int lov_sublock_fill(const struct lu_env *env, struct cl_lock *parent, - struct cl_io *io, struct lov_lock *lck, int idx) -{ - struct lov_lock_link *link = NULL; - struct cl_lock *sublock; - int result; - - LASSERT(parent->cll_depth == 1); - cl_lock_mutex_put(env, parent); - sublock = lov_sublock_alloc(env, io, lck, idx, &link); - if (!IS_ERR(sublock)) - cl_lock_mutex_get(env, sublock); - cl_lock_mutex_get(env, parent); - - if (!IS_ERR(sublock)) { - cl_lock_get_trust(sublock); - if (parent->cll_state == CLS_QUEUING && - !lck->lls_sub[idx].sub_lock) { - lov_sublock_adopt(env, lck, sublock, idx, link); - } else { - kmem_cache_free(lov_lock_link_kmem, link); - /* other thread allocated sub-lock, or enqueue is no - * longer going on - */ - cl_lock_mutex_put(env, parent); - cl_lock_unhold(env, sublock, "lov-parent", parent); - cl_lock_mutex_get(env, parent); - } - cl_lock_mutex_put(env, sublock); - cl_lock_put(env, sublock); - result = CLO_REPEAT; - } else - result = PTR_ERR(sublock); - return result; + kvfree(lovlck); } /** @@ -543,529 +225,59 @@ static int lov_sublock_fill(const struct lu_env *env, struct cl_lock *parent, */ static int lov_lock_enqueue(const struct lu_env *env, const struct cl_lock_slice *slice, - struct cl_io *io, __u32 enqflags) + struct cl_io *io, struct cl_sync_io *anchor) { - struct cl_lock *lock = slice->cls_lock; - struct lov_lock *lck = cl2lov_lock(slice); - struct cl_lock_closure *closure = lov_closure_get(env, lock); + struct cl_lock *lock = slice->cls_lock; + struct lov_lock *lovlck = cl2lov_lock(slice); int i; - int result; - enum cl_lock_state minstate; + int rc = 0; - for (result = 0, minstate = CLS_FREEING, i = 0; i < lck->lls_nr; ++i) { - int rc; - struct lovsub_lock *sub; - struct lov_lock_sub *lls; - struct cl_lock *sublock; + for (i = 0; i < lovlck->lls_nr; ++i) { + struct lov_lock_sub *lls = &lovlck->lls_sub[i]; struct lov_sublock_env *subenv; - if (lock->cll_state != CLS_QUEUING) { - /* - * Lock might have left QUEUING state if previous - * iteration released its mutex. Stop enqueing in this - * case and let the upper layer to decide what to do. - */ - LASSERT(i > 0 && result != 0); - break; - } - - lls = &lck->lls_sub[i]; - sub = lls->sub_lock; - /* - * Sub-lock might have been canceled, while top-lock was - * cached. - */ - if (!sub) { - result = lov_sublock_fill(env, lock, io, lck, i); - /* lov_sublock_fill() released @lock mutex, - * restart. - */ + subenv = lov_sublock_env_get(env, lock, lls); + if (IS_ERR(subenv)) { + rc = PTR_ERR(subenv); break; } - sublock = sub->lss_cl.cls_lock; - rc = lov_sublock_lock(env, lck, lls, closure, &subenv); - if (rc == 0) { - lov_sublock_hold(env, lck, i); - rc = lov_lock_enqueue_one(subenv->lse_env, lck, sublock, - subenv->lse_io, enqflags, - i == lck->lls_nr - 1); - minstate = min(minstate, sublock->cll_state); - if (rc == CLO_WAIT) { - switch (sublock->cll_state) { - case CLS_QUEUING: - /* take recursive mutex, the lock is - * released in lov_lock_enqueue_wait. - */ - cl_lock_mutex_get(env, sublock); - lov_sublock_unlock(env, sub, closure, - subenv); - rc = lov_lock_enqueue_wait(env, lck, - sublock); - break; - case CLS_CACHED: - cl_lock_get(sublock); - /* take recursive mutex of sublock */ - cl_lock_mutex_get(env, sublock); - /* need to release all locks in closure - * otherwise it may deadlock. LU-2683. - */ - lov_sublock_unlock(env, sub, closure, - subenv); - /* sublock and parent are held. */ - rc = lov_sublock_release(env, lck, i, - 1, rc); - cl_lock_mutex_put(env, sublock); - cl_lock_put(env, sublock); - break; - default: - lov_sublock_unlock(env, sub, closure, - subenv); - break; - } - } else { - LASSERT(!sublock->cll_conflict); - lov_sublock_unlock(env, sub, closure, subenv); - } - } - result = lov_subresult(result, rc); - if (result != 0) + rc = cl_lock_enqueue(subenv->lse_env, subenv->lse_io, + &lls->sub_lock, anchor); + lov_sublock_env_put(subenv); + if (rc != 0) break; - } - cl_lock_closure_fini(closure); - return result ?: minstate >= CLS_ENQUEUED ? 0 : CLO_WAIT; -} - -static int lov_lock_unuse(const struct lu_env *env, - const struct cl_lock_slice *slice) -{ - struct lov_lock *lck = cl2lov_lock(slice); - struct cl_lock_closure *closure = lov_closure_get(env, slice->cls_lock); - int i; - int result; - - for (result = 0, i = 0; i < lck->lls_nr; ++i) { - int rc; - struct lovsub_lock *sub; - struct cl_lock *sublock; - struct lov_lock_sub *lls; - struct lov_sublock_env *subenv; - /* top-lock state cannot change concurrently, because single - * thread (one that released the last hold) carries unlocking - * to the completion. - */ - LASSERT(slice->cls_lock->cll_state == CLS_INTRANSIT); - lls = &lck->lls_sub[i]; - sub = lls->sub_lock; - if (!sub) - continue; - - sublock = sub->lss_cl.cls_lock; - rc = lov_sublock_lock(env, lck, lls, closure, &subenv); - if (rc == 0) { - if (lls->sub_flags & LSF_HELD) { - LASSERT(sublock->cll_state == CLS_HELD || - sublock->cll_state == CLS_ENQUEUED); - rc = cl_unuse_try(subenv->lse_env, sublock); - rc = lov_sublock_release(env, lck, i, 0, rc); - } - lov_sublock_unlock(env, sub, closure, subenv); - } - result = lov_subresult(result, rc); + lls->sub_is_enqueued = 1; } - - if (result == 0 && lck->lls_cancel_race) { - lck->lls_cancel_race = 0; - result = -ESTALE; - } - cl_lock_closure_fini(closure); - return result; + return rc; } static void lov_lock_cancel(const struct lu_env *env, const struct cl_lock_slice *slice) { - struct lov_lock *lck = cl2lov_lock(slice); - struct cl_lock_closure *closure = lov_closure_get(env, slice->cls_lock); + struct cl_lock *lock = slice->cls_lock; + struct lov_lock *lovlck = cl2lov_lock(slice); int i; - int result; - for (result = 0, i = 0; i < lck->lls_nr; ++i) { - int rc; - struct lovsub_lock *sub; - struct cl_lock *sublock; - struct lov_lock_sub *lls; + for (i = 0; i < lovlck->lls_nr; ++i) { + struct lov_lock_sub *lls = &lovlck->lls_sub[i]; + struct cl_lock *sublock = &lls->sub_lock; struct lov_sublock_env *subenv; - /* top-lock state cannot change concurrently, because single - * thread (one that released the last hold) carries unlocking - * to the completion. - */ - lls = &lck->lls_sub[i]; - sub = lls->sub_lock; - if (!sub) - continue; - - sublock = sub->lss_cl.cls_lock; - rc = lov_sublock_lock(env, lck, lls, closure, &subenv); - if (rc == 0) { - if (!(lls->sub_flags & LSF_HELD)) { - lov_sublock_unlock(env, sub, closure, subenv); - continue; - } - - switch (sublock->cll_state) { - case CLS_HELD: - rc = cl_unuse_try(subenv->lse_env, sublock); - lov_sublock_release(env, lck, i, 0, 0); - break; - default: - lov_sublock_release(env, lck, i, 1, 0); - break; - } - lov_sublock_unlock(env, sub, closure, subenv); - } - - if (rc == CLO_REPEAT) { - --i; - continue; - } - - result = lov_subresult(result, rc); - } - - if (result) - CL_LOCK_DEBUG(D_ERROR, env, slice->cls_lock, - "lov_lock_cancel fails with %d.\n", result); - - cl_lock_closure_fini(closure); -} - -static int lov_lock_wait(const struct lu_env *env, - const struct cl_lock_slice *slice) -{ - struct lov_lock *lck = cl2lov_lock(slice); - struct cl_lock_closure *closure = lov_closure_get(env, slice->cls_lock); - enum cl_lock_state minstate; - int reenqueued; - int result; - int i; - -again: - for (result = 0, minstate = CLS_FREEING, i = 0, reenqueued = 0; - i < lck->lls_nr; ++i) { - int rc; - struct lovsub_lock *sub; - struct cl_lock *sublock; - struct lov_lock_sub *lls; - struct lov_sublock_env *subenv; - - lls = &lck->lls_sub[i]; - sub = lls->sub_lock; - sublock = sub->lss_cl.cls_lock; - rc = lov_sublock_lock(env, lck, lls, closure, &subenv); - if (rc == 0) { - LASSERT(sublock->cll_state >= CLS_ENQUEUED); - if (sublock->cll_state < CLS_HELD) - rc = cl_wait_try(env, sublock); - - minstate = min(minstate, sublock->cll_state); - lov_sublock_unlock(env, sub, closure, subenv); - } - if (rc == CLO_REENQUEUED) { - reenqueued++; - rc = 0; - } - result = lov_subresult(result, rc); - if (result != 0) - break; - } - /* Each sublock only can be reenqueued once, so will not loop - * forever. - */ - if (result == 0 && reenqueued != 0) - goto again; - cl_lock_closure_fini(closure); - return result ?: minstate >= CLS_HELD ? 0 : CLO_WAIT; -} - -static int lov_lock_use(const struct lu_env *env, - const struct cl_lock_slice *slice) -{ - struct lov_lock *lck = cl2lov_lock(slice); - struct cl_lock_closure *closure = lov_closure_get(env, slice->cls_lock); - int result; - int i; - - LASSERT(slice->cls_lock->cll_state == CLS_INTRANSIT); - - for (result = 0, i = 0; i < lck->lls_nr; ++i) { - int rc; - struct lovsub_lock *sub; - struct cl_lock *sublock; - struct lov_lock_sub *lls; - struct lov_sublock_env *subenv; - - LASSERT(slice->cls_lock->cll_state == CLS_INTRANSIT); - - lls = &lck->lls_sub[i]; - sub = lls->sub_lock; - if (!sub) { - /* - * Sub-lock might have been canceled, while top-lock was - * cached. - */ - result = -ESTALE; - break; - } - - sublock = sub->lss_cl.cls_lock; - rc = lov_sublock_lock(env, lck, lls, closure, &subenv); - if (rc == 0) { - LASSERT(sublock->cll_state != CLS_FREEING); - lov_sublock_hold(env, lck, i); - if (sublock->cll_state == CLS_CACHED) { - rc = cl_use_try(subenv->lse_env, sublock, 0); - if (rc != 0) - rc = lov_sublock_release(env, lck, - i, 1, rc); - } else if (sublock->cll_state == CLS_NEW) { - /* Sub-lock might have been canceled, while - * top-lock was cached. - */ - result = -ESTALE; - lov_sublock_release(env, lck, i, 1, result); - } - lov_sublock_unlock(env, sub, closure, subenv); - } - result = lov_subresult(result, rc); - if (result != 0) - break; - } - - if (lck->lls_cancel_race) { - /* - * If there is unlocking happened at the same time, then - * sublock_lock state should be FREEING, and lov_sublock_lock - * should return CLO_REPEAT. In this case, it should return - * ESTALE, and up layer should reset the lock state to be NEW. - */ - lck->lls_cancel_race = 0; - LASSERT(result != 0); - result = -ESTALE; - } - cl_lock_closure_fini(closure); - return result; -} - -/** - * Check if the extent region \a descr is covered by \a child against the - * specific \a stripe. - */ -static int lov_lock_stripe_is_matching(const struct lu_env *env, - struct lov_object *lov, int stripe, - const struct cl_lock_descr *child, - const struct cl_lock_descr *descr) -{ - struct lov_stripe_md *lsm = lov->lo_lsm; - u64 start; - u64 end; - int result; - - if (lov_r0(lov)->lo_nr == 1) - return cl_lock_ext_match(child, descr); - - /* - * For a multi-stripes object: - * - make sure the descr only covers child's stripe, and - * - check if extent is matching. - */ - start = cl_offset(&lov->lo_cl, descr->cld_start); - end = cl_offset(&lov->lo_cl, descr->cld_end + 1) - 1; - result = 0; - /* glimpse should work on the object with LOV EA hole. */ - if (end - start <= lsm->lsm_stripe_size) { - int idx; - - idx = lov_stripe_number(lsm, start); - if (idx == stripe || - unlikely(!lov_r0(lov)->lo_sub[idx])) { - idx = lov_stripe_number(lsm, end); - if (idx == stripe || - unlikely(!lov_r0(lov)->lo_sub[idx])) - result = 1; - } - } - - if (result != 0) { - struct cl_lock_descr *subd = &lov_env_info(env)->lti_ldescr; - u64 sub_start; - u64 sub_end; - - subd->cld_obj = NULL; /* don't need sub object at all */ - subd->cld_mode = descr->cld_mode; - subd->cld_gid = descr->cld_gid; - result = lov_stripe_intersects(lsm, stripe, start, end, - &sub_start, &sub_end); - LASSERT(result); - subd->cld_start = cl_index(child->cld_obj, sub_start); - subd->cld_end = cl_index(child->cld_obj, sub_end); - result = cl_lock_ext_match(child, subd); - } - return result; -} - -/** - * An implementation of cl_lock_operations::clo_fits_into() method. - * - * Checks whether a lock (given by \a slice) is suitable for \a - * io. Multi-stripe locks can be used only for "quick" io, like truncate, or - * O_APPEND write. - * - * \see ccc_lock_fits_into(). - */ -static int lov_lock_fits_into(const struct lu_env *env, - const struct cl_lock_slice *slice, - const struct cl_lock_descr *need, - const struct cl_io *io) -{ - struct lov_lock *lov = cl2lov_lock(slice); - struct lov_object *obj = cl2lov(slice->cls_obj); - int result; - - LASSERT(cl_object_same(need->cld_obj, slice->cls_obj)); - LASSERT(lov->lls_nr > 0); - - /* for top lock, it's necessary to match enq flags otherwise it will - * run into problem if a sublock is missing and reenqueue. - */ - if (need->cld_enq_flags != lov->lls_orig.cld_enq_flags) - return 0; - - if (need->cld_mode == CLM_GROUP) - /* - * always allow to match group lock. - */ - result = cl_lock_ext_match(&lov->lls_orig, need); - else if (lov->lls_nr == 1) { - struct cl_lock_descr *got = &lov->lls_sub[0].sub_got; - - result = lov_lock_stripe_is_matching(env, - cl2lov(slice->cls_obj), - lov->lls_sub[0].sub_stripe, - got, need); - } else if (io->ci_type != CIT_SETATTR && io->ci_type != CIT_MISC && - !cl_io_is_append(io) && need->cld_mode != CLM_PHANTOM) - /* - * Multi-stripe locks are only suitable for `quick' IO and for - * glimpse. - */ - result = 0; - else - /* - * Most general case: multi-stripe existing lock, and - * (potentially) multi-stripe @need lock. Check that @need is - * covered by @lov's sub-locks. - * - * For now, ignore lock expansions made by the server, and - * match against original lock extent. - */ - result = cl_lock_ext_match(&lov->lls_orig, need); - CDEBUG(D_DLMTRACE, DDESCR"/"DDESCR" %d %d/%d: %d\n", - PDESCR(&lov->lls_orig), PDESCR(&lov->lls_sub[0].sub_got), - lov->lls_sub[0].sub_stripe, lov->lls_nr, lov_r0(obj)->lo_nr, - result); - return result; -} - -void lov_lock_unlink(const struct lu_env *env, - struct lov_lock_link *link, struct lovsub_lock *sub) -{ - struct lov_lock *lck = link->lll_super; - struct cl_lock *parent = lck->lls_cl.cls_lock; - - LASSERT(cl_lock_is_mutexed(parent)); - LASSERT(cl_lock_is_mutexed(sub->lss_cl.cls_lock)); - - list_del_init(&link->lll_list); - LASSERT(lck->lls_sub[link->lll_idx].sub_lock == sub); - /* yank this sub-lock from parent's array */ - lck->lls_sub[link->lll_idx].sub_lock = NULL; - LASSERT(lck->lls_nr_filled > 0); - lck->lls_nr_filled--; - lu_ref_del(&parent->cll_reference, "lov-child", sub->lss_cl.cls_lock); - cl_lock_put(env, parent); - kmem_cache_free(lov_lock_link_kmem, link); -} - -struct lov_lock_link *lov_lock_link_find(const struct lu_env *env, - struct lov_lock *lck, - struct lovsub_lock *sub) -{ - struct lov_lock_link *scan; - - LASSERT(cl_lock_is_mutexed(sub->lss_cl.cls_lock)); - - list_for_each_entry(scan, &sub->lss_parents, lll_list) { - if (scan->lll_super == lck) - return scan; - } - return NULL; -} - -/** - * An implementation of cl_lock_operations::clo_delete() method. This is - * invoked for "top-to-bottom" delete, when lock destruction starts from the - * top-lock, e.g., as a result of inode destruction. - * - * Unlinks top-lock from all its sub-locks. Sub-locks are not deleted there: - * this is done separately elsewhere: - * - * - for inode destruction, lov_object_delete() calls cl_object_kill() for - * each sub-object, purging its locks; - * - * - in other cases (e.g., a fatal error with a top-lock) sub-locks are - * left in the cache. - */ -static void lov_lock_delete(const struct lu_env *env, - const struct cl_lock_slice *slice) -{ - struct lov_lock *lck = cl2lov_lock(slice); - struct cl_lock_closure *closure = lov_closure_get(env, slice->cls_lock); - struct lov_lock_link *link; - int rc; - int i; - - LASSERT(slice->cls_lock->cll_state == CLS_FREEING); - - for (i = 0; i < lck->lls_nr; ++i) { - struct lov_lock_sub *lls = &lck->lls_sub[i]; - struct lovsub_lock *lsl = lls->sub_lock; - - if (!lsl) /* already removed */ + if (!lls->sub_is_enqueued) continue; - rc = lov_sublock_lock(env, lck, lls, closure, NULL); - if (rc == CLO_REPEAT) { - --i; - continue; + lls->sub_is_enqueued = 0; + subenv = lov_sublock_env_get(env, lock, lls); + if (!IS_ERR(subenv)) { + cl_lock_cancel(subenv->lse_env, sublock); + lov_sublock_env_put(subenv); + } else { + CL_LOCK_DEBUG(D_ERROR, env, slice->cls_lock, + "lov_lock_cancel fails with %ld.\n", + PTR_ERR(subenv)); } - - LASSERT(rc == 0); - LASSERT(lsl->lss_cl.cls_lock->cll_state < CLS_FREEING); - - if (lls->sub_flags & LSF_HELD) - lov_sublock_release(env, lck, i, 1, 0); - - link = lov_lock_link_find(env, lck, lsl); - LASSERT(link); - lov_lock_unlink(env, link, lsl); - LASSERT(!lck->lls_sub[i].sub_lock); - - lov_sublock_unlock(env, lsl, closure, NULL); } - - cl_lock_closure_fini(closure); } static int lov_lock_print(const struct lu_env *env, void *cookie, @@ -1079,12 +291,8 @@ static int lov_lock_print(const struct lu_env *env, void *cookie, struct lov_lock_sub *sub; sub = &lck->lls_sub[i]; - (*p)(env, cookie, " %d %x: ", i, sub->sub_flags); - if (sub->sub_lock) - cl_lock_print(env, cookie, p, - sub->sub_lock->lss_cl.cls_lock); - else - (*p)(env, cookie, "---\n"); + (*p)(env, cookie, " %d %x: ", i, sub->sub_is_enqueued); + cl_lock_print(env, cookie, p, &sub->sub_lock); } return 0; } @@ -1092,12 +300,7 @@ static int lov_lock_print(const struct lu_env *env, void *cookie, static const struct cl_lock_operations lov_lock_ops = { .clo_fini = lov_lock_fini, .clo_enqueue = lov_lock_enqueue, - .clo_wait = lov_lock_wait, - .clo_use = lov_lock_use, - .clo_unuse = lov_lock_unuse, .clo_cancel = lov_lock_cancel, - .clo_fits_into = lov_lock_fits_into, - .clo_delete = lov_lock_delete, .clo_print = lov_lock_print }; @@ -1105,14 +308,13 @@ int lov_lock_init_raid0(const struct lu_env *env, struct cl_object *obj, struct cl_lock *lock, const struct cl_io *io) { struct lov_lock *lck; - int result; + int result = 0; - lck = kmem_cache_zalloc(lov_lock_kmem, GFP_NOFS); - if (lck) { + lck = lov_lock_sub_init(env, obj, lock); + if (!IS_ERR(lck)) cl_lock_slice_add(lock, &lck->lls_cl, obj, &lov_lock_ops); - result = lov_lock_sub_init(env, lck, io); - } else - result = -ENOMEM; + else + result = PTR_ERR(lck); return result; } @@ -1147,21 +349,9 @@ int lov_lock_init_empty(const struct lu_env *env, struct cl_object *obj, lck = kmem_cache_zalloc(lov_lock_kmem, GFP_NOFS); if (lck) { cl_lock_slice_add(lock, &lck->lls_cl, obj, &lov_empty_lock_ops); - lck->lls_orig = lock->cll_descr; result = 0; } return result; } -static struct cl_lock_closure *lov_closure_get(const struct lu_env *env, - struct cl_lock *parent) -{ - struct cl_lock_closure *closure; - - closure = &lov_env_info(env)->lti_closure; - LASSERT(list_empty(&closure->clc_list)); - cl_lock_closure_init(env, closure, parent, 1); - return closure; -} - /** @} lov */ diff --git a/drivers/staging/lustre/lustre/lov/lov_object.c b/drivers/staging/lustre/lustre/lov/lov_object.c index 0159b6f1e5c3..6a353d18eefe 100644 --- a/drivers/staging/lustre/lustre/lov/lov_object.c +++ b/drivers/staging/lustre/lustre/lov/lov_object.c @@ -310,8 +310,6 @@ static int lov_delete_empty(const struct lu_env *env, struct lov_object *lov, LASSERT(lov->lo_type == LLT_EMPTY || lov->lo_type == LLT_RELEASED); lov_layout_wait(env, lov); - - cl_locks_prune(env, &lov->lo_cl, 0); return 0; } @@ -379,7 +377,7 @@ static int lov_delete_raid0(const struct lu_env *env, struct lov_object *lov, struct lovsub_object *los = r0->lo_sub[i]; if (los) { - cl_locks_prune(env, &los->lso_cl, 1); + cl_object_prune(env, &los->lso_cl); /* * If top-level object is to be evicted from * the cache, so are its sub-objects. @@ -388,7 +386,6 @@ static int lov_delete_raid0(const struct lu_env *env, struct lov_object *lov, } } } - cl_locks_prune(env, &lov->lo_cl, 0); return 0; } @@ -714,7 +711,9 @@ static int lov_layout_change(const struct lu_env *unused, old_ops = &lov_dispatch[lov->lo_type]; new_ops = &lov_dispatch[llt]; - cl_object_prune(env, &lov->lo_cl); + result = cl_object_prune(env, &lov->lo_cl); + if (result != 0) + goto out; result = old_ops->llo_delete(env, lov, &lov->u); if (result == 0) { @@ -736,6 +735,7 @@ static int lov_layout_change(const struct lu_env *unused, } } +out: cl_env_put(env, &refcheck); cl_env_reexit(cookie); return result; @@ -816,7 +816,8 @@ static int lov_conf_set(const struct lu_env *env, struct cl_object *obj, goto out; } - lov->lo_layout_invalid = lov_layout_change(env, lov, conf); + result = lov_layout_change(env, lov, conf); + lov->lo_layout_invalid = result != 0; out: lov_conf_unlock(lov); diff --git a/drivers/staging/lustre/lustre/lov/lovsub_lock.c b/drivers/staging/lustre/lustre/lov/lovsub_lock.c index 3bb0c9068a90..670d203ab77e 100644 --- a/drivers/staging/lustre/lustre/lov/lovsub_lock.c +++ b/drivers/staging/lustre/lustre/lov/lovsub_lock.c @@ -62,391 +62,8 @@ static void lovsub_lock_fini(const struct lu_env *env, kmem_cache_free(lovsub_lock_kmem, lsl); } -static void lovsub_parent_lock(const struct lu_env *env, struct lov_lock *lov) -{ - struct cl_lock *parent; - - parent = lov->lls_cl.cls_lock; - cl_lock_get(parent); - lu_ref_add(&parent->cll_reference, "lovsub-parent", current); - cl_lock_mutex_get(env, parent); -} - -static void lovsub_parent_unlock(const struct lu_env *env, struct lov_lock *lov) -{ - struct cl_lock *parent; - - parent = lov->lls_cl.cls_lock; - cl_lock_mutex_put(env, lov->lls_cl.cls_lock); - lu_ref_del(&parent->cll_reference, "lovsub-parent", current); - cl_lock_put(env, parent); -} - -/** - * Implements cl_lock_operations::clo_state() method for lovsub layer, which - * method is called whenever sub-lock state changes. Propagates state change - * to the top-locks. - */ -static void lovsub_lock_state(const struct lu_env *env, - const struct cl_lock_slice *slice, - enum cl_lock_state state) -{ - struct lovsub_lock *sub = cl2lovsub_lock(slice); - struct lov_lock_link *scan; - - LASSERT(cl_lock_is_mutexed(slice->cls_lock)); - - list_for_each_entry(scan, &sub->lss_parents, lll_list) { - struct lov_lock *lov = scan->lll_super; - struct cl_lock *parent = lov->lls_cl.cls_lock; - - if (sub->lss_active != parent) { - lovsub_parent_lock(env, lov); - cl_lock_signal(env, parent); - lovsub_parent_unlock(env, lov); - } - } -} - -/** - * Implementation of cl_lock_operation::clo_weigh() estimating lock weight by - * asking parent lock. - */ -static unsigned long lovsub_lock_weigh(const struct lu_env *env, - const struct cl_lock_slice *slice) -{ - struct lovsub_lock *lock = cl2lovsub_lock(slice); - struct lov_lock *lov; - unsigned long dumbbell; - - LASSERT(cl_lock_is_mutexed(slice->cls_lock)); - - if (!list_empty(&lock->lss_parents)) { - /* - * It is not clear whether all parents have to be asked and - * their estimations summed, or it is enough to ask one. For - * the current usages, one is always enough. - */ - lov = container_of(lock->lss_parents.next, - struct lov_lock_link, lll_list)->lll_super; - - lovsub_parent_lock(env, lov); - dumbbell = cl_lock_weigh(env, lov->lls_cl.cls_lock); - lovsub_parent_unlock(env, lov); - } else - dumbbell = 0; - - return dumbbell; -} - -/** - * Maps start/end offsets within a stripe, to offsets within a file. - */ -static void lovsub_lock_descr_map(const struct cl_lock_descr *in, - struct lov_object *lov, - int stripe, struct cl_lock_descr *out) -{ - pgoff_t size; /* stripe size in pages */ - pgoff_t skip; /* how many pages in every stripe are occupied by - * "other" stripes - */ - pgoff_t start; - pgoff_t end; - - start = in->cld_start; - end = in->cld_end; - - if (lov->lo_lsm->lsm_stripe_count > 1) { - size = cl_index(lov2cl(lov), lov->lo_lsm->lsm_stripe_size); - skip = (lov->lo_lsm->lsm_stripe_count - 1) * size; - - /* XXX overflow check here? */ - start += start/size * skip + stripe * size; - - if (end != CL_PAGE_EOF) { - end += end/size * skip + stripe * size; - /* - * And check for overflow... - */ - if (end < in->cld_end) - end = CL_PAGE_EOF; - } - } - out->cld_start = start; - out->cld_end = end; -} - -/** - * Adjusts parent lock extent when a sub-lock is attached to a parent. This is - * called in two ways: - * - * - as part of receive call-back, when server returns granted extent to - * the client, and - * - * - when top-lock finds existing sub-lock in the cache. - * - * Note, that lock mode is not propagated to the parent: i.e., if CLM_READ - * top-lock matches CLM_WRITE sub-lock, top-lock is still CLM_READ. - */ -int lov_sublock_modify(const struct lu_env *env, struct lov_lock *lov, - struct lovsub_lock *sublock, - const struct cl_lock_descr *d, int idx) -{ - struct cl_lock *parent; - struct lovsub_object *subobj; - struct cl_lock_descr *pd; - struct cl_lock_descr *parent_descr; - int result; - - parent = lov->lls_cl.cls_lock; - parent_descr = &parent->cll_descr; - LASSERT(cl_lock_mode_match(d->cld_mode, parent_descr->cld_mode)); - - subobj = cl2lovsub(sublock->lss_cl.cls_obj); - pd = &lov_env_info(env)->lti_ldescr; - - pd->cld_obj = parent_descr->cld_obj; - pd->cld_mode = parent_descr->cld_mode; - pd->cld_gid = parent_descr->cld_gid; - lovsub_lock_descr_map(d, subobj->lso_super, subobj->lso_index, pd); - lov->lls_sub[idx].sub_got = *d; - /* - * Notify top-lock about modification, if lock description changes - * materially. - */ - if (!cl_lock_ext_match(parent_descr, pd)) - result = cl_lock_modify(env, parent, pd); - else - result = 0; - return result; -} - -static int lovsub_lock_modify(const struct lu_env *env, - const struct cl_lock_slice *s, - const struct cl_lock_descr *d) -{ - struct lovsub_lock *lock = cl2lovsub_lock(s); - struct lov_lock_link *scan; - struct lov_lock *lov; - int result = 0; - - LASSERT(cl_lock_mode_match(d->cld_mode, - s->cls_lock->cll_descr.cld_mode)); - list_for_each_entry(scan, &lock->lss_parents, lll_list) { - int rc; - - lov = scan->lll_super; - lovsub_parent_lock(env, lov); - rc = lov_sublock_modify(env, lov, lock, d, scan->lll_idx); - lovsub_parent_unlock(env, lov); - result = result ?: rc; - } - return result; -} - -static int lovsub_lock_closure(const struct lu_env *env, - const struct cl_lock_slice *slice, - struct cl_lock_closure *closure) -{ - struct lovsub_lock *sub; - struct cl_lock *parent; - struct lov_lock_link *scan; - int result; - - LASSERT(cl_lock_is_mutexed(slice->cls_lock)); - - sub = cl2lovsub_lock(slice); - result = 0; - - list_for_each_entry(scan, &sub->lss_parents, lll_list) { - parent = scan->lll_super->lls_cl.cls_lock; - result = cl_lock_closure_build(env, parent, closure); - if (result != 0) - break; - } - return result; -} - -/** - * A helper function for lovsub_lock_delete() that deals with a given parent - * top-lock. - */ -static int lovsub_lock_delete_one(const struct lu_env *env, - struct cl_lock *child, struct lov_lock *lov) -{ - struct cl_lock *parent; - int result; - - parent = lov->lls_cl.cls_lock; - if (parent->cll_error) - return 0; - - result = 0; - switch (parent->cll_state) { - case CLS_ENQUEUED: - /* See LU-1355 for the case that a glimpse lock is - * interrupted by signal - */ - LASSERT(parent->cll_flags & CLF_CANCELLED); - break; - case CLS_QUEUING: - case CLS_FREEING: - cl_lock_signal(env, parent); - break; - case CLS_INTRANSIT: - /* - * Here lies a problem: a sub-lock is canceled while top-lock - * is being unlocked. Top-lock cannot be moved into CLS_NEW - * state, because unlocking has to succeed eventually by - * placing lock into CLS_CACHED (or failing it), see - * cl_unuse_try(). Nor can top-lock be left in CLS_CACHED - * state, because lov maintains an invariant that all - * sub-locks exist in CLS_CACHED (this allows cached top-lock - * to be reused immediately). Nor can we wait for top-lock - * state to change, because this can be synchronous to the - * current thread. - * - * We know for sure that lov_lock_unuse() will be called at - * least one more time to finish un-using, so leave a mark on - * the top-lock, that will be seen by the next call to - * lov_lock_unuse(). - */ - if (cl_lock_is_intransit(parent)) - lov->lls_cancel_race = 1; - break; - case CLS_CACHED: - /* - * if a sub-lock is canceled move its top-lock into CLS_NEW - * state to preserve an invariant that a top-lock in - * CLS_CACHED is immediately ready for re-use (i.e., has all - * sub-locks), and so that next attempt to re-use the top-lock - * enqueues missing sub-lock. - */ - cl_lock_state_set(env, parent, CLS_NEW); - /* fall through */ - case CLS_NEW: - /* - * if last sub-lock is canceled, destroy the top-lock (which - * is now `empty') proactively. - */ - if (lov->lls_nr_filled == 0) { - /* ... but unfortunately, this cannot be done easily, - * as cancellation of a top-lock might acquire mutices - * of its other sub-locks, violating lock ordering, - * see cl_lock_{cancel,delete}() preconditions. - * - * To work around this, the mutex of this sub-lock is - * released, top-lock is destroyed, and sub-lock mutex - * acquired again. The list of parents has to be - * re-scanned from the beginning after this. - * - * Only do this if no mutices other than on @child and - * @parent are held by the current thread. - * - * TODO: The lock modal here is too complex, because - * the lock may be canceled and deleted by voluntarily: - * cl_lock_request - * -> osc_lock_enqueue_wait - * -> osc_lock_cancel_wait - * -> cl_lock_delete - * -> lovsub_lock_delete - * -> cl_lock_cancel/delete - * -> ... - * - * The better choice is to spawn a kernel thread for - * this purpose. -jay - */ - if (cl_lock_nr_mutexed(env) == 2) { - cl_lock_mutex_put(env, child); - cl_lock_cancel(env, parent); - cl_lock_delete(env, parent); - result = 1; - } - } - break; - case CLS_HELD: - CL_LOCK_DEBUG(D_ERROR, env, parent, "Delete CLS_HELD lock\n"); - default: - CERROR("Impossible state: %d\n", parent->cll_state); - LBUG(); - break; - } - - return result; -} - -/** - * An implementation of cl_lock_operations::clo_delete() method. This is - * invoked in "bottom-to-top" delete, when lock destruction starts from the - * sub-lock (e.g, as a result of ldlm lock LRU policy). - */ -static void lovsub_lock_delete(const struct lu_env *env, - const struct cl_lock_slice *slice) -{ - struct cl_lock *child = slice->cls_lock; - struct lovsub_lock *sub = cl2lovsub_lock(slice); - int restart; - - LASSERT(cl_lock_is_mutexed(child)); - - /* - * Destruction of a sub-lock might take multiple iterations, because - * when the last sub-lock of a given top-lock is deleted, top-lock is - * canceled proactively, and this requires to release sub-lock - * mutex. Once sub-lock mutex has been released, list of its parents - * has to be re-scanned from the beginning. - */ - do { - struct lov_lock *lov; - struct lov_lock_link *scan; - struct lov_lock_link *temp; - struct lov_lock_sub *subdata; - - restart = 0; - list_for_each_entry_safe(scan, temp, - &sub->lss_parents, lll_list) { - lov = scan->lll_super; - subdata = &lov->lls_sub[scan->lll_idx]; - lovsub_parent_lock(env, lov); - subdata->sub_got = subdata->sub_descr; - lov_lock_unlink(env, scan, sub); - restart = lovsub_lock_delete_one(env, child, lov); - lovsub_parent_unlock(env, lov); - - if (restart) { - cl_lock_mutex_get(env, child); - break; - } - } - } while (restart); -} - -static int lovsub_lock_print(const struct lu_env *env, void *cookie, - lu_printer_t p, const struct cl_lock_slice *slice) -{ - struct lovsub_lock *sub = cl2lovsub_lock(slice); - struct lov_lock *lov; - struct lov_lock_link *scan; - - list_for_each_entry(scan, &sub->lss_parents, lll_list) { - lov = scan->lll_super; - (*p)(env, cookie, "[%d %p ", scan->lll_idx, lov); - if (lov) - cl_lock_descr_print(env, cookie, p, - &lov->lls_cl.cls_lock->cll_descr); - (*p)(env, cookie, "] "); - } - return 0; -} - static const struct cl_lock_operations lovsub_lock_ops = { .clo_fini = lovsub_lock_fini, - .clo_state = lovsub_lock_state, - .clo_delete = lovsub_lock_delete, - .clo_modify = lovsub_lock_modify, - .clo_closure = lovsub_lock_closure, - .clo_weigh = lovsub_lock_weigh, - .clo_print = lovsub_lock_print }; int lovsub_lock_init(const struct lu_env *env, struct cl_object *obj, diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c index 6a8dd9faafca..7655dc485fef 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_io.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c @@ -160,7 +160,6 @@ static int cl_io_init0(const struct lu_env *env, struct cl_io *io, io->ci_type = iot; INIT_LIST_HEAD(&io->ci_lockset.cls_todo); - INIT_LIST_HEAD(&io->ci_lockset.cls_curr); INIT_LIST_HEAD(&io->ci_lockset.cls_done); INIT_LIST_HEAD(&io->ci_layers); @@ -242,37 +241,7 @@ static int cl_lock_descr_sort(const struct cl_lock_descr *d0, const struct cl_lock_descr *d1) { return lu_fid_cmp(lu_object_fid(&d0->cld_obj->co_lu), - lu_object_fid(&d1->cld_obj->co_lu)) ?: - __diff_normalize(d0->cld_start, d1->cld_start); -} - -static int cl_lock_descr_cmp(const struct cl_lock_descr *d0, - const struct cl_lock_descr *d1) -{ - int ret; - - ret = lu_fid_cmp(lu_object_fid(&d0->cld_obj->co_lu), - lu_object_fid(&d1->cld_obj->co_lu)); - if (ret) - return ret; - if (d0->cld_end < d1->cld_start) - return -1; - if (d0->cld_start > d0->cld_end) - return 1; - return 0; -} - -static void cl_lock_descr_merge(struct cl_lock_descr *d0, - const struct cl_lock_descr *d1) -{ - d0->cld_start = min(d0->cld_start, d1->cld_start); - d0->cld_end = max(d0->cld_end, d1->cld_end); - - if (d1->cld_mode == CLM_WRITE && d0->cld_mode != CLM_WRITE) - d0->cld_mode = CLM_WRITE; - - if (d1->cld_mode == CLM_GROUP && d0->cld_mode != CLM_GROUP) - d0->cld_mode = CLM_GROUP; + lu_object_fid(&d1->cld_obj->co_lu)); } /* @@ -321,33 +290,35 @@ static void cl_io_locks_sort(struct cl_io *io) } while (!done); } -/** - * Check whether \a queue contains locks matching \a need. - * - * \retval +ve there is a matching lock in the \a queue - * \retval 0 there are no matching locks in the \a queue - */ -int cl_queue_match(const struct list_head *queue, - const struct cl_lock_descr *need) +static void cl_lock_descr_merge(struct cl_lock_descr *d0, + const struct cl_lock_descr *d1) { - struct cl_io_lock_link *scan; + d0->cld_start = min(d0->cld_start, d1->cld_start); + d0->cld_end = max(d0->cld_end, d1->cld_end); - list_for_each_entry(scan, queue, cill_linkage) { - if (cl_lock_descr_match(&scan->cill_descr, need)) - return 1; - } - return 0; + if (d1->cld_mode == CLM_WRITE && d0->cld_mode != CLM_WRITE) + d0->cld_mode = CLM_WRITE; + + if (d1->cld_mode == CLM_GROUP && d0->cld_mode != CLM_GROUP) + d0->cld_mode = CLM_GROUP; } -EXPORT_SYMBOL(cl_queue_match); -static int cl_queue_merge(const struct list_head *queue, - const struct cl_lock_descr *need) +static int cl_lockset_merge(const struct cl_lockset *set, + const struct cl_lock_descr *need) { struct cl_io_lock_link *scan; - list_for_each_entry(scan, queue, cill_linkage) { - if (cl_lock_descr_cmp(&scan->cill_descr, need)) + list_for_each_entry(scan, &set->cls_todo, cill_linkage) { + if (!cl_object_same(scan->cill_descr.cld_obj, need->cld_obj)) continue; + + /* Merge locks for the same object because ldlm lock server + * may expand the lock extent, otherwise there is a deadlock + * case if two conflicted locks are queueud for the same object + * and lock server expands one lock to overlap the another. + * The side effect is that it can generate a multi-stripe lock + * that may cause casacading problem + */ cl_lock_descr_merge(&scan->cill_descr, need); CDEBUG(D_VFSTRACE, "lock: %d: [%lu, %lu]\n", scan->cill_descr.cld_mode, scan->cill_descr.cld_start, @@ -357,87 +328,20 @@ static int cl_queue_merge(const struct list_head *queue, return 0; } -static int cl_lockset_match(const struct cl_lockset *set, - const struct cl_lock_descr *need) -{ - return cl_queue_match(&set->cls_curr, need) || - cl_queue_match(&set->cls_done, need); -} - -static int cl_lockset_merge(const struct cl_lockset *set, - const struct cl_lock_descr *need) -{ - return cl_queue_merge(&set->cls_todo, need) || - cl_lockset_match(set, need); -} - -static int cl_lockset_lock_one(const struct lu_env *env, - struct cl_io *io, struct cl_lockset *set, - struct cl_io_lock_link *link) -{ - struct cl_lock *lock; - int result; - - lock = cl_lock_request(env, io, &link->cill_descr, "io", io); - - if (!IS_ERR(lock)) { - link->cill_lock = lock; - list_move(&link->cill_linkage, &set->cls_curr); - if (!(link->cill_descr.cld_enq_flags & CEF_ASYNC)) { - result = cl_wait(env, lock); - if (result == 0) - list_move(&link->cill_linkage, &set->cls_done); - } else - result = 0; - } else - result = PTR_ERR(lock); - return result; -} - -static void cl_lock_link_fini(const struct lu_env *env, struct cl_io *io, - struct cl_io_lock_link *link) -{ - struct cl_lock *lock = link->cill_lock; - - list_del_init(&link->cill_linkage); - if (lock) { - cl_lock_release(env, lock, "io", io); - link->cill_lock = NULL; - } - if (link->cill_fini) - link->cill_fini(env, link); -} - static int cl_lockset_lock(const struct lu_env *env, struct cl_io *io, struct cl_lockset *set) { struct cl_io_lock_link *link; struct cl_io_lock_link *temp; - struct cl_lock *lock; int result; result = 0; list_for_each_entry_safe(link, temp, &set->cls_todo, cill_linkage) { - if (!cl_lockset_match(set, &link->cill_descr)) { - /* XXX some locking to guarantee that locks aren't - * expanded in between. - */ - result = cl_lockset_lock_one(env, io, set, link); - if (result != 0) - break; - } else - cl_lock_link_fini(env, io, link); - } - if (result == 0) { - list_for_each_entry_safe(link, temp, - &set->cls_curr, cill_linkage) { - lock = link->cill_lock; - result = cl_wait(env, lock); - if (result == 0) - list_move(&link->cill_linkage, &set->cls_done); - else - break; - } + result = cl_lock_request(env, io, &link->cill_lock); + if (result < 0) + break; + + list_move(&link->cill_linkage, &set->cls_done); } return result; } @@ -493,16 +397,19 @@ void cl_io_unlock(const struct lu_env *env, struct cl_io *io) set = &io->ci_lockset; - list_for_each_entry_safe(link, temp, &set->cls_todo, cill_linkage) - cl_lock_link_fini(env, io, link); - - list_for_each_entry_safe(link, temp, &set->cls_curr, cill_linkage) - cl_lock_link_fini(env, io, link); + list_for_each_entry_safe(link, temp, &set->cls_todo, cill_linkage) { + list_del_init(&link->cill_linkage); + if (link->cill_fini) + link->cill_fini(env, link); + } list_for_each_entry_safe(link, temp, &set->cls_done, cill_linkage) { - cl_unuse(env, link->cill_lock); - cl_lock_link_fini(env, io, link); + list_del_init(&link->cill_linkage); + cl_lock_release(env, &link->cill_lock); + if (link->cill_fini) + link->cill_fini(env, link); } + cl_io_for_each_reverse(scan, io) { if (scan->cis_iop->op[io->ci_type].cio_unlock) scan->cis_iop->op[io->ci_type].cio_unlock(env, scan); @@ -1435,6 +1342,7 @@ EXPORT_SYMBOL(cl_sync_io_end); void cl_sync_io_init(struct cl_sync_io *anchor, int nr, void (*end)(const struct lu_env *, struct cl_sync_io *)) { + memset(anchor, 0, sizeof(*anchor)); init_waitqueue_head(&anchor->csi_waitq); atomic_set(&anchor->csi_sync_nr, nr); atomic_set(&anchor->csi_barrier, nr > 0); diff --git a/drivers/staging/lustre/lustre/obdclass/cl_lock.c b/drivers/staging/lustre/lustre/obdclass/cl_lock.c index fe8059a0ce5d..26a576b63a72 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_lock.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_lock.c @@ -48,1987 +48,187 @@ #include "../include/cl_object.h" #include "cl_internal.h" -/** Lock class of cl_lock::cll_guard */ -static struct lock_class_key cl_lock_guard_class; -static struct kmem_cache *cl_lock_kmem; - -static struct lu_kmem_descr cl_lock_caches[] = { - { - .ckd_cache = &cl_lock_kmem, - .ckd_name = "cl_lock_kmem", - .ckd_size = sizeof (struct cl_lock) - }, - { - .ckd_cache = NULL - } -}; - -#define CS_LOCK_INC(o, item) -#define CS_LOCK_DEC(o, item) -#define CS_LOCKSTATE_INC(o, state) -#define CS_LOCKSTATE_DEC(o, state) - -/** - * Basic lock invariant that is maintained at all times. Caller either has a - * reference to \a lock, or somehow assures that \a lock cannot be freed. - * - * \see cl_lock_invariant() - */ -static int cl_lock_invariant_trusted(const struct lu_env *env, - const struct cl_lock *lock) -{ - return ergo(lock->cll_state == CLS_FREEING, lock->cll_holds == 0) && - atomic_read(&lock->cll_ref) >= lock->cll_holds && - lock->cll_holds >= lock->cll_users && - lock->cll_holds >= 0 && - lock->cll_users >= 0 && - lock->cll_depth >= 0; -} - -/** - * Stronger lock invariant, checking that caller has a reference on a lock. - * - * \see cl_lock_invariant_trusted() - */ -static int cl_lock_invariant(const struct lu_env *env, - const struct cl_lock *lock) -{ - int result; - - result = atomic_read(&lock->cll_ref) > 0 && - cl_lock_invariant_trusted(env, lock); - if (!result && env) - CL_LOCK_DEBUG(D_ERROR, env, lock, "invariant broken\n"); - return result; -} - -/** - * Returns lock "nesting": 0 for a top-lock and 1 for a sub-lock. - */ -static enum clt_nesting_level cl_lock_nesting(const struct cl_lock *lock) -{ - return cl_object_header(lock->cll_descr.cld_obj)->coh_nesting; -} - -/** - * Returns a set of counters for this lock, depending on a lock nesting. - */ -static struct cl_thread_counters *cl_lock_counters(const struct lu_env *env, - const struct cl_lock *lock) -{ - struct cl_thread_info *info; - enum clt_nesting_level nesting; - - info = cl_env_info(env); - nesting = cl_lock_nesting(lock); - LASSERT(nesting < ARRAY_SIZE(info->clt_counters)); - return &info->clt_counters[nesting]; -} - -static void cl_lock_trace0(int level, const struct lu_env *env, - const char *prefix, const struct cl_lock *lock, - const char *func, const int line) -{ - struct cl_object_header *h = cl_object_header(lock->cll_descr.cld_obj); - - CDEBUG(level, "%s: %p@(%d %p %d %d %d %d %d %lx)(%p/%d/%d) at %s():%d\n", - prefix, lock, atomic_read(&lock->cll_ref), - lock->cll_guarder, lock->cll_depth, - lock->cll_state, lock->cll_error, lock->cll_holds, - lock->cll_users, lock->cll_flags, - env, h->coh_nesting, cl_lock_nr_mutexed(env), - func, line); -} - -#define cl_lock_trace(level, env, prefix, lock) \ - cl_lock_trace0(level, env, prefix, lock, __func__, __LINE__) - -#define RETIP ((unsigned long)__builtin_return_address(0)) - -#ifdef CONFIG_LOCKDEP -static struct lock_class_key cl_lock_key; - -static void cl_lock_lockdep_init(struct cl_lock *lock) -{ - lockdep_set_class_and_name(lock, &cl_lock_key, "EXT"); -} - -static void cl_lock_lockdep_acquire(const struct lu_env *env, - struct cl_lock *lock, __u32 enqflags) -{ - cl_lock_counters(env, lock)->ctc_nr_locks_acquired++; - lock_map_acquire(&lock->dep_map); -} - -static void cl_lock_lockdep_release(const struct lu_env *env, - struct cl_lock *lock) -{ - cl_lock_counters(env, lock)->ctc_nr_locks_acquired--; - lock_release(&lock->dep_map, 0, RETIP); -} - -#else /* !CONFIG_LOCKDEP */ - -static void cl_lock_lockdep_init(struct cl_lock *lock) -{} -static void cl_lock_lockdep_acquire(const struct lu_env *env, - struct cl_lock *lock, __u32 enqflags) -{} -static void cl_lock_lockdep_release(const struct lu_env *env, - struct cl_lock *lock) -{} - -#endif /* !CONFIG_LOCKDEP */ - -/** - * Adds lock slice to the compound lock. - * - * This is called by cl_object_operations::coo_lock_init() methods to add a - * per-layer state to the lock. New state is added at the end of - * cl_lock::cll_layers list, that is, it is at the bottom of the stack. - * - * \see cl_req_slice_add(), cl_page_slice_add(), cl_io_slice_add() - */ -void cl_lock_slice_add(struct cl_lock *lock, struct cl_lock_slice *slice, - struct cl_object *obj, - const struct cl_lock_operations *ops) -{ - slice->cls_lock = lock; - list_add_tail(&slice->cls_linkage, &lock->cll_layers); - slice->cls_obj = obj; - slice->cls_ops = ops; -} -EXPORT_SYMBOL(cl_lock_slice_add); - -/** - * Returns true iff a lock with the mode \a has provides at least the same - * guarantees as a lock with the mode \a need. - */ -int cl_lock_mode_match(enum cl_lock_mode has, enum cl_lock_mode need) -{ - LINVRNT(need == CLM_READ || need == CLM_WRITE || - need == CLM_PHANTOM || need == CLM_GROUP); - LINVRNT(has == CLM_READ || has == CLM_WRITE || - has == CLM_PHANTOM || has == CLM_GROUP); - CLASSERT(CLM_PHANTOM < CLM_READ); - CLASSERT(CLM_READ < CLM_WRITE); - CLASSERT(CLM_WRITE < CLM_GROUP); - - if (has != CLM_GROUP) - return need <= has; - else - return need == has; -} -EXPORT_SYMBOL(cl_lock_mode_match); - -/** - * Returns true iff extent portions of lock descriptions match. - */ -int cl_lock_ext_match(const struct cl_lock_descr *has, - const struct cl_lock_descr *need) -{ - return - has->cld_start <= need->cld_start && - has->cld_end >= need->cld_end && - cl_lock_mode_match(has->cld_mode, need->cld_mode) && - (has->cld_mode != CLM_GROUP || has->cld_gid == need->cld_gid); -} -EXPORT_SYMBOL(cl_lock_ext_match); - -/** - * Returns true iff a lock with the description \a has provides at least the - * same guarantees as a lock with the description \a need. - */ -int cl_lock_descr_match(const struct cl_lock_descr *has, - const struct cl_lock_descr *need) -{ - return - cl_object_same(has->cld_obj, need->cld_obj) && - cl_lock_ext_match(has, need); -} -EXPORT_SYMBOL(cl_lock_descr_match); - -static void cl_lock_free(const struct lu_env *env, struct cl_lock *lock) -{ - struct cl_object *obj = lock->cll_descr.cld_obj; - - LINVRNT(!cl_lock_is_mutexed(lock)); - - cl_lock_trace(D_DLMTRACE, env, "free lock", lock); - while (!list_empty(&lock->cll_layers)) { - struct cl_lock_slice *slice; - - slice = list_entry(lock->cll_layers.next, - struct cl_lock_slice, cls_linkage); - list_del_init(lock->cll_layers.next); - slice->cls_ops->clo_fini(env, slice); - } - CS_LOCK_DEC(obj, total); - CS_LOCKSTATE_DEC(obj, lock->cll_state); - lu_object_ref_del_at(&obj->co_lu, &lock->cll_obj_ref, "cl_lock", lock); - cl_object_put(env, obj); - lu_ref_fini(&lock->cll_reference); - lu_ref_fini(&lock->cll_holders); - mutex_destroy(&lock->cll_guard); - kmem_cache_free(cl_lock_kmem, lock); -} - -/** - * Releases a reference on a lock. - * - * When last reference is released, lock is returned to the cache, unless it - * is in cl_lock_state::CLS_FREEING state, in which case it is destroyed - * immediately. - * - * \see cl_object_put(), cl_page_put() - */ -void cl_lock_put(const struct lu_env *env, struct cl_lock *lock) -{ - struct cl_object *obj; - - LINVRNT(cl_lock_invariant(env, lock)); - obj = lock->cll_descr.cld_obj; - LINVRNT(obj); - - CDEBUG(D_TRACE, "releasing reference: %d %p %lu\n", - atomic_read(&lock->cll_ref), lock, RETIP); - - if (atomic_dec_and_test(&lock->cll_ref)) { - if (lock->cll_state == CLS_FREEING) { - LASSERT(list_empty(&lock->cll_linkage)); - cl_lock_free(env, lock); - } - CS_LOCK_DEC(obj, busy); - } -} -EXPORT_SYMBOL(cl_lock_put); - -/** - * Acquires an additional reference to a lock. - * - * This can be called only by caller already possessing a reference to \a - * lock. - * - * \see cl_object_get(), cl_page_get() - */ -void cl_lock_get(struct cl_lock *lock) -{ - LINVRNT(cl_lock_invariant(NULL, lock)); - CDEBUG(D_TRACE, "acquiring reference: %d %p %lu\n", - atomic_read(&lock->cll_ref), lock, RETIP); - atomic_inc(&lock->cll_ref); -} -EXPORT_SYMBOL(cl_lock_get); - -/** - * Acquires a reference to a lock. - * - * This is much like cl_lock_get(), except that this function can be used to - * acquire initial reference to the cached lock. Caller has to deal with all - * possible races. Use with care! - * - * \see cl_page_get_trust() - */ -void cl_lock_get_trust(struct cl_lock *lock) -{ - CDEBUG(D_TRACE, "acquiring trusted reference: %d %p %lu\n", - atomic_read(&lock->cll_ref), lock, RETIP); - if (atomic_inc_return(&lock->cll_ref) == 1) - CS_LOCK_INC(lock->cll_descr.cld_obj, busy); -} -EXPORT_SYMBOL(cl_lock_get_trust); - -/** - * Helper function destroying the lock that wasn't completely initialized. - * - * Other threads can acquire references to the top-lock through its - * sub-locks. Hence, it cannot be cl_lock_free()-ed immediately. - */ -static void cl_lock_finish(const struct lu_env *env, struct cl_lock *lock) -{ - cl_lock_mutex_get(env, lock); - cl_lock_cancel(env, lock); - cl_lock_delete(env, lock); - cl_lock_mutex_put(env, lock); - cl_lock_put(env, lock); -} - -static struct cl_lock *cl_lock_alloc(const struct lu_env *env, - struct cl_object *obj, - const struct cl_io *io, - const struct cl_lock_descr *descr) -{ - struct cl_lock *lock; - struct lu_object_header *head; - - lock = kmem_cache_zalloc(cl_lock_kmem, GFP_NOFS); - if (lock) { - atomic_set(&lock->cll_ref, 1); - lock->cll_descr = *descr; - lock->cll_state = CLS_NEW; - cl_object_get(obj); - lu_object_ref_add_at(&obj->co_lu, &lock->cll_obj_ref, "cl_lock", - lock); - INIT_LIST_HEAD(&lock->cll_layers); - INIT_LIST_HEAD(&lock->cll_linkage); - INIT_LIST_HEAD(&lock->cll_inclosure); - lu_ref_init(&lock->cll_reference); - lu_ref_init(&lock->cll_holders); - mutex_init(&lock->cll_guard); - lockdep_set_class(&lock->cll_guard, &cl_lock_guard_class); - init_waitqueue_head(&lock->cll_wq); - head = obj->co_lu.lo_header; - CS_LOCKSTATE_INC(obj, CLS_NEW); - CS_LOCK_INC(obj, total); - CS_LOCK_INC(obj, create); - cl_lock_lockdep_init(lock); - list_for_each_entry(obj, &head->loh_layers, co_lu.lo_linkage) { - int err; - - err = obj->co_ops->coo_lock_init(env, obj, lock, io); - if (err != 0) { - cl_lock_finish(env, lock); - lock = ERR_PTR(err); - break; - } - } - } else - lock = ERR_PTR(-ENOMEM); - return lock; -} - -/** - * Transfer the lock into INTRANSIT state and return the original state. - * - * \pre state: CLS_CACHED, CLS_HELD or CLS_ENQUEUED - * \post state: CLS_INTRANSIT - * \see CLS_INTRANSIT - */ -static enum cl_lock_state cl_lock_intransit(const struct lu_env *env, - struct cl_lock *lock) -{ - enum cl_lock_state state = lock->cll_state; - - LASSERT(cl_lock_is_mutexed(lock)); - LASSERT(state != CLS_INTRANSIT); - LASSERTF(state >= CLS_ENQUEUED && state <= CLS_CACHED, - "Malformed lock state %d.\n", state); - - cl_lock_state_set(env, lock, CLS_INTRANSIT); - lock->cll_intransit_owner = current; - cl_lock_hold_add(env, lock, "intransit", current); - return state; -} - -/** - * Exit the intransit state and restore the lock state to the original state - */ -static void cl_lock_extransit(const struct lu_env *env, struct cl_lock *lock, - enum cl_lock_state state) -{ - LASSERT(cl_lock_is_mutexed(lock)); - LASSERT(lock->cll_state == CLS_INTRANSIT); - LASSERT(state != CLS_INTRANSIT); - LASSERT(lock->cll_intransit_owner == current); - - lock->cll_intransit_owner = NULL; - cl_lock_state_set(env, lock, state); - cl_lock_unhold(env, lock, "intransit", current); -} - -/** - * Checking whether the lock is intransit state - */ -int cl_lock_is_intransit(struct cl_lock *lock) -{ - LASSERT(cl_lock_is_mutexed(lock)); - return lock->cll_state == CLS_INTRANSIT && - lock->cll_intransit_owner != current; -} -EXPORT_SYMBOL(cl_lock_is_intransit); -/** - * Returns true iff lock is "suitable" for given io. E.g., locks acquired by - * truncate and O_APPEND cannot be reused for read/non-append-write, as they - * cover multiple stripes and can trigger cascading timeouts. - */ -static int cl_lock_fits_into(const struct lu_env *env, - const struct cl_lock *lock, - const struct cl_lock_descr *need, - const struct cl_io *io) -{ - const struct cl_lock_slice *slice; - - LINVRNT(cl_lock_invariant_trusted(env, lock)); - list_for_each_entry(slice, &lock->cll_layers, cls_linkage) { - if (slice->cls_ops->clo_fits_into && - !slice->cls_ops->clo_fits_into(env, slice, need, io)) - return 0; - } - return 1; -} - -static struct cl_lock *cl_lock_lookup(const struct lu_env *env, - struct cl_object *obj, - const struct cl_io *io, - const struct cl_lock_descr *need) -{ - struct cl_lock *lock; - struct cl_object_header *head; - - head = cl_object_header(obj); - assert_spin_locked(&head->coh_lock_guard); - CS_LOCK_INC(obj, lookup); - list_for_each_entry(lock, &head->coh_locks, cll_linkage) { - int matched; - - matched = cl_lock_ext_match(&lock->cll_descr, need) && - lock->cll_state < CLS_FREEING && - lock->cll_error == 0 && - !(lock->cll_flags & CLF_CANCELLED) && - cl_lock_fits_into(env, lock, need, io); - CDEBUG(D_DLMTRACE, "has: "DDESCR"(%d) need: "DDESCR": %d\n", - PDESCR(&lock->cll_descr), lock->cll_state, PDESCR(need), - matched); - if (matched) { - cl_lock_get_trust(lock); - CS_LOCK_INC(obj, hit); - return lock; - } - } - return NULL; -} - -/** - * Returns a lock matching description \a need. - * - * This is the main entry point into the cl_lock caching interface. First, a - * cache (implemented as a per-object linked list) is consulted. If lock is - * found there, it is returned immediately. Otherwise new lock is allocated - * and returned. In any case, additional reference to lock is acquired. - * - * \see cl_object_find(), cl_page_find() - */ -static struct cl_lock *cl_lock_find(const struct lu_env *env, - const struct cl_io *io, - const struct cl_lock_descr *need) -{ - struct cl_object_header *head; - struct cl_object *obj; - struct cl_lock *lock; - - obj = need->cld_obj; - head = cl_object_header(obj); - - spin_lock(&head->coh_lock_guard); - lock = cl_lock_lookup(env, obj, io, need); - spin_unlock(&head->coh_lock_guard); - - if (!lock) { - lock = cl_lock_alloc(env, obj, io, need); - if (!IS_ERR(lock)) { - struct cl_lock *ghost; - - spin_lock(&head->coh_lock_guard); - ghost = cl_lock_lookup(env, obj, io, need); - if (!ghost) { - cl_lock_get_trust(lock); - list_add_tail(&lock->cll_linkage, - &head->coh_locks); - spin_unlock(&head->coh_lock_guard); - CS_LOCK_INC(obj, busy); - } else { - spin_unlock(&head->coh_lock_guard); - /* - * Other threads can acquire references to the - * top-lock through its sub-locks. Hence, it - * cannot be cl_lock_free()-ed immediately. - */ - cl_lock_finish(env, lock); - lock = ghost; - } - } - } - return lock; -} - -/** - * Returns existing lock matching given description. This is similar to - * cl_lock_find() except that no new lock is created, and returned lock is - * guaranteed to be in enum cl_lock_state::CLS_HELD state. - */ -struct cl_lock *cl_lock_peek(const struct lu_env *env, const struct cl_io *io, - const struct cl_lock_descr *need, - const char *scope, const void *source) -{ - struct cl_object_header *head; - struct cl_object *obj; - struct cl_lock *lock; - - obj = need->cld_obj; - head = cl_object_header(obj); - - do { - spin_lock(&head->coh_lock_guard); - lock = cl_lock_lookup(env, obj, io, need); - spin_unlock(&head->coh_lock_guard); - if (!lock) - return NULL; - - cl_lock_mutex_get(env, lock); - if (lock->cll_state == CLS_INTRANSIT) - /* Don't care return value. */ - cl_lock_state_wait(env, lock); - if (lock->cll_state == CLS_FREEING) { - cl_lock_mutex_put(env, lock); - cl_lock_put(env, lock); - lock = NULL; - } - } while (!lock); - - cl_lock_hold_add(env, lock, scope, source); - cl_lock_user_add(env, lock); - if (lock->cll_state == CLS_CACHED) - cl_use_try(env, lock, 1); - if (lock->cll_state == CLS_HELD) { - cl_lock_mutex_put(env, lock); - cl_lock_lockdep_acquire(env, lock, 0); - cl_lock_put(env, lock); - } else { - cl_unuse_try(env, lock); - cl_lock_unhold(env, lock, scope, source); - cl_lock_mutex_put(env, lock); - cl_lock_put(env, lock); - lock = NULL; - } - - return lock; -} -EXPORT_SYMBOL(cl_lock_peek); - -/** - * Returns a slice within a lock, corresponding to the given layer in the - * device stack. - * - * \see cl_page_at() - */ -const struct cl_lock_slice *cl_lock_at(const struct cl_lock *lock, - const struct lu_device_type *dtype) -{ - const struct cl_lock_slice *slice; - - LINVRNT(cl_lock_invariant_trusted(NULL, lock)); - - list_for_each_entry(slice, &lock->cll_layers, cls_linkage) { - if (slice->cls_obj->co_lu.lo_dev->ld_type == dtype) - return slice; - } - return NULL; -} -EXPORT_SYMBOL(cl_lock_at); - -static void cl_lock_mutex_tail(const struct lu_env *env, struct cl_lock *lock) -{ - struct cl_thread_counters *counters; - - counters = cl_lock_counters(env, lock); - lock->cll_depth++; - counters->ctc_nr_locks_locked++; - lu_ref_add(&counters->ctc_locks_locked, "cll_guard", lock); - cl_lock_trace(D_TRACE, env, "got mutex", lock); -} - -/** - * Locks cl_lock object. - * - * This is used to manipulate cl_lock fields, and to serialize state - * transitions in the lock state machine. - * - * \post cl_lock_is_mutexed(lock) - * - * \see cl_lock_mutex_put() - */ -void cl_lock_mutex_get(const struct lu_env *env, struct cl_lock *lock) -{ - LINVRNT(cl_lock_invariant(env, lock)); - - if (lock->cll_guarder == current) { - LINVRNT(cl_lock_is_mutexed(lock)); - LINVRNT(lock->cll_depth > 0); - } else { - struct cl_object_header *hdr; - struct cl_thread_info *info; - int i; - - LINVRNT(lock->cll_guarder != current); - hdr = cl_object_header(lock->cll_descr.cld_obj); - /* - * Check that mutices are taken in the bottom-to-top order. - */ - info = cl_env_info(env); - for (i = 0; i < hdr->coh_nesting; ++i) - LASSERT(info->clt_counters[i].ctc_nr_locks_locked == 0); - mutex_lock_nested(&lock->cll_guard, hdr->coh_nesting); - lock->cll_guarder = current; - LINVRNT(lock->cll_depth == 0); - } - cl_lock_mutex_tail(env, lock); -} -EXPORT_SYMBOL(cl_lock_mutex_get); - -/** - * Try-locks cl_lock object. - * - * \retval 0 \a lock was successfully locked - * - * \retval -EBUSY \a lock cannot be locked right now - * - * \post ergo(result == 0, cl_lock_is_mutexed(lock)) - * - * \see cl_lock_mutex_get() - */ -static int cl_lock_mutex_try(const struct lu_env *env, struct cl_lock *lock) -{ - int result; - - LINVRNT(cl_lock_invariant_trusted(env, lock)); - - result = 0; - if (lock->cll_guarder == current) { - LINVRNT(lock->cll_depth > 0); - cl_lock_mutex_tail(env, lock); - } else if (mutex_trylock(&lock->cll_guard)) { - LINVRNT(lock->cll_depth == 0); - lock->cll_guarder = current; - cl_lock_mutex_tail(env, lock); - } else - result = -EBUSY; - return result; -} - -/** - {* Unlocks cl_lock object. - * - * \pre cl_lock_is_mutexed(lock) - * - * \see cl_lock_mutex_get() - */ -void cl_lock_mutex_put(const struct lu_env *env, struct cl_lock *lock) -{ - struct cl_thread_counters *counters; - - LINVRNT(cl_lock_invariant(env, lock)); - LINVRNT(cl_lock_is_mutexed(lock)); - LINVRNT(lock->cll_guarder == current); - LINVRNT(lock->cll_depth > 0); - - counters = cl_lock_counters(env, lock); - LINVRNT(counters->ctc_nr_locks_locked > 0); - - cl_lock_trace(D_TRACE, env, "put mutex", lock); - lu_ref_del(&counters->ctc_locks_locked, "cll_guard", lock); - counters->ctc_nr_locks_locked--; - if (--lock->cll_depth == 0) { - lock->cll_guarder = NULL; - mutex_unlock(&lock->cll_guard); - } -} -EXPORT_SYMBOL(cl_lock_mutex_put); - -/** - * Returns true iff lock's mutex is owned by the current thread. - */ -int cl_lock_is_mutexed(struct cl_lock *lock) -{ - return lock->cll_guarder == current; -} -EXPORT_SYMBOL(cl_lock_is_mutexed); - -/** - * Returns number of cl_lock mutices held by the current thread (environment). - */ -int cl_lock_nr_mutexed(const struct lu_env *env) -{ - struct cl_thread_info *info; - int i; - int locked; - - /* - * NOTE: if summation across all nesting levels (currently 2) proves - * too expensive, a summary counter can be added to - * struct cl_thread_info. - */ - info = cl_env_info(env); - for (i = 0, locked = 0; i < ARRAY_SIZE(info->clt_counters); ++i) - locked += info->clt_counters[i].ctc_nr_locks_locked; - return locked; -} -EXPORT_SYMBOL(cl_lock_nr_mutexed); - -static void cl_lock_cancel0(const struct lu_env *env, struct cl_lock *lock) -{ - LINVRNT(cl_lock_is_mutexed(lock)); - LINVRNT(cl_lock_invariant(env, lock)); - if (!(lock->cll_flags & CLF_CANCELLED)) { - const struct cl_lock_slice *slice; - - lock->cll_flags |= CLF_CANCELLED; - list_for_each_entry_reverse(slice, &lock->cll_layers, - cls_linkage) { - if (slice->cls_ops->clo_cancel) - slice->cls_ops->clo_cancel(env, slice); - } - } -} - -static void cl_lock_delete0(const struct lu_env *env, struct cl_lock *lock) -{ - struct cl_object_header *head; - const struct cl_lock_slice *slice; - - LINVRNT(cl_lock_is_mutexed(lock)); - LINVRNT(cl_lock_invariant(env, lock)); - - if (lock->cll_state < CLS_FREEING) { - bool in_cache; - - LASSERT(lock->cll_state != CLS_INTRANSIT); - cl_lock_state_set(env, lock, CLS_FREEING); - - head = cl_object_header(lock->cll_descr.cld_obj); - - spin_lock(&head->coh_lock_guard); - in_cache = !list_empty(&lock->cll_linkage); - if (in_cache) - list_del_init(&lock->cll_linkage); - spin_unlock(&head->coh_lock_guard); - - if (in_cache) /* coh_locks cache holds a refcount. */ - cl_lock_put(env, lock); - - /* - * From now on, no new references to this lock can be acquired - * by cl_lock_lookup(). - */ - list_for_each_entry_reverse(slice, &lock->cll_layers, - cls_linkage) { - if (slice->cls_ops->clo_delete) - slice->cls_ops->clo_delete(env, slice); - } - /* - * From now on, no new references to this lock can be acquired - * by layer-specific means (like a pointer from struct - * ldlm_lock in osc, or a pointer from top-lock to sub-lock in - * lov). - * - * Lock will be finally freed in cl_lock_put() when last of - * existing references goes away. - */ - } -} - -/** - * Mod(ifie)s cl_lock::cll_holds counter for a given lock. Also, for a - * top-lock (nesting == 0) accounts for this modification in the per-thread - * debugging counters. Sub-lock holds can be released by a thread different - * from one that acquired it. - */ -static void cl_lock_hold_mod(const struct lu_env *env, struct cl_lock *lock, - int delta) -{ - struct cl_thread_counters *counters; - enum clt_nesting_level nesting; - - lock->cll_holds += delta; - nesting = cl_lock_nesting(lock); - if (nesting == CNL_TOP) { - counters = &cl_env_info(env)->clt_counters[CNL_TOP]; - counters->ctc_nr_held += delta; - LASSERT(counters->ctc_nr_held >= 0); - } -} - -/** - * Mod(ifie)s cl_lock::cll_users counter for a given lock. See - * cl_lock_hold_mod() for the explanation of the debugging code. - */ -static void cl_lock_used_mod(const struct lu_env *env, struct cl_lock *lock, - int delta) -{ - struct cl_thread_counters *counters; - enum clt_nesting_level nesting; - - lock->cll_users += delta; - nesting = cl_lock_nesting(lock); - if (nesting == CNL_TOP) { - counters = &cl_env_info(env)->clt_counters[CNL_TOP]; - counters->ctc_nr_used += delta; - LASSERT(counters->ctc_nr_used >= 0); - } -} - -void cl_lock_hold_release(const struct lu_env *env, struct cl_lock *lock, - const char *scope, const void *source) -{ - LINVRNT(cl_lock_is_mutexed(lock)); - LINVRNT(cl_lock_invariant(env, lock)); - LASSERT(lock->cll_holds > 0); - - cl_lock_trace(D_DLMTRACE, env, "hold release lock", lock); - lu_ref_del(&lock->cll_holders, scope, source); - cl_lock_hold_mod(env, lock, -1); - if (lock->cll_holds == 0) { - CL_LOCK_ASSERT(lock->cll_state != CLS_HELD, env, lock); - if (lock->cll_descr.cld_mode == CLM_PHANTOM || - lock->cll_descr.cld_mode == CLM_GROUP || - lock->cll_state != CLS_CACHED) - /* - * If lock is still phantom or grouplock when user is - * done with it---destroy the lock. - */ - lock->cll_flags |= CLF_CANCELPEND|CLF_DOOMED; - if (lock->cll_flags & CLF_CANCELPEND) { - lock->cll_flags &= ~CLF_CANCELPEND; - cl_lock_cancel0(env, lock); - } - if (lock->cll_flags & CLF_DOOMED) { - /* no longer doomed: it's dead... Jim. */ - lock->cll_flags &= ~CLF_DOOMED; - cl_lock_delete0(env, lock); - } - } -} -EXPORT_SYMBOL(cl_lock_hold_release); - -/** - * Waits until lock state is changed. - * - * This function is called with cl_lock mutex locked, atomically releases - * mutex and goes to sleep, waiting for a lock state change (signaled by - * cl_lock_signal()), and re-acquires the mutex before return. - * - * This function is used to wait until lock state machine makes some progress - * and to emulate synchronous operations on top of asynchronous lock - * interface. - * - * \retval -EINTR wait was interrupted - * - * \retval 0 wait wasn't interrupted - * - * \pre cl_lock_is_mutexed(lock) - * - * \see cl_lock_signal() - */ -int cl_lock_state_wait(const struct lu_env *env, struct cl_lock *lock) -{ - wait_queue_t waiter; - sigset_t blocked; - int result; - - LINVRNT(cl_lock_is_mutexed(lock)); - LINVRNT(cl_lock_invariant(env, lock)); - LASSERT(lock->cll_depth == 1); - LASSERT(lock->cll_state != CLS_FREEING); /* too late to wait */ - - cl_lock_trace(D_DLMTRACE, env, "state wait lock", lock); - result = lock->cll_error; - if (result == 0) { - /* To avoid being interrupted by the 'non-fatal' signals - * (SIGCHLD, for instance), we'd block them temporarily. - * LU-305 - */ - blocked = cfs_block_sigsinv(LUSTRE_FATAL_SIGS); - - init_waitqueue_entry(&waiter, current); - add_wait_queue(&lock->cll_wq, &waiter); - set_current_state(TASK_INTERRUPTIBLE); - cl_lock_mutex_put(env, lock); - - LASSERT(cl_lock_nr_mutexed(env) == 0); - - /* Returning ERESTARTSYS instead of EINTR so syscalls - * can be restarted if signals are pending here - */ - result = -ERESTARTSYS; - if (likely(!OBD_FAIL_CHECK(OBD_FAIL_LOCK_STATE_WAIT_INTR))) { - schedule(); - if (!signal_pending(current)) - result = 0; - } - - cl_lock_mutex_get(env, lock); - set_current_state(TASK_RUNNING); - remove_wait_queue(&lock->cll_wq, &waiter); - - /* Restore old blocked signals */ - cfs_restore_sigs(blocked); - } - return result; -} -EXPORT_SYMBOL(cl_lock_state_wait); - -static void cl_lock_state_signal(const struct lu_env *env, struct cl_lock *lock, - enum cl_lock_state state) -{ - const struct cl_lock_slice *slice; - - LINVRNT(cl_lock_is_mutexed(lock)); - LINVRNT(cl_lock_invariant(env, lock)); - - list_for_each_entry(slice, &lock->cll_layers, cls_linkage) - if (slice->cls_ops->clo_state) - slice->cls_ops->clo_state(env, slice, state); - wake_up_all(&lock->cll_wq); -} - -/** - * Notifies waiters that lock state changed. - * - * Wakes up all waiters sleeping in cl_lock_state_wait(), also notifies all - * layers about state change by calling cl_lock_operations::clo_state() - * top-to-bottom. - */ -void cl_lock_signal(const struct lu_env *env, struct cl_lock *lock) -{ - cl_lock_trace(D_DLMTRACE, env, "state signal lock", lock); - cl_lock_state_signal(env, lock, lock->cll_state); -} -EXPORT_SYMBOL(cl_lock_signal); - -/** - * Changes lock state. - * - * This function is invoked to notify layers that lock state changed, possible - * as a result of an asynchronous event such as call-back reception. - * - * \post lock->cll_state == state - * - * \see cl_lock_operations::clo_state() - */ -void cl_lock_state_set(const struct lu_env *env, struct cl_lock *lock, - enum cl_lock_state state) -{ - LASSERT(lock->cll_state <= state || - (lock->cll_state == CLS_CACHED && - (state == CLS_HELD || /* lock found in cache */ - state == CLS_NEW || /* sub-lock canceled */ - state == CLS_INTRANSIT)) || - /* lock is in transit state */ - lock->cll_state == CLS_INTRANSIT); - - if (lock->cll_state != state) { - CS_LOCKSTATE_DEC(lock->cll_descr.cld_obj, lock->cll_state); - CS_LOCKSTATE_INC(lock->cll_descr.cld_obj, state); - - cl_lock_state_signal(env, lock, state); - lock->cll_state = state; - } -} -EXPORT_SYMBOL(cl_lock_state_set); - -static int cl_unuse_try_internal(const struct lu_env *env, struct cl_lock *lock) -{ - const struct cl_lock_slice *slice; - int result; - - do { - result = 0; - - LINVRNT(cl_lock_is_mutexed(lock)); - LINVRNT(cl_lock_invariant(env, lock)); - LASSERT(lock->cll_state == CLS_INTRANSIT); - - result = -ENOSYS; - list_for_each_entry_reverse(slice, &lock->cll_layers, - cls_linkage) { - if (slice->cls_ops->clo_unuse) { - result = slice->cls_ops->clo_unuse(env, slice); - if (result != 0) - break; - } - } - LASSERT(result != -ENOSYS); - } while (result == CLO_REPEAT); - - return result; -} - -/** - * Yanks lock from the cache (cl_lock_state::CLS_CACHED state) by calling - * cl_lock_operations::clo_use() top-to-bottom to notify layers. - * @atomic = 1, it must unuse the lock to recovery the lock to keep the - * use process atomic - */ -int cl_use_try(const struct lu_env *env, struct cl_lock *lock, int atomic) -{ - const struct cl_lock_slice *slice; - int result; - enum cl_lock_state state; - - cl_lock_trace(D_DLMTRACE, env, "use lock", lock); - - LASSERT(lock->cll_state == CLS_CACHED); - if (lock->cll_error) - return lock->cll_error; - - result = -ENOSYS; - state = cl_lock_intransit(env, lock); - list_for_each_entry(slice, &lock->cll_layers, cls_linkage) { - if (slice->cls_ops->clo_use) { - result = slice->cls_ops->clo_use(env, slice); - if (result != 0) - break; - } - } - LASSERT(result != -ENOSYS); - - LASSERTF(lock->cll_state == CLS_INTRANSIT, "Wrong state %d.\n", - lock->cll_state); - - if (result == 0) { - state = CLS_HELD; - } else { - if (result == -ESTALE) { - /* - * ESTALE means sublock being cancelled - * at this time, and set lock state to - * be NEW here and ask the caller to repeat. - */ - state = CLS_NEW; - result = CLO_REPEAT; - } - - /* @atomic means back-off-on-failure. */ - if (atomic) { - int rc; - - rc = cl_unuse_try_internal(env, lock); - /* Vet the results. */ - if (rc < 0 && result > 0) - result = rc; - } - - } - cl_lock_extransit(env, lock, state); - return result; -} -EXPORT_SYMBOL(cl_use_try); - -/** - * Helper for cl_enqueue_try() that calls ->clo_enqueue() across all layers - * top-to-bottom. - */ -static int cl_enqueue_kick(const struct lu_env *env, - struct cl_lock *lock, - struct cl_io *io, __u32 flags) -{ - int result; - const struct cl_lock_slice *slice; - - result = -ENOSYS; - list_for_each_entry(slice, &lock->cll_layers, cls_linkage) { - if (slice->cls_ops->clo_enqueue) { - result = slice->cls_ops->clo_enqueue(env, - slice, io, flags); - if (result != 0) - break; - } - } - LASSERT(result != -ENOSYS); - return result; -} - -/** - * Tries to enqueue a lock. - * - * This function is called repeatedly by cl_enqueue() until either lock is - * enqueued, or error occurs. This function does not block waiting for - * networking communication to complete. - * - * \post ergo(result == 0, lock->cll_state == CLS_ENQUEUED || - * lock->cll_state == CLS_HELD) - * - * \see cl_enqueue() cl_lock_operations::clo_enqueue() - * \see cl_lock_state::CLS_ENQUEUED - */ -int cl_enqueue_try(const struct lu_env *env, struct cl_lock *lock, - struct cl_io *io, __u32 flags) -{ - int result; - - cl_lock_trace(D_DLMTRACE, env, "enqueue lock", lock); - do { - LINVRNT(cl_lock_is_mutexed(lock)); - - result = lock->cll_error; - if (result != 0) - break; - - switch (lock->cll_state) { - case CLS_NEW: - cl_lock_state_set(env, lock, CLS_QUEUING); - /* fall-through */ - case CLS_QUEUING: - /* kick layers. */ - result = cl_enqueue_kick(env, lock, io, flags); - /* For AGL case, the cl_lock::cll_state may - * become CLS_HELD already. - */ - if (result == 0 && lock->cll_state == CLS_QUEUING) - cl_lock_state_set(env, lock, CLS_ENQUEUED); - break; - case CLS_INTRANSIT: - LASSERT(cl_lock_is_intransit(lock)); - result = CLO_WAIT; - break; - case CLS_CACHED: - /* yank lock from the cache. */ - result = cl_use_try(env, lock, 0); - break; - case CLS_ENQUEUED: - case CLS_HELD: - result = 0; - break; - default: - case CLS_FREEING: - /* - * impossible, only held locks with increased - * ->cll_holds can be enqueued, and they cannot be - * freed. - */ - LBUG(); - } - } while (result == CLO_REPEAT); - return result; -} -EXPORT_SYMBOL(cl_enqueue_try); - -/** - * Cancel the conflicting lock found during previous enqueue. - * - * \retval 0 conflicting lock has been canceled. - * \retval -ve error code. - */ -int cl_lock_enqueue_wait(const struct lu_env *env, - struct cl_lock *lock, - int keep_mutex) -{ - struct cl_lock *conflict; - int rc = 0; - - LASSERT(cl_lock_is_mutexed(lock)); - LASSERT(lock->cll_state == CLS_QUEUING); - LASSERT(lock->cll_conflict); - - conflict = lock->cll_conflict; - lock->cll_conflict = NULL; - - cl_lock_mutex_put(env, lock); - LASSERT(cl_lock_nr_mutexed(env) == 0); - - cl_lock_mutex_get(env, conflict); - cl_lock_trace(D_DLMTRACE, env, "enqueue wait", conflict); - cl_lock_cancel(env, conflict); - cl_lock_delete(env, conflict); - - while (conflict->cll_state != CLS_FREEING) { - rc = cl_lock_state_wait(env, conflict); - if (rc != 0) - break; - } - cl_lock_mutex_put(env, conflict); - lu_ref_del(&conflict->cll_reference, "cancel-wait", lock); - cl_lock_put(env, conflict); - - if (keep_mutex) - cl_lock_mutex_get(env, lock); - - LASSERT(rc <= 0); - return rc; -} -EXPORT_SYMBOL(cl_lock_enqueue_wait); - -static int cl_enqueue_locked(const struct lu_env *env, struct cl_lock *lock, - struct cl_io *io, __u32 enqflags) +static void cl_lock_trace0(int level, const struct lu_env *env, + const char *prefix, const struct cl_lock *lock, + const char *func, const int line) { - int result; - - LINVRNT(cl_lock_is_mutexed(lock)); - LINVRNT(cl_lock_invariant(env, lock)); - LASSERT(lock->cll_holds > 0); + struct cl_object_header *h = cl_object_header(lock->cll_descr.cld_obj); - cl_lock_user_add(env, lock); - do { - result = cl_enqueue_try(env, lock, io, enqflags); - if (result == CLO_WAIT) { - if (lock->cll_conflict) - result = cl_lock_enqueue_wait(env, lock, 1); - else - result = cl_lock_state_wait(env, lock); - if (result == 0) - continue; - } - break; - } while (1); - if (result != 0) - cl_unuse_try(env, lock); - LASSERT(ergo(result == 0 && !(enqflags & CEF_AGL), - lock->cll_state == CLS_ENQUEUED || - lock->cll_state == CLS_HELD)); - return result; + CDEBUG(level, "%s: %p (%p/%d) at %s():%d\n", + prefix, lock, env, h->coh_nesting, func, line); } +#define cl_lock_trace(level, env, prefix, lock) \ + cl_lock_trace0(level, env, prefix, lock, __func__, __LINE__) /** - * Tries to unlock a lock. - * - * This function is called to release underlying resource: - * 1. for top lock, the resource is sublocks it held; - * 2. for sublock, the resource is the reference to dlmlock. + * Adds lock slice to the compound lock. * - * cl_unuse_try is a one-shot operation, so it must NOT return CLO_WAIT. + * This is called by cl_object_operations::coo_lock_init() methods to add a + * per-layer state to the lock. New state is added at the end of + * cl_lock::cll_layers list, that is, it is at the bottom of the stack. * - * \see cl_unuse() cl_lock_operations::clo_unuse() - * \see cl_lock_state::CLS_CACHED + * \see cl_req_slice_add(), cl_page_slice_add(), cl_io_slice_add() */ -int cl_unuse_try(const struct lu_env *env, struct cl_lock *lock) +void cl_lock_slice_add(struct cl_lock *lock, struct cl_lock_slice *slice, + struct cl_object *obj, + const struct cl_lock_operations *ops) { - int result; - enum cl_lock_state state = CLS_NEW; - - cl_lock_trace(D_DLMTRACE, env, "unuse lock", lock); - - if (lock->cll_users > 1) { - cl_lock_user_del(env, lock); - return 0; - } - - /* Only if the lock is in CLS_HELD or CLS_ENQUEUED state, it can hold - * underlying resources. - */ - if (!(lock->cll_state == CLS_HELD || lock->cll_state == CLS_ENQUEUED)) { - cl_lock_user_del(env, lock); - return 0; - } - - /* - * New lock users (->cll_users) are not protecting unlocking - * from proceeding. From this point, lock eventually reaches - * CLS_CACHED, is reinitialized to CLS_NEW or fails into - * CLS_FREEING. - */ - state = cl_lock_intransit(env, lock); - - result = cl_unuse_try_internal(env, lock); - LASSERT(lock->cll_state == CLS_INTRANSIT); - LASSERT(result != CLO_WAIT); - cl_lock_user_del(env, lock); - if (result == 0 || result == -ESTALE) { - /* - * Return lock back to the cache. This is the only - * place where lock is moved into CLS_CACHED state. - * - * If one of ->clo_unuse() methods returned -ESTALE, lock - * cannot be placed into cache and has to be - * re-initialized. This happens e.g., when a sub-lock was - * canceled while unlocking was in progress. - */ - if (state == CLS_HELD && result == 0) - state = CLS_CACHED; - else - state = CLS_NEW; - cl_lock_extransit(env, lock, state); - - /* - * Hide -ESTALE error. - * If the lock is a glimpse lock, and it has multiple - * stripes. Assuming that one of its sublock returned -ENAVAIL, - * and other sublocks are matched write locks. In this case, - * we can't set this lock to error because otherwise some of - * its sublocks may not be canceled. This causes some dirty - * pages won't be written to OSTs. -jay - */ - result = 0; - } else { - CERROR("result = %d, this is unlikely!\n", result); - state = CLS_NEW; - cl_lock_extransit(env, lock, state); - } - return result ?: lock->cll_error; + slice->cls_lock = lock; + list_add_tail(&slice->cls_linkage, &lock->cll_layers); + slice->cls_obj = obj; + slice->cls_ops = ops; } -EXPORT_SYMBOL(cl_unuse_try); +EXPORT_SYMBOL(cl_lock_slice_add); -static void cl_unuse_locked(const struct lu_env *env, struct cl_lock *lock) +void cl_lock_fini(const struct lu_env *env, struct cl_lock *lock) { - int result; + cl_lock_trace(D_DLMTRACE, env, "destroy lock", lock); - result = cl_unuse_try(env, lock); - if (result) - CL_LOCK_DEBUG(D_ERROR, env, lock, "unuse return %d\n", result); -} + while (!list_empty(&lock->cll_layers)) { + struct cl_lock_slice *slice; -/** - * Unlocks a lock. - */ -void cl_unuse(const struct lu_env *env, struct cl_lock *lock) -{ - cl_lock_mutex_get(env, lock); - cl_unuse_locked(env, lock); - cl_lock_mutex_put(env, lock); - cl_lock_lockdep_release(env, lock); + slice = list_entry(lock->cll_layers.next, + struct cl_lock_slice, cls_linkage); + list_del_init(lock->cll_layers.next); + slice->cls_ops->clo_fini(env, slice); + } + POISON(lock, 0x5a, sizeof(*lock)); } -EXPORT_SYMBOL(cl_unuse); +EXPORT_SYMBOL(cl_lock_fini); -/** - * Tries to wait for a lock. - * - * This function is called repeatedly by cl_wait() until either lock is - * granted, or error occurs. This function does not block waiting for network - * communication to complete. - * - * \see cl_wait() cl_lock_operations::clo_wait() - * \see cl_lock_state::CLS_HELD - */ -int cl_wait_try(const struct lu_env *env, struct cl_lock *lock) +int cl_lock_init(const struct lu_env *env, struct cl_lock *lock, + const struct cl_io *io) { - const struct cl_lock_slice *slice; - int result; - - cl_lock_trace(D_DLMTRACE, env, "wait lock try", lock); - do { - LINVRNT(cl_lock_is_mutexed(lock)); - LINVRNT(cl_lock_invariant(env, lock)); - LASSERTF(lock->cll_state == CLS_QUEUING || - lock->cll_state == CLS_ENQUEUED || - lock->cll_state == CLS_HELD || - lock->cll_state == CLS_INTRANSIT, - "lock state: %d\n", lock->cll_state); - LASSERT(lock->cll_users > 0); - LASSERT(lock->cll_holds > 0); + struct cl_object *obj = lock->cll_descr.cld_obj; + struct cl_object *scan; + int result = 0; - result = lock->cll_error; - if (result != 0) - break; + /* Make sure cl_lock::cll_descr is initialized. */ + LASSERT(obj); - if (cl_lock_is_intransit(lock)) { - result = CLO_WAIT; + INIT_LIST_HEAD(&lock->cll_layers); + list_for_each_entry(scan, &obj->co_lu.lo_header->loh_layers, + co_lu.lo_linkage) { + result = scan->co_ops->coo_lock_init(env, scan, lock, io); + if (result != 0) { + cl_lock_fini(env, lock); break; } + } - if (lock->cll_state == CLS_HELD) - /* nothing to do */ - break; - - result = -ENOSYS; - list_for_each_entry(slice, &lock->cll_layers, cls_linkage) { - if (slice->cls_ops->clo_wait) { - result = slice->cls_ops->clo_wait(env, slice); - if (result != 0) - break; - } - } - LASSERT(result != -ENOSYS); - if (result == 0) { - LASSERT(lock->cll_state != CLS_INTRANSIT); - cl_lock_state_set(env, lock, CLS_HELD); - } - } while (result == CLO_REPEAT); return result; } -EXPORT_SYMBOL(cl_wait_try); +EXPORT_SYMBOL(cl_lock_init); /** - * Waits until enqueued lock is granted. - * - * \pre current thread or io owns a hold on the lock - * \pre ergo(result == 0, lock->cll_state == CLS_ENQUEUED || - * lock->cll_state == CLS_HELD) + * Returns a slice with a lock, corresponding to the given layer in the + * device stack. * - * \post ergo(result == 0, lock->cll_state == CLS_HELD) - */ -int cl_wait(const struct lu_env *env, struct cl_lock *lock) -{ - int result; - - cl_lock_mutex_get(env, lock); - - LINVRNT(cl_lock_invariant(env, lock)); - LASSERTF(lock->cll_state == CLS_ENQUEUED || lock->cll_state == CLS_HELD, - "Wrong state %d\n", lock->cll_state); - LASSERT(lock->cll_holds > 0); - - do { - result = cl_wait_try(env, lock); - if (result == CLO_WAIT) { - result = cl_lock_state_wait(env, lock); - if (result == 0) - continue; - } - break; - } while (1); - if (result < 0) { - cl_unuse_try(env, lock); - cl_lock_lockdep_release(env, lock); - } - cl_lock_trace(D_DLMTRACE, env, "wait lock", lock); - cl_lock_mutex_put(env, lock); - LASSERT(ergo(result == 0, lock->cll_state == CLS_HELD)); - return result; -} -EXPORT_SYMBOL(cl_wait); - -/** - * Executes cl_lock_operations::clo_weigh(), and sums results to estimate lock - * value. + * \see cl_page_at() */ -unsigned long cl_lock_weigh(const struct lu_env *env, struct cl_lock *lock) +const struct cl_lock_slice *cl_lock_at(const struct cl_lock *lock, + const struct lu_device_type *dtype) { const struct cl_lock_slice *slice; - unsigned long pound; - unsigned long ounce; - LINVRNT(cl_lock_is_mutexed(lock)); - LINVRNT(cl_lock_invariant(env, lock)); - - pound = 0; - list_for_each_entry_reverse(slice, &lock->cll_layers, cls_linkage) { - if (slice->cls_ops->clo_weigh) { - ounce = slice->cls_ops->clo_weigh(env, slice); - pound += ounce; - if (pound < ounce) /* over-weight^Wflow */ - pound = ~0UL; - } + list_for_each_entry(slice, &lock->cll_layers, cls_linkage) { + if (slice->cls_obj->co_lu.lo_dev->ld_type == dtype) + return slice; } - return pound; + return NULL; } -EXPORT_SYMBOL(cl_lock_weigh); +EXPORT_SYMBOL(cl_lock_at); -/** - * Notifies layers that lock description changed. - * - * The server can grant client a lock different from one that was requested - * (e.g., larger in extent). This method is called when actually granted lock - * description becomes known to let layers to accommodate for changed lock - * description. - * - * \see cl_lock_operations::clo_modify() - */ -int cl_lock_modify(const struct lu_env *env, struct cl_lock *lock, - const struct cl_lock_descr *desc) +void cl_lock_cancel(const struct lu_env *env, struct cl_lock *lock) { const struct cl_lock_slice *slice; - struct cl_object *obj = lock->cll_descr.cld_obj; - struct cl_object_header *hdr = cl_object_header(obj); - int result; - - cl_lock_trace(D_DLMTRACE, env, "modify lock", lock); - /* don't allow object to change */ - LASSERT(obj == desc->cld_obj); - LINVRNT(cl_lock_is_mutexed(lock)); - LINVRNT(cl_lock_invariant(env, lock)); + cl_lock_trace(D_DLMTRACE, env, "cancel lock", lock); list_for_each_entry_reverse(slice, &lock->cll_layers, cls_linkage) { - if (slice->cls_ops->clo_modify) { - result = slice->cls_ops->clo_modify(env, slice, desc); - if (result != 0) - return result; - } - } - CL_LOCK_DEBUG(D_DLMTRACE, env, lock, " -> "DDESCR"@"DFID"\n", - PDESCR(desc), PFID(lu_object_fid(&desc->cld_obj->co_lu))); - /* - * Just replace description in place. Nothing more is needed for - * now. If locks were indexed according to their extent and/or mode, - * that index would have to be updated here. - */ - spin_lock(&hdr->coh_lock_guard); - lock->cll_descr = *desc; - spin_unlock(&hdr->coh_lock_guard); - return 0; -} -EXPORT_SYMBOL(cl_lock_modify); - -/** - * Initializes lock closure with a given origin. - * - * \see cl_lock_closure - */ -void cl_lock_closure_init(const struct lu_env *env, - struct cl_lock_closure *closure, - struct cl_lock *origin, int wait) -{ - LINVRNT(cl_lock_is_mutexed(origin)); - LINVRNT(cl_lock_invariant(env, origin)); - - INIT_LIST_HEAD(&closure->clc_list); - closure->clc_origin = origin; - closure->clc_wait = wait; - closure->clc_nr = 0; -} -EXPORT_SYMBOL(cl_lock_closure_init); - -/** - * Builds a closure of \a lock. - * - * Building of a closure consists of adding initial lock (\a lock) into it, - * and calling cl_lock_operations::clo_closure() methods of \a lock. These - * methods might call cl_lock_closure_build() recursively again, adding more - * locks to the closure, etc. - * - * \see cl_lock_closure - */ -int cl_lock_closure_build(const struct lu_env *env, struct cl_lock *lock, - struct cl_lock_closure *closure) -{ - const struct cl_lock_slice *slice; - int result; - - LINVRNT(cl_lock_is_mutexed(closure->clc_origin)); - LINVRNT(cl_lock_invariant(env, closure->clc_origin)); - - result = cl_lock_enclosure(env, lock, closure); - if (result == 0) { - list_for_each_entry(slice, &lock->cll_layers, cls_linkage) { - if (slice->cls_ops->clo_closure) { - result = slice->cls_ops->clo_closure(env, slice, - closure); - if (result != 0) - break; - } - } - } - if (result != 0) - cl_lock_disclosure(env, closure); - return result; -} -EXPORT_SYMBOL(cl_lock_closure_build); - -/** - * Adds new lock to a closure. - * - * Try-locks \a lock and if succeeded, adds it to the closure (never more than - * once). If try-lock failed, returns CLO_REPEAT, after optionally waiting - * until next try-lock is likely to succeed. - */ -int cl_lock_enclosure(const struct lu_env *env, struct cl_lock *lock, - struct cl_lock_closure *closure) -{ - int result = 0; - - cl_lock_trace(D_DLMTRACE, env, "enclosure lock", lock); - if (!cl_lock_mutex_try(env, lock)) { - /* - * If lock->cll_inclosure is not empty, lock is already in - * this closure. - */ - if (list_empty(&lock->cll_inclosure)) { - cl_lock_get_trust(lock); - lu_ref_add(&lock->cll_reference, "closure", closure); - list_add(&lock->cll_inclosure, &closure->clc_list); - closure->clc_nr++; - } else - cl_lock_mutex_put(env, lock); - result = 0; - } else { - cl_lock_disclosure(env, closure); - if (closure->clc_wait) { - cl_lock_get_trust(lock); - lu_ref_add(&lock->cll_reference, "closure-w", closure); - cl_lock_mutex_put(env, closure->clc_origin); - - LASSERT(cl_lock_nr_mutexed(env) == 0); - cl_lock_mutex_get(env, lock); - cl_lock_mutex_put(env, lock); - - cl_lock_mutex_get(env, closure->clc_origin); - lu_ref_del(&lock->cll_reference, "closure-w", closure); - cl_lock_put(env, lock); - } - result = CLO_REPEAT; - } - return result; -} -EXPORT_SYMBOL(cl_lock_enclosure); - -/** Releases mutices of enclosed locks. */ -void cl_lock_disclosure(const struct lu_env *env, - struct cl_lock_closure *closure) -{ - struct cl_lock *scan; - struct cl_lock *temp; - - cl_lock_trace(D_DLMTRACE, env, "disclosure lock", closure->clc_origin); - list_for_each_entry_safe(scan, temp, &closure->clc_list, - cll_inclosure) { - list_del_init(&scan->cll_inclosure); - cl_lock_mutex_put(env, scan); - lu_ref_del(&scan->cll_reference, "closure", closure); - cl_lock_put(env, scan); - closure->clc_nr--; - } - LASSERT(closure->clc_nr == 0); -} -EXPORT_SYMBOL(cl_lock_disclosure); - -/** Finalizes a closure. */ -void cl_lock_closure_fini(struct cl_lock_closure *closure) -{ - LASSERT(closure->clc_nr == 0); - LASSERT(list_empty(&closure->clc_list)); -} -EXPORT_SYMBOL(cl_lock_closure_fini); - -/** - * Destroys this lock. Notifies layers (bottom-to-top) that lock is being - * destroyed, then destroy the lock. If there are holds on the lock, postpone - * destruction until all holds are released. This is called when a decision is - * made to destroy the lock in the future. E.g., when a blocking AST is - * received on it, or fatal communication error happens. - * - * Caller must have a reference on this lock to prevent a situation, when - * deleted lock lingers in memory for indefinite time, because nobody calls - * cl_lock_put() to finish it. - * - * \pre atomic_read(&lock->cll_ref) > 0 - * \pre ergo(cl_lock_nesting(lock) == CNL_TOP, - * cl_lock_nr_mutexed(env) == 1) - * [i.e., if a top-lock is deleted, mutices of no other locks can be - * held, as deletion of sub-locks might require releasing a top-lock - * mutex] - * - * \see cl_lock_operations::clo_delete() - * \see cl_lock::cll_holds - */ -void cl_lock_delete(const struct lu_env *env, struct cl_lock *lock) -{ - LINVRNT(cl_lock_is_mutexed(lock)); - LINVRNT(cl_lock_invariant(env, lock)); - LASSERT(ergo(cl_lock_nesting(lock) == CNL_TOP, - cl_lock_nr_mutexed(env) == 1)); - - cl_lock_trace(D_DLMTRACE, env, "delete lock", lock); - if (lock->cll_holds == 0) - cl_lock_delete0(env, lock); - else - lock->cll_flags |= CLF_DOOMED; -} -EXPORT_SYMBOL(cl_lock_delete); - -/** - * Mark lock as irrecoverably failed, and mark it for destruction. This - * happens when, e.g., server fails to grant a lock to us, or networking - * time-out happens. - * - * \pre atomic_read(&lock->cll_ref) > 0 - * - * \see clo_lock_delete() - * \see cl_lock::cll_holds - */ -void cl_lock_error(const struct lu_env *env, struct cl_lock *lock, int error) -{ - LINVRNT(cl_lock_is_mutexed(lock)); - LINVRNT(cl_lock_invariant(env, lock)); - - if (lock->cll_error == 0 && error != 0) { - cl_lock_trace(D_DLMTRACE, env, "set lock error", lock); - lock->cll_error = error; - cl_lock_signal(env, lock); - cl_lock_cancel(env, lock); - cl_lock_delete(env, lock); + if (slice->cls_ops->clo_cancel) + slice->cls_ops->clo_cancel(env, slice); } } -EXPORT_SYMBOL(cl_lock_error); - -/** - * Cancels this lock. Notifies layers - * (bottom-to-top) that lock is being cancelled, then destroy the lock. If - * there are holds on the lock, postpone cancellation until - * all holds are released. - * - * Cancellation notification is delivered to layers at most once. - * - * \see cl_lock_operations::clo_cancel() - * \see cl_lock::cll_holds - */ -void cl_lock_cancel(const struct lu_env *env, struct cl_lock *lock) -{ - LINVRNT(cl_lock_is_mutexed(lock)); - LINVRNT(cl_lock_invariant(env, lock)); - - cl_lock_trace(D_DLMTRACE, env, "cancel lock", lock); - if (lock->cll_holds == 0) - cl_lock_cancel0(env, lock); - else - lock->cll_flags |= CLF_CANCELPEND; -} EXPORT_SYMBOL(cl_lock_cancel); /** - * Finds an existing lock covering given index and optionally different from a - * given \a except lock. + * Enqueue a lock. + * \param anchor: if we need to wait for resources before getting the lock, + * use @anchor for the purpose. + * \retval 0 enqueue successfully + * \retval <0 error code */ -struct cl_lock *cl_lock_at_pgoff(const struct lu_env *env, - struct cl_object *obj, pgoff_t index, - struct cl_lock *except, - int pending, int canceld) +int cl_lock_enqueue(const struct lu_env *env, struct cl_io *io, + struct cl_lock *lock, struct cl_sync_io *anchor) { - struct cl_object_header *head; - struct cl_lock *scan; - struct cl_lock *lock; - struct cl_lock_descr *need; - - head = cl_object_header(obj); - need = &cl_env_info(env)->clt_descr; - lock = NULL; + const struct cl_lock_slice *slice; + int rc = -ENOSYS; - need->cld_mode = CLM_READ; /* CLM_READ matches both READ & WRITE, but - * not PHANTOM - */ - need->cld_start = need->cld_end = index; - need->cld_enq_flags = 0; + list_for_each_entry(slice, &lock->cll_layers, cls_linkage) { + if (!slice->cls_ops->clo_enqueue) + continue; - spin_lock(&head->coh_lock_guard); - /* It is fine to match any group lock since there could be only one - * with a uniq gid and it conflicts with all other lock modes too - */ - list_for_each_entry(scan, &head->coh_locks, cll_linkage) { - if (scan != except && - (scan->cll_descr.cld_mode == CLM_GROUP || - cl_lock_ext_match(&scan->cll_descr, need)) && - scan->cll_state >= CLS_HELD && - scan->cll_state < CLS_FREEING && - /* - * This check is racy as the lock can be canceled right - * after it is done, but this is fine, because page exists - * already. - */ - (canceld || !(scan->cll_flags & CLF_CANCELLED)) && - (pending || !(scan->cll_flags & CLF_CANCELPEND))) { - /* Don't increase cs_hit here since this - * is just a helper function. - */ - cl_lock_get_trust(scan); - lock = scan; + rc = slice->cls_ops->clo_enqueue(env, slice, io, anchor); + if (rc != 0) break; } - } - spin_unlock(&head->coh_lock_guard); - return lock; + return rc; } -EXPORT_SYMBOL(cl_lock_at_pgoff); +EXPORT_SYMBOL(cl_lock_enqueue); /** - * Eliminate all locks for a given object. - * - * Caller has to guarantee that no lock is in active use. - * - * \param cancel when this is set, cl_locks_prune() cancels locks before - * destroying. + * Main high-level entry point of cl_lock interface that finds existing or + * enqueues new lock matching given description. */ -void cl_locks_prune(const struct lu_env *env, struct cl_object *obj, int cancel) +int cl_lock_request(const struct lu_env *env, struct cl_io *io, + struct cl_lock *lock) { - struct cl_object_header *head; - struct cl_lock *lock; - - head = cl_object_header(obj); - - spin_lock(&head->coh_lock_guard); - while (!list_empty(&head->coh_locks)) { - lock = container_of(head->coh_locks.next, - struct cl_lock, cll_linkage); - cl_lock_get_trust(lock); - spin_unlock(&head->coh_lock_guard); - lu_ref_add(&lock->cll_reference, "prune", current); - -again: - cl_lock_mutex_get(env, lock); - if (lock->cll_state < CLS_FREEING) { - LASSERT(lock->cll_users <= 1); - if (unlikely(lock->cll_users == 1)) { - struct l_wait_info lwi = { 0 }; - - cl_lock_mutex_put(env, lock); - l_wait_event(lock->cll_wq, - lock->cll_users == 0, - &lwi); - goto again; - } - - if (cancel) - cl_lock_cancel(env, lock); - cl_lock_delete(env, lock); - } - cl_lock_mutex_put(env, lock); - lu_ref_del(&lock->cll_reference, "prune", current); - cl_lock_put(env, lock); - spin_lock(&head->coh_lock_guard); - } - spin_unlock(&head->coh_lock_guard); -} -EXPORT_SYMBOL(cl_locks_prune); + struct cl_sync_io *anchor = NULL; + __u32 enq_flags = lock->cll_descr.cld_enq_flags; + int rc; -static struct cl_lock *cl_lock_hold_mutex(const struct lu_env *env, - const struct cl_io *io, - const struct cl_lock_descr *need, - const char *scope, const void *source) -{ - struct cl_lock *lock; + rc = cl_lock_init(env, lock, io); + if (rc < 0) + return rc; - while (1) { - lock = cl_lock_find(env, io, need); - if (IS_ERR(lock)) - break; - cl_lock_mutex_get(env, lock); - if (lock->cll_state < CLS_FREEING && - !(lock->cll_flags & CLF_CANCELLED)) { - cl_lock_hold_mod(env, lock, 1); - lu_ref_add(&lock->cll_holders, scope, source); - lu_ref_add(&lock->cll_reference, scope, source); - break; - } - cl_lock_mutex_put(env, lock); - cl_lock_put(env, lock); + if ((enq_flags & CEF_ASYNC) && !(enq_flags & CEF_AGL)) { + anchor = &cl_env_info(env)->clt_anchor; + cl_sync_io_init(anchor, 1, cl_sync_io_end); } - return lock; -} -/** - * Returns a lock matching \a need description with a reference and a hold on - * it. - * - * This is much like cl_lock_find(), except that cl_lock_hold() additionally - * guarantees that lock is not in the CLS_FREEING state on return. - */ -struct cl_lock *cl_lock_hold(const struct lu_env *env, const struct cl_io *io, - const struct cl_lock_descr *need, - const char *scope, const void *source) -{ - struct cl_lock *lock; + rc = cl_lock_enqueue(env, io, lock, anchor); - lock = cl_lock_hold_mutex(env, io, need, scope, source); - if (!IS_ERR(lock)) - cl_lock_mutex_put(env, lock); - return lock; -} -EXPORT_SYMBOL(cl_lock_hold); + if (anchor) { + int rc2; -/** - * Main high-level entry point of cl_lock interface that finds existing or - * enqueues new lock matching given description. - */ -struct cl_lock *cl_lock_request(const struct lu_env *env, struct cl_io *io, - const struct cl_lock_descr *need, - const char *scope, const void *source) -{ - struct cl_lock *lock; - int rc; - __u32 enqflags = need->cld_enq_flags; + /* drop the reference count held at initialization time */ + cl_sync_io_note(env, anchor, 0); + rc2 = cl_sync_io_wait(env, anchor, 0); + if (rc2 < 0 && rc == 0) + rc = rc2; + } - do { - lock = cl_lock_hold_mutex(env, io, need, scope, source); - if (IS_ERR(lock)) - break; + if (rc < 0) + cl_lock_release(env, lock); - rc = cl_enqueue_locked(env, lock, io, enqflags); - if (rc == 0) { - if (cl_lock_fits_into(env, lock, need, io)) { - if (!(enqflags & CEF_AGL)) { - cl_lock_mutex_put(env, lock); - cl_lock_lockdep_acquire(env, lock, - enqflags); - break; - } - rc = 1; - } - cl_unuse_locked(env, lock); - } - cl_lock_trace(D_DLMTRACE, env, - rc <= 0 ? "enqueue failed" : "agl succeed", lock); - cl_lock_hold_release(env, lock, scope, source); - cl_lock_mutex_put(env, lock); - lu_ref_del(&lock->cll_reference, scope, source); - cl_lock_put(env, lock); - if (rc > 0) { - LASSERT(enqflags & CEF_AGL); - lock = NULL; - } else if (rc != 0) { - lock = ERR_PTR(rc); - } - } while (rc == 0); - return lock; + return rc; } EXPORT_SYMBOL(cl_lock_request); -/** - * Adds a hold to a known lock. - */ -void cl_lock_hold_add(const struct lu_env *env, struct cl_lock *lock, - const char *scope, const void *source) -{ - LINVRNT(cl_lock_is_mutexed(lock)); - LINVRNT(cl_lock_invariant(env, lock)); - LASSERT(lock->cll_state != CLS_FREEING); - - cl_lock_get(lock); - cl_lock_hold_mod(env, lock, 1); - lu_ref_add(&lock->cll_holders, scope, source); - lu_ref_add(&lock->cll_reference, scope, source); -} -EXPORT_SYMBOL(cl_lock_hold_add); - -/** - * Releases a hold and a reference on a lock, on which caller acquired a - * mutex. - */ -void cl_lock_unhold(const struct lu_env *env, struct cl_lock *lock, - const char *scope, const void *source) -{ - LINVRNT(cl_lock_invariant(env, lock)); - cl_lock_hold_release(env, lock, scope, source); - lu_ref_del(&lock->cll_reference, scope, source); - cl_lock_put(env, lock); -} -EXPORT_SYMBOL(cl_lock_unhold); - /** * Releases a hold and a reference on a lock, obtained by cl_lock_hold(). */ -void cl_lock_release(const struct lu_env *env, struct cl_lock *lock, - const char *scope, const void *source) +void cl_lock_release(const struct lu_env *env, struct cl_lock *lock) { - LINVRNT(cl_lock_invariant(env, lock)); cl_lock_trace(D_DLMTRACE, env, "release lock", lock); - cl_lock_mutex_get(env, lock); - cl_lock_hold_release(env, lock, scope, source); - cl_lock_mutex_put(env, lock); - lu_ref_del(&lock->cll_reference, scope, source); - cl_lock_put(env, lock); + cl_lock_cancel(env, lock); + cl_lock_fini(env, lock); } EXPORT_SYMBOL(cl_lock_release); -void cl_lock_user_add(const struct lu_env *env, struct cl_lock *lock) -{ - LINVRNT(cl_lock_is_mutexed(lock)); - LINVRNT(cl_lock_invariant(env, lock)); - - cl_lock_used_mod(env, lock, 1); -} -EXPORT_SYMBOL(cl_lock_user_add); - -void cl_lock_user_del(const struct lu_env *env, struct cl_lock *lock) -{ - LINVRNT(cl_lock_is_mutexed(lock)); - LINVRNT(cl_lock_invariant(env, lock)); - LASSERT(lock->cll_users > 0); - - cl_lock_used_mod(env, lock, -1); - if (lock->cll_users == 0) - wake_up_all(&lock->cll_wq); -} -EXPORT_SYMBOL(cl_lock_user_del); - const char *cl_lock_mode_name(const enum cl_lock_mode mode) { static const char *names[] = { - [CLM_PHANTOM] = "P", [CLM_READ] = "R", [CLM_WRITE] = "W", [CLM_GROUP] = "G" @@ -2061,10 +261,8 @@ void cl_lock_print(const struct lu_env *env, void *cookie, lu_printer_t printer, const struct cl_lock *lock) { const struct cl_lock_slice *slice; - (*printer)(env, cookie, "lock@%p[%d %d %d %d %d %08lx] ", - lock, atomic_read(&lock->cll_ref), - lock->cll_state, lock->cll_error, lock->cll_holds, - lock->cll_users, lock->cll_flags); + + (*printer)(env, cookie, "lock@%p", lock); cl_lock_descr_print(env, cookie, printer, &lock->cll_descr); (*printer)(env, cookie, " {\n"); @@ -2079,13 +277,3 @@ void cl_lock_print(const struct lu_env *env, void *cookie, (*printer)(env, cookie, "} lock@%p\n", lock); } EXPORT_SYMBOL(cl_lock_print); - -int cl_lock_init(void) -{ - return lu_kmem_init(cl_lock_caches); -} - -void cl_lock_fini(void) -{ - lu_kmem_fini(cl_lock_caches); -} diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c index 72e6333220ea..395b92c6480d 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_object.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c @@ -44,7 +44,6 @@ * * i_mutex * PG_locked - * ->coh_lock_guard * ->coh_attr_guard * ->ls_guard */ @@ -63,8 +62,6 @@ static struct kmem_cache *cl_env_kmem; -/** Lock class of cl_object_header::coh_lock_guard */ -static struct lock_class_key cl_lock_guard_class; /** Lock class of cl_object_header::coh_attr_guard */ static struct lock_class_key cl_attr_guard_class; @@ -79,11 +76,8 @@ int cl_object_header_init(struct cl_object_header *h) result = lu_object_header_init(&h->coh_lu); if (result == 0) { - spin_lock_init(&h->coh_lock_guard); spin_lock_init(&h->coh_attr_guard); - lockdep_set_class(&h->coh_lock_guard, &cl_lock_guard_class); lockdep_set_class(&h->coh_attr_guard, &cl_attr_guard_class); - INIT_LIST_HEAD(&h->coh_locks); h->coh_page_bufsize = 0; } return result; @@ -310,7 +304,7 @@ EXPORT_SYMBOL(cl_conf_set); /** * Prunes caches of pages and locks for this object. */ -void cl_object_prune(const struct lu_env *env, struct cl_object *obj) +int cl_object_prune(const struct lu_env *env, struct cl_object *obj) { struct lu_object_header *top; struct cl_object *o; @@ -326,10 +320,7 @@ void cl_object_prune(const struct lu_env *env, struct cl_object *obj) } } - /* TODO: pruning locks will be moved into layers after cl_lock - * simplification is done - */ - cl_locks_prune(env, obj, 1); + return result; } EXPORT_SYMBOL(cl_object_prune); @@ -342,19 +333,9 @@ EXPORT_SYMBOL(cl_object_prune); */ void cl_object_kill(const struct lu_env *env, struct cl_object *obj) { - struct cl_object_header *hdr; - - hdr = cl_object_header(obj); + struct cl_object_header *hdr = cl_object_header(obj); set_bit(LU_OBJECT_HEARD_BANSHEE, &hdr->coh_lu.loh_flags); - /* - * Destroy all locks. Object destruction (including cl_inode_fini()) - * cannot cancel the locks, because in the case of a local client, - * where client and server share the same thread running - * prune_icache(), this can dead-lock with ldlm_cancel_handler() - * waiting on __wait_on_freeing_inode(). - */ - cl_locks_prune(env, obj, 0); } EXPORT_SYMBOL(cl_object_kill); @@ -406,11 +387,8 @@ int cl_site_init(struct cl_site *s, struct cl_device *d) result = lu_site_init(&s->cs_lu, &d->cd_lu_dev); if (result == 0) { cache_stats_init(&s->cs_pages, "pages"); - cache_stats_init(&s->cs_locks, "locks"); for (i = 0; i < ARRAY_SIZE(s->cs_pages_state); ++i) atomic_set(&s->cs_pages_state[0], 0); - for (i = 0; i < ARRAY_SIZE(s->cs_locks_state); ++i) - atomic_set(&s->cs_locks_state[i], 0); cl_env_percpu_refill(); } return result; @@ -445,15 +423,6 @@ int cl_site_stats_print(const struct cl_site *site, struct seq_file *m) [CPS_PAGEIN] = "r", [CPS_FREEING] = "f" }; - static const char *lstate[] = { - [CLS_NEW] = "n", - [CLS_QUEUING] = "q", - [CLS_ENQUEUED] = "e", - [CLS_HELD] = "h", - [CLS_INTRANSIT] = "t", - [CLS_CACHED] = "c", - [CLS_FREEING] = "f" - }; /* lookup hit total busy create pages: ...... ...... ...... ...... ...... [...... ...... ...... ......] @@ -467,12 +436,6 @@ locks: ...... ...... ...... ...... ...... [...... ...... ...... ...... ......] seq_printf(m, "%s: %u ", pstate[i], atomic_read(&site->cs_pages_state[i])); seq_printf(m, "]\n"); - cache_stats_print(&site->cs_locks, m, 0); - seq_printf(m, " ["); - for (i = 0; i < ARRAY_SIZE(site->cs_locks_state); ++i) - seq_printf(m, "%s: %u ", lstate[i], - atomic_read(&site->cs_locks_state[i])); - seq_printf(m, "]\n"); cache_stats_print(&cl_env_stats, m, 0); seq_printf(m, "\n"); return 0; @@ -1147,12 +1110,6 @@ void cl_stack_fini(const struct lu_env *env, struct cl_device *cl) } EXPORT_SYMBOL(cl_stack_fini); -int cl_lock_init(void); -void cl_lock_fini(void); - -int cl_page_init(void); -void cl_page_fini(void); - static struct lu_context_key cl_key; struct cl_thread_info *cl_env_info(const struct lu_env *env) @@ -1247,22 +1204,13 @@ int cl_global_init(void) if (result) goto out_kmem; - result = cl_lock_init(); - if (result) - goto out_context; - - result = cl_page_init(); - if (result) - goto out_lock; - result = cl_env_percpu_init(); if (result) /* no cl_env_percpu_fini on error */ - goto out_lock; + goto out_context; return 0; -out_lock: - cl_lock_fini(); + out_context: lu_context_key_degister(&cl_key); out_kmem: @@ -1278,8 +1226,6 @@ out_store: void cl_global_fini(void) { cl_env_percpu_fini(); - cl_lock_fini(); - cl_page_fini(); lu_context_key_degister(&cl_key); lu_kmem_fini(cl_object_caches); cl_env_store_fini(); diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c index ad7f0aec605b..8df39ced1725 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_page.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c @@ -1075,12 +1075,3 @@ void cl_page_slice_add(struct cl_page *page, struct cl_page_slice *slice, slice->cpl_page = page; } EXPORT_SYMBOL(cl_page_slice_add); - -int cl_page_init(void) -{ - return 0; -} - -void cl_page_fini(void) -{ -} diff --git a/drivers/staging/lustre/lustre/obdecho/echo_client.c b/drivers/staging/lustre/lustre/obdecho/echo_client.c index 0d84d04c12de..a752bb4e946b 100644 --- a/drivers/staging/lustre/lustre/obdecho/echo_client.c +++ b/drivers/staging/lustre/lustre/obdecho/echo_client.c @@ -171,7 +171,7 @@ struct echo_thread_info { struct cl_2queue eti_queue; struct cl_io eti_io; - struct cl_lock_descr eti_descr; + struct cl_lock eti_lock; struct lu_fid eti_fid; struct lu_fid eti_fid2; }; @@ -327,26 +327,8 @@ static void echo_lock_fini(const struct lu_env *env, kmem_cache_free(echo_lock_kmem, ecl); } -static void echo_lock_delete(const struct lu_env *env, - const struct cl_lock_slice *slice) -{ - struct echo_lock *ecl = cl2echo_lock(slice); - - LASSERT(list_empty(&ecl->el_chain)); -} - -static int echo_lock_fits_into(const struct lu_env *env, - const struct cl_lock_slice *slice, - const struct cl_lock_descr *need, - const struct cl_io *unused) -{ - return 1; -} - static struct cl_lock_operations echo_lock_ops = { .clo_fini = echo_lock_fini, - .clo_delete = echo_lock_delete, - .clo_fits_into = echo_lock_fits_into }; /** @} echo_lock */ @@ -811,16 +793,7 @@ static void echo_lock_release(const struct lu_env *env, { struct cl_lock *clk = echo_lock2cl(ecl); - cl_lock_get(clk); - cl_unuse(env, clk); - cl_lock_release(env, clk, "ec enqueue", ecl->el_object); - if (!still_used) { - cl_lock_mutex_get(env, clk); - cl_lock_cancel(env, clk); - cl_lock_delete(env, clk); - cl_lock_mutex_put(env, clk); - } - cl_lock_put(env, clk); + cl_lock_release(env, clk); } static struct lu_device *echo_device_free(const struct lu_env *env, @@ -1014,9 +987,11 @@ static int cl_echo_enqueue0(struct lu_env *env, struct echo_object *eco, info = echo_env_info(env); io = &info->eti_io; - descr = &info->eti_descr; + lck = &info->eti_lock; obj = echo_obj2cl(eco); + memset(lck, 0, sizeof(*lck)); + descr = &lck->cll_descr; descr->cld_obj = obj; descr->cld_start = cl_index(obj, start); descr->cld_end = cl_index(obj, end); @@ -1024,25 +999,20 @@ static int cl_echo_enqueue0(struct lu_env *env, struct echo_object *eco, descr->cld_enq_flags = enqflags; io->ci_obj = obj; - lck = cl_lock_request(env, io, descr, "ec enqueue", eco); - if (lck) { + rc = cl_lock_request(env, io, lck); + if (rc == 0) { struct echo_client_obd *ec = eco->eo_dev->ed_ec; struct echo_lock *el; - rc = cl_wait(env, lck); - if (rc == 0) { - el = cl2echo_lock(cl_lock_at(lck, &echo_device_type)); - spin_lock(&ec->ec_lock); - if (list_empty(&el->el_chain)) { - list_add(&el->el_chain, &ec->ec_locks); - el->el_cookie = ++ec->ec_unique; - } - atomic_inc(&el->el_refcount); - *cookie = el->el_cookie; - spin_unlock(&ec->ec_lock); - } else { - cl_lock_release(env, lck, "ec enqueue", current); + el = cl2echo_lock(cl_lock_at(lck, &echo_device_type)); + spin_lock(&ec->ec_lock); + if (list_empty(&el->el_chain)) { + list_add(&el->el_chain, &ec->ec_locks); + el->el_cookie = ++ec->ec_unique; } + atomic_inc(&el->el_refcount); + *cookie = el->el_cookie; + spin_unlock(&ec->ec_lock); } return rc; } diff --git a/drivers/staging/lustre/lustre/osc/osc_cache.c b/drivers/staging/lustre/lustre/osc/osc_cache.c index c5106592b3e4..d01f2a207a91 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cache.c +++ b/drivers/staging/lustre/lustre/osc/osc_cache.c @@ -76,6 +76,8 @@ static inline char *ext_flags(struct osc_extent *ext, char *flags) *buf++ = ext->oe_rw ? 'r' : 'w'; if (ext->oe_intree) *buf++ = 'i'; + if (ext->oe_sync) + *buf++ = 'S'; if (ext->oe_srvlock) *buf++ = 's'; if (ext->oe_hp) @@ -121,9 +123,13 @@ static const char *oes_strings[] = { __ext->oe_grants, __ext->oe_nr_pages, \ list_empty_marker(&__ext->oe_pages), \ waitqueue_active(&__ext->oe_waitq) ? '+' : '-', \ - __ext->oe_osclock, __ext->oe_mppr, __ext->oe_owner, \ + __ext->oe_dlmlock, __ext->oe_mppr, __ext->oe_owner, \ /* ----- part 4 ----- */ \ ## __VA_ARGS__); \ + if (lvl == D_ERROR && __ext->oe_dlmlock) \ + LDLM_ERROR(__ext->oe_dlmlock, "extent: %p\n", __ext); \ + else \ + LDLM_DEBUG(__ext->oe_dlmlock, "extent: %p\n", __ext); \ } while (0) #undef EASSERTF @@ -240,20 +246,25 @@ static int osc_extent_sanity_check0(struct osc_extent *ext, goto out; } - if (!ext->oe_osclock && ext->oe_grants > 0) { + if (ext->oe_sync && ext->oe_grants > 0) { rc = 90; goto out; } - if (ext->oe_osclock) { - struct cl_lock_descr *descr; + if (ext->oe_dlmlock) { + struct ldlm_extent *extent; - descr = &ext->oe_osclock->cll_descr; - if (!(descr->cld_start <= ext->oe_start && - descr->cld_end >= ext->oe_max_end)) { + extent = &ext->oe_dlmlock->l_policy_data.l_extent; + if (!(extent->start <= cl_offset(osc2cl(obj), ext->oe_start) && + extent->end >= cl_offset(osc2cl(obj), ext->oe_max_end))) { rc = 100; goto out; } + + if (!(ext->oe_dlmlock->l_granted_mode & (LCK_PW | LCK_GROUP))) { + rc = 102; + goto out; + } } if (ext->oe_nr_pages > ext->oe_mppr) { @@ -359,7 +370,7 @@ static struct osc_extent *osc_extent_alloc(struct osc_object *obj) ext->oe_state = OES_INV; INIT_LIST_HEAD(&ext->oe_pages); init_waitqueue_head(&ext->oe_waitq); - ext->oe_osclock = NULL; + ext->oe_dlmlock = NULL; return ext; } @@ -385,9 +396,11 @@ static void osc_extent_put(const struct lu_env *env, struct osc_extent *ext) LASSERT(ext->oe_state == OES_INV); LASSERT(!ext->oe_intree); - if (ext->oe_osclock) { - cl_lock_put(env, ext->oe_osclock); - ext->oe_osclock = NULL; + if (ext->oe_dlmlock) { + lu_ref_add(&ext->oe_dlmlock->l_reference, + "osc_extent", ext); + LDLM_LOCK_PUT(ext->oe_dlmlock); + ext->oe_dlmlock = NULL; } osc_extent_free(ext); } @@ -543,7 +556,7 @@ static int osc_extent_merge(const struct lu_env *env, struct osc_extent *cur, if (cur->oe_max_end != victim->oe_max_end) return -ERANGE; - LASSERT(cur->oe_osclock == victim->oe_osclock); + LASSERT(cur->oe_dlmlock == victim->oe_dlmlock); ppc_bits = osc_cli(obj)->cl_chunkbits - PAGE_CACHE_SHIFT; chunk_start = cur->oe_start >> ppc_bits; chunk_end = cur->oe_end >> ppc_bits; @@ -624,10 +637,10 @@ static inline int overlapped(struct osc_extent *ex1, struct osc_extent *ex2) static struct osc_extent *osc_extent_find(const struct lu_env *env, struct osc_object *obj, pgoff_t index, int *grants) - { struct client_obd *cli = osc_cli(obj); - struct cl_lock *lock; + struct osc_lock *olck; + struct cl_lock_descr *descr; struct osc_extent *cur; struct osc_extent *ext; struct osc_extent *conflict = NULL; @@ -644,8 +657,12 @@ static struct osc_extent *osc_extent_find(const struct lu_env *env, if (!cur) return ERR_PTR(-ENOMEM); - lock = cl_lock_at_pgoff(env, osc2cl(obj), index, NULL, 1, 0); - LASSERT(lock->cll_descr.cld_mode >= CLM_WRITE); + olck = osc_env_io(env)->oi_write_osclock; + LASSERTF(olck, "page %lu is not covered by lock\n", index); + LASSERT(olck->ols_state == OLS_GRANTED); + + descr = &olck->ols_cl.cls_lock->cll_descr; + LASSERT(descr->cld_mode >= CLM_WRITE); LASSERT(cli->cl_chunkbits >= PAGE_CACHE_SHIFT); ppc_bits = cli->cl_chunkbits - PAGE_CACHE_SHIFT; @@ -657,19 +674,23 @@ static struct osc_extent *osc_extent_find(const struct lu_env *env, max_pages = cli->cl_max_pages_per_rpc; LASSERT((max_pages & ~chunk_mask) == 0); max_end = index - (index % max_pages) + max_pages - 1; - max_end = min_t(pgoff_t, max_end, lock->cll_descr.cld_end); + max_end = min_t(pgoff_t, max_end, descr->cld_end); /* initialize new extent by parameters so far */ cur->oe_max_end = max_end; cur->oe_start = index & chunk_mask; cur->oe_end = ((index + ~chunk_mask + 1) & chunk_mask) - 1; - if (cur->oe_start < lock->cll_descr.cld_start) - cur->oe_start = lock->cll_descr.cld_start; + if (cur->oe_start < descr->cld_start) + cur->oe_start = descr->cld_start; if (cur->oe_end > max_end) cur->oe_end = max_end; - cur->oe_osclock = lock; cur->oe_grants = 0; cur->oe_mppr = max_pages; + if (olck->ols_dlmlock) { + LASSERT(olck->ols_hold); + cur->oe_dlmlock = LDLM_LOCK_GET(olck->ols_dlmlock); + lu_ref_add(&olck->ols_dlmlock->l_reference, "osc_extent", cur); + } /* grants has been allocated by caller */ LASSERTF(*grants >= chunksize + cli->cl_extent_tax, @@ -691,7 +712,7 @@ restart: break; /* if covering by different locks, no chance to match */ - if (lock != ext->oe_osclock) { + if (olck->ols_dlmlock != ext->oe_dlmlock) { EASSERTF(!overlapped(ext, cur), ext, EXTSTR"\n", EXTPARA(cur)); @@ -795,7 +816,7 @@ restart: if (found) { LASSERT(!conflict); if (!IS_ERR(found)) { - LASSERT(found->oe_osclock == cur->oe_osclock); + LASSERT(found->oe_dlmlock == cur->oe_dlmlock); OSC_EXTENT_DUMP(D_CACHE, found, "found caching ext for %lu.\n", index); } @@ -810,7 +831,7 @@ restart: found = osc_extent_hold(cur); osc_extent_insert(obj, cur); OSC_EXTENT_DUMP(D_CACHE, cur, "add into tree %lu/%lu.\n", - index, lock->cll_descr.cld_end); + index, descr->cld_end); } osc_object_unlock(obj); @@ -2630,6 +2651,7 @@ int osc_queue_sync_pages(const struct lu_env *env, struct osc_object *obj, } ext->oe_rw = !!(cmd & OBD_BRW_READ); + ext->oe_sync = 1; ext->oe_urgent = 1; ext->oe_start = start; ext->oe_end = ext->oe_max_end = end; @@ -3087,27 +3109,27 @@ static int check_and_discard_cb(const struct lu_env *env, struct cl_io *io, struct osc_page *ops, void *cbdata) { struct osc_thread_info *info = osc_env_info(env); - struct cl_lock *lock = cbdata; + struct osc_object *osc = cbdata; pgoff_t index; index = osc_index(ops); if (index >= info->oti_fn_index) { - struct cl_lock *tmp; + struct ldlm_lock *tmp; struct cl_page *page = ops->ops_cl.cpl_page; /* refresh non-overlapped index */ - tmp = cl_lock_at_pgoff(env, lock->cll_descr.cld_obj, index, - lock, 1, 0); + tmp = osc_dlmlock_at_pgoff(env, osc, index, 0, 0); if (tmp) { + __u64 end = tmp->l_policy_data.l_extent.end; /* Cache the first-non-overlapped index so as to skip - * all pages within [index, oti_fn_index). This - * is safe because if tmp lock is canceled, it will - * discard these pages. + * all pages within [index, oti_fn_index). This is safe + * because if tmp lock is canceled, it will discard + * these pages. */ - info->oti_fn_index = tmp->cll_descr.cld_end + 1; - if (tmp->cll_descr.cld_end == CL_PAGE_EOF) + info->oti_fn_index = cl_index(osc2cl(osc), end + 1); + if (end == OBD_OBJECT_EOF) info->oti_fn_index = CL_PAGE_EOF; - cl_lock_put(env, tmp); + LDLM_LOCK_PUT(tmp); } else if (cl_page_own(env, io, page) == 0) { /* discard the page */ cl_page_discard(env, io, page); @@ -3125,11 +3147,8 @@ static int discard_cb(const struct lu_env *env, struct cl_io *io, struct osc_page *ops, void *cbdata) { struct osc_thread_info *info = osc_env_info(env); - struct cl_lock *lock = cbdata; struct cl_page *page = ops->ops_cl.cpl_page; - LASSERT(lock->cll_descr.cld_mode >= CLM_WRITE); - /* page is top page. */ info->oti_next_index = osc_index(ops) + 1; if (cl_page_own(env, io, page) == 0) { @@ -3154,30 +3173,27 @@ static int discard_cb(const struct lu_env *env, struct cl_io *io, * If error happens on any step, the process continues anyway (the reasoning * behind this being that lock cancellation cannot be delayed indefinitely). */ -int osc_lock_discard_pages(const struct lu_env *env, struct osc_lock *ols) +int osc_lock_discard_pages(const struct lu_env *env, struct osc_object *osc, + pgoff_t start, pgoff_t end, enum cl_lock_mode mode) { struct osc_thread_info *info = osc_env_info(env); struct cl_io *io = &info->oti_io; - struct cl_object *osc = ols->ols_cl.cls_obj; - struct cl_lock *lock = ols->ols_cl.cls_lock; - struct cl_lock_descr *descr = &lock->cll_descr; osc_page_gang_cbt cb; int res; int result; - io->ci_obj = cl_object_top(osc); + io->ci_obj = cl_object_top(osc2cl(osc)); io->ci_ignore_layout = 1; result = cl_io_init(env, io, CIT_MISC, io->ci_obj); if (result != 0) goto out; - cb = descr->cld_mode == CLM_READ ? check_and_discard_cb : discard_cb; - info->oti_fn_index = info->oti_next_index = descr->cld_start; + cb = mode == CLM_READ ? check_and_discard_cb : discard_cb; + info->oti_fn_index = info->oti_next_index = start; do { - res = osc_page_gang_lookup(env, io, cl2osc(osc), - info->oti_next_index, descr->cld_end, - cb, (void *)lock); - if (info->oti_next_index > descr->cld_end) + res = osc_page_gang_lookup(env, io, osc, + info->oti_next_index, end, cb, osc); + if (info->oti_next_index > end) break; if (res == CLP_GANG_RESCHED) diff --git a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h index bb34b53aead6..c7a69e4cd944 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h +++ b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h @@ -68,6 +68,9 @@ struct osc_io { struct cl_io_slice oi_cl; /** true if this io is lockless. */ int oi_lockless; + /** how many LRU pages are reserved for this IO */ + int oi_lru_reserved; + /** active extents, we know how many bytes is going to be written, * so having an active extent will prevent it from being fragmented */ @@ -77,8 +80,8 @@ struct osc_io { */ struct osc_extent *oi_trunc; - int oi_lru_reserved; - + /** write osc_lock for this IO, used by osc_extent_find(). */ + struct osc_lock *oi_write_osclock; struct obd_info oi_info; struct obdo oi_oa; struct osc_async_cbargs { @@ -117,6 +120,7 @@ struct osc_thread_info { */ pgoff_t oti_next_index; pgoff_t oti_fn_index; /* first non-overlapped index */ + struct cl_sync_io oti_anchor; }; struct osc_object { @@ -173,6 +177,10 @@ struct osc_object { struct radix_tree_root oo_tree; spinlock_t oo_tree_lock; unsigned long oo_npages; + + /* Protect osc_lock this osc_object has */ + spinlock_t oo_ol_spin; + struct list_head oo_ol_list; }; static inline void osc_object_lock(struct osc_object *obj) @@ -212,8 +220,6 @@ enum osc_lock_state { OLS_ENQUEUED, OLS_UPCALL_RECEIVED, OLS_GRANTED, - OLS_RELEASED, - OLS_BLOCKED, OLS_CANCELLED }; @@ -222,10 +228,8 @@ enum osc_lock_state { * * Interaction with DLM. * - * CLIO enqueues all DLM locks through ptlrpcd (that is, in "async" mode). - * * Once receive upcall is invoked, osc_lock remembers a handle of DLM lock in - * osc_lock::ols_handle and a pointer to that lock in osc_lock::ols_lock. + * osc_lock::ols_handle and a pointer to that lock in osc_lock::ols_dlmlock. * * This pointer is protected through a reference, acquired by * osc_lock_upcall0(). Also, an additional reference is acquired by @@ -263,16 +267,27 @@ enum osc_lock_state { */ struct osc_lock { struct cl_lock_slice ols_cl; + /** Internal lock to protect states, etc. */ + spinlock_t ols_lock; + /** Owner sleeps on this channel for state change */ + struct cl_sync_io *ols_owner; + /** waiting list for this lock to be cancelled */ + struct list_head ols_waiting_list; + /** wait entry of ols_waiting_list */ + struct list_head ols_wait_entry; + /** list entry for osc_object::oo_ol_list */ + struct list_head ols_nextlock_oscobj; + /** underlying DLM lock */ - struct ldlm_lock *ols_lock; - /** lock value block */ - struct ost_lvb ols_lvb; + struct ldlm_lock *ols_dlmlock; /** DLM flags with which osc_lock::ols_lock was enqueued */ __u64 ols_flags; /** osc_lock::ols_lock handle */ struct lustre_handle ols_handle; struct ldlm_enqueue_info ols_einfo; enum osc_lock_state ols_state; + /** lock value block */ + struct ost_lvb ols_lvb; /** * true, if ldlm_lock_addref() was called against @@ -302,16 +317,6 @@ struct osc_lock { * If true, osc_lock_enqueue is able to tolerate the -EUSERS error. */ ols_locklessable:1, - /** - * set by osc_lock_use() to wait until blocking AST enters into - * osc_ldlm_blocking_ast0(), so that cl_lock mutex can be used for - * further synchronization. - */ - ols_ast_wait:1, - /** - * If the data of this lock has been flushed to server side. - */ - ols_flush:1, /** * if set, the osc_lock is a glimpse lock. For glimpse locks, we treat * the EVAVAIL error as tolerable, this will make upper logic happy @@ -325,15 +330,6 @@ struct osc_lock { * For async glimpse lock. */ ols_agl:1; - /** - * IO that owns this lock. This field is used for a dead-lock - * avoidance by osc_lock_enqueue_wait(). - * - * XXX: unfortunately, the owner of a osc_lock is not unique, - * the lock may have multiple users, if the lock is granted and - * then matched. - */ - struct osc_io *ols_owner; }; /** @@ -627,6 +623,8 @@ struct osc_extent { unsigned int oe_intree:1, /** 0 is write, 1 is read */ oe_rw:1, + /** sync extent, queued by osc_queue_sync_pages() */ + oe_sync:1, oe_srvlock:1, oe_memalloc:1, /** an ACTIVE extent is going to be truncated, so when this extent @@ -675,7 +673,7 @@ struct osc_extent { */ wait_queue_head_t oe_waitq; /** lock covering this extent */ - struct cl_lock *oe_osclock; + struct ldlm_lock *oe_dlmlock; /** terminator of this extent. Must be true if this extent is in IO. */ struct task_struct *oe_owner; /** return value of writeback. If somebody is waiting for this extent, @@ -690,14 +688,14 @@ int osc_extent_finish(const struct lu_env *env, struct osc_extent *ext, int sent, int rc); void osc_extent_release(const struct lu_env *env, struct osc_extent *ext); -int osc_lock_discard_pages(const struct lu_env *env, struct osc_lock *lock); +int osc_lock_discard_pages(const struct lu_env *env, struct osc_object *osc, + pgoff_t start, pgoff_t end, enum cl_lock_mode mode); typedef int (*osc_page_gang_cbt)(const struct lu_env *, struct cl_io *, struct osc_page *, void *); int osc_page_gang_lookup(const struct lu_env *env, struct cl_io *io, struct osc_object *osc, pgoff_t start, pgoff_t end, osc_page_gang_cbt cb, void *cbdata); - /** @} osc */ #endif /* OSC_CL_INTERNAL_H */ diff --git a/drivers/staging/lustre/lustre/osc/osc_internal.h b/drivers/staging/lustre/lustre/osc/osc_internal.h index b7fb01ad60a6..cf9f8b792f07 100644 --- a/drivers/staging/lustre/lustre/osc/osc_internal.h +++ b/drivers/staging/lustre/lustre/osc/osc_internal.h @@ -108,12 +108,14 @@ void osc_update_next_shrink(struct client_obd *cli); extern struct ptlrpc_request_set *PTLRPCD_SET; +typedef int (*osc_enqueue_upcall_f)(void *cookie, struct lustre_handle *lockh, + int rc); + int osc_enqueue_base(struct obd_export *exp, struct ldlm_res_id *res_id, __u64 *flags, ldlm_policy_data_t *policy, struct ost_lvb *lvb, int kms_valid, - obd_enqueue_update_f upcall, + osc_enqueue_upcall_f upcall, void *cookie, struct ldlm_enqueue_info *einfo, - struct lustre_handle *lockh, struct ptlrpc_request_set *rqset, int async, int agl); int osc_cancel_base(struct lustre_handle *lockh, __u32 mode); @@ -140,7 +142,6 @@ int osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, int target, bool force); int osc_lru_reclaim(struct client_obd *cli); -extern spinlock_t osc_ast_guard; unsigned long osc_ldlm_weigh_ast(struct ldlm_lock *dlmlock); int osc_setup(struct obd_device *obd, struct lustre_cfg *lcfg); @@ -199,5 +200,8 @@ int osc_quotactl(struct obd_device *unused, struct obd_export *exp, int osc_quotacheck(struct obd_device *unused, struct obd_export *exp, struct obd_quotactl *oqctl); int osc_quota_poll_check(struct obd_export *exp, struct if_quotacheck *qchk); +struct ldlm_lock *osc_dlmlock_at_pgoff(const struct lu_env *env, + struct osc_object *obj, pgoff_t index, + int pending, int canceling); #endif /* OSC_INTERNAL_H */ diff --git a/drivers/staging/lustre/lustre/osc/osc_io.c b/drivers/staging/lustre/lustre/osc/osc_io.c index 1ae8a227ad3d..cf7743d2f148 100644 --- a/drivers/staging/lustre/lustre/osc/osc_io.c +++ b/drivers/staging/lustre/lustre/osc/osc_io.c @@ -354,6 +354,7 @@ static void osc_io_rw_iter_fini(const struct lu_env *env, atomic_add(oio->oi_lru_reserved, cli->cl_lru_left); oio->oi_lru_reserved = 0; } + oio->oi_write_osclock = NULL; } static int osc_io_fault_start(const struct lu_env *env, @@ -751,8 +752,7 @@ static void osc_req_attr_set(const struct lu_env *env, struct lov_oinfo *oinfo; struct cl_req *clerq; struct cl_page *apage; /* _some_ page in @clerq */ - struct cl_lock *lock; /* _some_ lock protecting @apage */ - struct osc_lock *olck; + struct ldlm_lock *lock; /* _some_ lock protecting @apage */ struct osc_page *opg; struct obdo *oa; struct ost_lvb *lvb; @@ -782,38 +782,37 @@ static void osc_req_attr_set(const struct lu_env *env, oa->o_valid |= OBD_MD_FLID; } if (flags & OBD_MD_FLHANDLE) { - struct cl_object *subobj; clerq = slice->crs_req; LASSERT(!list_empty(&clerq->crq_pages)); apage = container_of(clerq->crq_pages.next, struct cl_page, cp_flight); opg = osc_cl_page_osc(apage, NULL); - subobj = opg->ops_cl.cpl_obj; - lock = cl_lock_at_pgoff(env, subobj, osc_index(opg), - NULL, 1, 1); - if (!lock) { - struct cl_object_header *head; - struct cl_lock *scan; - - head = cl_object_header(subobj); - list_for_each_entry(scan, &head->coh_locks, cll_linkage) - CL_LOCK_DEBUG(D_ERROR, env, scan, - "no cover page!\n"); - CL_PAGE_DEBUG(D_ERROR, env, apage, - "dump uncover page!\n"); + lock = osc_dlmlock_at_pgoff(env, cl2osc(obj), osc_index(opg), + 1, 1); + if (!lock && !opg->ops_srvlock) { + struct ldlm_resource *res; + struct ldlm_res_id *resname; + + CL_PAGE_DEBUG(D_ERROR, env, apage, "uncovered page!\n"); + + resname = &osc_env_info(env)->oti_resname; + ostid_build_res_name(&oinfo->loi_oi, resname); + res = ldlm_resource_get( + osc_export(cl2osc(obj))->exp_obd->obd_namespace, + NULL, resname, LDLM_EXTENT, 0); + ldlm_resource_dump(D_ERROR, res); + dump_stack(); LBUG(); } - olck = osc_lock_at(lock); - LASSERT(ergo(opg->ops_srvlock, !olck->ols_lock)); /* check for lockless io. */ - if (olck->ols_lock) { - oa->o_handle = olck->ols_lock->l_remote_handle; + if (lock) { + oa->o_handle = lock->l_remote_handle; oa->o_valid |= OBD_MD_FLHANDLE; + LDLM_LOCK_PUT(lock); } - cl_lock_put(env, lock); } } diff --git a/drivers/staging/lustre/lustre/osc/osc_lock.c b/drivers/staging/lustre/lustre/osc/osc_lock.c index 978b6ea67107..68c5013fdc3e 100644 --- a/drivers/staging/lustre/lustre/osc/osc_lock.c +++ b/drivers/staging/lustre/lustre/osc/osc_lock.c @@ -61,7 +61,6 @@ static const struct cl_lock_operations osc_lock_ops; static const struct cl_lock_operations osc_lock_lockless_ops; static void osc_lock_to_lockless(const struct lu_env *env, struct osc_lock *ols, int force); -static int osc_lock_has_pages(struct osc_lock *olck); int osc_lock_is_lockless(const struct osc_lock *olck) { @@ -89,11 +88,11 @@ static struct ldlm_lock *osc_handle_ptr(struct lustre_handle *handle) static int osc_lock_invariant(struct osc_lock *ols) { struct ldlm_lock *lock = osc_handle_ptr(&ols->ols_handle); - struct ldlm_lock *olock = ols->ols_lock; + struct ldlm_lock *olock = ols->ols_dlmlock; int handle_used = lustre_handle_is_used(&ols->ols_handle); if (ergo(osc_lock_is_lockless(ols), - ols->ols_locklessable && !ols->ols_lock)) + ols->ols_locklessable && !ols->ols_dlmlock)) return 1; /* @@ -110,7 +109,7 @@ static int osc_lock_invariant(struct osc_lock *ols) ergo(!lock, !olock))) return 0; /* - * Check that ->ols_handle and ->ols_lock are consistent, but + * Check that ->ols_handle and ->ols_dlmlock are consistent, but * take into account that they are set at the different time. */ if (!ergo(ols->ols_state == OLS_CANCELLED, @@ -137,115 +136,13 @@ static int osc_lock_invariant(struct osc_lock *ols) * */ -/** - * Breaks a link between osc_lock and dlm_lock. - */ -static void osc_lock_detach(const struct lu_env *env, struct osc_lock *olck) -{ - struct ldlm_lock *dlmlock; - - spin_lock(&osc_ast_guard); - dlmlock = olck->ols_lock; - if (!dlmlock) { - spin_unlock(&osc_ast_guard); - return; - } - - olck->ols_lock = NULL; - /* wb(); --- for all who checks (ols->ols_lock != NULL) before - * call to osc_lock_detach() - */ - dlmlock->l_ast_data = NULL; - olck->ols_handle.cookie = 0ULL; - spin_unlock(&osc_ast_guard); - - lock_res_and_lock(dlmlock); - if (dlmlock->l_granted_mode == dlmlock->l_req_mode) { - struct cl_object *obj = olck->ols_cl.cls_obj; - struct cl_attr *attr = &osc_env_info(env)->oti_attr; - __u64 old_kms; - - cl_object_attr_lock(obj); - /* Must get the value under the lock to avoid possible races. */ - old_kms = cl2osc(obj)->oo_oinfo->loi_kms; - /* Update the kms. Need to loop all granted locks. - * Not a problem for the client - */ - attr->cat_kms = ldlm_extent_shift_kms(dlmlock, old_kms); - - cl_object_attr_set(env, obj, attr, CAT_KMS); - cl_object_attr_unlock(obj); - } - unlock_res_and_lock(dlmlock); - - /* release a reference taken in osc_lock_upcall0(). */ - LASSERT(olck->ols_has_ref); - lu_ref_del(&dlmlock->l_reference, "osc_lock", olck); - LDLM_LOCK_RELEASE(dlmlock); - olck->ols_has_ref = 0; -} - -static int osc_lock_unhold(struct osc_lock *ols) -{ - int result = 0; - - if (ols->ols_hold) { - ols->ols_hold = 0; - result = osc_cancel_base(&ols->ols_handle, - ols->ols_einfo.ei_mode); - } - return result; -} - -static int osc_lock_unuse(const struct lu_env *env, - const struct cl_lock_slice *slice) -{ - struct osc_lock *ols = cl2osc_lock(slice); - - LINVRNT(osc_lock_invariant(ols)); - - switch (ols->ols_state) { - case OLS_NEW: - LASSERT(!ols->ols_hold); - LASSERT(ols->ols_agl); - return 0; - case OLS_UPCALL_RECEIVED: - osc_lock_unhold(ols); - case OLS_ENQUEUED: - LASSERT(!ols->ols_hold); - osc_lock_detach(env, ols); - ols->ols_state = OLS_NEW; - return 0; - case OLS_GRANTED: - LASSERT(!ols->ols_glimpse); - LASSERT(ols->ols_hold); - /* - * Move lock into OLS_RELEASED state before calling - * osc_cancel_base() so that possible synchronous cancellation - * sees that lock is released. - */ - ols->ols_state = OLS_RELEASED; - return osc_lock_unhold(ols); - default: - CERROR("Impossible state: %d\n", ols->ols_state); - LBUG(); - } -} - static void osc_lock_fini(const struct lu_env *env, struct cl_lock_slice *slice) { struct osc_lock *ols = cl2osc_lock(slice); LINVRNT(osc_lock_invariant(ols)); - /* - * ->ols_hold can still be true at this point if, for example, a - * thread that requested a lock was killed (and released a reference - * to the lock), before reply from a server was received. In this case - * lock is destroyed immediately after upcall. - */ - osc_lock_unhold(ols); - LASSERT(!ols->ols_lock); + LASSERT(!ols->ols_dlmlock); kmem_cache_free(osc_lock_kmem, ols); } @@ -272,54 +169,11 @@ static __u64 osc_enq2ldlm_flags(__u32 enqflags) result |= LDLM_FL_HAS_INTENT; if (enqflags & CEF_DISCARD_DATA) result |= LDLM_FL_AST_DISCARD_DATA; + if (enqflags & CEF_PEEK) + result |= LDLM_FL_TEST_LOCK; return result; } -/** - * Global spin-lock protecting consistency of ldlm_lock::l_ast_data - * pointers. Initialized in osc_init(). - */ -spinlock_t osc_ast_guard; - -static struct osc_lock *osc_ast_data_get(struct ldlm_lock *dlm_lock) -{ - struct osc_lock *olck; - - lock_res_and_lock(dlm_lock); - spin_lock(&osc_ast_guard); - olck = dlm_lock->l_ast_data; - if (olck) { - struct cl_lock *lock = olck->ols_cl.cls_lock; - /* - * If osc_lock holds a reference on ldlm lock, return it even - * when cl_lock is in CLS_FREEING state. This way - * - * osc_ast_data_get(dlmlock) == NULL - * - * guarantees that all osc references on dlmlock were - * released. osc_dlm_blocking_ast0() relies on that. - */ - if (lock->cll_state < CLS_FREEING || olck->ols_has_ref) { - cl_lock_get_trust(lock); - lu_ref_add_atomic(&lock->cll_reference, - "ast", current); - } else - olck = NULL; - } - spin_unlock(&osc_ast_guard); - unlock_res_and_lock(dlm_lock); - return olck; -} - -static void osc_ast_data_put(const struct lu_env *env, struct osc_lock *olck) -{ - struct cl_lock *lock; - - lock = olck->ols_cl.cls_lock; - lu_ref_del(&lock->cll_reference, "ast", current); - cl_lock_put(env, lock); -} - /** * Updates object attributes from a lock value block (lvb) received together * with the DLM lock reply from the server. Copy of osc_update_enqueue() @@ -330,35 +184,30 @@ static void osc_ast_data_put(const struct lu_env *env, struct osc_lock *olck) * * Called under lock and resource spin-locks. */ -static void osc_lock_lvb_update(const struct lu_env *env, struct osc_lock *olck, - int rc) +static void osc_lock_lvb_update(const struct lu_env *env, + struct osc_object *osc, + struct ldlm_lock *dlmlock, + struct ost_lvb *lvb) { - struct ost_lvb *lvb; - struct cl_object *obj; - struct lov_oinfo *oinfo; - struct cl_attr *attr; + struct cl_object *obj = osc2cl(osc); + struct lov_oinfo *oinfo = osc->oo_oinfo; + struct cl_attr *attr = &osc_env_info(env)->oti_attr; unsigned valid; - if (!(olck->ols_flags & LDLM_FL_LVB_READY)) - return; - - lvb = &olck->ols_lvb; - obj = olck->ols_cl.cls_obj; - oinfo = cl2osc(obj)->oo_oinfo; - attr = &osc_env_info(env)->oti_attr; valid = CAT_BLOCKS | CAT_ATIME | CAT_CTIME | CAT_MTIME | CAT_SIZE; + if (!lvb) + lvb = dlmlock->l_lvb_data; + cl_lvb2attr(attr, lvb); cl_object_attr_lock(obj); - if (rc == 0) { - struct ldlm_lock *dlmlock; + if (dlmlock) { __u64 size; - dlmlock = olck->ols_lock; - - /* re-grab LVB from a dlm lock under DLM spin-locks. */ - *lvb = *(struct ost_lvb *)dlmlock->l_lvb_data; + check_res_locked(dlmlock->l_resource); + LASSERT(lvb == dlmlock->l_lvb_data); size = lvb->lvb_size; + /* Extend KMS up to the end of this lock and no further * A lock on [x,y] means a KMS of up to y + 1 bytes! */ @@ -375,102 +224,67 @@ static void osc_lock_lvb_update(const struct lu_env *env, struct osc_lock *olck, dlmlock->l_policy_data.l_extent.end); } ldlm_lock_allow_match_locked(dlmlock); - } else if (rc == -ENAVAIL && olck->ols_glimpse) { - CDEBUG(D_INODE, "glimpsed, setting rss=%llu; leaving kms=%llu\n", - lvb->lvb_size, oinfo->loi_kms); - } else - valid = 0; - - if (valid != 0) - cl_object_attr_set(env, obj, attr, valid); + } + cl_object_attr_set(env, obj, attr, valid); cl_object_attr_unlock(obj); } -/** - * Called when a lock is granted, from an upcall (when server returned a - * granted lock), or from completion AST, when server returned a blocked lock. - * - * Called under lock and resource spin-locks, that are released temporarily - * here. - */ -static void osc_lock_granted(const struct lu_env *env, struct osc_lock *olck, - struct ldlm_lock *dlmlock, int rc) +static void osc_lock_granted(const struct lu_env *env, struct osc_lock *oscl, + struct lustre_handle *lockh, bool lvb_update) { - struct ldlm_extent *ext; - struct cl_lock *lock; - struct cl_lock_descr *descr; + struct ldlm_lock *dlmlock; - LASSERT(dlmlock->l_granted_mode == dlmlock->l_req_mode); + dlmlock = ldlm_handle2lock_long(lockh, 0); + LASSERT(dlmlock); + + /* lock reference taken by ldlm_handle2lock_long() is + * owned by osc_lock and released in osc_lock_detach() + */ + lu_ref_add(&dlmlock->l_reference, "osc_lock", oscl); + oscl->ols_has_ref = 1; - if (olck->ols_state < OLS_GRANTED) { - lock = olck->ols_cl.cls_lock; - ext = &dlmlock->l_policy_data.l_extent; - descr = &osc_env_info(env)->oti_descr; - descr->cld_obj = lock->cll_descr.cld_obj; + LASSERT(!oscl->ols_dlmlock); + oscl->ols_dlmlock = dlmlock; - /* XXX check that ->l_granted_mode is valid. */ - descr->cld_mode = osc_ldlm2cl_lock(dlmlock->l_granted_mode); - descr->cld_start = cl_index(descr->cld_obj, ext->start); - descr->cld_end = cl_index(descr->cld_obj, ext->end); - descr->cld_gid = ext->gid; - /* - * tell upper layers the extent of the lock that was actually - * granted - */ - olck->ols_state = OLS_GRANTED; - osc_lock_lvb_update(env, olck, rc); - - /* release DLM spin-locks to allow cl_lock_{modify,signal}() - * to take a semaphore on a parent lock. This is safe, because - * spin-locks are needed to protect consistency of - * dlmlock->l_*_mode and LVB, and we have finished processing - * them. + /* This may be a matched lock for glimpse request, do not hold + * lock reference in that case. + */ + if (!oscl->ols_glimpse) { + /* hold a refc for non glimpse lock which will + * be released in osc_lock_cancel() */ - unlock_res_and_lock(dlmlock); - cl_lock_modify(env, lock, descr); - cl_lock_signal(env, lock); - LINVRNT(osc_lock_invariant(olck)); - lock_res_and_lock(dlmlock); + lustre_handle_copy(&oscl->ols_handle, lockh); + ldlm_lock_addref(lockh, oscl->ols_einfo.ei_mode); + oscl->ols_hold = 1; } -} - -static void osc_lock_upcall0(const struct lu_env *env, struct osc_lock *olck) - -{ - struct ldlm_lock *dlmlock; - - dlmlock = ldlm_handle2lock_long(&olck->ols_handle, 0); - LASSERT(dlmlock); + /* Lock must have been granted. */ lock_res_and_lock(dlmlock); - spin_lock(&osc_ast_guard); - LASSERT(dlmlock->l_ast_data == olck); - LASSERT(!olck->ols_lock); - olck->ols_lock = dlmlock; - spin_unlock(&osc_ast_guard); + if (dlmlock->l_granted_mode == dlmlock->l_req_mode) { + struct ldlm_extent *ext = &dlmlock->l_policy_data.l_extent; + struct cl_lock_descr *descr = &oscl->ols_cl.cls_lock->cll_descr; - /* - * Lock might be not yet granted. In this case, completion ast - * (osc_ldlm_completion_ast()) comes later and finishes lock - * granting. - */ - if (dlmlock->l_granted_mode == dlmlock->l_req_mode) - osc_lock_granted(env, olck, dlmlock, 0); - unlock_res_and_lock(dlmlock); + /* extend the lock extent, otherwise it will have problem when + * we decide whether to grant a lockless lock. + */ + descr->cld_mode = osc_ldlm2cl_lock(dlmlock->l_granted_mode); + descr->cld_start = cl_index(descr->cld_obj, ext->start); + descr->cld_end = cl_index(descr->cld_obj, ext->end); + descr->cld_gid = ext->gid; - /* - * osc_enqueue_interpret() decrefs asynchronous locks, counter - * this. - */ - ldlm_lock_addref(&olck->ols_handle, olck->ols_einfo.ei_mode); - olck->ols_hold = 1; + /* no lvb update for matched lock */ + if (lvb_update) { + LASSERT(oscl->ols_flags & LDLM_FL_LVB_READY); + osc_lock_lvb_update(env, cl2osc(oscl->ols_cl.cls_obj), + dlmlock, NULL); + } + LINVRNT(osc_lock_invariant(oscl)); + } + unlock_res_and_lock(dlmlock); - /* lock reference taken by ldlm_handle2lock_long() is owned by - * osc_lock and released in osc_lock_detach() - */ - lu_ref_add(&dlmlock->l_reference, "osc_lock", olck); - olck->ols_has_ref = 1; + LASSERT(oscl->ols_state != OLS_GRANTED); + oscl->ols_state = OLS_GRANTED; } /** @@ -478,143 +292,124 @@ static void osc_lock_upcall0(const struct lu_env *env, struct osc_lock *olck) * received from a server, or after osc_enqueue_base() matched a local DLM * lock. */ -static int osc_lock_upcall(void *cookie, int errcode) +static int osc_lock_upcall(void *cookie, struct lustre_handle *lockh, + int errcode) { - struct osc_lock *olck = cookie; - struct cl_lock_slice *slice = &olck->ols_cl; - struct cl_lock *lock = slice->cls_lock; + struct osc_lock *oscl = cookie; + struct cl_lock_slice *slice = &oscl->ols_cl; struct lu_env *env; struct cl_env_nest nest; + int rc; env = cl_env_nested_get(&nest); - if (!IS_ERR(env)) { - int rc; - - cl_lock_mutex_get(env, lock); + /* should never happen, similar to osc_ldlm_blocking_ast(). */ + LASSERT(!IS_ERR(env)); + + rc = ldlm_error2errno(errcode); + if (oscl->ols_state == OLS_ENQUEUED) { + oscl->ols_state = OLS_UPCALL_RECEIVED; + } else if (oscl->ols_state == OLS_CANCELLED) { + rc = -EIO; + } else { + CERROR("Impossible state: %d\n", oscl->ols_state); + LBUG(); + } - LASSERT(lock->cll_state >= CLS_QUEUING); - if (olck->ols_state == OLS_ENQUEUED) { - olck->ols_state = OLS_UPCALL_RECEIVED; - rc = ldlm_error2errno(errcode); - } else if (olck->ols_state == OLS_CANCELLED) { - rc = -EIO; - } else { - CERROR("Impossible state: %d\n", olck->ols_state); - LBUG(); - } - if (rc) { - struct ldlm_lock *dlmlock; - - dlmlock = ldlm_handle2lock(&olck->ols_handle); - if (dlmlock) { - lock_res_and_lock(dlmlock); - spin_lock(&osc_ast_guard); - LASSERT(!olck->ols_lock); - dlmlock->l_ast_data = NULL; - olck->ols_handle.cookie = 0ULL; - spin_unlock(&osc_ast_guard); - ldlm_lock_fail_match_locked(dlmlock); - unlock_res_and_lock(dlmlock); - LDLM_LOCK_PUT(dlmlock); - } - } else { - if (olck->ols_glimpse) - olck->ols_glimpse = 0; - osc_lock_upcall0(env, olck); - } + if (rc == 0) + osc_lock_granted(env, oscl, lockh, errcode == ELDLM_OK); - /* Error handling, some errors are tolerable. */ - if (olck->ols_locklessable && rc == -EUSERS) { - /* This is a tolerable error, turn this lock into - * lockless lock. - */ - osc_object_set_contended(cl2osc(slice->cls_obj)); - LASSERT(slice->cls_ops == &osc_lock_ops); + /* Error handling, some errors are tolerable. */ + if (oscl->ols_locklessable && rc == -EUSERS) { + /* This is a tolerable error, turn this lock into + * lockless lock. + */ + osc_object_set_contended(cl2osc(slice->cls_obj)); + LASSERT(slice->cls_ops == &osc_lock_ops); + + /* Change this lock to ldlmlock-less lock. */ + osc_lock_to_lockless(env, oscl, 1); + oscl->ols_state = OLS_GRANTED; + rc = 0; + } else if (oscl->ols_glimpse && rc == -ENAVAIL) { + LASSERT(oscl->ols_flags & LDLM_FL_LVB_READY); + osc_lock_lvb_update(env, cl2osc(slice->cls_obj), + NULL, &oscl->ols_lvb); + /* Hide the error. */ + rc = 0; + } - /* Change this lock to ldlmlock-less lock. */ - osc_lock_to_lockless(env, olck, 1); - olck->ols_state = OLS_GRANTED; - rc = 0; - } else if (olck->ols_glimpse && rc == -ENAVAIL) { - osc_lock_lvb_update(env, olck, rc); - cl_lock_delete(env, lock); - /* Hide the error. */ - rc = 0; - } + if (oscl->ols_owner) + cl_sync_io_note(env, oscl->ols_owner, rc); + cl_env_nested_put(&nest, env); - if (rc == 0) { - /* For AGL case, the RPC sponsor may exits the cl_lock - * processing without wait() called before related OSC - * lock upcall(). So update the lock status according - * to the enqueue result inside AGL upcall(). - */ - if (olck->ols_agl) { - lock->cll_flags |= CLF_FROM_UPCALL; - cl_wait_try(env, lock); - lock->cll_flags &= ~CLF_FROM_UPCALL; - if (!olck->ols_glimpse) - olck->ols_agl = 0; - } - cl_lock_signal(env, lock); - /* del user for lock upcall cookie */ - cl_unuse_try(env, lock); - } else { - /* del user for lock upcall cookie */ - cl_lock_user_del(env, lock); - cl_lock_error(env, lock, rc); - } + return rc; +} - /* release cookie reference, acquired by osc_lock_enqueue() */ - cl_lock_hold_release(env, lock, "upcall", lock); - cl_lock_mutex_put(env, lock); +static int osc_lock_upcall_agl(void *cookie, struct lustre_handle *lockh, + int errcode) +{ + struct osc_object *osc = cookie; + struct ldlm_lock *dlmlock; + struct lu_env *env; + struct cl_env_nest nest; - lu_ref_del(&lock->cll_reference, "upcall", lock); - /* This maybe the last reference, so must be called after - * cl_lock_mutex_put(). - */ - cl_lock_put(env, lock); + env = cl_env_nested_get(&nest); + LASSERT(!IS_ERR(env)); - cl_env_nested_put(&nest, env); - } else { - /* should never happen, similar to osc_ldlm_blocking_ast(). */ - LBUG(); + if (errcode == ELDLM_LOCK_MATCHED) { + errcode = ELDLM_OK; + goto out; } - return errcode; + + if (errcode != ELDLM_OK) + goto out; + + dlmlock = ldlm_handle2lock(lockh); + LASSERT(dlmlock); + + lock_res_and_lock(dlmlock); + LASSERT(dlmlock->l_granted_mode == dlmlock->l_req_mode); + + /* there is no osc_lock associated with AGL lock */ + osc_lock_lvb_update(env, osc, dlmlock, NULL); + + unlock_res_and_lock(dlmlock); + LDLM_LOCK_PUT(dlmlock); + +out: + cl_object_put(env, osc2cl(osc)); + cl_env_nested_put(&nest, env); + return ldlm_error2errno(errcode); } -/** - * Core of osc_dlm_blocking_ast() logic. - */ -static void osc_lock_blocking(const struct lu_env *env, - struct ldlm_lock *dlmlock, - struct osc_lock *olck, int blocking) +static int osc_lock_flush(struct osc_object *obj, pgoff_t start, pgoff_t end, + enum cl_lock_mode mode, int discard) { - struct cl_lock *lock = olck->ols_cl.cls_lock; + struct lu_env *env; + struct cl_env_nest nest; + int rc = 0; + int rc2 = 0; - LASSERT(olck->ols_lock == dlmlock); - CLASSERT(OLS_BLOCKED < OLS_CANCELLED); - LASSERT(!osc_lock_is_lockless(olck)); + env = cl_env_nested_get(&nest); + if (IS_ERR(env)) + return PTR_ERR(env); + + if (mode == CLM_WRITE) { + rc = osc_cache_writeback_range(env, obj, start, end, 1, + discard); + CDEBUG(D_CACHE, "object %p: [%lu -> %lu] %d pages were %s.\n", + obj, start, end, rc, + discard ? "discarded" : "written back"); + if (rc > 0) + rc = 0; + } - /* - * Lock might be still addref-ed here, if e.g., blocking ast - * is sent for a failed lock. - */ - osc_lock_unhold(olck); + rc2 = osc_lock_discard_pages(env, obj, start, end, mode); + if (rc == 0 && rc2 < 0) + rc = rc2; - if (blocking && olck->ols_state < OLS_BLOCKED) - /* - * Move osc_lock into OLS_BLOCKED before canceling the lock, - * because it recursively re-enters osc_lock_blocking(), with - * the state set to OLS_CANCELLED. - */ - olck->ols_state = OLS_BLOCKED; - /* - * cancel and destroy lock at least once no matter how blocking ast is - * entered (see comment above osc_ldlm_blocking_ast() for use - * cases). cl_lock_cancel() and cl_lock_delete() are idempotent. - */ - cl_lock_cancel(env, lock); - cl_lock_delete(env, lock); + cl_env_nested_put(&nest, env); + return rc; } /** @@ -625,65 +420,63 @@ static int osc_dlm_blocking_ast0(const struct lu_env *env, struct ldlm_lock *dlmlock, void *data, int flag) { - struct osc_lock *olck; - struct cl_lock *lock; - int result; - int cancel; - - LASSERT(flag == LDLM_CB_BLOCKING || flag == LDLM_CB_CANCELING); - - cancel = 0; - olck = osc_ast_data_get(dlmlock); - if (olck) { - lock = olck->ols_cl.cls_lock; - cl_lock_mutex_get(env, lock); - LINVRNT(osc_lock_invariant(olck)); - if (olck->ols_ast_wait) { - /* wake up osc_lock_use() */ - cl_lock_signal(env, lock); - olck->ols_ast_wait = 0; - } - /* - * Lock might have been canceled while this thread was - * sleeping for lock mutex, but olck is pinned in memory. - */ - if (olck == dlmlock->l_ast_data) { - /* - * NOTE: DLM sends blocking AST's for failed locks - * (that are still in pre-OLS_GRANTED state) - * too, and they have to be canceled otherwise - * DLM lock is never destroyed and stuck in - * the memory. - * - * Alternatively, ldlm_cli_cancel() can be - * called here directly for osc_locks with - * ols_state < OLS_GRANTED to maintain an - * invariant that ->clo_cancel() is only called - * for locks that were granted. - */ - LASSERT(data == olck); - osc_lock_blocking(env, dlmlock, - olck, flag == LDLM_CB_BLOCKING); - } else - cancel = 1; - cl_lock_mutex_put(env, lock); - osc_ast_data_put(env, olck); - } else - /* - * DLM lock exists, but there is no cl_lock attached to it. - * This is a `normal' race. cl_object and its cl_lock's can be - * removed by memory pressure, together with all pages. + struct cl_object *obj = NULL; + int result = 0; + int discard; + enum cl_lock_mode mode = CLM_READ; + + LASSERT(flag == LDLM_CB_CANCELING); + + lock_res_and_lock(dlmlock); + if (dlmlock->l_granted_mode != dlmlock->l_req_mode) { + dlmlock->l_ast_data = NULL; + unlock_res_and_lock(dlmlock); + return 0; + } + + discard = ldlm_is_discard_data(dlmlock); + if (dlmlock->l_granted_mode & (LCK_PW | LCK_GROUP)) + mode = CLM_WRITE; + + if (dlmlock->l_ast_data) { + obj = osc2cl(dlmlock->l_ast_data); + dlmlock->l_ast_data = NULL; + + cl_object_get(obj); + } + + unlock_res_and_lock(dlmlock); + + /* if l_ast_data is NULL, the dlmlock was enqueued by AGL or + * the object has been destroyed. + */ + if (obj) { + struct ldlm_extent *extent = &dlmlock->l_policy_data.l_extent; + struct cl_attr *attr = &osc_env_info(env)->oti_attr; + __u64 old_kms; + + /* Destroy pages covered by the extent of the DLM lock */ + result = osc_lock_flush(cl2osc(obj), + cl_index(obj, extent->start), + cl_index(obj, extent->end), + mode, discard); + + /* losing a lock, update kms */ + lock_res_and_lock(dlmlock); + cl_object_attr_lock(obj); + /* Must get the value under the lock to avoid race. */ + old_kms = cl2osc(obj)->oo_oinfo->loi_kms; + /* Update the kms. Need to loop all granted locks. + * Not a problem for the client */ - cancel = (flag == LDLM_CB_BLOCKING); + attr->cat_kms = ldlm_extent_shift_kms(dlmlock, old_kms); - if (cancel) { - struct lustre_handle *lockh; + cl_object_attr_set(env, obj, attr, CAT_KMS); + cl_object_attr_unlock(obj); + unlock_res_and_lock(dlmlock); - lockh = &osc_env_info(env)->oti_handle; - ldlm_lock2handle(dlmlock, lockh); - result = ldlm_cli_cancel(lockh, LCF_ASYNC); - } else - result = 0; + cl_object_put(env, obj); + } return result; } @@ -733,107 +526,52 @@ static int osc_ldlm_blocking_ast(struct ldlm_lock *dlmlock, struct ldlm_lock_desc *new, void *data, int flag) { - struct lu_env *env; - struct cl_env_nest nest; - int result; + int result = 0; - /* - * This can be called in the context of outer IO, e.g., - * - * cl_enqueue()->... - * ->osc_enqueue_base()->... - * ->ldlm_prep_elc_req()->... - * ->ldlm_cancel_callback()->... - * ->osc_ldlm_blocking_ast() - * - * new environment has to be created to not corrupt outer context. - */ - env = cl_env_nested_get(&nest); - if (!IS_ERR(env)) { - result = osc_dlm_blocking_ast0(env, dlmlock, data, flag); - cl_env_nested_put(&nest, env); - } else { - result = PTR_ERR(env); - /* - * XXX This should never happen, as cl_lock is - * stuck. Pre-allocated environment a la vvp_inode_fini_env - * should be used. - */ - LBUG(); - } - if (result != 0) { + switch (flag) { + case LDLM_CB_BLOCKING: { + struct lustre_handle lockh; + + ldlm_lock2handle(dlmlock, &lockh); + result = ldlm_cli_cancel(&lockh, LCF_ASYNC); if (result == -ENODATA) result = 0; - else - CERROR("BAST failed: %d\n", result); + break; } - return result; -} - -static int osc_ldlm_completion_ast(struct ldlm_lock *dlmlock, - __u64 flags, void *data) -{ - struct cl_env_nest nest; - struct lu_env *env; - struct osc_lock *olck; - struct cl_lock *lock; - int result; - int dlmrc; + case LDLM_CB_CANCELING: { + struct lu_env *env; + struct cl_env_nest nest; - /* first, do dlm part of the work */ - dlmrc = ldlm_completion_ast_async(dlmlock, flags, data); - /* then, notify cl_lock */ - env = cl_env_nested_get(&nest); - if (!IS_ERR(env)) { - olck = osc_ast_data_get(dlmlock); - if (olck) { - lock = olck->ols_cl.cls_lock; - cl_lock_mutex_get(env, lock); - /* - * ldlm_handle_cp_callback() copied LVB from request - * to lock->l_lvb_data, store it in osc_lock. - */ - LASSERT(dlmlock->l_lvb_data); - lock_res_and_lock(dlmlock); - olck->ols_lvb = *(struct ost_lvb *)dlmlock->l_lvb_data; - if (!olck->ols_lock) { - /* - * upcall (osc_lock_upcall()) hasn't yet been - * called. Do nothing now, upcall will bind - * olck to dlmlock and signal the waiters. - * - * This maintains an invariant that osc_lock - * and ldlm_lock are always bound when - * osc_lock is in OLS_GRANTED state. - */ - } else if (dlmlock->l_granted_mode == - dlmlock->l_req_mode) { - osc_lock_granted(env, olck, dlmlock, dlmrc); - } - unlock_res_and_lock(dlmlock); + /* + * This can be called in the context of outer IO, e.g., + * + * osc_enqueue_base()->... + * ->ldlm_prep_elc_req()->... + * ->ldlm_cancel_callback()->... + * ->osc_ldlm_blocking_ast() + * + * new environment has to be created to not corrupt outer + * context. + */ + env = cl_env_nested_get(&nest); + if (IS_ERR(env)) { + result = PTR_ERR(env); + break; + } - if (dlmrc != 0) { - CL_LOCK_DEBUG(D_ERROR, env, lock, - "dlmlock returned %d\n", dlmrc); - cl_lock_error(env, lock, dlmrc); - } - cl_lock_mutex_put(env, lock); - osc_ast_data_put(env, olck); - result = 0; - } else - result = -ELDLM_NO_LOCK_DATA; + result = osc_dlm_blocking_ast0(env, dlmlock, data, flag); cl_env_nested_put(&nest, env); - } else - result = PTR_ERR(env); - return dlmrc ?: result; + break; + } + default: + LBUG(); + } + return result; } static int osc_ldlm_glimpse_ast(struct ldlm_lock *dlmlock, void *data) { struct ptlrpc_request *req = data; - struct osc_lock *olck; - struct cl_lock *lock; - struct cl_object *obj; struct cl_env_nest nest; struct lu_env *env; struct ost_lvb *lvb; @@ -844,14 +582,16 @@ static int osc_ldlm_glimpse_ast(struct ldlm_lock *dlmlock, void *data) env = cl_env_nested_get(&nest); if (!IS_ERR(env)) { - /* osc_ast_data_get() has to go after environment is - * allocated, because osc_ast_data() acquires a - * reference to a lock, and it can only be released in - * environment. - */ - olck = osc_ast_data_get(dlmlock); - if (olck) { - lock = olck->ols_cl.cls_lock; + struct cl_object *obj = NULL; + + lock_res_and_lock(dlmlock); + if (dlmlock->l_ast_data) { + obj = osc2cl(dlmlock->l_ast_data); + cl_object_get(obj); + } + unlock_res_and_lock(dlmlock); + + if (obj) { /* Do not grab the mutex of cl_lock for glimpse. * See LU-1274 for details. * BTW, it's okay for cl_lock to be cancelled during @@ -866,7 +606,6 @@ static int osc_ldlm_glimpse_ast(struct ldlm_lock *dlmlock, void *data) result = req_capsule_server_pack(cap); if (result == 0) { lvb = req_capsule_server_get(cap, &RMF_DLM_LVB); - obj = lock->cll_descr.cld_obj; result = cl_object_glimpse(env, obj, lvb); } if (!exp_connect_lvb_type(req->rq_export)) @@ -874,7 +613,7 @@ static int osc_ldlm_glimpse_ast(struct ldlm_lock *dlmlock, void *data) &RMF_DLM_LVB, sizeof(struct ost_lvb_v1), RCL_SERVER); - osc_ast_data_put(env, olck); + cl_object_put(env, obj); } else { /* * These errors are normal races, so we don't want to @@ -905,23 +644,24 @@ static int weigh_cb(const struct lu_env *env, struct cl_io *io, } static unsigned long osc_lock_weight(const struct lu_env *env, - const struct osc_lock *ols) + struct osc_object *oscobj, + struct ldlm_extent *extent) { struct cl_io *io = &osc_env_info(env)->oti_io; - struct cl_lock_descr *descr = &ols->ols_cl.cls_lock->cll_descr; - struct cl_object *obj = ols->ols_cl.cls_obj; + struct cl_object *obj = cl_object_top(&oscobj->oo_cl); unsigned long npages = 0; int result; - io->ci_obj = cl_object_top(obj); + io->ci_obj = obj; io->ci_ignore_layout = 1; result = cl_io_init(env, io, CIT_MISC, io->ci_obj); if (result != 0) return result; do { - result = osc_page_gang_lookup(env, io, cl2osc(obj), - descr->cld_start, descr->cld_end, + result = osc_page_gang_lookup(env, io, oscobj, + cl_index(obj, extent->start), + cl_index(obj, extent->end), weigh_cb, (void *)&npages); if (result == CLP_GANG_ABORT) break; @@ -940,8 +680,10 @@ unsigned long osc_ldlm_weigh_ast(struct ldlm_lock *dlmlock) { struct cl_env_nest nest; struct lu_env *env; - struct osc_lock *lock; + struct osc_object *obj; + struct osc_lock *oscl; unsigned long weight; + bool found = false; might_sleep(); /* @@ -957,18 +699,28 @@ unsigned long osc_ldlm_weigh_ast(struct ldlm_lock *dlmlock) return 1; LASSERT(dlmlock->l_resource->lr_type == LDLM_EXTENT); - lock = osc_ast_data_get(dlmlock); - if (!lock) { - /* cl_lock was destroyed because of memory pressure. - * It is much reasonable to assign this type of lock - * a lower cost. + obj = dlmlock->l_ast_data; + if (obj) { + weight = 1; + goto out; + } + + spin_lock(&obj->oo_ol_spin); + list_for_each_entry(oscl, &obj->oo_ol_list, ols_nextlock_oscobj) { + if (oscl->ols_dlmlock && oscl->ols_dlmlock != dlmlock) + continue; + found = true; + } + spin_unlock(&obj->oo_ol_spin); + if (found) { + /* + * If the lock is being used by an IO, definitely not cancel it. */ - weight = 0; + weight = 1; goto out; } - weight = osc_lock_weight(env, lock); - osc_ast_data_put(env, lock); + weight = osc_lock_weight(env, obj, &dlmlock->l_policy_data.l_extent); out: cl_env_nested_put(&nest, env); @@ -976,27 +728,16 @@ out: } static void osc_lock_build_einfo(const struct lu_env *env, - const struct cl_lock *clock, - struct osc_lock *lock, + const struct cl_lock *lock, + struct osc_object *osc, struct ldlm_enqueue_info *einfo) { - enum cl_lock_mode mode; - - mode = clock->cll_descr.cld_mode; - if (mode == CLM_PHANTOM) - /* - * For now, enqueue all glimpse locks in read mode. In the - * future, client might choose to enqueue LCK_PW lock for - * glimpse on a file opened for write. - */ - mode = CLM_READ; - einfo->ei_type = LDLM_EXTENT; - einfo->ei_mode = osc_cl_lock2ldlm(mode); + einfo->ei_mode = osc_cl_lock2ldlm(lock->cll_descr.cld_mode); einfo->ei_cb_bl = osc_ldlm_blocking_ast; - einfo->ei_cb_cp = osc_ldlm_completion_ast; + einfo->ei_cb_cp = ldlm_completion_ast; einfo->ei_cb_gl = osc_ldlm_glimpse_ast; - einfo->ei_cbdata = lock; /* value to be put into ->l_ast_data */ + einfo->ei_cbdata = osc; /* value to be put into ->l_ast_data */ } /** @@ -1052,113 +793,100 @@ static void osc_lock_to_lockless(const struct lu_env *env, LASSERT(ergo(ols->ols_glimpse, !osc_lock_is_lockless(ols))); } -static int osc_lock_compatible(const struct osc_lock *qing, - const struct osc_lock *qed) +static bool osc_lock_compatible(const struct osc_lock *qing, + const struct osc_lock *qed) { - enum cl_lock_mode qing_mode; - enum cl_lock_mode qed_mode; + struct cl_lock_descr *qed_descr = &qed->ols_cl.cls_lock->cll_descr; + struct cl_lock_descr *qing_descr = &qing->ols_cl.cls_lock->cll_descr; - qing_mode = qing->ols_cl.cls_lock->cll_descr.cld_mode; - if (qed->ols_glimpse && - (qed->ols_state >= OLS_UPCALL_RECEIVED || qing_mode == CLM_READ)) - return 1; + if (qed->ols_glimpse) + return true; + + if (qing_descr->cld_mode == CLM_READ && qed_descr->cld_mode == CLM_READ) + return true; + + if (qed->ols_state < OLS_GRANTED) + return true; + + if (qed_descr->cld_mode >= qing_descr->cld_mode && + qed_descr->cld_start <= qing_descr->cld_start && + qed_descr->cld_end >= qing_descr->cld_end) + return true; - qed_mode = qed->ols_cl.cls_lock->cll_descr.cld_mode; - return ((qing_mode == CLM_READ) && (qed_mode == CLM_READ)); + return false; } -/** - * Cancel all conflicting locks and wait for them to be destroyed. - * - * This function is used for two purposes: - * - * - early cancel all conflicting locks before starting IO, and - * - * - guarantee that pages added to the page cache by lockless IO are never - * covered by locks other than lockless IO lock, and, hence, are not - * visible to other threads. - */ -static int osc_lock_enqueue_wait(const struct lu_env *env, - const struct osc_lock *olck) +static void osc_lock_wake_waiters(const struct lu_env *env, + struct osc_object *osc, + struct osc_lock *oscl) { - struct cl_lock *lock = olck->ols_cl.cls_lock; - struct cl_lock_descr *descr = &lock->cll_descr; - struct cl_object_header *hdr = cl_object_header(descr->cld_obj); - struct cl_lock *scan; - struct cl_lock *conflict = NULL; - int lockless = osc_lock_is_lockless(olck); - int rc = 0; + spin_lock(&osc->oo_ol_spin); + list_del_init(&oscl->ols_nextlock_oscobj); + spin_unlock(&osc->oo_ol_spin); - LASSERT(cl_lock_is_mutexed(lock)); + spin_lock(&oscl->ols_lock); + while (!list_empty(&oscl->ols_waiting_list)) { + struct osc_lock *scan; - /* make it enqueue anyway for glimpse lock, because we actually - * don't need to cancel any conflicting locks. - */ - if (olck->ols_glimpse) - return 0; + scan = list_entry(oscl->ols_waiting_list.next, struct osc_lock, + ols_wait_entry); + list_del_init(&scan->ols_wait_entry); + + cl_sync_io_note(env, scan->ols_owner, 0); + } + spin_unlock(&oscl->ols_lock); +} - spin_lock(&hdr->coh_lock_guard); - list_for_each_entry(scan, &hdr->coh_locks, cll_linkage) { - struct cl_lock_descr *cld = &scan->cll_descr; - const struct osc_lock *scan_ols; +static void osc_lock_enqueue_wait(const struct lu_env *env, + struct osc_object *obj, + struct osc_lock *oscl) +{ + struct osc_lock *tmp_oscl; + struct cl_lock_descr *need = &oscl->ols_cl.cls_lock->cll_descr; + struct cl_sync_io *waiter = &osc_env_info(env)->oti_anchor; + + spin_lock(&obj->oo_ol_spin); + list_add_tail(&oscl->ols_nextlock_oscobj, &obj->oo_ol_list); - if (scan == lock) +restart: + list_for_each_entry(tmp_oscl, &obj->oo_ol_list, + ols_nextlock_oscobj) { + struct cl_lock_descr *descr; + + if (tmp_oscl == oscl) break; - if (scan->cll_state < CLS_QUEUING || - scan->cll_state == CLS_FREEING || - cld->cld_start > descr->cld_end || - cld->cld_end < descr->cld_start) + descr = &tmp_oscl->ols_cl.cls_lock->cll_descr; + if (descr->cld_start > need->cld_end || + descr->cld_end < need->cld_start) continue; - /* overlapped and living locks. */ + /* We're not supposed to give up group lock */ + if (descr->cld_mode == CLM_GROUP) + break; - /* We're not supposed to give up group lock. */ - if (scan->cll_descr.cld_mode == CLM_GROUP) { - LASSERT(descr->cld_mode != CLM_GROUP || - descr->cld_gid != scan->cll_descr.cld_gid); + if (!osc_lock_is_lockless(oscl) && + osc_lock_compatible(oscl, tmp_oscl)) continue; - } - scan_ols = osc_lock_at(scan); + /* wait for conflicting lock to be canceled */ + cl_sync_io_init(waiter, 1, cl_sync_io_end); + oscl->ols_owner = waiter; - /* We need to cancel the compatible locks if we're enqueuing - * a lockless lock, for example: - * imagine that client has PR lock on [0, 1000], and thread T0 - * is doing lockless IO in [500, 1500] region. Concurrent - * thread T1 can see lockless data in [500, 1000], which is - * wrong, because these data are possibly stale. - */ - if (!lockless && osc_lock_compatible(olck, scan_ols)) - continue; + spin_lock(&tmp_oscl->ols_lock); + /* add oscl into tmp's ols_waiting list */ + list_add_tail(&oscl->ols_wait_entry, + &tmp_oscl->ols_waiting_list); + spin_unlock(&tmp_oscl->ols_lock); - cl_lock_get_trust(scan); - conflict = scan; - break; - } - spin_unlock(&hdr->coh_lock_guard); + spin_unlock(&obj->oo_ol_spin); + (void)cl_sync_io_wait(env, waiter, 0); - if (conflict) { - if (lock->cll_descr.cld_mode == CLM_GROUP) { - /* we want a group lock but a previous lock request - * conflicts, we do not wait but return 0 so the - * request is send to the server - */ - CDEBUG(D_DLMTRACE, "group lock %p is conflicted with %p, no wait, send to server\n", - lock, conflict); - cl_lock_put(env, conflict); - rc = 0; - } else { - CDEBUG(D_DLMTRACE, "lock %p is conflicted with %p, will wait\n", - lock, conflict); - LASSERT(!lock->cll_conflict); - lu_ref_add(&conflict->cll_reference, "cancel-wait", - lock); - lock->cll_conflict = conflict; - rc = CLO_WAIT; - } + spin_lock(&obj->oo_ol_spin); + oscl->ols_owner = NULL; + goto restart; } - return rc; + spin_unlock(&obj->oo_ol_spin); } /** @@ -1177,188 +905,122 @@ static int osc_lock_enqueue_wait(const struct lu_env *env, */ static int osc_lock_enqueue(const struct lu_env *env, const struct cl_lock_slice *slice, - struct cl_io *unused, __u32 enqflags) + struct cl_io *unused, struct cl_sync_io *anchor) { - struct osc_lock *ols = cl2osc_lock(slice); - struct cl_lock *lock = ols->ols_cl.cls_lock; + struct osc_thread_info *info = osc_env_info(env); + struct osc_io *oio = osc_env_io(env); + struct osc_object *osc = cl2osc(slice->cls_obj); + struct osc_lock *oscl = cl2osc_lock(slice); + struct cl_lock *lock = slice->cls_lock; + struct ldlm_res_id *resname = &info->oti_resname; + ldlm_policy_data_t *policy = &info->oti_policy; + osc_enqueue_upcall_f upcall = osc_lock_upcall; + void *cookie = oscl; + bool async = false; int result; - LASSERT(cl_lock_is_mutexed(lock)); - LASSERTF(ols->ols_state == OLS_NEW, - "Impossible state: %d\n", ols->ols_state); - - LASSERTF(ergo(ols->ols_glimpse, lock->cll_descr.cld_mode <= CLM_READ), - "lock = %p, ols = %p\n", lock, ols); + LASSERTF(ergo(oscl->ols_glimpse, lock->cll_descr.cld_mode <= CLM_READ), + "lock = %p, ols = %p\n", lock, oscl); - result = osc_lock_enqueue_wait(env, ols); - if (result == 0) { - if (!osc_lock_is_lockless(ols)) { - struct osc_object *obj = cl2osc(slice->cls_obj); - struct osc_thread_info *info = osc_env_info(env); - struct ldlm_res_id *resname = &info->oti_resname; - ldlm_policy_data_t *policy = &info->oti_policy; - struct ldlm_enqueue_info *einfo = &ols->ols_einfo; + if (oscl->ols_state == OLS_GRANTED) + return 0; - /* lock will be passed as upcall cookie, - * hold ref to prevent to be released. - */ - cl_lock_hold_add(env, lock, "upcall", lock); - /* a user for lock also */ - cl_lock_user_add(env, lock); - ols->ols_state = OLS_ENQUEUED; + if (oscl->ols_flags & LDLM_FL_TEST_LOCK) + goto enqueue_base; - /* - * XXX: this is possible blocking point as - * ldlm_lock_match(LDLM_FL_LVB_READY) waits for - * LDLM_CP_CALLBACK. - */ - ostid_build_res_name(&obj->oo_oinfo->loi_oi, resname); - osc_lock_build_policy(env, lock, policy); - result = osc_enqueue_base(osc_export(obj), resname, - &ols->ols_flags, policy, - &ols->ols_lvb, - obj->oo_oinfo->loi_kms_valid, - osc_lock_upcall, - ols, einfo, &ols->ols_handle, - PTLRPCD_SET, 1, ols->ols_agl); - if (result != 0) { - cl_lock_user_del(env, lock); - cl_lock_unhold(env, lock, "upcall", lock); - if (unlikely(result == -ECANCELED)) { - ols->ols_state = OLS_NEW; - result = 0; - } - } - } else { - ols->ols_state = OLS_GRANTED; - ols->ols_owner = osc_env_io(env); - } + if (oscl->ols_glimpse) { + LASSERT(equi(oscl->ols_agl, !anchor)); + async = true; + goto enqueue_base; } - LASSERT(ergo(ols->ols_glimpse, !osc_lock_is_lockless(ols))); - return result; -} -static int osc_lock_wait(const struct lu_env *env, - const struct cl_lock_slice *slice) -{ - struct osc_lock *olck = cl2osc_lock(slice); - struct cl_lock *lock = olck->ols_cl.cls_lock; - - LINVRNT(osc_lock_invariant(olck)); - - if (olck->ols_glimpse && olck->ols_state >= OLS_UPCALL_RECEIVED) { - if (olck->ols_flags & LDLM_FL_LVB_READY) { - return 0; - } else if (olck->ols_agl) { - if (lock->cll_flags & CLF_FROM_UPCALL) - /* It is from enqueue RPC reply upcall for - * updating state. Do not re-enqueue. - */ - return -ENAVAIL; - olck->ols_state = OLS_NEW; - } else { - LASSERT(lock->cll_error); - return lock->cll_error; - } + osc_lock_enqueue_wait(env, osc, oscl); + + /* we can grant lockless lock right after all conflicting locks + * are canceled. + */ + if (osc_lock_is_lockless(oscl)) { + oscl->ols_state = OLS_GRANTED; + oio->oi_lockless = 1; + return 0; } - if (olck->ols_state == OLS_NEW) { - int rc; - - LASSERT(olck->ols_agl); - olck->ols_agl = 0; - olck->ols_flags &= ~LDLM_FL_BLOCK_NOWAIT; - rc = osc_lock_enqueue(env, slice, NULL, CEF_ASYNC | CEF_MUST); - if (rc != 0) - return rc; - else - return CLO_REENQUEUED; +enqueue_base: + oscl->ols_state = OLS_ENQUEUED; + if (anchor) { + atomic_inc(&anchor->csi_sync_nr); + oscl->ols_owner = anchor; } - LASSERT(equi(olck->ols_state >= OLS_UPCALL_RECEIVED && - lock->cll_error == 0, olck->ols_lock)); + /** + * DLM lock's ast data must be osc_object; + * if glimpse or AGL lock, async of osc_enqueue_base() must be true, + * DLM's enqueue callback set to osc_lock_upcall() with cookie as + * osc_lock. + */ + ostid_build_res_name(&osc->oo_oinfo->loi_oi, resname); + osc_lock_build_einfo(env, lock, osc, &oscl->ols_einfo); + osc_lock_build_policy(env, lock, policy); + if (oscl->ols_agl) { + oscl->ols_einfo.ei_cbdata = NULL; + /* hold a reference for callback */ + cl_object_get(osc2cl(osc)); + upcall = osc_lock_upcall_agl; + cookie = osc; + } + result = osc_enqueue_base(osc_export(osc), resname, &oscl->ols_flags, + policy, &oscl->ols_lvb, + osc->oo_oinfo->loi_kms_valid, + upcall, cookie, + &oscl->ols_einfo, PTLRPCD_SET, async, + oscl->ols_agl); + if (result != 0) { + oscl->ols_state = OLS_CANCELLED; + osc_lock_wake_waiters(env, osc, oscl); - return lock->cll_error ?: olck->ols_state >= OLS_GRANTED ? 0 : CLO_WAIT; + /* hide error for AGL lock. */ + if (oscl->ols_agl) { + cl_object_put(env, osc2cl(osc)); + result = 0; + } + if (anchor) + cl_sync_io_note(env, anchor, result); + } else { + if (osc_lock_is_lockless(oscl)) { + oio->oi_lockless = 1; + } else if (!async) { + LASSERT(oscl->ols_state == OLS_GRANTED); + LASSERT(oscl->ols_hold); + LASSERT(oscl->ols_dlmlock); + } + } + return result; } /** - * An implementation of cl_lock_operations::clo_use() method that pins cached - * lock. + * Breaks a link between osc_lock and dlm_lock. */ -static int osc_lock_use(const struct lu_env *env, - const struct cl_lock_slice *slice) +static void osc_lock_detach(const struct lu_env *env, struct osc_lock *olck) { - struct osc_lock *olck = cl2osc_lock(slice); - int rc; - - LASSERT(!olck->ols_hold); + struct ldlm_lock *dlmlock; - /* - * Atomically check for LDLM_FL_CBPENDING and addref a lock if this - * flag is not set. This protects us from a concurrent blocking ast. - */ - rc = ldlm_lock_addref_try(&olck->ols_handle, olck->ols_einfo.ei_mode); - if (rc == 0) { - olck->ols_hold = 1; - olck->ols_state = OLS_GRANTED; - } else { - struct cl_lock *lock; + dlmlock = olck->ols_dlmlock; + if (!dlmlock) + return; - /* - * Lock is being cancelled somewhere within - * ldlm_handle_bl_callback(): LDLM_FL_CBPENDING is already - * set, but osc_ldlm_blocking_ast() hasn't yet acquired - * cl_lock mutex. - */ - lock = slice->cls_lock; - LASSERT(lock->cll_state == CLS_INTRANSIT); - LASSERT(lock->cll_users > 0); - /* set a flag for osc_dlm_blocking_ast0() to signal the - * lock. - */ - olck->ols_ast_wait = 1; - rc = CLO_WAIT; + if (olck->ols_hold) { + olck->ols_hold = 0; + osc_cancel_base(&olck->ols_handle, olck->ols_einfo.ei_mode); + olck->ols_handle.cookie = 0ULL; } - return rc; -} -static int osc_lock_flush(struct osc_lock *ols, int discard) -{ - struct cl_lock *lock = ols->ols_cl.cls_lock; - struct cl_env_nest nest; - struct lu_env *env; - int result = 0; + olck->ols_dlmlock = NULL; - env = cl_env_nested_get(&nest); - if (!IS_ERR(env)) { - struct osc_object *obj = cl2osc(ols->ols_cl.cls_obj); - struct cl_lock_descr *descr = &lock->cll_descr; - int rc = 0; - - if (descr->cld_mode >= CLM_WRITE) { - result = osc_cache_writeback_range(env, obj, - descr->cld_start, - descr->cld_end, - 1, discard); - LDLM_DEBUG(ols->ols_lock, - "lock %p: %d pages were %s.\n", lock, result, - discard ? "discarded" : "written"); - if (result > 0) - result = 0; - } - - rc = osc_lock_discard_pages(env, ols); - if (result == 0 && rc < 0) - result = rc; - - cl_env_nested_put(&nest, env); - } else - result = PTR_ERR(env); - if (result == 0) { - ols->ols_flush = 1; - LINVRNT(!osc_lock_has_pages(ols)); - } - return result; + /* release a reference taken in osc_lock_upcall(). */ + LASSERT(olck->ols_has_ref); + lu_ref_del(&dlmlock->l_reference, "osc_lock", olck); + LDLM_LOCK_RELEASE(dlmlock); + olck->ols_has_ref = 0; } /** @@ -1378,96 +1040,16 @@ static int osc_lock_flush(struct osc_lock *ols, int discard) static void osc_lock_cancel(const struct lu_env *env, const struct cl_lock_slice *slice) { - struct cl_lock *lock = slice->cls_lock; - struct osc_lock *olck = cl2osc_lock(slice); - struct ldlm_lock *dlmlock = olck->ols_lock; - int result = 0; - int discard; - - LASSERT(cl_lock_is_mutexed(lock)); - LINVRNT(osc_lock_invariant(olck)); - - if (dlmlock) { - int do_cancel; - - discard = !!(dlmlock->l_flags & LDLM_FL_DISCARD_DATA); - if (olck->ols_state >= OLS_GRANTED) - result = osc_lock_flush(olck, discard); - osc_lock_unhold(olck); - - lock_res_and_lock(dlmlock); - /* Now that we're the only user of dlm read/write reference, - * mostly the ->l_readers + ->l_writers should be zero. - * However, there is a corner case. - * See bug 18829 for details. - */ - do_cancel = (dlmlock->l_readers == 0 && - dlmlock->l_writers == 0); - dlmlock->l_flags |= LDLM_FL_CBPENDING; - unlock_res_and_lock(dlmlock); - if (do_cancel) - result = ldlm_cli_cancel(&olck->ols_handle, LCF_ASYNC); - if (result < 0) - CL_LOCK_DEBUG(D_ERROR, env, lock, - "lock %p cancel failure with error(%d)\n", - lock, result); - } - olck->ols_state = OLS_CANCELLED; - olck->ols_flags &= ~LDLM_FL_LVB_READY; - osc_lock_detach(env, olck); -} - -static int osc_lock_has_pages(struct osc_lock *olck) -{ - return 0; -} - -static void osc_lock_delete(const struct lu_env *env, - const struct cl_lock_slice *slice) -{ - struct osc_lock *olck; - - olck = cl2osc_lock(slice); - if (olck->ols_glimpse) { - LASSERT(!olck->ols_hold); - LASSERT(!olck->ols_lock); - return; - } - - LINVRNT(osc_lock_invariant(olck)); - LINVRNT(!osc_lock_has_pages(olck)); - - osc_lock_unhold(olck); - osc_lock_detach(env, olck); -} + struct osc_object *obj = cl2osc(slice->cls_obj); + struct osc_lock *oscl = cl2osc_lock(slice); -/** - * Implements cl_lock_operations::clo_state() method for osc layer. - * - * Maintains osc_lock::ols_owner field. - * - * This assumes that lock always enters CLS_HELD (from some other state) in - * the same IO context as one that requested the lock. This should not be a - * problem, because context is by definition shared by all activity pertaining - * to the same high-level IO. - */ -static void osc_lock_state(const struct lu_env *env, - const struct cl_lock_slice *slice, - enum cl_lock_state state) -{ - struct osc_lock *lock = cl2osc_lock(slice); + LINVRNT(osc_lock_invariant(oscl)); - /* - * XXX multiple io contexts can use the lock at the same time. - */ - LINVRNT(osc_lock_invariant(lock)); - if (state == CLS_HELD && slice->cls_lock->cll_state != CLS_HELD) { - struct osc_io *oio = osc_env_io(env); + osc_lock_detach(env, oscl); + oscl->ols_state = OLS_CANCELLED; + oscl->ols_flags &= ~LDLM_FL_LVB_READY; - LASSERT(!lock->ols_owner); - lock->ols_owner = oio; - } else if (state != CLS_HELD) - lock->ols_owner = NULL; + osc_lock_wake_waiters(env, obj, oscl); } static int osc_lock_print(const struct lu_env *env, void *cookie, @@ -1475,197 +1057,161 @@ static int osc_lock_print(const struct lu_env *env, void *cookie, { struct osc_lock *lock = cl2osc_lock(slice); - /* - * XXX print ldlm lock and einfo properly. - */ (*p)(env, cookie, "%p %#16llx %#llx %d %p ", - lock->ols_lock, lock->ols_flags, lock->ols_handle.cookie, + lock->ols_dlmlock, lock->ols_flags, lock->ols_handle.cookie, lock->ols_state, lock->ols_owner); osc_lvb_print(env, cookie, p, &lock->ols_lvb); return 0; } -static int osc_lock_fits_into(const struct lu_env *env, - const struct cl_lock_slice *slice, - const struct cl_lock_descr *need, - const struct cl_io *io) -{ - struct osc_lock *ols = cl2osc_lock(slice); - - if (need->cld_enq_flags & CEF_NEVER) - return 0; - - if (ols->ols_state >= OLS_CANCELLED) - return 0; - - if (need->cld_mode == CLM_PHANTOM) { - if (ols->ols_agl) - return !(ols->ols_state > OLS_RELEASED); - - /* - * Note: the QUEUED lock can't be matched here, otherwise - * it might cause the deadlocks. - * In read_process, - * P1: enqueued read lock, create sublock1 - * P2: enqueued write lock, create sublock2(conflicted - * with sublock1). - * P1: Grant read lock. - * P1: enqueued glimpse lock(with holding sublock1_read), - * matched with sublock2, waiting sublock2 to be granted. - * But sublock2 can not be granted, because P1 - * will not release sublock1. Bang! - */ - if (ols->ols_state < OLS_GRANTED || - ols->ols_state > OLS_RELEASED) - return 0; - } else if (need->cld_enq_flags & CEF_MUST) { - /* - * If the lock hasn't ever enqueued, it can't be matched - * because enqueue process brings in many information - * which can be used to determine things such as lockless, - * CEF_MUST, etc. - */ - if (ols->ols_state < OLS_UPCALL_RECEIVED && - ols->ols_locklessable) - return 0; - } - return 1; -} - static const struct cl_lock_operations osc_lock_ops = { .clo_fini = osc_lock_fini, .clo_enqueue = osc_lock_enqueue, - .clo_wait = osc_lock_wait, - .clo_unuse = osc_lock_unuse, - .clo_use = osc_lock_use, - .clo_delete = osc_lock_delete, - .clo_state = osc_lock_state, .clo_cancel = osc_lock_cancel, .clo_print = osc_lock_print, - .clo_fits_into = osc_lock_fits_into, }; -static int osc_lock_lockless_unuse(const struct lu_env *env, - const struct cl_lock_slice *slice) -{ - struct osc_lock *ols = cl2osc_lock(slice); - struct cl_lock *lock = slice->cls_lock; - - LASSERT(ols->ols_state == OLS_GRANTED); - LINVRNT(osc_lock_invariant(ols)); - - cl_lock_cancel(env, lock); - cl_lock_delete(env, lock); - return 0; -} - static void osc_lock_lockless_cancel(const struct lu_env *env, const struct cl_lock_slice *slice) { struct osc_lock *ols = cl2osc_lock(slice); + struct osc_object *osc = cl2osc(slice->cls_obj); + struct cl_lock_descr *descr = &slice->cls_lock->cll_descr; int result; - result = osc_lock_flush(ols, 0); + LASSERT(!ols->ols_dlmlock); + result = osc_lock_flush(osc, descr->cld_start, descr->cld_end, + descr->cld_mode, 0); if (result) CERROR("Pages for lockless lock %p were not purged(%d)\n", ols, result); - ols->ols_state = OLS_CANCELLED; -} -static int osc_lock_lockless_wait(const struct lu_env *env, - const struct cl_lock_slice *slice) -{ - struct osc_lock *olck = cl2osc_lock(slice); - struct cl_lock *lock = olck->ols_cl.cls_lock; - - LINVRNT(osc_lock_invariant(olck)); - LASSERT(olck->ols_state >= OLS_UPCALL_RECEIVED); - - return lock->cll_error; + osc_lock_wake_waiters(env, osc, ols); } -static void osc_lock_lockless_state(const struct lu_env *env, - const struct cl_lock_slice *slice, - enum cl_lock_state state) -{ - struct osc_lock *lock = cl2osc_lock(slice); +static const struct cl_lock_operations osc_lock_lockless_ops = { + .clo_fini = osc_lock_fini, + .clo_enqueue = osc_lock_enqueue, + .clo_cancel = osc_lock_lockless_cancel, + .clo_print = osc_lock_print +}; - LINVRNT(osc_lock_invariant(lock)); - if (state == CLS_HELD) { - struct osc_io *oio = osc_env_io(env); +static void osc_lock_set_writer(const struct lu_env *env, + const struct cl_io *io, + struct cl_object *obj, struct osc_lock *oscl) +{ + struct cl_lock_descr *descr = &oscl->ols_cl.cls_lock->cll_descr; + pgoff_t io_start; + pgoff_t io_end; - LASSERT(ergo(lock->ols_owner, lock->ols_owner == oio)); - lock->ols_owner = oio; + if (!cl_object_same(io->ci_obj, obj)) + return; - /* set the io to be lockless if this lock is for io's - * host object - */ - if (cl_object_same(oio->oi_cl.cis_obj, slice->cls_obj)) - oio->oi_lockless = 1; + if (likely(io->ci_type == CIT_WRITE)) { + io_start = cl_index(obj, io->u.ci_rw.crw_pos); + io_end = cl_index(obj, io->u.ci_rw.crw_pos + + io->u.ci_rw.crw_count - 1); + if (cl_io_is_append(io)) { + io_start = 0; + io_end = CL_PAGE_EOF; + } + } else { + LASSERT(cl_io_is_mkwrite(io)); + io_start = io_end = io->u.ci_fault.ft_index; } -} -static int osc_lock_lockless_fits_into(const struct lu_env *env, - const struct cl_lock_slice *slice, - const struct cl_lock_descr *need, - const struct cl_io *io) -{ - struct osc_lock *lock = cl2osc_lock(slice); - - if (!(need->cld_enq_flags & CEF_NEVER)) - return 0; + if (descr->cld_mode >= CLM_WRITE && + descr->cld_start <= io_start && descr->cld_end >= io_end) { + struct osc_io *oio = osc_env_io(env); - /* lockless lock should only be used by its owning io. b22147 */ - return (lock->ols_owner == osc_env_io(env)); + /* There must be only one lock to match the write region */ + LASSERT(!oio->oi_write_osclock); + oio->oi_write_osclock = oscl; + } } -static const struct cl_lock_operations osc_lock_lockless_ops = { - .clo_fini = osc_lock_fini, - .clo_enqueue = osc_lock_enqueue, - .clo_wait = osc_lock_lockless_wait, - .clo_unuse = osc_lock_lockless_unuse, - .clo_state = osc_lock_lockless_state, - .clo_fits_into = osc_lock_lockless_fits_into, - .clo_cancel = osc_lock_lockless_cancel, - .clo_print = osc_lock_print -}; - int osc_lock_init(const struct lu_env *env, struct cl_object *obj, struct cl_lock *lock, - const struct cl_io *unused) + const struct cl_io *io) { - struct osc_lock *clk; - int result; + struct osc_lock *oscl; + __u32 enqflags = lock->cll_descr.cld_enq_flags; + + oscl = kmem_cache_zalloc(osc_lock_kmem, GFP_NOFS); + if (!oscl) + return -ENOMEM; + + oscl->ols_state = OLS_NEW; + spin_lock_init(&oscl->ols_lock); + INIT_LIST_HEAD(&oscl->ols_waiting_list); + INIT_LIST_HEAD(&oscl->ols_wait_entry); + INIT_LIST_HEAD(&oscl->ols_nextlock_oscobj); + + oscl->ols_flags = osc_enq2ldlm_flags(enqflags); + oscl->ols_agl = !!(enqflags & CEF_AGL); + if (oscl->ols_agl) + oscl->ols_flags |= LDLM_FL_BLOCK_NOWAIT; + if (oscl->ols_flags & LDLM_FL_HAS_INTENT) { + oscl->ols_flags |= LDLM_FL_BLOCK_GRANTED; + oscl->ols_glimpse = 1; + } - clk = kmem_cache_zalloc(osc_lock_kmem, GFP_NOFS); - if (clk) { - __u32 enqflags = lock->cll_descr.cld_enq_flags; + cl_lock_slice_add(lock, &oscl->ols_cl, obj, &osc_lock_ops); - osc_lock_build_einfo(env, lock, clk, &clk->ols_einfo); - clk->ols_state = OLS_NEW; + if (!(enqflags & CEF_MUST)) + /* try to convert this lock to a lockless lock */ + osc_lock_to_lockless(env, oscl, (enqflags & CEF_NEVER)); + if (oscl->ols_locklessable && !(enqflags & CEF_DISCARD_DATA)) + oscl->ols_flags |= LDLM_FL_DENY_ON_CONTENTION; - clk->ols_flags = osc_enq2ldlm_flags(enqflags); - clk->ols_agl = !!(enqflags & CEF_AGL); - if (clk->ols_agl) - clk->ols_flags |= LDLM_FL_BLOCK_NOWAIT; - if (clk->ols_flags & LDLM_FL_HAS_INTENT) - clk->ols_glimpse = 1; + if (io->ci_type == CIT_WRITE || cl_io_is_mkwrite(io)) + osc_lock_set_writer(env, io, obj, oscl); - cl_lock_slice_add(lock, &clk->ols_cl, obj, &osc_lock_ops); - if (!(enqflags & CEF_MUST)) - /* try to convert this lock to a lockless lock */ - osc_lock_to_lockless(env, clk, (enqflags & CEF_NEVER)); - if (clk->ols_locklessable && !(enqflags & CEF_DISCARD_DATA)) - clk->ols_flags |= LDLM_FL_DENY_ON_CONTENTION; + LDLM_DEBUG_NOLOCK("lock %p, osc lock %p, flags %llx\n", + lock, oscl, oscl->ols_flags); - LDLM_DEBUG_NOLOCK("lock %p, osc lock %p, flags %llx", - lock, clk, clk->ols_flags); + return 0; +} - result = 0; - } else - result = -ENOMEM; - return result; +/** + * Finds an existing lock covering given index and optionally different from a + * given \a except lock. + */ +struct ldlm_lock *osc_dlmlock_at_pgoff(const struct lu_env *env, + struct osc_object *obj, pgoff_t index, + int pending, int canceling) +{ + struct osc_thread_info *info = osc_env_info(env); + struct ldlm_res_id *resname = &info->oti_resname; + ldlm_policy_data_t *policy = &info->oti_policy; + struct lustre_handle lockh; + struct ldlm_lock *lock = NULL; + enum ldlm_mode mode; + __u64 flags; + + ostid_build_res_name(&obj->oo_oinfo->loi_oi, resname); + osc_index2policy(policy, osc2cl(obj), index, index); + policy->l_extent.gid = LDLM_GID_ANY; + + flags = LDLM_FL_BLOCK_GRANTED | LDLM_FL_TEST_LOCK; + if (pending) + flags |= LDLM_FL_CBPENDING; + /* + * It is fine to match any group lock since there could be only one + * with a uniq gid and it conflicts with all other lock modes too + */ +again: + mode = ldlm_lock_match(osc_export(obj)->exp_obd->obd_namespace, + flags, resname, LDLM_EXTENT, policy, + LCK_PR | LCK_PW | LCK_GROUP, &lockh, canceling); + if (mode != 0) { + lock = ldlm_handle2lock(&lockh); + /* RACE: the lock is cancelled so let's try again */ + if (unlikely(!lock)) + goto again; + } + return lock; } /** @} osc */ diff --git a/drivers/staging/lustre/lustre/osc/osc_object.c b/drivers/staging/lustre/lustre/osc/osc_object.c index 2d2d39a82982..a06bdf10b6ff 100644 --- a/drivers/staging/lustre/lustre/osc/osc_object.c +++ b/drivers/staging/lustre/lustre/osc/osc_object.c @@ -96,6 +96,8 @@ static int osc_object_init(const struct lu_env *env, struct lu_object *obj, atomic_set(&osc->oo_nr_writes, 0); spin_lock_init(&osc->oo_lock); spin_lock_init(&osc->oo_tree_lock); + spin_lock_init(&osc->oo_ol_spin); + INIT_LIST_HEAD(&osc->oo_ol_list); cl_object_page_init(lu2cl(obj), sizeof(struct osc_page)); @@ -122,6 +124,7 @@ static void osc_object_free(const struct lu_env *env, struct lu_object *obj) LASSERT(list_empty(&osc->oo_reading_exts)); LASSERT(atomic_read(&osc->oo_nr_reads) == 0); LASSERT(atomic_read(&osc->oo_nr_writes) == 0); + LASSERT(list_empty(&osc->oo_ol_list)); lu_object_fini(obj); kmem_cache_free(osc_object_kmem, osc); @@ -194,6 +197,32 @@ static int osc_object_glimpse(const struct lu_env *env, return 0; } +static int osc_object_ast_clear(struct ldlm_lock *lock, void *data) +{ + LASSERT(lock->l_granted_mode == lock->l_req_mode); + if (lock->l_ast_data == data) + lock->l_ast_data = NULL; + return LDLM_ITER_CONTINUE; +} + +static int osc_object_prune(const struct lu_env *env, struct cl_object *obj) +{ + struct osc_object *osc = cl2osc(obj); + struct ldlm_res_id *resname = &osc_env_info(env)->oti_resname; + + LASSERTF(osc->oo_npages == 0, + DFID "still have %lu pages, obj: %p, osc: %p\n", + PFID(lu_object_fid(&obj->co_lu)), osc->oo_npages, obj, osc); + + /* DLM locks don't hold a reference of osc_object so we have to + * clear it before the object is being destroyed. + */ + ostid_build_res_name(&osc->oo_oinfo->loi_oi, resname); + ldlm_resource_iterate(osc_export(osc)->exp_obd->obd_namespace, resname, + osc_object_ast_clear, osc); + return 0; +} + void osc_object_set_contended(struct osc_object *obj) { obj->oo_contention_time = cfs_time_current(); @@ -238,12 +267,12 @@ static const struct cl_object_operations osc_ops = { .coo_io_init = osc_io_init, .coo_attr_get = osc_attr_get, .coo_attr_set = osc_attr_set, - .coo_glimpse = osc_object_glimpse + .coo_glimpse = osc_object_glimpse, + .coo_prune = osc_object_prune }; static const struct lu_object_operations osc_lu_obj_ops = { .loo_object_init = osc_object_init, - .loo_object_delete = NULL, .loo_object_release = NULL, .loo_object_free = osc_object_free, .loo_object_print = osc_object_print, diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c index 5b313519637c..82979f4039c1 100644 --- a/drivers/staging/lustre/lustre/osc/osc_page.c +++ b/drivers/staging/lustre/lustre/osc/osc_page.c @@ -135,15 +135,15 @@ static int osc_page_is_under_lock(const struct lu_env *env, struct cl_io *unused, pgoff_t *max_index) { struct osc_page *opg = cl2osc_page(slice); - struct cl_lock *lock; + struct ldlm_lock *dlmlock; int result = -ENODATA; - *max_index = 0; - lock = cl_lock_at_pgoff(env, slice->cpl_obj, osc_index(opg), - NULL, 1, 0); - if (lock) { - *max_index = lock->cll_descr.cld_end; - cl_lock_put(env, lock); + dlmlock = osc_dlmlock_at_pgoff(env, cl2osc(slice->cpl_obj), + osc_index(opg), 1, 0); + if (dlmlock) { + *max_index = cl_index(slice->cpl_obj, + dlmlock->l_policy_data.l_extent.end); + LDLM_LOCK_PUT(dlmlock); result = 0; } return result; diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c index 372bd26b07c8..368b99719d48 100644 --- a/drivers/staging/lustre/lustre/osc/osc_request.c +++ b/drivers/staging/lustre/lustre/osc/osc_request.c @@ -92,12 +92,13 @@ struct osc_fsync_args { struct osc_enqueue_args { struct obd_export *oa_exp; + enum ldlm_type oa_type; + enum ldlm_mode oa_mode; __u64 *oa_flags; - obd_enqueue_update_f oa_upcall; + osc_enqueue_upcall_f oa_upcall; void *oa_cookie; struct ost_lvb *oa_lvb; - struct lustre_handle *oa_lockh; - struct ldlm_enqueue_info *oa_ei; + struct lustre_handle oa_lockh; unsigned int oa_agl:1; }; @@ -2068,14 +2069,12 @@ static int osc_set_lock_data_with_check(struct ldlm_lock *lock, LASSERT(lock->l_glimpse_ast == einfo->ei_cb_gl); lock_res_and_lock(lock); - spin_lock(&osc_ast_guard); if (!lock->l_ast_data) lock->l_ast_data = data; if (lock->l_ast_data == data) set = 1; - spin_unlock(&osc_ast_guard); unlock_res_and_lock(lock); return set; @@ -2117,36 +2116,38 @@ static int osc_find_cbdata(struct obd_export *exp, struct lov_stripe_md *lsm, return rc; } -static int osc_enqueue_fini(struct ptlrpc_request *req, struct ost_lvb *lvb, - obd_enqueue_update_f upcall, void *cookie, - __u64 *flags, int agl, int rc) +static int osc_enqueue_fini(struct ptlrpc_request *req, + osc_enqueue_upcall_f upcall, void *cookie, + struct lustre_handle *lockh, enum ldlm_mode mode, + __u64 *flags, int agl, int errcode) { - int intent = *flags & LDLM_FL_HAS_INTENT; - - if (intent) { - /* The request was created before ldlm_cli_enqueue call. */ - if (rc == ELDLM_LOCK_ABORTED) { - struct ldlm_reply *rep; + bool intent = *flags & LDLM_FL_HAS_INTENT; + int rc; - rep = req_capsule_server_get(&req->rq_pill, - &RMF_DLM_REP); + /* The request was created before ldlm_cli_enqueue call. */ + if (intent && errcode == ELDLM_LOCK_ABORTED) { + struct ldlm_reply *rep; - rep->lock_policy_res1 = - ptlrpc_status_ntoh(rep->lock_policy_res1); - if (rep->lock_policy_res1) - rc = rep->lock_policy_res1; - } - } + rep = req_capsule_server_get(&req->rq_pill, &RMF_DLM_REP); - if ((intent != 0 && rc == ELDLM_LOCK_ABORTED && agl == 0) || - (rc == 0)) { + rep->lock_policy_res1 = + ptlrpc_status_ntoh(rep->lock_policy_res1); + if (rep->lock_policy_res1) + errcode = rep->lock_policy_res1; + if (!agl) + *flags |= LDLM_FL_LVB_READY; + } else if (errcode == ELDLM_OK) { *flags |= LDLM_FL_LVB_READY; - CDEBUG(D_INODE, "got kms %llu blocks %llu mtime %llu\n", - lvb->lvb_size, lvb->lvb_blocks, lvb->lvb_mtime); } /* Call the update callback. */ - rc = (*upcall)(cookie, rc); + rc = (*upcall)(cookie, lockh, errcode); + /* release the reference taken in ldlm_cli_enqueue() */ + if (errcode == ELDLM_LOCK_MATCHED) + errcode = ELDLM_OK; + if (errcode == ELDLM_OK && lustre_handle_is_used(lockh)) + ldlm_lock_decref(lockh, mode); + return rc; } @@ -2155,62 +2156,47 @@ static int osc_enqueue_interpret(const struct lu_env *env, struct osc_enqueue_args *aa, int rc) { struct ldlm_lock *lock; - struct lustre_handle handle; - __u32 mode; - struct ost_lvb *lvb; - __u32 lvb_len; - __u64 *flags = aa->oa_flags; - - /* Make a local copy of a lock handle and a mode, because aa->oa_* - * might be freed anytime after lock upcall has been called. - */ - lustre_handle_copy(&handle, aa->oa_lockh); - mode = aa->oa_ei->ei_mode; + struct lustre_handle *lockh = &aa->oa_lockh; + enum ldlm_mode mode = aa->oa_mode; + struct ost_lvb *lvb = aa->oa_lvb; + __u32 lvb_len = sizeof(*lvb); + __u64 flags = 0; + /* ldlm_cli_enqueue is holding a reference on the lock, so it must * be valid. */ - lock = ldlm_handle2lock(&handle); + lock = ldlm_handle2lock(lockh); + LASSERTF(lock, "lockh %llx, req %p, aa %p - client evicted?\n", + lockh->cookie, req, aa); /* Take an additional reference so that a blocking AST that * ldlm_cli_enqueue_fini() might post for a failed lock, is guaranteed * to arrive after an upcall has been executed by * osc_enqueue_fini(). */ - ldlm_lock_addref(&handle, mode); + ldlm_lock_addref(lockh, mode); /* Let CP AST to grant the lock first. */ OBD_FAIL_TIMEOUT(OBD_FAIL_OSC_CP_ENQ_RACE, 1); - if (aa->oa_agl && rc == ELDLM_LOCK_ABORTED) { - lvb = NULL; - lvb_len = 0; - } else { - lvb = aa->oa_lvb; - lvb_len = sizeof(*aa->oa_lvb); + if (aa->oa_agl) { + LASSERT(!aa->oa_lvb); + LASSERT(!aa->oa_flags); + aa->oa_flags = &flags; } /* Complete obtaining the lock procedure. */ - rc = ldlm_cli_enqueue_fini(aa->oa_exp, req, aa->oa_ei->ei_type, 1, - mode, flags, lvb, lvb_len, &handle, rc); + rc = ldlm_cli_enqueue_fini(aa->oa_exp, req, aa->oa_type, 1, + aa->oa_mode, aa->oa_flags, lvb, lvb_len, + lockh, rc); /* Complete osc stuff. */ - rc = osc_enqueue_fini(req, aa->oa_lvb, aa->oa_upcall, aa->oa_cookie, - flags, aa->oa_agl, rc); + rc = osc_enqueue_fini(req, aa->oa_upcall, aa->oa_cookie, lockh, mode, + aa->oa_flags, aa->oa_agl, rc); OBD_FAIL_TIMEOUT(OBD_FAIL_OSC_CP_CANCEL_RACE, 10); - /* Release the lock for async request. */ - if (lustre_handle_is_used(&handle) && rc == ELDLM_OK) - /* - * Releases a reference taken by ldlm_cli_enqueue(), if it is - * not already released by - * ldlm_cli_enqueue_fini()->failed_lock_cleanup() - */ - ldlm_lock_decref(&handle, mode); - - LASSERTF(lock, "lockh %p, req %p, aa %p - client evicted?\n", - aa->oa_lockh, req, aa); - ldlm_lock_decref(&handle, mode); + ldlm_lock_decref(lockh, mode); LDLM_LOCK_PUT(lock); return rc; } @@ -2222,21 +2208,21 @@ struct ptlrpc_request_set *PTLRPCD_SET = (void *)1; * other synchronous requests, however keeping some locks and trying to obtain * others may take a considerable amount of time in a case of ost failure; and * when other sync requests do not get released lock from a client, the client - * is excluded from the cluster -- such scenarious make the life difficult, so + * is evicted from the cluster -- such scenaries make the life difficult, so * release locks just after they are obtained. */ int osc_enqueue_base(struct obd_export *exp, struct ldlm_res_id *res_id, __u64 *flags, ldlm_policy_data_t *policy, struct ost_lvb *lvb, int kms_valid, - obd_enqueue_update_f upcall, void *cookie, + osc_enqueue_upcall_f upcall, void *cookie, struct ldlm_enqueue_info *einfo, - struct lustre_handle *lockh, struct ptlrpc_request_set *rqset, int async, int agl) { struct obd_device *obd = exp->exp_obd; + struct lustre_handle lockh = { 0 }; struct ptlrpc_request *req = NULL; int intent = *flags & LDLM_FL_HAS_INTENT; - __u64 match_lvb = (agl != 0 ? 0 : LDLM_FL_LVB_READY); + __u64 match_lvb = agl ? 0 : LDLM_FL_LVB_READY; enum ldlm_mode mode; int rc; @@ -2272,55 +2258,39 @@ int osc_enqueue_base(struct obd_export *exp, struct ldlm_res_id *res_id, if (einfo->ei_mode == LCK_PR) mode |= LCK_PW; mode = ldlm_lock_match(obd->obd_namespace, *flags | match_lvb, res_id, - einfo->ei_type, policy, mode, lockh, 0); + einfo->ei_type, policy, mode, &lockh, 0); if (mode) { - struct ldlm_lock *matched = ldlm_handle2lock(lockh); + struct ldlm_lock *matched; - if ((agl != 0) && !(matched->l_flags & LDLM_FL_LVB_READY)) { - /* For AGL, if enqueue RPC is sent but the lock is not - * granted, then skip to process this strpe. - * Return -ECANCELED to tell the caller. + if (*flags & LDLM_FL_TEST_LOCK) + return ELDLM_OK; + + matched = ldlm_handle2lock(&lockh); + if (agl) { + /* AGL enqueues DLM locks speculatively. Therefore if + * it already exists a DLM lock, it wll just inform the + * caller to cancel the AGL process for this stripe. */ - ldlm_lock_decref(lockh, mode); + ldlm_lock_decref(&lockh, mode); LDLM_LOCK_PUT(matched); return -ECANCELED; - } - - if (osc_set_lock_data_with_check(matched, einfo)) { + } else if (osc_set_lock_data_with_check(matched, einfo)) { *flags |= LDLM_FL_LVB_READY; - /* addref the lock only if not async requests and PW - * lock is matched whereas we asked for PR. - */ - if (!rqset && einfo->ei_mode != mode) - ldlm_lock_addref(lockh, LCK_PR); - if (intent) { - /* I would like to be able to ASSERT here that - * rss <= kms, but I can't, for reasons which - * are explained in lov_enqueue() - */ - } - - /* We already have a lock, and it's referenced. - * - * At this point, the cl_lock::cll_state is CLS_QUEUING, - * AGL upcall may change it to CLS_HELD directly. - */ - (*upcall)(cookie, ELDLM_OK); + /* We already have a lock, and it's referenced. */ + (*upcall)(cookie, &lockh, ELDLM_LOCK_MATCHED); - if (einfo->ei_mode != mode) - ldlm_lock_decref(lockh, LCK_PW); - else if (rqset) - /* For async requests, decref the lock. */ - ldlm_lock_decref(lockh, einfo->ei_mode); + ldlm_lock_decref(&lockh, mode); LDLM_LOCK_PUT(matched); return ELDLM_OK; + } else { + ldlm_lock_decref(&lockh, mode); + LDLM_LOCK_PUT(matched); } - - ldlm_lock_decref(lockh, mode); - LDLM_LOCK_PUT(matched); } - no_match: +no_match: + if (*flags & LDLM_FL_TEST_LOCK) + return -ENOLCK; if (intent) { LIST_HEAD(cancels); @@ -2344,21 +2314,31 @@ int osc_enqueue_base(struct obd_export *exp, struct ldlm_res_id *res_id, *flags &= ~LDLM_FL_BLOCK_GRANTED; rc = ldlm_cli_enqueue(exp, &req, einfo, res_id, policy, flags, lvb, - sizeof(*lvb), LVB_T_OST, lockh, async); - if (rqset) { + sizeof(*lvb), LVB_T_OST, &lockh, async); + if (async) { if (!rc) { struct osc_enqueue_args *aa; - CLASSERT (sizeof(*aa) <= sizeof(req->rq_async_args)); + CLASSERT(sizeof(*aa) <= sizeof(req->rq_async_args)); aa = ptlrpc_req_async_args(req); - aa->oa_ei = einfo; aa->oa_exp = exp; - aa->oa_flags = flags; + aa->oa_mode = einfo->ei_mode; + aa->oa_type = einfo->ei_type; + lustre_handle_copy(&aa->oa_lockh, &lockh); aa->oa_upcall = upcall; aa->oa_cookie = cookie; - aa->oa_lvb = lvb; - aa->oa_lockh = lockh; aa->oa_agl = !!agl; + if (!agl) { + aa->oa_flags = flags; + aa->oa_lvb = lvb; + } else { + /* AGL is essentially to enqueue an DLM lock + * in advance, so we don't care about the + * result of AGL enqueue. + */ + aa->oa_lvb = NULL; + aa->oa_flags = NULL; + } req->rq_interpret_reply = (ptlrpc_interpterer_t)osc_enqueue_interpret; @@ -2372,7 +2352,8 @@ int osc_enqueue_base(struct obd_export *exp, struct ldlm_res_id *res_id, return rc; } - rc = osc_enqueue_fini(req, lvb, upcall, cookie, flags, agl, rc); + rc = osc_enqueue_fini(req, upcall, cookie, &lockh, einfo->ei_mode, + flags, agl, rc); if (intent) ptlrpc_req_finished(req); @@ -3359,7 +3340,6 @@ static struct obd_ops osc_obd_ops = { }; extern struct lu_kmem_descr osc_caches[]; -extern spinlock_t osc_ast_guard; extern struct lock_class_key osc_ast_guard_class; static int __init osc_init(void) @@ -3386,9 +3366,6 @@ static int __init osc_init(void) if (rc) goto out_kmem; - spin_lock_init(&osc_ast_guard); - lockdep_set_class(&osc_ast_guard, &osc_ast_guard_class); - /* This is obviously too much memory, only prevent overflow here */ if (osc_reqpool_mem_max >= 1 << 12 || osc_reqpool_mem_max == 0) { rc = -EINVAL; -- cgit v1.2.3 From 71a96a0539a8ebd8273bf627222e260968b82a16 Mon Sep 17 00:00:00 2001 From: Bobi Jam Date: Wed, 30 Mar 2016 19:48:41 -0400 Subject: staging/lustre: update comments after cl_lock simplification Update comments to reflect current cl_lock situations. Signed-off-by: Bobi Jam Reviewed-on: http://review.whamcloud.com/13137 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6046 Reviewed-by: John L. Hammond Reviewed-by: Jinshan Xiong Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/cl_object.h | 130 +++------------------ .../staging/lustre/lustre/lov/lov_cl_internal.h | 13 --- 2 files changed, 19 insertions(+), 124 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h index 8f9512ef3942..e613007683ae 100644 --- a/drivers/staging/lustre/lustre/include/cl_object.h +++ b/drivers/staging/lustre/lustre/include/cl_object.h @@ -1117,111 +1117,29 @@ static inline struct page *cl_page_vmpage(struct cl_page *page) * * LIFE CYCLE * - * cl_lock is reference counted. When reference counter drops to 0, lock is - * placed in the cache, except when lock is in CLS_FREEING state. CLS_FREEING - * lock is destroyed when last reference is released. Referencing between - * top-lock and its sub-locks is described in the lov documentation module. - * - * STATE MACHINE - * - * Also, cl_lock is a state machine. This requires some clarification. One of - * the goals of client IO re-write was to make IO path non-blocking, or at - * least to make it easier to make it non-blocking in the future. Here - * `non-blocking' means that when a system call (read, write, truncate) - * reaches a situation where it has to wait for a communication with the - * server, it should --instead of waiting-- remember its current state and - * switch to some other work. E.g,. instead of waiting for a lock enqueue, - * client should proceed doing IO on the next stripe, etc. Obviously this is - * rather radical redesign, and it is not planned to be fully implemented at - * this time, instead we are putting some infrastructure in place, that would - * make it easier to do asynchronous non-blocking IO easier in the - * future. Specifically, where old locking code goes to sleep (waiting for - * enqueue, for example), new code returns cl_lock_transition::CLO_WAIT. When - * enqueue reply comes, its completion handler signals that lock state-machine - * is ready to transit to the next state. There is some generic code in - * cl_lock.c that sleeps, waiting for these signals. As a result, for users of - * this cl_lock.c code, it looks like locking is done in normal blocking - * fashion, and it the same time it is possible to switch to the non-blocking - * locking (simply by returning cl_lock_transition::CLO_WAIT from cl_lock.c - * functions). - * - * For a description of state machine states and transitions see enum - * cl_lock_state. - * - * There are two ways to restrict a set of states which lock might move to: - * - * - placing a "hold" on a lock guarantees that lock will not be moved - * into cl_lock_state::CLS_FREEING state until hold is released. Hold - * can be only acquired on a lock that is not in - * cl_lock_state::CLS_FREEING. All holds on a lock are counted in - * cl_lock::cll_holds. Hold protects lock from cancellation and - * destruction. Requests to cancel and destroy a lock on hold will be - * recorded, but only honored when last hold on a lock is released; - * - * - placing a "user" on a lock guarantees that lock will not leave - * cl_lock_state::CLS_NEW, cl_lock_state::CLS_QUEUING, - * cl_lock_state::CLS_ENQUEUED and cl_lock_state::CLS_HELD set of - * states, once it enters this set. That is, if a user is added onto a - * lock in a state not from this set, it doesn't immediately enforce - * lock to move to this set, but once lock enters this set it will - * remain there until all users are removed. Lock users are counted in - * cl_lock::cll_users. - * - * User is used to assure that lock is not canceled or destroyed while - * it is being enqueued, or actively used by some IO. - * - * Currently, a user always comes with a hold (cl_lock_invariant() - * checks that a number of holds is not less than a number of users). - * - * CONCURRENCY - * - * This is how lock state-machine operates. struct cl_lock contains a mutex - * cl_lock::cll_guard that protects struct fields. - * - * - mutex is taken, and cl_lock::cll_state is examined. - * - * - for every state there are possible target states where lock can move - * into. They are tried in order. Attempts to move into next state are - * done by _try() functions in cl_lock.c:cl_{enqueue,unlock,wait}_try(). - * - * - if the transition can be performed immediately, state is changed, - * and mutex is released. - * - * - if the transition requires blocking, _try() function returns - * cl_lock_transition::CLO_WAIT. Caller unlocks mutex and goes to - * sleep, waiting for possibility of lock state change. It is woken - * up when some event occurs, that makes lock state change possible - * (e.g., the reception of the reply from the server), and repeats - * the loop. - * - * Top-lock and sub-lock has separate mutexes and the latter has to be taken - * first to avoid dead-lock. - * - * To see an example of interaction of all these issues, take a look at the - * lov_cl.c:lov_lock_enqueue() function. It is called as a part of - * cl_enqueue_try(), and tries to advance top-lock to ENQUEUED state, by - * advancing state-machines of its sub-locks (lov_lock_enqueue_one()). Note - * also, that it uses trylock to grab sub-lock mutex to avoid dead-lock. It - * also has to handle CEF_ASYNC enqueue, when sub-locks enqueues have to be - * done in parallel, rather than one after another (this is used for glimpse - * locks, that cannot dead-lock). + * cl_lock is a cacheless data container for the requirements of locks to + * complete the IO. cl_lock is created before I/O starts and destroyed when the + * I/O is complete. + * + * cl_lock depends on LDLM lock to fulfill lock semantics. LDLM lock is attached + * to cl_lock at OSC layer. LDLM lock is still cacheable. * * INTERFACE AND USAGE * - * struct cl_lock_operations provide a number of call-backs that are invoked - * when events of interest occurs. Layers can intercept and handle glimpse, - * blocking, cancel ASTs and a reception of the reply from the server. + * Two major methods are supported for cl_lock: clo_enqueue and clo_cancel. A + * cl_lock is enqueued by cl_lock_request(), which will call clo_enqueue() + * methods for each layer to enqueue the lock. At the LOV layer, if a cl_lock + * consists of multiple sub cl_locks, each sub locks will be enqueued + * correspondingly. At OSC layer, the lock enqueue request will tend to reuse + * cached LDLM lock; otherwise a new LDLM lock will have to be requested from + * OST side. * - * One important difference with the old client locking model is that new - * client has a representation for the top-lock, whereas in the old code only - * sub-locks existed as real data structures and file-level locks are - * represented by "request sets" that are created and destroyed on each and - * every lock creation. + * cl_lock_cancel() must be called to release a cl_lock after use. clo_cancel() + * method will be called for each layer to release the resource held by this + * lock. At OSC layer, the reference count of LDLM lock, which is held at + * clo_enqueue time, is released. * - * Top-locks are cached, and can be found in the cache by the system calls. It - * is possible that top-lock is in cache, but some of its sub-locks were - * canceled and destroyed. In that case top-lock has to be enqueued again - * before it can be used. + * LDLM lock can only be canceled if there is no cl_lock using it. * * Overall process of the locking during IO operation is as following: * @@ -1234,7 +1152,7 @@ static inline struct page *cl_page_vmpage(struct cl_page *page) * * - when all locks are acquired, IO is performed; * - * - locks are released into cache. + * - locks are released after IO is complete. * * Striping introduces major additional complexity into locking. The * fundamental problem is that it is generally unsafe to actively use (hold) @@ -1256,16 +1174,6 @@ static inline struct page *cl_page_vmpage(struct cl_page *page) * buf is a part of memory mapped Lustre file, a lock or locks protecting buf * has to be held together with the usual lock on [offset, offset + count]. * - * As multi-stripe locks have to be allowed, it makes sense to cache them, so - * that, for example, a sequence of O_APPEND writes can proceed quickly - * without going down to the individual stripes to do lock matching. On the - * other hand, multi-stripe locks shouldn't be used by normal read/write - * calls. To achieve this, every layer can implement ->clo_fits_into() method, - * that is called by lock matching code (cl_lock_lookup()), and that can be - * used to selectively disable matching of certain locks for certain IOs. For - * example, lov layer implements lov_lock_fits_into() that allow multi-stripe - * locks to be matched only for truncates and O_APPEND writes. - * * Interaction with DLM * * In the expected setup, cl_lock is ultimately backed up by a collection of diff --git a/drivers/staging/lustre/lustre/lov/lov_cl_internal.h b/drivers/staging/lustre/lustre/lov/lov_cl_internal.h index dfe41a82bdd2..ac9744e887ae 100644 --- a/drivers/staging/lustre/lustre/lov/lov_cl_internal.h +++ b/drivers/staging/lustre/lustre/lov/lov_cl_internal.h @@ -73,19 +73,6 @@ * - top-page keeps a reference to its sub-page, and destroys it when it * is destroyed. * - * - sub-lock keep a reference to its top-locks. Top-lock keeps a - * reference (and a hold, see cl_lock_hold()) on its sub-locks when it - * actively using them (that is, in cl_lock_state::CLS_QUEUING, - * cl_lock_state::CLS_ENQUEUED, cl_lock_state::CLS_HELD states). When - * moving into cl_lock_state::CLS_CACHED state, top-lock releases a - * hold. From this moment top-lock has only a 'weak' reference to its - * sub-locks. This reference is protected by top-lock - * cl_lock::cll_guard, and will be automatically cleared by the sub-lock - * when the latter is destroyed. When a sub-lock is canceled, a - * reference to it is removed from the top-lock array, and top-lock is - * moved into CLS_NEW state. It is guaranteed that all sub-locks exist - * while their top-lock is in CLS_HELD or CLS_CACHED states. - * * - IO's are not reference counted. * * To implement a connection between top and sub entities, lov layer is split -- cgit v1.2.3 From c11599b8d52d353f45b2dc05d58c48f9812ce6e9 Mon Sep 17 00:00:00 2001 From: Jinshan Xiong Date: Wed, 30 Mar 2016 19:48:42 -0400 Subject: staging/lustre/llite: clip page correctly for vvp_io_commit_sync The original code was wrong which clipped page incorrectly for partial pages started with zero. Signed-off-by: Jinshan Xiong Reviewed-on: http://review.whamcloud.com/8531 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-4201 Reviewed-by: Andreas Dilger Reviewed-by: wangdi Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/vvp_io.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c index fb6f93225b99..e44ef21b795e 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_io.c +++ b/drivers/staging/lustre/lustre/llite/vvp_io.c @@ -595,15 +595,17 @@ static int vvp_io_commit_sync(const struct lu_env *env, struct cl_io *io, if (plist->pl_nr == 0) return 0; - if (from != 0) { + if (from > 0 || to != PAGE_SIZE) { page = cl_page_list_first(plist); - cl_page_clip(env, page, from, - plist->pl_nr == 1 ? to : PAGE_SIZE); - } - if (to != PAGE_SIZE && plist->pl_nr > 1) { + if (plist->pl_nr == 1) { + cl_page_clip(env, page, from, to); + } else if (from > 0) { + cl_page_clip(env, page, from, PAGE_SIZE); + } else { page = cl_page_list_last(plist); cl_page_clip(env, page, 0, to); } + } cl_2queue_init(queue); cl_page_list_splice(plist, &queue->c2_qin); -- cgit v1.2.3 From d37dd10b71fd304289560901e81eddbe7defb351 Mon Sep 17 00:00:00 2001 From: Jinshan Xiong Date: Wed, 30 Mar 2016 19:48:43 -0400 Subject: staging/lustre/llite: deadlock for page write Writing thread already locked page #1, and then wait for the Writeback bit of page #2; Ptlrpc thread is composing a write RPC, so it sets Writeback on page #2 and tries to lock page #1 to make it ready. Deadlocked. Signed-off-by: Jinshan Xiong Reviewed-on: http://review.whamcloud.com/9036 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-4540 Reviewed-by: wangdi Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/rw26.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/llite/rw26.c b/drivers/staging/lustre/lustre/llite/rw26.c index 50d8289afe06..f87238b3373c 100644 --- a/drivers/staging/lustre/lustre/llite/rw26.c +++ b/drivers/staging/lustre/lustre/llite/rw26.c @@ -512,7 +512,7 @@ static int ll_write_begin(struct file *file, struct address_space *mapping, /* To avoid deadlock, try to lock page first. */ vmpage = grab_cache_page_nowait(mapping, index); - if (unlikely(!vmpage || PageDirty(vmpage))) { + if (unlikely(!vmpage || PageDirty(vmpage) || PageWriteback(vmpage))) { struct ccc_io *cio = ccc_env_io(env); struct cl_page_list *plist = &cio->u.write.cui_queue; @@ -522,7 +522,7 @@ static int ll_write_begin(struct file *file, struct address_space *mapping, * more grants. It's okay for the dirty page to be the first * one in commit page list, though. */ - if (vmpage && PageDirty(vmpage) && plist->pl_nr > 0) { + if (vmpage && plist->pl_nr > 0) { unlock_page(vmpage); page_cache_release(vmpage); vmpage = NULL; -- cgit v1.2.3 From 902a34ad7242bb50e467a24855b544148989daf4 Mon Sep 17 00:00:00 2001 From: Li Dongyang Date: Wed, 30 Mar 2016 19:48:44 -0400 Subject: staging/lustre/llite: make sure we do cl_page_clip on the last page When we are doing a partial IO on both first and last page, the logic currently only call cl_page_clip on the first page, which will end up with a incorrect i_size. Signed-off-by: Li Dongyang Reviewed-on: http://review.whamcloud.com/11630 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5552 Reviewed-by: Ian Costello Reviewed-by: Niu Yawei Reviewed-by: Li Xi Reviewed-by: Jinshan Xiong Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/vvp_io.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c index e44ef21b795e..1d2fc3bf9487 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_io.c +++ b/drivers/staging/lustre/lustre/llite/vvp_io.c @@ -599,12 +599,14 @@ static int vvp_io_commit_sync(const struct lu_env *env, struct cl_io *io, page = cl_page_list_first(plist); if (plist->pl_nr == 1) { cl_page_clip(env, page, from, to); - } else if (from > 0) { - cl_page_clip(env, page, from, PAGE_SIZE); } else { - page = cl_page_list_last(plist); - cl_page_clip(env, page, 0, to); - } + if (from > 0) + cl_page_clip(env, page, from, PAGE_SIZE); + if (to != PAGE_SIZE) { + page = cl_page_list_last(plist); + cl_page_clip(env, page, 0, to); + } + } } cl_2queue_init(queue); -- cgit v1.2.3 From 0d345656ea4221cec2dd34a0c7a7ba3f0a8e9047 Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Wed, 30 Mar 2016 19:48:45 -0400 Subject: staging/lustre/llite: merge lclient.h into llite/vvp_internal.h Move the definition of struct cl_client_cache to lustre/include/cl_object.h and move the rest of lustre/include/lclient.h in to lustre/llite/vvp_internal.h. Signed-off-by: John L. Hammond Reviewed-on: http://review.whamcloud.com/12592 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5971 Reviewed-by: Jinshan Xiong Reviewed-by: James Simmons Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/cl_object.h | 36 ++ drivers/staging/lustre/lustre/include/lclient.h | 409 --------------------- drivers/staging/lustre/lustre/llite/glimpse.c | 1 - drivers/staging/lustre/lustre/llite/lcommon_cl.c | 2 - drivers/staging/lustre/lustre/llite/lcommon_misc.c | 2 +- .../staging/lustre/lustre/llite/llite_internal.h | 2 +- drivers/staging/lustre/lustre/llite/vvp_internal.h | 368 +++++++++++++++++- drivers/staging/lustre/lustre/llite/vvp_io.c | 1 + drivers/staging/lustre/lustre/llite/vvp_object.c | 1 + drivers/staging/lustre/lustre/llite/vvp_page.c | 1 + drivers/staging/lustre/lustre/lov/lov_obd.c | 1 - .../staging/lustre/lustre/osc/osc_cl_internal.h | 1 - 12 files changed, 408 insertions(+), 417 deletions(-) delete mode 100644 drivers/staging/lustre/lustre/include/lclient.h (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h index e613007683ae..f2bb8f8637cf 100644 --- a/drivers/staging/lustre/lustre/include/cl_object.h +++ b/drivers/staging/lustre/lustre/include/cl_object.h @@ -97,9 +97,12 @@ * super-class definitions. */ #include "lu_object.h" +#include #include "linux/lustre_compat25.h" #include #include +#include +#include struct inode; @@ -2317,6 +2320,39 @@ void cl_lock_descr_print(const struct lu_env *env, void *cookie, const struct cl_lock_descr *descr); /* @} helper */ +/** + * Data structure managing a client's cached pages. A count of + * "unstable" pages is maintained, and an LRU of clean pages is + * maintained. "unstable" pages are pages pinned by the ptlrpc + * layer for recovery purposes. + */ +struct cl_client_cache { + /** + * # of users (OSCs) + */ + atomic_t ccc_users; + /** + * # of threads are doing shrinking + */ + unsigned int ccc_lru_shrinkers; + /** + * # of LRU entries available + */ + atomic_t ccc_lru_left; + /** + * List of entities(OSCs) for this LRU cache + */ + struct list_head ccc_lru; + /** + * Max # of LRU entries + */ + unsigned long ccc_lru_max; + /** + * Lock to protect ccc_lru list + */ + spinlock_t ccc_lru_lock; +}; + /** @} cl_page */ /** \defgroup cl_lock cl_lock diff --git a/drivers/staging/lustre/lustre/include/lclient.h b/drivers/staging/lustre/lustre/include/lclient.h deleted file mode 100644 index 82af8aeb7212..000000000000 --- a/drivers/staging/lustre/lustre/include/lclient.h +++ /dev/null @@ -1,409 +0,0 @@ -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * GPL HEADER END - */ -/* - * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. - * Use is subject to license terms. - * - * Copyright (c) 2011, 2012, Intel Corporation. - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - * - * Definitions shared between vvp and liblustre, and other clients in the - * future. - * - * Author: Oleg Drokin - * Author: Nikita Danilov - */ - -#ifndef LCLIENT_H -#define LCLIENT_H - -blkcnt_t dirty_cnt(struct inode *inode); - -int cl_glimpse_size0(struct inode *inode, int agl); -int cl_glimpse_lock(const struct lu_env *env, struct cl_io *io, - struct inode *inode, struct cl_object *clob, int agl); - -static inline int cl_glimpse_size(struct inode *inode) -{ - return cl_glimpse_size0(inode, 0); -} - -static inline int cl_agl(struct inode *inode) -{ - return cl_glimpse_size0(inode, 1); -} - -/** - * Locking policy for setattr. - */ -enum ccc_setattr_lock_type { - /** Locking is done by server */ - SETATTR_NOLOCK, - /** Extent lock is enqueued */ - SETATTR_EXTENT_LOCK, - /** Existing local extent lock is used */ - SETATTR_MATCH_LOCK -}; - -/** - * IO state private to vvp or slp layers. - */ -struct ccc_io { - /** super class */ - struct cl_io_slice cui_cl; - struct cl_io_lock_link cui_link; - /** - * I/O vector information to or from which read/write is going. - */ - struct iov_iter *cui_iter; - /** - * Total size for the left IO. - */ - size_t cui_tot_count; - - union { - struct { - enum ccc_setattr_lock_type cui_local_lock; - } setattr; - struct { - struct cl_page_list cui_queue; - unsigned long cui_written; - int cui_from; - int cui_to; - } write; - } u; - /** - * Layout version when this IO is initialized - */ - __u32 cui_layout_gen; - /** - * File descriptor against which IO is done. - */ - struct ll_file_data *cui_fd; - struct kiocb *cui_iocb; -}; - -/** - * True, if \a io is a normal io, False for splice_{read,write}. - * must be implemented in arch specific code. - */ -int cl_is_normalio(const struct lu_env *env, const struct cl_io *io); - -extern struct lu_context_key ccc_key; -extern struct lu_context_key ccc_session_key; - -struct ccc_thread_info { - struct cl_lock cti_lock; - struct cl_lock_descr cti_descr; - struct cl_io cti_io; - struct cl_attr cti_attr; -}; - -static inline struct ccc_thread_info *ccc_env_info(const struct lu_env *env) -{ - struct ccc_thread_info *info; - - info = lu_context_key_get(&env->le_ctx, &ccc_key); - LASSERT(info); - return info; -} - -static inline struct cl_lock *ccc_env_lock(const struct lu_env *env) -{ - struct cl_lock *lock = &ccc_env_info(env)->cti_lock; - - memset(lock, 0, sizeof(*lock)); - return lock; -} - -static inline struct cl_attr *ccc_env_thread_attr(const struct lu_env *env) -{ - struct cl_attr *attr = &ccc_env_info(env)->cti_attr; - - memset(attr, 0, sizeof(*attr)); - return attr; -} - -static inline struct cl_io *ccc_env_thread_io(const struct lu_env *env) -{ - struct cl_io *io = &ccc_env_info(env)->cti_io; - - memset(io, 0, sizeof(*io)); - return io; -} - -struct ccc_session { - struct ccc_io cs_ios; -}; - -static inline struct ccc_session *ccc_env_session(const struct lu_env *env) -{ - struct ccc_session *ses; - - ses = lu_context_key_get(env->le_ses, &ccc_session_key); - LASSERT(ses); - return ses; -} - -static inline struct ccc_io *ccc_env_io(const struct lu_env *env) -{ - return &ccc_env_session(env)->cs_ios; -} - -/** - * ccc-private object state. - */ -struct ccc_object { - struct cl_object_header cob_header; - struct cl_object cob_cl; - struct inode *cob_inode; - - /** - * A list of dirty pages pending IO in the cache. Used by - * SOM. Protected by ll_inode_info::lli_lock. - * - * \see ccc_page::cpg_pending_linkage - */ - struct list_head cob_pending_list; - - /** - * Access this counter is protected by inode->i_sem. Now that - * the lifetime of transient pages must be covered by inode sem, - * we don't need to hold any lock.. - */ - int cob_transient_pages; - /** - * Number of outstanding mmaps on this file. - * - * \see ll_vm_open(), ll_vm_close(). - */ - atomic_t cob_mmap_cnt; - - /** - * various flags - * cob_discard_page_warned - * if pages belonging to this object are discarded when a client - * is evicted, some debug info will be printed, this flag will be set - * during processing the first discarded page, then avoid flooding - * debug message for lots of discarded pages. - * - * \see ll_dirty_page_discard_warn. - */ - unsigned int cob_discard_page_warned:1; -}; - -/** - * ccc-private page state. - */ -struct ccc_page { - struct cl_page_slice cpg_cl; - int cpg_defer_uptodate; - int cpg_ra_used; - int cpg_write_queued; - /** - * Non-empty iff this page is already counted in - * ccc_object::cob_pending_list. Protected by - * ccc_object::cob_pending_guard. This list is only used as a flag, - * that is, never iterated through, only checked for list_empty(), but - * having a list is useful for debugging. - */ - struct list_head cpg_pending_linkage; - /** VM page */ - struct page *cpg_page; -}; - -static inline struct ccc_page *cl2ccc_page(const struct cl_page_slice *slice) -{ - return container_of(slice, struct ccc_page, cpg_cl); -} - -static inline pgoff_t ccc_index(struct ccc_page *ccc) -{ - return ccc->cpg_cl.cpl_index; -} - -struct ccc_device { - struct cl_device cdv_cl; - struct super_block *cdv_sb; - struct cl_device *cdv_next; -}; - -struct ccc_lock { - struct cl_lock_slice clk_cl; -}; - -struct ccc_req { - struct cl_req_slice crq_cl; -}; - -void *ccc_key_init (const struct lu_context *ctx, - struct lu_context_key *key); -void ccc_key_fini (const struct lu_context *ctx, - struct lu_context_key *key, void *data); -void *ccc_session_key_init(const struct lu_context *ctx, - struct lu_context_key *key); -void ccc_session_key_fini(const struct lu_context *ctx, - struct lu_context_key *key, void *data); - -int ccc_device_init (const struct lu_env *env, - struct lu_device *d, - const char *name, struct lu_device *next); -struct lu_device *ccc_device_fini (const struct lu_env *env, - struct lu_device *d); -struct lu_device *ccc_device_alloc(const struct lu_env *env, - struct lu_device_type *t, - struct lustre_cfg *cfg, - const struct lu_device_operations *luops, - const struct cl_device_operations *clops); -struct lu_device *ccc_device_free (const struct lu_env *env, - struct lu_device *d); -struct lu_object *ccc_object_alloc(const struct lu_env *env, - const struct lu_object_header *hdr, - struct lu_device *dev, - const struct cl_object_operations *clops, - const struct lu_object_operations *luops); - -int ccc_req_init(const struct lu_env *env, struct cl_device *dev, - struct cl_req *req); -void ccc_umount(const struct lu_env *env, struct cl_device *dev); -int ccc_global_init(struct lu_device_type *device_type); -void ccc_global_fini(struct lu_device_type *device_type); -int ccc_object_init0(const struct lu_env *env, struct ccc_object *vob, - const struct cl_object_conf *conf); -int ccc_object_init(const struct lu_env *env, struct lu_object *obj, - const struct lu_object_conf *conf); -void ccc_object_free(const struct lu_env *env, struct lu_object *obj); -int ccc_lock_init(const struct lu_env *env, struct cl_object *obj, - struct cl_lock *lock, const struct cl_io *io, - const struct cl_lock_operations *lkops); -int ccc_object_glimpse(const struct lu_env *env, - const struct cl_object *obj, struct ost_lvb *lvb); -int ccc_fail(const struct lu_env *env, const struct cl_page_slice *slice); -int ccc_transient_page_prep(const struct lu_env *env, - const struct cl_page_slice *slice, - struct cl_io *io); -void ccc_lock_delete(const struct lu_env *env, - const struct cl_lock_slice *slice); -void ccc_lock_fini(const struct lu_env *env, struct cl_lock_slice *slice); -int ccc_lock_enqueue(const struct lu_env *env, - const struct cl_lock_slice *slice, - struct cl_io *io, struct cl_sync_io *anchor); -int ccc_io_one_lock_index(const struct lu_env *env, struct cl_io *io, - __u32 enqflags, enum cl_lock_mode mode, - pgoff_t start, pgoff_t end); -int ccc_io_one_lock(const struct lu_env *env, struct cl_io *io, - __u32 enqflags, enum cl_lock_mode mode, - loff_t start, loff_t end); -void ccc_io_end(const struct lu_env *env, const struct cl_io_slice *ios); -void ccc_io_advance(const struct lu_env *env, const struct cl_io_slice *ios, - size_t nob); -void ccc_io_update_iov(const struct lu_env *env, struct ccc_io *cio, - struct cl_io *io); -int ccc_prep_size(const struct lu_env *env, struct cl_object *obj, - struct cl_io *io, loff_t start, size_t count, int *exceed); -void ccc_req_completion(const struct lu_env *env, - const struct cl_req_slice *slice, int ioret); -void ccc_req_attr_set(const struct lu_env *env, - const struct cl_req_slice *slice, - const struct cl_object *obj, - struct cl_req_attr *oa, u64 flags); - -struct lu_device *ccc2lu_dev (struct ccc_device *vdv); -struct lu_object *ccc2lu (struct ccc_object *vob); -struct ccc_device *lu2ccc_dev (const struct lu_device *d); -struct ccc_device *cl2ccc_dev (const struct cl_device *d); -struct ccc_object *lu2ccc (const struct lu_object *obj); -struct ccc_object *cl2ccc (const struct cl_object *obj); -struct ccc_lock *cl2ccc_lock (const struct cl_lock_slice *slice); -struct ccc_io *cl2ccc_io (const struct lu_env *env, - const struct cl_io_slice *slice); -struct ccc_req *cl2ccc_req (const struct cl_req_slice *slice); -struct page *cl2vm_page (const struct cl_page_slice *slice); -struct inode *ccc_object_inode(const struct cl_object *obj); -struct ccc_object *cl_inode2ccc (struct inode *inode); - -int cl_setattr_ost(struct inode *inode, const struct iattr *attr); - -int ccc_object_invariant(const struct cl_object *obj); -int cl_file_inode_init(struct inode *inode, struct lustre_md *md); -void cl_inode_fini(struct inode *inode); -int cl_local_size(struct inode *inode); - -__u16 ll_dirent_type_get(struct lu_dirent *ent); -__u64 cl_fid_build_ino(const struct lu_fid *fid, int api32); -__u32 cl_fid_build_gen(const struct lu_fid *fid); - -# define CLOBINVRNT(env, clob, expr) \ - ((void)sizeof(env), (void)sizeof(clob), (void)sizeof(!!(expr))) - -int cl_init_ea_size(struct obd_export *md_exp, struct obd_export *dt_exp); -int cl_ocd_update(struct obd_device *host, - struct obd_device *watched, - enum obd_notify_event ev, void *owner, void *data); - -struct ccc_grouplock { - struct lu_env *cg_env; - struct cl_io *cg_io; - struct cl_lock *cg_lock; - unsigned long cg_gid; -}; - -int cl_get_grouplock(struct cl_object *obj, unsigned long gid, int nonblock, - struct ccc_grouplock *cg); -void cl_put_grouplock(struct ccc_grouplock *cg); - -/** - * New interfaces to get and put lov_stripe_md from lov layer. This violates - * layering because lov_stripe_md is supposed to be a private data in lov. - * - * NB: If you find you have to use these interfaces for your new code, please - * think about it again. These interfaces may be removed in the future for - * better layering. - */ -struct lov_stripe_md *lov_lsm_get(struct cl_object *clobj); -void lov_lsm_put(struct cl_object *clobj, struct lov_stripe_md *lsm); -int lov_read_and_clear_async_rc(struct cl_object *clob); - -struct lov_stripe_md *ccc_inode_lsm_get(struct inode *inode); -void ccc_inode_lsm_put(struct inode *inode, struct lov_stripe_md *lsm); - -/** - * Data structure managing a client's cached clean pages. An LRU of - * pages is maintained, along with other statistics. - */ -struct cl_client_cache { - atomic_t ccc_users; /* # of users (OSCs) of this data */ - struct list_head ccc_lru; /* LRU list of cached clean pages */ - spinlock_t ccc_lru_lock; /* lock for list */ - atomic_t ccc_lru_left; /* # of LRU entries available */ - unsigned long ccc_lru_max; /* Max # of LRU entries possible */ - unsigned int ccc_lru_shrinkers; /* # of threads reclaiming */ -}; - -#endif /*LCLIENT_H */ diff --git a/drivers/staging/lustre/lustre/llite/glimpse.c b/drivers/staging/lustre/lustre/llite/glimpse.c index 0759dfc1995a..a6346339042f 100644 --- a/drivers/staging/lustre/lustre/llite/glimpse.c +++ b/drivers/staging/lustre/lustre/llite/glimpse.c @@ -52,7 +52,6 @@ #include #include "../include/cl_object.h" -#include "../include/lclient.h" #include "../llite/llite_internal.h" static const struct cl_lock_descr whole_file = { diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c b/drivers/staging/lustre/lustre/llite/lcommon_cl.c index b339d1bfc5c4..79cdf83c9c16 100644 --- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c +++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c @@ -59,8 +59,6 @@ #include "../include/lustre_mdc.h" #include "../include/cl_object.h" -#include "../include/lclient.h" - #include "../llite/llite_internal.h" static const struct cl_req_operations ccc_req_ops; diff --git a/drivers/staging/lustre/lustre/llite/lcommon_misc.c b/drivers/staging/lustre/lustre/llite/lcommon_misc.c index 4c12e219ffcc..68e3db1f1b4c 100644 --- a/drivers/staging/lustre/lustre/llite/lcommon_misc.c +++ b/drivers/staging/lustre/lustre/llite/lcommon_misc.c @@ -41,8 +41,8 @@ #include "../include/obd_support.h" #include "../include/obd.h" #include "../include/cl_object.h" -#include "../include/lclient.h" +#include "vvp_internal.h" #include "../include/lustre_lite.h" /* Initialize the default and maximum LOV EA and cookie sizes. This allows diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index ffed507da069..5686b94030d9 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -43,11 +43,11 @@ /* for struct cl_lock_descr and struct cl_io */ #include "../include/cl_object.h" -#include "../include/lclient.h" #include "../include/lustre_mdc.h" #include "../include/lustre_intent.h" #include #include +#include "vvp_internal.h" #ifndef FMODE_EXEC #define FMODE_EXEC 0 diff --git a/drivers/staging/lustre/lustre/llite/vvp_internal.h b/drivers/staging/lustre/lustre/llite/vvp_internal.h index aa06f4031311..d4fe61147232 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_internal.h +++ b/drivers/staging/lustre/lustre/llite/vvp_internal.h @@ -41,8 +41,374 @@ #ifndef VVP_INTERNAL_H #define VVP_INTERNAL_H +#include "../include/lustre/lustre_idl.h" #include "../include/cl_object.h" -#include "llite_internal.h" + +enum obd_notify_event; +struct inode; +struct lov_stripe_md; +struct lustre_md; +struct obd_capa; +struct obd_device; +struct obd_export; +struct page; + +blkcnt_t dirty_cnt(struct inode *inode); + +int cl_glimpse_size0(struct inode *inode, int agl); +int cl_glimpse_lock(const struct lu_env *env, struct cl_io *io, + struct inode *inode, struct cl_object *clob, int agl); + +static inline int cl_glimpse_size(struct inode *inode) +{ + return cl_glimpse_size0(inode, 0); +} + +static inline int cl_agl(struct inode *inode) +{ + return cl_glimpse_size0(inode, 1); +} + +/** + * Locking policy for setattr. + */ +enum ccc_setattr_lock_type { + /** Locking is done by server */ + SETATTR_NOLOCK, + /** Extent lock is enqueued */ + SETATTR_EXTENT_LOCK, + /** Existing local extent lock is used */ + SETATTR_MATCH_LOCK +}; + +/** + * IO state private to vvp or slp layers. + */ +struct ccc_io { + /** super class */ + struct cl_io_slice cui_cl; + struct cl_io_lock_link cui_link; + /** + * I/O vector information to or from which read/write is going. + */ + struct iov_iter *cui_iter; + /** + * Total size for the left IO. + */ + size_t cui_tot_count; + + union { + struct { + enum ccc_setattr_lock_type cui_local_lock; + } setattr; + struct { + struct cl_page_list cui_queue; + unsigned long cui_written; + int cui_from; + int cui_to; + } write; + } u; + /** + * Layout version when this IO is initialized + */ + __u32 cui_layout_gen; + /** + * File descriptor against which IO is done. + */ + struct ll_file_data *cui_fd; + struct kiocb *cui_iocb; +}; + +/** + * True, if \a io is a normal io, False for other splice_{read,write}. + * must be implemented in arch specific code. + */ +int cl_is_normalio(const struct lu_env *env, const struct cl_io *io); + +extern struct lu_context_key ccc_key; +extern struct lu_context_key ccc_session_key; + +struct ccc_thread_info { + struct cl_lock cti_lock; + struct cl_lock_descr cti_descr; + struct cl_io cti_io; + struct cl_attr cti_attr; +}; + +static inline struct ccc_thread_info *ccc_env_info(const struct lu_env *env) +{ + struct ccc_thread_info *info; + + info = lu_context_key_get(&env->le_ctx, &ccc_key); + LASSERT(info); + + return info; +} + +static inline struct cl_lock *ccc_env_lock(const struct lu_env *env) +{ + struct cl_lock *lock = &ccc_env_info(env)->cti_lock; + + memset(lock, 0, sizeof(*lock)); + return lock; +} + +static inline struct cl_attr *ccc_env_thread_attr(const struct lu_env *env) +{ + struct cl_attr *attr = &ccc_env_info(env)->cti_attr; + + memset(attr, 0, sizeof(*attr)); + + return attr; +} + +static inline struct cl_io *ccc_env_thread_io(const struct lu_env *env) +{ + struct cl_io *io = &ccc_env_info(env)->cti_io; + + memset(io, 0, sizeof(*io)); + + return io; +} + +struct ccc_session { + struct ccc_io cs_ios; +}; + +static inline struct ccc_session *ccc_env_session(const struct lu_env *env) +{ + struct ccc_session *ses; + + ses = lu_context_key_get(env->le_ses, &ccc_session_key); + LASSERT(ses); + + return ses; +} + +static inline struct ccc_io *ccc_env_io(const struct lu_env *env) +{ + return &ccc_env_session(env)->cs_ios; +} + +/** + * ccc-private object state. + */ +struct ccc_object { + struct cl_object_header cob_header; + struct cl_object cob_cl; + struct inode *cob_inode; + + /** + * A list of dirty pages pending IO in the cache. Used by + * SOM. Protected by ll_inode_info::lli_lock. + * + * \see ccc_page::cpg_pending_linkage + */ + struct list_head cob_pending_list; + + /** + * Access this counter is protected by inode->i_sem. Now that + * the lifetime of transient pages must be covered by inode sem, + * we don't need to hold any lock.. + */ + int cob_transient_pages; + /** + * Number of outstanding mmaps on this file. + * + * \see ll_vm_open(), ll_vm_close(). + */ + atomic_t cob_mmap_cnt; + + /** + * various flags + * cob_discard_page_warned + * if pages belonging to this object are discarded when a client + * is evicted, some debug info will be printed, this flag will be set + * during processing the first discarded page, then avoid flooding + * debug message for lots of discarded pages. + * + * \see ll_dirty_page_discard_warn. + */ + unsigned int cob_discard_page_warned:1; +}; + +/** + * ccc-private page state. + */ +struct ccc_page { + struct cl_page_slice cpg_cl; + int cpg_defer_uptodate; + int cpg_ra_used; + int cpg_write_queued; + /** + * Non-empty iff this page is already counted in + * ccc_object::cob_pending_list. Protected by + * ccc_object::cob_pending_guard. This list is only used as a flag, + * that is, never iterated through, only checked for list_empty(), but + * having a list is useful for debugging. + */ + struct list_head cpg_pending_linkage; + /** VM page */ + struct page *cpg_page; +}; + +static inline struct ccc_page *cl2ccc_page(const struct cl_page_slice *slice) +{ + return container_of(slice, struct ccc_page, cpg_cl); +} + +static inline pgoff_t ccc_index(struct ccc_page *ccc) +{ + return ccc->cpg_cl.cpl_index; +} + +struct cl_page *ccc_vmpage_page_transient(struct page *vmpage); + +struct ccc_device { + struct cl_device cdv_cl; + struct super_block *cdv_sb; + struct cl_device *cdv_next; +}; + +struct ccc_lock { + struct cl_lock_slice clk_cl; +}; + +struct ccc_req { + struct cl_req_slice crq_cl; +}; + +void *ccc_key_init(const struct lu_context *ctx, + struct lu_context_key *key); +void ccc_key_fini(const struct lu_context *ctx, + struct lu_context_key *key, void *data); +void *ccc_session_key_init(const struct lu_context *ctx, + struct lu_context_key *key); +void ccc_session_key_fini(const struct lu_context *ctx, + struct lu_context_key *key, void *data); + +int ccc_device_init(const struct lu_env *env, + struct lu_device *d, + const char *name, struct lu_device *next); +struct lu_device *ccc_device_fini(const struct lu_env *env, + struct lu_device *d); +struct lu_device *ccc_device_alloc(const struct lu_env *env, + struct lu_device_type *t, + struct lustre_cfg *cfg, + const struct lu_device_operations *luops, + const struct cl_device_operations *clops); +struct lu_device *ccc_device_free(const struct lu_env *env, + struct lu_device *d); +struct lu_object *ccc_object_alloc(const struct lu_env *env, + const struct lu_object_header *hdr, + struct lu_device *dev, + const struct cl_object_operations *clops, + const struct lu_object_operations *luops); + +int ccc_req_init(const struct lu_env *env, struct cl_device *dev, + struct cl_req *req); +void ccc_umount(const struct lu_env *env, struct cl_device *dev); +int ccc_global_init(struct lu_device_type *device_type); +void ccc_global_fini(struct lu_device_type *device_type); +int ccc_object_init0(const struct lu_env *env, struct ccc_object *vob, + const struct cl_object_conf *conf); +int ccc_object_init(const struct lu_env *env, struct lu_object *obj, + const struct lu_object_conf *conf); +void ccc_object_free(const struct lu_env *env, struct lu_object *obj); +int ccc_lock_init(const struct lu_env *env, struct cl_object *obj, + struct cl_lock *lock, const struct cl_io *io, + const struct cl_lock_operations *lkops); +int ccc_object_glimpse(const struct lu_env *env, + const struct cl_object *obj, struct ost_lvb *lvb); +int ccc_fail(const struct lu_env *env, const struct cl_page_slice *slice); +int ccc_transient_page_prep(const struct lu_env *env, + const struct cl_page_slice *slice, + struct cl_io *io); +void ccc_lock_delete(const struct lu_env *env, + const struct cl_lock_slice *slice); +void ccc_lock_fini(const struct lu_env *env, struct cl_lock_slice *slice); +int ccc_lock_enqueue(const struct lu_env *env, + const struct cl_lock_slice *slice, + struct cl_io *io, struct cl_sync_io *anchor); + +int ccc_io_one_lock_index(const struct lu_env *env, struct cl_io *io, + __u32 enqflags, enum cl_lock_mode mode, + pgoff_t start, pgoff_t end); +int ccc_io_one_lock(const struct lu_env *env, struct cl_io *io, + __u32 enqflags, enum cl_lock_mode mode, + loff_t start, loff_t end); +void ccc_io_end(const struct lu_env *env, const struct cl_io_slice *ios); +void ccc_io_advance(const struct lu_env *env, const struct cl_io_slice *ios, + size_t nob); +void ccc_io_update_iov(const struct lu_env *env, struct ccc_io *cio, + struct cl_io *io); +int ccc_prep_size(const struct lu_env *env, struct cl_object *obj, + struct cl_io *io, loff_t start, size_t count, int *exceed); +void ccc_req_completion(const struct lu_env *env, + const struct cl_req_slice *slice, int ioret); +void ccc_req_attr_set(const struct lu_env *env, + const struct cl_req_slice *slice, + const struct cl_object *obj, + struct cl_req_attr *oa, u64 flags); + +struct lu_device *ccc2lu_dev(struct ccc_device *vdv); +struct lu_object *ccc2lu(struct ccc_object *vob); +struct ccc_device *lu2ccc_dev(const struct lu_device *d); +struct ccc_device *cl2ccc_dev(const struct cl_device *d); +struct ccc_object *lu2ccc(const struct lu_object *obj); +struct ccc_object *cl2ccc(const struct cl_object *obj); +struct ccc_lock *cl2ccc_lock(const struct cl_lock_slice *slice); +struct ccc_io *cl2ccc_io(const struct lu_env *env, + const struct cl_io_slice *slice); +struct ccc_req *cl2ccc_req(const struct cl_req_slice *slice); +struct page *cl2vm_page(const struct cl_page_slice *slice); +struct inode *ccc_object_inode(const struct cl_object *obj); +struct ccc_object *cl_inode2ccc(struct inode *inode); + +int cl_setattr_ost(struct inode *inode, const struct iattr *attr); + +int ccc_object_invariant(const struct cl_object *obj); +int cl_file_inode_init(struct inode *inode, struct lustre_md *md); +void cl_inode_fini(struct inode *inode); +int cl_local_size(struct inode *inode); + +__u16 ll_dirent_type_get(struct lu_dirent *ent); +__u64 cl_fid_build_ino(const struct lu_fid *fid, int api32); +__u32 cl_fid_build_gen(const struct lu_fid *fid); + +# define CLOBINVRNT(env, clob, expr) \ + ((void)sizeof(env), (void)sizeof(clob), (void)sizeof(!!(expr))) + +int cl_init_ea_size(struct obd_export *md_exp, struct obd_export *dt_exp); +int cl_ocd_update(struct obd_device *host, + struct obd_device *watched, + enum obd_notify_event ev, void *owner, void *data); + +struct ccc_grouplock { + struct lu_env *cg_env; + struct cl_io *cg_io; + struct cl_lock *cg_lock; + unsigned long cg_gid; +}; + +int cl_get_grouplock(struct cl_object *obj, unsigned long gid, int nonblock, + struct ccc_grouplock *cg); +void cl_put_grouplock(struct ccc_grouplock *cg); + +/** + * New interfaces to get and put lov_stripe_md from lov layer. This violates + * layering because lov_stripe_md is supposed to be a private data in lov. + * + * NB: If you find you have to use these interfaces for your new code, please + * think about it again. These interfaces may be removed in the future for + * better layering. + */ +struct lov_stripe_md *lov_lsm_get(struct cl_object *clobj); +void lov_lsm_put(struct cl_object *clobj, struct lov_stripe_md *lsm); +int lov_read_and_clear_async_rc(struct cl_object *clob); + +struct lov_stripe_md *ccc_inode_lsm_get(struct inode *inode); +void ccc_inode_lsm_put(struct inode *inode, struct lov_stripe_md *lsm); int vvp_io_init(const struct lu_env *env, struct cl_object *obj, struct cl_io *io); diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c index 1d2fc3bf9487..fcf0cfe070ab 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_io.c +++ b/drivers/staging/lustre/lustre/llite/vvp_io.c @@ -44,6 +44,7 @@ #include "../include/obd.h" #include "../include/lustre_lite.h" +#include "llite_internal.h" #include "vvp_internal.h" static struct vvp_io *cl2vvp_io(const struct lu_env *env, diff --git a/drivers/staging/lustre/lustre/llite/vvp_object.c b/drivers/staging/lustre/lustre/llite/vvp_object.c index 34210dbc8cd2..45fac697cd3d 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_object.c +++ b/drivers/staging/lustre/lustre/llite/vvp_object.c @@ -45,6 +45,7 @@ #include "../include/obd.h" #include "../include/lustre_lite.h" +#include "llite_internal.h" #include "vvp_internal.h" /***************************************************************************** diff --git a/drivers/staging/lustre/lustre/llite/vvp_page.c b/drivers/staging/lustre/lustre/llite/vvp_page.c index 3c6b72398d62..66a4f9b0aa0b 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_page.c +++ b/drivers/staging/lustre/lustre/llite/vvp_page.c @@ -44,6 +44,7 @@ #include "../include/obd.h" #include "../include/lustre_lite.h" +#include "llite_internal.h" #include "vvp_internal.h" /***************************************************************************** diff --git a/drivers/staging/lustre/lustre/lov/lov_obd.c b/drivers/staging/lustre/lustre/lov/lov_obd.c index 5daa7faf4dda..1a9e3e8cdda9 100644 --- a/drivers/staging/lustre/lustre/lov/lov_obd.c +++ b/drivers/staging/lustre/lustre/lov/lov_obd.c @@ -54,7 +54,6 @@ #include "../include/lprocfs_status.h" #include "../include/lustre_param.h" #include "../include/cl_object.h" -#include "../include/lclient.h" /* for cl_client_lru */ #include "../include/lustre/ll_fiemap.h" #include "../include/lustre_fid.h" diff --git a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h index c7a69e4cd944..d6d7661ab5ad 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h +++ b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h @@ -51,7 +51,6 @@ #include "../include/obd.h" /* osc_build_res_name() */ #include "../include/cl_object.h" -#include "../include/lclient.h" #include "osc_internal.h" /** \defgroup osc osc -- cgit v1.2.3 From 3c95b8396758428405b445fe1faca936f1fe7dc5 Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Wed, 30 Mar 2016 19:48:46 -0400 Subject: staging/lustre/llite: rename ccc_device to vvp_device Rename struct ccc_device to struct vvp_device and merge the CCC device methods into the VVP device methods. Signed-off-by: John L. Hammond Reviewed-on: http://review.whamcloud.com/13075 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5971 Reviewed-by: Lai Siyao Reviewed-by: James Simmons Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/cl_object.h | 2 +- drivers/staging/lustre/lustre/llite/lcommon_cl.c | 104 +-------------------- .../staging/lustre/lustre/llite/llite_internal.h | 2 +- drivers/staging/lustre/lustre/llite/vvp_dev.c | 84 ++++++++++++++++- drivers/staging/lustre/lustre/llite/vvp_internal.h | 38 ++++---- 5 files changed, 102 insertions(+), 128 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h index f2bb8f8637cf..f2a242b74220 100644 --- a/drivers/staging/lustre/lustre/include/cl_object.h +++ b/drivers/staging/lustre/lustre/include/cl_object.h @@ -149,7 +149,7 @@ struct cl_device_operations { /** * Device in the client stack. * - * \see ccc_device, lov_device, lovsub_device, osc_device + * \see vvp_device, lov_device, lovsub_device, osc_device */ struct cl_device { /** Super-class. */ diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c b/drivers/staging/lustre/lustre/llite/lcommon_cl.c index 79cdf83c9c16..b0d4a3de8ff0 100644 --- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c +++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c @@ -159,91 +159,6 @@ struct lu_context_key ccc_session_key = { .lct_fini = ccc_session_key_fini }; -/* type constructor/destructor: ccc_type_{init,fini,start,stop}(). */ -/* LU_TYPE_INIT_FINI(ccc, &ccc_key, &ccc_session_key); */ - -int ccc_device_init(const struct lu_env *env, struct lu_device *d, - const char *name, struct lu_device *next) -{ - struct ccc_device *vdv; - int rc; - - vdv = lu2ccc_dev(d); - vdv->cdv_next = lu2cl_dev(next); - - LASSERT(d->ld_site && next->ld_type); - next->ld_site = d->ld_site; - rc = next->ld_type->ldt_ops->ldto_device_init( - env, next, next->ld_type->ldt_name, NULL); - if (rc == 0) { - lu_device_get(next); - lu_ref_add(&next->ld_reference, "lu-stack", &lu_site_init); - } - return rc; -} - -struct lu_device *ccc_device_fini(const struct lu_env *env, - struct lu_device *d) -{ - return cl2lu_dev(lu2ccc_dev(d)->cdv_next); -} - -struct lu_device *ccc_device_alloc(const struct lu_env *env, - struct lu_device_type *t, - struct lustre_cfg *cfg, - const struct lu_device_operations *luops, - const struct cl_device_operations *clops) -{ - struct ccc_device *vdv; - struct lu_device *lud; - struct cl_site *site; - int rc; - - vdv = kzalloc(sizeof(*vdv), GFP_NOFS); - if (!vdv) - return ERR_PTR(-ENOMEM); - - lud = &vdv->cdv_cl.cd_lu_dev; - cl_device_init(&vdv->cdv_cl, t); - ccc2lu_dev(vdv)->ld_ops = luops; - vdv->cdv_cl.cd_ops = clops; - - site = kzalloc(sizeof(*site), GFP_NOFS); - if (site) { - rc = cl_site_init(site, &vdv->cdv_cl); - if (rc == 0) { - rc = lu_site_init_finish(&site->cs_lu); - } else { - LASSERT(!lud->ld_site); - CERROR("Cannot init lu_site, rc %d.\n", rc); - kfree(site); - } - } else { - rc = -ENOMEM; - } - if (rc != 0) { - ccc_device_free(env, lud); - lud = ERR_PTR(rc); - } - return lud; -} - -struct lu_device *ccc_device_free(const struct lu_env *env, - struct lu_device *d) -{ - struct ccc_device *vdv = lu2ccc_dev(d); - struct cl_site *site = lu2cl_site(d->ld_site); - struct lu_device *next = cl2lu_dev(vdv->cdv_next); - - if (d->ld_site) { - cl_site_fini(site); - kfree(site); - } - cl_device_fini(lu2cl_dev(d)); - kfree(vdv); - return next; -} - int ccc_req_init(const struct lu_env *env, struct cl_device *dev, struct cl_req *req) { @@ -360,13 +275,13 @@ int ccc_object_init0(const struct lu_env *env, int ccc_object_init(const struct lu_env *env, struct lu_object *obj, const struct lu_object_conf *conf) { - struct ccc_device *dev = lu2ccc_dev(obj->lo_dev); + struct vvp_device *dev = lu2vvp_dev(obj->lo_dev); struct ccc_object *vob = lu2ccc(obj); struct lu_object *below; struct lu_device *under; int result; - under = &dev->cdv_next->cd_lu_dev; + under = &dev->vdv_next->cd_lu_dev; below = under->ld_ops->ldo_object_alloc(env, obj->lo_header, under); if (below) { const struct cl_object_conf *cconf; @@ -779,21 +694,6 @@ again: * */ -struct lu_device *ccc2lu_dev(struct ccc_device *vdv) -{ - return &vdv->cdv_cl.cd_lu_dev; -} - -struct ccc_device *lu2ccc_dev(const struct lu_device *d) -{ - return container_of0(d, struct ccc_device, cdv_cl.cd_lu_dev); -} - -struct ccc_device *cl2ccc_dev(const struct cl_device *d) -{ - return container_of0(d, struct ccc_device, cdv_cl); -} - struct lu_object *ccc2lu(struct ccc_object *vob) { return &vob->cob_cl.co_lu; diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index 5686b94030d9..1e9e41b225aa 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -1321,7 +1321,7 @@ static inline void cl_stats_tally(struct cl_device *dev, enum cl_req_type crt, int opc = (crt == CRT_READ) ? LPROC_LL_OSC_READ : LPROC_LL_OSC_WRITE; - ll_stats_ops_tally(ll_s2sbi(cl2ccc_dev(dev)->cdv_sb), opc, rc); + ll_stats_ops_tally(ll_s2sbi(cl2vvp_dev(dev)->vdv_sb), opc, rc); } ssize_t ll_direct_rw_pages(const struct lu_env *env, struct cl_io *io, diff --git a/drivers/staging/lustre/lustre/llite/vvp_dev.c b/drivers/staging/lustre/lustre/llite/vvp_dev.c index 29d24c98d259..e934ec87cf60 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_dev.c +++ b/drivers/staging/lustre/lustre/llite/vvp_dev.c @@ -136,11 +136,85 @@ static const struct cl_device_operations vvp_cl_ops = { .cdo_req_init = ccc_req_init }; +static struct lu_device *vvp_device_free(const struct lu_env *env, + struct lu_device *d) +{ + struct vvp_device *vdv = lu2vvp_dev(d); + struct cl_site *site = lu2cl_site(d->ld_site); + struct lu_device *next = cl2lu_dev(vdv->vdv_next); + + if (d->ld_site) { + cl_site_fini(site); + kfree(site); + } + cl_device_fini(lu2cl_dev(d)); + kfree(vdv); + return next; +} + static struct lu_device *vvp_device_alloc(const struct lu_env *env, struct lu_device_type *t, struct lustre_cfg *cfg) { - return ccc_device_alloc(env, t, cfg, &vvp_lu_ops, &vvp_cl_ops); + struct vvp_device *vdv; + struct lu_device *lud; + struct cl_site *site; + int rc; + + vdv = kzalloc(sizeof(*vdv), GFP_NOFS); + if (!vdv) + return ERR_PTR(-ENOMEM); + + lud = &vdv->vdv_cl.cd_lu_dev; + cl_device_init(&vdv->vdv_cl, t); + vvp2lu_dev(vdv)->ld_ops = &vvp_lu_ops; + vdv->vdv_cl.cd_ops = &vvp_cl_ops; + + site = kzalloc(sizeof(*site), GFP_NOFS); + if (site) { + rc = cl_site_init(site, &vdv->vdv_cl); + if (rc == 0) { + rc = lu_site_init_finish(&site->cs_lu); + } else { + LASSERT(!lud->ld_site); + CERROR("Cannot init lu_site, rc %d.\n", rc); + kfree(site); + } + } else { + rc = -ENOMEM; + } + if (rc != 0) { + vvp_device_free(env, lud); + lud = ERR_PTR(rc); + } + return lud; +} + +static int vvp_device_init(const struct lu_env *env, struct lu_device *d, + const char *name, struct lu_device *next) +{ + struct vvp_device *vdv; + int rc; + + vdv = lu2vvp_dev(d); + vdv->vdv_next = lu2cl_dev(next); + + LASSERT(d->ld_site && next->ld_type); + next->ld_site = d->ld_site; + rc = next->ld_type->ldt_ops->ldto_device_init(env, next, + next->ld_type->ldt_name, + NULL); + if (rc == 0) { + lu_device_get(next); + lu_ref_add(&next->ld_reference, "lu-stack", &lu_site_init); + } + return rc; +} + +static struct lu_device *vvp_device_fini(const struct lu_env *env, + struct lu_device *d) +{ + return cl2lu_dev(lu2vvp_dev(d)->vdv_next); } static const struct lu_device_type_operations vvp_device_type_ops = { @@ -151,9 +225,9 @@ static const struct lu_device_type_operations vvp_device_type_ops = { .ldto_stop = vvp_type_stop, .ldto_device_alloc = vvp_device_alloc, - .ldto_device_free = ccc_device_free, - .ldto_device_init = ccc_device_init, - .ldto_device_fini = ccc_device_fini + .ldto_device_free = vvp_device_free, + .ldto_device_init = vvp_device_init, + .ldto_device_fini = vvp_device_fini, }; struct lu_device_type vvp_device_type = { @@ -206,7 +280,7 @@ int cl_sb_init(struct super_block *sb) cl = cl_type_setup(env, NULL, &vvp_device_type, sbi->ll_dt_exp->exp_obd->obd_lu_dev); if (!IS_ERR(cl)) { - cl2ccc_dev(cl)->cdv_sb = sb; + cl2vvp_dev(cl)->vdv_sb = sb; sbi->ll_cl = cl; sbi->ll_site = cl2lu_dev(cl)->ld_site; } diff --git a/drivers/staging/lustre/lustre/llite/vvp_internal.h b/drivers/staging/lustre/lustre/llite/vvp_internal.h index d4fe61147232..34509f9d889f 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_internal.h +++ b/drivers/staging/lustre/lustre/llite/vvp_internal.h @@ -264,10 +264,10 @@ static inline pgoff_t ccc_index(struct ccc_page *ccc) struct cl_page *ccc_vmpage_page_transient(struct page *vmpage); -struct ccc_device { - struct cl_device cdv_cl; - struct super_block *cdv_sb; - struct cl_device *cdv_next; +struct vvp_device { + struct cl_device vdv_cl; + struct super_block *vdv_sb; + struct cl_device *vdv_next; }; struct ccc_lock { @@ -287,18 +287,6 @@ void *ccc_session_key_init(const struct lu_context *ctx, void ccc_session_key_fini(const struct lu_context *ctx, struct lu_context_key *key, void *data); -int ccc_device_init(const struct lu_env *env, - struct lu_device *d, - const char *name, struct lu_device *next); -struct lu_device *ccc_device_fini(const struct lu_env *env, - struct lu_device *d); -struct lu_device *ccc_device_alloc(const struct lu_env *env, - struct lu_device_type *t, - struct lustre_cfg *cfg, - const struct lu_device_operations *luops, - const struct cl_device_operations *clops); -struct lu_device *ccc_device_free(const struct lu_env *env, - struct lu_device *d); struct lu_object *ccc_object_alloc(const struct lu_env *env, const struct lu_object_header *hdr, struct lu_device *dev, @@ -351,10 +339,22 @@ void ccc_req_attr_set(const struct lu_env *env, const struct cl_object *obj, struct cl_req_attr *oa, u64 flags); -struct lu_device *ccc2lu_dev(struct ccc_device *vdv); +static inline struct lu_device *vvp2lu_dev(struct vvp_device *vdv) +{ + return &vdv->vdv_cl.cd_lu_dev; +} + +static inline struct vvp_device *lu2vvp_dev(const struct lu_device *d) +{ + return container_of0(d, struct vvp_device, vdv_cl.cd_lu_dev); +} + +static inline struct vvp_device *cl2vvp_dev(const struct cl_device *d) +{ + return container_of0(d, struct vvp_device, vdv_cl); +} + struct lu_object *ccc2lu(struct ccc_object *vob); -struct ccc_device *lu2ccc_dev(const struct lu_device *d); -struct ccc_device *cl2ccc_dev(const struct cl_device *d); struct ccc_object *lu2ccc(const struct lu_object *obj); struct ccc_object *cl2ccc(const struct cl_object *obj); struct ccc_lock *cl2ccc_lock(const struct cl_lock_slice *slice); -- cgit v1.2.3 From 8c7b0e1a67471b621b2200eced63ec2ea6f3b8fa Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Wed, 30 Mar 2016 19:48:47 -0400 Subject: staging/lustre/llite: rename ccc_object to vvp_object Rename struct ccc_object to struct vvp_object and merge the CCC object methods into the VVP object methods. Signed-off-by: John L. Hammond Reviewed-on: http://review.whamcloud.com/13077 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5971 Reviewed-by: James Simmons Reviewed-by: Dmitry Eremin Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/cl_object.h | 4 +- drivers/staging/lustre/lustre/llite/glimpse.c | 4 +- drivers/staging/lustre/lustre/llite/lcommon_cl.c | 166 ++------------------- drivers/staging/lustre/lustre/llite/llite_close.c | 22 +-- .../staging/lustre/lustre/llite/llite_internal.h | 6 +- drivers/staging/lustre/lustre/llite/llite_lib.c | 4 +- drivers/staging/lustre/lustre/llite/llite_mmap.c | 16 +- drivers/staging/lustre/lustre/llite/rw.c | 4 +- drivers/staging/lustre/lustre/llite/rw26.c | 6 +- drivers/staging/lustre/lustre/llite/vvp_dev.c | 10 +- drivers/staging/lustre/lustre/llite/vvp_internal.h | 61 ++++---- drivers/staging/lustre/lustre/llite/vvp_io.c | 36 ++--- drivers/staging/lustre/lustre/llite/vvp_object.c | 121 +++++++++++++-- drivers/staging/lustre/lustre/llite/vvp_page.c | 40 ++--- .../staging/lustre/lustre/osc/osc_cl_internal.h | 2 +- 15 files changed, 231 insertions(+), 271 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h index f2a242b74220..d3271ffe17da 100644 --- a/drivers/staging/lustre/lustre/include/cl_object.h +++ b/drivers/staging/lustre/lustre/include/cl_object.h @@ -245,7 +245,7 @@ enum cl_attr_valid { * be discarded from the memory, all its sub-objects are torn-down and * destroyed too. * - * \see ccc_object, lov_object, lovsub_object, osc_object + * \see vvp_object, lov_object, lovsub_object, osc_object */ struct cl_object { /** super class */ @@ -385,7 +385,7 @@ struct cl_object_operations { * object. Layers are supposed to fill parts of \a lvb that will be * shipped to the glimpse originator as a glimpse result. * - * \see ccc_object_glimpse(), lovsub_object_glimpse(), + * \see vvp_object_glimpse(), lovsub_object_glimpse(), * \see osc_object_glimpse() */ int (*coo_glimpse)(const struct lu_env *env, diff --git a/drivers/staging/lustre/lustre/llite/glimpse.c b/drivers/staging/lustre/lustre/llite/glimpse.c index a6346339042f..d76fa163c362 100644 --- a/drivers/staging/lustre/lustre/llite/glimpse.c +++ b/drivers/staging/lustre/lustre/llite/glimpse.c @@ -69,14 +69,14 @@ static const struct cl_lock_descr whole_file = { blkcnt_t dirty_cnt(struct inode *inode) { blkcnt_t cnt = 0; - struct ccc_object *vob = cl_inode2ccc(inode); + struct vvp_object *vob = cl_inode2vvp(inode); void *results[1]; if (inode->i_mapping) cnt += radix_tree_gang_lookup_tag(&inode->i_mapping->page_tree, results, 0, 1, PAGECACHE_TAG_DIRTY); - if (cnt == 0 && atomic_read(&vob->cob_mmap_cnt) > 0) + if (cnt == 0 && atomic_read(&vob->vob_mmap_cnt) > 0) cnt = 1; return (cnt > 0) ? 1 : 0; diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c b/drivers/staging/lustre/lustre/llite/lcommon_cl.c index b0d4a3de8ff0..9db0510d2693 100644 --- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c +++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c @@ -68,7 +68,6 @@ static const struct cl_req_operations ccc_req_ops; */ static struct kmem_cache *ccc_lock_kmem; -static struct kmem_cache *ccc_object_kmem; static struct kmem_cache *ccc_thread_kmem; static struct kmem_cache *ccc_session_kmem; static struct kmem_cache *ccc_req_kmem; @@ -79,11 +78,6 @@ static struct lu_kmem_descr ccc_caches[] = { .ckd_name = "ccc_lock_kmem", .ckd_size = sizeof(struct ccc_lock) }, - { - .ckd_cache = &ccc_object_kmem, - .ckd_name = "ccc_object_kmem", - .ckd_size = sizeof(struct ccc_object) - }, { .ckd_cache = &ccc_thread_kmem, .ckd_name = "ccc_thread_kmem", @@ -227,84 +221,6 @@ void ccc_global_fini(struct lu_device_type *device_type) lu_kmem_fini(ccc_caches); } -/***************************************************************************** - * - * Object operations. - * - */ - -struct lu_object *ccc_object_alloc(const struct lu_env *env, - const struct lu_object_header *unused, - struct lu_device *dev, - const struct cl_object_operations *clops, - const struct lu_object_operations *luops) -{ - struct ccc_object *vob; - struct lu_object *obj; - - vob = kmem_cache_zalloc(ccc_object_kmem, GFP_NOFS); - if (vob) { - struct cl_object_header *hdr; - - obj = ccc2lu(vob); - hdr = &vob->cob_header; - cl_object_header_init(hdr); - hdr->coh_page_bufsize = cfs_size_round(sizeof(struct cl_page)); - - lu_object_init(obj, &hdr->coh_lu, dev); - lu_object_add_top(&hdr->coh_lu, obj); - - vob->cob_cl.co_ops = clops; - obj->lo_ops = luops; - } else { - obj = NULL; - } - return obj; -} - -int ccc_object_init0(const struct lu_env *env, - struct ccc_object *vob, - const struct cl_object_conf *conf) -{ - vob->cob_inode = conf->coc_inode; - vob->cob_transient_pages = 0; - cl_object_page_init(&vob->cob_cl, sizeof(struct ccc_page)); - return 0; -} - -int ccc_object_init(const struct lu_env *env, struct lu_object *obj, - const struct lu_object_conf *conf) -{ - struct vvp_device *dev = lu2vvp_dev(obj->lo_dev); - struct ccc_object *vob = lu2ccc(obj); - struct lu_object *below; - struct lu_device *under; - int result; - - under = &dev->vdv_next->cd_lu_dev; - below = under->ld_ops->ldo_object_alloc(env, obj->lo_header, under); - if (below) { - const struct cl_object_conf *cconf; - - cconf = lu2cl_conf(conf); - INIT_LIST_HEAD(&vob->cob_pending_list); - lu_object_add(obj, below); - result = ccc_object_init0(env, vob, cconf); - } else { - result = -ENOMEM; - } - return result; -} - -void ccc_object_free(const struct lu_env *env, struct lu_object *obj) -{ - struct ccc_object *vob = lu2ccc(obj); - - lu_object_fini(obj); - lu_object_header_fini(obj->lo_header); - kmem_cache_free(ccc_object_kmem, vob); -} - int ccc_lock_init(const struct lu_env *env, struct cl_object *obj, struct cl_lock *lock, const struct cl_io *unused, @@ -313,7 +229,7 @@ int ccc_lock_init(const struct lu_env *env, struct ccc_lock *clk; int result; - CLOBINVRNT(env, obj, ccc_object_invariant(obj)); + CLOBINVRNT(env, obj, vvp_object_invariant(obj)); clk = kmem_cache_zalloc(ccc_lock_kmem, GFP_NOFS); if (clk) { @@ -325,35 +241,17 @@ int ccc_lock_init(const struct lu_env *env, return result; } -int ccc_object_glimpse(const struct lu_env *env, - const struct cl_object *obj, struct ost_lvb *lvb) -{ - struct inode *inode = ccc_object_inode(obj); - - lvb->lvb_mtime = LTIME_S(inode->i_mtime); - lvb->lvb_atime = LTIME_S(inode->i_atime); - lvb->lvb_ctime = LTIME_S(inode->i_ctime); - /* - * LU-417: Add dirty pages block count lest i_blocks reports 0, some - * "cp" or "tar" on remote node may think it's a completely sparse file - * and skip it. - */ - if (lvb->lvb_size > 0 && lvb->lvb_blocks == 0) - lvb->lvb_blocks = dirty_cnt(inode); - return 0; -} - -static void ccc_object_size_lock(struct cl_object *obj) +static void vvp_object_size_lock(struct cl_object *obj) { - struct inode *inode = ccc_object_inode(obj); + struct inode *inode = vvp_object_inode(obj); ll_inode_size_lock(inode); cl_object_attr_lock(obj); } -static void ccc_object_size_unlock(struct cl_object *obj) +static void vvp_object_size_unlock(struct cl_object *obj) { - struct inode *inode = ccc_object_inode(obj); + struct inode *inode = vvp_object_inode(obj); cl_object_attr_unlock(obj); ll_inode_size_unlock(inode); @@ -399,7 +297,7 @@ int ccc_lock_enqueue(const struct lu_env *env, const struct cl_lock_slice *slice, struct cl_io *unused, struct cl_sync_io *anchor) { - CLOBINVRNT(env, slice->cls_obj, ccc_object_invariant(slice->cls_obj)); + CLOBINVRNT(env, slice->cls_obj, vvp_object_invariant(slice->cls_obj)); return 0; } @@ -417,7 +315,7 @@ int ccc_io_one_lock_index(const struct lu_env *env, struct cl_io *io, struct cl_lock_descr *descr = &cio->cui_link.cill_descr; struct cl_object *obj = io->ci_obj; - CLOBINVRNT(env, obj, ccc_object_invariant(obj)); + CLOBINVRNT(env, obj, vvp_object_invariant(obj)); CDEBUG(D_VFSTRACE, "lock: %d [%lu, %lu]\n", mode, start, end); @@ -462,7 +360,7 @@ int ccc_io_one_lock(const struct lu_env *env, struct cl_io *io, void ccc_io_end(const struct lu_env *env, const struct cl_io_slice *ios) { CLOBINVRNT(env, ios->cis_io->ci_obj, - ccc_object_invariant(ios->cis_io->ci_obj)); + vvp_object_invariant(ios->cis_io->ci_obj)); } void ccc_io_advance(const struct lu_env *env, @@ -473,7 +371,7 @@ void ccc_io_advance(const struct lu_env *env, struct cl_io *io = ios->cis_io; struct cl_object *obj = ios->cis_io->ci_obj; - CLOBINVRNT(env, obj, ccc_object_invariant(obj)); + CLOBINVRNT(env, obj, vvp_object_invariant(obj)); if (!cl_is_normalio(env, io)) return; @@ -496,7 +394,7 @@ int ccc_prep_size(const struct lu_env *env, struct cl_object *obj, struct cl_io *io, loff_t start, size_t count, int *exceed) { struct cl_attr *attr = ccc_env_thread_attr(env); - struct inode *inode = ccc_object_inode(obj); + struct inode *inode = vvp_object_inode(obj); loff_t pos = start + count - 1; loff_t kms; int result; @@ -520,7 +418,7 @@ int ccc_prep_size(const struct lu_env *env, struct cl_object *obj, * ll_inode_size_lock(). This guarantees that short reads are handled * correctly in the face of concurrent writes and truncates. */ - ccc_object_size_lock(obj); + vvp_object_size_lock(obj); result = cl_object_attr_get(env, obj, attr); if (result == 0) { kms = attr->cat_kms; @@ -530,7 +428,7 @@ int ccc_prep_size(const struct lu_env *env, struct cl_object *obj, * return a short read (B) or some zeroes at the end * of the buffer (C) */ - ccc_object_size_unlock(obj); + vvp_object_size_unlock(obj); result = cl_glimpse_lock(env, io, inode, obj, 0); if (result == 0 && exceed) { /* If objective page index exceed end-of-file @@ -567,7 +465,9 @@ int ccc_prep_size(const struct lu_env *env, struct cl_object *obj, (__u64)i_size_read(inode)); } } - ccc_object_size_unlock(obj); + + vvp_object_size_unlock(obj); + return result; } @@ -618,7 +518,7 @@ void ccc_req_attr_set(const struct lu_env *env, u32 valid_flags; oa = attr->cra_oa; - inode = ccc_object_inode(obj); + inode = vvp_object_inode(obj); valid_flags = OBD_MD_FLTYPE; if (slice->crs_req->crq_type == CRT_WRITE) { @@ -694,21 +594,6 @@ again: * */ -struct lu_object *ccc2lu(struct ccc_object *vob) -{ - return &vob->cob_cl.co_lu; -} - -struct ccc_object *lu2ccc(const struct lu_object *obj) -{ - return container_of0(obj, struct ccc_object, cob_cl.co_lu); -} - -struct ccc_object *cl2ccc(const struct cl_object *obj) -{ - return container_of0(obj, struct ccc_object, cob_cl); -} - struct ccc_lock *cl2ccc_lock(const struct cl_lock_slice *slice) { return container_of(slice, struct ccc_lock, clk_cl); @@ -734,25 +619,6 @@ struct page *cl2vm_page(const struct cl_page_slice *slice) return cl2ccc_page(slice)->cpg_page; } -/***************************************************************************** - * - * Accessors. - * - */ -int ccc_object_invariant(const struct cl_object *obj) -{ - struct inode *inode = ccc_object_inode(obj); - struct ll_inode_info *lli = ll_i2info(inode); - - return (S_ISREG(inode->i_mode) || inode->i_mode == 0) && - lli->lli_clob == obj; -} - -struct inode *ccc_object_inode(const struct cl_object *obj) -{ - return cl2ccc(obj)->cob_inode; -} - /** * Initialize or update CLIO structures for regular files when new * meta-data arrives from the server. diff --git a/drivers/staging/lustre/lustre/llite/llite_close.c b/drivers/staging/lustre/lustre/llite/llite_close.c index a55ac4dccd90..6e99d341112f 100644 --- a/drivers/staging/lustre/lustre/llite/llite_close.c +++ b/drivers/staging/lustre/lustre/llite/llite_close.c @@ -46,21 +46,21 @@ #include "llite_internal.h" /** records that a write is in flight */ -void vvp_write_pending(struct ccc_object *club, struct ccc_page *page) +void vvp_write_pending(struct vvp_object *club, struct ccc_page *page) { - struct ll_inode_info *lli = ll_i2info(club->cob_inode); + struct ll_inode_info *lli = ll_i2info(club->vob_inode); spin_lock(&lli->lli_lock); lli->lli_flags |= LLIF_SOM_DIRTY; if (page && list_empty(&page->cpg_pending_linkage)) - list_add(&page->cpg_pending_linkage, &club->cob_pending_list); + list_add(&page->cpg_pending_linkage, &club->vob_pending_list); spin_unlock(&lli->lli_lock); } /** records that a write has completed */ -void vvp_write_complete(struct ccc_object *club, struct ccc_page *page) +void vvp_write_complete(struct vvp_object *club, struct ccc_page *page) { - struct ll_inode_info *lli = ll_i2info(club->cob_inode); + struct ll_inode_info *lli = ll_i2info(club->vob_inode); int rc = 0; spin_lock(&lli->lli_lock); @@ -70,7 +70,7 @@ void vvp_write_complete(struct ccc_object *club, struct ccc_page *page) } spin_unlock(&lli->lli_lock); if (rc) - ll_queue_done_writing(club->cob_inode, 0); + ll_queue_done_writing(club->vob_inode, 0); } /** Queues DONE_WRITING if @@ -80,13 +80,13 @@ void vvp_write_complete(struct ccc_object *club, struct ccc_page *page) void ll_queue_done_writing(struct inode *inode, unsigned long flags) { struct ll_inode_info *lli = ll_i2info(inode); - struct ccc_object *club = cl2ccc(ll_i2info(inode)->lli_clob); + struct vvp_object *club = cl2vvp(ll_i2info(inode)->lli_clob); spin_lock(&lli->lli_lock); lli->lli_flags |= flags; if ((lli->lli_flags & LLIF_DONE_WRITING) && - list_empty(&club->cob_pending_list)) { + list_empty(&club->vob_pending_list)) { struct ll_close_queue *lcq = ll_i2sbi(inode)->ll_lcq; if (lli->lli_flags & LLIF_MDS_SIZE_LOCK) @@ -140,10 +140,10 @@ void ll_ioepoch_close(struct inode *inode, struct md_op_data *op_data, struct obd_client_handle **och, unsigned long flags) { struct ll_inode_info *lli = ll_i2info(inode); - struct ccc_object *club = cl2ccc(ll_i2info(inode)->lli_clob); + struct vvp_object *club = cl2vvp(ll_i2info(inode)->lli_clob); spin_lock(&lli->lli_lock); - if (!(list_empty(&club->cob_pending_list))) { + if (!(list_empty(&club->vob_pending_list))) { if (!(lli->lli_flags & LLIF_EPOCH_PENDING)) { LASSERT(*och); LASSERT(!lli->lli_pending_och); @@ -198,7 +198,7 @@ void ll_ioepoch_close(struct inode *inode, struct md_op_data *op_data, } } - LASSERT(list_empty(&club->cob_pending_list)); + LASSERT(list_empty(&club->vob_pending_list)); lli->lli_flags &= ~LLIF_SOM_DIRTY; spin_unlock(&lli->lli_lock); ll_done_writing_attr(inode, op_data); diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index 1e9e41b225aa..1c39d15f34f5 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -828,10 +828,8 @@ struct ll_close_queue { atomic_t lcq_stop; }; -struct ccc_object *cl_inode2ccc(struct inode *inode); - -void vvp_write_pending (struct ccc_object *club, struct ccc_page *page); -void vvp_write_complete(struct ccc_object *club, struct ccc_page *page); +void vvp_write_pending(struct vvp_object *club, struct ccc_page *page); +void vvp_write_complete(struct vvp_object *club, struct ccc_page *page); /* specific architecture can implement only part of this list */ enum vvp_io_subtype { diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index 0f01cfc14b72..95c55c316ec0 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -2270,7 +2270,7 @@ void ll_dirty_page_discard_warn(struct page *page, int ioret) { char *buf, *path = NULL; struct dentry *dentry = NULL; - struct ccc_object *obj = cl_inode2ccc(page->mapping->host); + struct vvp_object *obj = cl_inode2vvp(page->mapping->host); /* this can be called inside spin lock so use GFP_ATOMIC. */ buf = (char *)__get_free_page(GFP_ATOMIC); @@ -2284,7 +2284,7 @@ void ll_dirty_page_discard_warn(struct page *page, int ioret) "%s: dirty page discard: %s/fid: " DFID "/%s may get corrupted (rc %d)\n", ll_get_fsname(page->mapping->host->i_sb, NULL, 0), s2lsi(page->mapping->host->i_sb)->lsi_lmd->lmd_dev, - PFID(&obj->cob_header.coh_lu.loh_fid), + PFID(&obj->vob_header.coh_lu.loh_fid), (path && !IS_ERR(path)) ? path : "", ioret); if (dentry) diff --git a/drivers/staging/lustre/lustre/llite/llite_mmap.c b/drivers/staging/lustre/lustre/llite/llite_mmap.c index baccf9379ca7..1263da85dd7f 100644 --- a/drivers/staging/lustre/lustre/llite/llite_mmap.c +++ b/drivers/staging/lustre/lustre/llite/llite_mmap.c @@ -200,7 +200,7 @@ static int ll_page_mkwrite0(struct vm_area_struct *vma, struct page *vmpage, * Otherwise, we could add dirty pages into osc cache * while truncate is on-going. */ - inode = ccc_object_inode(io->ci_obj); + inode = vvp_object_inode(io->ci_obj); lli = ll_i2info(inode); down_read(&lli->lli_trunc_sem); @@ -422,16 +422,16 @@ static int ll_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) /** * To avoid cancel the locks covering mmapped region for lock cache pressure, - * we track the mapped vma count in ccc_object::cob_mmap_cnt. + * we track the mapped vma count in vvp_object::vob_mmap_cnt. */ static void ll_vm_open(struct vm_area_struct *vma) { struct inode *inode = file_inode(vma->vm_file); - struct ccc_object *vob = cl_inode2ccc(inode); + struct vvp_object *vob = cl_inode2vvp(inode); LASSERT(vma->vm_file); - LASSERT(atomic_read(&vob->cob_mmap_cnt) >= 0); - atomic_inc(&vob->cob_mmap_cnt); + LASSERT(atomic_read(&vob->vob_mmap_cnt) >= 0); + atomic_inc(&vob->vob_mmap_cnt); } /** @@ -440,11 +440,11 @@ static void ll_vm_open(struct vm_area_struct *vma) static void ll_vm_close(struct vm_area_struct *vma) { struct inode *inode = file_inode(vma->vm_file); - struct ccc_object *vob = cl_inode2ccc(inode); + struct vvp_object *vob = cl_inode2vvp(inode); LASSERT(vma->vm_file); - atomic_dec(&vob->cob_mmap_cnt); - LASSERT(atomic_read(&vob->cob_mmap_cnt) >= 0); + atomic_dec(&vob->vob_mmap_cnt); + LASSERT(atomic_read(&vob->vob_mmap_cnt) >= 0); } /* XXX put nice comment here. talk about __free_pte -> dirty pages and diff --git a/drivers/staging/lustre/lustre/llite/rw.c b/drivers/staging/lustre/lustre/llite/rw.c index ad15058c2ddb..5ae0993c23dd 100644 --- a/drivers/staging/lustre/lustre/llite/rw.c +++ b/drivers/staging/lustre/lustre/llite/rw.c @@ -343,7 +343,7 @@ static int ll_read_ahead_page(const struct lu_env *env, struct cl_io *io, pgoff_t index, pgoff_t *max_index) { struct cl_object *clob = io->ci_obj; - struct inode *inode = ccc_object_inode(clob); + struct inode *inode = vvp_object_inode(clob); struct page *vmpage; struct cl_page *page; enum ra_stat which = _NR_RA_STAT; /* keep gcc happy */ @@ -558,7 +558,7 @@ int ll_readahead(const struct lu_env *env, struct cl_io *io, __u64 kms; clob = io->ci_obj; - inode = ccc_object_inode(clob); + inode = vvp_object_inode(clob); memset(ria, 0, sizeof(*ria)); diff --git a/drivers/staging/lustre/lustre/llite/rw26.c b/drivers/staging/lustre/lustre/llite/rw26.c index f87238b3373c..ec114bc1c2af 100644 --- a/drivers/staging/lustre/lustre/llite/rw26.c +++ b/drivers/staging/lustre/lustre/llite/rw26.c @@ -350,7 +350,7 @@ static ssize_t ll_direct_IO_26(struct kiocb *iocb, struct iov_iter *iter, struct cl_io *io; struct file *file = iocb->ki_filp; struct inode *inode = file->f_mapping->host; - struct ccc_object *obj = cl_inode2ccc(inode); + struct vvp_object *obj = cl_inode2vvp(inode); ssize_t count = iov_iter_count(iter); ssize_t tot_bytes = 0, result = 0; struct ll_inode_info *lli = ll_i2info(inode); @@ -386,7 +386,7 @@ static ssize_t ll_direct_IO_26(struct kiocb *iocb, struct iov_iter *iter, if (iov_iter_rw(iter) == READ) inode_lock(inode); - LASSERT(obj->cob_transient_pages == 0); + LASSERT(obj->vob_transient_pages == 0); while (iov_iter_count(iter)) { struct page **pages; size_t offs; @@ -434,7 +434,7 @@ static ssize_t ll_direct_IO_26(struct kiocb *iocb, struct iov_iter *iter, file_offset += result; } out: - LASSERT(obj->cob_transient_pages == 0); + LASSERT(obj->vob_transient_pages == 0); if (iov_iter_rw(iter) == READ) inode_unlock(inode); diff --git a/drivers/staging/lustre/lustre/llite/vvp_dev.c b/drivers/staging/lustre/lustre/llite/vvp_dev.c index e934ec87cf60..45c549cb4e53 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_dev.c +++ b/drivers/staging/lustre/lustre/llite/vvp_dev.c @@ -57,9 +57,15 @@ * "llite_" (var. "ll_") prefix. */ +struct kmem_cache *vvp_object_kmem; static struct kmem_cache *vvp_thread_kmem; static struct kmem_cache *vvp_session_kmem; static struct lu_kmem_descr vvp_caches[] = { + { + .ckd_cache = &vvp_object_kmem, + .ckd_name = "vvp_object_kmem", + .ckd_size = sizeof(struct vvp_object), + }, { .ckd_cache = &vvp_thread_kmem, .ckd_name = "vvp_thread_kmem", @@ -431,7 +437,7 @@ static loff_t vvp_pgcache_find(const struct lu_env *env, return ~0ULL; clob = vvp_pgcache_obj(env, dev, &id); if (clob) { - struct inode *inode = ccc_object_inode(clob); + struct inode *inode = vvp_object_inode(clob); struct page *vmpage; int nr; @@ -512,7 +518,7 @@ static int vvp_pgcache_show(struct seq_file *f, void *v) sbi = f->private; clob = vvp_pgcache_obj(env, &sbi->ll_cl->cd_lu_dev, &id); if (clob) { - struct inode *inode = ccc_object_inode(clob); + struct inode *inode = vvp_object_inode(clob); struct cl_page *page = NULL; struct page *vmpage; diff --git a/drivers/staging/lustre/lustre/llite/vvp_internal.h b/drivers/staging/lustre/lustre/llite/vvp_internal.h index 34509f9d889f..76e7b4c30af0 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_internal.h +++ b/drivers/staging/lustre/lustre/llite/vvp_internal.h @@ -128,6 +128,8 @@ int cl_is_normalio(const struct lu_env *env, const struct cl_io *io); extern struct lu_context_key ccc_key; extern struct lu_context_key ccc_session_key; +extern struct kmem_cache *vvp_object_kmem; + struct ccc_thread_info { struct cl_lock cti_lock; struct cl_lock_descr cti_descr; @@ -193,10 +195,10 @@ static inline struct ccc_io *ccc_env_io(const struct lu_env *env) /** * ccc-private object state. */ -struct ccc_object { - struct cl_object_header cob_header; - struct cl_object cob_cl; - struct inode *cob_inode; +struct vvp_object { + struct cl_object_header vob_header; + struct cl_object vob_cl; + struct inode *vob_inode; /** * A list of dirty pages pending IO in the cache. Used by @@ -204,24 +206,24 @@ struct ccc_object { * * \see ccc_page::cpg_pending_linkage */ - struct list_head cob_pending_list; + struct list_head vob_pending_list; /** * Access this counter is protected by inode->i_sem. Now that * the lifetime of transient pages must be covered by inode sem, * we don't need to hold any lock.. */ - int cob_transient_pages; + int vob_transient_pages; /** * Number of outstanding mmaps on this file. * * \see ll_vm_open(), ll_vm_close(). */ - atomic_t cob_mmap_cnt; + atomic_t vob_mmap_cnt; /** * various flags - * cob_discard_page_warned + * vob_discard_page_warned * if pages belonging to this object are discarded when a client * is evicted, some debug info will be printed, this flag will be set * during processing the first discarded page, then avoid flooding @@ -229,7 +231,7 @@ struct ccc_object { * * \see ll_dirty_page_discard_warn. */ - unsigned int cob_discard_page_warned:1; + unsigned int vob_discard_page_warned:1; }; /** @@ -242,8 +244,7 @@ struct ccc_page { int cpg_write_queued; /** * Non-empty iff this page is already counted in - * ccc_object::cob_pending_list. Protected by - * ccc_object::cob_pending_guard. This list is only used as a flag, + * vvp_object::vob_pending_list. This list is only used as a flag, * that is, never iterated through, only checked for list_empty(), but * having a list is useful for debugging. */ @@ -287,27 +288,14 @@ void *ccc_session_key_init(const struct lu_context *ctx, void ccc_session_key_fini(const struct lu_context *ctx, struct lu_context_key *key, void *data); -struct lu_object *ccc_object_alloc(const struct lu_env *env, - const struct lu_object_header *hdr, - struct lu_device *dev, - const struct cl_object_operations *clops, - const struct lu_object_operations *luops); - int ccc_req_init(const struct lu_env *env, struct cl_device *dev, struct cl_req *req); void ccc_umount(const struct lu_env *env, struct cl_device *dev); int ccc_global_init(struct lu_device_type *device_type); void ccc_global_fini(struct lu_device_type *device_type); -int ccc_object_init0(const struct lu_env *env, struct ccc_object *vob, - const struct cl_object_conf *conf); -int ccc_object_init(const struct lu_env *env, struct lu_object *obj, - const struct lu_object_conf *conf); -void ccc_object_free(const struct lu_env *env, struct lu_object *obj); int ccc_lock_init(const struct lu_env *env, struct cl_object *obj, struct cl_lock *lock, const struct cl_io *io, const struct cl_lock_operations *lkops); -int ccc_object_glimpse(const struct lu_env *env, - const struct cl_object *obj, struct ost_lvb *lvb); int ccc_fail(const struct lu_env *env, const struct cl_page_slice *slice); int ccc_transient_page_prep(const struct lu_env *env, const struct cl_page_slice *slice, @@ -354,20 +342,32 @@ static inline struct vvp_device *cl2vvp_dev(const struct cl_device *d) return container_of0(d, struct vvp_device, vdv_cl); } -struct lu_object *ccc2lu(struct ccc_object *vob); -struct ccc_object *lu2ccc(const struct lu_object *obj); -struct ccc_object *cl2ccc(const struct cl_object *obj); +static inline struct vvp_object *cl2vvp(const struct cl_object *obj) +{ + return container_of0(obj, struct vvp_object, vob_cl); +} + +static inline struct vvp_object *lu2vvp(const struct lu_object *obj) +{ + return container_of0(obj, struct vvp_object, vob_cl.co_lu); +} + +static inline struct inode *vvp_object_inode(const struct cl_object *obj) +{ + return cl2vvp(obj)->vob_inode; +} + +int vvp_object_invariant(const struct cl_object *obj); +struct vvp_object *cl_inode2vvp(struct inode *inode); + struct ccc_lock *cl2ccc_lock(const struct cl_lock_slice *slice); struct ccc_io *cl2ccc_io(const struct lu_env *env, const struct cl_io_slice *slice); struct ccc_req *cl2ccc_req(const struct cl_req_slice *slice); struct page *cl2vm_page(const struct cl_page_slice *slice); -struct inode *ccc_object_inode(const struct cl_object *obj); -struct ccc_object *cl_inode2ccc(struct inode *inode); int cl_setattr_ost(struct inode *inode, const struct iattr *attr); -int ccc_object_invariant(const struct cl_object *obj); int cl_file_inode_init(struct inode *inode, struct lustre_md *md); void cl_inode_fini(struct inode *inode); int cl_local_size(struct inode *inode); @@ -419,7 +419,6 @@ int vvp_page_init(const struct lu_env *env, struct cl_object *obj, struct lu_object *vvp_object_alloc(const struct lu_env *env, const struct lu_object_header *hdr, struct lu_device *dev); -struct ccc_object *cl_inode2ccc(struct inode *inode); extern const struct file_operations vvp_dump_pgcache_file_ops; diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c index fcf0cfe070ab..1773cb24f7b3 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_io.c +++ b/drivers/staging/lustre/lustre/llite/vvp_io.c @@ -127,7 +127,7 @@ static int vvp_io_fault_iter_init(const struct lu_env *env, const struct cl_io_slice *ios) { struct vvp_io *vio = cl2vvp_io(env, ios); - struct inode *inode = ccc_object_inode(ios->cis_obj); + struct inode *inode = vvp_object_inode(ios->cis_obj); LASSERT(inode == file_inode(cl2ccc_io(env, ios)->cui_fd->fd_file)); @@ -141,7 +141,7 @@ static void vvp_io_fini(const struct lu_env *env, const struct cl_io_slice *ios) struct cl_object *obj = io->ci_obj; struct ccc_io *cio = cl2ccc_io(env, ios); - CLOBINVRNT(env, obj, ccc_object_invariant(obj)); + CLOBINVRNT(env, obj, vvp_object_invariant(obj)); CDEBUG(D_VFSTRACE, DFID " ignore/verify layout %d/%d, layout version %d restore needed %d\n", @@ -155,7 +155,7 @@ static void vvp_io_fini(const struct lu_env *env, const struct cl_io_slice *ios) /* file was detected release, we need to restore it * before finishing the io */ - rc = ll_layout_restore(ccc_object_inode(obj)); + rc = ll_layout_restore(vvp_object_inode(obj)); /* if restore registration failed, no restart, * we will return -ENODATA */ @@ -181,7 +181,7 @@ static void vvp_io_fini(const struct lu_env *env, const struct cl_io_slice *ios) __u32 gen = 0; /* check layout version */ - ll_layout_refresh(ccc_object_inode(obj), &gen); + ll_layout_refresh(vvp_object_inode(obj), &gen); io->ci_need_restart = cio->cui_layout_gen != gen; if (io->ci_need_restart) { CDEBUG(D_VFSTRACE, @@ -190,7 +190,7 @@ static void vvp_io_fini(const struct lu_env *env, const struct cl_io_slice *ios) cio->cui_layout_gen, gen); /* today successful restore is the only possible case */ /* restore was done, clear restoring state */ - ll_i2info(ccc_object_inode(obj))->lli_flags &= + ll_i2info(vvp_object_inode(obj))->lli_flags &= ~LLIF_FILE_RESTORING; } } @@ -202,7 +202,7 @@ static void vvp_io_fault_fini(const struct lu_env *env, struct cl_io *io = ios->cis_io; struct cl_page *page = io->u.ci_fault.ft_page; - CLOBINVRNT(env, io->ci_obj, ccc_object_invariant(io->ci_obj)); + CLOBINVRNT(env, io->ci_obj, vvp_object_invariant(io->ci_obj)); if (page) { lu_ref_del(&page->cp_reference, "fault", io); @@ -459,7 +459,7 @@ static int vvp_io_setattr_start(const struct lu_env *env, const struct cl_io_slice *ios) { struct cl_io *io = ios->cis_io; - struct inode *inode = ccc_object_inode(io->ci_obj); + struct inode *inode = vvp_object_inode(io->ci_obj); int result = 0; inode_lock(inode); @@ -475,7 +475,7 @@ static void vvp_io_setattr_end(const struct lu_env *env, const struct cl_io_slice *ios) { struct cl_io *io = ios->cis_io; - struct inode *inode = ccc_object_inode(io->ci_obj); + struct inode *inode = vvp_object_inode(io->ci_obj); if (cl_io_is_trunc(io)) /* Truncate in memory pages - they must be clean pages @@ -499,7 +499,7 @@ static int vvp_io_read_start(const struct lu_env *env, struct ccc_io *cio = cl2ccc_io(env, ios); struct cl_io *io = ios->cis_io; struct cl_object *obj = io->ci_obj; - struct inode *inode = ccc_object_inode(obj); + struct inode *inode = vvp_object_inode(obj); struct ll_ra_read *bead = &vio->cui_bead; struct file *file = cio->cui_fd->fd_file; @@ -509,7 +509,7 @@ static int vvp_io_read_start(const struct lu_env *env, long tot = cio->cui_tot_count; int exceed = 0; - CLOBINVRNT(env, obj, ccc_object_invariant(obj)); + CLOBINVRNT(env, obj, vvp_object_invariant(obj)); CDEBUG(D_VFSTRACE, "read: -> [%lli, %lli)\n", pos, pos + cnt); @@ -653,7 +653,7 @@ static void write_commit_callback(const struct lu_env *env, struct cl_io *io, set_page_dirty(vmpage); cp = cl2ccc_page(cl_object_page_slice(clob, page)); - vvp_write_pending(cl2ccc(clob), cp); + vvp_write_pending(cl2vvp(clob), cp); cl_page_disown(env, io, page); @@ -690,7 +690,7 @@ static bool page_list_sanity_check(struct cl_object *obj, int vvp_io_write_commit(const struct lu_env *env, struct cl_io *io) { struct cl_object *obj = io->ci_obj; - struct inode *inode = ccc_object_inode(obj); + struct inode *inode = vvp_object_inode(obj); struct ccc_io *cio = ccc_env_io(env); struct cl_page_list *queue = &cio->u.write.cui_queue; struct cl_page *page; @@ -773,7 +773,7 @@ static int vvp_io_write_start(const struct lu_env *env, struct ccc_io *cio = cl2ccc_io(env, ios); struct cl_io *io = ios->cis_io; struct cl_object *obj = io->ci_obj; - struct inode *inode = ccc_object_inode(obj); + struct inode *inode = vvp_object_inode(obj); ssize_t result = 0; loff_t pos = io->u.ci_wr.wr.crw_pos; size_t cnt = io->u.ci_wr.wr.crw_count; @@ -874,7 +874,7 @@ static void mkwrite_commit_callback(const struct lu_env *env, struct cl_io *io, set_page_dirty(page->cp_vmpage); cp = cl2ccc_page(cl_object_page_slice(clob, page)); - vvp_write_pending(cl2ccc(clob), cp); + vvp_write_pending(cl2vvp(clob), cp); } static int vvp_io_fault_start(const struct lu_env *env, @@ -883,7 +883,7 @@ static int vvp_io_fault_start(const struct lu_env *env, struct vvp_io *vio = cl2vvp_io(env, ios); struct cl_io *io = ios->cis_io; struct cl_object *obj = io->ci_obj; - struct inode *inode = ccc_object_inode(obj); + struct inode *inode = vvp_object_inode(obj); struct cl_fault_io *fio = &io->u.ci_fault; struct vvp_fault_io *cfio = &vio->u.fault; loff_t offset; @@ -1060,7 +1060,7 @@ static int vvp_io_read_page(const struct lu_env *env, struct cl_io *io = ios->cis_io; struct ccc_page *cp = cl2ccc_page(slice); struct cl_page *page = slice->cpl_page; - struct inode *inode = ccc_object_inode(slice->cpl_obj); + struct inode *inode = vvp_object_inode(slice->cpl_obj); struct ll_sb_info *sbi = ll_i2sbi(inode); struct ll_file_data *fd = cl2ccc_io(env, ios)->cui_fd; struct ll_readahead_state *ras = &fd->fd_ras; @@ -1135,10 +1135,10 @@ int vvp_io_init(const struct lu_env *env, struct cl_object *obj, { struct vvp_io *vio = vvp_env_io(env); struct ccc_io *cio = ccc_env_io(env); - struct inode *inode = ccc_object_inode(obj); + struct inode *inode = vvp_object_inode(obj); int result; - CLOBINVRNT(env, obj, ccc_object_invariant(obj)); + CLOBINVRNT(env, obj, vvp_object_invariant(obj)); CDEBUG(D_VFSTRACE, DFID " ignore/verify layout %d/%d, layout version %d restore needed %d\n", diff --git a/drivers/staging/lustre/lustre/llite/vvp_object.c b/drivers/staging/lustre/lustre/llite/vvp_object.c index 45fac697cd3d..9f5e6a6a8f57 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_object.c +++ b/drivers/staging/lustre/lustre/llite/vvp_object.c @@ -54,16 +54,25 @@ * */ +int vvp_object_invariant(const struct cl_object *obj) +{ + struct inode *inode = vvp_object_inode(obj); + struct ll_inode_info *lli = ll_i2info(inode); + + return (S_ISREG(inode->i_mode) || inode->i_mode == 0) && + lli->lli_clob == obj; +} + static int vvp_object_print(const struct lu_env *env, void *cookie, lu_printer_t p, const struct lu_object *o) { - struct ccc_object *obj = lu2ccc(o); - struct inode *inode = obj->cob_inode; + struct vvp_object *obj = lu2vvp(o); + struct inode *inode = obj->vob_inode; struct ll_inode_info *lli; (*p)(env, cookie, "(%s %d %d) inode: %p ", - list_empty(&obj->cob_pending_list) ? "-" : "+", - obj->cob_transient_pages, atomic_read(&obj->cob_mmap_cnt), + list_empty(&obj->vob_pending_list) ? "-" : "+", + obj->vob_transient_pages, atomic_read(&obj->vob_mmap_cnt), inode); if (inode) { lli = ll_i2info(inode); @@ -78,7 +87,7 @@ static int vvp_object_print(const struct lu_env *env, void *cookie, static int vvp_attr_get(const struct lu_env *env, struct cl_object *obj, struct cl_attr *attr) { - struct inode *inode = ccc_object_inode(obj); + struct inode *inode = vvp_object_inode(obj); /* * lov overwrites most of these fields in @@ -100,7 +109,7 @@ static int vvp_attr_get(const struct lu_env *env, struct cl_object *obj, static int vvp_attr_set(const struct lu_env *env, struct cl_object *obj, const struct cl_attr *attr, unsigned valid) { - struct inode *inode = ccc_object_inode(obj); + struct inode *inode = vvp_object_inode(obj); if (valid & CAT_UID) inode->i_uid = make_kuid(&init_user_ns, attr->cat_uid); @@ -168,7 +177,7 @@ static int vvp_conf_set(const struct lu_env *env, struct cl_object *obj, static int vvp_prune(const struct lu_env *env, struct cl_object *obj) { - struct inode *inode = ccc_object_inode(obj); + struct inode *inode = vvp_object_inode(obj); int rc; rc = cl_sync_file_range(inode, 0, OBD_OBJECT_EOF, CL_FSYNC_LOCAL, 1); @@ -182,6 +191,24 @@ static int vvp_prune(const struct lu_env *env, struct cl_object *obj) return 0; } +static int vvp_object_glimpse(const struct lu_env *env, + const struct cl_object *obj, struct ost_lvb *lvb) +{ + struct inode *inode = vvp_object_inode(obj); + + lvb->lvb_mtime = LTIME_S(inode->i_mtime); + lvb->lvb_atime = LTIME_S(inode->i_atime); + lvb->lvb_ctime = LTIME_S(inode->i_ctime); + /* + * LU-417: Add dirty pages block count lest i_blocks reports 0, some + * "cp" or "tar" on remote node may think it's a completely sparse file + * and skip it. + */ + if (lvb->lvb_size > 0 && lvb->lvb_blocks == 0) + lvb->lvb_blocks = dirty_cnt(inode); + return 0; +} + static const struct cl_object_operations vvp_ops = { .coo_page_init = vvp_page_init, .coo_lock_init = vvp_lock_init, @@ -190,16 +217,60 @@ static const struct cl_object_operations vvp_ops = { .coo_attr_set = vvp_attr_set, .coo_conf_set = vvp_conf_set, .coo_prune = vvp_prune, - .coo_glimpse = ccc_object_glimpse + .coo_glimpse = vvp_object_glimpse }; +static int vvp_object_init0(const struct lu_env *env, + struct vvp_object *vob, + const struct cl_object_conf *conf) +{ + vob->vob_inode = conf->coc_inode; + vob->vob_transient_pages = 0; + cl_object_page_init(&vob->vob_cl, sizeof(struct ccc_page)); + return 0; +} + +static int vvp_object_init(const struct lu_env *env, struct lu_object *obj, + const struct lu_object_conf *conf) +{ + struct vvp_device *dev = lu2vvp_dev(obj->lo_dev); + struct vvp_object *vob = lu2vvp(obj); + struct lu_object *below; + struct lu_device *under; + int result; + + under = &dev->vdv_next->cd_lu_dev; + below = under->ld_ops->ldo_object_alloc(env, obj->lo_header, under); + if (below) { + const struct cl_object_conf *cconf; + + cconf = lu2cl_conf(conf); + INIT_LIST_HEAD(&vob->vob_pending_list); + lu_object_add(obj, below); + result = vvp_object_init0(env, vob, cconf); + } else { + result = -ENOMEM; + } + + return result; +} + +static void vvp_object_free(const struct lu_env *env, struct lu_object *obj) +{ + struct vvp_object *vob = lu2vvp(obj); + + lu_object_fini(obj); + lu_object_header_fini(obj->lo_header); + kmem_cache_free(vvp_object_kmem, vob); +} + static const struct lu_object_operations vvp_lu_obj_ops = { - .loo_object_init = ccc_object_init, - .loo_object_free = ccc_object_free, - .loo_object_print = vvp_object_print + .loo_object_init = vvp_object_init, + .loo_object_free = vvp_object_free, + .loo_object_print = vvp_object_print, }; -struct ccc_object *cl_inode2ccc(struct inode *inode) +struct vvp_object *cl_inode2vvp(struct inode *inode) { struct ll_inode_info *lli = ll_i2info(inode); struct cl_object *obj = lli->lli_clob; @@ -207,12 +278,32 @@ struct ccc_object *cl_inode2ccc(struct inode *inode) lu = lu_object_locate(obj->co_lu.lo_header, &vvp_device_type); LASSERT(lu); - return lu2ccc(lu); + return lu2vvp(lu); } struct lu_object *vvp_object_alloc(const struct lu_env *env, - const struct lu_object_header *hdr, + const struct lu_object_header *unused, struct lu_device *dev) { - return ccc_object_alloc(env, hdr, dev, &vvp_ops, &vvp_lu_obj_ops); + struct vvp_object *vob; + struct lu_object *obj; + + vob = kmem_cache_zalloc(vvp_object_kmem, GFP_NOFS); + if (vob) { + struct cl_object_header *hdr; + + obj = &vob->vob_cl.co_lu; + hdr = &vob->vob_header; + cl_object_header_init(hdr); + hdr->coh_page_bufsize = cfs_size_round(sizeof(struct cl_page)); + + lu_object_init(obj, &hdr->coh_lu, dev); + lu_object_add_top(&hdr->coh_lu, obj); + + vob->vob_cl.co_ops = &vvp_ops; + obj->lo_ops = &vvp_lu_obj_ops; + } else { + obj = NULL; + } + return obj; } diff --git a/drivers/staging/lustre/lustre/llite/vvp_page.c b/drivers/staging/lustre/lustre/llite/vvp_page.c index 66a4f9b0aa0b..419a535c79c9 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_page.c +++ b/drivers/staging/lustre/lustre/llite/vvp_page.c @@ -159,9 +159,9 @@ static void vvp_page_delete(const struct lu_env *env, LASSERT(PageLocked(vmpage)); LASSERT((struct cl_page *)vmpage->private == page); - LASSERT(inode == ccc_object_inode(obj)); + LASSERT(inode == vvp_object_inode(obj)); - vvp_write_complete(cl2ccc(obj), cl2ccc_page(slice)); + vvp_write_complete(cl2vvp(obj), cl2ccc_page(slice)); /* Drop the reference count held in vvp_page_init */ refc = atomic_dec_return(&page->cp_ref); @@ -220,7 +220,7 @@ static int vvp_page_prep_write(const struct lu_env *env, if (!pg->cp_sync_io) set_page_writeback(vmpage); - vvp_write_pending(cl2ccc(slice->cpl_obj), cl2ccc_page(slice)); + vvp_write_pending(cl2vvp(slice->cpl_obj), cl2ccc_page(slice)); return 0; } @@ -233,11 +233,11 @@ static int vvp_page_prep_write(const struct lu_env *env, */ static void vvp_vmpage_error(struct inode *inode, struct page *vmpage, int ioret) { - struct ccc_object *obj = cl_inode2ccc(inode); + struct vvp_object *obj = cl_inode2vvp(inode); if (ioret == 0) { ClearPageError(vmpage); - obj->cob_discard_page_warned = 0; + obj->vob_discard_page_warned = 0; } else { SetPageError(vmpage); if (ioret == -ENOSPC) @@ -246,8 +246,8 @@ static void vvp_vmpage_error(struct inode *inode, struct page *vmpage, int ioret set_bit(AS_EIO, &inode->i_mapping->flags); if ((ioret == -ESHUTDOWN || ioret == -EINTR) && - obj->cob_discard_page_warned == 0) { - obj->cob_discard_page_warned = 1; + obj->vob_discard_page_warned == 0) { + obj->vob_discard_page_warned = 1; ll_dirty_page_discard_warn(vmpage, ioret); } } @@ -260,7 +260,7 @@ static void vvp_page_completion_read(const struct lu_env *env, struct ccc_page *cp = cl2ccc_page(slice); struct page *vmpage = cp->cpg_page; struct cl_page *page = slice->cpl_page; - struct inode *inode = ccc_object_inode(page->cp_obj); + struct inode *inode = vvp_object_inode(page->cp_obj); LASSERT(PageLocked(vmpage)); CL_PAGE_HEADER(D_PAGE, env, page, "completing READ with %d\n", ioret); @@ -299,7 +299,7 @@ static void vvp_page_completion_write(const struct lu_env *env, */ cp->cpg_write_queued = 0; - vvp_write_complete(cl2ccc(slice->cpl_obj), cp); + vvp_write_complete(cl2vvp(slice->cpl_obj), cp); if (pg->cp_sync_io) { LASSERT(PageLocked(vmpage)); @@ -310,7 +310,7 @@ static void vvp_page_completion_write(const struct lu_env *env, * Only mark the page error only when it's an async write * because applications won't wait for IO to finish. */ - vvp_vmpage_error(ccc_object_inode(pg->cp_obj), vmpage, ioret); + vvp_vmpage_error(vvp_object_inode(pg->cp_obj), vmpage, ioret); end_page_writeback(vmpage); } @@ -342,7 +342,7 @@ static int vvp_page_make_ready(const struct lu_env *env, LASSERT(pg->cp_state == CPS_CACHED); /* This actually clears the dirty bit in the radix tree. */ set_page_writeback(vmpage); - vvp_write_pending(cl2ccc(slice->cpl_obj), cl2ccc_page(slice)); + vvp_write_pending(cl2vvp(slice->cpl_obj), cl2ccc_page(slice)); CL_PAGE_HEADER(D_PAGE, env, pg, "readied\n"); } else if (pg->cp_state == CPS_PAGEOUT) { /* is it possible for osc_flush_async_page() to already @@ -421,7 +421,7 @@ static const struct cl_page_operations vvp_page_ops = { static void vvp_transient_page_verify(const struct cl_page *page) { - struct inode *inode = ccc_object_inode(page->cp_obj); + struct inode *inode = vvp_object_inode(page->cp_obj); LASSERT(!inode_trylock(inode)); } @@ -472,7 +472,7 @@ static void vvp_transient_page_discard(const struct lu_env *env, static int vvp_transient_page_is_vmlocked(const struct lu_env *env, const struct cl_page_slice *slice) { - struct inode *inode = ccc_object_inode(slice->cpl_obj); + struct inode *inode = vvp_object_inode(slice->cpl_obj); int locked; locked = !inode_trylock(inode); @@ -494,11 +494,11 @@ static void vvp_transient_page_fini(const struct lu_env *env, { struct ccc_page *cp = cl2ccc_page(slice); struct cl_page *clp = slice->cpl_page; - struct ccc_object *clobj = cl2ccc(clp->cp_obj); + struct vvp_object *clobj = cl2vvp(clp->cp_obj); vvp_page_fini_common(cp); - LASSERT(!inode_trylock(clobj->cob_inode)); - clobj->cob_transient_pages--; + LASSERT(!inode_trylock(clobj->vob_inode)); + clobj->vob_transient_pages--; } static const struct cl_page_operations vvp_transient_page_ops = { @@ -529,7 +529,7 @@ int vvp_page_init(const struct lu_env *env, struct cl_object *obj, struct ccc_page *cpg = cl_object_page_slice(obj, page); struct page *vmpage = page->cp_vmpage; - CLOBINVRNT(env, obj, ccc_object_invariant(obj)); + CLOBINVRNT(env, obj, vvp_object_invariant(obj)); cpg->cpg_page = vmpage; page_cache_get(vmpage); @@ -543,12 +543,12 @@ int vvp_page_init(const struct lu_env *env, struct cl_object *obj, cl_page_slice_add(page, &cpg->cpg_cl, obj, index, &vvp_page_ops); } else { - struct ccc_object *clobj = cl2ccc(obj); + struct vvp_object *clobj = cl2vvp(obj); - LASSERT(!inode_trylock(clobj->cob_inode)); + LASSERT(!inode_trylock(clobj->vob_inode)); cl_page_slice_add(page, &cpg->cpg_cl, obj, index, &vvp_transient_page_ops); - clobj->cob_transient_pages++; + clobj->vob_transient_pages++; } return 0; } diff --git a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h index d6d7661ab5ad..aba646956900 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h +++ b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h @@ -135,7 +135,7 @@ struct osc_object { */ struct list_head oo_inflight[CRT_NR]; /** - * Lock, protecting ccc_object::cob_inflight, because a seat-belt is + * Lock, protecting osc_page::ops_inflight, because a seat-belt is * locked during take-off and landing. */ spinlock_t oo_seatbelt; -- cgit v1.2.3 From 3a52f803382541569f30f225d6f868a36b4c3014 Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Wed, 30 Mar 2016 19:48:48 -0400 Subject: staging/lustre/llite: rename ccc_page to vvp_page Rename struct ccc_page to struct vvp_page and remove obsolete CCC page methods. Signed-off-by: John L. Hammond Reviewed-on: http://review.whamcloud.com/13086 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5971 Reviewed-by: James Simmons Reviewed-by: Jinshan Xiong Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/cl_object.h | 2 +- drivers/staging/lustre/lustre/llite/lcommon_cl.c | 28 ------ drivers/staging/lustre/lustre/llite/llite_close.c | 12 +-- .../staging/lustre/lustre/llite/llite_internal.h | 4 +- drivers/staging/lustre/lustre/llite/rw.c | 14 +-- drivers/staging/lustre/lustre/llite/rw26.c | 10 +- drivers/staging/lustre/lustre/llite/vvp_dev.c | 12 +-- drivers/staging/lustre/lustre/llite/vvp_internal.h | 38 ++++---- drivers/staging/lustre/lustre/llite/vvp_io.c | 34 +++---- drivers/staging/lustre/lustre/llite/vvp_object.c | 2 +- drivers/staging/lustre/lustre/llite/vvp_page.c | 107 +++++++++++++-------- 11 files changed, 131 insertions(+), 132 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h index d3271ffe17da..3488349d8087 100644 --- a/drivers/staging/lustre/lustre/include/cl_object.h +++ b/drivers/staging/lustre/lustre/include/cl_object.h @@ -769,7 +769,7 @@ struct cl_page { /** * Per-layer part of cl_page. * - * \see ccc_page, lov_page, osc_page + * \see vvp_page, lov_page, osc_page */ struct cl_page_slice { struct cl_page *cpl_page; diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c b/drivers/staging/lustre/lustre/llite/lcommon_cl.c index 9db0510d2693..07620326081d 100644 --- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c +++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c @@ -257,29 +257,6 @@ static void vvp_object_size_unlock(struct cl_object *obj) ll_inode_size_unlock(inode); } -/***************************************************************************** - * - * Page operations. - * - */ - -int ccc_fail(const struct lu_env *env, const struct cl_page_slice *slice) -{ - /* - * Cached read? - */ - LBUG(); - return 0; -} - -int ccc_transient_page_prep(const struct lu_env *env, - const struct cl_page_slice *slice, - struct cl_io *unused) -{ - /* transient page should always be sent. */ - return 0; -} - /***************************************************************************** * * Lock operations. @@ -614,11 +591,6 @@ struct ccc_req *cl2ccc_req(const struct cl_req_slice *slice) return container_of0(slice, struct ccc_req, crq_cl); } -struct page *cl2vm_page(const struct cl_page_slice *slice) -{ - return cl2ccc_page(slice)->cpg_page; -} - /** * Initialize or update CLIO structures for regular files when new * meta-data arrives from the server. diff --git a/drivers/staging/lustre/lustre/llite/llite_close.c b/drivers/staging/lustre/lustre/llite/llite_close.c index 6e99d341112f..8d2398003c5a 100644 --- a/drivers/staging/lustre/lustre/llite/llite_close.c +++ b/drivers/staging/lustre/lustre/llite/llite_close.c @@ -46,26 +46,26 @@ #include "llite_internal.h" /** records that a write is in flight */ -void vvp_write_pending(struct vvp_object *club, struct ccc_page *page) +void vvp_write_pending(struct vvp_object *club, struct vvp_page *page) { struct ll_inode_info *lli = ll_i2info(club->vob_inode); spin_lock(&lli->lli_lock); lli->lli_flags |= LLIF_SOM_DIRTY; - if (page && list_empty(&page->cpg_pending_linkage)) - list_add(&page->cpg_pending_linkage, &club->vob_pending_list); + if (page && list_empty(&page->vpg_pending_linkage)) + list_add(&page->vpg_pending_linkage, &club->vob_pending_list); spin_unlock(&lli->lli_lock); } /** records that a write has completed */ -void vvp_write_complete(struct vvp_object *club, struct ccc_page *page) +void vvp_write_complete(struct vvp_object *club, struct vvp_page *page) { struct ll_inode_info *lli = ll_i2info(club->vob_inode); int rc = 0; spin_lock(&lli->lli_lock); - if (page && !list_empty(&page->cpg_pending_linkage)) { - list_del_init(&page->cpg_pending_linkage); + if (page && !list_empty(&page->vpg_pending_linkage)) { + list_del_init(&page->vpg_pending_linkage); rc = 1; } spin_unlock(&lli->lli_lock); diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index 1c39d15f34f5..78b3eddcc715 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -828,8 +828,8 @@ struct ll_close_queue { atomic_t lcq_stop; }; -void vvp_write_pending(struct vvp_object *club, struct ccc_page *page); -void vvp_write_complete(struct vvp_object *club, struct ccc_page *page); +void vvp_write_pending(struct vvp_object *club, struct vvp_page *page); +void vvp_write_complete(struct vvp_object *club, struct vvp_page *page); /* specific architecture can implement only part of this list */ enum vvp_io_subtype { diff --git a/drivers/staging/lustre/lustre/llite/rw.c b/drivers/staging/lustre/lustre/llite/rw.c index 5ae0993c23dd..2c4d4c40b407 100644 --- a/drivers/staging/lustre/lustre/llite/rw.c +++ b/drivers/staging/lustre/lustre/llite/rw.c @@ -298,21 +298,21 @@ static int cl_read_ahead_page(const struct lu_env *env, struct cl_io *io, struct cl_object *clob, pgoff_t *max_index) { struct page *vmpage = page->cp_vmpage; - struct ccc_page *cp; + struct vvp_page *vpg; int rc; rc = 0; cl_page_assume(env, io, page); lu_ref_add(&page->cp_reference, "ra", current); - cp = cl2ccc_page(cl_object_page_slice(clob, page)); - if (!cp->cpg_defer_uptodate && !PageUptodate(vmpage)) { + vpg = cl2vvp_page(cl_object_page_slice(clob, page)); + if (!vpg->vpg_defer_uptodate && !PageUptodate(vmpage)) { CDEBUG(D_READA, "page index %lu, max_index: %lu\n", - ccc_index(cp), *max_index); - if (*max_index == 0 || ccc_index(cp) > *max_index) + vvp_index(vpg), *max_index); + if (*max_index == 0 || vvp_index(vpg) > *max_index) rc = cl_page_is_under_lock(env, io, page, max_index); if (rc == 0) { - cp->cpg_defer_uptodate = 1; - cp->cpg_ra_used = 0; + vpg->vpg_defer_uptodate = 1; + vpg->vpg_ra_used = 0; cl_page_list_add(queue, page); rc = 1; } else { diff --git a/drivers/staging/lustre/lustre/llite/rw26.c b/drivers/staging/lustre/lustre/llite/rw26.c index ec114bc1c2af..bb85629dd105 100644 --- a/drivers/staging/lustre/lustre/llite/rw26.c +++ b/drivers/staging/lustre/lustre/llite/rw26.c @@ -457,8 +457,8 @@ static int ll_prepare_partial_page(const struct lu_env *env, struct cl_io *io, { struct cl_attr *attr = ccc_env_thread_attr(env); struct cl_object *obj = io->ci_obj; - struct ccc_page *cp = cl_object_page_slice(obj, pg); - loff_t offset = cl_offset(obj, ccc_index(cp)); + struct vvp_page *vpg = cl_object_page_slice(obj, pg); + loff_t offset = cl_offset(obj, vvp_index(vpg)); int result; cl_object_attr_lock(obj); @@ -471,12 +471,12 @@ static int ll_prepare_partial_page(const struct lu_env *env, struct cl_io *io, * purposes here we can treat it like i_size. */ if (attr->cat_kms <= offset) { - char *kaddr = kmap_atomic(cp->cpg_page); + char *kaddr = kmap_atomic(vpg->vpg_page); memset(kaddr, 0, cl_page_size(obj)); kunmap_atomic(kaddr); - } else if (cp->cpg_defer_uptodate) { - cp->cpg_ra_used = 1; + } else if (vpg->vpg_defer_uptodate) { + vpg->vpg_ra_used = 1; } else { result = ll_page_sync_io(env, io, pg, CRT_READ); } diff --git a/drivers/staging/lustre/lustre/llite/vvp_dev.c b/drivers/staging/lustre/lustre/llite/vvp_dev.c index 45c549cb4e53..3891b0d694a6 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_dev.c +++ b/drivers/staging/lustre/lustre/llite/vvp_dev.c @@ -474,18 +474,18 @@ static loff_t vvp_pgcache_find(const struct lu_env *env, static void vvp_pgcache_page_show(const struct lu_env *env, struct seq_file *seq, struct cl_page *page) { - struct ccc_page *cpg; + struct vvp_page *vpg; struct page *vmpage; int has_flags; - cpg = cl2ccc_page(cl_page_at(page, &vvp_device_type)); - vmpage = cpg->cpg_page; + vpg = cl2vvp_page(cl_page_at(page, &vvp_device_type)); + vmpage = vpg->vpg_page; seq_printf(seq, " %5i | %p %p %s %s %s %s | %p %lu/%u(%p) %lu %u [", 0 /* gen */, - cpg, page, + vpg, page, "none", - cpg->cpg_write_queued ? "wq" : "- ", - cpg->cpg_defer_uptodate ? "du" : "- ", + vpg->vpg_write_queued ? "wq" : "- ", + vpg->vpg_defer_uptodate ? "du" : "- ", PageWriteback(vmpage) ? "wb" : "-", vmpage, vmpage->mapping->host->i_ino, vmpage->mapping->host->i_generation, diff --git a/drivers/staging/lustre/lustre/llite/vvp_internal.h b/drivers/staging/lustre/lustre/llite/vvp_internal.h index 76e7b4c30af0..4991ce75e590 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_internal.h +++ b/drivers/staging/lustre/lustre/llite/vvp_internal.h @@ -204,7 +204,7 @@ struct vvp_object { * A list of dirty pages pending IO in the cache. Used by * SOM. Protected by ll_inode_info::lli_lock. * - * \see ccc_page::cpg_pending_linkage + * \see vvp_page::vpg_pending_linkage */ struct list_head vob_pending_list; @@ -235,36 +235,34 @@ struct vvp_object { }; /** - * ccc-private page state. + * VVP-private page state. */ -struct ccc_page { - struct cl_page_slice cpg_cl; - int cpg_defer_uptodate; - int cpg_ra_used; - int cpg_write_queued; +struct vvp_page { + struct cl_page_slice vpg_cl; + int vpg_defer_uptodate; + int vpg_ra_used; + int vpg_write_queued; /** * Non-empty iff this page is already counted in * vvp_object::vob_pending_list. This list is only used as a flag, * that is, never iterated through, only checked for list_empty(), but * having a list is useful for debugging. */ - struct list_head cpg_pending_linkage; + struct list_head vpg_pending_linkage; /** VM page */ - struct page *cpg_page; + struct page *vpg_page; }; -static inline struct ccc_page *cl2ccc_page(const struct cl_page_slice *slice) +static inline struct vvp_page *cl2vvp_page(const struct cl_page_slice *slice) { - return container_of(slice, struct ccc_page, cpg_cl); + return container_of(slice, struct vvp_page, vpg_cl); } -static inline pgoff_t ccc_index(struct ccc_page *ccc) +static inline pgoff_t vvp_index(struct vvp_page *vvp) { - return ccc->cpg_cl.cpl_index; + return vvp->vpg_cl.cpl_index; } -struct cl_page *ccc_vmpage_page_transient(struct page *vmpage); - struct vvp_device { struct cl_device vdv_cl; struct super_block *vdv_sb; @@ -296,10 +294,6 @@ void ccc_global_fini(struct lu_device_type *device_type); int ccc_lock_init(const struct lu_env *env, struct cl_object *obj, struct cl_lock *lock, const struct cl_io *io, const struct cl_lock_operations *lkops); -int ccc_fail(const struct lu_env *env, const struct cl_page_slice *slice); -int ccc_transient_page_prep(const struct lu_env *env, - const struct cl_page_slice *slice, - struct cl_io *io); void ccc_lock_delete(const struct lu_env *env, const struct cl_lock_slice *slice); void ccc_lock_fini(const struct lu_env *env, struct cl_lock_slice *slice); @@ -360,11 +354,15 @@ static inline struct inode *vvp_object_inode(const struct cl_object *obj) int vvp_object_invariant(const struct cl_object *obj); struct vvp_object *cl_inode2vvp(struct inode *inode); +static inline struct page *cl2vm_page(const struct cl_page_slice *slice) +{ + return cl2vvp_page(slice)->vpg_page; +} + struct ccc_lock *cl2ccc_lock(const struct cl_lock_slice *slice); struct ccc_io *cl2ccc_io(const struct lu_env *env, const struct cl_io_slice *slice); struct ccc_req *cl2ccc_req(const struct cl_req_slice *slice); -struct page *cl2vm_page(const struct cl_page_slice *slice); int cl_setattr_ost(struct inode *inode, const struct iattr *attr); diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c index 1773cb24f7b3..eb6ce1c68fd0 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_io.c +++ b/drivers/staging/lustre/lustre/llite/vvp_io.c @@ -645,15 +645,15 @@ static int vvp_io_commit_sync(const struct lu_env *env, struct cl_io *io, static void write_commit_callback(const struct lu_env *env, struct cl_io *io, struct cl_page *page) { - struct ccc_page *cp; + struct vvp_page *vpg; struct page *vmpage = page->cp_vmpage; struct cl_object *clob = cl_io_top(io)->ci_obj; SetPageUptodate(vmpage); set_page_dirty(vmpage); - cp = cl2ccc_page(cl_object_page_slice(clob, page)); - vvp_write_pending(cl2vvp(clob), cp); + vpg = cl2vvp_page(cl_object_page_slice(clob, page)); + vvp_write_pending(cl2vvp(clob), vpg); cl_page_disown(env, io, page); @@ -670,15 +670,15 @@ static bool page_list_sanity_check(struct cl_object *obj, pgoff_t index = CL_PAGE_EOF; cl_page_list_for_each(page, plist) { - struct ccc_page *cp = cl_object_page_slice(obj, page); + struct vvp_page *vpg = cl_object_page_slice(obj, page); if (index == CL_PAGE_EOF) { - index = ccc_index(cp); + index = vvp_index(vpg); continue; } ++index; - if (index == ccc_index(cp)) + if (index == vvp_index(vpg)) continue; return false; @@ -868,13 +868,13 @@ static int vvp_io_kernel_fault(struct vvp_fault_io *cfio) static void mkwrite_commit_callback(const struct lu_env *env, struct cl_io *io, struct cl_page *page) { - struct ccc_page *cp; + struct vvp_page *vpg; struct cl_object *clob = cl_io_top(io)->ci_obj; set_page_dirty(page->cp_vmpage); - cp = cl2ccc_page(cl_object_page_slice(clob, page)); - vvp_write_pending(cl2vvp(clob), cp); + vpg = cl2vvp_page(cl_object_page_slice(clob, page)); + vvp_write_pending(cl2vvp(clob), vpg); } static int vvp_io_fault_start(const struct lu_env *env, @@ -979,7 +979,7 @@ static int vvp_io_fault_start(const struct lu_env *env, wait_on_page_writeback(vmpage); if (!PageDirty(vmpage)) { struct cl_page_list *plist = &io->ci_queue.c2_qin; - struct ccc_page *cp = cl_object_page_slice(obj, page); + struct vvp_page *vpg = cl_object_page_slice(obj, page); int to = PAGE_SIZE; /* vvp_page_assume() calls wait_on_page_writeback(). */ @@ -989,7 +989,7 @@ static int vvp_io_fault_start(const struct lu_env *env, cl_page_list_add(plist, page); /* size fixup */ - if (last_index == ccc_index(cp)) + if (last_index == vvp_index(vpg)) to = size & ~PAGE_MASK; /* Do not set Dirty bit here so that in case IO is @@ -1058,7 +1058,7 @@ static int vvp_io_read_page(const struct lu_env *env, const struct cl_page_slice *slice) { struct cl_io *io = ios->cis_io; - struct ccc_page *cp = cl2ccc_page(slice); + struct vvp_page *vpg = cl2vvp_page(slice); struct cl_page *page = slice->cpl_page; struct inode *inode = vvp_object_inode(slice->cpl_obj); struct ll_sb_info *sbi = ll_i2sbi(inode); @@ -1068,11 +1068,11 @@ static int vvp_io_read_page(const struct lu_env *env, if (sbi->ll_ra_info.ra_max_pages_per_file && sbi->ll_ra_info.ra_max_pages) - ras_update(sbi, inode, ras, ccc_index(cp), - cp->cpg_defer_uptodate); + ras_update(sbi, inode, ras, vvp_index(vpg), + vpg->vpg_defer_uptodate); - if (cp->cpg_defer_uptodate) { - cp->cpg_ra_used = 1; + if (vpg->vpg_defer_uptodate) { + vpg->vpg_ra_used = 1; cl_page_export(env, page, 1); } /* @@ -1084,7 +1084,7 @@ static int vvp_io_read_page(const struct lu_env *env, if (sbi->ll_ra_info.ra_max_pages_per_file && sbi->ll_ra_info.ra_max_pages) ll_readahead(env, io, &queue->c2_qin, ras, - cp->cpg_defer_uptodate); + vpg->vpg_defer_uptodate); return 0; } diff --git a/drivers/staging/lustre/lustre/llite/vvp_object.c b/drivers/staging/lustre/lustre/llite/vvp_object.c index 9f5e6a6a8f57..18c9df7ebdda 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_object.c +++ b/drivers/staging/lustre/lustre/llite/vvp_object.c @@ -226,7 +226,7 @@ static int vvp_object_init0(const struct lu_env *env, { vob->vob_inode = conf->coc_inode; vob->vob_transient_pages = 0; - cl_object_page_init(&vob->vob_cl, sizeof(struct ccc_page)); + cl_object_page_init(&vob->vob_cl, sizeof(struct vvp_page)); return 0; } diff --git a/drivers/staging/lustre/lustre/llite/vvp_page.c b/drivers/staging/lustre/lustre/llite/vvp_page.c index 419a535c79c9..5ebbe27104f1 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_page.c +++ b/drivers/staging/lustre/lustre/llite/vvp_page.c @@ -41,7 +41,13 @@ #define DEBUG_SUBSYSTEM S_LLITE -#include "../include/obd.h" +#include +#include +#include +#include +#include +#include + #include "../include/lustre_lite.h" #include "llite_internal.h" @@ -53,9 +59,9 @@ * */ -static void vvp_page_fini_common(struct ccc_page *cp) +static void vvp_page_fini_common(struct vvp_page *vpg) { - struct page *vmpage = cp->cpg_page; + struct page *vmpage = vpg->vpg_page; LASSERT(vmpage); page_cache_release(vmpage); @@ -64,23 +70,23 @@ static void vvp_page_fini_common(struct ccc_page *cp) static void vvp_page_fini(const struct lu_env *env, struct cl_page_slice *slice) { - struct ccc_page *cp = cl2ccc_page(slice); - struct page *vmpage = cp->cpg_page; + struct vvp_page *vpg = cl2vvp_page(slice); + struct page *vmpage = vpg->vpg_page; /* * vmpage->private was already cleared when page was moved into * VPG_FREEING state. */ LASSERT((struct cl_page *)vmpage->private != slice->cpl_page); - vvp_page_fini_common(cp); + vvp_page_fini_common(vpg); } static int vvp_page_own(const struct lu_env *env, const struct cl_page_slice *slice, struct cl_io *io, int nonblock) { - struct ccc_page *vpg = cl2ccc_page(slice); - struct page *vmpage = vpg->cpg_page; + struct vvp_page *vpg = cl2vvp_page(slice); + struct page *vmpage = vpg->vpg_page; LASSERT(vmpage); if (nonblock) { @@ -97,6 +103,7 @@ static int vvp_page_own(const struct lu_env *env, lock_page(vmpage); wait_on_page_writeback(vmpage); + return 0; } @@ -137,12 +144,12 @@ static void vvp_page_discard(const struct lu_env *env, struct cl_io *unused) { struct page *vmpage = cl2vm_page(slice); - struct ccc_page *cpg = cl2ccc_page(slice); + struct vvp_page *vpg = cl2vvp_page(slice); LASSERT(vmpage); LASSERT(PageLocked(vmpage)); - if (cpg->cpg_defer_uptodate && !cpg->cpg_ra_used) + if (vpg->vpg_defer_uptodate && !vpg->vpg_ra_used) ll_ra_stats_inc(vmpage->mapping->host, RA_STAT_DISCARDED); ll_invalidate_page(vmpage); @@ -161,7 +168,7 @@ static void vvp_page_delete(const struct lu_env *env, LASSERT((struct cl_page *)vmpage->private == page); LASSERT(inode == vvp_object_inode(obj)); - vvp_write_complete(cl2vvp(obj), cl2ccc_page(slice)); + vvp_write_complete(cl2vvp(obj), cl2vvp_page(slice)); /* Drop the reference count held in vvp_page_init */ refc = atomic_dec_return(&page->cp_ref); @@ -220,7 +227,7 @@ static int vvp_page_prep_write(const struct lu_env *env, if (!pg->cp_sync_io) set_page_writeback(vmpage); - vvp_write_pending(cl2vvp(slice->cpl_obj), cl2ccc_page(slice)); + vvp_write_pending(cl2vvp(slice->cpl_obj), cl2vvp_page(slice)); return 0; } @@ -257,22 +264,23 @@ static void vvp_page_completion_read(const struct lu_env *env, const struct cl_page_slice *slice, int ioret) { - struct ccc_page *cp = cl2ccc_page(slice); - struct page *vmpage = cp->cpg_page; + struct vvp_page *vpg = cl2vvp_page(slice); + struct page *vmpage = vpg->vpg_page; struct cl_page *page = slice->cpl_page; struct inode *inode = vvp_object_inode(page->cp_obj); LASSERT(PageLocked(vmpage)); CL_PAGE_HEADER(D_PAGE, env, page, "completing READ with %d\n", ioret); - if (cp->cpg_defer_uptodate) + if (vpg->vpg_defer_uptodate) ll_ra_count_put(ll_i2sbi(inode), 1); if (ioret == 0) { - if (!cp->cpg_defer_uptodate) + if (!vpg->vpg_defer_uptodate) cl_page_export(env, page, 1); - } else - cp->cpg_defer_uptodate = 0; + } else { + vpg->vpg_defer_uptodate = 0; + } if (!page->cp_sync_io) unlock_page(vmpage); @@ -282,9 +290,9 @@ static void vvp_page_completion_write(const struct lu_env *env, const struct cl_page_slice *slice, int ioret) { - struct ccc_page *cp = cl2ccc_page(slice); + struct vvp_page *vpg = cl2vvp_page(slice); struct cl_page *pg = slice->cpl_page; - struct page *vmpage = cp->cpg_page; + struct page *vmpage = vpg->vpg_page; CL_PAGE_HEADER(D_PAGE, env, pg, "completing WRITE with %d\n", ioret); @@ -298,8 +306,8 @@ static void vvp_page_completion_write(const struct lu_env *env, * and then re-add the page into pending transfer queue. -jay */ - cp->cpg_write_queued = 0; - vvp_write_complete(cl2vvp(slice->cpl_obj), cp); + vpg->vpg_write_queued = 0; + vvp_write_complete(cl2vvp(slice->cpl_obj), vpg); if (pg->cp_sync_io) { LASSERT(PageLocked(vmpage)); @@ -342,7 +350,7 @@ static int vvp_page_make_ready(const struct lu_env *env, LASSERT(pg->cp_state == CPS_CACHED); /* This actually clears the dirty bit in the radix tree. */ set_page_writeback(vmpage); - vvp_write_pending(cl2vvp(slice->cpl_obj), cl2ccc_page(slice)); + vvp_write_pending(cl2vvp(slice->cpl_obj), cl2vvp_page(slice)); CL_PAGE_HEADER(D_PAGE, env, pg, "readied\n"); } else if (pg->cp_state == CPS_PAGEOUT) { /* is it possible for osc_flush_async_page() to already @@ -376,12 +384,12 @@ static int vvp_page_print(const struct lu_env *env, const struct cl_page_slice *slice, void *cookie, lu_printer_t printer) { - struct ccc_page *vp = cl2ccc_page(slice); - struct page *vmpage = vp->cpg_page; + struct vvp_page *vpg = cl2vvp_page(slice); + struct page *vmpage = vpg->vpg_page; (*printer)(env, cookie, LUSTRE_VVP_NAME "-page@%p(%d:%d:%d) vm@%p ", - vp, vp->cpg_defer_uptodate, vp->cpg_ra_used, - vp->cpg_write_queued, vmpage); + vpg, vpg->vpg_defer_uptodate, vpg->vpg_ra_used, + vpg->vpg_write_queued, vmpage); if (vmpage) { (*printer)(env, cookie, "%lx %d:%d %lx %lu %slru", (long)vmpage->flags, page_count(vmpage), @@ -389,7 +397,20 @@ static int vvp_page_print(const struct lu_env *env, page_index(vmpage), list_empty(&vmpage->lru) ? "not-" : ""); } + (*printer)(env, cookie, "\n"); + + return 0; +} + +static int vvp_page_fail(const struct lu_env *env, + const struct cl_page_slice *slice) +{ + /* + * Cached read? + */ + LBUG(); + return 0; } @@ -409,16 +430,24 @@ static const struct cl_page_operations vvp_page_ops = { [CRT_READ] = { .cpo_prep = vvp_page_prep_read, .cpo_completion = vvp_page_completion_read, - .cpo_make_ready = ccc_fail, + .cpo_make_ready = vvp_page_fail, }, [CRT_WRITE] = { .cpo_prep = vvp_page_prep_write, .cpo_completion = vvp_page_completion_write, .cpo_make_ready = vvp_page_make_ready, - } - } + }, + }, }; +static int vvp_transient_page_prep(const struct lu_env *env, + const struct cl_page_slice *slice, + struct cl_io *unused) +{ + /* transient page should always be sent. */ + return 0; +} + static void vvp_transient_page_verify(const struct cl_page *page) { struct inode *inode = vvp_object_inode(page->cp_obj); @@ -492,11 +521,11 @@ vvp_transient_page_completion(const struct lu_env *env, static void vvp_transient_page_fini(const struct lu_env *env, struct cl_page_slice *slice) { - struct ccc_page *cp = cl2ccc_page(slice); + struct vvp_page *vpg = cl2vvp_page(slice); struct cl_page *clp = slice->cpl_page; struct vvp_object *clobj = cl2vvp(clp->cp_obj); - vvp_page_fini_common(cp); + vvp_page_fini_common(vpg); LASSERT(!inode_trylock(clobj->vob_inode)); clobj->vob_transient_pages--; } @@ -513,11 +542,11 @@ static const struct cl_page_operations vvp_transient_page_ops = { .cpo_is_under_lock = vvp_page_is_under_lock, .io = { [CRT_READ] = { - .cpo_prep = ccc_transient_page_prep, + .cpo_prep = vvp_transient_page_prep, .cpo_completion = vvp_transient_page_completion, }, [CRT_WRITE] = { - .cpo_prep = ccc_transient_page_prep, + .cpo_prep = vvp_transient_page_prep, .cpo_completion = vvp_transient_page_completion, } } @@ -526,27 +555,27 @@ static const struct cl_page_operations vvp_transient_page_ops = { int vvp_page_init(const struct lu_env *env, struct cl_object *obj, struct cl_page *page, pgoff_t index) { - struct ccc_page *cpg = cl_object_page_slice(obj, page); + struct vvp_page *vpg = cl_object_page_slice(obj, page); struct page *vmpage = page->cp_vmpage; CLOBINVRNT(env, obj, vvp_object_invariant(obj)); - cpg->cpg_page = vmpage; + vpg->vpg_page = vmpage; page_cache_get(vmpage); - INIT_LIST_HEAD(&cpg->cpg_pending_linkage); + INIT_LIST_HEAD(&vpg->vpg_pending_linkage); if (page->cp_type == CPT_CACHEABLE) { /* in cache, decref in vvp_page_delete */ atomic_inc(&page->cp_ref); SetPagePrivate(vmpage); vmpage->private = (unsigned long)page; - cl_page_slice_add(page, &cpg->cpg_cl, obj, index, + cl_page_slice_add(page, &vpg->vpg_cl, obj, index, &vvp_page_ops); } else { struct vvp_object *clobj = cl2vvp(obj); LASSERT(!inode_trylock(clobj->vob_inode)); - cl_page_slice_add(page, &cpg->cpg_cl, obj, index, + cl_page_slice_add(page, &vpg->vpg_cl, obj, index, &vvp_transient_page_ops); clobj->vob_transient_pages++; } -- cgit v1.2.3 From 4a4eee07f3f579e9ebc5b5db35214c3ada5c1378 Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Wed, 30 Mar 2016 19:48:49 -0400 Subject: staging/lustre/llite: rename ccc_lock to vvp_lock Rename struct ccc_lock to struct vvp_lock and merge the CCC lock methods into the VVP lock methods. Signed-off-by: John L. Hammond Reviewed-on: http://review.whamcloud.com/13088 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5971 Reviewed-by: James Simmons Reviewed-by: Jinshan Xiong Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/cl_object.h | 6 +-- drivers/staging/lustre/lustre/llite/lcommon_cl.c | 52 ---------------------- drivers/staging/lustre/lustre/llite/vvp_dev.c | 6 +++ drivers/staging/lustre/lustre/llite/vvp_internal.h | 20 ++++----- drivers/staging/lustre/lustre/llite/vvp_lock.c | 38 +++++++++++++--- 5 files changed, 50 insertions(+), 72 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h index 3488349d8087..d509f9407abc 100644 --- a/drivers/staging/lustre/lustre/include/cl_object.h +++ b/drivers/staging/lustre/lustre/include/cl_object.h @@ -1227,7 +1227,7 @@ struct cl_lock { /** * Per-layer part of cl_lock * - * \see ccc_lock, lov_lock, lovsub_lock, osc_lock + * \see vvp_lock, lov_lock, lovsub_lock, osc_lock */ struct cl_lock_slice { struct cl_lock *cls_lock; @@ -1254,7 +1254,7 @@ struct cl_lock_operations { * @anchor for resources * \retval -ve failure * - * \see ccc_lock_enqueue(), lov_lock_enqueue(), lovsub_lock_enqueue(), + * \see vvp_lock_enqueue(), lov_lock_enqueue(), lovsub_lock_enqueue(), * \see osc_lock_enqueue() */ int (*clo_enqueue)(const struct lu_env *env, @@ -1270,7 +1270,7 @@ struct cl_lock_operations { /** * Destructor. Frees resources and the slice. * - * \see ccc_lock_fini(), lov_lock_fini(), lovsub_lock_fini(), + * \see vvp_lock_fini(), lov_lock_fini(), lovsub_lock_fini(), * \see osc_lock_fini() */ void (*clo_fini)(const struct lu_env *env, struct cl_lock_slice *slice); diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c b/drivers/staging/lustre/lustre/llite/lcommon_cl.c index 07620326081d..88843170b3e6 100644 --- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c +++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c @@ -67,17 +67,11 @@ static const struct cl_req_operations ccc_req_ops; * ccc_ prefix stands for "Common Client Code". */ -static struct kmem_cache *ccc_lock_kmem; static struct kmem_cache *ccc_thread_kmem; static struct kmem_cache *ccc_session_kmem; static struct kmem_cache *ccc_req_kmem; static struct lu_kmem_descr ccc_caches[] = { - { - .ckd_cache = &ccc_lock_kmem, - .ckd_name = "ccc_lock_kmem", - .ckd_size = sizeof(struct ccc_lock) - }, { .ckd_cache = &ccc_thread_kmem, .ckd_name = "ccc_thread_kmem", @@ -221,26 +215,6 @@ void ccc_global_fini(struct lu_device_type *device_type) lu_kmem_fini(ccc_caches); } -int ccc_lock_init(const struct lu_env *env, - struct cl_object *obj, struct cl_lock *lock, - const struct cl_io *unused, - const struct cl_lock_operations *lkops) -{ - struct ccc_lock *clk; - int result; - - CLOBINVRNT(env, obj, vvp_object_invariant(obj)); - - clk = kmem_cache_zalloc(ccc_lock_kmem, GFP_NOFS); - if (clk) { - cl_lock_slice_add(lock, &clk->clk_cl, obj, lkops); - result = 0; - } else { - result = -ENOMEM; - } - return result; -} - static void vvp_object_size_lock(struct cl_object *obj) { struct inode *inode = vvp_object_inode(obj); @@ -257,27 +231,6 @@ static void vvp_object_size_unlock(struct cl_object *obj) ll_inode_size_unlock(inode); } -/***************************************************************************** - * - * Lock operations. - * - */ - -void ccc_lock_fini(const struct lu_env *env, struct cl_lock_slice *slice) -{ - struct ccc_lock *clk = cl2ccc_lock(slice); - - kmem_cache_free(ccc_lock_kmem, clk); -} - -int ccc_lock_enqueue(const struct lu_env *env, - const struct cl_lock_slice *slice, - struct cl_io *unused, struct cl_sync_io *anchor) -{ - CLOBINVRNT(env, slice->cls_obj, vvp_object_invariant(slice->cls_obj)); - return 0; -} - /***************************************************************************** * * io operations. @@ -571,11 +524,6 @@ again: * */ -struct ccc_lock *cl2ccc_lock(const struct cl_lock_slice *slice) -{ - return container_of(slice, struct ccc_lock, clk_cl); -} - struct ccc_io *cl2ccc_io(const struct lu_env *env, const struct cl_io_slice *slice) { diff --git a/drivers/staging/lustre/lustre/llite/vvp_dev.c b/drivers/staging/lustre/lustre/llite/vvp_dev.c index 3891b0d694a6..4b77db34f516 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_dev.c +++ b/drivers/staging/lustre/lustre/llite/vvp_dev.c @@ -57,10 +57,16 @@ * "llite_" (var. "ll_") prefix. */ +struct kmem_cache *vvp_lock_kmem; struct kmem_cache *vvp_object_kmem; static struct kmem_cache *vvp_thread_kmem; static struct kmem_cache *vvp_session_kmem; static struct lu_kmem_descr vvp_caches[] = { + { + .ckd_cache = &vvp_lock_kmem, + .ckd_name = "vvp_lock_kmem", + .ckd_size = sizeof(struct vvp_lock), + }, { .ckd_cache = &vvp_object_kmem, .ckd_name = "vvp_object_kmem", diff --git a/drivers/staging/lustre/lustre/llite/vvp_internal.h b/drivers/staging/lustre/lustre/llite/vvp_internal.h index 4991ce75e590..403d2a7ba0af 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_internal.h +++ b/drivers/staging/lustre/lustre/llite/vvp_internal.h @@ -128,6 +128,7 @@ int cl_is_normalio(const struct lu_env *env, const struct cl_io *io); extern struct lu_context_key ccc_key; extern struct lu_context_key ccc_session_key; +extern struct kmem_cache *vvp_lock_kmem; extern struct kmem_cache *vvp_object_kmem; struct ccc_thread_info { @@ -269,8 +270,8 @@ struct vvp_device { struct cl_device *vdv_next; }; -struct ccc_lock { - struct cl_lock_slice clk_cl; +struct vvp_lock { + struct cl_lock_slice vlk_cl; }; struct ccc_req { @@ -291,15 +292,6 @@ int ccc_req_init(const struct lu_env *env, struct cl_device *dev, void ccc_umount(const struct lu_env *env, struct cl_device *dev); int ccc_global_init(struct lu_device_type *device_type); void ccc_global_fini(struct lu_device_type *device_type); -int ccc_lock_init(const struct lu_env *env, struct cl_object *obj, - struct cl_lock *lock, const struct cl_io *io, - const struct cl_lock_operations *lkops); -void ccc_lock_delete(const struct lu_env *env, - const struct cl_lock_slice *slice); -void ccc_lock_fini(const struct lu_env *env, struct cl_lock_slice *slice); -int ccc_lock_enqueue(const struct lu_env *env, - const struct cl_lock_slice *slice, - struct cl_io *io, struct cl_sync_io *anchor); int ccc_io_one_lock_index(const struct lu_env *env, struct cl_io *io, __u32 enqflags, enum cl_lock_mode mode, @@ -359,7 +351,11 @@ static inline struct page *cl2vm_page(const struct cl_page_slice *slice) return cl2vvp_page(slice)->vpg_page; } -struct ccc_lock *cl2ccc_lock(const struct cl_lock_slice *slice); +static inline struct vvp_lock *cl2vvp_lock(const struct cl_lock_slice *slice) +{ + return container_of(slice, struct vvp_lock, vlk_cl); +} + struct ccc_io *cl2ccc_io(const struct lu_env *env, const struct cl_io_slice *slice); struct ccc_req *cl2ccc_req(const struct cl_req_slice *slice); diff --git a/drivers/staging/lustre/lustre/llite/vvp_lock.c b/drivers/staging/lustre/lustre/llite/vvp_lock.c index 8c505a6052b2..f5bd6c22e112 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_lock.c +++ b/drivers/staging/lustre/lustre/llite/vvp_lock.c @@ -40,7 +40,7 @@ #define DEBUG_SUBSYSTEM S_LLITE -#include "../include/obd.h" +#include "../include/obd_support.h" #include "../include/lustre_lite.h" #include "vvp_internal.h" @@ -51,13 +51,41 @@ * */ +static void vvp_lock_fini(const struct lu_env *env, struct cl_lock_slice *slice) +{ + struct vvp_lock *vlk = cl2vvp_lock(slice); + + kmem_cache_free(vvp_lock_kmem, vlk); +} + +static int vvp_lock_enqueue(const struct lu_env *env, + const struct cl_lock_slice *slice, + struct cl_io *unused, struct cl_sync_io *anchor) +{ + CLOBINVRNT(env, slice->cls_obj, vvp_object_invariant(slice->cls_obj)); + + return 0; +} + static const struct cl_lock_operations vvp_lock_ops = { - .clo_fini = ccc_lock_fini, - .clo_enqueue = ccc_lock_enqueue + .clo_fini = vvp_lock_fini, + .clo_enqueue = vvp_lock_enqueue, }; int vvp_lock_init(const struct lu_env *env, struct cl_object *obj, - struct cl_lock *lock, const struct cl_io *io) + struct cl_lock *lock, const struct cl_io *unused) { - return ccc_lock_init(env, obj, lock, io, &vvp_lock_ops); + struct vvp_lock *vlk; + int result; + + CLOBINVRNT(env, obj, vvp_object_invariant(obj)); + + vlk = kmem_cache_zalloc(vvp_lock_kmem, GFP_NOFS); + if (vlk) { + cl_lock_slice_add(lock, &vlk->vlk_cl, obj, &vvp_lock_ops); + result = 0; + } else { + result = -ENOMEM; + } + return result; } -- cgit v1.2.3 From bc4320a9186ccace8887eac930b574491ae886c0 Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Wed, 30 Mar 2016 19:48:50 -0400 Subject: staging/lustre:llite: remove struct ll_ra_read Ever since removal of the the unused function ll_ra_read_get(), the struct ll_ra_read members lrr_reader and lrr_linkage and the struct ll_readahead_state member ras_read_beads unnecessary so remove them. In struct vvp_io replace the struct ll_ra_read cui_bead member with cui_ra_start and cui_ra_count. Signed-off-by: John L. Hammond Reviewed-on: http://review.whamcloud.com/13347 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5971 Reviewed-by: Bobi Jam Reviewed-by: Lai Siyao Reviewed-by: Jinshan Xiong Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- .../staging/lustre/lustre/llite/llite_internal.h | 30 +++--------- drivers/staging/lustre/lustre/llite/rw.c | 53 ++++++---------------- drivers/staging/lustre/lustre/llite/vvp_io.c | 31 ++++--------- 3 files changed, 28 insertions(+), 86 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index 78b3eddcc715..9dd4325e8e00 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -528,13 +528,6 @@ struct ll_sb_info { struct completion ll_kobj_unregister; }; -struct ll_ra_read { - pgoff_t lrr_start; - pgoff_t lrr_count; - struct task_struct *lrr_reader; - struct list_head lrr_linkage; -}; - /* * per file-descriptor read-ahead data. */ @@ -592,12 +585,6 @@ struct ll_readahead_state { * will not be accurate when dealing with reads issued via mmap. */ unsigned long ras_request_index; - /* - * list of struct ll_ra_read's one per read(2) call current in - * progress against this file descriptor. Used by read-ahead code, - * protected by ->ras_lock. - */ - struct list_head ras_read_beads; /* * The following 3 items are used for detecting the stride I/O * mode. @@ -666,8 +653,7 @@ static inline int ll_need_32bit_api(struct ll_sb_info *sbi) #endif } -void ll_ra_read_in(struct file *f, struct ll_ra_read *rar); -void ll_ra_read_ex(struct file *f, struct ll_ra_read *rar); +void ll_ras_enter(struct file *f); /* llite/lproc_llite.c */ int ldebugfs_register_mountpoint(struct dentry *parent, @@ -876,14 +862,12 @@ struct vvp_io { } fault; } fault; } u; - /** - * Read-ahead state used by read and page-fault IO contexts. - */ - struct ll_ra_read cui_bead; - /** - * Set when cui_bead has been initialized. - */ - int cui_ra_window_set; + + /* Readahead state. */ + pgoff_t cui_ra_start; + pgoff_t cui_ra_count; + /* Set when cui_ra_{start,count} have been initialized. */ + bool cui_ra_valid; }; /** diff --git a/drivers/staging/lustre/lustre/llite/rw.c b/drivers/staging/lustre/lustre/llite/rw.c index 2c4d4c40b407..f06d8be2c9ea 100644 --- a/drivers/staging/lustre/lustre/llite/rw.c +++ b/drivers/staging/lustre/lustre/llite/rw.c @@ -258,38 +258,15 @@ static int index_in_window(unsigned long index, unsigned long point, return start <= index && index <= end; } -static struct ll_readahead_state *ll_ras_get(struct file *f) +void ll_ras_enter(struct file *f) { - struct ll_file_data *fd; - - fd = LUSTRE_FPRIVATE(f); - return &fd->fd_ras; -} - -void ll_ra_read_in(struct file *f, struct ll_ra_read *rar) -{ - struct ll_readahead_state *ras; - - ras = ll_ras_get(f); + struct ll_file_data *fd = LUSTRE_FPRIVATE(f); + struct ll_readahead_state *ras = &fd->fd_ras; spin_lock(&ras->ras_lock); ras->ras_requests++; ras->ras_request_index = 0; ras->ras_consecutive_requests++; - rar->lrr_reader = current; - - list_add(&rar->lrr_linkage, &ras->ras_read_beads); - spin_unlock(&ras->ras_lock); -} - -void ll_ra_read_ex(struct file *f, struct ll_ra_read *rar) -{ - struct ll_readahead_state *ras; - - ras = ll_ras_get(f); - - spin_lock(&ras->ras_lock); - list_del_init(&rar->lrr_linkage); spin_unlock(&ras->ras_lock); } @@ -551,7 +528,6 @@ int ll_readahead(const struct lu_env *env, struct cl_io *io, unsigned long start = 0, end = 0, reserved; unsigned long ra_end, len, mlen = 0; struct inode *inode; - struct ll_ra_read *bead; struct ra_io_arg *ria = &vti->vti_ria; struct cl_object *clob; int ret = 0; @@ -575,17 +551,15 @@ int ll_readahead(const struct lu_env *env, struct cl_io *io, } spin_lock(&ras->ras_lock); - if (vio->cui_ra_window_set) - bead = &vio->cui_bead; - else - bead = NULL; /* Enlarge the RA window to encompass the full read */ - if (bead && ras->ras_window_start + ras->ras_window_len < - bead->lrr_start + bead->lrr_count) { - ras->ras_window_len = bead->lrr_start + bead->lrr_count - + if (vio->cui_ra_valid && + ras->ras_window_start + ras->ras_window_len < + vio->cui_ra_start + vio->cui_ra_count) { + ras->ras_window_len = vio->cui_ra_start + vio->cui_ra_count - ras->ras_window_start; } + /* Reserve a part of the read-ahead window that we'll be issuing */ if (ras->ras_window_len) { start = ras->ras_next_readahead; @@ -641,15 +615,15 @@ int ll_readahead(const struct lu_env *env, struct cl_io *io, CDEBUG(D_READA, DFID ": ria: %lu/%lu, bead: %lu/%lu, hit: %d\n", PFID(lu_object_fid(&clob->co_lu)), ria->ria_start, ria->ria_end, - !bead ? 0 : bead->lrr_start, - !bead ? 0 : bead->lrr_count, + vio->cui_ra_valid ? vio->cui_ra_start : 0, + vio->cui_ra_valid ? vio->cui_ra_count : 0, hit); /* at least to extend the readahead window to cover current read */ - if (!hit && bead && - bead->lrr_start + bead->lrr_count > ria->ria_start) { + if (!hit && vio->cui_ra_valid && + vio->cui_ra_start + vio->cui_ra_count > ria->ria_start) { /* to the end of current read window. */ - mlen = bead->lrr_start + bead->lrr_count - ria->ria_start; + mlen = vio->cui_ra_start + vio->cui_ra_count - ria->ria_start; /* trim to RPC boundary */ start = ria->ria_start & (PTLRPC_MAX_BRW_PAGES - 1); mlen = min(mlen, PTLRPC_MAX_BRW_PAGES - start); @@ -730,7 +704,6 @@ void ll_readahead_init(struct inode *inode, struct ll_readahead_state *ras) spin_lock_init(&ras->ras_lock); ras_reset(inode, ras, 0); ras->ras_requests = 0; - INIT_LIST_HEAD(&ras->ras_read_beads); } /* diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c index eb6ce1c68fd0..86e73d512a91 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_io.c +++ b/drivers/staging/lustre/lustre/llite/vvp_io.c @@ -500,7 +500,6 @@ static int vvp_io_read_start(const struct lu_env *env, struct cl_io *io = ios->cis_io; struct cl_object *obj = io->ci_obj; struct inode *inode = vvp_object_inode(obj); - struct ll_ra_read *bead = &vio->cui_bead; struct file *file = cio->cui_fd->fd_file; int result; @@ -530,14 +529,11 @@ static int vvp_io_read_start(const struct lu_env *env, cio->cui_fd->fd_file->f_ra.ra_pages = 0; /* initialize read-ahead window once per syscall */ - if (!vio->cui_ra_window_set) { - vio->cui_ra_window_set = 1; - bead->lrr_start = cl_index(obj, pos); - /* - * XXX: explicit PAGE_CACHE_SIZE - */ - bead->lrr_count = cl_index(obj, tot + PAGE_CACHE_SIZE - 1); - ll_ra_read_in(file, bead); + if (!vio->cui_ra_valid) { + vio->cui_ra_valid = true; + vio->cui_ra_start = cl_index(obj, pos); + vio->cui_ra_count = cl_index(obj, tot + PAGE_CACHE_SIZE - 1); + ll_ras_enter(file); } /* BUG: 5972 */ @@ -574,17 +570,6 @@ out: return result; } -static void vvp_io_read_fini(const struct lu_env *env, const struct cl_io_slice *ios) -{ - struct vvp_io *vio = cl2vvp_io(env, ios); - struct ccc_io *cio = cl2ccc_io(env, ios); - - if (vio->cui_ra_window_set) - ll_ra_read_ex(cio->cui_fd->fd_file, &vio->cui_bead); - - vvp_io_fini(env, ios); -} - static int vvp_io_commit_sync(const struct lu_env *env, struct cl_io *io, struct cl_page_list *plist, int from, int to) { @@ -1092,10 +1077,10 @@ static int vvp_io_read_page(const struct lu_env *env, static const struct cl_io_operations vvp_io_ops = { .op = { [CIT_READ] = { - .cio_fini = vvp_io_read_fini, + .cio_fini = vvp_io_fini, .cio_lock = vvp_io_read_lock, .cio_start = vvp_io_read_start, - .cio_advance = ccc_io_advance + .cio_advance = ccc_io_advance, }, [CIT_WRITE] = { .cio_fini = vvp_io_fini, @@ -1148,7 +1133,7 @@ int vvp_io_init(const struct lu_env *env, struct cl_object *obj, CL_IO_SLICE_CLEAN(cio, cui_cl); cl_io_slice_add(io, &cio->cui_cl, obj, &vvp_io_ops); - vio->cui_ra_window_set = 0; + vio->cui_ra_valid = false; result = 0; if (io->ci_type == CIT_READ || io->ci_type == CIT_WRITE) { size_t count; -- cgit v1.2.3 From 10cdef73396c816e9844e467558c2f87776fc11f Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Wed, 30 Mar 2016 19:48:51 -0400 Subject: staging/lustre/llite: merge ccc_io and vvp_io Move the contents of struct vvp_io into struct ccc_io, delete the former, and rename the latter to struct vvp_io. Rename various ccc_io related functions to use vvp rather than ccc. Signed-off-by: John L. Hammond Reviewed-on: http://review.whamcloud.com/13351 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5971 Reviewed-by: Lai Siyao Reviewed-by: Jinshan Xiong Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/cl_object.h | 2 +- drivers/staging/lustre/lustre/llite/file.c | 13 ++- drivers/staging/lustre/lustre/llite/lcommon_cl.c | 60 +++--------- .../staging/lustre/lustre/llite/llite_internal.h | 72 --------------- drivers/staging/lustre/lustre/llite/llite_mmap.c | 12 +-- drivers/staging/lustre/lustre/llite/rw.c | 4 +- drivers/staging/lustre/lustre/llite/rw26.c | 10 +- drivers/staging/lustre/lustre/llite/vvp_dev.c | 2 +- drivers/staging/lustre/lustre/llite/vvp_internal.h | 81 +++++++++++++---- drivers/staging/lustre/lustre/llite/vvp_io.c | 101 ++++++++++----------- drivers/staging/lustre/lustre/llite/vvp_page.c | 2 +- 11 files changed, 144 insertions(+), 215 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h index d509f9407abc..104dc9f15efb 100644 --- a/drivers/staging/lustre/lustre/include/cl_object.h +++ b/drivers/staging/lustre/lustre/include/cl_object.h @@ -1461,7 +1461,7 @@ enum cl_io_state { * This is usually embedded into layer session data, rather than allocated * dynamically. * - * \see vvp_io, lov_io, osc_io, ccc_io + * \see vvp_io, lov_io, osc_io */ struct cl_io_slice { struct cl_io *cis_io; diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index bf2a5ee1e687..27e7e65b3a98 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -1135,14 +1135,13 @@ restart: ll_io_init(io, file, iot == CIT_WRITE); if (cl_io_rw_init(env, io, iot, *ppos, count) == 0) { - struct vvp_io *vio = vvp_env_io(env); - struct ccc_io *cio = ccc_env_io(env); + struct vvp_io *cio = vvp_env_io(env); int write_mutex_locked = 0; cio->cui_fd = LUSTRE_FPRIVATE(file); - vio->cui_io_subtype = args->via_io_subtype; + cio->cui_io_subtype = args->via_io_subtype; - switch (vio->cui_io_subtype) { + switch (cio->cui_io_subtype) { case IO_NORMAL: cio->cui_iter = args->u.normal.via_iter; cio->cui_iocb = args->u.normal.via_iocb; @@ -1158,11 +1157,11 @@ restart: down_read(&lli->lli_trunc_sem); break; case IO_SPLICE: - vio->u.splice.cui_pipe = args->u.splice.via_pipe; - vio->u.splice.cui_flags = args->u.splice.via_flags; + cio->u.splice.cui_pipe = args->u.splice.via_pipe; + cio->u.splice.cui_flags = args->u.splice.via_flags; break; default: - CERROR("Unknown IO type - %u\n", vio->cui_io_subtype); + CERROR("Unknown IO type - %u\n", cio->cui_io_subtype); LBUG(); } result = cl_io_loop(env, io); diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c b/drivers/staging/lustre/lustre/llite/lcommon_cl.c index 88843170b3e6..9a9d7061fff0 100644 --- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c +++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c @@ -68,7 +68,6 @@ static const struct cl_req_operations ccc_req_ops; */ static struct kmem_cache *ccc_thread_kmem; -static struct kmem_cache *ccc_session_kmem; static struct kmem_cache *ccc_req_kmem; static struct lu_kmem_descr ccc_caches[] = { @@ -77,11 +76,6 @@ static struct lu_kmem_descr ccc_caches[] = { .ckd_name = "ccc_thread_kmem", .ckd_size = sizeof(struct ccc_thread_info), }, - { - .ckd_cache = &ccc_session_kmem, - .ckd_name = "ccc_session_kmem", - .ckd_size = sizeof(struct ccc_session) - }, { .ckd_cache = &ccc_req_kmem, .ckd_name = "ccc_req_kmem", @@ -116,37 +110,12 @@ void ccc_key_fini(const struct lu_context *ctx, kmem_cache_free(ccc_thread_kmem, info); } -void *ccc_session_key_init(const struct lu_context *ctx, - struct lu_context_key *key) -{ - struct ccc_session *session; - - session = kmem_cache_zalloc(ccc_session_kmem, GFP_NOFS); - if (!session) - session = ERR_PTR(-ENOMEM); - return session; -} - -void ccc_session_key_fini(const struct lu_context *ctx, - struct lu_context_key *key, void *data) -{ - struct ccc_session *session = data; - - kmem_cache_free(ccc_session_kmem, session); -} - struct lu_context_key ccc_key = { .lct_tags = LCT_CL_THREAD, .lct_init = ccc_key_init, .lct_fini = ccc_key_fini }; -struct lu_context_key ccc_session_key = { - .lct_tags = LCT_SESSION, - .lct_init = ccc_session_key_init, - .lct_fini = ccc_session_key_fini -}; - int ccc_req_init(const struct lu_env *env, struct cl_device *dev, struct cl_req *req) { @@ -237,11 +206,11 @@ static void vvp_object_size_unlock(struct cl_object *obj) * */ -int ccc_io_one_lock_index(const struct lu_env *env, struct cl_io *io, +int vvp_io_one_lock_index(const struct lu_env *env, struct cl_io *io, __u32 enqflags, enum cl_lock_mode mode, pgoff_t start, pgoff_t end) { - struct ccc_io *cio = ccc_env_io(env); + struct vvp_io *cio = vvp_env_io(env); struct cl_lock_descr *descr = &cio->cui_link.cill_descr; struct cl_object *obj = io->ci_obj; @@ -266,8 +235,8 @@ int ccc_io_one_lock_index(const struct lu_env *env, struct cl_io *io, return 0; } -void ccc_io_update_iov(const struct lu_env *env, - struct ccc_io *cio, struct cl_io *io) +void vvp_io_update_iov(const struct lu_env *env, + struct vvp_io *cio, struct cl_io *io) { size_t size = io->u.ci_rw.crw_count; @@ -277,27 +246,27 @@ void ccc_io_update_iov(const struct lu_env *env, iov_iter_truncate(cio->cui_iter, size); } -int ccc_io_one_lock(const struct lu_env *env, struct cl_io *io, +int vvp_io_one_lock(const struct lu_env *env, struct cl_io *io, __u32 enqflags, enum cl_lock_mode mode, loff_t start, loff_t end) { struct cl_object *obj = io->ci_obj; - return ccc_io_one_lock_index(env, io, enqflags, mode, + return vvp_io_one_lock_index(env, io, enqflags, mode, cl_index(obj, start), cl_index(obj, end)); } -void ccc_io_end(const struct lu_env *env, const struct cl_io_slice *ios) +void vvp_io_end(const struct lu_env *env, const struct cl_io_slice *ios) { CLOBINVRNT(env, ios->cis_io->ci_obj, vvp_object_invariant(ios->cis_io->ci_obj)); } -void ccc_io_advance(const struct lu_env *env, +void vvp_io_advance(const struct lu_env *env, const struct cl_io_slice *ios, size_t nob) { - struct ccc_io *cio = cl2ccc_io(env, ios); + struct vvp_io *cio = cl2vvp_io(env, ios); struct cl_io *io = ios->cis_io; struct cl_object *obj = ios->cis_io->ci_obj; @@ -492,7 +461,7 @@ int cl_setattr_ost(struct inode *inode, const struct iattr *attr) again: if (cl_io_init(env, io, CIT_SETATTR, io->ci_obj) == 0) { - struct ccc_io *cio = ccc_env_io(env); + struct vvp_io *cio = vvp_env_io(env); if (attr->ia_valid & ATTR_FILE) /* populate the file descriptor for ftruncate to honor @@ -524,13 +493,14 @@ again: * */ -struct ccc_io *cl2ccc_io(const struct lu_env *env, +struct vvp_io *cl2vvp_io(const struct lu_env *env, const struct cl_io_slice *slice) { - struct ccc_io *cio; + struct vvp_io *cio; + + cio = container_of(slice, struct vvp_io, cui_cl); + LASSERT(cio == vvp_env_io(env)); - cio = container_of(slice, struct ccc_io, cui_cl); - LASSERT(cio == ccc_env_io(env)); return cio; } diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index 9dd4325e8e00..9856bb6daf15 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -817,59 +817,6 @@ struct ll_close_queue { void vvp_write_pending(struct vvp_object *club, struct vvp_page *page); void vvp_write_complete(struct vvp_object *club, struct vvp_page *page); -/* specific architecture can implement only part of this list */ -enum vvp_io_subtype { - /** normal IO */ - IO_NORMAL, - /** io started from splice_{read|write} */ - IO_SPLICE -}; - -/* IO subtypes */ -struct vvp_io { - /** io subtype */ - enum vvp_io_subtype cui_io_subtype; - - union { - struct { - struct pipe_inode_info *cui_pipe; - unsigned int cui_flags; - } splice; - struct vvp_fault_io { - /** - * Inode modification time that is checked across DLM - * lock request. - */ - time64_t ft_mtime; - struct vm_area_struct *ft_vma; - /** - * locked page returned from vvp_io - */ - struct page *ft_vmpage; - struct vm_fault_api { - /** - * kernel fault info - */ - struct vm_fault *ft_vmf; - /** - * fault API used bitflags for return code. - */ - unsigned int ft_flags; - /** - * check that flags are from filemap_fault - */ - bool ft_flags_valid; - } fault; - } fault; - } u; - - /* Readahead state. */ - pgoff_t cui_ra_start; - pgoff_t cui_ra_count; - /* Set when cui_ra_{start,count} have been initialized. */ - bool cui_ra_valid; -}; - /** * IO arguments for various VFS I/O interfaces. */ @@ -923,25 +870,6 @@ static inline struct vvp_io_args *vvp_env_args(const struct lu_env *env, return ret; } -struct vvp_session { - struct vvp_io vs_ios; -}; - -static inline struct vvp_session *vvp_env_session(const struct lu_env *env) -{ - extern struct lu_context_key vvp_session_key; - struct vvp_session *ses; - - ses = lu_context_key_get(env->le_ses, &vvp_session_key); - LASSERT(ses); - return ses; -} - -static inline struct vvp_io *vvp_env_io(const struct lu_env *env) -{ - return &vvp_env_session(env)->vs_ios; -} - int vvp_global_init(void); void vvp_global_fini(void); diff --git a/drivers/staging/lustre/lustre/llite/llite_mmap.c b/drivers/staging/lustre/lustre/llite/llite_mmap.c index 1263da85dd7f..7c214f8a1e71 100644 --- a/drivers/staging/lustre/lustre/llite/llite_mmap.c +++ b/drivers/staging/lustre/lustre/llite/llite_mmap.c @@ -146,7 +146,7 @@ ll_fault_io_init(struct vm_area_struct *vma, struct lu_env **env_ret, rc = cl_io_init(env, io, CIT_FAULT, io->ci_obj); if (rc == 0) { - struct ccc_io *cio = ccc_env_io(env); + struct vvp_io *cio = vvp_env_io(env); struct ll_file_data *fd = LUSTRE_FPRIVATE(file); LASSERT(cio->cui_cl.cis_io == io); @@ -307,17 +307,17 @@ static int ll_fault0(struct vm_area_struct *vma, struct vm_fault *vmf) vio = vvp_env_io(env); vio->u.fault.ft_vma = vma; vio->u.fault.ft_vmpage = NULL; - vio->u.fault.fault.ft_vmf = vmf; - vio->u.fault.fault.ft_flags = 0; - vio->u.fault.fault.ft_flags_valid = false; + vio->u.fault.ft_vmf = vmf; + vio->u.fault.ft_flags = 0; + vio->u.fault.ft_flags_valid = false; result = cl_io_loop(env, io); /* ft_flags are only valid if we reached * the call to filemap_fault */ - if (vio->u.fault.fault.ft_flags_valid) - fault_ret = vio->u.fault.fault.ft_flags; + if (vio->u.fault.ft_flags_valid) + fault_ret = vio->u.fault.ft_flags; vmpage = vio->u.fault.ft_vmpage; if (result != 0 && vmpage) { diff --git a/drivers/staging/lustre/lustre/llite/rw.c b/drivers/staging/lustre/lustre/llite/rw.c index f06d8be2c9ea..da4410712f83 100644 --- a/drivers/staging/lustre/lustre/llite/rw.c +++ b/drivers/staging/lustre/lustre/llite/rw.c @@ -90,7 +90,7 @@ struct ll_cl_context *ll_cl_init(struct file *file, struct page *vmpage) struct lu_env *env; struct cl_io *io; struct cl_object *clob; - struct ccc_io *cio; + struct vvp_io *cio; int refcheck; int result = 0; @@ -108,7 +108,7 @@ struct ll_cl_context *ll_cl_init(struct file *file, struct page *vmpage) lcc->lcc_refcheck = refcheck; lcc->lcc_cookie = current; - cio = ccc_env_io(env); + cio = vvp_env_io(env); io = cio->cui_cl.cis_io; lcc->lcc_io = io; if (!io) { diff --git a/drivers/staging/lustre/lustre/llite/rw26.c b/drivers/staging/lustre/lustre/llite/rw26.c index bb85629dd105..2f69634376f9 100644 --- a/drivers/staging/lustre/lustre/llite/rw26.c +++ b/drivers/staging/lustre/lustre/llite/rw26.c @@ -376,7 +376,7 @@ static ssize_t ll_direct_IO_26(struct kiocb *iocb, struct iov_iter *iter, env = cl_env_get(&refcheck); LASSERT(!IS_ERR(env)); - io = ccc_env_io(env)->cui_cl.cis_io; + io = vvp_env_io(env)->cui_cl.cis_io; LASSERT(io); /* 0. Need locking between buffered and direct access. and race with @@ -439,7 +439,7 @@ out: inode_unlock(inode); if (tot_bytes > 0) { - struct ccc_io *cio = ccc_env_io(env); + struct vvp_io *cio = vvp_env_io(env); /* no commit async for direct IO */ cio->u.write.cui_written += tot_bytes; @@ -513,7 +513,7 @@ static int ll_write_begin(struct file *file, struct address_space *mapping, /* To avoid deadlock, try to lock page first. */ vmpage = grab_cache_page_nowait(mapping, index); if (unlikely(!vmpage || PageDirty(vmpage) || PageWriteback(vmpage))) { - struct ccc_io *cio = ccc_env_io(env); + struct vvp_io *cio = vvp_env_io(env); struct cl_page_list *plist = &cio->u.write.cui_queue; /* if the page is already in dirty cache, we have to commit @@ -595,7 +595,7 @@ static int ll_write_end(struct file *file, struct address_space *mapping, struct ll_cl_context *lcc = fsdata; struct lu_env *env; struct cl_io *io; - struct ccc_io *cio; + struct vvp_io *cio; struct cl_page *page; unsigned from = pos & (PAGE_CACHE_SIZE - 1); bool unplug = false; @@ -606,7 +606,7 @@ static int ll_write_end(struct file *file, struct address_space *mapping, env = lcc->lcc_env; page = lcc->lcc_page; io = lcc->lcc_io; - cio = ccc_env_io(env); + cio = vvp_env_io(env); LASSERT(cl_page_is_owned(page, io)); if (copied > 0) { diff --git a/drivers/staging/lustre/lustre/llite/vvp_dev.c b/drivers/staging/lustre/lustre/llite/vvp_dev.c index 4b77db34f516..030a2460cf24 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_dev.c +++ b/drivers/staging/lustre/lustre/llite/vvp_dev.c @@ -138,7 +138,7 @@ struct lu_context_key vvp_session_key = { }; /* type constructor/destructor: vvp_type_{init,fini,start,stop}(). */ -LU_TYPE_INIT_FINI(vvp, &ccc_key, &ccc_session_key, &vvp_key, &vvp_session_key); +LU_TYPE_INIT_FINI(vvp, &ccc_key, &vvp_key, &vvp_session_key); static const struct lu_device_operations vvp_lu_ops = { .ldo_object_alloc = vvp_object_alloc diff --git a/drivers/staging/lustre/lustre/llite/vvp_internal.h b/drivers/staging/lustre/lustre/llite/vvp_internal.h index 403d2a7ba0af..443485c8c3ee 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_internal.h +++ b/drivers/staging/lustre/lustre/llite/vvp_internal.h @@ -81,10 +81,18 @@ enum ccc_setattr_lock_type { SETATTR_MATCH_LOCK }; +/* specific architecture can implement only part of this list */ +enum vvp_io_subtype { + /** normal IO */ + IO_NORMAL, + /** io started from splice_{read|write} */ + IO_SPLICE +}; + /** - * IO state private to vvp or slp layers. + * IO state private to IO state private to VVP layer. */ -struct ccc_io { +struct vvp_io { /** super class */ struct cl_io_slice cui_cl; struct cl_io_lock_link cui_link; @@ -98,9 +106,37 @@ struct ccc_io { size_t cui_tot_count; union { + struct vvp_fault_io { + /** + * Inode modification time that is checked across DLM + * lock request. + */ + time64_t ft_mtime; + struct vm_area_struct *ft_vma; + /** + * locked page returned from vvp_io + */ + struct page *ft_vmpage; + /** + * kernel fault info + */ + struct vm_fault *ft_vmf; + /** + * fault API used bitflags for return code. + */ + unsigned int ft_flags; + /** + * check that flags are from filemap_fault + */ + bool ft_flags_valid; + } fault; struct { enum ccc_setattr_lock_type cui_local_lock; } setattr; + struct { + struct pipe_inode_info *cui_pipe; + unsigned int cui_flags; + } splice; struct { struct cl_page_list cui_queue; unsigned long cui_written; @@ -108,6 +144,9 @@ struct ccc_io { int cui_to; } write; } u; + + enum vvp_io_subtype cui_io_subtype; + /** * Layout version when this IO is initialized */ @@ -117,6 +156,12 @@ struct ccc_io { */ struct ll_file_data *cui_fd; struct kiocb *cui_iocb; + + /* Readahead state. */ + pgoff_t cui_ra_start; + pgoff_t cui_ra_count; + /* Set when cui_ra_{start,count} have been initialized. */ + bool cui_ra_valid; }; /** @@ -126,7 +171,7 @@ struct ccc_io { int cl_is_normalio(const struct lu_env *env, const struct cl_io *io); extern struct lu_context_key ccc_key; -extern struct lu_context_key ccc_session_key; +extern struct lu_context_key vvp_session_key; extern struct kmem_cache *vvp_lock_kmem; extern struct kmem_cache *vvp_object_kmem; @@ -174,23 +219,23 @@ static inline struct cl_io *ccc_env_thread_io(const struct lu_env *env) return io; } -struct ccc_session { - struct ccc_io cs_ios; +struct vvp_session { + struct vvp_io cs_ios; }; -static inline struct ccc_session *ccc_env_session(const struct lu_env *env) +static inline struct vvp_session *vvp_env_session(const struct lu_env *env) { - struct ccc_session *ses; + struct vvp_session *ses; - ses = lu_context_key_get(env->le_ses, &ccc_session_key); + ses = lu_context_key_get(env->le_ses, &vvp_session_key); LASSERT(ses); return ses; } -static inline struct ccc_io *ccc_env_io(const struct lu_env *env) +static inline struct vvp_io *vvp_env_io(const struct lu_env *env) { - return &ccc_env_session(env)->cs_ios; + return &vvp_env_session(env)->cs_ios; } /** @@ -282,10 +327,6 @@ void *ccc_key_init(const struct lu_context *ctx, struct lu_context_key *key); void ccc_key_fini(const struct lu_context *ctx, struct lu_context_key *key, void *data); -void *ccc_session_key_init(const struct lu_context *ctx, - struct lu_context_key *key); -void ccc_session_key_fini(const struct lu_context *ctx, - struct lu_context_key *key, void *data); int ccc_req_init(const struct lu_env *env, struct cl_device *dev, struct cl_req *req); @@ -293,16 +334,16 @@ void ccc_umount(const struct lu_env *env, struct cl_device *dev); int ccc_global_init(struct lu_device_type *device_type); void ccc_global_fini(struct lu_device_type *device_type); -int ccc_io_one_lock_index(const struct lu_env *env, struct cl_io *io, +int vvp_io_one_lock_index(const struct lu_env *env, struct cl_io *io, __u32 enqflags, enum cl_lock_mode mode, pgoff_t start, pgoff_t end); -int ccc_io_one_lock(const struct lu_env *env, struct cl_io *io, +int vvp_io_one_lock(const struct lu_env *env, struct cl_io *io, __u32 enqflags, enum cl_lock_mode mode, loff_t start, loff_t end); -void ccc_io_end(const struct lu_env *env, const struct cl_io_slice *ios); -void ccc_io_advance(const struct lu_env *env, const struct cl_io_slice *ios, +void vvp_io_end(const struct lu_env *env, const struct cl_io_slice *ios); +void vvp_io_advance(const struct lu_env *env, const struct cl_io_slice *ios, size_t nob); -void ccc_io_update_iov(const struct lu_env *env, struct ccc_io *cio, +void vvp_io_update_iov(const struct lu_env *env, struct vvp_io *cio, struct cl_io *io); int ccc_prep_size(const struct lu_env *env, struct cl_object *obj, struct cl_io *io, loff_t start, size_t count, int *exceed); @@ -356,7 +397,7 @@ static inline struct vvp_lock *cl2vvp_lock(const struct cl_lock_slice *slice) return container_of(slice, struct vvp_lock, vlk_cl); } -struct ccc_io *cl2ccc_io(const struct lu_env *env, +struct vvp_io *cl2vvp_io(const struct lu_env *env, const struct cl_io_slice *slice); struct ccc_req *cl2ccc_req(const struct cl_req_slice *slice); diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c index 86e73d512a91..1059c6353327 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_io.c +++ b/drivers/staging/lustre/lustre/llite/vvp_io.c @@ -47,9 +47,6 @@ #include "llite_internal.h" #include "vvp_internal.h" -static struct vvp_io *cl2vvp_io(const struct lu_env *env, - const struct cl_io_slice *slice); - /** * True, if \a io is a normal io, False for splice_{read,write} */ @@ -72,7 +69,7 @@ static bool can_populate_pages(const struct lu_env *env, struct cl_io *io, struct inode *inode) { struct ll_inode_info *lli = ll_i2info(inode); - struct ccc_io *cio = ccc_env_io(env); + struct vvp_io *cio = vvp_env_io(env); bool rc = true; switch (io->ci_type) { @@ -105,7 +102,7 @@ static bool can_populate_pages(const struct lu_env *env, struct cl_io *io, static int vvp_io_write_iter_init(const struct lu_env *env, const struct cl_io_slice *ios) { - struct ccc_io *cio = cl2ccc_io(env, ios); + struct vvp_io *cio = cl2vvp_io(env, ios); cl_page_list_init(&cio->u.write.cui_queue); cio->u.write.cui_written = 0; @@ -118,7 +115,7 @@ static int vvp_io_write_iter_init(const struct lu_env *env, static void vvp_io_write_iter_fini(const struct lu_env *env, const struct cl_io_slice *ios) { - struct ccc_io *cio = cl2ccc_io(env, ios); + struct vvp_io *cio = cl2vvp_io(env, ios); LASSERT(cio->u.write.cui_queue.pl_nr == 0); } @@ -129,8 +126,7 @@ static int vvp_io_fault_iter_init(const struct lu_env *env, struct vvp_io *vio = cl2vvp_io(env, ios); struct inode *inode = vvp_object_inode(ios->cis_obj); - LASSERT(inode == - file_inode(cl2ccc_io(env, ios)->cui_fd->fd_file)); + LASSERT(inode == file_inode(vio->cui_fd->fd_file)); vio->u.fault.ft_mtime = inode->i_mtime.tv_sec; return 0; } @@ -139,7 +135,7 @@ static void vvp_io_fini(const struct lu_env *env, const struct cl_io_slice *ios) { struct cl_io *io = ios->cis_io; struct cl_object *obj = io->ci_obj; - struct ccc_io *cio = cl2ccc_io(env, ios); + struct vvp_io *cio = cl2vvp_io(env, ios); CLOBINVRNT(env, obj, vvp_object_invariant(obj)); @@ -225,7 +221,7 @@ static enum cl_lock_mode vvp_mode_from_vma(struct vm_area_struct *vma) } static int vvp_mmap_locks(const struct lu_env *env, - struct ccc_io *vio, struct cl_io *io) + struct vvp_io *vio, struct cl_io *io) { struct ccc_thread_info *cti = ccc_env_info(env); struct mm_struct *mm = current->mm; @@ -310,19 +306,19 @@ static int vvp_mmap_locks(const struct lu_env *env, static int vvp_io_rw_lock(const struct lu_env *env, struct cl_io *io, enum cl_lock_mode mode, loff_t start, loff_t end) { - struct ccc_io *cio = ccc_env_io(env); + struct vvp_io *cio = vvp_env_io(env); int result; int ast_flags = 0; LASSERT(io->ci_type == CIT_READ || io->ci_type == CIT_WRITE); - ccc_io_update_iov(env, cio, io); + vvp_io_update_iov(env, cio, io); if (io->u.ci_rw.crw_nonblock) ast_flags |= CEF_NONBLOCK; result = vvp_mmap_locks(env, cio, io); if (result == 0) - result = ccc_io_one_lock(env, io, ast_flags, mode, start, end); + result = vvp_io_one_lock(env, io, ast_flags, mode, start, end); return result; } @@ -347,9 +343,11 @@ static int vvp_io_fault_lock(const struct lu_env *env, /* * XXX LDLM_FL_CBPENDING */ - return ccc_io_one_lock_index - (env, io, 0, vvp_mode_from_vma(vio->u.fault.ft_vma), - io->u.ci_fault.ft_index, io->u.ci_fault.ft_index); + return vvp_io_one_lock_index(env, + io, 0, + vvp_mode_from_vma(vio->u.fault.ft_vma), + io->u.ci_fault.ft_index, + io->u.ci_fault.ft_index); } static int vvp_io_write_lock(const struct lu_env *env, @@ -383,7 +381,7 @@ static int vvp_io_setattr_iter_init(const struct lu_env *env, static int vvp_io_setattr_lock(const struct lu_env *env, const struct cl_io_slice *ios) { - struct ccc_io *cio = ccc_env_io(env); + struct vvp_io *cio = vvp_env_io(env); struct cl_io *io = ios->cis_io; __u64 new_size; __u32 enqflags = 0; @@ -401,7 +399,8 @@ static int vvp_io_setattr_lock(const struct lu_env *env, new_size = 0; } cio->u.setattr.cui_local_lock = SETATTR_EXTENT_LOCK; - return ccc_io_one_lock(env, io, enqflags, CLM_WRITE, + + return vvp_io_one_lock(env, io, enqflags, CLM_WRITE, new_size, OBD_OBJECT_EOF); } @@ -496,16 +495,15 @@ static int vvp_io_read_start(const struct lu_env *env, const struct cl_io_slice *ios) { struct vvp_io *vio = cl2vvp_io(env, ios); - struct ccc_io *cio = cl2ccc_io(env, ios); struct cl_io *io = ios->cis_io; struct cl_object *obj = io->ci_obj; struct inode *inode = vvp_object_inode(obj); - struct file *file = cio->cui_fd->fd_file; + struct file *file = vio->cui_fd->fd_file; int result; loff_t pos = io->u.ci_rd.rd.crw_pos; long cnt = io->u.ci_rd.rd.crw_count; - long tot = cio->cui_tot_count; + long tot = vio->cui_tot_count; int exceed = 0; CLOBINVRNT(env, obj, vvp_object_invariant(obj)); @@ -526,7 +524,7 @@ static int vvp_io_read_start(const struct lu_env *env, inode->i_ino, cnt, pos, i_size_read(inode)); /* turn off the kernel's read-ahead */ - cio->cui_fd->fd_file->f_ra.ra_pages = 0; + vio->cui_fd->fd_file->f_ra.ra_pages = 0; /* initialize read-ahead window once per syscall */ if (!vio->cui_ra_valid) { @@ -540,8 +538,8 @@ static int vvp_io_read_start(const struct lu_env *env, file_accessed(file); switch (vio->cui_io_subtype) { case IO_NORMAL: - LASSERT(cio->cui_iocb->ki_pos == pos); - result = generic_file_read_iter(cio->cui_iocb, cio->cui_iter); + LASSERT(vio->cui_iocb->ki_pos == pos); + result = generic_file_read_iter(vio->cui_iocb, vio->cui_iter); break; case IO_SPLICE: result = generic_file_splice_read(file, &pos, @@ -564,7 +562,7 @@ out: io->ci_continue = 0; io->ci_nob += result; ll_rw_stats_tally(ll_i2sbi(inode), current->pid, - cio->cui_fd, pos, result, READ); + vio->cui_fd, pos, result, READ); result = 0; } return result; @@ -676,7 +674,7 @@ int vvp_io_write_commit(const struct lu_env *env, struct cl_io *io) { struct cl_object *obj = io->ci_obj; struct inode *inode = vvp_object_inode(obj); - struct ccc_io *cio = ccc_env_io(env); + struct vvp_io *cio = vvp_env_io(env); struct cl_page_list *queue = &cio->u.write.cui_queue; struct cl_page *page; int rc = 0; @@ -755,7 +753,7 @@ int vvp_io_write_commit(const struct lu_env *env, struct cl_io *io) static int vvp_io_write_start(const struct lu_env *env, const struct cl_io_slice *ios) { - struct ccc_io *cio = cl2ccc_io(env, ios); + struct vvp_io *cio = cl2vvp_io(env, ios); struct cl_io *io = ios->cis_io; struct cl_object *obj = io->ci_obj; struct inode *inode = vvp_object_inode(obj); @@ -813,10 +811,10 @@ static int vvp_io_write_start(const struct lu_env *env, static int vvp_io_kernel_fault(struct vvp_fault_io *cfio) { - struct vm_fault *vmf = cfio->fault.ft_vmf; + struct vm_fault *vmf = cfio->ft_vmf; - cfio->fault.ft_flags = filemap_fault(cfio->ft_vma, vmf); - cfio->fault.ft_flags_valid = 1; + cfio->ft_flags = filemap_fault(cfio->ft_vma, vmf); + cfio->ft_flags_valid = 1; if (vmf->page) { CDEBUG(D_PAGE, @@ -824,29 +822,29 @@ static int vvp_io_kernel_fault(struct vvp_fault_io *cfio) vmf->page, vmf->page->mapping, vmf->page->index, (long)vmf->page->flags, page_count(vmf->page), page_private(vmf->page), vmf->virtual_address); - if (unlikely(!(cfio->fault.ft_flags & VM_FAULT_LOCKED))) { + if (unlikely(!(cfio->ft_flags & VM_FAULT_LOCKED))) { lock_page(vmf->page); - cfio->fault.ft_flags |= VM_FAULT_LOCKED; + cfio->ft_flags |= VM_FAULT_LOCKED; } cfio->ft_vmpage = vmf->page; return 0; } - if (cfio->fault.ft_flags & (VM_FAULT_SIGBUS | VM_FAULT_SIGSEGV)) { + if (cfio->ft_flags & (VM_FAULT_SIGBUS | VM_FAULT_SIGSEGV)) { CDEBUG(D_PAGE, "got addr %p - SIGBUS\n", vmf->virtual_address); return -EFAULT; } - if (cfio->fault.ft_flags & VM_FAULT_OOM) { + if (cfio->ft_flags & VM_FAULT_OOM) { CDEBUG(D_PAGE, "got addr %p - OOM\n", vmf->virtual_address); return -ENOMEM; } - if (cfio->fault.ft_flags & VM_FAULT_RETRY) + if (cfio->ft_flags & VM_FAULT_RETRY) return -EAGAIN; - CERROR("Unknown error in page fault %d!\n", cfio->fault.ft_flags); + CERROR("Unknown error in page fault %d!\n", cfio->ft_flags); return -EINVAL; } @@ -1024,7 +1022,9 @@ out: /* return unlocked vmpage to avoid deadlocking */ if (vmpage) unlock_page(vmpage); - cfio->fault.ft_flags &= ~VM_FAULT_LOCKED; + + cfio->ft_flags &= ~VM_FAULT_LOCKED; + return result; } @@ -1047,7 +1047,7 @@ static int vvp_io_read_page(const struct lu_env *env, struct cl_page *page = slice->cpl_page; struct inode *inode = vvp_object_inode(slice->cpl_obj); struct ll_sb_info *sbi = ll_i2sbi(inode); - struct ll_file_data *fd = cl2ccc_io(env, ios)->cui_fd; + struct ll_file_data *fd = cl2vvp_io(env, ios)->cui_fd; struct ll_readahead_state *ras = &fd->fd_ras; struct cl_2queue *queue = &io->ci_queue; @@ -1080,7 +1080,7 @@ static const struct cl_io_operations vvp_io_ops = { .cio_fini = vvp_io_fini, .cio_lock = vvp_io_read_lock, .cio_start = vvp_io_read_start, - .cio_advance = ccc_io_advance, + .cio_advance = vvp_io_advance, }, [CIT_WRITE] = { .cio_fini = vvp_io_fini, @@ -1088,7 +1088,7 @@ static const struct cl_io_operations vvp_io_ops = { .cio_iter_fini = vvp_io_write_iter_fini, .cio_lock = vvp_io_write_lock, .cio_start = vvp_io_write_start, - .cio_advance = ccc_io_advance + .cio_advance = vvp_io_advance, }, [CIT_SETATTR] = { .cio_fini = vvp_io_setattr_fini, @@ -1102,7 +1102,7 @@ static const struct cl_io_operations vvp_io_ops = { .cio_iter_init = vvp_io_fault_iter_init, .cio_lock = vvp_io_fault_lock, .cio_start = vvp_io_fault_start, - .cio_end = ccc_io_end + .cio_end = vvp_io_end, }, [CIT_FSYNC] = { .cio_start = vvp_io_fsync_start, @@ -1119,7 +1119,6 @@ int vvp_io_init(const struct lu_env *env, struct cl_object *obj, struct cl_io *io) { struct vvp_io *vio = vvp_env_io(env); - struct ccc_io *cio = ccc_env_io(env); struct inode *inode = vvp_object_inode(obj); int result; @@ -1129,10 +1128,10 @@ int vvp_io_init(const struct lu_env *env, struct cl_object *obj, " ignore/verify layout %d/%d, layout version %d restore needed %d\n", PFID(lu_object_fid(&obj->co_lu)), io->ci_ignore_layout, io->ci_verify_layout, - cio->cui_layout_gen, io->ci_restore_needed); + vio->cui_layout_gen, io->ci_restore_needed); - CL_IO_SLICE_CLEAN(cio, cui_cl); - cl_io_slice_add(io, &cio->cui_cl, obj, &vvp_io_ops); + CL_IO_SLICE_CLEAN(vio, cui_cl); + cl_io_slice_add(io, &vio->cui_cl, obj, &vvp_io_ops); vio->cui_ra_valid = false; result = 0; if (io->ci_type == CIT_READ || io->ci_type == CIT_WRITE) { @@ -1146,7 +1145,7 @@ int vvp_io_init(const struct lu_env *env, struct cl_object *obj, if (count == 0) result = 1; else - cio->cui_tot_count = count; + vio->cui_tot_count = count; /* for read/write, we store the jobid in the inode, and * it'll be fetched by osc when building RPC. @@ -1172,7 +1171,7 @@ int vvp_io_init(const struct lu_env *env, struct cl_object *obj, * because it might not grant layout lock in IT_OPEN. */ if (result == 0 && !io->ci_ignore_layout) { - result = ll_layout_refresh(inode, &cio->cui_layout_gen); + result = ll_layout_refresh(inode, &vio->cui_layout_gen); if (result == -ENOENT) /* If the inode on MDS has been removed, but the objects * on OSTs haven't been destroyed (async unlink), layout @@ -1188,11 +1187,3 @@ int vvp_io_init(const struct lu_env *env, struct cl_object *obj, return result; } - -static struct vvp_io *cl2vvp_io(const struct lu_env *env, - const struct cl_io_slice *slice) -{ - /* Calling just for assertion */ - cl2ccc_io(env, slice); - return vvp_env_io(env); -} diff --git a/drivers/staging/lustre/lustre/llite/vvp_page.c b/drivers/staging/lustre/lustre/llite/vvp_page.c index 5ebbe27104f1..4f7dfe221544 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_page.c +++ b/drivers/staging/lustre/lustre/llite/vvp_page.c @@ -372,7 +372,7 @@ static int vvp_page_is_under_lock(const struct lu_env *env, { if (io->ci_type == CIT_READ || io->ci_type == CIT_WRITE || io->ci_type == CIT_FAULT) { - struct ccc_io *cio = ccc_env_io(env); + struct vvp_io *cio = vvp_env_io(env); if (unlikely(cio->cui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) *max_index = CL_PAGE_EOF; -- cgit v1.2.3 From e0a8144b8c32031d37ff849fc07e6c5646e61198 Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Wed, 30 Mar 2016 19:48:52 -0400 Subject: staging/lustre/llite: use vui prefix for struct vvp_io members Rename members of struct vvp_io to used to start with vui_ rather than cui_. Rename several instances of struct vvp_io * from cio to vio. Signed-off-by: John L. Hammond Reviewed-on: http://review.whamcloud.com/13363 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5971 Reviewed-by: Bobi Jam Reviewed-by: Lai Siyao Reviewed-by: Jinshan Xiong Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/file.c | 20 ++-- drivers/staging/lustre/lustre/llite/lcommon_cl.c | 34 +++--- drivers/staging/lustre/lustre/llite/llite_mmap.c | 6 +- drivers/staging/lustre/lustre/llite/rw.c | 24 ++-- drivers/staging/lustre/lustre/llite/rw26.c | 20 ++-- drivers/staging/lustre/lustre/llite/vvp_internal.h | 38 +++--- drivers/staging/lustre/lustre/llite/vvp_io.c | 131 +++++++++++---------- drivers/staging/lustre/lustre/llite/vvp_page.c | 4 +- 8 files changed, 139 insertions(+), 138 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index 27e7e65b3a98..63aa080785d4 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -1135,18 +1135,18 @@ restart: ll_io_init(io, file, iot == CIT_WRITE); if (cl_io_rw_init(env, io, iot, *ppos, count) == 0) { - struct vvp_io *cio = vvp_env_io(env); + struct vvp_io *vio = vvp_env_io(env); int write_mutex_locked = 0; - cio->cui_fd = LUSTRE_FPRIVATE(file); - cio->cui_io_subtype = args->via_io_subtype; + vio->vui_fd = LUSTRE_FPRIVATE(file); + vio->vui_io_subtype = args->via_io_subtype; - switch (cio->cui_io_subtype) { + switch (vio->vui_io_subtype) { case IO_NORMAL: - cio->cui_iter = args->u.normal.via_iter; - cio->cui_iocb = args->u.normal.via_iocb; + vio->vui_iter = args->u.normal.via_iter; + vio->vui_iocb = args->u.normal.via_iocb; if ((iot == CIT_WRITE) && - !(cio->cui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) { + !(vio->vui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) { if (mutex_lock_interruptible(&lli-> lli_write_mutex)) { result = -ERESTARTSYS; @@ -1157,11 +1157,11 @@ restart: down_read(&lli->lli_trunc_sem); break; case IO_SPLICE: - cio->u.splice.cui_pipe = args->u.splice.via_pipe; - cio->u.splice.cui_flags = args->u.splice.via_flags; + vio->u.splice.vui_pipe = args->u.splice.via_pipe; + vio->u.splice.vui_flags = args->u.splice.via_flags; break; default: - CERROR("Unknown IO type - %u\n", cio->cui_io_subtype); + CERROR("Unknown IO type - %u\n", vio->vui_io_subtype); LBUG(); } result = cl_io_loop(env, io); diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c b/drivers/staging/lustre/lustre/llite/lcommon_cl.c index 9a9d7061fff0..630c37142d31 100644 --- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c +++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c @@ -210,19 +210,19 @@ int vvp_io_one_lock_index(const struct lu_env *env, struct cl_io *io, __u32 enqflags, enum cl_lock_mode mode, pgoff_t start, pgoff_t end) { - struct vvp_io *cio = vvp_env_io(env); - struct cl_lock_descr *descr = &cio->cui_link.cill_descr; + struct vvp_io *vio = vvp_env_io(env); + struct cl_lock_descr *descr = &vio->vui_link.cill_descr; struct cl_object *obj = io->ci_obj; CLOBINVRNT(env, obj, vvp_object_invariant(obj)); CDEBUG(D_VFSTRACE, "lock: %d [%lu, %lu]\n", mode, start, end); - memset(&cio->cui_link, 0, sizeof(cio->cui_link)); + memset(&vio->vui_link, 0, sizeof(vio->vui_link)); - if (cio->cui_fd && (cio->cui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) { + if (vio->vui_fd && (vio->vui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) { descr->cld_mode = CLM_GROUP; - descr->cld_gid = cio->cui_fd->fd_grouplock.cg_gid; + descr->cld_gid = vio->vui_fd->fd_grouplock.cg_gid; } else { descr->cld_mode = mode; } @@ -231,19 +231,19 @@ int vvp_io_one_lock_index(const struct lu_env *env, struct cl_io *io, descr->cld_end = end; descr->cld_enq_flags = enqflags; - cl_io_lock_add(env, io, &cio->cui_link); + cl_io_lock_add(env, io, &vio->vui_link); return 0; } void vvp_io_update_iov(const struct lu_env *env, - struct vvp_io *cio, struct cl_io *io) + struct vvp_io *vio, struct cl_io *io) { size_t size = io->u.ci_rw.crw_count; - if (!cl_is_normalio(env, io) || !cio->cui_iter) + if (!cl_is_normalio(env, io) || !vio->vui_iter) return; - iov_iter_truncate(cio->cui_iter, size); + iov_iter_truncate(vio->vui_iter, size); } int vvp_io_one_lock(const struct lu_env *env, struct cl_io *io, @@ -266,7 +266,7 @@ void vvp_io_advance(const struct lu_env *env, const struct cl_io_slice *ios, size_t nob) { - struct vvp_io *cio = cl2vvp_io(env, ios); + struct vvp_io *vio = cl2vvp_io(env, ios); struct cl_io *io = ios->cis_io; struct cl_object *obj = ios->cis_io->ci_obj; @@ -275,7 +275,7 @@ void vvp_io_advance(const struct lu_env *env, if (!cl_is_normalio(env, io)) return; - iov_iter_reexpand(cio->cui_iter, cio->cui_tot_count -= nob); + iov_iter_reexpand(vio->vui_iter, vio->vui_tot_count -= nob); } /** @@ -461,13 +461,13 @@ int cl_setattr_ost(struct inode *inode, const struct iattr *attr) again: if (cl_io_init(env, io, CIT_SETATTR, io->ci_obj) == 0) { - struct vvp_io *cio = vvp_env_io(env); + struct vvp_io *vio = vvp_env_io(env); if (attr->ia_valid & ATTR_FILE) /* populate the file descriptor for ftruncate to honor * group lock - see LU-787 */ - cio->cui_fd = LUSTRE_FPRIVATE(attr->ia_file); + vio->vui_fd = LUSTRE_FPRIVATE(attr->ia_file); result = cl_io_loop(env, io); } else { @@ -496,12 +496,12 @@ again: struct vvp_io *cl2vvp_io(const struct lu_env *env, const struct cl_io_slice *slice) { - struct vvp_io *cio; + struct vvp_io *vio; - cio = container_of(slice, struct vvp_io, cui_cl); - LASSERT(cio == vvp_env_io(env)); + vio = container_of(slice, struct vvp_io, vui_cl); + LASSERT(vio == vvp_env_io(env)); - return cio; + return vio; } struct ccc_req *cl2ccc_req(const struct cl_req_slice *slice) diff --git a/drivers/staging/lustre/lustre/llite/llite_mmap.c b/drivers/staging/lustre/lustre/llite/llite_mmap.c index 7c214f8a1e71..a7693c55cc46 100644 --- a/drivers/staging/lustre/lustre/llite/llite_mmap.c +++ b/drivers/staging/lustre/lustre/llite/llite_mmap.c @@ -146,14 +146,14 @@ ll_fault_io_init(struct vm_area_struct *vma, struct lu_env **env_ret, rc = cl_io_init(env, io, CIT_FAULT, io->ci_obj); if (rc == 0) { - struct vvp_io *cio = vvp_env_io(env); + struct vvp_io *vio = vvp_env_io(env); struct ll_file_data *fd = LUSTRE_FPRIVATE(file); - LASSERT(cio->cui_cl.cis_io == io); + LASSERT(vio->vui_cl.cis_io == io); /* mmap lock must be MANDATORY it has to cache pages. */ io->ci_lockreq = CILR_MANDATORY; - cio->cui_fd = fd; + vio->vui_fd = fd; } else { LASSERT(rc < 0); cl_io_fini(env, io); diff --git a/drivers/staging/lustre/lustre/llite/rw.c b/drivers/staging/lustre/lustre/llite/rw.c index da4410712f83..634f0bb355e3 100644 --- a/drivers/staging/lustre/lustre/llite/rw.c +++ b/drivers/staging/lustre/lustre/llite/rw.c @@ -90,7 +90,7 @@ struct ll_cl_context *ll_cl_init(struct file *file, struct page *vmpage) struct lu_env *env; struct cl_io *io; struct cl_object *clob; - struct vvp_io *cio; + struct vvp_io *vio; int refcheck; int result = 0; @@ -108,8 +108,8 @@ struct ll_cl_context *ll_cl_init(struct file *file, struct page *vmpage) lcc->lcc_refcheck = refcheck; lcc->lcc_cookie = current; - cio = vvp_env_io(env); - io = cio->cui_cl.cis_io; + vio = vvp_env_io(env); + io = vio->vui_cl.cis_io; lcc->lcc_io = io; if (!io) { struct inode *inode = file_inode(file); @@ -125,7 +125,7 @@ struct ll_cl_context *ll_cl_init(struct file *file, struct page *vmpage) struct cl_page *page; LASSERT(io->ci_state == CIS_IO_GOING); - LASSERT(cio->cui_fd == LUSTRE_FPRIVATE(file)); + LASSERT(vio->vui_fd == LUSTRE_FPRIVATE(file)); page = cl_page_find(env, clob, vmpage->index, vmpage, CPT_CACHEABLE); if (!IS_ERR(page)) { @@ -553,10 +553,10 @@ int ll_readahead(const struct lu_env *env, struct cl_io *io, spin_lock(&ras->ras_lock); /* Enlarge the RA window to encompass the full read */ - if (vio->cui_ra_valid && + if (vio->vui_ra_valid && ras->ras_window_start + ras->ras_window_len < - vio->cui_ra_start + vio->cui_ra_count) { - ras->ras_window_len = vio->cui_ra_start + vio->cui_ra_count - + vio->vui_ra_start + vio->vui_ra_count) { + ras->ras_window_len = vio->vui_ra_start + vio->vui_ra_count - ras->ras_window_start; } @@ -615,15 +615,15 @@ int ll_readahead(const struct lu_env *env, struct cl_io *io, CDEBUG(D_READA, DFID ": ria: %lu/%lu, bead: %lu/%lu, hit: %d\n", PFID(lu_object_fid(&clob->co_lu)), ria->ria_start, ria->ria_end, - vio->cui_ra_valid ? vio->cui_ra_start : 0, - vio->cui_ra_valid ? vio->cui_ra_count : 0, + vio->vui_ra_valid ? vio->vui_ra_start : 0, + vio->vui_ra_valid ? vio->vui_ra_count : 0, hit); /* at least to extend the readahead window to cover current read */ - if (!hit && vio->cui_ra_valid && - vio->cui_ra_start + vio->cui_ra_count > ria->ria_start) { + if (!hit && vio->vui_ra_valid && + vio->vui_ra_start + vio->vui_ra_count > ria->ria_start) { /* to the end of current read window. */ - mlen = vio->cui_ra_start + vio->cui_ra_count - ria->ria_start; + mlen = vio->vui_ra_start + vio->vui_ra_count - ria->ria_start; /* trim to RPC boundary */ start = ria->ria_start & (PTLRPC_MAX_BRW_PAGES - 1); mlen = min(mlen, PTLRPC_MAX_BRW_PAGES - start); diff --git a/drivers/staging/lustre/lustre/llite/rw26.c b/drivers/staging/lustre/lustre/llite/rw26.c index 2f69634376f9..106473eb4117 100644 --- a/drivers/staging/lustre/lustre/llite/rw26.c +++ b/drivers/staging/lustre/lustre/llite/rw26.c @@ -376,7 +376,7 @@ static ssize_t ll_direct_IO_26(struct kiocb *iocb, struct iov_iter *iter, env = cl_env_get(&refcheck); LASSERT(!IS_ERR(env)); - io = vvp_env_io(env)->cui_cl.cis_io; + io = vvp_env_io(env)->vui_cl.cis_io; LASSERT(io); /* 0. Need locking between buffered and direct access. and race with @@ -439,10 +439,10 @@ out: inode_unlock(inode); if (tot_bytes > 0) { - struct vvp_io *cio = vvp_env_io(env); + struct vvp_io *vio = vvp_env_io(env); /* no commit async for direct IO */ - cio->u.write.cui_written += tot_bytes; + vio->u.write.vui_written += tot_bytes; } cl_env_put(env, &refcheck); @@ -513,8 +513,8 @@ static int ll_write_begin(struct file *file, struct address_space *mapping, /* To avoid deadlock, try to lock page first. */ vmpage = grab_cache_page_nowait(mapping, index); if (unlikely(!vmpage || PageDirty(vmpage) || PageWriteback(vmpage))) { - struct vvp_io *cio = vvp_env_io(env); - struct cl_page_list *plist = &cio->u.write.cui_queue; + struct vvp_io *vio = vvp_env_io(env); + struct cl_page_list *plist = &vio->u.write.vui_queue; /* if the page is already in dirty cache, we have to commit * the pages right now; otherwise, it may cause deadlock @@ -595,7 +595,7 @@ static int ll_write_end(struct file *file, struct address_space *mapping, struct ll_cl_context *lcc = fsdata; struct lu_env *env; struct cl_io *io; - struct vvp_io *cio; + struct vvp_io *vio; struct cl_page *page; unsigned from = pos & (PAGE_CACHE_SIZE - 1); bool unplug = false; @@ -606,21 +606,21 @@ static int ll_write_end(struct file *file, struct address_space *mapping, env = lcc->lcc_env; page = lcc->lcc_page; io = lcc->lcc_io; - cio = vvp_env_io(env); + vio = vvp_env_io(env); LASSERT(cl_page_is_owned(page, io)); if (copied > 0) { - struct cl_page_list *plist = &cio->u.write.cui_queue; + struct cl_page_list *plist = &vio->u.write.vui_queue; lcc->lcc_page = NULL; /* page will be queued */ /* Add it into write queue */ cl_page_list_add(plist, page); if (plist->pl_nr == 1) /* first page */ - cio->u.write.cui_from = from; + vio->u.write.vui_from = from; else LASSERT(from == 0); - cio->u.write.cui_to = from + copied; + vio->u.write.vui_to = from + copied; /* We may have one full RPC, commit it soon */ if (plist->pl_nr >= PTLRPC_MAX_BRW_PAGES) diff --git a/drivers/staging/lustre/lustre/llite/vvp_internal.h b/drivers/staging/lustre/lustre/llite/vvp_internal.h index 443485c8c3ee..e04f23ea403e 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_internal.h +++ b/drivers/staging/lustre/lustre/llite/vvp_internal.h @@ -94,16 +94,16 @@ enum vvp_io_subtype { */ struct vvp_io { /** super class */ - struct cl_io_slice cui_cl; - struct cl_io_lock_link cui_link; + struct cl_io_slice vui_cl; + struct cl_io_lock_link vui_link; /** * I/O vector information to or from which read/write is going. */ - struct iov_iter *cui_iter; + struct iov_iter *vui_iter; /** * Total size for the left IO. */ - size_t cui_tot_count; + size_t vui_tot_count; union { struct vvp_fault_io { @@ -131,37 +131,37 @@ struct vvp_io { bool ft_flags_valid; } fault; struct { - enum ccc_setattr_lock_type cui_local_lock; + enum ccc_setattr_lock_type vui_local_lock; } setattr; struct { - struct pipe_inode_info *cui_pipe; - unsigned int cui_flags; + struct pipe_inode_info *vui_pipe; + unsigned int vui_flags; } splice; struct { - struct cl_page_list cui_queue; - unsigned long cui_written; - int cui_from; - int cui_to; + struct cl_page_list vui_queue; + unsigned long vui_written; + int vui_from; + int vui_to; } write; } u; - enum vvp_io_subtype cui_io_subtype; + enum vvp_io_subtype vui_io_subtype; /** * Layout version when this IO is initialized */ - __u32 cui_layout_gen; + __u32 vui_layout_gen; /** * File descriptor against which IO is done. */ - struct ll_file_data *cui_fd; - struct kiocb *cui_iocb; + struct ll_file_data *vui_fd; + struct kiocb *vui_iocb; /* Readahead state. */ - pgoff_t cui_ra_start; - pgoff_t cui_ra_count; - /* Set when cui_ra_{start,count} have been initialized. */ - bool cui_ra_valid; + pgoff_t vui_ra_start; + pgoff_t vui_ra_count; + /* Set when vui_ra_{start,count} have been initialized. */ + bool vui_ra_valid; }; /** diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c index 1059c6353327..53cf2be0e152 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_io.c +++ b/drivers/staging/lustre/lustre/llite/vvp_io.c @@ -56,7 +56,7 @@ int cl_is_normalio(const struct lu_env *env, const struct cl_io *io) LASSERT(io->ci_type == CIT_READ || io->ci_type == CIT_WRITE); - return vio->cui_io_subtype == IO_NORMAL; + return vio->vui_io_subtype == IO_NORMAL; } /** @@ -69,7 +69,7 @@ static bool can_populate_pages(const struct lu_env *env, struct cl_io *io, struct inode *inode) { struct ll_inode_info *lli = ll_i2info(inode); - struct vvp_io *cio = vvp_env_io(env); + struct vvp_io *vio = vvp_env_io(env); bool rc = true; switch (io->ci_type) { @@ -78,7 +78,7 @@ static bool can_populate_pages(const struct lu_env *env, struct cl_io *io, /* don't need lock here to check lli_layout_gen as we have held * extent lock and GROUP lock has to hold to swap layout */ - if (ll_layout_version_get(lli) != cio->cui_layout_gen) { + if (ll_layout_version_get(lli) != vio->vui_layout_gen) { io->ci_need_restart = 1; /* this will return application a short read/write */ io->ci_continue = 0; @@ -102,12 +102,12 @@ static bool can_populate_pages(const struct lu_env *env, struct cl_io *io, static int vvp_io_write_iter_init(const struct lu_env *env, const struct cl_io_slice *ios) { - struct vvp_io *cio = cl2vvp_io(env, ios); + struct vvp_io *vio = cl2vvp_io(env, ios); - cl_page_list_init(&cio->u.write.cui_queue); - cio->u.write.cui_written = 0; - cio->u.write.cui_from = 0; - cio->u.write.cui_to = PAGE_SIZE; + cl_page_list_init(&vio->u.write.vui_queue); + vio->u.write.vui_written = 0; + vio->u.write.vui_from = 0; + vio->u.write.vui_to = PAGE_SIZE; return 0; } @@ -115,9 +115,9 @@ static int vvp_io_write_iter_init(const struct lu_env *env, static void vvp_io_write_iter_fini(const struct lu_env *env, const struct cl_io_slice *ios) { - struct vvp_io *cio = cl2vvp_io(env, ios); + struct vvp_io *vio = cl2vvp_io(env, ios); - LASSERT(cio->u.write.cui_queue.pl_nr == 0); + LASSERT(vio->u.write.vui_queue.pl_nr == 0); } static int vvp_io_fault_iter_init(const struct lu_env *env, @@ -126,7 +126,7 @@ static int vvp_io_fault_iter_init(const struct lu_env *env, struct vvp_io *vio = cl2vvp_io(env, ios); struct inode *inode = vvp_object_inode(ios->cis_obj); - LASSERT(inode == file_inode(vio->cui_fd->fd_file)); + LASSERT(inode == file_inode(vio->vui_fd->fd_file)); vio->u.fault.ft_mtime = inode->i_mtime.tv_sec; return 0; } @@ -135,7 +135,7 @@ static void vvp_io_fini(const struct lu_env *env, const struct cl_io_slice *ios) { struct cl_io *io = ios->cis_io; struct cl_object *obj = io->ci_obj; - struct vvp_io *cio = cl2vvp_io(env, ios); + struct vvp_io *vio = cl2vvp_io(env, ios); CLOBINVRNT(env, obj, vvp_object_invariant(obj)); @@ -143,7 +143,7 @@ static void vvp_io_fini(const struct lu_env *env, const struct cl_io_slice *ios) " ignore/verify layout %d/%d, layout version %d restore needed %d\n", PFID(lu_object_fid(&obj->co_lu)), io->ci_ignore_layout, io->ci_verify_layout, - cio->cui_layout_gen, io->ci_restore_needed); + vio->vui_layout_gen, io->ci_restore_needed); if (io->ci_restore_needed == 1) { int rc; @@ -178,12 +178,12 @@ static void vvp_io_fini(const struct lu_env *env, const struct cl_io_slice *ios) /* check layout version */ ll_layout_refresh(vvp_object_inode(obj), &gen); - io->ci_need_restart = cio->cui_layout_gen != gen; + io->ci_need_restart = vio->vui_layout_gen != gen; if (io->ci_need_restart) { CDEBUG(D_VFSTRACE, DFID" layout changed from %d to %d.\n", PFID(lu_object_fid(&obj->co_lu)), - cio->cui_layout_gen, gen); + vio->vui_layout_gen, gen); /* today successful restore is the only possible case */ /* restore was done, clear restoring state */ ll_i2info(vvp_object_inode(obj))->lli_flags &= @@ -239,14 +239,14 @@ static int vvp_mmap_locks(const struct lu_env *env, if (!cl_is_normalio(env, io)) return 0; - if (!vio->cui_iter) /* nfs or loop back device write */ + if (!vio->vui_iter) /* nfs or loop back device write */ return 0; /* No MM (e.g. NFS)? No vmas too. */ if (!mm) return 0; - iov_for_each(iov, i, *(vio->cui_iter)) { + iov_for_each(iov, i, *vio->vui_iter) { addr = (unsigned long)iov.iov_base; count = iov.iov_len; if (count == 0) @@ -306,17 +306,17 @@ static int vvp_mmap_locks(const struct lu_env *env, static int vvp_io_rw_lock(const struct lu_env *env, struct cl_io *io, enum cl_lock_mode mode, loff_t start, loff_t end) { - struct vvp_io *cio = vvp_env_io(env); + struct vvp_io *vio = vvp_env_io(env); int result; int ast_flags = 0; LASSERT(io->ci_type == CIT_READ || io->ci_type == CIT_WRITE); - vvp_io_update_iov(env, cio, io); + vvp_io_update_iov(env, vio, io); if (io->u.ci_rw.crw_nonblock) ast_flags |= CEF_NONBLOCK; - result = vvp_mmap_locks(env, cio, io); + result = vvp_mmap_locks(env, vio, io); if (result == 0) result = vvp_io_one_lock(env, io, ast_flags, mode, start, end); return result; @@ -374,14 +374,14 @@ static int vvp_io_setattr_iter_init(const struct lu_env *env, } /** - * Implementation of cl_io_operations::cio_lock() method for CIT_SETATTR io. + * Implementation of cl_io_operations::vio_lock() method for CIT_SETATTR io. * * Handles "lockless io" mode when extent locking is done by server. */ static int vvp_io_setattr_lock(const struct lu_env *env, const struct cl_io_slice *ios) { - struct vvp_io *cio = vvp_env_io(env); + struct vvp_io *vio = vvp_env_io(env); struct cl_io *io = ios->cis_io; __u64 new_size; __u32 enqflags = 0; @@ -398,7 +398,8 @@ static int vvp_io_setattr_lock(const struct lu_env *env, return 0; new_size = 0; } - cio->u.setattr.cui_local_lock = SETATTR_EXTENT_LOCK; + + vio->u.setattr.vui_local_lock = SETATTR_EXTENT_LOCK; return vvp_io_one_lock(env, io, enqflags, CLM_WRITE, new_size, OBD_OBJECT_EOF); @@ -498,12 +499,12 @@ static int vvp_io_read_start(const struct lu_env *env, struct cl_io *io = ios->cis_io; struct cl_object *obj = io->ci_obj; struct inode *inode = vvp_object_inode(obj); - struct file *file = vio->cui_fd->fd_file; + struct file *file = vio->vui_fd->fd_file; int result; loff_t pos = io->u.ci_rd.rd.crw_pos; long cnt = io->u.ci_rd.rd.crw_count; - long tot = vio->cui_tot_count; + long tot = vio->vui_tot_count; int exceed = 0; CLOBINVRNT(env, obj, vvp_object_invariant(obj)); @@ -524,27 +525,27 @@ static int vvp_io_read_start(const struct lu_env *env, inode->i_ino, cnt, pos, i_size_read(inode)); /* turn off the kernel's read-ahead */ - vio->cui_fd->fd_file->f_ra.ra_pages = 0; + vio->vui_fd->fd_file->f_ra.ra_pages = 0; /* initialize read-ahead window once per syscall */ - if (!vio->cui_ra_valid) { - vio->cui_ra_valid = true; - vio->cui_ra_start = cl_index(obj, pos); - vio->cui_ra_count = cl_index(obj, tot + PAGE_CACHE_SIZE - 1); + if (!vio->vui_ra_valid) { + vio->vui_ra_valid = true; + vio->vui_ra_start = cl_index(obj, pos); + vio->vui_ra_count = cl_index(obj, tot + PAGE_CACHE_SIZE - 1); ll_ras_enter(file); } /* BUG: 5972 */ file_accessed(file); - switch (vio->cui_io_subtype) { + switch (vio->vui_io_subtype) { case IO_NORMAL: - LASSERT(vio->cui_iocb->ki_pos == pos); - result = generic_file_read_iter(vio->cui_iocb, vio->cui_iter); + LASSERT(vio->vui_iocb->ki_pos == pos); + result = generic_file_read_iter(vio->vui_iocb, vio->vui_iter); break; case IO_SPLICE: result = generic_file_splice_read(file, &pos, - vio->u.splice.cui_pipe, cnt, - vio->u.splice.cui_flags); + vio->u.splice.vui_pipe, cnt, + vio->u.splice.vui_flags); /* LU-1109: do splice read stripe by stripe otherwise if it * may make nfsd stuck if this read occupied all internal pipe * buffers. @@ -552,7 +553,7 @@ static int vvp_io_read_start(const struct lu_env *env, io->ci_continue = 0; break; default: - CERROR("Wrong IO type %u\n", vio->cui_io_subtype); + CERROR("Wrong IO type %u\n", vio->vui_io_subtype); LBUG(); } @@ -562,7 +563,7 @@ out: io->ci_continue = 0; io->ci_nob += result; ll_rw_stats_tally(ll_i2sbi(inode), current->pid, - vio->cui_fd, pos, result, READ); + vio->vui_fd, pos, result, READ); result = 0; } return result; @@ -674,24 +675,24 @@ int vvp_io_write_commit(const struct lu_env *env, struct cl_io *io) { struct cl_object *obj = io->ci_obj; struct inode *inode = vvp_object_inode(obj); - struct vvp_io *cio = vvp_env_io(env); - struct cl_page_list *queue = &cio->u.write.cui_queue; + struct vvp_io *vio = vvp_env_io(env); + struct cl_page_list *queue = &vio->u.write.vui_queue; struct cl_page *page; int rc = 0; int bytes = 0; - unsigned int npages = cio->u.write.cui_queue.pl_nr; + unsigned int npages = vio->u.write.vui_queue.pl_nr; if (npages == 0) return 0; CDEBUG(D_VFSTRACE, "commit async pages: %d, from %d, to %d\n", - npages, cio->u.write.cui_from, cio->u.write.cui_to); + npages, vio->u.write.vui_from, vio->u.write.vui_to); LASSERT(page_list_sanity_check(obj, queue)); /* submit IO with async write */ rc = cl_io_commit_async(env, io, queue, - cio->u.write.cui_from, cio->u.write.cui_to, + vio->u.write.vui_from, vio->u.write.vui_to, write_commit_callback); npages -= queue->pl_nr; /* already committed pages */ if (npages > 0) { @@ -699,18 +700,18 @@ int vvp_io_write_commit(const struct lu_env *env, struct cl_io *io) bytes = npages << PAGE_SHIFT; /* first page */ - bytes -= cio->u.write.cui_from; + bytes -= vio->u.write.vui_from; if (queue->pl_nr == 0) /* last page */ - bytes -= PAGE_SIZE - cio->u.write.cui_to; + bytes -= PAGE_SIZE - vio->u.write.vui_to; LASSERTF(bytes > 0, "bytes = %d, pages = %d\n", bytes, npages); - cio->u.write.cui_written += bytes; + vio->u.write.vui_written += bytes; CDEBUG(D_VFSTRACE, "Committed %d pages %d bytes, tot: %ld\n", - npages, bytes, cio->u.write.cui_written); + npages, bytes, vio->u.write.vui_written); /* the first page must have been written. */ - cio->u.write.cui_from = 0; + vio->u.write.vui_from = 0; } LASSERT(page_list_sanity_check(obj, queue)); LASSERT(ergo(rc == 0, queue->pl_nr == 0)); @@ -718,10 +719,10 @@ int vvp_io_write_commit(const struct lu_env *env, struct cl_io *io) /* out of quota, try sync write */ if (rc == -EDQUOT && !cl_io_is_mkwrite(io)) { rc = vvp_io_commit_sync(env, io, queue, - cio->u.write.cui_from, - cio->u.write.cui_to); + vio->u.write.vui_from, + vio->u.write.vui_to); if (rc > 0) { - cio->u.write.cui_written += rc; + vio->u.write.vui_written += rc; rc = 0; } } @@ -753,7 +754,7 @@ int vvp_io_write_commit(const struct lu_env *env, struct cl_io *io) static int vvp_io_write_start(const struct lu_env *env, const struct cl_io_slice *ios) { - struct vvp_io *cio = cl2vvp_io(env, ios); + struct vvp_io *vio = cl2vvp_io(env, ios); struct cl_io *io = ios->cis_io; struct cl_object *obj = io->ci_obj; struct inode *inode = vvp_object_inode(obj); @@ -771,22 +772,22 @@ static int vvp_io_write_start(const struct lu_env *env, */ ll_merge_attr(env, inode); pos = io->u.ci_wr.wr.crw_pos = i_size_read(inode); - cio->cui_iocb->ki_pos = pos; + vio->vui_iocb->ki_pos = pos; } else { - LASSERT(cio->cui_iocb->ki_pos == pos); + LASSERT(vio->vui_iocb->ki_pos == pos); } CDEBUG(D_VFSTRACE, "write: [%lli, %lli)\n", pos, pos + (long long)cnt); - if (!cio->cui_iter) /* from a temp io in ll_cl_init(). */ + if (!vio->vui_iter) /* from a temp io in ll_cl_init(). */ result = 0; else - result = generic_file_write_iter(cio->cui_iocb, cio->cui_iter); + result = generic_file_write_iter(vio->vui_iocb, vio->vui_iter); if (result > 0) { result = vvp_io_write_commit(env, io); - if (cio->u.write.cui_written > 0) { - result = cio->u.write.cui_written; + if (vio->u.write.vui_written > 0) { + result = vio->u.write.vui_written; io->ci_nob += result; CDEBUG(D_VFSTRACE, "write: nob %zd, result: %zd\n", @@ -803,7 +804,7 @@ static int vvp_io_write_start(const struct lu_env *env, if (result < cnt) io->ci_continue = 0; ll_rw_stats_tally(ll_i2sbi(inode), current->pid, - cio->cui_fd, pos, result, WRITE); + vio->vui_fd, pos, result, WRITE); result = 0; } return result; @@ -1047,7 +1048,7 @@ static int vvp_io_read_page(const struct lu_env *env, struct cl_page *page = slice->cpl_page; struct inode *inode = vvp_object_inode(slice->cpl_obj); struct ll_sb_info *sbi = ll_i2sbi(inode); - struct ll_file_data *fd = cl2vvp_io(env, ios)->cui_fd; + struct ll_file_data *fd = cl2vvp_io(env, ios)->vui_fd; struct ll_readahead_state *ras = &fd->fd_ras; struct cl_2queue *queue = &io->ci_queue; @@ -1128,11 +1129,11 @@ int vvp_io_init(const struct lu_env *env, struct cl_object *obj, " ignore/verify layout %d/%d, layout version %d restore needed %d\n", PFID(lu_object_fid(&obj->co_lu)), io->ci_ignore_layout, io->ci_verify_layout, - vio->cui_layout_gen, io->ci_restore_needed); + vio->vui_layout_gen, io->ci_restore_needed); - CL_IO_SLICE_CLEAN(vio, cui_cl); - cl_io_slice_add(io, &vio->cui_cl, obj, &vvp_io_ops); - vio->cui_ra_valid = false; + CL_IO_SLICE_CLEAN(vio, vui_cl); + cl_io_slice_add(io, &vio->vui_cl, obj, &vvp_io_ops); + vio->vui_ra_valid = false; result = 0; if (io->ci_type == CIT_READ || io->ci_type == CIT_WRITE) { size_t count; @@ -1145,7 +1146,7 @@ int vvp_io_init(const struct lu_env *env, struct cl_object *obj, if (count == 0) result = 1; else - vio->cui_tot_count = count; + vio->vui_tot_count = count; /* for read/write, we store the jobid in the inode, and * it'll be fetched by osc when building RPC. @@ -1171,7 +1172,7 @@ int vvp_io_init(const struct lu_env *env, struct cl_object *obj, * because it might not grant layout lock in IT_OPEN. */ if (result == 0 && !io->ci_ignore_layout) { - result = ll_layout_refresh(inode, &vio->cui_layout_gen); + result = ll_layout_refresh(inode, &vio->vui_layout_gen); if (result == -ENOENT) /* If the inode on MDS has been removed, but the objects * on OSTs haven't been destroyed (async unlink), layout diff --git a/drivers/staging/lustre/lustre/llite/vvp_page.c b/drivers/staging/lustre/lustre/llite/vvp_page.c index 4f7dfe221544..69316c191de6 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_page.c +++ b/drivers/staging/lustre/lustre/llite/vvp_page.c @@ -372,9 +372,9 @@ static int vvp_page_is_under_lock(const struct lu_env *env, { if (io->ci_type == CIT_READ || io->ci_type == CIT_WRITE || io->ci_type == CIT_FAULT) { - struct vvp_io *cio = vvp_env_io(env); + struct vvp_io *vio = vvp_env_io(env); - if (unlikely(cio->cui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) + if (unlikely(vio->vui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) *max_index = CL_PAGE_EOF; } return 0; -- cgit v1.2.3 From fee6eb5052fc394c6f40316052033cd69ee4ebc5 Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Wed, 30 Mar 2016 19:48:53 -0400 Subject: staging/lustre/llite: move vvp_io functions to vvp_io.c Move all vvp_io related functions from lustre/llite/lcommon_cl.c to the sole file where they are used lustre/llite/vvp_io.c. Signed-off-by: John L. Hammond Reviewed-on: http://review.whamcloud.com/13376 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5971 Reviewed-by: Jinshan Xiong Reviewed-by: Bobi Jam Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/lcommon_cl.c | 197 -------------------- .../staging/lustre/lustre/llite/llite_internal.h | 1 - drivers/staging/lustre/lustre/llite/vvp_internal.h | 22 +-- drivers/staging/lustre/lustre/llite/vvp_io.c | 198 ++++++++++++++++++++- 4 files changed, 196 insertions(+), 222 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c b/drivers/staging/lustre/lustre/llite/lcommon_cl.c index 630c37142d31..1b1110349312 100644 --- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c +++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c @@ -184,192 +184,6 @@ void ccc_global_fini(struct lu_device_type *device_type) lu_kmem_fini(ccc_caches); } -static void vvp_object_size_lock(struct cl_object *obj) -{ - struct inode *inode = vvp_object_inode(obj); - - ll_inode_size_lock(inode); - cl_object_attr_lock(obj); -} - -static void vvp_object_size_unlock(struct cl_object *obj) -{ - struct inode *inode = vvp_object_inode(obj); - - cl_object_attr_unlock(obj); - ll_inode_size_unlock(inode); -} - -/***************************************************************************** - * - * io operations. - * - */ - -int vvp_io_one_lock_index(const struct lu_env *env, struct cl_io *io, - __u32 enqflags, enum cl_lock_mode mode, - pgoff_t start, pgoff_t end) -{ - struct vvp_io *vio = vvp_env_io(env); - struct cl_lock_descr *descr = &vio->vui_link.cill_descr; - struct cl_object *obj = io->ci_obj; - - CLOBINVRNT(env, obj, vvp_object_invariant(obj)); - - CDEBUG(D_VFSTRACE, "lock: %d [%lu, %lu]\n", mode, start, end); - - memset(&vio->vui_link, 0, sizeof(vio->vui_link)); - - if (vio->vui_fd && (vio->vui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) { - descr->cld_mode = CLM_GROUP; - descr->cld_gid = vio->vui_fd->fd_grouplock.cg_gid; - } else { - descr->cld_mode = mode; - } - descr->cld_obj = obj; - descr->cld_start = start; - descr->cld_end = end; - descr->cld_enq_flags = enqflags; - - cl_io_lock_add(env, io, &vio->vui_link); - return 0; -} - -void vvp_io_update_iov(const struct lu_env *env, - struct vvp_io *vio, struct cl_io *io) -{ - size_t size = io->u.ci_rw.crw_count; - - if (!cl_is_normalio(env, io) || !vio->vui_iter) - return; - - iov_iter_truncate(vio->vui_iter, size); -} - -int vvp_io_one_lock(const struct lu_env *env, struct cl_io *io, - __u32 enqflags, enum cl_lock_mode mode, - loff_t start, loff_t end) -{ - struct cl_object *obj = io->ci_obj; - - return vvp_io_one_lock_index(env, io, enqflags, mode, - cl_index(obj, start), cl_index(obj, end)); -} - -void vvp_io_end(const struct lu_env *env, const struct cl_io_slice *ios) -{ - CLOBINVRNT(env, ios->cis_io->ci_obj, - vvp_object_invariant(ios->cis_io->ci_obj)); -} - -void vvp_io_advance(const struct lu_env *env, - const struct cl_io_slice *ios, - size_t nob) -{ - struct vvp_io *vio = cl2vvp_io(env, ios); - struct cl_io *io = ios->cis_io; - struct cl_object *obj = ios->cis_io->ci_obj; - - CLOBINVRNT(env, obj, vvp_object_invariant(obj)); - - if (!cl_is_normalio(env, io)) - return; - - iov_iter_reexpand(vio->vui_iter, vio->vui_tot_count -= nob); -} - -/** - * Helper function that if necessary adjusts file size (inode->i_size), when - * position at the offset \a pos is accessed. File size can be arbitrary stale - * on a Lustre client, but client at least knows KMS. If accessed area is - * inside [0, KMS], set file size to KMS, otherwise glimpse file size. - * - * Locking: cl_isize_lock is used to serialize changes to inode size and to - * protect consistency between inode size and cl_object - * attributes. cl_object_size_lock() protects consistency between cl_attr's of - * top-object and sub-objects. - */ -int ccc_prep_size(const struct lu_env *env, struct cl_object *obj, - struct cl_io *io, loff_t start, size_t count, int *exceed) -{ - struct cl_attr *attr = ccc_env_thread_attr(env); - struct inode *inode = vvp_object_inode(obj); - loff_t pos = start + count - 1; - loff_t kms; - int result; - - /* - * Consistency guarantees: following possibilities exist for the - * relation between region being accessed and real file size at this - * moment: - * - * (A): the region is completely inside of the file; - * - * (B-x): x bytes of region are inside of the file, the rest is - * outside; - * - * (C): the region is completely outside of the file. - * - * This classification is stable under DLM lock already acquired by - * the caller, because to change the class, other client has to take - * DLM lock conflicting with our lock. Also, any updates to ->i_size - * by other threads on this client are serialized by - * ll_inode_size_lock(). This guarantees that short reads are handled - * correctly in the face of concurrent writes and truncates. - */ - vvp_object_size_lock(obj); - result = cl_object_attr_get(env, obj, attr); - if (result == 0) { - kms = attr->cat_kms; - if (pos > kms) { - /* - * A glimpse is necessary to determine whether we - * return a short read (B) or some zeroes at the end - * of the buffer (C) - */ - vvp_object_size_unlock(obj); - result = cl_glimpse_lock(env, io, inode, obj, 0); - if (result == 0 && exceed) { - /* If objective page index exceed end-of-file - * page index, return directly. Do not expect - * kernel will check such case correctly. - * linux-2.6.18-128.1.1 miss to do that. - * --bug 17336 - */ - loff_t size = i_size_read(inode); - loff_t cur_index = start >> PAGE_CACHE_SHIFT; - loff_t size_index = (size - 1) >> - PAGE_CACHE_SHIFT; - - if ((size == 0 && cur_index != 0) || - size_index < cur_index) - *exceed = 1; - } - return result; - } - /* - * region is within kms and, hence, within real file - * size (A). We need to increase i_size to cover the - * read region so that generic_file_read() will do its - * job, but that doesn't mean the kms size is - * _correct_, it is only the _minimum_ size. If - * someone does a stat they will get the correct size - * which will always be >= the kms value here. - * b=11081 - */ - if (i_size_read(inode) < kms) { - i_size_write(inode, kms); - CDEBUG(D_VFSTRACE, DFID " updating i_size %llu\n", - PFID(lu_object_fid(&obj->co_lu)), - (__u64)i_size_read(inode)); - } - } - - vvp_object_size_unlock(obj); - - return result; -} - /***************************************************************************** * * Transfer operations. @@ -493,17 +307,6 @@ again: * */ -struct vvp_io *cl2vvp_io(const struct lu_env *env, - const struct cl_io_slice *slice) -{ - struct vvp_io *vio; - - vio = container_of(slice, struct vvp_io, vui_cl); - LASSERT(vio == vvp_env_io(env)); - - return vio; -} - struct ccc_req *cl2ccc_req(const struct cl_req_slice *slice) { return container_of0(slice, struct ccc_req, crq_cl); diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index 9856bb6daf15..86e93c04b12c 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -693,7 +693,6 @@ void ll_readahead_init(struct inode *inode, struct ll_readahead_state *ras); int ll_readahead(const struct lu_env *env, struct cl_io *io, struct cl_page_list *queue, struct ll_readahead_state *ras, bool hit); -int vvp_io_write_commit(const struct lu_env *env, struct cl_io *io); struct ll_cl_context *ll_cl_init(struct file *file, struct page *vmpage); void ll_cl_fini(struct ll_cl_context *lcc); diff --git a/drivers/staging/lustre/lustre/llite/vvp_internal.h b/drivers/staging/lustre/lustre/llite/vvp_internal.h index e04f23ea403e..7af8c445be77 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_internal.h +++ b/drivers/staging/lustre/lustre/llite/vvp_internal.h @@ -164,12 +164,6 @@ struct vvp_io { bool vui_ra_valid; }; -/** - * True, if \a io is a normal io, False for other splice_{read,write}. - * must be implemented in arch specific code. - */ -int cl_is_normalio(const struct lu_env *env, const struct cl_io *io); - extern struct lu_context_key ccc_key; extern struct lu_context_key vvp_session_key; @@ -334,19 +328,6 @@ void ccc_umount(const struct lu_env *env, struct cl_device *dev); int ccc_global_init(struct lu_device_type *device_type); void ccc_global_fini(struct lu_device_type *device_type); -int vvp_io_one_lock_index(const struct lu_env *env, struct cl_io *io, - __u32 enqflags, enum cl_lock_mode mode, - pgoff_t start, pgoff_t end); -int vvp_io_one_lock(const struct lu_env *env, struct cl_io *io, - __u32 enqflags, enum cl_lock_mode mode, - loff_t start, loff_t end); -void vvp_io_end(const struct lu_env *env, const struct cl_io_slice *ios); -void vvp_io_advance(const struct lu_env *env, const struct cl_io_slice *ios, - size_t nob); -void vvp_io_update_iov(const struct lu_env *env, struct vvp_io *cio, - struct cl_io *io); -int ccc_prep_size(const struct lu_env *env, struct cl_object *obj, - struct cl_io *io, loff_t start, size_t count, int *exceed); void ccc_req_completion(const struct lu_env *env, const struct cl_req_slice *slice, int ioret); void ccc_req_attr_set(const struct lu_env *env, @@ -397,8 +378,6 @@ static inline struct vvp_lock *cl2vvp_lock(const struct cl_lock_slice *slice) return container_of(slice, struct vvp_lock, vlk_cl); } -struct vvp_io *cl2vvp_io(const struct lu_env *env, - const struct cl_io_slice *slice); struct ccc_req *cl2ccc_req(const struct cl_req_slice *slice); int cl_setattr_ost(struct inode *inode, const struct iattr *attr); @@ -447,6 +426,7 @@ void ccc_inode_lsm_put(struct inode *inode, struct lov_stripe_md *lsm); int vvp_io_init(const struct lu_env *env, struct cl_object *obj, struct cl_io *io); +int vvp_io_write_commit(const struct lu_env *env, struct cl_io *io); int vvp_lock_init(const struct lu_env *env, struct cl_object *obj, struct cl_lock *lock, const struct cl_io *io); int vvp_page_init(const struct lu_env *env, struct cl_object *obj, diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c index 53cf2be0e152..48b0693edb1f 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_io.c +++ b/drivers/staging/lustre/lustre/llite/vvp_io.c @@ -47,10 +47,21 @@ #include "llite_internal.h" #include "vvp_internal.h" +struct vvp_io *cl2vvp_io(const struct lu_env *env, + const struct cl_io_slice *slice) +{ + struct vvp_io *vio; + + vio = container_of(slice, struct vvp_io, vui_cl); + LASSERT(vio == vvp_env_io(env)); + + return vio; +} + /** * True, if \a io is a normal io, False for splice_{read,write} */ -int cl_is_normalio(const struct lu_env *env, const struct cl_io *io) +static int cl_is_normalio(const struct lu_env *env, const struct cl_io *io) { struct vvp_io *vio = vvp_env_io(env); @@ -93,12 +104,160 @@ static bool can_populate_pages(const struct lu_env *env, struct cl_io *io, return rc; } +static void vvp_object_size_lock(struct cl_object *obj) +{ + struct inode *inode = vvp_object_inode(obj); + + ll_inode_size_lock(inode); + cl_object_attr_lock(obj); +} + +static void vvp_object_size_unlock(struct cl_object *obj) +{ + struct inode *inode = vvp_object_inode(obj); + + cl_object_attr_unlock(obj); + ll_inode_size_unlock(inode); +} + +/** + * Helper function that if necessary adjusts file size (inode->i_size), when + * position at the offset \a pos is accessed. File size can be arbitrary stale + * on a Lustre client, but client at least knows KMS. If accessed area is + * inside [0, KMS], set file size to KMS, otherwise glimpse file size. + * + * Locking: cl_isize_lock is used to serialize changes to inode size and to + * protect consistency between inode size and cl_object + * attributes. cl_object_size_lock() protects consistency between cl_attr's of + * top-object and sub-objects. + */ +static int vvp_prep_size(const struct lu_env *env, struct cl_object *obj, + struct cl_io *io, loff_t start, size_t count, + int *exceed) +{ + struct cl_attr *attr = ccc_env_thread_attr(env); + struct inode *inode = vvp_object_inode(obj); + loff_t pos = start + count - 1; + loff_t kms; + int result; + + /* + * Consistency guarantees: following possibilities exist for the + * relation between region being accessed and real file size at this + * moment: + * + * (A): the region is completely inside of the file; + * + * (B-x): x bytes of region are inside of the file, the rest is + * outside; + * + * (C): the region is completely outside of the file. + * + * This classification is stable under DLM lock already acquired by + * the caller, because to change the class, other client has to take + * DLM lock conflicting with our lock. Also, any updates to ->i_size + * by other threads on this client are serialized by + * ll_inode_size_lock(). This guarantees that short reads are handled + * correctly in the face of concurrent writes and truncates. + */ + vvp_object_size_lock(obj); + result = cl_object_attr_get(env, obj, attr); + if (result == 0) { + kms = attr->cat_kms; + if (pos > kms) { + /* + * A glimpse is necessary to determine whether we + * return a short read (B) or some zeroes at the end + * of the buffer (C) + */ + vvp_object_size_unlock(obj); + result = cl_glimpse_lock(env, io, inode, obj, 0); + if (result == 0 && exceed) { + /* If objective page index exceed end-of-file + * page index, return directly. Do not expect + * kernel will check such case correctly. + * linux-2.6.18-128.1.1 miss to do that. + * --bug 17336 + */ + loff_t size = i_size_read(inode); + loff_t cur_index = start >> PAGE_CACHE_SHIFT; + loff_t size_index = (size - 1) >> + PAGE_CACHE_SHIFT; + + if ((size == 0 && cur_index != 0) || + size_index < cur_index) + *exceed = 1; + } + return result; + } + /* + * region is within kms and, hence, within real file + * size (A). We need to increase i_size to cover the + * read region so that generic_file_read() will do its + * job, but that doesn't mean the kms size is + * _correct_, it is only the _minimum_ size. If + * someone does a stat they will get the correct size + * which will always be >= the kms value here. + * b=11081 + */ + if (i_size_read(inode) < kms) { + i_size_write(inode, kms); + CDEBUG(D_VFSTRACE, DFID " updating i_size %llu\n", + PFID(lu_object_fid(&obj->co_lu)), + (__u64)i_size_read(inode)); + } + } + + vvp_object_size_unlock(obj); + + return result; +} + /***************************************************************************** * * io operations. * */ +static int vvp_io_one_lock_index(const struct lu_env *env, struct cl_io *io, + __u32 enqflags, enum cl_lock_mode mode, + pgoff_t start, pgoff_t end) +{ + struct vvp_io *vio = vvp_env_io(env); + struct cl_lock_descr *descr = &vio->vui_link.cill_descr; + struct cl_object *obj = io->ci_obj; + + CLOBINVRNT(env, obj, vvp_object_invariant(obj)); + + CDEBUG(D_VFSTRACE, "lock: %d [%lu, %lu]\n", mode, start, end); + + memset(&vio->vui_link, 0, sizeof(vio->vui_link)); + + if (vio->vui_fd && (vio->vui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) { + descr->cld_mode = CLM_GROUP; + descr->cld_gid = vio->vui_fd->fd_grouplock.cg_gid; + } else { + descr->cld_mode = mode; + } + descr->cld_obj = obj; + descr->cld_start = start; + descr->cld_end = end; + descr->cld_enq_flags = enqflags; + + cl_io_lock_add(env, io, &vio->vui_link); + return 0; +} + +static int vvp_io_one_lock(const struct lu_env *env, struct cl_io *io, + __u32 enqflags, enum cl_lock_mode mode, + loff_t start, loff_t end) +{ + struct cl_object *obj = io->ci_obj; + + return vvp_io_one_lock_index(env, io, enqflags, mode, + cl_index(obj, start), cl_index(obj, end)); +} + static int vvp_io_write_iter_init(const struct lu_env *env, const struct cl_io_slice *ios) { @@ -303,6 +462,33 @@ static int vvp_mmap_locks(const struct lu_env *env, return result; } +static void vvp_io_advance(const struct lu_env *env, + const struct cl_io_slice *ios, + size_t nob) +{ + struct vvp_io *vio = cl2vvp_io(env, ios); + struct cl_io *io = ios->cis_io; + struct cl_object *obj = ios->cis_io->ci_obj; + + CLOBINVRNT(env, obj, vvp_object_invariant(obj)); + + if (!cl_is_normalio(env, io)) + return; + + iov_iter_reexpand(vio->vui_iter, vio->vui_tot_count -= nob); +} + +static void vvp_io_update_iov(const struct lu_env *env, + struct vvp_io *vio, struct cl_io *io) +{ + size_t size = io->u.ci_rw.crw_count; + + if (!cl_is_normalio(env, io) || !vio->vui_iter) + return; + + iov_iter_truncate(vio->vui_iter, size); +} + static int vvp_io_rw_lock(const struct lu_env *env, struct cl_io *io, enum cl_lock_mode mode, loff_t start, loff_t end) { @@ -514,7 +700,7 @@ static int vvp_io_read_start(const struct lu_env *env, if (!can_populate_pages(env, io, inode)) return 0; - result = ccc_prep_size(env, obj, io, pos, tot, &exceed); + result = vvp_prep_size(env, obj, io, pos, tot, &exceed); if (result != 0) return result; else if (exceed != 0) @@ -886,7 +1072,7 @@ static int vvp_io_fault_start(const struct lu_env *env, /* offset of the last byte on the page */ offset = cl_offset(obj, fio->ft_index + 1) - 1; LASSERT(cl_index(obj, offset) == fio->ft_index); - result = ccc_prep_size(env, obj, io, 0, offset + 1, NULL); + result = vvp_prep_size(env, obj, io, 0, offset + 1, NULL); if (result != 0) return result; @@ -1075,6 +1261,12 @@ static int vvp_io_read_page(const struct lu_env *env, return 0; } +void vvp_io_end(const struct lu_env *env, const struct cl_io_slice *ios) +{ + CLOBINVRNT(env, ios->cis_io->ci_obj, + vvp_object_invariant(ios->cis_io->ci_obj)); +} + static const struct cl_io_operations vvp_io_ops = { .op = { [CIT_READ] = { -- cgit v1.2.3 From 103b8bda3e4be03e3d05ccb3c2ae5bb4a9182067 Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Wed, 30 Mar 2016 19:48:54 -0400 Subject: staging/lustre/llite: rename ccc_req to vvp_req Rename struct ccc_req to struct vvp_req and move related functions from lustre/llite/lcommon_cl.c to the new file lustre/llite/vvp_req.c. Signed-off-by: John L. Hammond Reviewed-on: http://review.whamcloud.com/13377 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5971 Reviewed-by: Jinshan Xiong Reviewed-by: Bobi Jam Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/cl_object.h | 2 +- drivers/staging/lustre/lustre/llite/Makefile | 3 +- drivers/staging/lustre/lustre/llite/lcommon_cl.c | 104 ------------------ drivers/staging/lustre/lustre/llite/vvp_dev.c | 8 +- drivers/staging/lustre/lustre/llite/vvp_internal.h | 18 +-- drivers/staging/lustre/lustre/llite/vvp_req.c | 121 +++++++++++++++++++++ 6 files changed, 136 insertions(+), 120 deletions(-) create mode 100644 drivers/staging/lustre/lustre/llite/vvp_req.c (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h index 104dc9f15efb..918be65acdaf 100644 --- a/drivers/staging/lustre/lustre/include/cl_object.h +++ b/drivers/staging/lustre/lustre/include/cl_object.h @@ -140,7 +140,7 @@ struct cl_device_operations { * cl_req_slice_add(). * * \see osc_req_init(), lov_req_init(), lovsub_req_init() - * \see ccc_req_init() + * \see vvp_req_init() */ int (*cdo_req_init)(const struct lu_env *env, struct cl_device *dev, struct cl_req *req); diff --git a/drivers/staging/lustre/lustre/llite/Makefile b/drivers/staging/lustre/lustre/llite/Makefile index 24085e2624b4..2ce10ff01b80 100644 --- a/drivers/staging/lustre/lustre/llite/Makefile +++ b/drivers/staging/lustre/lustre/llite/Makefile @@ -5,6 +5,7 @@ lustre-y := dcache.o dir.o file.o llite_close.o llite_lib.o llite_nfs.o \ xattr.o xattr_cache.o remote_perm.o llite_rmtacl.o \ rw26.o super25.o statahead.o \ glimpse.o lcommon_cl.o lcommon_misc.o \ - vvp_dev.o vvp_page.o vvp_lock.o vvp_io.o vvp_object.o lproc_llite.o + vvp_dev.o vvp_page.o vvp_lock.o vvp_io.o vvp_object.o vvp_req.o \ + lproc_llite.o llite_lloop-y := lloop.o diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c b/drivers/staging/lustre/lustre/llite/lcommon_cl.c index 1b1110349312..d28546a1728e 100644 --- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c +++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c @@ -61,14 +61,11 @@ #include "../llite/llite_internal.h" -static const struct cl_req_operations ccc_req_ops; - /* * ccc_ prefix stands for "Common Client Code". */ static struct kmem_cache *ccc_thread_kmem; -static struct kmem_cache *ccc_req_kmem; static struct lu_kmem_descr ccc_caches[] = { { @@ -76,11 +73,6 @@ static struct lu_kmem_descr ccc_caches[] = { .ckd_name = "ccc_thread_kmem", .ckd_size = sizeof(struct ccc_thread_info), }, - { - .ckd_cache = &ccc_req_kmem, - .ckd_name = "ccc_req_kmem", - .ckd_size = sizeof(struct ccc_req) - }, { .ckd_cache = NULL } @@ -116,22 +108,6 @@ struct lu_context_key ccc_key = { .lct_fini = ccc_key_fini }; -int ccc_req_init(const struct lu_env *env, struct cl_device *dev, - struct cl_req *req) -{ - struct ccc_req *vrq; - int result; - - vrq = kmem_cache_zalloc(ccc_req_kmem, GFP_NOFS); - if (vrq) { - cl_req_slice_add(req, &vrq->crq_cl, dev, &ccc_req_ops); - result = 0; - } else { - result = -ENOMEM; - } - return result; -} - /** * An `emergency' environment used by ccc_inode_fini() when cl_env_get() * fails. Access to this environment is serialized by ccc_inode_fini_guard @@ -184,75 +160,6 @@ void ccc_global_fini(struct lu_device_type *device_type) lu_kmem_fini(ccc_caches); } -/***************************************************************************** - * - * Transfer operations. - * - */ - -void ccc_req_completion(const struct lu_env *env, - const struct cl_req_slice *slice, int ioret) -{ - struct ccc_req *vrq; - - if (ioret > 0) - cl_stats_tally(slice->crs_dev, slice->crs_req->crq_type, ioret); - - vrq = cl2ccc_req(slice); - kmem_cache_free(ccc_req_kmem, vrq); -} - -/** - * Implementation of struct cl_req_operations::cro_attr_set() for ccc - * layer. ccc is responsible for - * - * - o_[mac]time - * - * - o_mode - * - * - o_parent_seq - * - * - o_[ug]id - * - * - o_parent_oid - * - * - o_parent_ver - * - * - o_ioepoch, - * - */ -void ccc_req_attr_set(const struct lu_env *env, - const struct cl_req_slice *slice, - const struct cl_object *obj, - struct cl_req_attr *attr, u64 flags) -{ - struct inode *inode; - struct obdo *oa; - u32 valid_flags; - - oa = attr->cra_oa; - inode = vvp_object_inode(obj); - valid_flags = OBD_MD_FLTYPE; - - if (slice->crs_req->crq_type == CRT_WRITE) { - if (flags & OBD_MD_FLEPOCH) { - oa->o_valid |= OBD_MD_FLEPOCH; - oa->o_ioepoch = ll_i2info(inode)->lli_ioepoch; - valid_flags |= OBD_MD_FLMTIME | OBD_MD_FLCTIME | - OBD_MD_FLUID | OBD_MD_FLGID; - } - } - obdo_from_inode(oa, inode, valid_flags & flags); - obdo_set_parent_fid(oa, &ll_i2info(inode)->lli_fid); - memcpy(attr->cra_jobid, ll_i2info(inode)->lli_jobid, - JOBSTATS_JOBID_SIZE); -} - -static const struct cl_req_operations ccc_req_ops = { - .cro_attr_set = ccc_req_attr_set, - .cro_completion = ccc_req_completion -}; - int cl_setattr_ost(struct inode *inode, const struct iattr *attr) { struct lu_env *env; @@ -301,17 +208,6 @@ again: return result; } -/***************************************************************************** - * - * Type conversions. - * - */ - -struct ccc_req *cl2ccc_req(const struct cl_req_slice *slice) -{ - return container_of0(slice, struct ccc_req, crq_cl); -} - /** * Initialize or update CLIO structures for regular files when new * meta-data arrives from the server. diff --git a/drivers/staging/lustre/lustre/llite/vvp_dev.c b/drivers/staging/lustre/lustre/llite/vvp_dev.c index 030a2460cf24..5d3beb62423c 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_dev.c +++ b/drivers/staging/lustre/lustre/llite/vvp_dev.c @@ -59,6 +59,7 @@ struct kmem_cache *vvp_lock_kmem; struct kmem_cache *vvp_object_kmem; +struct kmem_cache *vvp_req_kmem; static struct kmem_cache *vvp_thread_kmem; static struct kmem_cache *vvp_session_kmem; static struct lu_kmem_descr vvp_caches[] = { @@ -72,6 +73,11 @@ static struct lu_kmem_descr vvp_caches[] = { .ckd_name = "vvp_object_kmem", .ckd_size = sizeof(struct vvp_object), }, + { + .ckd_cache = &vvp_req_kmem, + .ckd_name = "vvp_req_kmem", + .ckd_size = sizeof(struct vvp_req), + }, { .ckd_cache = &vvp_thread_kmem, .ckd_name = "vvp_thread_kmem", @@ -145,7 +151,7 @@ static const struct lu_device_operations vvp_lu_ops = { }; static const struct cl_device_operations vvp_cl_ops = { - .cdo_req_init = ccc_req_init + .cdo_req_init = vvp_req_init }; static struct lu_device *vvp_device_free(const struct lu_env *env, diff --git a/drivers/staging/lustre/lustre/llite/vvp_internal.h b/drivers/staging/lustre/lustre/llite/vvp_internal.h index 7af8c445be77..99e7ef347069 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_internal.h +++ b/drivers/staging/lustre/lustre/llite/vvp_internal.h @@ -169,6 +169,7 @@ extern struct lu_context_key vvp_session_key; extern struct kmem_cache *vvp_lock_kmem; extern struct kmem_cache *vvp_object_kmem; +extern struct kmem_cache *vvp_req_kmem; struct ccc_thread_info { struct cl_lock cti_lock; @@ -313,8 +314,8 @@ struct vvp_lock { struct cl_lock_slice vlk_cl; }; -struct ccc_req { - struct cl_req_slice crq_cl; +struct vvp_req { + struct cl_req_slice vrq_cl; }; void *ccc_key_init(const struct lu_context *ctx, @@ -322,19 +323,10 @@ void *ccc_key_init(const struct lu_context *ctx, void ccc_key_fini(const struct lu_context *ctx, struct lu_context_key *key, void *data); -int ccc_req_init(const struct lu_env *env, struct cl_device *dev, - struct cl_req *req); void ccc_umount(const struct lu_env *env, struct cl_device *dev); int ccc_global_init(struct lu_device_type *device_type); void ccc_global_fini(struct lu_device_type *device_type); -void ccc_req_completion(const struct lu_env *env, - const struct cl_req_slice *slice, int ioret); -void ccc_req_attr_set(const struct lu_env *env, - const struct cl_req_slice *slice, - const struct cl_object *obj, - struct cl_req_attr *oa, u64 flags); - static inline struct lu_device *vvp2lu_dev(struct vvp_device *vdv) { return &vdv->vdv_cl.cd_lu_dev; @@ -378,8 +370,6 @@ static inline struct vvp_lock *cl2vvp_lock(const struct cl_lock_slice *slice) return container_of(slice, struct vvp_lock, vlk_cl); } -struct ccc_req *cl2ccc_req(const struct cl_req_slice *slice); - int cl_setattr_ost(struct inode *inode, const struct iattr *attr); int cl_file_inode_init(struct inode *inode, struct lustre_md *md); @@ -431,6 +421,8 @@ int vvp_lock_init(const struct lu_env *env, struct cl_object *obj, struct cl_lock *lock, const struct cl_io *io); int vvp_page_init(const struct lu_env *env, struct cl_object *obj, struct cl_page *page, pgoff_t index); +int vvp_req_init(const struct lu_env *env, struct cl_device *dev, + struct cl_req *req); struct lu_object *vvp_object_alloc(const struct lu_env *env, const struct lu_object_header *hdr, struct lu_device *dev); diff --git a/drivers/staging/lustre/lustre/llite/vvp_req.c b/drivers/staging/lustre/lustre/llite/vvp_req.c new file mode 100644 index 000000000000..fb886291a4e2 --- /dev/null +++ b/drivers/staging/lustre/lustre/llite/vvp_req.c @@ -0,0 +1,121 @@ +/* + * GPL HEADER START + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 only, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 for more details (a copy is included + * in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; If not, see + * http://www.gnu.org/licenses/gpl-2.0.html + * + * GPL HEADER END + */ +/* + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Use is subject to license terms. + * + * Copyright (c) 2011, 2014, Intel Corporation. + */ + +#define DEBUG_SUBSYSTEM S_LLITE + +#include "../include/lustre/lustre_idl.h" +#include "../include/cl_object.h" +#include "../include/obd.h" +#include "../include/obd_support.h" +#include "../include/lustre_lite.h" +#include "llite_internal.h" +#include "vvp_internal.h" + +static inline struct vvp_req *cl2vvp_req(const struct cl_req_slice *slice) +{ + return container_of0(slice, struct vvp_req, vrq_cl); +} + +/** + * Implementation of struct cl_req_operations::cro_attr_set() for VVP + * layer. VVP is responsible for + * + * - o_[mac]time + * + * - o_mode + * + * - o_parent_seq + * + * - o_[ug]id + * + * - o_parent_oid + * + * - o_parent_ver + * + * - o_ioepoch, + * + */ +void vvp_req_attr_set(const struct lu_env *env, + const struct cl_req_slice *slice, + const struct cl_object *obj, + struct cl_req_attr *attr, u64 flags) +{ + struct inode *inode; + struct obdo *oa; + u32 valid_flags; + + oa = attr->cra_oa; + inode = vvp_object_inode(obj); + valid_flags = OBD_MD_FLTYPE; + + if (slice->crs_req->crq_type == CRT_WRITE) { + if (flags & OBD_MD_FLEPOCH) { + oa->o_valid |= OBD_MD_FLEPOCH; + oa->o_ioepoch = ll_i2info(inode)->lli_ioepoch; + valid_flags |= OBD_MD_FLMTIME | OBD_MD_FLCTIME | + OBD_MD_FLUID | OBD_MD_FLGID; + } + } + obdo_from_inode(oa, inode, valid_flags & flags); + obdo_set_parent_fid(oa, &ll_i2info(inode)->lli_fid); + memcpy(attr->cra_jobid, ll_i2info(inode)->lli_jobid, + JOBSTATS_JOBID_SIZE); +} + +void vvp_req_completion(const struct lu_env *env, + const struct cl_req_slice *slice, int ioret) +{ + struct vvp_req *vrq; + + if (ioret > 0) + cl_stats_tally(slice->crs_dev, slice->crs_req->crq_type, ioret); + + vrq = cl2vvp_req(slice); + kmem_cache_free(vvp_req_kmem, vrq); +} + +static const struct cl_req_operations vvp_req_ops = { + .cro_attr_set = vvp_req_attr_set, + .cro_completion = vvp_req_completion +}; + +int vvp_req_init(const struct lu_env *env, struct cl_device *dev, + struct cl_req *req) +{ + struct vvp_req *vrq; + int result; + + vrq = kmem_cache_zalloc(vvp_req_kmem, GFP_NOFS); + if (vrq) { + cl_req_slice_add(req, &vrq->vrq_cl, dev, &vvp_req_ops); + result = 0; + } else { + result = -ENOMEM; + } + return result; +} -- cgit v1.2.3 From 98eae5e71cdcf2954f9b022a78d0507878410df6 Mon Sep 17 00:00:00 2001 From: John Hammond Date: Wed, 30 Mar 2016 19:48:55 -0400 Subject: staging/lustre/llite: Rename struct ccc_grouplock to ll_grouplock And move the definition from vvp_internal.h to llite_internal.h. Signed-off-by: John L. Hammond Signed-off-by: Jinshan Xiong Reviewed-on: http://review.whamcloud.com/13714 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5971 Reviewed-by: Bobi Jam Reviewed-by: James Simmons Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/file.c | 16 ++++++------- drivers/staging/lustre/lustre/llite/lcommon_misc.c | 26 +++++++++++----------- .../staging/lustre/lustre/llite/llite_internal.h | 14 +++++++++++- drivers/staging/lustre/lustre/llite/vvp_internal.h | 11 --------- drivers/staging/lustre/lustre/llite/vvp_io.c | 2 +- 5 files changed, 35 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index 63aa080785d4..210d1e22660a 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -278,7 +278,7 @@ static int ll_md_close(struct obd_export *md_exp, struct inode *inode, /* clear group lock, if present */ if (unlikely(fd->fd_flags & LL_FILE_GROUP_LOCKED)) - ll_put_grouplock(inode, file, fd->fd_grouplock.cg_gid); + ll_put_grouplock(inode, file, fd->fd_grouplock.lg_gid); if (fd->fd_lease_och) { bool lease_broken; @@ -1570,7 +1570,7 @@ ll_get_grouplock(struct inode *inode, struct file *file, unsigned long arg) { struct ll_inode_info *lli = ll_i2info(inode); struct ll_file_data *fd = LUSTRE_FPRIVATE(file); - struct ccc_grouplock grouplock; + struct ll_grouplock grouplock; int rc; if (arg == 0) { @@ -1584,11 +1584,11 @@ ll_get_grouplock(struct inode *inode, struct file *file, unsigned long arg) spin_lock(&lli->lli_lock); if (fd->fd_flags & LL_FILE_GROUP_LOCKED) { CWARN("group lock already existed with gid %lu\n", - fd->fd_grouplock.cg_gid); + fd->fd_grouplock.lg_gid); spin_unlock(&lli->lli_lock); return -EINVAL; } - LASSERT(!fd->fd_grouplock.cg_lock); + LASSERT(!fd->fd_grouplock.lg_lock); spin_unlock(&lli->lli_lock); rc = cl_get_grouplock(ll_i2info(inode)->lli_clob, @@ -1617,7 +1617,7 @@ static int ll_put_grouplock(struct inode *inode, struct file *file, { struct ll_inode_info *lli = ll_i2info(inode); struct ll_file_data *fd = LUSTRE_FPRIVATE(file); - struct ccc_grouplock grouplock; + struct ll_grouplock grouplock; spin_lock(&lli->lli_lock); if (!(fd->fd_flags & LL_FILE_GROUP_LOCKED)) { @@ -1625,11 +1625,11 @@ static int ll_put_grouplock(struct inode *inode, struct file *file, CWARN("no group lock held\n"); return -EINVAL; } - LASSERT(fd->fd_grouplock.cg_lock); + LASSERT(fd->fd_grouplock.lg_lock); - if (fd->fd_grouplock.cg_gid != arg) { + if (fd->fd_grouplock.lg_gid != arg) { CWARN("group lock %lu doesn't match current id %lu\n", - arg, fd->fd_grouplock.cg_gid); + arg, fd->fd_grouplock.lg_gid); spin_unlock(&lli->lli_lock); return -EINVAL; } diff --git a/drivers/staging/lustre/lustre/llite/lcommon_misc.c b/drivers/staging/lustre/lustre/llite/lcommon_misc.c index 68e3db1f1b4c..5e3e43fe9550 100644 --- a/drivers/staging/lustre/lustre/llite/lcommon_misc.c +++ b/drivers/staging/lustre/lustre/llite/lcommon_misc.c @@ -42,8 +42,8 @@ #include "../include/obd.h" #include "../include/cl_object.h" -#include "vvp_internal.h" #include "../include/lustre_lite.h" +#include "llite_internal.h" /* Initialize the default and maximum LOV EA and cookie sizes. This allows * us to make MDS RPCs with large enough reply buffers to hold the @@ -126,7 +126,7 @@ int cl_ocd_update(struct obd_device *host, #define GROUPLOCK_SCOPE "grouplock" int cl_get_grouplock(struct cl_object *obj, unsigned long gid, int nonblock, - struct ccc_grouplock *cg) + struct ll_grouplock *cg) { struct lu_env *env; struct cl_io *io; @@ -172,25 +172,25 @@ int cl_get_grouplock(struct cl_object *obj, unsigned long gid, int nonblock, return rc; } - cg->cg_env = cl_env_get(&refcheck); - cg->cg_io = io; - cg->cg_lock = lock; - cg->cg_gid = gid; - LASSERT(cg->cg_env == env); + cg->lg_env = cl_env_get(&refcheck); + cg->lg_io = io; + cg->lg_lock = lock; + cg->lg_gid = gid; + LASSERT(cg->lg_env == env); cl_env_unplant(env, &refcheck); return 0; } -void cl_put_grouplock(struct ccc_grouplock *cg) +void cl_put_grouplock(struct ll_grouplock *cg) { - struct lu_env *env = cg->cg_env; - struct cl_io *io = cg->cg_io; - struct cl_lock *lock = cg->cg_lock; + struct lu_env *env = cg->lg_env; + struct cl_io *io = cg->lg_io; + struct cl_lock *lock = cg->lg_lock; int refcheck; - LASSERT(cg->cg_env); - LASSERT(cg->cg_gid); + LASSERT(cg->lg_env); + LASSERT(cg->lg_gid); cl_env_implant(env, &refcheck); cl_env_put(env, &refcheck); diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index 86e93c04b12c..8b943df111e1 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -99,6 +99,13 @@ struct ll_remote_perm { */ }; +struct ll_grouplock { + struct lu_env *lg_env; + struct cl_io *lg_io; + struct cl_lock *lg_lock; + unsigned long lg_gid; +}; + enum lli_flags { /* MDS has an authority for the Size-on-MDS attributes. */ LLIF_MDS_SIZE_LOCK = (1 << 0), @@ -612,7 +619,7 @@ extern struct kmem_cache *ll_file_data_slab; struct lustre_handle; struct ll_file_data { struct ll_readahead_state fd_ras; - struct ccc_grouplock fd_grouplock; + struct ll_grouplock fd_grouplock; __u64 lfd_pos; __u32 fd_flags; fmode_t fd_omode; @@ -655,6 +662,11 @@ static inline int ll_need_32bit_api(struct ll_sb_info *sbi) void ll_ras_enter(struct file *f); +/* llite/lcommon_misc.c */ +int cl_get_grouplock(struct cl_object *obj, unsigned long gid, int nonblock, + struct ll_grouplock *cg); +void cl_put_grouplock(struct ll_grouplock *cg); + /* llite/lproc_llite.c */ int ldebugfs_register_mountpoint(struct dentry *parent, struct super_block *sb, char *osc, char *mdc); diff --git a/drivers/staging/lustre/lustre/llite/vvp_internal.h b/drivers/staging/lustre/lustre/llite/vvp_internal.h index 99e7ef347069..4740ff51a2b7 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_internal.h +++ b/drivers/staging/lustre/lustre/llite/vvp_internal.h @@ -388,17 +388,6 @@ int cl_ocd_update(struct obd_device *host, struct obd_device *watched, enum obd_notify_event ev, void *owner, void *data); -struct ccc_grouplock { - struct lu_env *cg_env; - struct cl_io *cg_io; - struct cl_lock *cg_lock; - unsigned long cg_gid; -}; - -int cl_get_grouplock(struct cl_object *obj, unsigned long gid, int nonblock, - struct ccc_grouplock *cg); -void cl_put_grouplock(struct ccc_grouplock *cg); - /** * New interfaces to get and put lov_stripe_md from lov layer. This violates * layering because lov_stripe_md is supposed to be a private data in lov. diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c index 48b0693edb1f..18bc71b8777d 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_io.c +++ b/drivers/staging/lustre/lustre/llite/vvp_io.c @@ -235,7 +235,7 @@ static int vvp_io_one_lock_index(const struct lu_env *env, struct cl_io *io, if (vio->vui_fd && (vio->vui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) { descr->cld_mode = CLM_GROUP; - descr->cld_gid = vio->vui_fd->fd_grouplock.cg_gid; + descr->cld_gid = vio->vui_fd->fd_grouplock.lg_gid; } else { descr->cld_mode = mode; } -- cgit v1.2.3 From 9989a58ee1b1e47008870e60583cefc105402cfa Mon Sep 17 00:00:00 2001 From: John Hammond Date: Wed, 30 Mar 2016 19:48:56 -0400 Subject: staging/lustre/llite: Rename struct vvp_thread_info to ll_thread_info struct vvp_thread_info is used in the non-VVP parts of llite so rename it struct ll_thread_info. Rename supporting functions accordingly. Signed-off-by: John L. Hammond Signed-off-by: Jinshan Xiong Reviewed-on: http://review.whamcloud.com/13714 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5971 Reviewed-by: Bobi Jam Reviewed-by: James Simmons Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/file.c | 6 ++-- .../staging/lustre/lustre/llite/llite_internal.h | 30 ++++++++--------- drivers/staging/lustre/lustre/llite/rw.c | 6 ++-- drivers/staging/lustre/lustre/llite/vvp_dev.c | 38 +++++++++++----------- 4 files changed, 40 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index 210d1e22660a..f7aabacb1f5c 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -1221,7 +1221,7 @@ static ssize_t ll_file_read_iter(struct kiocb *iocb, struct iov_iter *to) if (IS_ERR(env)) return PTR_ERR(env); - args = vvp_env_args(env, IO_NORMAL); + args = ll_env_args(env, IO_NORMAL); args->u.normal.via_iter = to; args->u.normal.via_iocb = iocb; @@ -1245,7 +1245,7 @@ static ssize_t ll_file_write_iter(struct kiocb *iocb, struct iov_iter *from) if (IS_ERR(env)) return PTR_ERR(env); - args = vvp_env_args(env, IO_NORMAL); + args = ll_env_args(env, IO_NORMAL); args->u.normal.via_iter = from; args->u.normal.via_iocb = iocb; @@ -1271,7 +1271,7 @@ static ssize_t ll_file_splice_read(struct file *in_file, loff_t *ppos, if (IS_ERR(env)) return PTR_ERR(env); - args = vvp_env_args(env, IO_SPLICE); + args = ll_env_args(env, IO_SPLICE); args->u.splice.via_pipe = pipe; args->u.splice.via_flags = flags; diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index 8b943df111e1..a6ee2fe31fdc 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -855,30 +855,30 @@ struct ll_cl_context { int lcc_refcheck; }; -struct vvp_thread_info { - struct vvp_io_args vti_args; - struct ra_io_arg vti_ria; - struct ll_cl_context vti_io_ctx; +struct ll_thread_info { + struct vvp_io_args lti_args; + struct ra_io_arg lti_ria; + struct ll_cl_context lti_io_ctx; }; -static inline struct vvp_thread_info *vvp_env_info(const struct lu_env *env) +extern struct lu_context_key ll_thread_key; +static inline struct ll_thread_info *ll_env_info(const struct lu_env *env) { - extern struct lu_context_key vvp_key; - struct vvp_thread_info *info; + struct ll_thread_info *lti; - info = lu_context_key_get(&env->le_ctx, &vvp_key); - LASSERT(info); - return info; + lti = lu_context_key_get(&env->le_ctx, &ll_thread_key); + LASSERT(lti); + return lti; } -static inline struct vvp_io_args *vvp_env_args(const struct lu_env *env, - enum vvp_io_subtype type) +static inline struct vvp_io_args *ll_env_args(const struct lu_env *env, + enum vvp_io_subtype type) { - struct vvp_io_args *ret = &vvp_env_info(env)->vti_args; + struct vvp_io_args *via = &ll_env_info(env)->lti_args; - ret->via_io_subtype = type; + via->via_io_subtype = type; - return ret; + return via; } int vvp_global_init(void); diff --git a/drivers/staging/lustre/lustre/llite/rw.c b/drivers/staging/lustre/lustre/llite/rw.c index 634f0bb355e3..f9bc3e44b072 100644 --- a/drivers/staging/lustre/lustre/llite/rw.c +++ b/drivers/staging/lustre/lustre/llite/rw.c @@ -102,7 +102,7 @@ struct ll_cl_context *ll_cl_init(struct file *file, struct page *vmpage) if (IS_ERR(env)) return ERR_CAST(env); - lcc = &vvp_env_info(env)->vti_io_ctx; + lcc = &ll_env_info(env)->lti_io_ctx; memset(lcc, 0, sizeof(*lcc)); lcc->lcc_env = env; lcc->lcc_refcheck = refcheck; @@ -523,12 +523,12 @@ int ll_readahead(const struct lu_env *env, struct cl_io *io, bool hit) { struct vvp_io *vio = vvp_env_io(env); - struct vvp_thread_info *vti = vvp_env_info(env); + struct ll_thread_info *lti = ll_env_info(env); struct cl_attr *attr = ccc_env_thread_attr(env); unsigned long start = 0, end = 0, reserved; unsigned long ra_end, len, mlen = 0; struct inode *inode; - struct ra_io_arg *ria = &vti->vti_ria; + struct ra_io_arg *ria = <i->lti_ria; struct cl_object *clob; int ret = 0; __u64 kms; diff --git a/drivers/staging/lustre/lustre/llite/vvp_dev.c b/drivers/staging/lustre/lustre/llite/vvp_dev.c index 5d3beb62423c..227843327f09 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_dev.c +++ b/drivers/staging/lustre/lustre/llite/vvp_dev.c @@ -57,12 +57,17 @@ * "llite_" (var. "ll_") prefix. */ +static struct kmem_cache *ll_thread_kmem; struct kmem_cache *vvp_lock_kmem; struct kmem_cache *vvp_object_kmem; struct kmem_cache *vvp_req_kmem; -static struct kmem_cache *vvp_thread_kmem; static struct kmem_cache *vvp_session_kmem; static struct lu_kmem_descr vvp_caches[] = { + { + .ckd_cache = &ll_thread_kmem, + .ckd_name = "ll_thread_kmem", + .ckd_size = sizeof(struct ll_thread_info), + }, { .ckd_cache = &vvp_lock_kmem, .ckd_name = "vvp_lock_kmem", @@ -78,11 +83,6 @@ static struct lu_kmem_descr vvp_caches[] = { .ckd_name = "vvp_req_kmem", .ckd_size = sizeof(struct vvp_req), }, - { - .ckd_cache = &vvp_thread_kmem, - .ckd_name = "vvp_thread_kmem", - .ckd_size = sizeof(struct vvp_thread_info), - }, { .ckd_cache = &vvp_session_kmem, .ckd_name = "vvp_session_kmem", @@ -93,25 +93,31 @@ static struct lu_kmem_descr vvp_caches[] = { } }; -static void *vvp_key_init(const struct lu_context *ctx, - struct lu_context_key *key) +static void *ll_thread_key_init(const struct lu_context *ctx, + struct lu_context_key *key) { struct vvp_thread_info *info; - info = kmem_cache_zalloc(vvp_thread_kmem, GFP_NOFS); + info = kmem_cache_zalloc(ll_thread_kmem, GFP_NOFS); if (!info) info = ERR_PTR(-ENOMEM); return info; } -static void vvp_key_fini(const struct lu_context *ctx, - struct lu_context_key *key, void *data) +static void ll_thread_key_fini(const struct lu_context *ctx, + struct lu_context_key *key, void *data) { struct vvp_thread_info *info = data; - kmem_cache_free(vvp_thread_kmem, info); + kmem_cache_free(ll_thread_kmem, info); } +struct lu_context_key ll_thread_key = { + .lct_tags = LCT_CL_THREAD, + .lct_init = ll_thread_key_init, + .lct_fini = ll_thread_key_fini +}; + static void *vvp_session_key_init(const struct lu_context *ctx, struct lu_context_key *key) { @@ -131,12 +137,6 @@ static void vvp_session_key_fini(const struct lu_context *ctx, kmem_cache_free(vvp_session_kmem, session); } -struct lu_context_key vvp_key = { - .lct_tags = LCT_CL_THREAD, - .lct_init = vvp_key_init, - .lct_fini = vvp_key_fini -}; - struct lu_context_key vvp_session_key = { .lct_tags = LCT_SESSION, .lct_init = vvp_session_key_init, @@ -144,7 +144,7 @@ struct lu_context_key vvp_session_key = { }; /* type constructor/destructor: vvp_type_{init,fini,start,stop}(). */ -LU_TYPE_INIT_FINI(vvp, &ccc_key, &vvp_key, &vvp_session_key); +LU_TYPE_INIT_FINI(vvp, &ccc_key, &ll_thread_key, &vvp_session_key); static const struct lu_device_operations vvp_lu_ops = { .ldo_object_alloc = vvp_object_alloc -- cgit v1.2.3 From 9acc4500b44723d12bec63519038ef820479eaad Mon Sep 17 00:00:00 2001 From: John Hammond Date: Wed, 30 Mar 2016 19:48:57 -0400 Subject: staging/lustre/llite: rename struct ccc_thread_info to vvp_thread_info struct ccc_thread_info is used in the VVP parts of llite so rename it struct vvp_thread_info. Rename supporting functions accordingly. Move init code from lcommon_cl.c to vvp_dev.c Signed-off-by: John L. Hammond Signed-off-by: Jinshan Xiong Reviewed-on: http://review.whamcloud.com/13714 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5971 Reviewed-by: Bobi Jam Reviewed-by: James Simmons Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/file.c | 6 +-- drivers/staging/lustre/lustre/llite/glimpse.c | 6 +-- drivers/staging/lustre/lustre/llite/lcommon_cl.c | 48 +--------------------- drivers/staging/lustre/lustre/llite/lcommon_misc.c | 4 +- drivers/staging/lustre/lustre/llite/llite_mmap.c | 2 +- drivers/staging/lustre/lustre/llite/rw.c | 4 +- drivers/staging/lustre/lustre/llite/rw26.c | 2 +- drivers/staging/lustre/lustre/llite/vvp_dev.c | 34 ++++++++++++++- drivers/staging/lustre/lustre/llite/vvp_internal.h | 34 +++++++-------- drivers/staging/lustre/lustre/llite/vvp_io.c | 8 ++-- 10 files changed, 68 insertions(+), 80 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index f7aabacb1f5c..69b56a816fcb 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -998,7 +998,7 @@ int ll_merge_attr(const struct lu_env *env, struct inode *inode) { struct ll_inode_info *lli = ll_i2info(inode); struct cl_object *obj = lli->lli_clob; - struct cl_attr *attr = ccc_env_thread_attr(env); + struct cl_attr *attr = vvp_env_thread_attr(env); s64 atime; s64 mtime; s64 ctime; @@ -1131,7 +1131,7 @@ ll_file_io_generic(const struct lu_env *env, struct vvp_io_args *args, file->f_path.dentry->d_name.name, iot, *ppos, count); restart: - io = ccc_env_thread_io(env); + io = vvp_env_thread_io(env); ll_io_init(io, file, iot == CIT_WRITE); if (cl_io_rw_init(env, io, iot, *ppos, count) == 0) { @@ -2612,7 +2612,7 @@ int cl_sync_file_range(struct inode *inode, loff_t start, loff_t end, if (IS_ERR(env)) return PTR_ERR(env); - io = ccc_env_thread_io(env); + io = vvp_env_thread_io(env); io->ci_obj = ll_i2info(inode)->lli_clob; io->ci_ignore_layout = ignore_layout; diff --git a/drivers/staging/lustre/lustre/llite/glimpse.c b/drivers/staging/lustre/lustre/llite/glimpse.c index d76fa163c362..d8ea75424e2f 100644 --- a/drivers/staging/lustre/lustre/llite/glimpse.c +++ b/drivers/staging/lustre/lustre/llite/glimpse.c @@ -93,7 +93,7 @@ int cl_glimpse_lock(const struct lu_env *env, struct cl_io *io, if (!(lli->lli_flags & LLIF_MDS_SIZE_LOCK)) { CDEBUG(D_DLMTRACE, "Glimpsing inode " DFID "\n", PFID(fid)); if (lli->lli_has_smd) { - struct cl_lock *lock = ccc_env_lock(env); + struct cl_lock *lock = vvp_env_lock(env); struct cl_lock_descr *descr = &lock->cll_descr; /* NOTE: this looks like DLM lock request, but it may @@ -163,7 +163,7 @@ static int cl_io_get(struct inode *inode, struct lu_env **envout, if (S_ISREG(inode->i_mode)) { env = cl_env_get(refcheck); if (!IS_ERR(env)) { - io = ccc_env_thread_io(env); + io = vvp_env_thread_io(env); io->ci_obj = clob; *envout = env; *ioout = io; @@ -238,7 +238,7 @@ int cl_local_size(struct inode *inode) if (result > 0) { result = io->ci_result; } else if (result == 0) { - struct cl_lock *lock = ccc_env_lock(env); + struct cl_lock *lock = vvp_env_lock(env); lock->cll_descr = whole_file; lock->cll_descr.cld_enq_flags = CEF_PEEK; diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c b/drivers/staging/lustre/lustre/llite/lcommon_cl.c index d28546a1728e..5b523e338119 100644 --- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c +++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c @@ -65,49 +65,12 @@ * ccc_ prefix stands for "Common Client Code". */ -static struct kmem_cache *ccc_thread_kmem; - -static struct lu_kmem_descr ccc_caches[] = { - { - .ckd_cache = &ccc_thread_kmem, - .ckd_name = "ccc_thread_kmem", - .ckd_size = sizeof(struct ccc_thread_info), - }, - { - .ckd_cache = NULL - } -}; - /***************************************************************************** * * Vvp device and device type functions. * */ -void *ccc_key_init(const struct lu_context *ctx, struct lu_context_key *key) -{ - struct ccc_thread_info *info; - - info = kmem_cache_zalloc(ccc_thread_kmem, GFP_NOFS); - if (!info) - info = ERR_PTR(-ENOMEM); - return info; -} - -void ccc_key_fini(const struct lu_context *ctx, - struct lu_context_key *key, void *data) -{ - struct ccc_thread_info *info = data; - - kmem_cache_free(ccc_thread_kmem, info); -} - -struct lu_context_key ccc_key = { - .lct_tags = LCT_CL_THREAD, - .lct_init = ccc_key_init, - .lct_fini = ccc_key_fini -}; - /** * An `emergency' environment used by ccc_inode_fini() when cl_env_get() * fails. Access to this environment is serialized by ccc_inode_fini_guard @@ -126,13 +89,9 @@ int ccc_global_init(struct lu_device_type *device_type) { int result; - result = lu_kmem_init(ccc_caches); - if (result) - return result; - result = lu_device_type_init(device_type); if (result) - goto out_kmem; + return result; ccc_inode_fini_env = cl_env_alloc(&dummy_refcheck, LCT_REMEMBER | LCT_NOREF); @@ -145,8 +104,6 @@ int ccc_global_init(struct lu_device_type *device_type) return 0; out_device: lu_device_type_fini(device_type); -out_kmem: - lu_kmem_fini(ccc_caches); return result; } @@ -157,7 +114,6 @@ void ccc_global_fini(struct lu_device_type *device_type) ccc_inode_fini_env = NULL; } lu_device_type_fini(device_type); - lu_kmem_fini(ccc_caches); } int cl_setattr_ost(struct inode *inode, const struct iattr *attr) @@ -171,7 +127,7 @@ int cl_setattr_ost(struct inode *inode, const struct iattr *attr) if (IS_ERR(env)) return PTR_ERR(env); - io = ccc_env_thread_io(env); + io = vvp_env_thread_io(env); io->ci_obj = ll_i2info(inode)->lli_clob; io->u.ci_setattr.sa_attr.lvb_atime = LTIME_S(attr->ia_atime); diff --git a/drivers/staging/lustre/lustre/llite/lcommon_misc.c b/drivers/staging/lustre/lustre/llite/lcommon_misc.c index 5e3e43fe9550..12f3e71f48c2 100644 --- a/drivers/staging/lustre/lustre/llite/lcommon_misc.c +++ b/drivers/staging/lustre/lustre/llite/lcommon_misc.c @@ -140,7 +140,7 @@ int cl_get_grouplock(struct cl_object *obj, unsigned long gid, int nonblock, if (IS_ERR(env)) return PTR_ERR(env); - io = ccc_env_thread_io(env); + io = vvp_env_thread_io(env); io->ci_obj = obj; io->ci_ignore_layout = 1; @@ -154,7 +154,7 @@ int cl_get_grouplock(struct cl_object *obj, unsigned long gid, int nonblock, return rc; } - lock = ccc_env_lock(env); + lock = vvp_env_lock(env); descr = &lock->cll_descr; descr->cld_obj = obj; descr->cld_start = 0; diff --git a/drivers/staging/lustre/lustre/llite/llite_mmap.c b/drivers/staging/lustre/lustre/llite/llite_mmap.c index a7693c55cc46..83d7006546dc 100644 --- a/drivers/staging/lustre/lustre/llite/llite_mmap.c +++ b/drivers/staging/lustre/lustre/llite/llite_mmap.c @@ -123,7 +123,7 @@ ll_fault_io_init(struct vm_area_struct *vma, struct lu_env **env_ret, *env_ret = env; - io = ccc_env_thread_io(env); + io = vvp_env_thread_io(env); io->ci_obj = ll_i2info(inode)->lli_clob; LASSERT(io->ci_obj); diff --git a/drivers/staging/lustre/lustre/llite/rw.c b/drivers/staging/lustre/lustre/llite/rw.c index f9bc3e44b072..7d5dd3848552 100644 --- a/drivers/staging/lustre/lustre/llite/rw.c +++ b/drivers/staging/lustre/lustre/llite/rw.c @@ -524,7 +524,7 @@ int ll_readahead(const struct lu_env *env, struct cl_io *io, { struct vvp_io *vio = vvp_env_io(env); struct ll_thread_info *lti = ll_env_info(env); - struct cl_attr *attr = ccc_env_thread_attr(env); + struct cl_attr *attr = vvp_env_thread_attr(env); unsigned long start = 0, end = 0, reserved; unsigned long ra_end, len, mlen = 0; struct inode *inode; @@ -999,7 +999,7 @@ int ll_writepage(struct page *vmpage, struct writeback_control *wbc) clob = ll_i2info(inode)->lli_clob; LASSERT(clob); - io = ccc_env_thread_io(env); + io = vvp_env_thread_io(env); io->ci_obj = clob; io->ci_ignore_layout = 1; result = cl_io_init(env, io, CIT_MISC, clob); diff --git a/drivers/staging/lustre/lustre/llite/rw26.c b/drivers/staging/lustre/lustre/llite/rw26.c index 106473eb4117..65baeebead72 100644 --- a/drivers/staging/lustre/lustre/llite/rw26.c +++ b/drivers/staging/lustre/lustre/llite/rw26.c @@ -455,7 +455,7 @@ out: static int ll_prepare_partial_page(const struct lu_env *env, struct cl_io *io, struct cl_page *pg) { - struct cl_attr *attr = ccc_env_thread_attr(env); + struct cl_attr *attr = vvp_env_thread_attr(env); struct cl_object *obj = io->ci_obj; struct vvp_page *vpg = cl_object_page_slice(obj, pg); loff_t offset = cl_offset(obj, vvp_index(vpg)); diff --git a/drivers/staging/lustre/lustre/llite/vvp_dev.c b/drivers/staging/lustre/lustre/llite/vvp_dev.c index 227843327f09..b33cd3502d8c 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_dev.c +++ b/drivers/staging/lustre/lustre/llite/vvp_dev.c @@ -62,6 +62,8 @@ struct kmem_cache *vvp_lock_kmem; struct kmem_cache *vvp_object_kmem; struct kmem_cache *vvp_req_kmem; static struct kmem_cache *vvp_session_kmem; +static struct kmem_cache *vvp_thread_kmem; + static struct lu_kmem_descr vvp_caches[] = { { .ckd_cache = &ll_thread_kmem, @@ -88,6 +90,11 @@ static struct lu_kmem_descr vvp_caches[] = { .ckd_name = "vvp_session_kmem", .ckd_size = sizeof(struct vvp_session) }, + { + .ckd_cache = &vvp_thread_kmem, + .ckd_name = "vvp_thread_kmem", + .ckd_size = sizeof(struct vvp_thread_info), + }, { .ckd_cache = NULL } @@ -143,8 +150,33 @@ struct lu_context_key vvp_session_key = { .lct_fini = vvp_session_key_fini }; +void *vvp_thread_key_init(const struct lu_context *ctx, + struct lu_context_key *key) +{ + struct vvp_thread_info *vti; + + vti = kmem_cache_zalloc(vvp_thread_kmem, GFP_NOFS); + if (!vti) + vti = ERR_PTR(-ENOMEM); + return vti; +} + +void vvp_thread_key_fini(const struct lu_context *ctx, + struct lu_context_key *key, void *data) +{ + struct vvp_thread_info *vti = data; + + kmem_cache_free(vvp_thread_kmem, vti); +} + +struct lu_context_key vvp_thread_key = { + .lct_tags = LCT_CL_THREAD, + .lct_init = vvp_thread_key_init, + .lct_fini = vvp_thread_key_fini +}; + /* type constructor/destructor: vvp_type_{init,fini,start,stop}(). */ -LU_TYPE_INIT_FINI(vvp, &ccc_key, &ll_thread_key, &vvp_session_key); +LU_TYPE_INIT_FINI(vvp, &vvp_thread_key, &ll_thread_key, &vvp_session_key); static const struct lu_device_operations vvp_lu_ops = { .ldo_object_alloc = vvp_object_alloc diff --git a/drivers/staging/lustre/lustre/llite/vvp_internal.h b/drivers/staging/lustre/lustre/llite/vvp_internal.h index 4740ff51a2b7..0e15202a0789 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_internal.h +++ b/drivers/staging/lustre/lustre/llite/vvp_internal.h @@ -164,50 +164,50 @@ struct vvp_io { bool vui_ra_valid; }; -extern struct lu_context_key ccc_key; extern struct lu_context_key vvp_session_key; +extern struct lu_context_key vvp_thread_key; extern struct kmem_cache *vvp_lock_kmem; extern struct kmem_cache *vvp_object_kmem; extern struct kmem_cache *vvp_req_kmem; -struct ccc_thread_info { - struct cl_lock cti_lock; - struct cl_lock_descr cti_descr; - struct cl_io cti_io; - struct cl_attr cti_attr; +struct vvp_thread_info { + struct cl_lock vti_lock; + struct cl_lock_descr vti_descr; + struct cl_io vti_io; + struct cl_attr vti_attr; }; -static inline struct ccc_thread_info *ccc_env_info(const struct lu_env *env) +static inline struct vvp_thread_info *vvp_env_info(const struct lu_env *env) { - struct ccc_thread_info *info; + struct vvp_thread_info *vti; - info = lu_context_key_get(&env->le_ctx, &ccc_key); - LASSERT(info); + vti = lu_context_key_get(&env->le_ctx, &vvp_thread_key); + LASSERT(vti); - return info; + return vti; } -static inline struct cl_lock *ccc_env_lock(const struct lu_env *env) +static inline struct cl_lock *vvp_env_lock(const struct lu_env *env) { - struct cl_lock *lock = &ccc_env_info(env)->cti_lock; + struct cl_lock *lock = &vvp_env_info(env)->vti_lock; memset(lock, 0, sizeof(*lock)); return lock; } -static inline struct cl_attr *ccc_env_thread_attr(const struct lu_env *env) +static inline struct cl_attr *vvp_env_thread_attr(const struct lu_env *env) { - struct cl_attr *attr = &ccc_env_info(env)->cti_attr; + struct cl_attr *attr = &vvp_env_info(env)->vti_attr; memset(attr, 0, sizeof(*attr)); return attr; } -static inline struct cl_io *ccc_env_thread_io(const struct lu_env *env) +static inline struct cl_io *vvp_env_thread_io(const struct lu_env *env) { - struct cl_io *io = &ccc_env_info(env)->cti_io; + struct cl_io *io = &vvp_env_info(env)->vti_io; memset(io, 0, sizeof(*io)); diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c index 18bc71b8777d..366ac1cc0e77 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_io.c +++ b/drivers/staging/lustre/lustre/llite/vvp_io.c @@ -135,7 +135,7 @@ static int vvp_prep_size(const struct lu_env *env, struct cl_object *obj, struct cl_io *io, loff_t start, size_t count, int *exceed) { - struct cl_attr *attr = ccc_env_thread_attr(env); + struct cl_attr *attr = vvp_env_thread_attr(env); struct inode *inode = vvp_object_inode(obj); loff_t pos = start + count - 1; loff_t kms; @@ -382,10 +382,10 @@ static enum cl_lock_mode vvp_mode_from_vma(struct vm_area_struct *vma) static int vvp_mmap_locks(const struct lu_env *env, struct vvp_io *vio, struct cl_io *io) { - struct ccc_thread_info *cti = ccc_env_info(env); + struct vvp_thread_info *cti = vvp_env_info(env); struct mm_struct *mm = current->mm; struct vm_area_struct *vma; - struct cl_lock_descr *descr = &cti->cti_descr; + struct cl_lock_descr *descr = &cti->vti_descr; ldlm_policy_data_t policy; unsigned long addr; ssize_t count; @@ -621,7 +621,7 @@ static int vvp_io_setattr_time(const struct lu_env *env, { struct cl_io *io = ios->cis_io; struct cl_object *obj = io->ci_obj; - struct cl_attr *attr = ccc_env_thread_attr(env); + struct cl_attr *attr = vvp_env_thread_attr(env); int result; unsigned valid = CAT_CTIME; -- cgit v1.2.3 From a37bec74c4aa12849c0e4733c86d9377ad15e58a Mon Sep 17 00:00:00 2001 From: John Hammond Date: Wed, 30 Mar 2016 19:48:58 -0400 Subject: staging/lustre/llite: Remove ccc_global_{init, fini}() Merge their contents into vvp_global_{init,fini}() and {init,exit}_lustre_lite(). Rename ccc_inode_fini_* to cl_inode_fini_*. Signed-off-by: John L. Hammond Signed-off-by: Jinshan Xiong Reviewed-on: http://review.whamcloud.com/13714 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5971 Reviewed-by: Bobi Jam Reviewed-by: James Simmons Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/lcommon_cl.c | 53 +++++----------------- .../staging/lustre/lustre/llite/llite_internal.h | 7 +-- drivers/staging/lustre/lustre/llite/super25.c | 14 +++++- drivers/staging/lustre/lustre/llite/vvp_dev.c | 25 ++++++---- drivers/staging/lustre/lustre/llite/vvp_internal.h | 4 +- 5 files changed, 46 insertions(+), 57 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c b/drivers/staging/lustre/lustre/llite/lcommon_cl.c index 5b523e338119..164737a16865 100644 --- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c +++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c @@ -72,49 +72,18 @@ */ /** - * An `emergency' environment used by ccc_inode_fini() when cl_env_get() - * fails. Access to this environment is serialized by ccc_inode_fini_guard + * An `emergency' environment used by cl_inode_fini() when cl_env_get() + * fails. Access to this environment is serialized by cl_inode_fini_guard * mutex. */ -static struct lu_env *ccc_inode_fini_env; +struct lu_env *cl_inode_fini_env; +int cl_inode_fini_refcheck; /** * A mutex serializing calls to slp_inode_fini() under extreme memory * pressure, when environments cannot be allocated. */ -static DEFINE_MUTEX(ccc_inode_fini_guard); -static int dummy_refcheck; - -int ccc_global_init(struct lu_device_type *device_type) -{ - int result; - - result = lu_device_type_init(device_type); - if (result) - return result; - - ccc_inode_fini_env = cl_env_alloc(&dummy_refcheck, - LCT_REMEMBER | LCT_NOREF); - if (IS_ERR(ccc_inode_fini_env)) { - result = PTR_ERR(ccc_inode_fini_env); - goto out_device; - } - - ccc_inode_fini_env->le_ctx.lc_cookie = 0x4; - return 0; -out_device: - lu_device_type_fini(device_type); - return result; -} - -void ccc_global_fini(struct lu_device_type *device_type) -{ - if (ccc_inode_fini_env) { - cl_env_put(ccc_inode_fini_env, &dummy_refcheck); - ccc_inode_fini_env = NULL; - } - lu_device_type_fini(device_type); -} +static DEFINE_MUTEX(cl_inode_fini_guard); int cl_setattr_ost(struct inode *inode, const struct iattr *attr) { @@ -286,10 +255,10 @@ void cl_inode_fini(struct inode *inode) env = cl_env_get(&refcheck); emergency = IS_ERR(env); if (emergency) { - mutex_lock(&ccc_inode_fini_guard); - LASSERT(ccc_inode_fini_env); - cl_env_implant(ccc_inode_fini_env, &refcheck); - env = ccc_inode_fini_env; + mutex_lock(&cl_inode_fini_guard); + LASSERT(cl_inode_fini_env); + cl_env_implant(cl_inode_fini_env, &refcheck); + env = cl_inode_fini_env; } /* * cl_object cache is a slave to inode cache (which, in turn @@ -301,8 +270,8 @@ void cl_inode_fini(struct inode *inode) cl_object_put_last(env, clob); lli->lli_clob = NULL; if (emergency) { - cl_env_unplant(ccc_inode_fini_env, &refcheck); - mutex_unlock(&ccc_inode_fini_guard); + cl_env_unplant(cl_inode_fini_env, &refcheck); + mutex_unlock(&cl_inode_fini_guard); } else { cl_env_put(env, &refcheck); } diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index a6ee2fe31fdc..993cee818dc2 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -984,9 +984,6 @@ void free_rmtperm_hash(struct hlist_head *hash); int ll_update_remote_perm(struct inode *inode, struct mdt_remote_perm *perm); int lustre_check_remote_perm(struct inode *inode, int mask); -/* llite/llite_cl.c */ -extern struct lu_device_type vvp_device_type; - /** * Common IO arguments for various VFS I/O interfaces. */ @@ -1371,4 +1368,8 @@ void ll_xattr_fini(void); int ll_page_sync_io(const struct lu_env *env, struct cl_io *io, struct cl_page *page, enum cl_req_type crt); +/* lcommon_cl.c */ +extern struct lu_env *cl_inode_fini_env; +extern int cl_inode_fini_refcheck; + #endif /* LLITE_INTERNAL_H */ diff --git a/drivers/staging/lustre/lustre/llite/super25.c b/drivers/staging/lustre/lustre/llite/super25.c index 61856d37afc5..415750b0bff4 100644 --- a/drivers/staging/lustre/lustre/llite/super25.c +++ b/drivers/staging/lustre/lustre/llite/super25.c @@ -164,9 +164,18 @@ static int __init lustre_init(void) if (rc != 0) goto out_sysfs; + cl_inode_fini_env = cl_env_alloc(&cl_inode_fini_refcheck, + LCT_REMEMBER | LCT_NOREF); + if (IS_ERR(cl_inode_fini_env)) { + rc = PTR_ERR(cl_inode_fini_env); + goto out_vvp; + } + + cl_inode_fini_env->le_ctx.lc_cookie = 0x4; + rc = ll_xattr_init(); if (rc != 0) - goto out_vvp; + goto out_inode_fini_env; lustre_register_client_fill_super(ll_fill_super); lustre_register_kill_super_cb(ll_kill_super); @@ -174,6 +183,8 @@ static int __init lustre_init(void) return 0; +out_inode_fini_env: + cl_env_put(cl_inode_fini_env, &cl_inode_fini_refcheck); out_vvp: vvp_global_fini(); out_sysfs: @@ -198,6 +209,7 @@ static void __exit lustre_exit(void) kset_unregister(llite_kset); ll_xattr_fini(); + cl_env_put(cl_inode_fini_env, &cl_inode_fini_refcheck); vvp_global_fini(); kmem_cache_destroy(ll_inode_cachep); diff --git a/drivers/staging/lustre/lustre/llite/vvp_dev.c b/drivers/staging/lustre/lustre/llite/vvp_dev.c index b33cd3502d8c..e35c1a1f272e 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_dev.c +++ b/drivers/staging/lustre/lustre/llite/vvp_dev.c @@ -293,20 +293,27 @@ struct lu_device_type vvp_device_type = { */ int vvp_global_init(void) { - int result; + int rc; - result = lu_kmem_init(vvp_caches); - if (result == 0) { - result = ccc_global_init(&vvp_device_type); - if (result != 0) - lu_kmem_fini(vvp_caches); - } - return result; + rc = lu_kmem_init(vvp_caches); + if (rc != 0) + return rc; + + rc = lu_device_type_init(&vvp_device_type); + if (rc != 0) + goto out_kmem; + + return 0; + +out_kmem: + lu_kmem_fini(vvp_caches); + + return rc; } void vvp_global_fini(void) { - ccc_global_fini(&vvp_device_type); + lu_device_type_fini(&vvp_device_type); lu_kmem_fini(vvp_caches); } diff --git a/drivers/staging/lustre/lustre/llite/vvp_internal.h b/drivers/staging/lustre/lustre/llite/vvp_internal.h index 0e15202a0789..fe29fb53832c 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_internal.h +++ b/drivers/staging/lustre/lustre/llite/vvp_internal.h @@ -164,6 +164,8 @@ struct vvp_io { bool vui_ra_valid; }; +extern struct lu_device_type vvp_device_type; + extern struct lu_context_key vvp_session_key; extern struct lu_context_key vvp_thread_key; @@ -324,8 +326,6 @@ void ccc_key_fini(const struct lu_context *ctx, struct lu_context_key *key, void *data); void ccc_umount(const struct lu_env *env, struct cl_device *dev); -int ccc_global_init(struct lu_device_type *device_type); -void ccc_global_fini(struct lu_device_type *device_type); static inline struct lu_device *vvp2lu_dev(struct vvp_device *vdv) { -- cgit v1.2.3 From 0097dcabe6d8f91d85f59b442cd162c02b8827f4 Mon Sep 17 00:00:00 2001 From: Oleg Drokin Date: Wed, 30 Mar 2016 19:48:59 -0400 Subject: staging/lustre/llite: Move ll_dirent_type_get and make it static ll_dirent_type_get is only used in one place in llite/dir.c, so move it there. Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/dir.c | 22 ++++++++++++++++++++++ drivers/staging/lustre/lustre/llite/lcommon_cl.c | 22 ---------------------- drivers/staging/lustre/lustre/llite/vvp_internal.h | 1 - 3 files changed, 22 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c index 2ca4b0ef82ad..b085fb4ffc56 100644 --- a/drivers/staging/lustre/lustre/llite/dir.c +++ b/drivers/staging/lustre/lustre/llite/dir.c @@ -469,6 +469,28 @@ fail: goto out_unlock; } +/** + * return IF_* type for given lu_dirent entry. + * IF_* flag shld be converted to particular OS file type in + * platform llite module. + */ +static __u16 ll_dirent_type_get(struct lu_dirent *ent) +{ + __u16 type = 0; + struct luda_type *lt; + int len = 0; + + if (le32_to_cpu(ent->lde_attrs) & LUDA_TYPE) { + const unsigned int align = sizeof(struct luda_type) - 1; + + len = le16_to_cpu(ent->lde_namelen); + len = (len + align) & ~align; + lt = (void *)ent->lde_name + len; + type = IFTODT(le16_to_cpu(lt->lt_type)); + } + return type; +} + int ll_dir_read(struct inode *inode, struct dir_context *ctx) { struct ll_inode_info *info = ll_i2info(inode); diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c b/drivers/staging/lustre/lustre/llite/lcommon_cl.c index 164737a16865..6c00715b438f 100644 --- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c +++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c @@ -279,28 +279,6 @@ void cl_inode_fini(struct inode *inode) } } -/** - * return IF_* type for given lu_dirent entry. - * IF_* flag shld be converted to particular OS file type in - * platform llite module. - */ -__u16 ll_dirent_type_get(struct lu_dirent *ent) -{ - __u16 type = 0; - struct luda_type *lt; - int len = 0; - - if (le32_to_cpu(ent->lde_attrs) & LUDA_TYPE) { - const unsigned int align = sizeof(struct luda_type) - 1; - - len = le16_to_cpu(ent->lde_namelen); - len = (len + align) & ~align; - lt = (void *)ent->lde_name + len; - type = IFTODT(le16_to_cpu(lt->lt_type)); - } - return type; -} - /** * build inode number from passed @fid */ diff --git a/drivers/staging/lustre/lustre/llite/vvp_internal.h b/drivers/staging/lustre/lustre/llite/vvp_internal.h index fe29fb53832c..06e2726a472f 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_internal.h +++ b/drivers/staging/lustre/lustre/llite/vvp_internal.h @@ -376,7 +376,6 @@ int cl_file_inode_init(struct inode *inode, struct lustre_md *md); void cl_inode_fini(struct inode *inode); int cl_local_size(struct inode *inode); -__u16 ll_dirent_type_get(struct lu_dirent *ent); __u64 cl_fid_build_ino(const struct lu_fid *fid, int api32); __u32 cl_fid_build_gen(const struct lu_fid *fid); -- cgit v1.2.3 From 5c5af0fce77e480930fbb17de458c327f405b965 Mon Sep 17 00:00:00 2001 From: John Hammond Date: Wed, 30 Mar 2016 19:49:00 -0400 Subject: staging/lustre/llite: Move several declarations to llite_internal.h Move several declarations between llite_internal.h and vvp_internal.h with the goal of reserving the latter header for functions that pertain to vvp_{device,object,page,...}. Signed-off-by: John L. Hammond Signed-off-by: Jinshan Xiong Reviewed-on: http://review.whamcloud.com/13714 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5971 Reviewed-by: Bobi Jam Reviewed-by: James Simmons Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- .../staging/lustre/lustre/llite/llite_internal.h | 32 +++++++++++++++++-- drivers/staging/lustre/lustre/llite/vvp_internal.h | 36 ++-------------------- 2 files changed, 32 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index 993cee818dc2..ba24f09ba1f9 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -663,6 +663,10 @@ static inline int ll_need_32bit_api(struct ll_sb_info *sbi) void ll_ras_enter(struct file *f); /* llite/lcommon_misc.c */ +int cl_init_ea_size(struct obd_export *md_exp, struct obd_export *dt_exp); +int cl_ocd_update(struct obd_device *host, + struct obd_device *watched, + enum obd_notify_event ev, void *owner, void *data); int cl_get_grouplock(struct cl_object *obj, unsigned long gid, int nonblock, struct ll_grouplock *cg); void cl_put_grouplock(struct ll_grouplock *cg); @@ -881,9 +885,6 @@ static inline struct vvp_io_args *ll_env_args(const struct lu_env *env, return via; } -int vvp_global_init(void); -void vvp_global_fini(void); - void ll_queue_done_writing(struct inode *inode, unsigned long flags); void ll_close_thread_shutdown(struct ll_close_queue *lcq); int ll_close_thread_start(struct ll_close_queue **lcq_ret); @@ -1089,6 +1090,22 @@ int do_statahead_enter(struct inode *dir, struct dentry **dentry, int only_unplug); void ll_stop_statahead(struct inode *dir, void *key); +blkcnt_t dirty_cnt(struct inode *inode); + +int cl_glimpse_size0(struct inode *inode, int agl); +int cl_glimpse_lock(const struct lu_env *env, struct cl_io *io, + struct inode *inode, struct cl_object *clob, int agl); + +static inline int cl_glimpse_size(struct inode *inode) +{ + return cl_glimpse_size0(inode, 0); +} + +static inline int cl_agl(struct inode *inode) +{ + return cl_glimpse_size0(inode, 1); +} + static inline int ll_glimpse_size(struct inode *inode) { struct ll_inode_info *lli = ll_i2info(inode); @@ -1369,7 +1386,16 @@ int ll_page_sync_io(const struct lu_env *env, struct cl_io *io, struct cl_page *page, enum cl_req_type crt); /* lcommon_cl.c */ +int cl_setattr_ost(struct inode *inode, const struct iattr *attr); + extern struct lu_env *cl_inode_fini_env; extern int cl_inode_fini_refcheck; +int cl_file_inode_init(struct inode *inode, struct lustre_md *md); +void cl_inode_fini(struct inode *inode); +int cl_local_size(struct inode *inode); + +__u64 cl_fid_build_ino(const struct lu_fid *fid, int api32); +__u32 cl_fid_build_gen(const struct lu_fid *fid); + #endif /* LLITE_INTERNAL_H */ diff --git a/drivers/staging/lustre/lustre/llite/vvp_internal.h b/drivers/staging/lustre/lustre/llite/vvp_internal.h index 06e2726a472f..ce4aeca1b0fb 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_internal.h +++ b/drivers/staging/lustre/lustre/llite/vvp_internal.h @@ -53,25 +53,6 @@ struct obd_device; struct obd_export; struct page; -blkcnt_t dirty_cnt(struct inode *inode); - -int cl_glimpse_size0(struct inode *inode, int agl); -int cl_glimpse_lock(const struct lu_env *env, struct cl_io *io, - struct inode *inode, struct cl_object *clob, int agl); - -static inline int cl_glimpse_size(struct inode *inode) -{ - return cl_glimpse_size0(inode, 0); -} - -static inline int cl_agl(struct inode *inode) -{ - return cl_glimpse_size0(inode, 1); -} - -/** - * Locking policy for setattr. - */ enum ccc_setattr_lock_type { /** Locking is done by server */ SETATTR_NOLOCK, @@ -370,23 +351,9 @@ static inline struct vvp_lock *cl2vvp_lock(const struct cl_lock_slice *slice) return container_of(slice, struct vvp_lock, vlk_cl); } -int cl_setattr_ost(struct inode *inode, const struct iattr *attr); - -int cl_file_inode_init(struct inode *inode, struct lustre_md *md); -void cl_inode_fini(struct inode *inode); -int cl_local_size(struct inode *inode); - -__u64 cl_fid_build_ino(const struct lu_fid *fid, int api32); -__u32 cl_fid_build_gen(const struct lu_fid *fid); - # define CLOBINVRNT(env, clob, expr) \ ((void)sizeof(env), (void)sizeof(clob), (void)sizeof(!!(expr))) -int cl_init_ea_size(struct obd_export *md_exp, struct obd_export *dt_exp); -int cl_ocd_update(struct obd_device *host, - struct obd_device *watched, - enum obd_notify_event ev, void *owner, void *data); - /** * New interfaces to get and put lov_stripe_md from lov layer. This violates * layering because lov_stripe_md is supposed to be a private data in lov. @@ -415,6 +382,9 @@ struct lu_object *vvp_object_alloc(const struct lu_env *env, const struct lu_object_header *hdr, struct lu_device *dev); +int vvp_global_init(void); +void vvp_global_fini(void); + extern const struct file_operations vvp_dump_pgcache_file_ops; #endif /* VVP_INTERNAL_H */ -- cgit v1.2.3 From 047d41bd71c5553bdd5bda56edbc77b8cbc1ae87 Mon Sep 17 00:00:00 2001 From: Oleg Drokin Date: Wed, 30 Mar 2016 19:49:01 -0400 Subject: staging/lustre/llite: Remove unused vui_local_lock field vvp_io_setattr_lock is the only user that sets it, but it's never checked anywhere, so could go away. Also get rid of enum ccc_setattr_lock_type that becomes unused. Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/vvp_internal.h | 12 ------------ drivers/staging/lustre/lustre/llite/vvp_io.c | 3 --- 2 files changed, 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/llite/vvp_internal.h b/drivers/staging/lustre/lustre/llite/vvp_internal.h index ce4aeca1b0fb..27b9b0a01f32 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_internal.h +++ b/drivers/staging/lustre/lustre/llite/vvp_internal.h @@ -53,15 +53,6 @@ struct obd_device; struct obd_export; struct page; -enum ccc_setattr_lock_type { - /** Locking is done by server */ - SETATTR_NOLOCK, - /** Extent lock is enqueued */ - SETATTR_EXTENT_LOCK, - /** Existing local extent lock is used */ - SETATTR_MATCH_LOCK -}; - /* specific architecture can implement only part of this list */ enum vvp_io_subtype { /** normal IO */ @@ -111,9 +102,6 @@ struct vvp_io { */ bool ft_flags_valid; } fault; - struct { - enum ccc_setattr_lock_type vui_local_lock; - } setattr; struct { struct pipe_inode_info *vui_pipe; unsigned int vui_flags; diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c index 366ac1cc0e77..aed7b8e41a51 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_io.c +++ b/drivers/staging/lustre/lustre/llite/vvp_io.c @@ -567,7 +567,6 @@ static int vvp_io_setattr_iter_init(const struct lu_env *env, static int vvp_io_setattr_lock(const struct lu_env *env, const struct cl_io_slice *ios) { - struct vvp_io *vio = vvp_env_io(env); struct cl_io *io = ios->cis_io; __u64 new_size; __u32 enqflags = 0; @@ -585,8 +584,6 @@ static int vvp_io_setattr_lock(const struct lu_env *env, new_size = 0; } - vio->u.setattr.vui_local_lock = SETATTR_EXTENT_LOCK; - return vvp_io_one_lock(env, io, enqflags, CLM_WRITE, new_size, OBD_OBJECT_EOF); } -- cgit v1.2.3 From 7d44333467a949b6ea4e21b5fb7618f97cc10ce0 Mon Sep 17 00:00:00 2001 From: Jinshan Xiong Date: Wed, 30 Mar 2016 19:49:02 -0400 Subject: staging/lustre/ldlm: ELC picks locks in a safer policy Change the policy of ELC to pick locks that have no dirty pages, no page in writeback state, and no locked pages. Signed-off-by: Jinshan Xiong Reviewed-on: http://review.whamcloud.com/9175 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-4300 Reviewed-by: Andreas Dilger Reviewed-by: Bobi Jam Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/lustre_dlm.h | 13 ++++++---- drivers/staging/lustre/lustre/ldlm/ldlm_request.c | 28 +++++++++++++++------- drivers/staging/lustre/lustre/mdc/mdc_request.c | 4 ++-- drivers/staging/lustre/lustre/osc/osc_lock.c | 4 +++- drivers/staging/lustre/lustre/osc/osc_request.c | 19 ++++++--------- 5 files changed, 39 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/include/lustre_dlm.h b/drivers/staging/lustre/lustre/include/lustre_dlm.h index b1abdc28b261..9cade144faca 100644 --- a/drivers/staging/lustre/lustre/include/lustre_dlm.h +++ b/drivers/staging/lustre/lustre/include/lustre_dlm.h @@ -270,7 +270,7 @@ struct ldlm_pool { struct completion pl_kobj_unregister; }; -typedef int (*ldlm_cancel_for_recovery)(struct ldlm_lock *lock); +typedef int (*ldlm_cancel_cbt)(struct ldlm_lock *lock); /** * LVB operations. @@ -447,8 +447,11 @@ struct ldlm_namespace { /** Limit of parallel AST RPC count. */ unsigned ns_max_parallel_ast; - /** Callback to cancel locks before replaying it during recovery. */ - ldlm_cancel_for_recovery ns_cancel_for_recovery; + /** + * Callback to check if a lock is good to be canceled by ELC or + * during recovery. + */ + ldlm_cancel_cbt ns_cancel; /** LDLM lock stats */ struct lprocfs_stats *ns_stats; @@ -480,9 +483,9 @@ static inline int ns_connect_lru_resize(struct ldlm_namespace *ns) } static inline void ns_register_cancel(struct ldlm_namespace *ns, - ldlm_cancel_for_recovery arg) + ldlm_cancel_cbt arg) { - ns->ns_cancel_for_recovery = arg; + ns->ns_cancel = arg; } struct ldlm_lock; diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c index 42925ac3331c..2f12194aa6df 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c @@ -1137,7 +1137,6 @@ static ldlm_policy_res_t ldlm_cancel_no_wait_policy(struct ldlm_namespace *ns, int count) { ldlm_policy_res_t result = LDLM_POLICY_CANCEL_LOCK; - ldlm_cancel_for_recovery cb = ns->ns_cancel_for_recovery; /* don't check added & count since we want to process all locks * from unused list. @@ -1147,7 +1146,7 @@ static ldlm_policy_res_t ldlm_cancel_no_wait_policy(struct ldlm_namespace *ns, switch (lock->l_resource->lr_type) { case LDLM_EXTENT: case LDLM_IBITS: - if (cb && cb(lock)) + if (ns->ns_cancel && ns->ns_cancel(lock) != 0) break; default: result = LDLM_POLICY_SKIP_LOCK; @@ -1197,8 +1196,13 @@ static ldlm_policy_res_t ldlm_cancel_lrur_policy(struct ldlm_namespace *ns, /* Stop when SLV is not yet come from server or lv is smaller than * it is. */ - return (slv == 0 || lv < slv) ? - LDLM_POLICY_KEEP_LOCK : LDLM_POLICY_CANCEL_LOCK; + if (slv == 0 || lv < slv) + return LDLM_POLICY_KEEP_LOCK; + + if (ns->ns_cancel && ns->ns_cancel(lock) == 0) + return LDLM_POLICY_KEEP_LOCK; + + return LDLM_POLICY_CANCEL_LOCK; } /** @@ -1236,11 +1240,17 @@ static ldlm_policy_res_t ldlm_cancel_aged_policy(struct ldlm_namespace *ns, int unused, int added, int count) { - /* Stop LRU processing if young lock is found and we reach past count */ - return ((added >= count) && - time_before(cfs_time_current(), - cfs_time_add(lock->l_last_used, ns->ns_max_age))) ? - LDLM_POLICY_KEEP_LOCK : LDLM_POLICY_CANCEL_LOCK; + if (added >= count) + return LDLM_POLICY_KEEP_LOCK; + + if (time_before(cfs_time_current(), + cfs_time_add(lock->l_last_used, ns->ns_max_age))) + return LDLM_POLICY_KEEP_LOCK; + + if (ns->ns_cancel && ns->ns_cancel(lock) == 0) + return LDLM_POLICY_KEEP_LOCK; + + return LDLM_POLICY_CANCEL_LOCK; } /** diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c index 55dd8ef9525b..98b27f1f9915 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c @@ -2249,7 +2249,7 @@ static struct obd_uuid *mdc_get_uuid(struct obd_export *exp) * recovery, non zero value will be return if the lock can be canceled, * or zero returned for not */ -static int mdc_cancel_for_recovery(struct ldlm_lock *lock) +static int mdc_cancel_weight(struct ldlm_lock *lock) { if (lock->l_resource->lr_type != LDLM_IBITS) return 0; @@ -2331,7 +2331,7 @@ static int mdc_setup(struct obd_device *obd, struct lustre_cfg *cfg) sptlrpc_lprocfs_cliobd_attach(obd); ptlrpc_lprocfs_register_obd(obd); - ns_register_cancel(obd->obd_namespace, mdc_cancel_for_recovery); + ns_register_cancel(obd->obd_namespace, mdc_cancel_weight); obd->obd_namespace->ns_lvbo = &inode_lvbo; diff --git a/drivers/staging/lustre/lustre/osc/osc_lock.c b/drivers/staging/lustre/lustre/osc/osc_lock.c index 68c5013fdc3e..49dfe9f8bc4b 100644 --- a/drivers/staging/lustre/lustre/osc/osc_lock.c +++ b/drivers/staging/lustre/lustre/osc/osc_lock.c @@ -635,7 +635,9 @@ static int weigh_cb(const struct lu_env *env, struct cl_io *io, { struct cl_page *page = ops->ops_cl.cpl_page; - if (cl_page_is_vmlocked(env, page)) { + if (cl_page_is_vmlocked(env, page) || + PageDirty(page->cp_vmpage) || PageWriteback(page->cp_vmpage) + ) { (*(unsigned long *)cbdata)++; return CLP_GANG_ABORT; } diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c index 368b99719d48..a6dc517d178b 100644 --- a/drivers/staging/lustre/lustre/osc/osc_request.c +++ b/drivers/staging/lustre/lustre/osc/osc_request.c @@ -2292,15 +2292,13 @@ no_match: if (*flags & LDLM_FL_TEST_LOCK) return -ENOLCK; if (intent) { - LIST_HEAD(cancels); - req = ptlrpc_request_alloc(class_exp2cliimp(exp), &RQF_LDLM_ENQUEUE_LVB); if (!req) return -ENOMEM; - rc = ldlm_prep_enqueue_req(exp, req, &cancels, 0); - if (rc) { + rc = ptlrpc_request_pack(req, LUSTRE_DLM_VERSION, LDLM_ENQUEUE); + if (rc < 0) { ptlrpc_request_free(req); return rc; } @@ -3110,17 +3108,14 @@ static int osc_import_event(struct obd_device *obd, * \retval zero the lock can't be canceled * \retval other ok to cancel */ -static int osc_cancel_for_recovery(struct ldlm_lock *lock) +static int osc_cancel_weight(struct ldlm_lock *lock) { /* - * Cancel all unused extent lock in granted mode LCK_PR or LCK_CR. - * - * XXX as a future improvement, we can also cancel unused write lock - * if it doesn't have dirty data and active mmaps. + * Cancel all unused and granted extent lock. */ if (lock->l_resource->lr_type == LDLM_EXTENT && - (lock->l_granted_mode == LCK_PR || - lock->l_granted_mode == LCK_CR) && osc_ldlm_weigh_ast(lock) == 0) + lock->l_granted_mode == lock->l_req_mode && + osc_ldlm_weigh_ast(lock) == 0) return 1; return 0; @@ -3197,7 +3192,7 @@ int osc_setup(struct obd_device *obd, struct lustre_cfg *lcfg) } INIT_LIST_HEAD(&cli->cl_grant_shrink_list); - ns_register_cancel(obd->obd_namespace, osc_cancel_for_recovery); + ns_register_cancel(obd->obd_namespace, osc_cancel_weight); return rc; out_ptlrpcd_work: -- cgit v1.2.3 From 7b2d26b0af8bcc44fb3a279f28f380010890c4a4 Mon Sep 17 00:00:00 2001 From: Niu Yawei Date: Wed, 30 Mar 2016 19:49:03 -0400 Subject: staging/lustre/ldlm: revert changes to ldlm_cancel_aged_policy() The changes to ldlm_cancel_aged_policy() introduced from LU-4300 was incorrect. This patch revert this part of changes. Signed-off-by: Niu Yawei Reviewed-on: http://review.whamcloud.com/12448 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5727 Reviewed-by: Bobi Jam Reviewed-by: Jinshan Xiong Reviewed-by: Andreas Dilger Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/ldlm/ldlm_request.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c index 2f12194aa6df..48e982867db3 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c @@ -1240,10 +1240,8 @@ static ldlm_policy_res_t ldlm_cancel_aged_policy(struct ldlm_namespace *ns, int unused, int added, int count) { - if (added >= count) - return LDLM_POLICY_KEEP_LOCK; - - if (time_before(cfs_time_current(), + if ((added >= count) && + time_before(cfs_time_current(), cfs_time_add(lock->l_last_used, ns->ns_max_age))) return LDLM_POLICY_KEEP_LOCK; -- cgit v1.2.3 From 2640256e388f8f5dd2f9fdbb034b3c0332e10e41 Mon Sep 17 00:00:00 2001 From: Vitaly Fertman Date: Wed, 30 Mar 2016 19:49:04 -0400 Subject: staging/lustre/ldlm: restore the ELC for enqueue after LU-4300 enqueue does not ELC anymore, however if enqueue is agressive (ls -la of a large dir) we may exceed lru-resize limit quickly because LRUR shrinker and recalc are called not so often. ELC is to be restored in enqueue. ELC also should check for the lock weight, in addition to LRUR. ELC can also keep "skipped" locks, i.e. once checked for the weight and left in the lru - let LRUR take care about them later. LRUR is to be left untouched, no weight logic, otherwise LU-5727 appears and OPEN locks do not get canceled. Xyratex-bug-id: MRP-2550 Signed-off-by: Vitaly Fertman Reviewed-on: http://review.whamcloud.com/14342 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6390 Reviewed-by: Jinshan Xiong Reviewed-by: Niu Yawei Reviewed-by: Andreas Dilger Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/ldlm/ldlm_internal.h | 7 +++--- drivers/staging/lustre/lustre/ldlm/ldlm_request.c | 25 ++++++++++++++++++---- drivers/staging/lustre/lustre/osc/osc_request.c | 4 ++-- 3 files changed, 27 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h b/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h index e21373e7306f..e31d84aad4e4 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h @@ -95,9 +95,10 @@ enum { LDLM_CANCEL_PASSED = 1 << 1, /* Cancel passed number of locks. */ LDLM_CANCEL_SHRINK = 1 << 2, /* Cancel locks from shrinker. */ LDLM_CANCEL_LRUR = 1 << 3, /* Cancel locks from lru resize. */ - LDLM_CANCEL_NO_WAIT = 1 << 4 /* Cancel locks w/o blocking (neither - * sending nor waiting for any rpcs) - */ + LDLM_CANCEL_NO_WAIT = 1 << 4, /* Cancel locks w/o blocking (neither + * sending nor waiting for any rpcs) + */ + LDLM_CANCEL_LRUR_NO_WAIT = 1 << 5, /* LRUR + NO_WAIT */ }; int ldlm_cancel_lru(struct ldlm_namespace *ns, int nr, diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c index 48e982867db3..9aa4c2dfe143 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c @@ -601,7 +601,7 @@ int ldlm_prep_elc_req(struct obd_export *exp, struct ptlrpc_request *req, avail = ldlm_capsule_handles_avail(pill, RCL_CLIENT, canceloff); flags = ns_connect_lru_resize(ns) ? - LDLM_CANCEL_LRUR : LDLM_CANCEL_AGED; + LDLM_CANCEL_LRUR_NO_WAIT : LDLM_CANCEL_AGED; to_free = !ns_connect_lru_resize(ns) && opc == LDLM_ENQUEUE ? 1 : 0; @@ -1146,7 +1146,7 @@ static ldlm_policy_res_t ldlm_cancel_no_wait_policy(struct ldlm_namespace *ns, switch (lock->l_resource->lr_type) { case LDLM_EXTENT: case LDLM_IBITS: - if (ns->ns_cancel && ns->ns_cancel(lock) != 0) + if (ns->ns_cancel && ns->ns_cancel(lock) != 0) break; default: result = LDLM_POLICY_SKIP_LOCK; @@ -1251,6 +1251,21 @@ static ldlm_policy_res_t ldlm_cancel_aged_policy(struct ldlm_namespace *ns, return LDLM_POLICY_CANCEL_LOCK; } +static ldlm_policy_res_t +ldlm_cancel_lrur_no_wait_policy(struct ldlm_namespace *ns, + struct ldlm_lock *lock, + int unused, int added, + int count) +{ + ldlm_policy_res_t result; + + result = ldlm_cancel_lrur_policy(ns, lock, unused, added, count); + if (result == LDLM_POLICY_KEEP_LOCK) + return result; + + return ldlm_cancel_no_wait_policy(ns, lock, unused, added, count); +} + /** * Callback function for default policy. Makes decision whether to keep \a lock * in LRU for current LRU size \a unused, added in current scan \a added and @@ -1290,6 +1305,8 @@ ldlm_cancel_lru_policy(struct ldlm_namespace *ns, int flags) return ldlm_cancel_lrur_policy; else if (flags & LDLM_CANCEL_PASSED) return ldlm_cancel_passed_policy; + else if (flags & LDLM_CANCEL_LRUR_NO_WAIT) + return ldlm_cancel_lrur_no_wait_policy; } else { if (flags & LDLM_CANCEL_AGED) return ldlm_cancel_aged_policy; @@ -1338,6 +1355,7 @@ static int ldlm_prepare_lru_list(struct ldlm_namespace *ns, ldlm_cancel_lru_policy_t pf; struct ldlm_lock *lock, *next; int added = 0, unused, remained; + int no_wait = flags & (LDLM_CANCEL_NO_WAIT | LDLM_CANCEL_LRUR_NO_WAIT); spin_lock(&ns->ns_lock); unused = ns->ns_nr_unused; @@ -1365,8 +1383,7 @@ static int ldlm_prepare_lru_list(struct ldlm_namespace *ns, /* No locks which got blocking requests. */ LASSERT(!(lock->l_flags & LDLM_FL_BL_AST)); - if (flags & LDLM_CANCEL_NO_WAIT && - lock->l_flags & LDLM_FL_SKIPPED) + if (no_wait && lock->l_flags & LDLM_FL_SKIPPED) /* already processed */ continue; diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c index a6dc517d178b..5b9f72c909b7 100644 --- a/drivers/staging/lustre/lustre/osc/osc_request.c +++ b/drivers/staging/lustre/lustre/osc/osc_request.c @@ -2297,8 +2297,8 @@ no_match: if (!req) return -ENOMEM; - rc = ptlrpc_request_pack(req, LUSTRE_DLM_VERSION, LDLM_ENQUEUE); - if (rc < 0) { + rc = ldlm_prep_enqueue_req(exp, req, NULL, 0); + if (rc) { ptlrpc_request_free(req); return rc; } -- cgit v1.2.3 From e9570b490ba209220b43530ca250060035d6bcba Mon Sep 17 00:00:00 2001 From: Oleg Drokin Date: Wed, 30 Mar 2016 19:49:05 -0400 Subject: staging/lustre: Fix spacing style before open parenthesis This fixes the remaining occurences of checkpatch warnings of the form of WARNING: space prohibited between function name and open parenthesis '(' Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/lu_object.h | 64 +++++++++++----------- .../lustre/lustre/include/lustre/lustre_idl.h | 2 +- .../lustre/lustre/include/lustre/lustre_user.h | 36 ++++++------ drivers/staging/lustre/lustre/include/lustre_cfg.h | 2 +- .../staging/lustre/lustre/include/lustre_import.h | 2 +- drivers/staging/lustre/lustre/include/lustre_lib.h | 36 ++++++------ drivers/staging/lustre/lustre/obdclass/debug.c | 4 +- .../staging/lustre/lustre/osc/osc_cl_internal.h | 22 ++++---- drivers/staging/lustre/lustre/osc/osc_request.c | 2 +- 9 files changed, 85 insertions(+), 85 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/include/lu_object.h b/drivers/staging/lustre/lustre/include/lu_object.h index b5088b13a305..fcb9db6e1f1a 100644 --- a/drivers/staging/lustre/lustre/include/lu_object.h +++ b/drivers/staging/lustre/lustre/include/lu_object.h @@ -656,21 +656,21 @@ static inline struct seq_server_site *lu_site2seq(const struct lu_site *s) * @{ */ -int lu_site_init (struct lu_site *s, struct lu_device *d); -void lu_site_fini (struct lu_site *s); -int lu_site_init_finish (struct lu_site *s); -void lu_stack_fini (const struct lu_env *env, struct lu_device *top); -void lu_device_get (struct lu_device *d); -void lu_device_put (struct lu_device *d); -int lu_device_init (struct lu_device *d, struct lu_device_type *t); -void lu_device_fini (struct lu_device *d); -int lu_object_header_init(struct lu_object_header *h); +int lu_site_init(struct lu_site *s, struct lu_device *d); +void lu_site_fini(struct lu_site *s); +int lu_site_init_finish(struct lu_site *s); +void lu_stack_fini(const struct lu_env *env, struct lu_device *top); +void lu_device_get(struct lu_device *d); +void lu_device_put(struct lu_device *d); +int lu_device_init(struct lu_device *d, struct lu_device_type *t); +void lu_device_fini(struct lu_device *d); +int lu_object_header_init(struct lu_object_header *h); void lu_object_header_fini(struct lu_object_header *h); -int lu_object_init (struct lu_object *o, - struct lu_object_header *h, struct lu_device *d); -void lu_object_fini (struct lu_object *o); -void lu_object_add_top (struct lu_object_header *h, struct lu_object *o); -void lu_object_add (struct lu_object *before, struct lu_object *o); +int lu_object_init(struct lu_object *o, + struct lu_object_header *h, struct lu_device *d); +void lu_object_fini(struct lu_object *o); +void lu_object_add_top(struct lu_object_header *h, struct lu_object *o); +void lu_object_add(struct lu_object *before, struct lu_object *o); /** * Helpers to initialize and finalize device types. @@ -1118,7 +1118,7 @@ struct lu_context_key { { \ type *value; \ \ - CLASSERT(PAGE_CACHE_SIZE >= sizeof (*value)); \ + CLASSERT(PAGE_CACHE_SIZE >= sizeof(*value)); \ \ value = kzalloc(sizeof(*value), GFP_NOFS); \ if (!value) \ @@ -1154,12 +1154,12 @@ do { \ (key)->lct_owner = THIS_MODULE; \ } while (0) -int lu_context_key_register(struct lu_context_key *key); -void lu_context_key_degister(struct lu_context_key *key); -void *lu_context_key_get (const struct lu_context *ctx, - const struct lu_context_key *key); -void lu_context_key_quiesce (struct lu_context_key *key); -void lu_context_key_revive (struct lu_context_key *key); +int lu_context_key_register(struct lu_context_key *key); +void lu_context_key_degister(struct lu_context_key *key); +void *lu_context_key_get(const struct lu_context *ctx, + const struct lu_context_key *key); +void lu_context_key_quiesce(struct lu_context_key *key); +void lu_context_key_revive(struct lu_context_key *key); /* * LU_KEY_INIT_GENERIC() has to be a macro to correctly determine an @@ -1216,21 +1216,21 @@ void lu_context_key_revive (struct lu_context_key *key); LU_TYPE_START(mod, __VA_ARGS__); \ LU_TYPE_STOP(mod, __VA_ARGS__) -int lu_context_init (struct lu_context *ctx, __u32 tags); -void lu_context_fini (struct lu_context *ctx); -void lu_context_enter (struct lu_context *ctx); -void lu_context_exit (struct lu_context *ctx); -int lu_context_refill(struct lu_context *ctx); +int lu_context_init(struct lu_context *ctx, __u32 tags); +void lu_context_fini(struct lu_context *ctx); +void lu_context_enter(struct lu_context *ctx); +void lu_context_exit(struct lu_context *ctx); +int lu_context_refill(struct lu_context *ctx); /* * Helper functions to operate on multiple keys. These are used by the default * device type operations, defined by LU_TYPE_INIT_FINI(). */ -int lu_context_key_register_many(struct lu_context_key *k, ...); +int lu_context_key_register_many(struct lu_context_key *k, ...); void lu_context_key_degister_many(struct lu_context_key *k, ...); -void lu_context_key_revive_many (struct lu_context_key *k, ...); -void lu_context_key_quiesce_many (struct lu_context_key *k, ...); +void lu_context_key_revive_many(struct lu_context_key *k, ...); +void lu_context_key_quiesce_many(struct lu_context_key *k, ...); /** * Environment. @@ -1246,9 +1246,9 @@ struct lu_env { struct lu_context *le_ses; }; -int lu_env_init (struct lu_env *env, __u32 tags); -void lu_env_fini (struct lu_env *env); -int lu_env_refill(struct lu_env *env); +int lu_env_init(struct lu_env *env, __u32 tags); +void lu_env_fini(struct lu_env *env); +int lu_env_refill(struct lu_env *env); /** @} lu_context */ diff --git a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h index 4318511de0c9..12e6718f2adb 100644 --- a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h +++ b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h @@ -3306,7 +3306,7 @@ struct getinfo_fid2path { char gf_path[0]; } __packed; -void lustre_swab_fid2path (struct getinfo_fid2path *gf); +void lustre_swab_fid2path(struct getinfo_fid2path *gf); enum { LAYOUT_INTENT_ACCESS = 0, diff --git a/drivers/staging/lustre/lustre/include/lustre/lustre_user.h b/drivers/staging/lustre/lustre/include/lustre/lustre_user.h index 276906e646f5..19f2271cc6b9 100644 --- a/drivers/staging/lustre/lustre/include/lustre/lustre_user.h +++ b/drivers/staging/lustre/lustre/include/lustre/lustre_user.h @@ -193,37 +193,37 @@ struct ost_id { * *INFO - set/get lov_user_mds_data */ /* see for ioctl numberss 101-150 */ -#define LL_IOC_GETFLAGS _IOR ('f', 151, long) -#define LL_IOC_SETFLAGS _IOW ('f', 152, long) -#define LL_IOC_CLRFLAGS _IOW ('f', 153, long) +#define LL_IOC_GETFLAGS _IOR('f', 151, long) +#define LL_IOC_SETFLAGS _IOW('f', 152, long) +#define LL_IOC_CLRFLAGS _IOW('f', 153, long) /* LL_IOC_LOV_SETSTRIPE: See also OBD_IOC_LOV_SETSTRIPE */ -#define LL_IOC_LOV_SETSTRIPE _IOW ('f', 154, long) +#define LL_IOC_LOV_SETSTRIPE _IOW('f', 154, long) /* LL_IOC_LOV_GETSTRIPE: See also OBD_IOC_LOV_GETSTRIPE */ -#define LL_IOC_LOV_GETSTRIPE _IOW ('f', 155, long) +#define LL_IOC_LOV_GETSTRIPE _IOW('f', 155, long) /* LL_IOC_LOV_SETEA: See also OBD_IOC_LOV_SETEA */ -#define LL_IOC_LOV_SETEA _IOW ('f', 156, long) -#define LL_IOC_RECREATE_OBJ _IOW ('f', 157, long) -#define LL_IOC_RECREATE_FID _IOW ('f', 157, struct lu_fid) -#define LL_IOC_GROUP_LOCK _IOW ('f', 158, long) -#define LL_IOC_GROUP_UNLOCK _IOW ('f', 159, long) +#define LL_IOC_LOV_SETEA _IOW('f', 156, long) +#define LL_IOC_RECREATE_OBJ _IOW('f', 157, long) +#define LL_IOC_RECREATE_FID _IOW('f', 157, struct lu_fid) +#define LL_IOC_GROUP_LOCK _IOW('f', 158, long) +#define LL_IOC_GROUP_UNLOCK _IOW('f', 159, long) /* LL_IOC_QUOTACHECK: See also OBD_IOC_QUOTACHECK */ -#define LL_IOC_QUOTACHECK _IOW ('f', 160, int) +#define LL_IOC_QUOTACHECK _IOW('f', 160, int) /* LL_IOC_POLL_QUOTACHECK: See also OBD_IOC_POLL_QUOTACHECK */ -#define LL_IOC_POLL_QUOTACHECK _IOR ('f', 161, struct if_quotacheck *) +#define LL_IOC_POLL_QUOTACHECK _IOR('f', 161, struct if_quotacheck *) /* LL_IOC_QUOTACTL: See also OBD_IOC_QUOTACTL */ #define LL_IOC_QUOTACTL _IOWR('f', 162, struct if_quotactl) #define IOC_OBD_STATFS _IOWR('f', 164, struct obd_statfs *) #define IOC_LOV_GETINFO _IOWR('f', 165, struct lov_user_mds_data *) -#define LL_IOC_FLUSHCTX _IOW ('f', 166, long) -#define LL_IOC_RMTACL _IOW ('f', 167, long) -#define LL_IOC_GETOBDCOUNT _IOR ('f', 168, long) +#define LL_IOC_FLUSHCTX _IOW('f', 166, long) +#define LL_IOC_RMTACL _IOW('f', 167, long) +#define LL_IOC_GETOBDCOUNT _IOR('f', 168, long) #define LL_IOC_LLOOP_ATTACH _IOWR('f', 169, long) #define LL_IOC_LLOOP_DETACH _IOWR('f', 170, long) #define LL_IOC_LLOOP_INFO _IOWR('f', 171, struct lu_fid) #define LL_IOC_LLOOP_DETACH_BYDEV _IOWR('f', 172, long) -#define LL_IOC_PATH2FID _IOR ('f', 173, long) +#define LL_IOC_PATH2FID _IOR('f', 173, long) #define LL_IOC_GET_CONNECT_FLAGS _IOWR('f', 174, __u64 *) -#define LL_IOC_GET_MDTIDX _IOR ('f', 175, int) +#define LL_IOC_GET_MDTIDX _IOR('f', 175, int) /* see for ioctl numbers 177-210 */ @@ -1100,7 +1100,7 @@ struct hsm_action_list { } __packed; #ifndef HAVE_CFS_SIZE_ROUND -static inline int cfs_size_round (int val) +static inline int cfs_size_round(int val) { return (val + 7) & (~0x7); } diff --git a/drivers/staging/lustre/lustre/include/lustre_cfg.h b/drivers/staging/lustre/lustre/include/lustre_cfg.h index bb16ae980b98..e229e91f7f56 100644 --- a/drivers/staging/lustre/lustre/include/lustre_cfg.h +++ b/drivers/staging/lustre/lustre/include/lustre_cfg.h @@ -161,7 +161,7 @@ static inline void *lustre_cfg_buf(struct lustre_cfg *lcfg, int index) int offset; int bufcount; - LASSERT (index >= 0); + LASSERT(index >= 0); bufcount = lcfg->lcfg_bufcount; if (index >= bufcount) diff --git a/drivers/staging/lustre/lustre/include/lustre_import.h b/drivers/staging/lustre/lustre/include/lustre_import.h index dac2d84d8266..8325c82b3ebf 100644 --- a/drivers/staging/lustre/lustre/include/lustre_import.h +++ b/drivers/staging/lustre/lustre/include/lustre_import.h @@ -109,7 +109,7 @@ static inline char *ptlrpc_import_state_name(enum lustre_imp_state state) "RECOVER", "FULL", "EVICTED", }; - LASSERT (state <= LUSTRE_IMP_EVICTED); + LASSERT(state <= LUSTRE_IMP_EVICTED); return import_state_names[state]; } diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h b/drivers/staging/lustre/lustre/include/lustre_lib.h index c5713d74486a..2e66b271b6e9 100644 --- a/drivers/staging/lustre/lustre/include/lustre_lib.h +++ b/drivers/staging/lustre/lustre/include/lustre_lib.h @@ -280,16 +280,16 @@ static inline void obd_ioctl_freedata(char *buf, int len) #define OBD_IOC_DATA_TYPE long #define OBD_IOC_CREATE _IOWR('f', 101, OBD_IOC_DATA_TYPE) -#define OBD_IOC_DESTROY _IOW ('f', 104, OBD_IOC_DATA_TYPE) +#define OBD_IOC_DESTROY _IOW('f', 104, OBD_IOC_DATA_TYPE) #define OBD_IOC_PREALLOCATE _IOWR('f', 105, OBD_IOC_DATA_TYPE) -#define OBD_IOC_SETATTR _IOW ('f', 107, OBD_IOC_DATA_TYPE) +#define OBD_IOC_SETATTR _IOW('f', 107, OBD_IOC_DATA_TYPE) #define OBD_IOC_GETATTR _IOWR ('f', 108, OBD_IOC_DATA_TYPE) #define OBD_IOC_READ _IOWR('f', 109, OBD_IOC_DATA_TYPE) #define OBD_IOC_WRITE _IOWR('f', 110, OBD_IOC_DATA_TYPE) #define OBD_IOC_STATFS _IOWR('f', 113, OBD_IOC_DATA_TYPE) -#define OBD_IOC_SYNC _IOW ('f', 114, OBD_IOC_DATA_TYPE) +#define OBD_IOC_SYNC _IOW('f', 114, OBD_IOC_DATA_TYPE) #define OBD_IOC_READ2 _IOWR('f', 115, OBD_IOC_DATA_TYPE) #define OBD_IOC_FORMAT _IOWR('f', 116, OBD_IOC_DATA_TYPE) #define OBD_IOC_PARTITION _IOWR('f', 117, OBD_IOC_DATA_TYPE) @@ -308,13 +308,13 @@ static inline void obd_ioctl_freedata(char *buf, int len) #define OBD_IOC_GETDTNAME OBD_IOC_GETNAME #define OBD_IOC_LOV_GET_CONFIG _IOWR('f', 132, OBD_IOC_DATA_TYPE) -#define OBD_IOC_CLIENT_RECOVER _IOW ('f', 133, OBD_IOC_DATA_TYPE) -#define OBD_IOC_PING_TARGET _IOW ('f', 136, OBD_IOC_DATA_TYPE) +#define OBD_IOC_CLIENT_RECOVER _IOW('f', 133, OBD_IOC_DATA_TYPE) +#define OBD_IOC_PING_TARGET _IOW('f', 136, OBD_IOC_DATA_TYPE) #define OBD_IOC_DEC_FS_USE_COUNT _IO ('f', 139) -#define OBD_IOC_NO_TRANSNO _IOW ('f', 140, OBD_IOC_DATA_TYPE) -#define OBD_IOC_SET_READONLY _IOW ('f', 141, OBD_IOC_DATA_TYPE) -#define OBD_IOC_ABORT_RECOVERY _IOR ('f', 142, OBD_IOC_DATA_TYPE) +#define OBD_IOC_NO_TRANSNO _IOW('f', 140, OBD_IOC_DATA_TYPE) +#define OBD_IOC_SET_READONLY _IOW('f', 141, OBD_IOC_DATA_TYPE) +#define OBD_IOC_ABORT_RECOVERY _IOR('f', 142, OBD_IOC_DATA_TYPE) #define OBD_IOC_ROOT_SQUASH _IOWR('f', 143, OBD_IOC_DATA_TYPE) @@ -324,27 +324,27 @@ static inline void obd_ioctl_freedata(char *buf, int len) #define OBD_IOC_CLOSE_UUID _IOWR ('f', 147, OBD_IOC_DATA_TYPE) -#define OBD_IOC_CHANGELOG_SEND _IOW ('f', 148, OBD_IOC_DATA_TYPE) +#define OBD_IOC_CHANGELOG_SEND _IOW('f', 148, OBD_IOC_DATA_TYPE) #define OBD_IOC_GETDEVICE _IOWR ('f', 149, OBD_IOC_DATA_TYPE) #define OBD_IOC_FID2PATH _IOWR ('f', 150, OBD_IOC_DATA_TYPE) /* see also for ioctls 151-153 */ /* OBD_IOC_LOV_SETSTRIPE: See also LL_IOC_LOV_SETSTRIPE */ -#define OBD_IOC_LOV_SETSTRIPE _IOW ('f', 154, OBD_IOC_DATA_TYPE) +#define OBD_IOC_LOV_SETSTRIPE _IOW('f', 154, OBD_IOC_DATA_TYPE) /* OBD_IOC_LOV_GETSTRIPE: See also LL_IOC_LOV_GETSTRIPE */ -#define OBD_IOC_LOV_GETSTRIPE _IOW ('f', 155, OBD_IOC_DATA_TYPE) +#define OBD_IOC_LOV_GETSTRIPE _IOW('f', 155, OBD_IOC_DATA_TYPE) /* OBD_IOC_LOV_SETEA: See also LL_IOC_LOV_SETEA */ -#define OBD_IOC_LOV_SETEA _IOW ('f', 156, OBD_IOC_DATA_TYPE) +#define OBD_IOC_LOV_SETEA _IOW('f', 156, OBD_IOC_DATA_TYPE) /* see for ioctls 157-159 */ /* OBD_IOC_QUOTACHECK: See also LL_IOC_QUOTACHECK */ -#define OBD_IOC_QUOTACHECK _IOW ('f', 160, int) +#define OBD_IOC_QUOTACHECK _IOW('f', 160, int) /* OBD_IOC_POLL_QUOTACHECK: See also LL_IOC_POLL_QUOTACHECK */ -#define OBD_IOC_POLL_QUOTACHECK _IOR ('f', 161, struct if_quotacheck *) +#define OBD_IOC_POLL_QUOTACHECK _IOR('f', 161, struct if_quotacheck *) /* OBD_IOC_QUOTACTL: See also LL_IOC_QUOTACTL */ #define OBD_IOC_QUOTACTL _IOWR('f', 162, struct if_quotactl) /* see also for ioctls 163-176 */ -#define OBD_IOC_CHANGELOG_REG _IOW ('f', 177, struct obd_ioctl_data) -#define OBD_IOC_CHANGELOG_DEREG _IOW ('f', 178, struct obd_ioctl_data) -#define OBD_IOC_CHANGELOG_CLEAR _IOW ('f', 179, struct obd_ioctl_data) +#define OBD_IOC_CHANGELOG_REG _IOW('f', 177, struct obd_ioctl_data) +#define OBD_IOC_CHANGELOG_DEREG _IOW('f', 178, struct obd_ioctl_data) +#define OBD_IOC_CHANGELOG_CLEAR _IOW('f', 179, struct obd_ioctl_data) #define OBD_IOC_RECORD _IOWR('f', 180, OBD_IOC_DATA_TYPE) #define OBD_IOC_ENDRECORD _IOWR('f', 181, OBD_IOC_DATA_TYPE) #define OBD_IOC_PARSE _IOWR('f', 182, OBD_IOC_DATA_TYPE) @@ -352,7 +352,7 @@ static inline void obd_ioctl_freedata(char *buf, int len) #define OBD_IOC_PROCESS_CFG _IOWR('f', 184, OBD_IOC_DATA_TYPE) #define OBD_IOC_DUMP_LOG _IOWR('f', 185, OBD_IOC_DATA_TYPE) #define OBD_IOC_CLEAR_LOG _IOWR('f', 186, OBD_IOC_DATA_TYPE) -#define OBD_IOC_PARAM _IOW ('f', 187, OBD_IOC_DATA_TYPE) +#define OBD_IOC_PARAM _IOW('f', 187, OBD_IOC_DATA_TYPE) #define OBD_IOC_POOL _IOWR('f', 188, OBD_IOC_DATA_TYPE) #define OBD_IOC_REPLACE_NIDS _IOWR('f', 189, OBD_IOC_DATA_TYPE) diff --git a/drivers/staging/lustre/lustre/obdclass/debug.c b/drivers/staging/lustre/lustre/obdclass/debug.c index 43a7f7a79b35..e4edfb2c0a20 100644 --- a/drivers/staging/lustre/lustre/obdclass/debug.c +++ b/drivers/staging/lustre/lustre/obdclass/debug.c @@ -68,8 +68,8 @@ int block_debug_check(char *who, void *addr, int end, __u64 off, __u64 id) LASSERT(addr); - ne_off = le64_to_cpu (off); - id = le64_to_cpu (id); + ne_off = le64_to_cpu(off); + id = le64_to_cpu(id); if (memcmp(addr, (char *)&ne_off, LPDS)) { CDEBUG(D_ERROR, "%s: id %#llx offset %llu off: %#llx != %#llx\n", who, id, off, *(__u64 *)addr, ne_off); diff --git a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h index aba646956900..ae19d396b537 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h +++ b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h @@ -403,20 +403,20 @@ extern struct lu_context_key osc_session_key; int osc_lock_init(const struct lu_env *env, struct cl_object *obj, struct cl_lock *lock, const struct cl_io *io); -int osc_io_init (const struct lu_env *env, - struct cl_object *obj, struct cl_io *io); -int osc_req_init (const struct lu_env *env, struct cl_device *dev, - struct cl_req *req); +int osc_io_init(const struct lu_env *env, + struct cl_object *obj, struct cl_io *io); +int osc_req_init(const struct lu_env *env, struct cl_device *dev, + struct cl_req *req); struct lu_object *osc_object_alloc(const struct lu_env *env, const struct lu_object_header *hdr, struct lu_device *dev); int osc_page_init(const struct lu_env *env, struct cl_object *obj, struct cl_page *page, pgoff_t ind); -void osc_index2policy (ldlm_policy_data_t *policy, const struct cl_object *obj, - pgoff_t start, pgoff_t end); -int osc_lvb_print (const struct lu_env *env, void *cookie, - lu_printer_t p, const struct ost_lvb *lvb); +void osc_index2policy(ldlm_policy_data_t *policy, const struct cl_object *obj, + pgoff_t start, pgoff_t end); +int osc_lvb_print(const struct lu_env *env, void *cookie, + lu_printer_t p, const struct ost_lvb *lvb); void osc_lru_add_batch(struct client_obd *cli, struct list_head *list); void osc_page_submit(const struct lu_env *env, struct osc_page *opg, @@ -448,11 +448,11 @@ void osc_io_unplug(const struct lu_env *env, struct client_obd *cli, struct osc_object *osc); int lru_queue_work(const struct lu_env *env, void *data); -void osc_object_set_contended (struct osc_object *obj); +void osc_object_set_contended(struct osc_object *obj); void osc_object_clear_contended(struct osc_object *obj); -int osc_object_is_contended (struct osc_object *obj); +int osc_object_is_contended(struct osc_object *obj); -int osc_lock_is_lockless (const struct osc_lock *olck); +int osc_lock_is_lockless(const struct osc_lock *olck); /***************************************************************************** * diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c index 5b9f72c909b7..4d3eed6ee3f7 100644 --- a/drivers/staging/lustre/lustre/osc/osc_request.c +++ b/drivers/staging/lustre/lustre/osc/osc_request.c @@ -2485,7 +2485,7 @@ static int osc_statfs_async(struct obd_export *exp, } req->rq_interpret_reply = (ptlrpc_interpterer_t)osc_statfs_interpret; - CLASSERT (sizeof(*aa) <= sizeof(req->rq_async_args)); + CLASSERT(sizeof(*aa) <= sizeof(req->rq_async_args)); aa = ptlrpc_req_async_args(req); aa->aa_oi = oinfo; -- cgit v1.2.3 From 6cead36d284f230d29c2500c774180b8c716d4e6 Mon Sep 17 00:00:00 2001 From: Vitaly Fertman Date: Wed, 30 Mar 2016 19:49:06 -0400 Subject: staging/lustre/ldlm: Solve a race for LRU lock cancel This patch solves a race condition that the lock may be used again after LRU cancellation policy check. In that case, the lock may have locked or dirty pages that makes the policy check totally useless. The problem is solved by checking l_last_used at cancellation time therefore it can make sure that the lock has not been used. Signed-off-by: Jinshan Xiong Signed-off-by: Vitaly Fertman Reviewed-on: http://review.whamcloud.com/12603 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5781 Reviewed-by: James Simmons Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/ldlm/ldlm_internal.h | 3 ++- drivers/staging/lustre/lustre/ldlm/ldlm_lock.c | 16 +++++++++++++--- drivers/staging/lustre/lustre/ldlm/ldlm_request.c | 11 +++++++++-- 3 files changed, 24 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h b/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h index e31d84aad4e4..351f8b44947f 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h @@ -146,7 +146,8 @@ void ldlm_lock_decref_internal(struct ldlm_lock *, __u32 mode); void ldlm_lock_decref_internal_nolock(struct ldlm_lock *, __u32 mode); int ldlm_run_ast_work(struct ldlm_namespace *ns, struct list_head *rpc_list, enum ldlm_desc_ast_t ast_type); -int ldlm_lock_remove_from_lru(struct ldlm_lock *lock); +int ldlm_lock_remove_from_lru_check(struct ldlm_lock *lock, time_t last_use); +#define ldlm_lock_remove_from_lru(lock) ldlm_lock_remove_from_lru_check(lock, 0) int ldlm_lock_remove_from_lru_nolock(struct ldlm_lock *lock); void ldlm_lock_destroy_nolock(struct ldlm_lock *lock); diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c index 27a051b085b5..3f9b85262770 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c @@ -229,15 +229,25 @@ int ldlm_lock_remove_from_lru_nolock(struct ldlm_lock *lock) /** * Removes LDLM lock \a lock from LRU. Obtains the LRU lock first. + * + * If \a last_use is non-zero, it will remove the lock from LRU only if + * it matches lock's l_last_used. + * + * \retval 0 if \a last_use is set, the lock is not in LRU list or \a last_use + * doesn't match lock's l_last_used; + * otherwise, the lock hasn't been in the LRU list. + * \retval 1 the lock was in LRU list and removed. */ -int ldlm_lock_remove_from_lru(struct ldlm_lock *lock) +int ldlm_lock_remove_from_lru_check(struct ldlm_lock *lock, time_t last_use) { struct ldlm_namespace *ns = ldlm_lock_to_ns(lock); - int rc; + int rc = 0; spin_lock(&ns->ns_lock); - rc = ldlm_lock_remove_from_lru_nolock(lock); + if (last_use == 0 || last_use == lock->l_last_used) + rc = ldlm_lock_remove_from_lru_nolock(lock); spin_unlock(&ns->ns_lock); + return rc; } diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c index 9aa4c2dfe143..5b0e396a9908 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c @@ -1369,6 +1369,7 @@ static int ldlm_prepare_lru_list(struct ldlm_namespace *ns, while (!list_empty(&ns->ns_unused_list)) { ldlm_policy_res_t result; + time_t last_use = 0; /* all unused locks */ if (remained-- <= 0) @@ -1387,6 +1388,10 @@ static int ldlm_prepare_lru_list(struct ldlm_namespace *ns, /* already processed */ continue; + last_use = lock->l_last_used; + if (last_use == cfs_time_current()) + continue; + /* Somebody is already doing CANCEL. No need for this * lock in LRU, do not traverse it again. */ @@ -1434,11 +1439,13 @@ static int ldlm_prepare_lru_list(struct ldlm_namespace *ns, lock_res_and_lock(lock); /* Check flags again under the lock. */ if ((lock->l_flags & LDLM_FL_CANCELING) || - (ldlm_lock_remove_from_lru(lock) == 0)) { + (ldlm_lock_remove_from_lru_check(lock, last_use) == 0)) { /* Another thread is removing lock from LRU, or * somebody is already doing CANCEL, or there * is a blocking request which will send cancel - * by itself, or the lock is no longer unused. + * by itself, or the lock is no longer unused or + * the lock has been used since the pf() call and + * pages could be put under it. */ unlock_res_and_lock(lock); lu_ref_del(&lock->l_reference, -- cgit v1.2.3 From 30889c72a9fe53b3d4303464fc688497cbb14219 Mon Sep 17 00:00:00 2001 From: Bobi Jam Date: Wed, 30 Mar 2016 19:49:07 -0400 Subject: staging/lustre: lov_io_init() should return error code lov_io_init_empty/release() should returns error code instead of true on error case. Fault IO needs to handle restart in the case of accessing HSM released file Signed-off-by: Bobi Jam Reviewed-on: http://review.whamcloud.com/17240 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-7446 Reviewed-by: John L. Hammond Reviewed-by: Jinshan Xiong Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/llite_mmap.c | 4 ++++ drivers/staging/lustre/lustre/lov/lov_io.c | 4 ++-- drivers/staging/lustre/lustre/obdclass/cl_io.c | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/llite/llite_mmap.c b/drivers/staging/lustre/lustre/llite/llite_mmap.c index 83d7006546dc..5b4382cca0d7 100644 --- a/drivers/staging/lustre/lustre/llite/llite_mmap.c +++ b/drivers/staging/lustre/lustre/llite/llite_mmap.c @@ -123,6 +123,7 @@ ll_fault_io_init(struct vm_area_struct *vma, struct lu_env **env_ret, *env_ret = env; +restart: io = vvp_env_thread_io(env); io->ci_obj = ll_i2info(inode)->lli_clob; LASSERT(io->ci_obj); @@ -157,6 +158,9 @@ ll_fault_io_init(struct vm_area_struct *vma, struct lu_env **env_ret, } else { LASSERT(rc < 0); cl_io_fini(env, io); + if (io->ci_need_restart) + goto restart; + cl_env_nested_put(nest, env); io = ERR_PTR(rc); } diff --git a/drivers/staging/lustre/lustre/lov/lov_io.c b/drivers/staging/lustre/lustre/lov/lov_io.c index ba79955f54bb..41512372c472 100644 --- a/drivers/staging/lustre/lustre/lov/lov_io.c +++ b/drivers/staging/lustre/lustre/lov/lov_io.c @@ -916,7 +916,7 @@ int lov_io_init_empty(const struct lu_env *env, struct cl_object *obj, } io->ci_result = result < 0 ? result : 0; - return result != 0; + return result; } int lov_io_init_released(const struct lu_env *env, struct cl_object *obj, @@ -959,7 +959,7 @@ int lov_io_init_released(const struct lu_env *env, struct cl_object *obj, } io->ci_result = result < 0 ? result : 0; - return result != 0; + return result; } /** @} lov */ diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c index 7655dc485fef..f4b3178ec043 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_io.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c @@ -133,6 +133,7 @@ void cl_io_fini(const struct lu_env *env, struct cl_io *io) case CIT_WRITE: break; case CIT_FAULT: + break; case CIT_FSYNC: LASSERT(!io->ci_need_restart); break; -- cgit v1.2.3 From 4c5b7f3ae53b02136d38dee46b412ac8a7f6f4ff Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 18 Mar 2016 19:14:55 -0400 Subject: drm/atomic: export drm_atomic_helper_wait_for_fences() Signed-off-by: Rob Clark Reviewed-by: Gustavo Padovan Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1458342904-23326-3-git-send-email-robdclark@gmail.com --- drivers/gpu/drm/drm_atomic_helper.c | 15 +++++++++++++-- include/drm/drm_atomic_helper.h | 2 ++ 2 files changed, 15 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 91351111d0f9..00afa9ffa7d0 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -984,7 +984,17 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev, } EXPORT_SYMBOL(drm_atomic_helper_commit_modeset_enables); -static void wait_for_fences(struct drm_device *dev, +/** + * drm_atomic_helper_wait_for_fences - wait for fences stashed in plane state + * @dev: DRM device + * @state: atomic state object with old state structures + * + * For implicit sync, driver should fish the exclusive fence out from the + * incoming fb's and stash it in the drm_plane_state. This is called after + * drm_atomic_helper_swap_state() so it uses the current plane state (and + * just uses the atomic state to find the changed planes) + */ +void drm_atomic_helper_wait_for_fences(struct drm_device *dev, struct drm_atomic_state *state) { struct drm_plane *plane; @@ -1002,6 +1012,7 @@ static void wait_for_fences(struct drm_device *dev, plane->state->fence = NULL; } } +EXPORT_SYMBOL(drm_atomic_helper_wait_for_fences); /** * drm_atomic_helper_framebuffer_changed - check if framebuffer has changed @@ -1163,7 +1174,7 @@ int drm_atomic_helper_commit(struct drm_device *dev, * current layout. */ - wait_for_fences(dev, state); + drm_atomic_helper_wait_for_fences(dev, state); drm_atomic_helper_commit_modeset_disables(dev, state); diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h index 9054598c9a7a..fe9d89c7d1ed 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h @@ -42,6 +42,8 @@ int drm_atomic_helper_commit(struct drm_device *dev, struct drm_atomic_state *state, bool async); +void drm_atomic_helper_wait_for_fences(struct drm_device *dev, + struct drm_atomic_state *state); bool drm_atomic_helper_framebuffer_changed(struct drm_device *dev, struct drm_atomic_state *old_state, struct drm_crtc *crtc); -- cgit v1.2.3 From 0b55257ebc66d333e86415b0fdf46450ca807059 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 8 Mar 2016 09:33:39 -0300 Subject: clk: imx6sx: Register SAI clocks as shared clocks SAIx and SAIx_IPG share the same bit fields in the CCM registers, so we should better register them via imx_clk_gate2_shared(). Signed-off-by: Fabio Estevam Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-imx6sx.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/imx/clk-imx6sx.c b/drivers/clk/imx/clk-imx6sx.c index fea125eb4330..97e742a8be17 100644 --- a/drivers/clk/imx/clk-imx6sx.c +++ b/drivers/clk/imx/clk-imx6sx.c @@ -134,6 +134,8 @@ static u32 share_count_esai; static u32 share_count_ssi1; static u32 share_count_ssi2; static u32 share_count_ssi3; +static u32 share_count_sai1; +static u32 share_count_sai2; static struct clk ** const uart_clks[] __initconst = { &clks[IMX6SX_CLK_UART_IPG], @@ -469,10 +471,10 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) clks[IMX6SX_CLK_SSI3] = imx_clk_gate2_shared("ssi3", "ssi3_podf", base + 0x7c, 22, &share_count_ssi3); clks[IMX6SX_CLK_UART_IPG] = imx_clk_gate2("uart_ipg", "ipg", base + 0x7c, 24); clks[IMX6SX_CLK_UART_SERIAL] = imx_clk_gate2("uart_serial", "uart_podf", base + 0x7c, 26); - clks[IMX6SX_CLK_SAI1_IPG] = imx_clk_gate2("sai1_ipg", "ipg", base + 0x7c, 28); - clks[IMX6SX_CLK_SAI2_IPG] = imx_clk_gate2("sai2_ipg", "ipg", base + 0x7c, 30); - clks[IMX6SX_CLK_SAI1] = imx_clk_gate2("sai1", "ssi1_podf", base + 0x7c, 28); - clks[IMX6SX_CLK_SAI2] = imx_clk_gate2("sai2", "ssi2_podf", base + 0x7c, 30); + clks[IMX6SX_CLK_SAI1_IPG] = imx_clk_gate2_shared("sai1_ipg", "ipg", base + 0x7c, 28, &share_count_sai1); + clks[IMX6SX_CLK_SAI2_IPG] = imx_clk_gate2_shared("sai2_ipg", "ipg", base + 0x7c, 30, &share_count_sai2); + clks[IMX6SX_CLK_SAI1] = imx_clk_gate2_shared("sai1", "ssi1_podf", base + 0x7c, 28, &share_count_sai1); + clks[IMX6SX_CLK_SAI2] = imx_clk_gate2_shared("sai2", "ssi2_podf", base + 0x7c, 30, &share_count_sai2); /* CCGR6 */ clks[IMX6SX_CLK_USBOH3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0); -- cgit v1.2.3 From fbf6d8798fceb1f64eb0e5fd7cd541becfc376cd Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Wed, 23 Mar 2016 14:51:12 +0100 Subject: drm/i915: Add locking to pll updates, v3. With async modesets this is no longer protected with connection_mutex, so ensure that each pll has its own lock. The pll configuration state is still protected; it's only the pll updates that need locking against concurrency. Changes since v1: - Rebased. - Fix locking to protect all accesses. (Durgadoss) Changes since v2: - Make the dpll_lock global to protect concurrent updates to the same register, for example DPLL_CTRL1 on skl. (Ander) Signed-off-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/56F29F50.1090708@linux.intel.com Reviewed-by: Ander Conselvan de Oliveira --- drivers/gpu/drm/i915/i915_drv.h | 7 +++++++ drivers/gpu/drm/i915/intel_dpll_mgr.c | 25 +++++++++++++++++++------ 2 files changed, 26 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f6d71590bd7b..86fafd88ad3b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1837,6 +1837,13 @@ struct drm_i915_private { struct intel_shared_dpll shared_dplls[I915_NUM_PLLS]; const struct intel_dpll_mgr *dpll_mgr; + /* + * dpll_lock serializes intel_{prepare,enable,disable}_shared_dpll. + * Must be global rather than per dpll, because on some platforms + * plls share registers. + */ + struct mutex dpll_lock; + unsigned int active_crtcs; unsigned int min_pixclk[I915_MAX_PIPES]; diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c index 19bfe6743ef2..1175eebfe03b 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c @@ -89,14 +89,16 @@ void intel_prepare_shared_dpll(struct intel_crtc *crtc) if (WARN_ON(pll == NULL)) return; + mutex_lock(&dev_priv->dpll_lock); WARN_ON(!pll->config.crtc_mask); - if (pll->active_mask == 0) { + if (!pll->active_mask) { DRM_DEBUG_DRIVER("setting up %s\n", pll->name); WARN_ON(pll->on); assert_shared_dpll_disabled(dev_priv, pll); pll->funcs.mode_set(dev_priv, pll); } + mutex_unlock(&dev_priv->dpll_lock); } /** @@ -113,14 +115,17 @@ void intel_enable_shared_dpll(struct intel_crtc *crtc) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_shared_dpll *pll = crtc->config->shared_dpll; unsigned crtc_mask = 1 << drm_crtc_index(&crtc->base); - unsigned old_mask = pll->active_mask; + unsigned old_mask; if (WARN_ON(pll == NULL)) return; + mutex_lock(&dev_priv->dpll_lock); + old_mask = pll->active_mask; + if (WARN_ON(!(pll->config.crtc_mask & crtc_mask)) || WARN_ON(pll->active_mask & crtc_mask)) - return; + goto out; pll->active_mask |= crtc_mask; @@ -131,13 +136,16 @@ void intel_enable_shared_dpll(struct intel_crtc *crtc) if (old_mask) { WARN_ON(!pll->on); assert_shared_dpll_enabled(dev_priv, pll); - return; + goto out; } WARN_ON(pll->on); DRM_DEBUG_KMS("enabling %s\n", pll->name); pll->funcs.enable(dev_priv, pll); pll->on = true; + +out: + mutex_unlock(&dev_priv->dpll_lock); } void intel_disable_shared_dpll(struct intel_crtc *crtc) @@ -154,8 +162,9 @@ void intel_disable_shared_dpll(struct intel_crtc *crtc) if (pll == NULL) return; + mutex_lock(&dev_priv->dpll_lock); if (WARN_ON(!(pll->active_mask & crtc_mask))) - return; + goto out; DRM_DEBUG_KMS("disable %s (active %x, on? %d) for crtc %d\n", pll->name, pll->active_mask, pll->on, @@ -166,11 +175,14 @@ void intel_disable_shared_dpll(struct intel_crtc *crtc) pll->active_mask &= ~crtc_mask; if (pll->active_mask) - return; + goto out; DRM_DEBUG_KMS("disabling %s\n", pll->name); pll->funcs.disable(dev_priv, pll); pll->on = false; + +out: + mutex_unlock(&dev_priv->dpll_lock); } static struct intel_shared_dpll * @@ -1750,6 +1762,7 @@ void intel_shared_dpll_init(struct drm_device *dev) dev_priv->dpll_mgr = dpll_mgr; dev_priv->num_shared_dpll = i; + mutex_init(&dev_priv->dpll_lock); BUG_ON(dev_priv->num_shared_dpll > I915_NUM_PLLS); -- cgit v1.2.3 From 42a44402ecb78e87eecf7ccad8099287e660ec36 Mon Sep 17 00:00:00 2001 From: Wang Hongcheng Date: Fri, 11 Mar 2016 10:58:42 +0800 Subject: pinctrl: amd:Add device HID for future AMD GPIO controller Add device HID AMDI0030 to match the AMD ACPI Vendor ID (AMDI) as registered in http://www.uefi.org/acpi_id_list, and the GPIO controller on future AMD paltform will use the HID instead of AMD0030. Signed-off-by: Wang Hongcheng Acked-by: Ken Xue Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-amd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c index 5c025f5b5048..cc44ae8c8758 100644 --- a/drivers/pinctrl/pinctrl-amd.c +++ b/drivers/pinctrl/pinctrl-amd.c @@ -844,6 +844,7 @@ static int amd_gpio_remove(struct platform_device *pdev) static const struct acpi_device_id amd_gpio_acpi_match[] = { { "AMD0030", 0 }, + { "AMDI0030", 0}, { }, }; MODULE_DEVICE_TABLE(acpi, amd_gpio_acpi_match); -- cgit v1.2.3 From 456829228f96702ca281b65e11d11e8c09ca9da0 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Wed, 9 Mar 2016 18:16:47 -0800 Subject: clk: imx: clk-gate2: allow custom gate configuration The 2-bit gates found i.MX and Vybrid SoC support different clock configuration: 0b00: clk disabled 0b01: clk enabled in RUN mode but disabled in WAIT and STOP mode 0b10: clk enabled in RUN, WAIT and STOP mode (only Vybrid) 0b11: clk enabled in RUN and WAIT mode For some clocks, we might want to configure different behaviour, e.g. a memory clock should be on even in STOP mode. Add a new function imx_clk_gate2_cgr which allow to configure specific gate values through the cgr_val parameter. Signed-off-by: Stefan Agner Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-gate2.c | 7 +++++-- drivers/clk/imx/clk.h | 13 ++++++++++--- 2 files changed, 15 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c index 8935bff99fe7..db44a198a0d9 100644 --- a/drivers/clk/imx/clk-gate2.c +++ b/drivers/clk/imx/clk-gate2.c @@ -31,6 +31,7 @@ struct clk_gate2 { struct clk_hw hw; void __iomem *reg; u8 bit_idx; + u8 cgr_val; u8 flags; spinlock_t *lock; unsigned int *share_count; @@ -50,7 +51,8 @@ static int clk_gate2_enable(struct clk_hw *hw) goto out; reg = readl(gate->reg); - reg |= 3 << gate->bit_idx; + reg &= ~(3 << gate->bit_idx); + reg |= gate->cgr_val << gate->bit_idx; writel(reg, gate->reg); out: @@ -125,7 +127,7 @@ static struct clk_ops clk_gate2_ops = { struct clk *clk_register_gate2(struct device *dev, const char *name, const char *parent_name, unsigned long flags, - void __iomem *reg, u8 bit_idx, + void __iomem *reg, u8 bit_idx, u8 cgr_val, u8 clk_gate2_flags, spinlock_t *lock, unsigned int *share_count) { @@ -140,6 +142,7 @@ struct clk *clk_register_gate2(struct device *dev, const char *name, /* struct clk_gate2 assignments */ gate->reg = reg; gate->bit_idx = bit_idx; + gate->cgr_val = cgr_val; gate->flags = clk_gate2_flags; gate->lock = lock; gate->share_count = share_count; diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h index d942f5748d08..508d0fad84cf 100644 --- a/drivers/clk/imx/clk.h +++ b/drivers/clk/imx/clk.h @@ -41,7 +41,7 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name, struct clk *clk_register_gate2(struct device *dev, const char *name, const char *parent_name, unsigned long flags, - void __iomem *reg, u8 bit_idx, + void __iomem *reg, u8 bit_idx, u8 cgr_val, u8 clk_gate_flags, spinlock_t *lock, unsigned int *share_count); @@ -55,7 +55,7 @@ static inline struct clk *imx_clk_gate2(const char *name, const char *parent, void __iomem *reg, u8 shift) { return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, - shift, 0, &imx_ccm_lock, NULL); + shift, 0x3, 0, &imx_ccm_lock, NULL); } static inline struct clk *imx_clk_gate2_shared(const char *name, @@ -63,7 +63,14 @@ static inline struct clk *imx_clk_gate2_shared(const char *name, unsigned int *share_count) { return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, - shift, 0, &imx_ccm_lock, share_count); + shift, 0x3, 0, &imx_ccm_lock, share_count); +} + +static inline struct clk *imx_clk_gate2_cgr(const char *name, const char *parent, + void __iomem *reg, u8 shift, u8 cgr_val) +{ + return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, + shift, cgr_val, 0, &imx_ccm_lock, NULL); } struct clk *imx_clk_pfd(const char *name, const char *parent_name, -- cgit v1.2.3 From 0da15d36a90f405541773e884b3264e0f94debd3 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Wed, 9 Mar 2016 18:16:48 -0800 Subject: clk: imx: vf610: leave DDR clock on To use STOP mode without putting DDR3 into self-refresh mode, we need to keep the DDR clock enabled. Use the new gate configuration with a value of 2 to make sure that the clock is enabled in RUN, WAIT and STOP mode. Signed-off-by: Stefan Agner Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-vf610.c | 3 +++ include/dt-bindings/clock/vf610-clock.h | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clk/imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c index 0a94d9661d91..f0ff45811e76 100644 --- a/drivers/clk/imx/clk-vf610.c +++ b/drivers/clk/imx/clk-vf610.c @@ -119,6 +119,7 @@ static unsigned int const clks_init_on[] __initconst = { VF610_CLK_SYS_BUS, VF610_CLK_DDR_SEL, VF610_CLK_DAP, + VF610_CLK_DDRMC, }; static struct clk * __init vf610_get_fixed_clock( @@ -233,6 +234,8 @@ static void __init vf610_clocks_init(struct device_node *ccm_node) clk[VF610_CLK_PLL4_MAIN_DIV] = clk_register_divider_table(NULL, "pll4_audio_div", "pll4_audio", 0, CCM_CACRR, 6, 3, 0, pll4_audio_div_table, &imx_ccm_lock); clk[VF610_CLK_PLL6_MAIN_DIV] = imx_clk_divider("pll6_video_div", "pll6_video", CCM_CACRR, 21, 1); + clk[VF610_CLK_DDRMC] = imx_clk_gate2_cgr("ddrmc", "ddr_sel", CCM_CCGR6, CCM_CCGRx_CGn(14), 0x2); + clk[VF610_CLK_USBPHY0] = imx_clk_gate("usbphy0", "pll3_usb_otg", PLL3_CTRL, 6); clk[VF610_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll7_usb_host", PLL7_CTRL, 6); diff --git a/include/dt-bindings/clock/vf610-clock.h b/include/dt-bindings/clock/vf610-clock.h index 56c16aaea112..cf2c00a06d10 100644 --- a/include/dt-bindings/clock/vf610-clock.h +++ b/include/dt-bindings/clock/vf610-clock.h @@ -195,6 +195,7 @@ #define VF610_CLK_SNVS 182 #define VF610_CLK_DAP 183 #define VF610_CLK_OCOTP 184 -#define VF610_CLK_END 185 +#define VF610_CLK_DDRMC 185 +#define VF610_CLK_END 186 #endif /* __DT_BINDINGS_CLOCK_VF610_H */ -- cgit v1.2.3 From 349efbeedb2b79292eee12cf6b9a2422ef93853d Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Wed, 9 Mar 2016 18:16:49 -0800 Subject: clk: imx: vf610: add WKPU unit Signed-off-by: Stefan Agner Acked-by: Stephen Boyd Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-vf610.c | 2 ++ include/dt-bindings/clock/vf610-clock.h | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clk/imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c index f0ff45811e76..610a72464f1e 100644 --- a/drivers/clk/imx/clk-vf610.c +++ b/drivers/clk/imx/clk-vf610.c @@ -120,6 +120,7 @@ static unsigned int const clks_init_on[] __initconst = { VF610_CLK_DDR_SEL, VF610_CLK_DAP, VF610_CLK_DDRMC, + VF610_CLK_WKPU, }; static struct clk * __init vf610_get_fixed_clock( @@ -235,6 +236,7 @@ static void __init vf610_clocks_init(struct device_node *ccm_node) clk[VF610_CLK_PLL6_MAIN_DIV] = imx_clk_divider("pll6_video_div", "pll6_video", CCM_CACRR, 21, 1); clk[VF610_CLK_DDRMC] = imx_clk_gate2_cgr("ddrmc", "ddr_sel", CCM_CCGR6, CCM_CCGRx_CGn(14), 0x2); + clk[VF610_CLK_WKPU] = imx_clk_gate2_cgr("wkpu", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(10), 0x2); clk[VF610_CLK_USBPHY0] = imx_clk_gate("usbphy0", "pll3_usb_otg", PLL3_CTRL, 6); clk[VF610_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll7_usb_host", PLL7_CTRL, 6); diff --git a/include/dt-bindings/clock/vf610-clock.h b/include/dt-bindings/clock/vf610-clock.h index cf2c00a06d10..7dc1b84fde07 100644 --- a/include/dt-bindings/clock/vf610-clock.h +++ b/include/dt-bindings/clock/vf610-clock.h @@ -196,6 +196,7 @@ #define VF610_CLK_DAP 183 #define VF610_CLK_OCOTP 184 #define VF610_CLK_DDRMC 185 -#define VF610_CLK_END 186 +#define VF610_CLK_WKPU 186 +#define VF610_CLK_END 187 #endif /* __DT_BINDINGS_CLOCK_VF610_H */ -- cgit v1.2.3 From 4cfe6aebb272d7c75a2c21ce5db3a9e10f57901a Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Wed, 9 Mar 2016 18:16:50 -0800 Subject: clk: imx: vf610: add suspend/resume support The clock register are lost when enterying LPSTOPx, hence provide suspend/resume functions restoring them. The clock gates get restored by the individual driver, hence we do not need to restore them here. Signed-off-by: Stefan Agner Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-vf610.c | 48 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c index 610a72464f1e..66e6faede8e5 100644 --- a/drivers/clk/imx/clk-vf610.c +++ b/drivers/clk/imx/clk-vf610.c @@ -10,6 +10,7 @@ #include #include +#include #include #include "clk.h" @@ -40,6 +41,7 @@ #define CCM_CCGR9 (ccm_base + 0x64) #define CCM_CCGR10 (ccm_base + 0x68) #define CCM_CCGR11 (ccm_base + 0x6c) +#define CCM_CCGRx(x) (CCM_CCGR0 + (x) * 4) #define CCM_CMEOR0 (ccm_base + 0x70) #define CCM_CMEOR1 (ccm_base + 0x74) #define CCM_CMEOR2 (ccm_base + 0x78) @@ -115,6 +117,13 @@ static struct clk_div_table pll4_audio_div_table[] = { static struct clk *clk[VF610_CLK_END]; static struct clk_onecell_data clk_data; +static u32 cscmr1; +static u32 cscmr2; +static u32 cscdr1; +static u32 cscdr2; +static u32 cscdr3; +static u32 ccgr[12]; + static unsigned int const clks_init_on[] __initconst = { VF610_CLK_SYS_BUS, VF610_CLK_DDR_SEL, @@ -134,6 +143,43 @@ static struct clk * __init vf610_get_fixed_clock( return clk; }; +static int vf610_clk_suspend(void) +{ + int i; + + cscmr1 = readl_relaxed(CCM_CSCMR1); + cscmr2 = readl_relaxed(CCM_CSCMR2); + + cscdr1 = readl_relaxed(CCM_CSCDR1); + cscdr2 = readl_relaxed(CCM_CSCDR2); + cscdr3 = readl_relaxed(CCM_CSCDR3); + + for (i = 0; i < 12; i++) + ccgr[i] = readl_relaxed(CCM_CCGRx(i)); + + return 0; +} + +static void vf610_clk_resume(void) +{ + int i; + + writel_relaxed(cscmr1, CCM_CSCMR1); + writel_relaxed(cscmr2, CCM_CSCMR2); + + writel_relaxed(cscdr1, CCM_CSCDR1); + writel_relaxed(cscdr2, CCM_CSCDR2); + writel_relaxed(cscdr3, CCM_CSCDR3); + + for (i = 0; i < 12; i++) + writel_relaxed(ccgr[i], CCM_CCGRx(i)); +} + +static struct syscore_ops vf610_clk_syscore_ops = { + .suspend = vf610_clk_suspend, + .resume = vf610_clk_resume, +}; + static void __init vf610_clocks_init(struct device_node *ccm_node) { struct device_node *np; @@ -414,6 +460,8 @@ static void __init vf610_clocks_init(struct device_node *ccm_node) for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) clk_prepare_enable(clk[clks_init_on[i]]); + register_syscore_ops(&vf610_clk_syscore_ops); + /* Add the clocks to provider list */ clk_data.clks = clk; clk_data.clk_num = ARRAY_SIZE(clk); -- cgit v1.2.3 From 3a9b33c6048a9f41c596954e9c3de7c3ab3c4717 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 30 Mar 2016 11:51:25 +0200 Subject: drm/tegra: Don't set a gamma table size Tegra doesn't have any functions to set gamma tables, so this is completely defunct. Not nice to lie to userspace, so let's stop! Cc: Thierry Reding Signed-off-by: Daniel Vetter Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/dc.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index fb2b4b0271a2..3b85a31b625d 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -1722,7 +1722,6 @@ static int tegra_dc_init(struct host1x_client *client) if (err < 0) goto cleanup; - drm_mode_crtc_set_gamma_size(&dc->base, 256); drm_crtc_helper_add(&dc->base, &tegra_crtc_helper_funcs); /* -- cgit v1.2.3 From b95c532148dd839d0cd362e469c9a37172427480 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Wed, 30 Mar 2016 17:16:34 +0200 Subject: drm/i915: Pass crtc_state to color management functions. Signed-off-by: Maarten Lankhorst Reviewed-by: Lionel Landwerlin Link: http://patchwork.freedesktop.org/patch/msgid/1459350996-4957-2-git-send-email-maarten.lankhorst@linux.intel.com --- drivers/gpu/drm/i915/i915_drv.h | 4 ++-- drivers/gpu/drm/i915/intel_color.c | 43 ++++++++++++++++++------------------ drivers/gpu/drm/i915/intel_display.c | 22 +++++++++++------- drivers/gpu/drm/i915/intel_drv.h | 4 ++-- 4 files changed, 40 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 86fafd88ad3b..820c91f551ba 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -612,8 +612,8 @@ struct drm_i915_display_funcs { /* display clock increase/decrease */ /* pll clock increase/decrease */ - void (*load_csc_matrix)(struct drm_crtc *crtc); - void (*load_luts)(struct drm_crtc *crtc); + void (*load_csc_matrix)(struct drm_crtc_state *crtc_state); + void (*load_luts)(struct drm_crtc_state *crtc_state); }; enum forcewake_domain_id { diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index aa0b20dcb834..9cffa638c351 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -92,10 +92,10 @@ static void ctm_mult_by_limited(uint64_t *result, int64_t *input) } /* Set up the pipe CSC unit. */ -static void i9xx_load_csc_matrix(struct drm_crtc *crtc) +static void i9xx_load_csc_matrix(struct drm_crtc_state *crtc_state) { + struct drm_crtc *crtc = crtc_state->crtc; struct drm_device *dev = crtc->dev; - struct drm_crtc_state *crtc_state = crtc->state; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int i, pipe = intel_crtc->pipe; @@ -203,10 +203,10 @@ static void i9xx_load_csc_matrix(struct drm_crtc *crtc) /* * Set up the pipe CSC unit on CherryView. */ -static void cherryview_load_csc_matrix(struct drm_crtc *crtc) +static void cherryview_load_csc_matrix(struct drm_crtc_state *state) { + struct drm_crtc *crtc = state->crtc; struct drm_device *dev = crtc->dev; - struct drm_crtc_state *state = crtc->state; struct drm_i915_private *dev_priv = dev->dev_private; int pipe = to_intel_crtc(crtc)->pipe; uint32_t mode; @@ -252,13 +252,13 @@ static void cherryview_load_csc_matrix(struct drm_crtc *crtc) I915_WRITE(CGM_PIPE_MODE(pipe), mode); } -void intel_color_set_csc(struct drm_crtc *crtc) +void intel_color_set_csc(struct drm_crtc_state *crtc_state) { - struct drm_device *dev = crtc->dev; + struct drm_device *dev = crtc_state->crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; if (dev_priv->display.load_csc_matrix) - dev_priv->display.load_csc_matrix(crtc); + dev_priv->display.load_csc_matrix(crtc_state); } /* Loads the legacy palette/gamma unit for the CRTC. */ @@ -303,19 +303,20 @@ static void i9xx_load_luts_internal(struct drm_crtc *crtc, } } -static void i9xx_load_luts(struct drm_crtc *crtc) +static void i9xx_load_luts(struct drm_crtc_state *crtc_state) { - i9xx_load_luts_internal(crtc, crtc->state->gamma_lut); + i9xx_load_luts_internal(crtc_state->crtc, crtc_state->gamma_lut); } /* Loads the legacy palette/gamma unit for the CRTC on Haswell. */ -static void haswell_load_luts(struct drm_crtc *crtc) +static void haswell_load_luts(struct drm_crtc_state *crtc_state) { + struct drm_crtc *crtc = crtc_state->crtc; struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc_state *intel_crtc_state = - to_intel_crtc_state(crtc->state); + to_intel_crtc_state(crtc_state); bool reenable_ips = false; /* @@ -331,24 +332,24 @@ static void haswell_load_luts(struct drm_crtc *crtc) intel_crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT; I915_WRITE(GAMMA_MODE(intel_crtc->pipe), GAMMA_MODE_MODE_8BIT); - i9xx_load_luts(crtc); + i9xx_load_luts(crtc_state); if (reenable_ips) hsw_enable_ips(intel_crtc); } /* Loads the palette/gamma unit for the CRTC on Broadwell+. */ -static void broadwell_load_luts(struct drm_crtc *crtc) +static void broadwell_load_luts(struct drm_crtc_state *state) { + struct drm_crtc *crtc = state->crtc; struct drm_device *dev = crtc->dev; - struct drm_crtc_state *state = crtc->state; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc_state *intel_state = to_intel_crtc_state(state); enum pipe pipe = to_intel_crtc(crtc)->pipe; uint32_t i, lut_size = INTEL_INFO(dev)->color.degamma_lut_size; if (crtc_state_is_legacy(state)) { - haswell_load_luts(crtc); + haswell_load_luts(state); return; } @@ -421,11 +422,11 @@ static void broadwell_load_luts(struct drm_crtc *crtc) } /* Loads the palette/gamma unit for the CRTC on CherryView. */ -static void cherryview_load_luts(struct drm_crtc *crtc) +static void cherryview_load_luts(struct drm_crtc_state *state) { + struct drm_crtc *crtc = state->crtc; struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_crtc_state *state = crtc->state; enum pipe pipe = to_intel_crtc(crtc)->pipe; struct drm_color_lut *lut; uint32_t i, lut_size; @@ -481,16 +482,16 @@ static void cherryview_load_luts(struct drm_crtc *crtc) i9xx_load_luts_internal(crtc, NULL); } -void intel_color_load_luts(struct drm_crtc *crtc) +void intel_color_load_luts(struct drm_crtc_state *crtc_state) { - struct drm_device *dev = crtc->dev; + struct drm_device *dev = crtc_state->crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; /* The clocks have to be on to load the palette. */ - if (!crtc->state->active) + if (!crtc_state->active) return; - dev_priv->display.load_luts(crtc); + dev_priv->display.load_luts(crtc_state); } int intel_color_check(struct drm_crtc *crtc, diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index fec6392dfc02..c33f2accef1e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3223,7 +3223,7 @@ static void intel_update_pipe_config(struct intel_crtc *crtc, pipe_config->pipe_src_w, pipe_config->pipe_src_h); if (HAS_DDI(dev)) - intel_color_set_csc(&crtc->base); + intel_color_set_csc(&pipe_config->base); /* * Update pipe size and adjust fitter if needed: the reason for this is @@ -4723,6 +4723,8 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_encoder *encoder; int pipe = intel_crtc->pipe; + struct intel_crtc_state *pipe_config = + to_intel_crtc_state(crtc->state); if (WARN_ON(intel_crtc->active)) return; @@ -4770,7 +4772,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) * On ILK+ LUT must be loaded before the pipe is running but with * clocks enabled */ - intel_color_load_luts(crtc); + intel_color_load_luts(&pipe_config->base); if (dev_priv->display.initial_watermarks != NULL) dev_priv->display.initial_watermarks(intel_crtc->config); @@ -4845,7 +4847,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) haswell_set_pipemisc(crtc); - intel_color_set_csc(crtc); + intel_color_set_csc(&pipe_config->base); intel_crtc->active = true; @@ -4874,7 +4876,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) * On ILK+ LUT must be loaded before the pipe is running but with * clocks enabled */ - intel_color_load_luts(crtc); + intel_color_load_luts(&pipe_config->base); intel_ddi_set_pipe_settings(crtc); if (!intel_crtc->config->has_dsi_encoder) @@ -6035,6 +6037,8 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_encoder *encoder; + struct intel_crtc_state *pipe_config = + to_intel_crtc_state(crtc->state); int pipe = intel_crtc->pipe; if (WARN_ON(intel_crtc->active)) @@ -6079,7 +6083,7 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) i9xx_pfit_enable(intel_crtc); - intel_color_load_luts(crtc); + intel_color_load_luts(&pipe_config->base); intel_update_watermarks(crtc); intel_enable_pipe(intel_crtc); @@ -6106,6 +6110,8 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_encoder *encoder; + struct intel_crtc_state *pipe_config = + to_intel_crtc_state(crtc->state); int pipe = intel_crtc->pipe; if (WARN_ON(intel_crtc->active)) @@ -6134,7 +6140,7 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) i9xx_pfit_enable(intel_crtc); - intel_color_load_luts(crtc); + intel_color_load_luts(&pipe_config->base); intel_update_watermarks(crtc); intel_enable_pipe(intel_crtc); @@ -13593,8 +13599,8 @@ static int intel_atomic_commit(struct drm_device *dev, * a modeset as this will be done by * crtc_enable already. */ - intel_color_set_csc(crtc); - intel_color_load_luts(crtc); + intel_color_set_csc(crtc->state); + intel_color_load_luts(crtc->state); } if (!modeset) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index c87b4503435d..6ac46d921cde 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1669,7 +1669,7 @@ extern const struct drm_plane_helper_funcs intel_plane_helper_funcs; /* intel_color.c */ void intel_color_init(struct drm_crtc *crtc); int intel_color_check(struct drm_crtc *crtc, struct drm_crtc_state *state); -void intel_color_set_csc(struct drm_crtc *crtc); -void intel_color_load_luts(struct drm_crtc *crtc); +void intel_color_set_csc(struct drm_crtc_state *crtc_state); +void intel_color_load_luts(struct drm_crtc_state *crtc_state); #endif /* __INTEL_DRV_H__ */ -- cgit v1.2.3 From e872ef6941ac302ec3e30974e84c9070eeec99ef Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Wed, 30 Mar 2016 17:16:35 +0200 Subject: drm/i915: Do not check crtc_state->active in intel_color_load_luts. This is already tested by its callers. Signed-off-by: Maarten Lankhorst Reviewed-by: Lionel Landwerlin Link: http://patchwork.freedesktop.org/patch/msgid/1459350996-4957-3-git-send-email-maarten.lankhorst@linux.intel.com --- drivers/gpu/drm/i915/intel_color.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index 9cffa638c351..1b3f97449395 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -487,10 +487,6 @@ void intel_color_load_luts(struct drm_crtc_state *crtc_state) struct drm_device *dev = crtc_state->crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; - /* The clocks have to be on to load the palette. */ - if (!crtc_state->active) - return; - dev_priv->display.load_luts(crtc_state); } -- cgit v1.2.3 From 20a34e78f0d71cab058a943b2e9601b97b761227 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Wed, 30 Mar 2016 17:16:36 +0200 Subject: drm/i915: Update color management during vblank evasion. Without this a vblank may occur between updating color management and planes, which should be prevented. intel_color_set_csc was called in update pipe config because the handover from hardware may not have any csc set, which resulted in a black screen. Because of this also update color management during fastset. Signed-off-by: Maarten Lankhorst Tested-by: Lionel Landwerlin Reviewed-by: Lionel Landwerlin Link: http://patchwork.freedesktop.org/patch/msgid/1459350996-4957-4-git-send-email-maarten.lankhorst@linux.intel.com [mlankhorst: Remove comment in response to review feedback.] --- drivers/gpu/drm/i915/intel_display.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c33f2accef1e..60bb486b4d6e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3222,9 +3222,6 @@ static void intel_update_pipe_config(struct intel_crtc *crtc, old_crtc_state->pipe_src_w, old_crtc_state->pipe_src_h, pipe_config->pipe_src_w, pipe_config->pipe_src_h); - if (HAS_DDI(dev)) - intel_color_set_csc(&pipe_config->base); - /* * Update pipe size and adjust fitter if needed: the reason for this is * that in compute_mode_changes we check the native mode (not the pfit @@ -13591,18 +13588,6 @@ static int intel_atomic_commit(struct drm_device *dev, dev_priv->display.crtc_enable(crtc); } - if (!modeset && - crtc->state->active && - crtc->state->color_mgmt_changed) { - /* - * Only update color management when not doing - * a modeset as this will be done by - * crtc_enable already. - */ - intel_color_set_csc(crtc->state); - intel_color_load_luts(crtc->state); - } - if (!modeset) intel_pre_plane_update(to_intel_crtc_state(old_crtc_state)); @@ -13921,6 +13906,11 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc, if (modeset) return; + if (crtc->state->color_mgmt_changed || to_intel_crtc_state(crtc->state)->update_pipe) { + intel_color_set_csc(crtc->state); + intel_color_load_luts(crtc->state); + } + if (to_intel_crtc_state(crtc->state)->update_pipe) intel_update_pipe_config(intel_crtc, old_intel_state); else if (INTEL_INFO(dev)->gen >= 9) -- cgit v1.2.3 From 72e96d6450c067f58b65224bb5e73914e2cc43ab Mon Sep 17 00:00:00 2001 From: Joonas Lahtinen Date: Wed, 30 Mar 2016 16:57:10 +0300 Subject: drm/i915: Refer to GGTT {,VM} consistently Refer to the GGTT VM consistently as "ggtt->base" instead of just "ggtt", "vm" or indirectly through other variables like "dev_priv->ggtt.base" to avoid confusion with the i915_ggtt object itself and PPGTT VMs. Refer to the GGTT as "ggtt" instead of indirectly through chaining. As a bonus gets rid of the long-standing i915_obj_to_ggtt vs. i915_gem_obj_to_ggtt conflict, due to removal of i915_obj_to_ggtt! v2: - Added some more after grepping sources with Chris v3: - Refer to GGTT VM through ggtt->base consistently instead of ggtt_vm (Chris) v4: - Convert all dev_priv->ggtt->foo accesses to ggtt->foo. v5: - Make patch checker happy Cc: Tvrtko Ursulin Cc: Mika Kuoppala Cc: Chris Wilson Signed-off-by: Joonas Lahtinen Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 19 ++-- drivers/gpu/drm/i915/i915_dma.c | 21 ++-- drivers/gpu/drm/i915/i915_drv.h | 13 ++- drivers/gpu/drm/i915/i915_gem.c | 50 ++++++--- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 12 +- drivers/gpu/drm/i915/i915_gem_gtt.c | 170 +++++++++++++++-------------- drivers/gpu/drm/i915/i915_gem_gtt.h | 2 +- drivers/gpu/drm/i915/i915_gem_stolen.c | 98 +++++++++-------- drivers/gpu/drm/i915/i915_gpu_error.c | 12 +- drivers/gpu/drm/i915/i915_vgpu.c | 36 +++--- drivers/gpu/drm/i915/intel_display.c | 8 +- drivers/gpu/drm/i915/intel_fbc.c | 5 +- drivers/gpu/drm/i915/intel_fbdev.c | 10 +- drivers/gpu/drm/i915/intel_overlay.c | 10 +- drivers/gpu/drm/i915/intel_pm.c | 13 ++- drivers/gpu/drm/i915/intel_ringbuffer.c | 3 +- 16 files changed, 264 insertions(+), 218 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index d02f8ce0b1c8..74f227415765 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -202,8 +202,8 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) uintptr_t list = (uintptr_t) node->info_ent->data; struct list_head *head; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct i915_address_space *vm = &dev_priv->ggtt.base; + struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; struct i915_vma *vma; u64 total_obj_size, total_gtt_size; int count, ret; @@ -216,11 +216,11 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) switch (list) { case ACTIVE_LIST: seq_puts(m, "Active:\n"); - head = &vm->active_list; + head = &ggtt->base.active_list; break; case INACTIVE_LIST: seq_puts(m, "Inactive:\n"); - head = &vm->inactive_list; + head = &ggtt->base.inactive_list; break; default: mutex_unlock(&dev->struct_mutex); @@ -429,11 +429,11 @@ static int i915_gem_object_info(struct seq_file *m, void* data) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; u32 count, mappable_count, purgeable_count; u64 size, mappable_size, purgeable_size; struct drm_i915_gem_object *obj; - struct i915_address_space *vm = &dev_priv->ggtt.base; struct drm_file *file; struct i915_vma *vma; int ret; @@ -452,12 +452,12 @@ static int i915_gem_object_info(struct seq_file *m, void* data) count, mappable_count, size, mappable_size); size = count = mappable_size = mappable_count = 0; - count_vmas(&vm->active_list, vm_link); + count_vmas(&ggtt->base.active_list, vm_link); seq_printf(m, " %u [%u] active objects, %llu [%llu] bytes\n", count, mappable_count, size, mappable_size); size = count = mappable_size = mappable_count = 0; - count_vmas(&vm->inactive_list, vm_link); + count_vmas(&ggtt->base.inactive_list, vm_link); seq_printf(m, " %u [%u] inactive objects, %llu [%llu] bytes\n", count, mappable_count, size, mappable_size); @@ -492,8 +492,7 @@ static int i915_gem_object_info(struct seq_file *m, void* data) count, size); seq_printf(m, "%llu [%llu] gtt total\n", - dev_priv->ggtt.base.total, - (u64)dev_priv->ggtt.mappable_end - dev_priv->ggtt.base.start); + ggtt->base.total, ggtt->mappable_end - ggtt->base.start); seq_putc(m, '\n'); print_batch_pool_stats(m, dev_priv); diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index d3011735c9c8..a66ce4944cae 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -527,6 +527,7 @@ static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv) { struct apertures_struct *ap; struct pci_dev *pdev = dev_priv->dev->pdev; + struct i915_ggtt *ggtt = &dev_priv->ggtt; bool primary; int ret; @@ -534,8 +535,8 @@ static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv) if (!ap) return -ENOMEM; - ap->ranges[0].base = dev_priv->ggtt.mappable_base; - ap->ranges[0].size = dev_priv->ggtt.mappable_end; + ap->ranges[0].base = ggtt->mappable_base; + ap->ranges[0].size = ggtt->mappable_end; primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; @@ -1170,6 +1171,7 @@ static void i915_driver_cleanup_mmio(struct drm_i915_private *dev_priv) static int i915_driver_init_hw(struct drm_i915_private *dev_priv) { struct drm_device *dev = dev_priv->dev; + struct i915_ggtt *ggtt = &dev_priv->ggtt; uint32_t aperture_size; int ret; @@ -1213,17 +1215,17 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv) if (IS_BROADWATER(dev) || IS_CRESTLINE(dev)) dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(32)); - aperture_size = dev_priv->ggtt.mappable_end; + aperture_size = ggtt->mappable_end; - dev_priv->ggtt.mappable = - io_mapping_create_wc(dev_priv->ggtt.mappable_base, + ggtt->mappable = + io_mapping_create_wc(ggtt->mappable_base, aperture_size); - if (dev_priv->ggtt.mappable == NULL) { + if (!ggtt->mappable) { ret = -EIO; goto out_ggtt; } - dev_priv->ggtt.mtrr = arch_phys_wc_add(dev_priv->ggtt.mappable_base, + ggtt->mtrr = arch_phys_wc_add(ggtt->mappable_base, aperture_size); pm_qos_add_request(&dev_priv->pm_qos, PM_QOS_CPU_DMA_LATENCY, @@ -1266,13 +1268,14 @@ out_ggtt: static void i915_driver_cleanup_hw(struct drm_i915_private *dev_priv) { struct drm_device *dev = dev_priv->dev; + struct i915_ggtt *ggtt = &dev_priv->ggtt; if (dev->pdev->msi_enabled) pci_disable_msi(dev->pdev); pm_qos_remove_request(&dev_priv->pm_qos); - arch_phys_wc_del(dev_priv->ggtt.mtrr); - io_mapping_free(dev_priv->ggtt.mappable); + arch_phys_wc_del(ggtt->mtrr); + io_mapping_free(ggtt->mappable); i915_ggtt_cleanup_hw(dev); } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 820c91f551ba..d3ebb2fa46fa 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3154,9 +3154,6 @@ i915_gem_obj_to_ggtt(struct drm_i915_gem_object *obj) bool i915_gem_obj_is_pinned(struct drm_i915_gem_object *obj); /* Some GGTT VM helpers */ -#define i915_obj_to_ggtt(obj) \ - (&((struct drm_i915_private *)(obj)->base.dev->dev_private)->ggtt.base) - static inline struct i915_hw_ppgtt * i915_vm_to_ppgtt(struct i915_address_space *vm) { @@ -3173,7 +3170,10 @@ static inline bool i915_gem_obj_ggtt_bound(struct drm_i915_gem_object *obj) static inline unsigned long i915_gem_obj_ggtt_size(struct drm_i915_gem_object *obj) { - return i915_gem_obj_size(obj, i915_obj_to_ggtt(obj)); + struct drm_i915_private *dev_priv = to_i915(obj->base.dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; + + return i915_gem_obj_size(obj, &ggtt->base); } static inline int __must_check @@ -3181,7 +3181,10 @@ i915_gem_obj_ggtt_pin(struct drm_i915_gem_object *obj, uint32_t alignment, unsigned flags) { - return i915_gem_object_pin(obj, i915_obj_to_ggtt(obj), + struct drm_i915_private *dev_priv = to_i915(obj->base.dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; + + return i915_gem_object_pin(obj, &ggtt->base, alignment, flags | PIN_GLOBAL); } diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 11a6ccd8c607..ca96fc12cdf4 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -130,9 +130,9 @@ int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_get_aperture *args = data; + struct drm_i915_private *dev_priv = to_i915(dev); struct i915_ggtt *ggtt = &dev_priv->ggtt; + struct drm_i915_gem_get_aperture *args = data; struct i915_vma *vma; size_t pinned; @@ -146,7 +146,7 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, pinned += vma->node.size; mutex_unlock(&dev->struct_mutex); - args->aper_size = dev_priv->ggtt.base.total; + args->aper_size = ggtt->base.total; args->aper_available_size = args->aper_size - pinned; return 0; @@ -765,7 +765,8 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_i915_gem_pwrite *args, struct drm_file *file) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; ssize_t remain; loff_t offset, page_base; char __user *user_data; @@ -807,7 +808,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, * source page isn't available. Return the error and we'll * retry in the slow path. */ - if (fast_user_write(dev_priv->ggtt.mappable, page_base, + if (fast_user_write(ggtt->mappable, page_base, page_offset, user_data, page_length)) { ret = -EFAULT; goto out_flush; @@ -1790,7 +1791,8 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { struct drm_i915_gem_object *obj = to_intel_bo(vma->vm_private_data); struct drm_device *dev = obj->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; struct i915_ggtt_view view = i915_ggtt_view_normal; pgoff_t page_offset; unsigned long pfn; @@ -1825,7 +1827,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) } /* Use a partial view if the object is bigger than the aperture. */ - if (obj->base.size >= dev_priv->ggtt.mappable_end && + if (obj->base.size >= ggtt->mappable_end && obj->tiling_mode == I915_TILING_NONE) { static const unsigned int chunk_size = 256; // 1 MiB @@ -1853,7 +1855,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) goto unpin; /* Finally, remap it using the new GTT offset */ - pfn = dev_priv->ggtt.mappable_base + + pfn = ggtt->mappable_base + i915_gem_obj_ggtt_offset_view(obj, &view); pfn >>= PAGE_SHIFT; @@ -3458,7 +3460,8 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj, uint64_t flags) { struct drm_device *dev = obj->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; u32 fence_alignment, unfenced_alignment; u32 search_flag, alloc_flag; u64 start, end; @@ -3505,7 +3508,7 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj, start = flags & PIN_OFFSET_BIAS ? flags & PIN_OFFSET_MASK : 0; end = vm->total; if (flags & PIN_MAPPABLE) - end = min_t(u64, end, dev_priv->ggtt.mappable_end); + end = min_t(u64, end, ggtt->mappable_end); if (flags & PIN_ZONE_4G) end = min_t(u64, end, (1ULL << 32) - PAGE_SIZE); @@ -3712,6 +3715,9 @@ i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj) int i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) { + struct drm_device *dev = obj->base.dev; + struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; uint32_t old_write_domain, old_read_domains; struct i915_vma *vma; int ret; @@ -3766,7 +3772,7 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) vma = i915_gem_obj_to_ggtt(obj); if (vma && drm_mm_node_allocated(&vma->node) && !obj->active) list_move_tail(&vma->vm_link, - &to_i915(obj->base.dev)->ggtt.base.inactive_list); + &ggtt->base.inactive_list); return 0; } @@ -4297,9 +4303,13 @@ i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj, uint32_t alignment, uint64_t flags) { + struct drm_device *dev = obj->base.dev; + struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; + BUG_ON(!view); - return i915_gem_object_do_pin(obj, i915_obj_to_ggtt(obj), view, + return i915_gem_object_do_pin(obj, &ggtt->base, view, alignment, flags | PIN_GLOBAL); } @@ -4611,13 +4621,15 @@ struct i915_vma *i915_gem_obj_to_vma(struct drm_i915_gem_object *obj, struct i915_vma *i915_gem_obj_to_ggtt_view(struct drm_i915_gem_object *obj, const struct i915_ggtt_view *view) { - struct i915_address_space *ggtt = i915_obj_to_ggtt(obj); + struct drm_device *dev = obj->base.dev; + struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; struct i915_vma *vma; BUG_ON(!view); list_for_each_entry(vma, &obj->vma_list, obj_link) - if (vma->vm == ggtt && + if (vma->vm == &ggtt->base && i915_ggtt_view_equal(&vma->ggtt_view, view)) return vma; return NULL; @@ -5210,11 +5222,12 @@ u64 i915_gem_obj_offset(struct drm_i915_gem_object *o, u64 i915_gem_obj_ggtt_offset_view(struct drm_i915_gem_object *o, const struct i915_ggtt_view *view) { - struct i915_address_space *ggtt = i915_obj_to_ggtt(o); + struct drm_i915_private *dev_priv = to_i915(o->base.dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; struct i915_vma *vma; list_for_each_entry(vma, &o->vma_list, obj_link) - if (vma->vm == ggtt && + if (vma->vm == &ggtt->base && i915_ggtt_view_equal(&vma->ggtt_view, view)) return vma->node.start; @@ -5241,11 +5254,12 @@ bool i915_gem_obj_bound(struct drm_i915_gem_object *o, bool i915_gem_obj_ggtt_bound_view(struct drm_i915_gem_object *o, const struct i915_ggtt_view *view) { - struct i915_address_space *ggtt = i915_obj_to_ggtt(o); + struct drm_i915_private *dev_priv = to_i915(o->base.dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; struct i915_vma *vma; list_for_each_entry(vma, &o->vma_list, obj_link) - if (vma->vm == ggtt && + if (vma->vm == &ggtt->base && i915_ggtt_view_equal(&vma->ggtt_view, view) && drm_mm_node_allocated(&vma->node)) return true; diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 374a0cb7a092..0ee61fd014df 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -313,7 +313,8 @@ relocate_entry_gtt(struct drm_i915_gem_object *obj, uint64_t target_offset) { struct drm_device *dev = obj->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; uint64_t delta = relocation_target(reloc, target_offset); uint64_t offset; void __iomem *reloc_page; @@ -330,7 +331,7 @@ relocate_entry_gtt(struct drm_i915_gem_object *obj, /* Map the page containing the relocation we're going to perform. */ offset = i915_gem_obj_ggtt_offset(obj); offset += reloc->offset; - reloc_page = io_mapping_map_atomic_wc(dev_priv->ggtt.mappable, + reloc_page = io_mapping_map_atomic_wc(ggtt->mappable, offset & PAGE_MASK); iowrite32(lower_32_bits(delta), reloc_page + offset_in_page(offset)); @@ -340,7 +341,7 @@ relocate_entry_gtt(struct drm_i915_gem_object *obj, if (offset_in_page(offset) == 0) { io_mapping_unmap_atomic(reloc_page); reloc_page = - io_mapping_map_atomic_wc(dev_priv->ggtt.mappable, + io_mapping_map_atomic_wc(ggtt->mappable, offset); } @@ -1431,7 +1432,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, struct drm_i915_gem_execbuffer2 *args, struct drm_i915_gem_exec_object2 *exec) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; struct drm_i915_gem_request *req = NULL; struct eb_vmas *eb; struct drm_i915_gem_object *batch_obj; @@ -1504,7 +1506,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, if (ctx->ppgtt) vm = &ctx->ppgtt->base; else - vm = &dev_priv->ggtt.base; + vm = &ggtt->base; memset(¶ms_master, 0x00, sizeof(params_master)); diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index f8f09d1cb5ae..ae9cb2735767 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1629,6 +1629,7 @@ static void gen6_write_page_range(struct drm_i915_private *dev_priv, struct i915_page_directory *pd, uint32_t start, uint32_t length) { + struct i915_ggtt *ggtt = &dev_priv->ggtt; struct i915_page_table *pt; uint32_t pde, temp; @@ -1637,7 +1638,7 @@ static void gen6_write_page_range(struct drm_i915_private *dev_priv, /* Make sure write is complete before other code can use this page * table. Also require for WC mapped PTEs */ - readl(dev_priv->ggtt.gsm); + readl(ggtt->gsm); } static uint32_t get_pd_offset(struct i915_hw_ppgtt *ppgtt) @@ -1862,7 +1863,8 @@ static int gen6_alloc_va_range(struct i915_address_space *vm, { DECLARE_BITMAP(new_page_tables, I915_PDES); struct drm_device *dev = vm->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; struct i915_hw_ppgtt *ppgtt = container_of(vm, struct i915_hw_ppgtt, base); struct i915_page_table *pt; @@ -1930,7 +1932,7 @@ static int gen6_alloc_va_range(struct i915_address_space *vm, /* Make sure write is complete before other code can use this page * table. Also require for WC mapped PTEs */ - readl(dev_priv->ggtt.gsm); + readl(ggtt->gsm); mark_tlbs_dirty(ppgtt); return 0; @@ -1995,7 +1997,8 @@ static int gen6_ppgtt_allocate_page_directories(struct i915_hw_ppgtt *ppgtt) { struct i915_address_space *vm = &ppgtt->base; struct drm_device *dev = ppgtt->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; bool retried = false; int ret; @@ -2003,23 +2006,23 @@ static int gen6_ppgtt_allocate_page_directories(struct i915_hw_ppgtt *ppgtt) * allocator works in address space sizes, so it's multiplied by page * size. We allocate at the top of the GTT to avoid fragmentation. */ - BUG_ON(!drm_mm_initialized(&dev_priv->ggtt.base.mm)); + BUG_ON(!drm_mm_initialized(&ggtt->base.mm)); ret = gen6_init_scratch(vm); if (ret) return ret; alloc: - ret = drm_mm_insert_node_in_range_generic(&dev_priv->ggtt.base.mm, + ret = drm_mm_insert_node_in_range_generic(&ggtt->base.mm, &ppgtt->node, GEN6_PD_SIZE, GEN6_PD_ALIGN, 0, - 0, dev_priv->ggtt.base.total, + 0, ggtt->base.total, DRM_MM_TOPDOWN); if (ret == -ENOSPC && !retried) { - ret = i915_gem_evict_something(dev, &dev_priv->ggtt.base, + ret = i915_gem_evict_something(dev, &ggtt->base, GEN6_PD_SIZE, GEN6_PD_ALIGN, I915_CACHE_NONE, - 0, dev_priv->ggtt.base.total, + 0, ggtt->base.total, 0); if (ret) goto err_out; @@ -2032,7 +2035,7 @@ alloc: goto err_out; - if (ppgtt->node.start < dev_priv->ggtt.mappable_end) + if (ppgtt->node.start < ggtt->mappable_end) DRM_DEBUG("Forced to use aperture for PDEs\n"); return 0; @@ -2060,10 +2063,11 @@ static void gen6_scratch_va_range(struct i915_hw_ppgtt *ppgtt, static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) { struct drm_device *dev = ppgtt->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; int ret; - ppgtt->base.pte_encode = dev_priv->ggtt.base.pte_encode; + ppgtt->base.pte_encode = ggtt->base.pte_encode; if (IS_GEN6(dev)) { ppgtt->switch_mm = gen6_mm_switch; } else if (IS_HASWELL(dev)) { @@ -2093,7 +2097,7 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) ppgtt->pd.base.ggtt_offset = ppgtt->node.start / PAGE_SIZE * sizeof(gen6_pte_t); - ppgtt->pd_addr = (gen6_pte_t __iomem *)dev_priv->ggtt.gsm + + ppgtt->pd_addr = (gen6_pte_t __iomem *)ggtt->gsm + ppgtt->pd.base.ggtt_offset / sizeof(gen6_pte_t); gen6_scratch_va_range(ppgtt, 0, ppgtt->base.total); @@ -2261,9 +2265,10 @@ static bool needs_idle_maps(struct drm_device *dev) static bool do_idling(struct drm_i915_private *dev_priv) { + struct i915_ggtt *ggtt = &dev_priv->ggtt; bool ret = dev_priv->mm.interruptible; - if (unlikely(dev_priv->ggtt.do_idle_maps)) { + if (unlikely(ggtt->do_idle_maps)) { dev_priv->mm.interruptible = false; if (i915_gpu_idle(dev_priv->dev)) { DRM_ERROR("Couldn't idle GPU\n"); @@ -2277,7 +2282,9 @@ static bool do_idling(struct drm_i915_private *dev_priv) static void undo_idling(struct drm_i915_private *dev_priv, bool interruptible) { - if (unlikely(dev_priv->ggtt.do_idle_maps)) + struct i915_ggtt *ggtt = &dev_priv->ggtt; + + if (unlikely(ggtt->do_idle_maps)) dev_priv->mm.interruptible = interruptible; } @@ -2321,7 +2328,8 @@ static void i915_ggtt_flush(struct drm_i915_private *dev_priv) void i915_gem_suspend_gtt_mappings(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; /* Don't bother messing with faults pre GEN6 as we have little * documentation supporting that it's a good idea. @@ -2331,10 +2339,8 @@ void i915_gem_suspend_gtt_mappings(struct drm_device *dev) i915_check_and_clear_faults(dev); - dev_priv->ggtt.base.clear_range(&dev_priv->ggtt.base, - dev_priv->ggtt.base.start, - dev_priv->ggtt.base.total, - true); + ggtt->base.clear_range(&ggtt->base, ggtt->base.start, ggtt->base.total, + true); i915_ggtt_flush(dev_priv); } @@ -2364,10 +2370,11 @@ static void gen8_ggtt_insert_entries(struct i915_address_space *vm, uint64_t start, enum i915_cache_level level, u32 unused) { - struct drm_i915_private *dev_priv = vm->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(vm->dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; unsigned first_entry = start >> PAGE_SHIFT; gen8_pte_t __iomem *gtt_entries = - (gen8_pte_t __iomem *)dev_priv->ggtt.gsm + first_entry; + (gen8_pte_t __iomem *)ggtt->gsm + first_entry; int i = 0; struct sg_page_iter sg_iter; dma_addr_t addr = 0; /* shut up gcc */ @@ -2441,10 +2448,11 @@ static void gen6_ggtt_insert_entries(struct i915_address_space *vm, uint64_t start, enum i915_cache_level level, u32 flags) { - struct drm_i915_private *dev_priv = vm->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(vm->dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; unsigned first_entry = start >> PAGE_SHIFT; gen6_pte_t __iomem *gtt_entries = - (gen6_pte_t __iomem *)dev_priv->ggtt.gsm + first_entry; + (gen6_pte_t __iomem *)ggtt->gsm + first_entry; int i = 0; struct sg_page_iter sg_iter; dma_addr_t addr = 0; @@ -2484,12 +2492,13 @@ static void gen8_ggtt_clear_range(struct i915_address_space *vm, uint64_t length, bool use_scratch) { - struct drm_i915_private *dev_priv = vm->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(vm->dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; unsigned first_entry = start >> PAGE_SHIFT; unsigned num_entries = length >> PAGE_SHIFT; gen8_pte_t scratch_pte, __iomem *gtt_base = - (gen8_pte_t __iomem *) dev_priv->ggtt.gsm + first_entry; - const int max_entries = gtt_total_entries(dev_priv->ggtt) - first_entry; + (gen8_pte_t __iomem *)ggtt->gsm + first_entry; + const int max_entries = ggtt_total_entries(ggtt) - first_entry; int i; int rpm_atomic_seq; @@ -2515,12 +2524,13 @@ static void gen6_ggtt_clear_range(struct i915_address_space *vm, uint64_t length, bool use_scratch) { - struct drm_i915_private *dev_priv = vm->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(vm->dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; unsigned first_entry = start >> PAGE_SHIFT; unsigned num_entries = length >> PAGE_SHIFT; gen6_pte_t scratch_pte, __iomem *gtt_base = - (gen6_pte_t __iomem *) dev_priv->ggtt.gsm + first_entry; - const int max_entries = gtt_total_entries(dev_priv->ggtt) - first_entry; + (gen6_pte_t __iomem *)ggtt->gsm + first_entry; + const int max_entries = ggtt_total_entries(ggtt) - first_entry; int i; int rpm_atomic_seq; @@ -2713,8 +2723,8 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev, * aperture. One page should be enough to keep any prefetching inside * of the aperture. */ - struct drm_i915_private *dev_priv = dev->dev_private; - struct i915_address_space *ggtt_vm = &dev_priv->ggtt.base; + struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; struct drm_mm_node *entry; struct drm_i915_gem_object *obj; unsigned long hole_start, hole_end; @@ -2722,13 +2732,13 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev, BUG_ON(mappable_end > end); - ggtt_vm->start = start; + ggtt->base.start = start; /* Subtract the guard page before address space initialization to * shrink the range used by drm_mm */ - ggtt_vm->total = end - start - PAGE_SIZE; - i915_address_space_init(ggtt_vm, dev_priv); - ggtt_vm->total += PAGE_SIZE; + ggtt->base.total = end - start - PAGE_SIZE; + i915_address_space_init(&ggtt->base, dev_priv); + ggtt->base.total += PAGE_SIZE; if (intel_vgpu_active(dev)) { ret = intel_vgt_balloon(dev); @@ -2737,36 +2747,36 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev, } if (!HAS_LLC(dev)) - ggtt_vm->mm.color_adjust = i915_gtt_color_adjust; + ggtt->base.mm.color_adjust = i915_gtt_color_adjust; /* Mark any preallocated objects as occupied */ list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { - struct i915_vma *vma = i915_gem_obj_to_vma(obj, ggtt_vm); + struct i915_vma *vma = i915_gem_obj_to_vma(obj, &ggtt->base); DRM_DEBUG_KMS("reserving preallocated space: %llx + %zx\n", i915_gem_obj_ggtt_offset(obj), obj->base.size); WARN_ON(i915_gem_obj_ggtt_bound(obj)); - ret = drm_mm_reserve_node(&ggtt_vm->mm, &vma->node); + ret = drm_mm_reserve_node(&ggtt->base.mm, &vma->node); if (ret) { DRM_DEBUG_KMS("Reservation failed: %i\n", ret); return ret; } vma->bound |= GLOBAL_BIND; __i915_vma_set_map_and_fenceable(vma); - list_add_tail(&vma->vm_link, &ggtt_vm->inactive_list); + list_add_tail(&vma->vm_link, &ggtt->base.inactive_list); } /* Clear any non-preallocated blocks */ - drm_mm_for_each_hole(entry, &ggtt_vm->mm, hole_start, hole_end) { + drm_mm_for_each_hole(entry, &ggtt->base.mm, hole_start, hole_end) { DRM_DEBUG_KMS("clearing unused GTT space: [%lx, %lx]\n", hole_start, hole_end); - ggtt_vm->clear_range(ggtt_vm, hole_start, + ggtt->base.clear_range(&ggtt->base, hole_start, hole_end - hole_start, true); } /* And finally clear the reserved guard page */ - ggtt_vm->clear_range(ggtt_vm, end - PAGE_SIZE, PAGE_SIZE, true); + ggtt->base.clear_range(&ggtt->base, end - PAGE_SIZE, PAGE_SIZE, true); if (USES_PPGTT(dev) && !USES_FULL_PPGTT(dev)) { struct i915_hw_ppgtt *ppgtt; @@ -2797,8 +2807,8 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev, true); dev_priv->mm.aliasing_ppgtt = ppgtt; - WARN_ON(dev_priv->ggtt.base.bind_vma != ggtt_bind_vma); - dev_priv->ggtt.base.bind_vma = aliasing_gtt_bind_vma; + WARN_ON(ggtt->base.bind_vma != ggtt_bind_vma); + ggtt->base.bind_vma = aliasing_gtt_bind_vma; } return 0; @@ -2810,13 +2820,10 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev, */ void i915_gem_init_ggtt(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; - u64 gtt_size, mappable_size; - - gtt_size = dev_priv->ggtt.base.total; - mappable_size = dev_priv->ggtt.mappable_end; + struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; - i915_gem_setup_global_gtt(dev, 0, mappable_size, gtt_size); + i915_gem_setup_global_gtt(dev, 0, ggtt->mappable_end, ggtt->base.total); } /** @@ -2825,8 +2832,8 @@ void i915_gem_init_ggtt(struct drm_device *dev) */ void i915_ggtt_cleanup_hw(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; - struct i915_address_space *vm = &dev_priv->ggtt.base; + struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; if (dev_priv->mm.aliasing_ppgtt) { struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; @@ -2836,15 +2843,15 @@ void i915_ggtt_cleanup_hw(struct drm_device *dev) i915_gem_cleanup_stolen(dev); - if (drm_mm_initialized(&vm->mm)) { + if (drm_mm_initialized(&ggtt->base.mm)) { if (intel_vgpu_active(dev)) intel_vgt_deballoon(); - drm_mm_takedown(&vm->mm); - list_del(&vm->global_link); + drm_mm_takedown(&ggtt->base.mm); + list_del(&ggtt->base.global_link); } - vm->cleanup(vm); + ggtt->base.cleanup(&ggtt->base); } static unsigned int gen6_get_total_gtt_size(u16 snb_gmch_ctl) @@ -2928,13 +2935,14 @@ static size_t gen9_get_stolen_size(u16 gen9_gmch_ctl) static int ggtt_probe_common(struct drm_device *dev, size_t gtt_size) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; struct i915_page_scratch *scratch_page; - phys_addr_t gtt_phys_addr; + phys_addr_t ggtt_phys_addr; /* For Modern GENs the PTEs and register space are split in the BAR */ - gtt_phys_addr = pci_resource_start(dev->pdev, 0) + - (pci_resource_len(dev->pdev, 0) / 2); + ggtt_phys_addr = pci_resource_start(dev->pdev, 0) + + (pci_resource_len(dev->pdev, 0) / 2); /* * On BXT writes larger than 64 bit to the GTT pagetable range will be @@ -2944,10 +2952,10 @@ static int ggtt_probe_common(struct drm_device *dev, * readback check when writing GTT PTE entries. */ if (IS_BROXTON(dev)) - dev_priv->ggtt.gsm = ioremap_nocache(gtt_phys_addr, gtt_size); + ggtt->gsm = ioremap_nocache(ggtt_phys_addr, gtt_size); else - dev_priv->ggtt.gsm = ioremap_wc(gtt_phys_addr, gtt_size); - if (!dev_priv->ggtt.gsm) { + ggtt->gsm = ioremap_wc(ggtt_phys_addr, gtt_size); + if (!ggtt->gsm) { DRM_ERROR("Failed to map the gtt page table\n"); return -ENOMEM; } @@ -2956,11 +2964,11 @@ static int ggtt_probe_common(struct drm_device *dev, if (IS_ERR(scratch_page)) { DRM_ERROR("Scratch setup failed\n"); /* iounmap will also get called at remove, but meh */ - iounmap(dev_priv->ggtt.gsm); + iounmap(ggtt->gsm); return PTR_ERR(scratch_page); } - dev_priv->ggtt.base.scratch_page = scratch_page; + ggtt->base.scratch_page = scratch_page; return 0; } @@ -3041,7 +3049,7 @@ static void chv_setup_private_ppat(struct drm_i915_private *dev_priv) static int gen8_gmch_probe(struct i915_ggtt *ggtt) { struct drm_device *dev = ggtt->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u16 snb_gmch_ctl; int ret; @@ -3082,7 +3090,6 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt) ggtt->base.bind_vma = ggtt_bind_vma; ggtt->base.unbind_vma = ggtt_unbind_vma; - return ret; } @@ -3132,7 +3139,7 @@ static void gen6_gmch_remove(struct i915_address_space *vm) static int i915_gmch_probe(struct i915_ggtt *ggtt) { struct drm_device *dev = ggtt->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int ret; ret = intel_gmch_probe(dev_priv->bridge_dev, dev_priv->dev->pdev, NULL); @@ -3167,7 +3174,7 @@ static void i915_gmch_remove(struct i915_address_space *vm) */ int i915_ggtt_init_hw(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct i915_ggtt *ggtt = &dev_priv->ggtt; int ret; @@ -3236,33 +3243,30 @@ int i915_ggtt_init_hw(struct drm_device *dev) return 0; out_gtt_cleanup: - ggtt->base.cleanup(&dev_priv->ggtt.base); + ggtt->base.cleanup(&ggtt->base); return ret; } void i915_gem_restore_gtt_mappings(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; struct drm_i915_gem_object *obj; - struct i915_address_space *vm; struct i915_vma *vma; bool flush; i915_check_and_clear_faults(dev); /* First fill our portion of the GTT with scratch pages */ - dev_priv->ggtt.base.clear_range(&dev_priv->ggtt.base, - dev_priv->ggtt.base.start, - dev_priv->ggtt.base.total, - true); + ggtt->base.clear_range(&ggtt->base, ggtt->base.start, ggtt->base.total, + true); /* Cache flush objects bound into GGTT and rebind them. */ - vm = &dev_priv->ggtt.base; list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { flush = false; list_for_each_entry(vma, &obj->vma_list, obj_link) { - if (vma->vm != vm) + if (vma->vm != &ggtt->base) continue; WARN_ON(i915_vma_bind(vma, obj->cache_level, @@ -3285,6 +3289,8 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev) } if (USES_PPGTT(dev)) { + struct i915_address_space *vm; + list_for_each_entry(vm, &dev_priv->vm_list, global_link) { /* TODO: Perhaps it shouldn't be gen6 specific */ @@ -3352,11 +3358,13 @@ struct i915_vma * i915_gem_obj_lookup_or_create_ggtt_vma(struct drm_i915_gem_object *obj, const struct i915_ggtt_view *view) { - struct i915_address_space *ggtt = i915_obj_to_ggtt(obj); + struct drm_device *dev = obj->base.dev; + struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; struct i915_vma *vma = i915_gem_obj_to_ggtt_view(obj, view); if (!vma) - vma = __i915_gem_vma_create(obj, ggtt, view); + vma = __i915_gem_vma_create(obj, &ggtt->base, view); return vma; diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index 242a13b8129a..d7dd3d8a8758 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -42,7 +42,7 @@ typedef uint64_t gen8_pde_t; typedef uint64_t gen8_ppgtt_pdpe_t; typedef uint64_t gen8_ppgtt_pml4e_t; -#define gtt_total_entries(gtt) ((gtt).base.total >> PAGE_SHIFT) +#define ggtt_total_entries(ggtt) ((ggtt)->base.total >> PAGE_SHIFT) /* gen6-hsw has bit 11-4 for physical addr bit 39-32 */ #define GEN6_GTT_ADDR_ENCODE(addr) ((addr) | (((addr) >> 28) & 0xff0)) diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c index de891c928b2f..ea06da012d32 100644 --- a/drivers/gpu/drm/i915/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c @@ -72,9 +72,11 @@ int i915_gem_stolen_insert_node(struct drm_i915_private *dev_priv, struct drm_mm_node *node, u64 size, unsigned alignment) { + struct i915_ggtt *ggtt = &dev_priv->ggtt; + return i915_gem_stolen_insert_node_in_range(dev_priv, node, size, - alignment, 0, - dev_priv->ggtt.stolen_usable_size); + alignment, 0, + ggtt->stolen_usable_size); } void i915_gem_stolen_remove_node(struct drm_i915_private *dev_priv, @@ -87,7 +89,8 @@ void i915_gem_stolen_remove_node(struct drm_i915_private *dev_priv, static unsigned long i915_stolen_to_physical(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; struct resource *r; u32 base; @@ -134,7 +137,7 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) I85X_DRB3, &tmp); tom = tmp * MB(32); - base = tom - tseg_size - dev_priv->ggtt.stolen_size; + base = tom - tseg_size - ggtt->stolen_size; } else if (IS_845G(dev)) { u32 tseg_size = 0; u32 tom; @@ -158,7 +161,7 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) I830_DRB3, &tmp); tom = tmp * MB(32); - base = tom - tseg_size - dev_priv->ggtt.stolen_size; + base = tom - tseg_size - ggtt->stolen_size; } else if (IS_I830(dev)) { u32 tseg_size = 0; u32 tom; @@ -178,7 +181,7 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) I830_DRB3, &tmp); tom = tmp * MB(32); - base = tom - tseg_size - dev_priv->ggtt.stolen_size; + base = tom - tseg_size - ggtt->stolen_size; } if (base == 0) @@ -189,41 +192,41 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) struct { u32 start, end; } stolen[2] = { - { .start = base, .end = base + dev_priv->ggtt.stolen_size, }, - { .start = base, .end = base + dev_priv->ggtt.stolen_size, }, + { .start = base, .end = base + ggtt->stolen_size, }, + { .start = base, .end = base + ggtt->stolen_size, }, }; - u64 gtt_start, gtt_end; + u64 ggtt_start, ggtt_end; - gtt_start = I915_READ(PGTBL_CTL); + ggtt_start = I915_READ(PGTBL_CTL); if (IS_GEN4(dev)) - gtt_start = (gtt_start & PGTBL_ADDRESS_LO_MASK) | - (gtt_start & PGTBL_ADDRESS_HI_MASK) << 28; + ggtt_start = (ggtt_start & PGTBL_ADDRESS_LO_MASK) | + (ggtt_start & PGTBL_ADDRESS_HI_MASK) << 28; else - gtt_start &= PGTBL_ADDRESS_LO_MASK; - gtt_end = gtt_start + gtt_total_entries(dev_priv->ggtt) * 4; + ggtt_start &= PGTBL_ADDRESS_LO_MASK; + ggtt_end = ggtt_start + ggtt_total_entries(ggtt) * 4; - if (gtt_start >= stolen[0].start && gtt_start < stolen[0].end) - stolen[0].end = gtt_start; - if (gtt_end > stolen[1].start && gtt_end <= stolen[1].end) - stolen[1].start = gtt_end; + if (ggtt_start >= stolen[0].start && ggtt_start < stolen[0].end) + stolen[0].end = ggtt_start; + if (ggtt_end > stolen[1].start && ggtt_end <= stolen[1].end) + stolen[1].start = ggtt_end; /* pick the larger of the two chunks */ if (stolen[0].end - stolen[0].start > stolen[1].end - stolen[1].start) { base = stolen[0].start; - dev_priv->ggtt.stolen_size = stolen[0].end - stolen[0].start; + ggtt->stolen_size = stolen[0].end - stolen[0].start; } else { base = stolen[1].start; - dev_priv->ggtt.stolen_size = stolen[1].end - stolen[1].start; + ggtt->stolen_size = stolen[1].end - stolen[1].start; } if (stolen[0].start != stolen[1].start || stolen[0].end != stolen[1].end) { DRM_DEBUG_KMS("GTT within stolen memory at 0x%llx-0x%llx\n", - (unsigned long long) gtt_start, - (unsigned long long) gtt_end - 1); + (unsigned long long)ggtt_start, + (unsigned long long)ggtt_end - 1); DRM_DEBUG_KMS("Stolen memory adjusted to 0x%x-0x%x\n", - base, base + (u32) dev_priv->ggtt.stolen_size - 1); + base, base + (u32)ggtt->stolen_size - 1); } } @@ -233,7 +236,7 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) * kernel. So if the region is already marked as busy, something * is seriously wrong. */ - r = devm_request_mem_region(dev->dev, base, dev_priv->ggtt.stolen_size, + r = devm_request_mem_region(dev->dev, base, ggtt->stolen_size, "Graphics Stolen Memory"); if (r == NULL) { /* @@ -245,7 +248,7 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) * reservation starting from 1 instead of 0. */ r = devm_request_mem_region(dev->dev, base + 1, - dev_priv->ggtt.stolen_size - 1, + ggtt->stolen_size - 1, "Graphics Stolen Memory"); /* * GEN3 firmware likes to smash pci bridges into the stolen @@ -253,7 +256,7 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) */ if (r == NULL && !IS_GEN3(dev)) { DRM_ERROR("conflict detected with stolen region: [0x%08x - 0x%08x]\n", - base, base + (uint32_t)dev_priv->ggtt.stolen_size); + base, base + (uint32_t)ggtt->stolen_size); base = 0; } } @@ -274,11 +277,12 @@ void i915_gem_cleanup_stolen(struct drm_device *dev) static void g4x_get_stolen_reserved(struct drm_i915_private *dev_priv, unsigned long *base, unsigned long *size) { + struct i915_ggtt *ggtt = &dev_priv->ggtt; uint32_t reg_val = I915_READ(IS_GM45(dev_priv) ? CTG_STOLEN_RESERVED : ELK_STOLEN_RESERVED); unsigned long stolen_top = dev_priv->mm.stolen_base + - dev_priv->ggtt.stolen_size; + ggtt->stolen_size; *base = (reg_val & G4X_STOLEN_RESERVED_ADDR2_MASK) << 16; @@ -369,10 +373,11 @@ static void gen8_get_stolen_reserved(struct drm_i915_private *dev_priv, static void bdw_get_stolen_reserved(struct drm_i915_private *dev_priv, unsigned long *base, unsigned long *size) { + struct i915_ggtt *ggtt = &dev_priv->ggtt; uint32_t reg_val = I915_READ(GEN6_STOLEN_RESERVED); unsigned long stolen_top; - stolen_top = dev_priv->mm.stolen_base + dev_priv->ggtt.stolen_size; + stolen_top = dev_priv->mm.stolen_base + ggtt->stolen_size; *base = reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK; @@ -388,7 +393,8 @@ static void bdw_get_stolen_reserved(struct drm_i915_private *dev_priv, int i915_gem_init_stolen(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; unsigned long reserved_total, reserved_base = 0, reserved_size; unsigned long stolen_top; @@ -401,14 +407,14 @@ int i915_gem_init_stolen(struct drm_device *dev) } #endif - if (dev_priv->ggtt.stolen_size == 0) + if (ggtt->stolen_size == 0) return 0; dev_priv->mm.stolen_base = i915_stolen_to_physical(dev); if (dev_priv->mm.stolen_base == 0) return 0; - stolen_top = dev_priv->mm.stolen_base + dev_priv->ggtt.stolen_size; + stolen_top = dev_priv->mm.stolen_base + ggtt->stolen_size; switch (INTEL_INFO(dev_priv)->gen) { case 2: @@ -458,19 +464,18 @@ int i915_gem_init_stolen(struct drm_device *dev) return 0; } - dev_priv->ggtt.stolen_reserved_base = reserved_base; - dev_priv->ggtt.stolen_reserved_size = reserved_size; + ggtt->stolen_reserved_base = reserved_base; + ggtt->stolen_reserved_size = reserved_size; /* It is possible for the reserved area to end before the end of stolen * memory, so just consider the start. */ reserved_total = stolen_top - reserved_base; DRM_DEBUG_KMS("Memory reserved for graphics device: %zuK, usable: %luK\n", - dev_priv->ggtt.stolen_size >> 10, - (dev_priv->ggtt.stolen_size - reserved_total) >> 10); + ggtt->stolen_size >> 10, + (ggtt->stolen_size - reserved_total) >> 10); - dev_priv->ggtt.stolen_usable_size = dev_priv->ggtt.stolen_size - - reserved_total; + ggtt->stolen_usable_size = ggtt->stolen_size - reserved_total; /* * Basic memrange allocator for stolen space. @@ -483,7 +488,7 @@ int i915_gem_init_stolen(struct drm_device *dev) * i915_gem_stolen_insert_node_in_range(). We may want to fix the fbcon * problem later. */ - drm_mm_init(&dev_priv->mm.stolen, 0, dev_priv->ggtt.stolen_usable_size); + drm_mm_init(&dev_priv->mm.stolen, 0, ggtt->stolen_usable_size); return 0; } @@ -492,12 +497,13 @@ static struct sg_table * i915_pages_create_for_stolen(struct drm_device *dev, u32 offset, u32 size) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; struct sg_table *st; struct scatterlist *sg; DRM_DEBUG_DRIVER("offset=0x%x, size=%d\n", offset, size); - BUG_ON(offset > dev_priv->ggtt.stolen_size - size); + BUG_ON(offset > ggtt->stolen_size - size); /* We hide that we have no struct page backing our stolen object * by wrapping the contiguous physical allocation with a fake @@ -628,8 +634,8 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, u32 gtt_offset, u32 size) { - struct drm_i915_private *dev_priv = dev->dev_private; - struct i915_address_space *ggtt = &dev_priv->ggtt.base; + struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; struct drm_i915_gem_object *obj; struct drm_mm_node *stolen; struct i915_vma *vma; @@ -675,7 +681,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, if (gtt_offset == I915_GTT_OFFSET_NONE) return obj; - vma = i915_gem_obj_lookup_or_create_vma(obj, ggtt); + vma = i915_gem_obj_lookup_or_create_vma(obj, &ggtt->base); if (IS_ERR(vma)) { ret = PTR_ERR(vma); goto err; @@ -688,8 +694,8 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, */ vma->node.start = gtt_offset; vma->node.size = size; - if (drm_mm_initialized(&ggtt->mm)) { - ret = drm_mm_reserve_node(&ggtt->mm, &vma->node); + if (drm_mm_initialized(&ggtt->base.mm)) { + ret = drm_mm_reserve_node(&ggtt->base.mm, &vma->node); if (ret) { DRM_DEBUG_KMS("failed to allocate stolen GTT space\n"); goto err; @@ -697,7 +703,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, vma->bound |= GLOBAL_BIND; __i915_vma_set_map_and_fenceable(vma); - list_add_tail(&vma->vm_link, &ggtt->inactive_list); + list_add_tail(&vma->vm_link, &ggtt->base.inactive_list); } list_add_tail(&obj->global_list, &dev_priv->mm.bound_list); diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 54c208665b0d..9b55409d91b3 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -627,6 +627,7 @@ i915_error_object_create(struct drm_i915_private *dev_priv, struct drm_i915_gem_object *src, struct i915_address_space *vm) { + struct i915_ggtt *ggtt = &dev_priv->ggtt; struct drm_i915_error_object *dst; struct i915_vma *vma = NULL; int num_pages; @@ -653,7 +654,7 @@ i915_error_object_create(struct drm_i915_private *dev_priv, vma = i915_gem_obj_to_ggtt(src); use_ggtt = (src->cache_level == I915_CACHE_NONE && vma && (vma->bound & GLOBAL_BIND) && - reloc_offset + num_pages * PAGE_SIZE <= dev_priv->ggtt.mappable_end); + reloc_offset + num_pages * PAGE_SIZE <= ggtt->mappable_end); /* Cannot access stolen address directly, try to use the aperture */ if (src->stolen) { @@ -663,7 +664,7 @@ i915_error_object_create(struct drm_i915_private *dev_priv, goto unwind; reloc_offset = i915_gem_obj_ggtt_offset(src); - if (reloc_offset + num_pages * PAGE_SIZE > dev_priv->ggtt.mappable_end) + if (reloc_offset + num_pages * PAGE_SIZE > ggtt->mappable_end) goto unwind; } @@ -689,7 +690,7 @@ i915_error_object_create(struct drm_i915_private *dev_priv, * captures what the GPU read. */ - s = io_mapping_map_atomic_wc(dev_priv->ggtt.mappable, + s = io_mapping_map_atomic_wc(ggtt->mappable, reloc_offset); memcpy_fromio(d, s, PAGE_SIZE); io_mapping_unmap_atomic(s); @@ -1015,7 +1016,8 @@ static void i915_gem_record_active_context(struct intel_engine_cs *engine, static void i915_gem_record_rings(struct drm_device *dev, struct drm_i915_error_state *error) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; struct drm_i915_gem_request *request; int i, count; @@ -1038,7 +1040,7 @@ static void i915_gem_record_rings(struct drm_device *dev, vm = request->ctx && request->ctx->ppgtt ? &request->ctx->ppgtt->base : - &dev_priv->ggtt.base; + &ggtt->base; /* We need to copy these to an anonymous buffer * as the simplest method to avoid being overwritten diff --git a/drivers/gpu/drm/i915/i915_vgpu.c b/drivers/gpu/drm/i915/i915_vgpu.c index 2891bcfcd71e..d02efb8cad4d 100644 --- a/drivers/gpu/drm/i915/i915_vgpu.c +++ b/drivers/gpu/drm/i915/i915_vgpu.c @@ -181,8 +181,8 @@ static int vgt_balloon_space(struct drm_mm *mm, int intel_vgt_balloon(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); - struct i915_address_space *ggtt_vm = &dev_priv->ggtt.base; - unsigned long ggtt_vm_end = ggtt_vm->start + ggtt_vm->total; + struct i915_ggtt *ggtt = &dev_priv->ggtt; + unsigned long ggtt_end = ggtt->base.start + ggtt->base.total; unsigned long mappable_base, mappable_size, mappable_end; unsigned long unmappable_base, unmappable_size, unmappable_end; @@ -202,19 +202,19 @@ int intel_vgt_balloon(struct drm_device *dev) DRM_INFO("Unmappable graphic memory: base 0x%lx size %ldKiB\n", unmappable_base, unmappable_size / 1024); - if (mappable_base < ggtt_vm->start || - mappable_end > dev_priv->ggtt.mappable_end || - unmappable_base < dev_priv->ggtt.mappable_end || - unmappable_end > ggtt_vm_end) { + if (mappable_base < ggtt->base.start || + mappable_end > ggtt->mappable_end || + unmappable_base < ggtt->mappable_end || + unmappable_end > ggtt_end) { DRM_ERROR("Invalid ballooning configuration!\n"); return -EINVAL; } /* Unmappable graphic memory ballooning */ - if (unmappable_base > dev_priv->ggtt.mappable_end) { - ret = vgt_balloon_space(&ggtt_vm->mm, + if (unmappable_base > ggtt->mappable_end) { + ret = vgt_balloon_space(&ggtt->base.mm, &bl_info.space[2], - dev_priv->ggtt.mappable_end, + ggtt->mappable_end, unmappable_base); if (ret) @@ -225,30 +225,30 @@ int intel_vgt_balloon(struct drm_device *dev) * No need to partition out the last physical page, * because it is reserved to the guard page. */ - if (unmappable_end < ggtt_vm_end - PAGE_SIZE) { - ret = vgt_balloon_space(&ggtt_vm->mm, + if (unmappable_end < ggtt_end - PAGE_SIZE) { + ret = vgt_balloon_space(&ggtt->base.mm, &bl_info.space[3], unmappable_end, - ggtt_vm_end - PAGE_SIZE); + ggtt_end - PAGE_SIZE); if (ret) goto err; } /* Mappable graphic memory ballooning */ - if (mappable_base > ggtt_vm->start) { - ret = vgt_balloon_space(&ggtt_vm->mm, + if (mappable_base > ggtt->base.start) { + ret = vgt_balloon_space(&ggtt->base.mm, &bl_info.space[0], - ggtt_vm->start, mappable_base); + ggtt->base.start, mappable_base); if (ret) goto err; } - if (mappable_end < dev_priv->ggtt.mappable_end) { - ret = vgt_balloon_space(&ggtt_vm->mm, + if (mappable_end < ggtt->mappable_end) { + ret = vgt_balloon_space(&ggtt->base.mm, &bl_info.space[1], mappable_end, - dev_priv->ggtt.mappable_end); + ggtt->mappable_end); if (ret) goto err; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 60bb486b4d6e..e6b5ee51739b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2444,6 +2444,7 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc, { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; struct drm_i915_gem_object *obj = NULL; struct drm_mode_fb_cmd2 mode_cmd = { 0 }; struct drm_framebuffer *fb = &plane_config->fb->base; @@ -2459,7 +2460,7 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc, /* If the FB is too big, just don't use it since fbdev is not very * important and we should probably use that space with FBC or other * features. */ - if (size_aligned * 2 > dev_priv->ggtt.stolen_usable_size) + if (size_aligned * 2 > ggtt->stolen_usable_size) return false; mutex_lock(&dev->struct_mutex); @@ -15282,7 +15283,8 @@ fail: void intel_modeset_init(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; int sprite, ret; enum pipe pipe; struct intel_crtc *crtc; @@ -15346,7 +15348,7 @@ void intel_modeset_init(struct drm_device *dev) dev->mode_config.cursor_height = MAX_CURSOR_HEIGHT; } - dev->mode_config.fb_base = dev_priv->ggtt.mappable_base; + dev->mode_config.fb_base = ggtt->mappable_base; DRM_DEBUG_KMS("%d display pipe%s available.\n", INTEL_INFO(dev)->num_pipes, diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 2e571f5f3b22..d5a7cfec589b 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -506,6 +506,7 @@ static int find_compression_threshold(struct drm_i915_private *dev_priv, int size, int fb_cpp) { + struct i915_ggtt *ggtt = &dev_priv->ggtt; int compression_threshold = 1; int ret; u64 end; @@ -516,9 +517,9 @@ static int find_compression_threshold(struct drm_i915_private *dev_priv, * underruns, even if that range is not reserved by the BIOS. */ if (IS_BROADWELL(dev_priv) || IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) - end = dev_priv->ggtt.stolen_size - 8 * 1024 * 1024; + end = ggtt->stolen_size - 8 * 1024 * 1024; else - end = dev_priv->ggtt.stolen_usable_size; + end = ggtt->stolen_usable_size; /* HACK: This code depends on what we will do in *_enable_fbc. If that * code changes, this code needs to change as well. diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index 153ea7a3fcf6..4cf04ceccfc2 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -122,6 +122,7 @@ static int intelfb_alloc(struct drm_fb_helper *helper, struct drm_framebuffer *fb; struct drm_device *dev = helper->dev; struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; struct drm_mode_fb_cmd2 mode_cmd = {}; struct drm_i915_gem_object *obj = NULL; int size, ret; @@ -146,7 +147,7 @@ static int intelfb_alloc(struct drm_fb_helper *helper, /* If the FB is too big, just don't use it since fbdev is not very * important and we should probably use that space with FBC or other * features. */ - if (size * 2 < dev_priv->ggtt.stolen_usable_size) + if (size * 2 < ggtt->stolen_usable_size) obj = i915_gem_object_create_stolen(dev, size); if (obj == NULL) obj = i915_gem_alloc_object(dev, size); @@ -181,7 +182,8 @@ static int intelfb_create(struct drm_fb_helper *helper, container_of(helper, struct intel_fbdev, helper); struct intel_framebuffer *intel_fb = ifbdev->fb; struct drm_device *dev = helper->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; struct fb_info *info; struct drm_framebuffer *fb; struct drm_i915_gem_object *obj; @@ -244,13 +246,13 @@ static int intelfb_create(struct drm_fb_helper *helper, /* setup aperture base/size for vesafb takeover */ info->apertures->ranges[0].base = dev->mode_config.fb_base; - info->apertures->ranges[0].size = dev_priv->ggtt.mappable_end; + info->apertures->ranges[0].size = ggtt->mappable_end; info->fix.smem_start = dev->mode_config.fb_base + i915_gem_obj_ggtt_offset(obj); info->fix.smem_len = size; info->screen_base = - ioremap_wc(dev_priv->ggtt.mappable_base + i915_gem_obj_ggtt_offset(obj), + ioremap_wc(ggtt->mappable_base + i915_gem_obj_ggtt_offset(obj), size); if (!info->screen_base) { DRM_ERROR("Failed to remap framebuffer into virtual memory\n"); diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index e1acb41f187a..6694e9230cd5 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -190,13 +190,14 @@ struct intel_overlay { static struct overlay_registers __iomem * intel_overlay_map_regs(struct intel_overlay *overlay) { - struct drm_i915_private *dev_priv = overlay->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(overlay->dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; struct overlay_registers __iomem *regs; if (OVERLAY_NEEDS_PHYSICAL(overlay->dev)) regs = (struct overlay_registers __iomem *)overlay->reg_bo->phys_handle->vaddr; else - regs = io_mapping_map_wc(dev_priv->ggtt.mappable, + regs = io_mapping_map_wc(ggtt->mappable, i915_gem_obj_ggtt_offset(overlay->reg_bo)); return regs; @@ -1481,7 +1482,8 @@ struct intel_overlay_error_state { static struct overlay_registers __iomem * intel_overlay_map_regs_atomic(struct intel_overlay *overlay) { - struct drm_i915_private *dev_priv = overlay->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(overlay->dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; struct overlay_registers __iomem *regs; if (OVERLAY_NEEDS_PHYSICAL(overlay->dev)) @@ -1490,7 +1492,7 @@ intel_overlay_map_regs_atomic(struct intel_overlay *overlay) regs = (struct overlay_registers __iomem *) overlay->reg_bo->phys_handle->vaddr; else - regs = io_mapping_map_atomic_wc(dev_priv->ggtt.mappable, + regs = io_mapping_map_atomic_wc(ggtt->mappable, i915_gem_obj_ggtt_offset(overlay->reg_bo)); return regs; diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 6a04761ddc0f..9bc9c25423e9 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4630,7 +4630,8 @@ static void intel_print_rc6_info(struct drm_device *dev, u32 mode) static bool bxt_check_bios_rc6_setup(const struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; bool enable_rc6 = true; unsigned long rc6_ctx_base; @@ -4644,9 +4645,9 @@ static bool bxt_check_bios_rc6_setup(const struct drm_device *dev) * for this check. */ rc6_ctx_base = I915_READ(RC6_CTX_BASE) & RC6_CTX_BASE_MASK; - if (!((rc6_ctx_base >= dev_priv->ggtt.stolen_reserved_base) && - (rc6_ctx_base + PAGE_SIZE <= dev_priv->ggtt.stolen_reserved_base + - dev_priv->ggtt.stolen_reserved_size))) { + if (!((rc6_ctx_base >= ggtt->stolen_reserved_base) && + (rc6_ctx_base + PAGE_SIZE <= ggtt->stolen_reserved_base + + ggtt->stolen_reserved_size))) { DRM_DEBUG_KMS("RC6 Base address not as expected.\n"); enable_rc6 = false; } @@ -5287,9 +5288,9 @@ static void cherryview_check_pctx(struct drm_i915_private *dev_priv) static void cherryview_setup_pctx(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; - unsigned long pctx_paddr, paddr; + struct drm_i915_private *dev_priv = to_i915(dev); struct i915_ggtt *ggtt = &dev_priv->ggtt; + unsigned long pctx_paddr, paddr; u32 pcbr; int pctx_size = 32*1024; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index a492bcabd30d..2e864b7a528b 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -2111,6 +2111,7 @@ int intel_pin_and_map_ringbuffer_obj(struct drm_device *dev, struct intel_ringbuffer *ringbuf) { struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_ggtt *ggtt = &dev_priv->ggtt; struct drm_i915_gem_object *obj = ringbuf->obj; int ret; @@ -2144,7 +2145,7 @@ int intel_pin_and_map_ringbuffer_obj(struct drm_device *dev, /* Access through the GTT requires the device to be awake. */ assert_rpm_wakelock_held(dev_priv); - ringbuf->virtual_start = ioremap_wc(dev_priv->ggtt.mappable_base + + ringbuf->virtual_start = ioremap_wc(ggtt->mappable_base + i915_gem_obj_ggtt_offset(obj), ringbuf->size); if (ringbuf->virtual_start == NULL) { i915_gem_object_ggtt_unpin(obj); -- cgit v1.2.3 From 564f5d6e92d16ad893b4b5bad520bba6a3008b09 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Thu, 31 Mar 2016 10:18:35 -0400 Subject: staging: lustre: libcfs: move add_wait_queue_exclusive_head to lustre layer Only lustre client uses add_wait_queue_exclusive_head() so move it from libcfs layer to lustre_lib.h where it is needed. Signed-off-by: James Simmons Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6245 Reviewed-on: http://review.whamcloud.com/13874 Reviewed-by: Dmitry Eremin Reviewed-by: John L. Hammond Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- .../lustre/include/linux/libcfs/libcfs_prim.h | 2 -- .../staging/lustre/lnet/libcfs/linux/linux-prim.c | 24 ---------------------- drivers/staging/lustre/lustre/include/lustre_lib.h | 22 ++++++++++++++++++++ 3 files changed, 22 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_prim.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_prim.h index 082fe6de90e4..d7846e86f925 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_prim.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_prim.h @@ -40,8 +40,6 @@ #ifndef __LIBCFS_PRIM_H__ #define __LIBCFS_PRIM_H__ -void add_wait_queue_exclusive_head(wait_queue_head_t *, wait_queue_t *); - /* * Memory */ diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-prim.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-prim.c index 7e5ef0a20f93..bbe19a684c81 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-prim.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-prim.c @@ -46,30 +46,6 @@ #include #endif -/** - * wait_queue_t of Linux (version < 2.6.34) is a FIFO list for exclusively - * waiting threads, which is not always desirable because all threads will - * be waken up again and again, even user only needs a few of them to be - * active most time. This is not good for performance because cache can - * be polluted by different threads. - * - * LIFO list can resolve this problem because we always wakeup the most - * recent active thread by default. - * - * NB: please don't call non-exclusive & exclusive wait on the same - * waitq if add_wait_queue_exclusive_head is used. - */ -void -add_wait_queue_exclusive_head(wait_queue_head_t *waitq, wait_queue_t *link) -{ - unsigned long flags; - - spin_lock_irqsave(&waitq->lock, flags); - __add_wait_queue_exclusive(waitq, link); - spin_unlock_irqrestore(&waitq->lock, flags); -} -EXPORT_SYMBOL(add_wait_queue_exclusive_head); - sigset_t cfs_block_allsigs(void) { diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h b/drivers/staging/lustre/lustre/include/lustre_lib.h index 2e66b271b6e9..00b976766aef 100644 --- a/drivers/staging/lustre/lustre/include/lustre_lib.h +++ b/drivers/staging/lustre/lustre/include/lustre_lib.h @@ -522,6 +522,28 @@ struct l_wait_info { sigmask(SIGTERM) | sigmask(SIGQUIT) | \ sigmask(SIGALRM)) +/** + * wait_queue_t of Linux (version < 2.6.34) is a FIFO list for exclusively + * waiting threads, which is not always desirable because all threads will + * be waken up again and again, even user only needs a few of them to be + * active most time. This is not good for performance because cache can + * be polluted by different threads. + * + * LIFO list can resolve this problem because we always wakeup the most + * recent active thread by default. + * + * NB: please don't call non-exclusive & exclusive wait on the same + * waitq if add_wait_queue_exclusive_head is used. + */ +#define add_wait_queue_exclusive_head(waitq, link) \ +{ \ + unsigned long flags; \ + \ + spin_lock_irqsave(&((waitq)->lock), flags); \ + __add_wait_queue_exclusive(waitq, link); \ + spin_unlock_irqrestore(&((waitq)->lock), flags); \ +} + /* * wait for @condition to become true, but no longer than timeout, specified * by @info. -- cgit v1.2.3 From bd6e2c5067ad6ead097ada26e899ba97266a8bf0 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Thu, 31 Mar 2016 10:18:36 -0400 Subject: staging: lustre: libcfs: move memory_pressure functions to libcfs_prim.h Long ago libcfs_prim.h was used for userland code which is why memory_pressure_*() handling is in both libcfs_prim.h and linux-mem.h headers. So lets just move the memory_pressure_*() to libcfs_prim.h. Signed-off-by: James Simmons Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6245 Reviewed-on: http://review.whamcloud.com/13841 Reviewed-by: frank zago Reviewed-by: Dmitry Eremin Reviewed-by: John L. Hammond Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- .../lustre/include/linux/libcfs/libcfs_prim.h | 23 +++++++++++++--------- .../lustre/include/linux/libcfs/linux/linux-mem.h | 4 ---- 2 files changed, 14 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_prim.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_prim.h index d7846e86f925..d97060b8be74 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_prim.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_prim.h @@ -43,15 +43,20 @@ /* * Memory */ -#ifndef memory_pressure_get -#define memory_pressure_get() (0) -#endif -#ifndef memory_pressure_set -#define memory_pressure_set() do {} while (0) -#endif -#ifndef memory_pressure_clr -#define memory_pressure_clr() do {} while (0) -#endif +static inline unsigned int memory_pressure_get(void) +{ + return current->flags & PF_MEMALLOC; +} + +static inline void memory_pressure_set(void) +{ + current->flags |= PF_MEMALLOC; +} + +static inline void memory_pressure_clr(void) +{ + current->flags &= ~PF_MEMALLOC; +} static inline int cfs_memory_pressure_get_and_set(void) { diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h b/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h index 448379b2a01e..c50ef8352b10 100644 --- a/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h +++ b/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h @@ -59,10 +59,6 @@ #define page_index(p) ((p)->index) -#define memory_pressure_get() (current->flags & PF_MEMALLOC) -#define memory_pressure_set() do { current->flags |= PF_MEMALLOC; } while (0) -#define memory_pressure_clr() do { current->flags &= ~PF_MEMALLOC; } while (0) - #if BITS_PER_LONG == 32 /* limit to lowmem on 32-bit systems */ #define NUM_CACHEPAGES \ -- cgit v1.2.3 From badc9feddfd30096666e22afbda028971a49bfa9 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Thu, 31 Mar 2016 10:18:37 -0400 Subject: staging: lustre: libcfs: remove page_index() macro Just use the index field directly for struct page. Signed-off-by: James Simmons Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6245 Reviewed-on: http://review.whamcloud.com/13841 Reviewed-by: frank zago Reviewed-by: Dmitry Eremin Reviewed-by: John L. Hammond Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h | 2 -- drivers/staging/lustre/lustre/llite/vvp_page.c | 2 +- drivers/staging/lustre/lustre/osc/osc_request.c | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h b/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h index c50ef8352b10..12fde3ca5b7b 100644 --- a/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h +++ b/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h @@ -57,8 +57,6 @@ #include "../libcfs_cpu.h" #endif -#define page_index(p) ((p)->index) - #if BITS_PER_LONG == 32 /* limit to lowmem on 32-bit systems */ #define NUM_CACHEPAGES \ diff --git a/drivers/staging/lustre/lustre/llite/vvp_page.c b/drivers/staging/lustre/lustre/llite/vvp_page.c index 69316c191de6..0c92293dbf2e 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_page.c +++ b/drivers/staging/lustre/lustre/llite/vvp_page.c @@ -394,7 +394,7 @@ static int vvp_page_print(const struct lu_env *env, (*printer)(env, cookie, "%lx %d:%d %lx %lu %slru", (long)vmpage->flags, page_count(vmpage), page_mapcount(vmpage), vmpage->private, - page_index(vmpage), + vmpage->index, list_empty(&vmpage->lru) ? "not-" : ""); } diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c index 4d3eed6ee3f7..547539c74a7b 100644 --- a/drivers/staging/lustre/lustre/osc/osc_request.c +++ b/drivers/staging/lustre/lustre/osc/osc_request.c @@ -1934,7 +1934,7 @@ int osc_build_rpc(const struct lu_env *env, struct client_obd *cli, pga[i] = &oap->oap_brw_page; pga[i]->off = oap->oap_obj_off + oap->oap_page_off; CDEBUG(0, "put page %p index %lu oap %p flg %x to pga\n", - pga[i]->pg, page_index(oap->oap_page), oap, + pga[i]->pg, oap->oap_page->index, oap, pga[i]->flag); i++; cl_req_page_add(env, clerq, page); -- cgit v1.2.3 From e3e30e10c5d72844f020fe42e62066e9fd1b051c Mon Sep 17 00:00:00 2001 From: James Simmons Date: Thu, 31 Mar 2016 10:18:38 -0400 Subject: staging: lustre: libcfs: remove MMSPACE macros Another abstraction that is not needed. Signed-off-by: James Simmons Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6245 Reviewed-on: http://review.whamcloud.com/13841 Reviewed-by: frank zago Reviewed-by: Dmitry Eremin Reviewed-by: John L. Hammond Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- .../lustre/include/linux/libcfs/linux/linux-mem.h | 5 ----- drivers/staging/lustre/lnet/libcfs/tracefile.c | 17 ++++++++--------- 2 files changed, 8 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h b/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h index 12fde3ca5b7b..c4b428478c73 100644 --- a/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h +++ b/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h @@ -65,9 +65,4 @@ #define NUM_CACHEPAGES totalram_pages #endif -#define DECL_MMSPACE mm_segment_t __oldfs -#define MMSPACE_OPEN \ - do { __oldfs = get_fs(); set_fs(get_ds()); } while (0) -#define MMSPACE_CLOSE set_fs(__oldfs) - #endif /* __LINUX_CFS_MEM_H__ */ diff --git a/drivers/staging/lustre/lnet/libcfs/tracefile.c b/drivers/staging/lustre/lnet/libcfs/tracefile.c index ec3bc04bd89f..5169597e2c34 100644 --- a/drivers/staging/lustre/lnet/libcfs/tracefile.c +++ b/drivers/staging/lustre/lnet/libcfs/tracefile.c @@ -707,10 +707,9 @@ int cfs_tracefile_dump_all_pages(char *filename) struct cfs_trace_page *tage; struct cfs_trace_page *tmp; char *buf; + mm_segment_t __oldfs; int rc; - DECL_MMSPACE; - cfs_tracefile_write_lock(); filp = filp_open(filename, O_CREAT | O_EXCL | O_WRONLY | O_LARGEFILE, @@ -729,11 +728,12 @@ int cfs_tracefile_dump_all_pages(char *filename) rc = 0; goto close; } + __oldfs = get_fs(); + set_fs(get_ds()); /* ok, for now, just write the pages. in the future we'll be building * iobufs with the pages and calling generic_direct_IO */ - MMSPACE_OPEN; list_for_each_entry_safe(tage, tmp, &pc.pc_pages, linkage) { __LASSERT_TAGE_INVARIANT(tage); @@ -752,7 +752,7 @@ int cfs_tracefile_dump_all_pages(char *filename) list_del(&tage->linkage); cfs_tage_free(tage); } - MMSPACE_CLOSE; + set_fs(__oldfs); rc = vfs_fsync(filp, 1); if (rc) pr_err("sync returns %d\n", rc); @@ -986,13 +986,12 @@ static int tracefiled(void *arg) struct tracefiled_ctl *tctl = arg; struct cfs_trace_page *tage; struct cfs_trace_page *tmp; + mm_segment_t __oldfs; struct file *filp; char *buf; int last_loop = 0; int rc; - DECL_MMSPACE; - /* we're started late enough that we pick up init's fs context */ /* this is so broken in uml? what on earth is going on? */ @@ -1025,8 +1024,8 @@ static int tracefiled(void *arg) __LASSERT(list_empty(&pc.pc_pages)); goto end_loop; } - - MMSPACE_OPEN; + __oldfs = get_fs(); + set_fs(get_ds()); list_for_each_entry_safe(tage, tmp, &pc.pc_pages, linkage) { static loff_t f_pos; @@ -1051,7 +1050,7 @@ static int tracefiled(void *arg) break; } } - MMSPACE_CLOSE; + set_fs(__oldfs); filp_close(filp, NULL); put_pages_on_daemon_list(&pc); -- cgit v1.2.3 From 5c89dc06eb45bebe4dcc59205ac0ed3fe3c44c34 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Thu, 31 Mar 2016 10:18:39 -0400 Subject: staging: lustre: libcfs: move NUM_CACHEPAGES to libcfs_prim.h We don't really need linux specific headers anymore so move NUM_CACHEPAGES macro to libcfs_prim.h. Signed-off-by: James Simmons Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6245 Reviewed-on: http://review.whamcloud.com/13841 Reviewed-by: frank zago Reviewed-by: Dmitry Eremin Reviewed-by: John L. Hammond Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/include/linux/libcfs/libcfs_prim.h | 8 ++++++++ drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h | 8 -------- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_prim.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_prim.h index d97060b8be74..6f7a276b87b7 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_prim.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_prim.h @@ -43,6 +43,14 @@ /* * Memory */ +#if BITS_PER_LONG == 32 +/* limit to lowmem on 32-bit systems */ +#define NUM_CACHEPAGES \ + min(totalram_pages, 1UL << (30 - PAGE_CACHE_SHIFT) * 3 / 4) +#else +#define NUM_CACHEPAGES totalram_pages +#endif + static inline unsigned int memory_pressure_get(void) { return current->flags & PF_MEMALLOC; diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h b/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h index c4b428478c73..9285fefcdf79 100644 --- a/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h +++ b/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h @@ -57,12 +57,4 @@ #include "../libcfs_cpu.h" #endif -#if BITS_PER_LONG == 32 -/* limit to lowmem on 32-bit systems */ -#define NUM_CACHEPAGES \ - min(totalram_pages, 1UL << (30 - PAGE_CACHE_SHIFT) * 3 / 4) -#else -#define NUM_CACHEPAGES totalram_pages -#endif - #endif /* __LINUX_CFS_MEM_H__ */ -- cgit v1.2.3 From 899e1a31ffc0cf01b1ca7512e079721b79803929 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Thu, 31 Mar 2016 10:18:40 -0400 Subject: staging: lustre: libcfs: delete linux-mem.h The header linux-mem.h is no longer needed. Signed-off-by: James Simmons Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6245 Reviewed-on: http://review.whamcloud.com/13841 Reviewed-by: frank zago Reviewed-by: Dmitry Eremin Reviewed-by: John L. Hammond Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- .../lustre/include/linux/libcfs/linux/libcfs.h | 2 +- .../lustre/include/linux/libcfs/linux/linux-cpu.h | 2 +- .../lustre/include/linux/libcfs/linux/linux-mem.h | 60 ---------------------- 3 files changed, 2 insertions(+), 62 deletions(-) delete mode 100644 drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h (limited to 'drivers') diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/libcfs.h b/drivers/staging/lustre/include/linux/libcfs/linux/libcfs.h index d94b2661658a..a268ef7aa19d 100644 --- a/drivers/staging/lustre/include/linux/libcfs/linux/libcfs.h +++ b/drivers/staging/lustre/include/linux/libcfs/linux/libcfs.h @@ -60,6 +60,7 @@ #include #include #include +#include #include #include #include @@ -83,7 +84,6 @@ #include #include "linux-cpu.h" #include "linux-time.h" -#include "linux-mem.h" #define LUSTRE_TRACE_SIZE (THREAD_SIZE >> 5) diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/linux-cpu.h b/drivers/staging/lustre/include/linux/libcfs/linux/linux-cpu.h index c04979ae0a38..f63cb47bc309 100644 --- a/drivers/staging/lustre/include/linux/libcfs/linux/linux-cpu.h +++ b/drivers/staging/lustre/include/linux/libcfs/linux/linux-cpu.h @@ -23,7 +23,7 @@ * This file is part of Lustre, http://www.lustre.org/ * Lustre is a trademark of Sun Microsystems, Inc. * - * libcfs/include/libcfs/linux/linux-mem.h + * libcfs/include/libcfs/linux/linux-cpu.h * * Basic library routines. * diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h b/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h deleted file mode 100644 index 9285fefcdf79..000000000000 --- a/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * GPL HEADER END - */ -/* - * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. - * Use is subject to license terms. - * - * Copyright (c) 2011, 2012, Intel Corporation. - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - * - * libcfs/include/libcfs/linux/linux-mem.h - * - * Basic library routines. - */ - -#ifndef __LIBCFS_LINUX_CFS_MEM_H__ -#define __LIBCFS_LINUX_CFS_MEM_H__ - -#ifndef __LIBCFS_LIBCFS_H__ -#error Do not #include this file directly. #include instead -#endif - -#include -#include -#include -#include -#include -#include - -#ifndef HAVE_LIBCFS_CPT -/* Need this for cfs_cpt_table */ -#include "../libcfs_cpu.h" -#endif - -#endif /* __LINUX_CFS_MEM_H__ */ -- cgit v1.2.3 From 1f2f03c201d4df0035268f8cbecb31bf58f59355 Mon Sep 17 00:00:00 2001 From: Tim Sell Date: Wed, 30 Mar 2016 23:06:08 -0400 Subject: staging: unisys: visorbus: remove unnecessary poll_count logic The use of poll_count is a vestige from long-ago testing, which is no longer needed. It is removed by this patch. Signed-off-by: Tim Sell Signed-off-by: David Kershner Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorbus/visorchipset.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/unisys/visorbus/visorchipset.c b/drivers/staging/unisys/visorbus/visorchipset.c index 17bedbc6761d..61877722b1da 100644 --- a/drivers/staging/unisys/visorbus/visorchipset.c +++ b/drivers/staging/unisys/visorbus/visorchipset.c @@ -1868,18 +1868,11 @@ controlvm_periodic_work(struct work_struct *work) struct controlvm_message inmsg; bool got_command = false; bool handle_command_failed = false; - static u64 poll_count; /* make sure visorbus server is registered for controlvm callbacks */ if (visorchipset_visorbusregwait && !visorbusregistered) goto cleanup; - poll_count++; - if (poll_count >= 250) - ; /* keep going */ - else - goto cleanup; - /* Check events to determine if response to CHIPSET_READY * should be sent */ -- cgit v1.2.3 From e491e716dc6a8f43cec7353e5a89e19058f3a48a Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Thu, 31 Mar 2016 17:03:35 +0900 Subject: staging: dgnc: remove useless variables for saving tty's It doesn't need to save major number with variable. And there are no use of these variables(dgnc_serial_major and dgnc_transparent_print_major) Signed-off-by: Daeseok Youn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_driver.h | 3 --- drivers/staging/dgnc/dgnc_tty.c | 4 ---- 2 files changed, 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dgnc/dgnc_driver.h b/drivers/staging/dgnc/dgnc_driver.h index 44216aede109..6609ba5f3e7f 100644 --- a/drivers/staging/dgnc/dgnc_driver.h +++ b/drivers/staging/dgnc/dgnc_driver.h @@ -210,9 +210,6 @@ struct dgnc_board { bool dgnc_major_serial_registered; bool dgnc_major_transparent_print_registered; - uint dgnc_serial_major; - uint dgnc_transparent_print_major; - u16 dpatype; /* The board "type", * as defined by DPA */ diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index 98b88d1a5f04..5097208e6a4d 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -286,8 +286,6 @@ int dgnc_tty_register(struct dgnc_board *brd) } dgnc_BoardsByMajor[brd->serial_driver.major] = brd; - brd->dgnc_serial_major = brd->serial_driver.major; - brd->dgnc_transparent_print_major = brd->print_driver.major; return rc; } @@ -409,7 +407,6 @@ void dgnc_tty_uninit(struct dgnc_board *brd) if (brd->dgnc_major_serial_registered) { dgnc_BoardsByMajor[brd->serial_driver.major] = NULL; - brd->dgnc_serial_major = 0; for (i = 0; i < brd->nasync; i++) { if (brd->channels[i]) dgnc_remove_tty_sysfs(brd->channels[i]-> @@ -422,7 +419,6 @@ void dgnc_tty_uninit(struct dgnc_board *brd) if (brd->dgnc_major_transparent_print_registered) { dgnc_BoardsByMajor[brd->print_driver.major] = NULL; - brd->dgnc_transparent_print_major = 0; for (i = 0; i < brd->nasync; i++) { if (brd->channels[i]) dgnc_remove_tty_sysfs(brd->channels[i]-> -- cgit v1.2.3 From 56d118c243fbc62d95a79183bb6bcfc38a398da5 Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Thu, 31 Mar 2016 17:03:59 +0900 Subject: staging: dgnc: clean up dgnc_input function This is for fixing checkpatch.pl warning about "Alignment should match open parenthesis" but if that is fixed, code line is over 80 characters. I think "ch->ch_rqueue + tail + i" could be declared once in the begining of loop. Signed-off-by: Daeseok Youn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_tty.c | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index 5097208e6a4d..d617fca682dc 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -602,6 +602,8 @@ void dgnc_input(struct channel_t *ch) * or the amount of data the card actually has pending... */ while (n) { + unsigned char *ch_pos = ch->ch_equeue + tail; + s = ((head >= tail) ? head : RQUEUESIZE) - tail; s = min(s, n); @@ -616,29 +618,20 @@ void dgnc_input(struct channel_t *ch) */ if (I_PARMRK(tp) || I_BRKINT(tp) || I_INPCK(tp)) { for (i = 0; i < s; i++) { - if (*(ch->ch_equeue + tail + i) & UART_LSR_BI) - tty_insert_flip_char(tp->port, - *(ch->ch_rqueue + tail + i), - TTY_BREAK); - else if (*(ch->ch_equeue + tail + i) & - UART_LSR_PE) - tty_insert_flip_char(tp->port, - *(ch->ch_rqueue + tail + i), - TTY_PARITY); - else if (*(ch->ch_equeue + tail + i) & - UART_LSR_FE) - tty_insert_flip_char(tp->port, - *(ch->ch_rqueue + tail + i), - TTY_FRAME); - else - tty_insert_flip_char(tp->port, - *(ch->ch_rqueue + tail + i), - TTY_NORMAL); + unsigned char ch = *(ch_pos + i); + char flag = TTY_NORMAL; + + if (ch & UART_LSR_BI) + flag = TTY_BREAK; + else if (ch & UART_LSR_PE) + flag = TTY_PARITY; + else if (ch & UART_LSR_FE) + flag = TTY_FRAME; + + tty_insert_flip_char(tp->port, ch, flag); } } else { - tty_insert_flip_string(tp->port, - ch->ch_rqueue + tail, - s); + tty_insert_flip_string(tp->port, ch_pos, s); } tail += s; -- cgit v1.2.3 From 423de92f56bdfc3e68503af31e6ec041d59a6a25 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Thu, 24 Mar 2016 10:38:04 +0200 Subject: mei: bus: use scnprintf in *_show There's no reason to duplicate the logic provided by scnprintf(). Signed-off-by: Rasmus Villemoes Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/bus.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 5d5996e39a67..04dc05150898 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -634,11 +634,8 @@ static ssize_t name_show(struct device *dev, struct device_attribute *a, char *buf) { struct mei_cl_device *cldev = to_mei_cl_device(dev); - size_t len; - len = snprintf(buf, PAGE_SIZE, "%s", cldev->name); - - return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; + return scnprintf(buf, PAGE_SIZE, "%s", cldev->name); } static DEVICE_ATTR_RO(name); @@ -647,11 +644,8 @@ static ssize_t uuid_show(struct device *dev, struct device_attribute *a, { struct mei_cl_device *cldev = to_mei_cl_device(dev); const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl); - size_t len; - - len = snprintf(buf, PAGE_SIZE, "%pUl", uuid); - return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; + return scnprintf(buf, PAGE_SIZE, "%pUl", uuid); } static DEVICE_ATTR_RO(uuid); @@ -660,11 +654,8 @@ static ssize_t version_show(struct device *dev, struct device_attribute *a, { struct mei_cl_device *cldev = to_mei_cl_device(dev); u8 version = mei_me_cl_ver(cldev->me_cl); - size_t len; - - len = snprintf(buf, PAGE_SIZE, "%02X", version); - return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; + return scnprintf(buf, PAGE_SIZE, "%02X", version); } static DEVICE_ATTR_RO(version); @@ -673,10 +664,8 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *a, { struct mei_cl_device *cldev = to_mei_cl_device(dev); const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl); - size_t len; - len = snprintf(buf, PAGE_SIZE, "mei:%s:%pUl:", cldev->name, uuid); - return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; + return scnprintf(buf, PAGE_SIZE, "mei:%s:%pUl:", cldev->name, uuid); } static DEVICE_ATTR_RO(modalias); -- cgit v1.2.3 From 0b27c02a7f1c697694f2ad6d6517e7dbf9ecfa39 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 18 Mar 2016 12:34:59 -0700 Subject: drm: Add an encoder and connector type enum for DPI. Right now exynos is exposing DPI as a TMDS encoder and VGA connector, which seems rather misleading. This isn't just an internal detail, since xrandr actually exposes "VGA" as the output name. Define some new enums so that vc4's DPI can have a more informative name. I considered other names for the connector as well. For VC4, the Adafruit DPI kippah takes the 28 GPIO pins and routes them to a standard-ish 40-pin FPC connector, but "40-pin FPC" doesn't uniquely identify an ordering of pins (apparently some other orderings exist), doesn't explain things as well for the user (who, if anything, knows their product is a DPI kippah/panel combo), and actually doesn't have to exist (one could connect the 28 GPIOs directly to something else). Simply "DPI" seems like a good compromise name to distinguish from the HDMI, DSI, and TV connectors . Signed-off-by: Eric Anholt Reviewed-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc.c | 2 ++ include/uapi/drm/drm_mode.h | 2 ++ 2 files changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index e08f962288d9..6bd8133de3b7 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -168,6 +168,7 @@ static struct drm_conn_prop_enum_list drm_connector_enum_list[] = { { DRM_MODE_CONNECTOR_eDP, "eDP" }, { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" }, { DRM_MODE_CONNECTOR_DSI, "DSI" }, + { DRM_MODE_CONNECTOR_DPI, "DPI" }, }; static const struct drm_prop_enum_list drm_encoder_enum_list[] = { @@ -179,6 +180,7 @@ static const struct drm_prop_enum_list drm_encoder_enum_list[] = { { DRM_MODE_ENCODER_VIRTUAL, "Virtual" }, { DRM_MODE_ENCODER_DSI, "DSI" }, { DRM_MODE_ENCODER_DPMST, "DP MST" }, + { DRM_MODE_ENCODER_DPI, "DPI" }, }; static const struct drm_prop_enum_list drm_subpixel_enum_list[] = { diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index c0217434d28d..c10ab61bbc44 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -202,6 +202,7 @@ struct drm_mode_get_plane_res { #define DRM_MODE_ENCODER_VIRTUAL 5 #define DRM_MODE_ENCODER_DSI 6 #define DRM_MODE_ENCODER_DPMST 7 +#define DRM_MODE_ENCODER_DPI 8 struct drm_mode_get_encoder { __u32 encoder_id; @@ -241,6 +242,7 @@ struct drm_mode_get_encoder { #define DRM_MODE_CONNECTOR_eDP 14 #define DRM_MODE_CONNECTOR_VIRTUAL 15 #define DRM_MODE_CONNECTOR_DSI 16 +#define DRM_MODE_CONNECTOR_DPI 17 struct drm_mode_get_connector { -- cgit v1.2.3 From f21a21983ef13a031250c4c3f6018e29a549d0f1 Mon Sep 17 00:00:00 2001 From: Shubhangi Shrivastava Date: Wed, 30 Mar 2016 18:05:22 +0530 Subject: drm/i915: Splitting intel_dp_detect intel_dp_detect() is called for not just detection but during modes enumeration as well. Repeating the whole sequence during each of these calls is wasteful and time consuming. This patch moves probing for panel, DPCD read etc done in intel_dp_detect() to a new function intel_dp_long_pulse(). Note that the behavior of intel_dp_detect() is changed to report connected or disconnected depending on whether the EDID is available or not. This change will be required by further patches in the series to avoid performing duplicated DPCD operations on hotplug. v2: Moved a hunk to next patch of the series. Moved intel_dp_unset_edid to out. (Ander) v3: Rephrased commit message and intel_dp_unset_dp() is called within intel_dp_set_dp() to free the previous EDID. (Ander) v4: Added overriding of status to disconnected for MST. (Ander) Tested-by: Nathan D Ciobanu Signed-off-by: Sivakumar Thulasimani Signed-off-by: Shubhangi Shrivastava Reviewed-by: Ander Conselvan de Oliveira [anderco: fix parenthesis alignment] Signed-off-by: Ander Conselvan de Oliveira Link: http://patchwork.freedesktop.org/patch/msgid/1459341326-13142-1-git-send-email-shubhangi.shrivastava@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 63 ++++++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 3bdd8ba59b8c..81f10ab5890b 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -129,6 +129,7 @@ static void edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync); static void vlv_init_panel_power_sequencer(struct intel_dp *intel_dp); static void vlv_steal_power_sequencer(struct drm_device *dev, enum pipe pipe); +static void intel_dp_unset_edid(struct intel_dp *intel_dp); static unsigned int intel_dp_unused_lane_mask(int lane_count) { @@ -4513,6 +4514,7 @@ intel_dp_set_edid(struct intel_dp *intel_dp) struct intel_connector *intel_connector = intel_dp->attached_connector; struct edid *edid; + intel_dp_unset_edid(intel_dp); edid = intel_dp_get_edid(intel_dp); intel_connector->detect_edid = edid; @@ -4533,9 +4535,10 @@ intel_dp_unset_edid(struct intel_dp *intel_dp) intel_dp->has_audio = false; } -static enum drm_connector_status -intel_dp_detect(struct drm_connector *connector, bool force) +static void +intel_dp_long_pulse(struct intel_connector *intel_connector) { + struct drm_connector *connector = &intel_connector->base; struct intel_dp *intel_dp = intel_attached_dp(connector); struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct intel_encoder *intel_encoder = &intel_dig_port->base; @@ -4545,17 +4548,6 @@ intel_dp_detect(struct drm_connector *connector, bool force) bool ret; u8 sink_irq_vector; - DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", - connector->base.id, connector->name); - intel_dp_unset_edid(intel_dp); - - if (intel_dp->is_mst) { - /* MST devices are disconnected from a monitor POV */ - if (intel_encoder->type != INTEL_OUTPUT_EDP) - intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT; - return connector_status_disconnected; - } - power_domain = intel_display_port_aux_power_domain(intel_encoder); intel_display_power_get(to_i915(dev), power_domain); @@ -4576,14 +4568,18 @@ intel_dp_detect(struct drm_connector *connector, bool force) goto out; } + if (intel_encoder->type != INTEL_OUTPUT_EDP) + intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT; + intel_dp_probe_oui(intel_dp); ret = intel_dp_probe_mst(intel_dp); if (ret) { - /* if we are in MST mode then this connector - won't appear connected or have anything with EDID on it */ - if (intel_encoder->type != INTEL_OUTPUT_EDP) - intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT; + /* + * If we are in MST mode then this connector + * won't appear connected or have anything + * with EDID on it + */ status = connector_status_disconnected; goto out; } @@ -4598,8 +4594,6 @@ intel_dp_detect(struct drm_connector *connector, bool force) intel_dp_set_edid(intel_dp); - if (intel_encoder->type != INTEL_OUTPUT_EDP) - intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT; status = connector_status_connected; /* Try to read the source of the interrupt */ @@ -4617,8 +4611,37 @@ intel_dp_detect(struct drm_connector *connector, bool force) } out: + if (status != connector_status_connected) + intel_dp_unset_edid(intel_dp); intel_display_power_put(to_i915(dev), power_domain); - return status; + return; +} + +static enum drm_connector_status +intel_dp_detect(struct drm_connector *connector, bool force) +{ + struct intel_dp *intel_dp = intel_attached_dp(connector); + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); + struct intel_encoder *intel_encoder = &intel_dig_port->base; + struct intel_connector *intel_connector = to_intel_connector(connector); + + DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", + connector->base.id, connector->name); + + if (intel_dp->is_mst) { + /* MST devices are disconnected from a monitor POV */ + intel_dp_unset_edid(intel_dp); + if (intel_encoder->type != INTEL_OUTPUT_EDP) + intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT; + return connector_status_disconnected; + } + + intel_dp_long_pulse(intel_dp->attached_connector); + + if (intel_connector->detect_edid) + return connector_status_connected; + else + return connector_status_disconnected; } static void -- cgit v1.2.3 From 7d23e3c37bb3fc6952dc84007ee60cb533fd2d5c Mon Sep 17 00:00:00 2001 From: Shubhangi Shrivastava Date: Wed, 30 Mar 2016 18:05:23 +0530 Subject: drm/i915: Cleaning up intel_dp_hpd_pulse Current DP detection has DPCD operations split across intel_dp_hpd_pulse and intel_dp_detect which contains duplicates as well. Also intel_dp_detect is called during modes enumeration as well which will result in multiple dpcd operations. So this patch tries to solve both these by bringing all DPCD operations in one single function and make intel_dp_detect use existing values instead of repeating same steps. v2: Pulled in a hunk from last patch of the series to this patch. (Ander) v3: Added MST hotplug handling. (Ander) v4: Added a flag to check if detect is performed to prevent multiple detects on hotplug. (Ander) Tested-by: Nathan D Ciobanu Signed-off-by: Sivakumar Thulasimani Signed-off-by: Shubhangi Shrivastava Reviewed-by: Ander Conselvan de Oliveira [anderco: fix parenthesis aligment] Signed-off-by: Ander Conselvan de Oliveira Link: http://patchwork.freedesktop.org/patch/msgid/1459341326-13142-2-git-send-email-shubhangi.shrivastava@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 72 +++++++++++++++++++++++++--------------- drivers/gpu/drm/i915/intel_drv.h | 1 + 2 files changed, 47 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 81f10ab5890b..01b9f181727c 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4582,6 +4582,16 @@ intel_dp_long_pulse(struct intel_connector *intel_connector) */ status = connector_status_disconnected; goto out; + } else if (connector->status == connector_status_connected) { + /* + * If display was connected already and is still connected + * check links status, there has been known issues of + * link loss triggerring long pulse!!!! + */ + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); + intel_dp_check_link_status(intel_dp); + drm_modeset_unlock(&dev->mode_config.connection_mutex); + goto out; } /* @@ -4595,6 +4605,7 @@ intel_dp_long_pulse(struct intel_connector *intel_connector) intel_dp_set_edid(intel_dp); status = connector_status_connected; + intel_dp->detect_done = true; /* Try to read the source of the interrupt */ if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 && @@ -4611,8 +4622,21 @@ intel_dp_long_pulse(struct intel_connector *intel_connector) } out: - if (status != connector_status_connected) + if (status != connector_status_connected) { intel_dp_unset_edid(intel_dp); + /* + * If we were in MST mode, and device is not there, + * get out of MST mode + */ + if (intel_dp->is_mst) { + DRM_DEBUG_KMS("MST device may have disappeared %d vs %d\n", + intel_dp->is_mst, intel_dp->mst_mgr.mst_state); + intel_dp->is_mst = false; + drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, + intel_dp->is_mst); + } + } + intel_display_power_put(to_i915(dev), power_domain); return; } @@ -4636,7 +4660,11 @@ intel_dp_detect(struct drm_connector *connector, bool force) return connector_status_disconnected; } - intel_dp_long_pulse(intel_dp->attached_connector); + /* If full detect is not performed yet, do a full detect */ + if (!intel_dp->detect_done) + intel_dp_long_pulse(intel_dp->attached_connector); + + intel_dp->detect_done = false; if (intel_connector->detect_edid) return connector_status_connected; @@ -4968,25 +4996,25 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) /* indicate that we need to restart link training */ intel_dp->train_set_valid = false; - if (!intel_digital_port_connected(dev_priv, intel_dig_port)) - goto mst_fail; - - if (!intel_dp_get_dpcd(intel_dp)) { - goto mst_fail; - } - - intel_dp_probe_oui(intel_dp); + intel_dp_long_pulse(intel_dp->attached_connector); + if (intel_dp->is_mst) + ret = IRQ_HANDLED; + goto put_power; - if (!intel_dp_probe_mst(intel_dp)) { - drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); - intel_dp_check_link_status(intel_dp); - drm_modeset_unlock(&dev->mode_config.connection_mutex); - goto mst_fail; - } } else { if (intel_dp->is_mst) { - if (intel_dp_check_mst_status(intel_dp) == -EINVAL) - goto mst_fail; + if (intel_dp_check_mst_status(intel_dp) == -EINVAL) { + /* + * If we were in MST mode, and device is not + * there, get out of MST mode + */ + DRM_DEBUG_KMS("MST device may have disappeared %d vs %d\n", + intel_dp->is_mst, intel_dp->mst_mgr.mst_state); + intel_dp->is_mst = false; + drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, + intel_dp->is_mst); + goto put_power; + } } if (!intel_dp->is_mst) { @@ -4998,14 +5026,6 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) ret = IRQ_HANDLED; - goto put_power; -mst_fail: - /* if we were in MST mode, and device is not there get out of MST mode */ - if (intel_dp->is_mst) { - DRM_DEBUG_KMS("MST device may have disappeared %d vs %d\n", intel_dp->is_mst, intel_dp->mst_mgr.mst_state); - intel_dp->is_mst = false; - drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, intel_dp->is_mst); - } put_power: intel_display_power_put(dev_priv, power_domain); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 6ac46d921cde..ed65a7145158 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -797,6 +797,7 @@ struct intel_dp { int link_rate; uint8_t lane_count; bool has_audio; + bool detect_done; enum hdmi_force_audio force_audio; bool limited_color_range; bool color_range_auto; -- cgit v1.2.3 From 5c9114d0ced2f16d1bfeda650b4acf95159f4759 Mon Sep 17 00:00:00 2001 From: Shubhangi Shrivastava Date: Wed, 30 Mar 2016 18:05:24 +0530 Subject: drm/i915: Reorganizing intel_dp_check_link_status When created originally intel_dp_check_link_status() was supposed to handle only link training for short pulse but has grown into handler for short pulse itself. This patch cleans up this function by splitting it into two halves. First intel_dp_short_pulse() is called, which will be entry point and handle all logic for short pulse handling while intel_dp_check_link_status() will retain its original purpose of only doing link status related work. intel_dp_short_pulse: All existing code other than link status read and link training upon error status. intel_dp_check_link_status: The link status should be read on short pulse irrespective of panel being enabled or not so intel_dp_get_link_status() performs dpcd read first then based on crtc active / enabled it will perform the link training. This is because short pulse is a generic interrupt which should always be handled, because it may mean: 1. Hotplug/unplug of MST panel 2. Hotplug/unplug of dongle 3. Link status change for other DP panels v2: Added WARN_ON to intel_dp_check_link_status() Removed a call to intel_dp_get_link_status() (Ander) v3: Changed commit message to explain need of link status being read before performing encoder checks (Daniel) v4: Changed commit message to explain need of reading link status on short pulse (Ander) Tested-by: Nathan D Ciobanu Signed-off-by: Sivakumar Thulasimani Signed-off-by: Shubhangi Shrivastava Reviewed-by: Ander Conselvan de Oliveira [anderco: fix parenthesis alignment] Signed-off-by: Ander Conselvan de Oliveira Link: http://patchwork.freedesktop.org/patch/msgid/1459341326-13142-3-git-send-email-shubhangi.shrivastava@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 65 +++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 01b9f181727c..9ee7a739a67f 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4215,6 +4215,36 @@ go_again: return -EINVAL; } +static void +intel_dp_check_link_status(struct intel_dp *intel_dp) +{ + struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base; + struct drm_device *dev = intel_dp_to_dev(intel_dp); + u8 link_status[DP_LINK_STATUS_SIZE]; + + WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); + + if (!intel_dp_get_link_status(intel_dp, link_status)) { + DRM_ERROR("Failed to get link status\n"); + return; + } + + if (!intel_encoder->base.crtc) + return; + + if (!to_intel_crtc(intel_encoder->base.crtc)->active) + return; + + /* if link training is requested we should perform it always */ + if ((intel_dp->compliance_test_type == DP_TEST_LINK_TRAINING) || + (!drm_dp_channel_eq_ok(link_status, intel_dp->lane_count))) { + DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n", + intel_encoder->base.name); + intel_dp_start_link_train(intel_dp); + intel_dp_stop_link_train(intel_dp); + } +} + /* * According to DP spec * 5.1.2: @@ -4224,14 +4254,10 @@ go_again: * 4. Check link status on receipt of hot-plug interrupt */ static void -intel_dp_check_link_status(struct intel_dp *intel_dp) +intel_dp_short_pulse(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); - struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base; u8 sink_irq_vector; - u8 link_status[DP_LINK_STATUS_SIZE]; - - WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); /* * Clearing compliance test variables to allow capturing @@ -4241,17 +4267,6 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) intel_dp->compliance_test_type = 0; intel_dp->compliance_test_data = 0; - if (!intel_encoder->base.crtc) - return; - - if (!to_intel_crtc(intel_encoder->base.crtc)->active) - return; - - /* Try to read receiver status if the link appears to be up */ - if (!intel_dp_get_link_status(intel_dp, link_status)) { - return; - } - /* Now read the DPCD to see if it's actually running */ if (!intel_dp_get_dpcd(intel_dp)) { return; @@ -4271,14 +4286,9 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n"); } - /* if link training is requested we should perform it always */ - if ((intel_dp->compliance_test_type == DP_TEST_LINK_TRAINING) || - (!drm_dp_channel_eq_ok(link_status, intel_dp->lane_count))) { - DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n", - intel_encoder->base.name); - intel_dp_start_link_train(intel_dp); - intel_dp_stop_link_train(intel_dp); - } + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); + intel_dp_check_link_status(intel_dp); + drm_modeset_unlock(&dev->mode_config.connection_mutex); } /* XXX this is probably wrong for multiple downstream ports */ @@ -5017,11 +5027,8 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) } } - if (!intel_dp->is_mst) { - drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); - intel_dp_check_link_status(intel_dp); - drm_modeset_unlock(&dev->mode_config.connection_mutex); - } + if (!intel_dp->is_mst) + intel_dp_short_pulse(intel_dp); } ret = IRQ_HANDLED; -- cgit v1.2.3 From 30d9aa4265fe4b2b28239934770b2c2d59858df3 Mon Sep 17 00:00:00 2001 From: Shubhangi Shrivastava Date: Wed, 30 Mar 2016 18:05:25 +0530 Subject: drm/i915: Read sink_count dpcd always Sink count can change between short pulse hpd hence this patch adds a member variable to intel_dp so we can track any changes between short pulse interrupts. This patch reads sink_count dpcd always and removes its read operation based on values in downstream port dpcd. SINK_COUNT dpcd is not dependent on DOWNSTREAM_PORT_PRESENT dpcd. SINK_COUNT denotes if a display is attached, while DOWNSTREAM_PORT_PRESET indicates how many ports are available in the dongle where display can be attached. so it is possible for sink count to change irrespective of value in downstream port dpcd. Here is a table of possible values and scenarios sink_count downstream_port present 0 0 no display is attached 0 1 dongle is connected without display 1 0 display connected directly 1 1 display connected through dongle v2: Storing value of intel_dp->sink_count that is ready for consumption. (Ander) Squashing two commits into one. (Ander) v3: Added comment to explain the need of early return when sink count is 0. (Ander) Tested-by: Nathan D Ciobanu Signed-off-by: Sivakumar Thulasimani Signed-off-by: Shubhangi Shrivastava Reviewed-by: Ander Conselvan de Oliveira Signed-off-by: Ander Conselvan de Oliveira Link: http://patchwork.freedesktop.org/patch/msgid/1459341326-13142-4-git-send-email-shubhangi.shrivastava@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 30 +++++++++++++++++++++++------- drivers/gpu/drm/i915/intel_drv.h | 1 + 2 files changed, 24 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 9ee7a739a67f..c8d22be1ff0f 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3788,6 +3788,27 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp) if (intel_dp->dpcd[DP_DPCD_REV] == 0) return false; /* DPCD not present */ + if (intel_dp_dpcd_read_wake(&intel_dp->aux, DP_SINK_COUNT, + &intel_dp->sink_count, 1) < 0) + return false; + + /* + * Sink count can change between short pulse hpd hence + * a member variable in intel_dp will track any changes + * between short pulse interrupts. + */ + intel_dp->sink_count = DP_GET_SINK_COUNT(intel_dp->sink_count); + + /* + * SINK_COUNT == 0 and DOWNSTREAM_PORT_PRESENT == 1 implies that + * a dongle is present but no display. Unless we require to know + * if a dongle is present or not, we don't need to update + * downstream port information. So, an early return here saves + * time from performing other operations which are not required. + */ + if (!intel_dp->sink_count) + return false; + /* Check if the panel supports PSR */ memset(intel_dp->psr_dpcd, 0, sizeof(intel_dp->psr_dpcd)); if (is_edp(intel_dp)) { @@ -4308,14 +4329,9 @@ intel_dp_detect_dpcd(struct intel_dp *intel_dp) /* If we're HPD-aware, SINK_COUNT changes dynamically */ if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 && intel_dp->downstream_ports[0] & DP_DS_PORT_HPD) { - uint8_t reg; - - if (intel_dp_dpcd_read_wake(&intel_dp->aux, DP_SINK_COUNT, - ®, 1) < 0) - return connector_status_unknown; - return DP_GET_SINK_COUNT(reg) ? connector_status_connected - : connector_status_disconnected; + return intel_dp->sink_count ? + connector_status_connected : connector_status_disconnected; } /* If no HPD, poke DDC gently */ diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index ed65a7145158..9255b56a6c5e 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -796,6 +796,7 @@ struct intel_dp { uint32_t DP; int link_rate; uint8_t lane_count; + uint8_t sink_count; bool has_audio; bool detect_done; enum hdmi_force_audio force_audio; -- cgit v1.2.3 From 39ff747b2f8197de51dae540e742de4acdbd7763 Mon Sep 17 00:00:00 2001 From: Shubhangi Shrivastava Date: Wed, 30 Mar 2016 18:05:26 +0530 Subject: drm/i915: force full detect on sink count change This patch checks for changes in sink count between short pulse hpds and forces full detect when there is a change. This will allow both detection of hotplug and unplug of panels through dongles that give only short pulse for such events. v2: changed variable type from u8 to bool (Jani) return immediately if perform_full_detect is set(Siva) v3: changed method of determining full detection from using pointer to return code (Siva) v4: changed comments to indicate meaning of return value of intel_dp_short_pulse and explain the use of return value from intel_dp_get_dpcd in intel_dp_short_pulse (Ander) Tested-by: Nathan D Ciobanu Signed-off-by: Sivakumar Thulasimani Signed-off-by: Shubhangi Shrivastava Reviewed-by: Ander Conselvan de Oliveira Signed-off-by: Ander Conselvan de Oliveira Link: http://patchwork.freedesktop.org/patch/msgid/1459341326-13142-5-git-send-email-shubhangi.shrivastava@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index c8d22be1ff0f..da0c3d29fda8 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4273,12 +4273,19 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) * 2. Configure link according to Receiver Capabilities * 3. Use Link Training from 2.5.3.3 and 3.5.1.3 * 4. Check link status on receipt of hot-plug interrupt + * + * intel_dp_short_pulse - handles short pulse interrupts + * when full detection is not required. + * Returns %true if short pulse is handled and full detection + * is NOT required and %false otherwise. */ -static void +static bool intel_dp_short_pulse(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); u8 sink_irq_vector; + u8 old_sink_count = intel_dp->sink_count; + bool ret; /* * Clearing compliance test variables to allow capturing @@ -4288,9 +4295,17 @@ intel_dp_short_pulse(struct intel_dp *intel_dp) intel_dp->compliance_test_type = 0; intel_dp->compliance_test_data = 0; - /* Now read the DPCD to see if it's actually running */ - if (!intel_dp_get_dpcd(intel_dp)) { - return; + /* + * Now read the DPCD to see if it's actually running + * If the current value of sink count doesn't match with + * the value that was stored earlier or dpcd read failed + * we need to do full detection + */ + ret = intel_dp_get_dpcd(intel_dp); + + if ((old_sink_count != intel_dp->sink_count) || !ret) { + /* No need to proceed if we are going to do full detect */ + return false; } /* Try to read the source of the interrupt */ @@ -4310,6 +4325,8 @@ intel_dp_short_pulse(struct intel_dp *intel_dp) drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); intel_dp_check_link_status(intel_dp); drm_modeset_unlock(&dev->mode_config.connection_mutex); + + return true; } /* XXX this is probably wrong for multiple downstream ports */ @@ -5043,8 +5060,12 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) } } - if (!intel_dp->is_mst) - intel_dp_short_pulse(intel_dp); + if (!intel_dp->is_mst) { + if (!intel_dp_short_pulse(intel_dp)) { + intel_dp_long_pulse(intel_dp->attached_connector); + goto put_power; + } + } } ret = IRQ_HANDLED; -- cgit v1.2.3 From b61e79967a6f35043aa838ff36d9970658a0af3d Mon Sep 17 00:00:00 2001 From: Vandana Kannan Date: Thu, 31 Mar 2016 23:15:54 +0530 Subject: drm/i915: BXT DDI PHY sequence BUN According to the BSpec update, bit 7 of PORT_CL1CM_DW0 register needs to be checked to ensure that the register is in accessible state. Also, based on a BSpec update, changing the timeout value to check iphypwrgood, from 10ms to wait for up to 100us. v2: [Ville] use wait_for_us instead of the atomic call. v3: [Jani/Imre] read register only once Signed-off-by: Vandana Kannan Reported-by: Philippe Lecluse Cc: Deak, Imre Cc: Nikula, Jani Acked-by: Jani Nikula Reviewed-by: Imre Deak Signed-off-by: Imre Deak Link: http://patchwork.freedesktop.org/patch/msgid/1459446354-19012-1-git-send-email-vandana.kannan@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_ddi.c | 13 +++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index c839ce952a50..6df3c59fb192 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1324,6 +1324,7 @@ enum skl_disp_power_wells { #define _PORT_CL1CM_DW0_A 0x162000 #define _PORT_CL1CM_DW0_BC 0x6C000 #define PHY_POWER_GOOD (1 << 16) +#define PHY_RESERVED (1 << 7) #define BXT_PORT_CL1CM_DW0(phy) _BXT_PHY((phy), _PORT_CL1CM_DW0_BC, \ _PORT_CL1CM_DW0_A) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 1e083853c70d..3d62b601188f 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1732,9 +1732,18 @@ static void broxton_phy_init(struct drm_i915_private *dev_priv, val |= GT_DISPLAY_POWER_ON(phy); I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val); - /* Considering 10ms timeout until BSpec is updated */ - if (wait_for(I915_READ(BXT_PORT_CL1CM_DW0(phy)) & PHY_POWER_GOOD, 10)) + /* + * The PHY registers start out inaccessible and respond to reads with + * all 1s. Eventually they become accessible as they power up, then + * the reserved bit will give the default 0. Poll on the reserved bit + * becoming 0 to find when the PHY is accessible. + * HW team confirmed that the time to reach phypowergood status is + * anywhere between 50 us and 100us. + */ + if (wait_for_us(((I915_READ(BXT_PORT_CL1CM_DW0(phy)) & + (PHY_RESERVED | PHY_POWER_GOOD)) == PHY_POWER_GOOD), 100)) { DRM_ERROR("timeout during PHY%d power on\n", phy); + } for (port = (phy == DPIO_PHY0 ? PORT_B : PORT_A); port <= (phy == DPIO_PHY0 ? PORT_C : PORT_A); port++) { -- cgit v1.2.3 From 11b538cd6df398c86f4f0e09049c41e3058af10d Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 1 Apr 2016 10:44:41 +0300 Subject: drm/i915: use for_each_port_masked in bxt phy init for clarity Make it easier to see which ports are configured for each phy. No functional changes. Signed-off-by: Jani Nikula Reviewed-by: Ander Conselvan de Oliveira Signed-off-by: Imre Deak Link: http://patchwork.freedesktop.org/patch/msgid/1459496681-398-1-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_ddi.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 3d62b601188f..2758622a5c2d 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1726,7 +1726,7 @@ static void broxton_phy_init(struct drm_i915_private *dev_priv, enum dpio_phy phy) { enum port port; - uint32_t val; + u32 ports, val; val = I915_READ(BXT_P_CR_GT_DISP_PWRON); val |= GT_DISPLAY_POWER_ON(phy); @@ -1745,8 +1745,12 @@ static void broxton_phy_init(struct drm_i915_private *dev_priv, DRM_ERROR("timeout during PHY%d power on\n", phy); } - for (port = (phy == DPIO_PHY0 ? PORT_B : PORT_A); - port <= (phy == DPIO_PHY0 ? PORT_C : PORT_A); port++) { + if (phy == DPIO_PHY0) + ports = BIT(PORT_B) | BIT(PORT_C); + else + ports = BIT(PORT_A); + + for_each_port_masked(port, ports) { int lane; for (lane = 0; lane < 4; lane++) { -- cgit v1.2.3 From e37788fdb2c8138a1e3733de1e780389242e52d9 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 18 Mar 2016 13:11:09 +0200 Subject: drm/i915/dsi: refer to gpio index instead of gpio to avoid confusion The DSI sequence blocks contain gpio index references, not actual gpio numbers. No functional changes. Reviewed-by: Mika Kahola Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/4a54778e56b507e8a0bd635ba02ed2a4734b00ac.1458299160.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c index 8302a972d2d4..f687b2e9d8ca 100644 --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c @@ -198,7 +198,7 @@ static const u8 *mipi_exec_delay(struct intel_dsi *intel_dsi, const u8 *data) static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data) { - u8 gpio, action; + u8 gpio_index, action; u16 function, pad; u32 val; struct drm_device *dev = intel_dsi->base.base.dev; @@ -207,13 +207,13 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data) if (dev_priv->vbt.dsi.seq_version >= 3) data++; - gpio = *data++; + gpio_index = *data++; /* pull up/down */ action = *data++ & 1; - if (gpio >= ARRAY_SIZE(gtable)) { - DRM_DEBUG_KMS("unknown gpio %u\n", gpio); + if (gpio_index >= ARRAY_SIZE(gtable)) { + DRM_DEBUG_KMS("unknown gpio index %u\n", gpio_index); goto out; } @@ -227,16 +227,16 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data) goto out; } - function = gtable[gpio].function_reg; - pad = gtable[gpio].pad_reg; + function = gtable[gpio_index].function_reg; + pad = gtable[gpio_index].pad_reg; mutex_lock(&dev_priv->sb_lock); - if (!gtable[gpio].init) { + if (!gtable[gpio_index].init) { /* program the function */ /* FIXME: remove constant below */ vlv_iosf_sb_write(dev_priv, IOSF_PORT_GPIO_NC, function, 0x2000CC00); - gtable[gpio].init = 1; + gtable[gpio_index].init = 1; } val = 0x4 | action; -- cgit v1.2.3 From 934458c2c95df4077b426a00bfd9d62e818f914e Mon Sep 17 00:00:00 2001 From: Joonas Lahtinen Date: Fri, 1 Apr 2016 14:41:01 +0300 Subject: Revert "drm/i915: Fix races on fbdev" This reverts commit a7442b93cf32c1e1ddb721a26cd1f92302e2a222. With the patch applied SNB, IVB and ILK are experiencing hard machine hangs. Original patch was to fix "just" kernel panics so it's not a good trade-off. Proper fix for the panic is on the way, lets revert until then. Fixes: a7442b93cf32 ("drm/i915: Fix races on fbdev") Cc: Lukas Wunner Cc: Daniel Vetter Cc: Chris Wilson Cc: Tomi Sarvela Cc: stable@vger.kernel.org Acked-by: Lukas Wunner Tested-by: Tomi Sarvela Suggested-by: Chris Wilson Signed-off-by: Joonas Lahtinen Link: http://patchwork.freedesktop.org/patch/msgid/1459510861-29035-1-git-send-email-joonas.lahtinen@linux.intel.com --- drivers/gpu/drm/i915/i915_dma.c | 8 +++++--- drivers/gpu/drm/i915/intel_fbdev.c | 3 --- 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index a66ce4944cae..b377753717d1 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -493,9 +493,11 @@ static int i915_load_modeset_init(struct drm_device *dev) * Some ports require correctly set-up hpd registers for detection to * work properly (leading to ghost connected connector status), e.g. VGA * on gm45. Hence we can only set up the initial fbdev config after hpd - * irqs are fully enabled. We protect the fbdev initial config scanning - * against hotplug events by waiting in intel_fbdev_output_poll_changed - * until the asynchronous thread has finished. + * irqs are fully enabled. Now we should scan for the initial config + * only once hotplug handling is enabled, but due to screwed-up locking + * around kms/fbdev init we can't protect the fdbev initial config + * scanning against hotplug events. Hence do this first and ignore the + * tiny window where we will loose hotplug notifactions. */ intel_fbdev_initial_config_async(dev); diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index 4cf04ceccfc2..79ac202f3870 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -810,8 +810,6 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous void intel_fbdev_output_poll_changed(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - - async_synchronize_full(); if (dev_priv->fbdev) drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper); } @@ -823,7 +821,6 @@ void intel_fbdev_restore_mode(struct drm_device *dev) struct intel_fbdev *ifbdev = dev_priv->fbdev; struct drm_fb_helper *fb_helper; - async_synchronize_full(); if (!ifbdev) return; -- cgit v1.2.3 From 20b3d2a79f0f9ff1ac189f43df7598d0e968210a Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Mon, 28 Mar 2016 14:58:24 +0000 Subject: pinctrl: bcm2835: Implement get_direction callback Implement gpio_chip's get_direction() callback, that lets other drivers get particular GPIOs direction using gpiod_get_direction(). Signed-off-by: Stefan Wahren Reviewed-by: Eric Anholt Reviewed-by: Stephen Warren Signed-off-by: Linus Walleij --- drivers/pinctrl/bcm/pinctrl-bcm2835.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c index 08b1d93da9fe..57e7d21d526b 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -342,6 +342,18 @@ static int bcm2835_gpio_get(struct gpio_chip *chip, unsigned offset) return bcm2835_gpio_get_bit(pc, GPLEV0, offset); } +static int bcm2835_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) +{ + struct bcm2835_pinctrl *pc = gpiochip_get_data(chip); + enum bcm2835_fsel fsel = bcm2835_pinctrl_fsel_get(pc, offset); + + /* Alternative function doesn't clearly provide a direction */ + if (fsel > BCM2835_FSEL_GPIO_OUT) + return -EINVAL; + + return (fsel == BCM2835_FSEL_GPIO_IN); +} + static void bcm2835_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { struct bcm2835_pinctrl *pc = gpiochip_get_data(chip); @@ -370,6 +382,7 @@ static struct gpio_chip bcm2835_gpio_chip = { .free = gpiochip_generic_free, .direction_input = bcm2835_gpio_direction_input, .direction_output = bcm2835_gpio_direction_output, + .get_direction = bcm2835_gpio_get_direction, .get = bcm2835_gpio_get, .set = bcm2835_gpio_set, .to_irq = bcm2835_gpio_to_irq, -- cgit v1.2.3 From d32f7fd3bbc32732b094d938b95169521503a9fb Mon Sep 17 00:00:00 2001 From: Irina Tirdea Date: Thu, 31 Mar 2016 14:44:42 +0300 Subject: pinctrl: Rename pinctrl_utils_dt_free_map to pinctrl_utils_free_map Rename pinctrl_utils_dt_free_map to pinctrl_utils_free_map, since it does not depend on device tree despite the current name. This will enforce a consistent naming in pinctr-utils.c and will make it clear it can be called from outside device tree (e.g. from ACPI handling code). Signed-off-by: Irina Tirdea Signed-off-by: Linus Walleij --- drivers/pinctrl/bcm/pinctrl-bcm281xx.c | 2 +- drivers/pinctrl/bcm/pinctrl-cygnus-mux.c | 2 +- drivers/pinctrl/bcm/pinctrl-iproc-gpio.c | 2 +- drivers/pinctrl/bcm/pinctrl-nsp-gpio.c | 2 +- drivers/pinctrl/berlin/berlin.c | 2 +- drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 4 ++-- drivers/pinctrl/meson/pinctrl-meson.c | 2 +- drivers/pinctrl/nomadik/pinctrl-abx500.c | 4 ++-- drivers/pinctrl/nomadik/pinctrl-nomadik.c | 4 ++-- drivers/pinctrl/pinconf-generic.c | 2 +- drivers/pinctrl/pinctrl-amd.c | 2 +- drivers/pinctrl/pinctrl-as3722.c | 2 +- drivers/pinctrl/pinctrl-at91-pio4.c | 4 ++-- drivers/pinctrl/pinctrl-digicolor.c | 2 +- drivers/pinctrl/pinctrl-lpc18xx.c | 2 +- drivers/pinctrl/pinctrl-palmas.c | 2 +- drivers/pinctrl/pinctrl-pic32.c | 2 +- drivers/pinctrl/pinctrl-pistachio.c | 2 +- drivers/pinctrl/pinctrl-tb10x.c | 2 +- drivers/pinctrl/pinctrl-utils.c | 4 ++-- drivers/pinctrl/pinctrl-utils.h | 2 +- drivers/pinctrl/pinctrl-zynq.c | 2 +- drivers/pinctrl/pxa/pinctrl-pxa2xx.c | 2 +- drivers/pinctrl/qcom/pinctrl-msm.c | 2 +- drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 2 +- drivers/pinctrl/qcom/pinctrl-spmi-mpp.c | 2 +- drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c | 2 +- drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c | 2 +- drivers/pinctrl/stm32/pinctrl-stm32.c | 4 ++-- drivers/pinctrl/tegra/pinctrl-tegra-xusb.c | 2 +- drivers/pinctrl/tegra/pinctrl-tegra.c | 4 ++-- drivers/pinctrl/uniphier/pinctrl-uniphier-core.c | 2 +- 32 files changed, 39 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/bcm/pinctrl-bcm281xx.c b/drivers/pinctrl/bcm/pinctrl-bcm281xx.c index c3c692e508e8..f043b83b18f0 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm281xx.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm281xx.c @@ -1024,7 +1024,7 @@ static struct pinctrl_ops bcm281xx_pinctrl_ops = { .get_group_pins = bcm281xx_pinctrl_get_group_pins, .pin_dbg_show = bcm281xx_pinctrl_pin_dbg_show, .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, - .dt_free_map = pinctrl_utils_dt_free_map, + .dt_free_map = pinctrl_utils_free_map, }; static int bcm281xx_pinctrl_get_fcns_count(struct pinctrl_dev *pctldev) diff --git a/drivers/pinctrl/bcm/pinctrl-cygnus-mux.c b/drivers/pinctrl/bcm/pinctrl-cygnus-mux.c index 9728f3db9126..f0184dc16730 100644 --- a/drivers/pinctrl/bcm/pinctrl-cygnus-mux.c +++ b/drivers/pinctrl/bcm/pinctrl-cygnus-mux.c @@ -737,7 +737,7 @@ static const struct pinctrl_ops cygnus_pinctrl_ops = { .get_group_pins = cygnus_get_group_pins, .pin_dbg_show = cygnus_pin_dbg_show, .dt_node_to_map = pinconf_generic_dt_node_to_map_group, - .dt_free_map = pinctrl_utils_dt_free_map, + .dt_free_map = pinctrl_utils_free_map, }; static int cygnus_get_functions_count(struct pinctrl_dev *pctrl_dev) diff --git a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c index d530ab4b9d85..9ed98813c7d0 100644 --- a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c +++ b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c @@ -379,7 +379,7 @@ static const struct pinctrl_ops iproc_pctrl_ops = { .get_groups_count = iproc_get_groups_count, .get_group_name = iproc_get_group_name, .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, - .dt_free_map = pinctrl_utils_dt_free_map, + .dt_free_map = pinctrl_utils_free_map, }; static int iproc_gpio_set_pull(struct iproc_gpio *chip, unsigned gpio, diff --git a/drivers/pinctrl/bcm/pinctrl-nsp-gpio.c b/drivers/pinctrl/bcm/pinctrl-nsp-gpio.c index ac900435dc39..6c7d5f500f35 100644 --- a/drivers/pinctrl/bcm/pinctrl-nsp-gpio.c +++ b/drivers/pinctrl/bcm/pinctrl-nsp-gpio.c @@ -363,7 +363,7 @@ static const struct pinctrl_ops nsp_pctrl_ops = { .get_groups_count = nsp_get_groups_count, .get_group_name = nsp_get_group_name, .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, - .dt_free_map = pinctrl_utils_dt_free_map, + .dt_free_map = pinctrl_utils_free_map, }; static int nsp_gpio_set_slew(struct nsp_gpio *chip, unsigned gpio, u16 slew) diff --git a/drivers/pinctrl/berlin/berlin.c b/drivers/pinctrl/berlin/berlin.c index 46f2b4818da3..87b17b77df02 100644 --- a/drivers/pinctrl/berlin/berlin.c +++ b/drivers/pinctrl/berlin/berlin.c @@ -104,7 +104,7 @@ static const struct pinctrl_ops berlin_pinctrl_ops = { .get_groups_count = &berlin_pinctrl_get_group_count, .get_group_name = &berlin_pinctrl_get_group_name, .dt_node_to_map = &berlin_pinctrl_dt_node_to_map, - .dt_free_map = &pinctrl_utils_dt_free_map, + .dt_free_map = &pinctrl_utils_free_map, }; static int berlin_pinmux_get_functions_count(struct pinctrl_dev *pctrl_dev) diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c index 2bbe6f7964a7..8ca82c134260 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c @@ -605,7 +605,7 @@ static int mtk_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev, ret = mtk_pctrl_dt_subnode_to_map(pctldev, np, map, &reserved_maps, num_maps); if (ret < 0) { - pinctrl_utils_dt_free_map(pctldev, *map, *num_maps); + pinctrl_utils_free_map(pctldev, *map, *num_maps); of_node_put(np); return ret; } @@ -644,7 +644,7 @@ static int mtk_pctrl_get_group_pins(struct pinctrl_dev *pctldev, static const struct pinctrl_ops mtk_pctrl_ops = { .dt_node_to_map = mtk_pctrl_dt_node_to_map, - .dt_free_map = pinctrl_utils_dt_free_map, + .dt_free_map = pinctrl_utils_free_map, .get_groups_count = mtk_pctrl_get_groups_count, .get_group_name = mtk_pctrl_get_group_name, .get_group_pins = mtk_pctrl_get_group_pins, diff --git a/drivers/pinctrl/meson/pinctrl-meson.c b/drivers/pinctrl/meson/pinctrl-meson.c index 0bdb8fd3afd1..5bcbd3ee758c 100644 --- a/drivers/pinctrl/meson/pinctrl-meson.c +++ b/drivers/pinctrl/meson/pinctrl-meson.c @@ -171,7 +171,7 @@ static const struct pinctrl_ops meson_pctrl_ops = { .get_group_name = meson_get_group_name, .get_group_pins = meson_get_group_pins, .dt_node_to_map = pinconf_generic_dt_node_to_map_all, - .dt_free_map = pinctrl_utils_dt_free_map, + .dt_free_map = pinctrl_utils_free_map, .pin_dbg_show = meson_pin_dbg_show, }; diff --git a/drivers/pinctrl/nomadik/pinctrl-abx500.c b/drivers/pinctrl/nomadik/pinctrl-abx500.c index 1f7469c9857d..532356823eea 100644 --- a/drivers/pinctrl/nomadik/pinctrl-abx500.c +++ b/drivers/pinctrl/nomadik/pinctrl-abx500.c @@ -937,7 +937,7 @@ static int abx500_dt_node_to_map(struct pinctrl_dev *pctldev, ret = abx500_dt_subnode_to_map(pctldev, np, map, &reserved_maps, num_maps); if (ret < 0) { - pinctrl_utils_dt_free_map(pctldev, *map, *num_maps); + pinctrl_utils_free_map(pctldev, *map, *num_maps); return ret; } } @@ -951,7 +951,7 @@ static const struct pinctrl_ops abx500_pinctrl_ops = { .get_group_pins = abx500_get_group_pins, .pin_dbg_show = abx500_pin_dbg_show, .dt_node_to_map = abx500_dt_node_to_map, - .dt_free_map = pinctrl_utils_dt_free_map, + .dt_free_map = pinctrl_utils_free_map, }; static int abx500_pin_config_get(struct pinctrl_dev *pctldev, diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c index 352406108fa0..c9c8c17678d7 100644 --- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c @@ -1612,7 +1612,7 @@ static int nmk_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, ret = nmk_pinctrl_dt_subnode_to_map(pctldev, np, map, &reserved_maps, num_maps); if (ret < 0) { - pinctrl_utils_dt_free_map(pctldev, *map, *num_maps); + pinctrl_utils_free_map(pctldev, *map, *num_maps); return ret; } } @@ -1626,7 +1626,7 @@ static const struct pinctrl_ops nmk_pinctrl_ops = { .get_group_pins = nmk_get_group_pins, .pin_dbg_show = nmk_pin_dbg_show, .dt_node_to_map = nmk_pinctrl_dt_node_to_map, - .dt_free_map = pinctrl_utils_dt_free_map, + .dt_free_map = pinctrl_utils_free_map, }; static int nmk_pmx_get_funcs_cnt(struct pinctrl_dev *pctldev) diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c index 79e6159712c2..d5bf9fae2ddd 100644 --- a/drivers/pinctrl/pinconf-generic.c +++ b/drivers/pinctrl/pinconf-generic.c @@ -386,7 +386,7 @@ int pinconf_generic_dt_node_to_map(struct pinctrl_dev *pctldev, return 0; exit: - pinctrl_utils_dt_free_map(pctldev, *map, *num_maps); + pinctrl_utils_free_map(pctldev, *map, *num_maps); return ret; } EXPORT_SYMBOL_GPL(pinconf_generic_dt_node_to_map); diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c index cc44ae8c8758..b0e2ec0daed3 100644 --- a/drivers/pinctrl/pinctrl-amd.c +++ b/drivers/pinctrl/pinctrl-amd.c @@ -580,7 +580,7 @@ static const struct pinctrl_ops amd_pinctrl_ops = { .get_group_pins = amd_get_group_pins, #ifdef CONFIG_OF .dt_node_to_map = pinconf_generic_dt_node_to_map_group, - .dt_free_map = pinctrl_utils_dt_free_map, + .dt_free_map = pinctrl_utils_free_map, #endif }; diff --git a/drivers/pinctrl/pinctrl-as3722.c b/drivers/pinctrl/pinctrl-as3722.c index e844fdc6d3a8..1070bb9fa99d 100644 --- a/drivers/pinctrl/pinctrl-as3722.c +++ b/drivers/pinctrl/pinctrl-as3722.c @@ -201,7 +201,7 @@ static const struct pinctrl_ops as3722_pinctrl_ops = { .get_group_name = as3722_pinctrl_get_group_name, .get_group_pins = as3722_pinctrl_get_group_pins, .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, - .dt_free_map = pinctrl_utils_dt_free_map, + .dt_free_map = pinctrl_utils_free_map, }; static int as3722_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev) diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c index 4429312e848d..629b6fefa8e0 100644 --- a/drivers/pinctrl/pinctrl-at91-pio4.c +++ b/drivers/pinctrl/pinctrl-at91-pio4.c @@ -579,7 +579,7 @@ static int atmel_pctl_dt_node_to_map(struct pinctrl_dev *pctldev, } if (ret < 0) { - pinctrl_utils_dt_free_map(pctldev, *map, *num_maps); + pinctrl_utils_free_map(pctldev, *map, *num_maps); dev_err(pctldev->dev, "can't create maps for node %s\n", np_config->full_name); } @@ -592,7 +592,7 @@ static const struct pinctrl_ops atmel_pctlops = { .get_group_name = atmel_pctl_get_group_name, .get_group_pins = atmel_pctl_get_group_pins, .dt_node_to_map = atmel_pctl_dt_node_to_map, - .dt_free_map = pinctrl_utils_dt_free_map, + .dt_free_map = pinctrl_utils_free_map, }; static int atmel_pmx_get_functions_count(struct pinctrl_dev *pctldev) diff --git a/drivers/pinctrl/pinctrl-digicolor.c b/drivers/pinctrl/pinctrl-digicolor.c index f1343d6ca823..b347806215e7 100644 --- a/drivers/pinctrl/pinctrl-digicolor.c +++ b/drivers/pinctrl/pinctrl-digicolor.c @@ -84,7 +84,7 @@ static struct pinctrl_ops dc_pinctrl_ops = { .get_group_name = dc_get_group_name, .get_group_pins = dc_get_group_pins, .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, - .dt_free_map = pinctrl_utils_dt_free_map, + .dt_free_map = pinctrl_utils_free_map, }; static const char *const dc_functions[] = { diff --git a/drivers/pinctrl/pinctrl-lpc18xx.c b/drivers/pinctrl/pinctrl-lpc18xx.c index b1767f7e45d1..e897b63bd1bb 100644 --- a/drivers/pinctrl/pinctrl-lpc18xx.c +++ b/drivers/pinctrl/pinctrl-lpc18xx.c @@ -1252,7 +1252,7 @@ static const struct pinctrl_ops lpc18xx_pctl_ops = { .get_group_name = lpc18xx_pctl_get_group_name, .get_group_pins = lpc18xx_pctl_get_group_pins, .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, - .dt_free_map = pinctrl_utils_dt_free_map, + .dt_free_map = pinctrl_utils_free_map, }; static struct pinctrl_desc lpc18xx_scu_desc = { diff --git a/drivers/pinctrl/pinctrl-palmas.c b/drivers/pinctrl/pinctrl-palmas.c index f7e168044baf..8f0163feda28 100644 --- a/drivers/pinctrl/pinctrl-palmas.c +++ b/drivers/pinctrl/pinctrl-palmas.c @@ -656,7 +656,7 @@ static const struct pinctrl_ops palmas_pinctrl_ops = { .get_group_name = palmas_pinctrl_get_group_name, .get_group_pins = palmas_pinctrl_get_group_pins, .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, - .dt_free_map = pinctrl_utils_dt_free_map, + .dt_free_map = pinctrl_utils_free_map, }; static int palmas_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev) diff --git a/drivers/pinctrl/pinctrl-pic32.c b/drivers/pinctrl/pinctrl-pic32.c index 0b07d4bdab95..87ee1c4e70a7 100644 --- a/drivers/pinctrl/pinctrl-pic32.c +++ b/drivers/pinctrl/pinctrl-pic32.c @@ -1743,7 +1743,7 @@ static const struct pinctrl_ops pic32_pinctrl_ops = { .get_group_name = pic32_pinctrl_get_group_name, .get_group_pins = pic32_pinctrl_get_group_pins, .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, - .dt_free_map = pinctrl_utils_dt_free_map, + .dt_free_map = pinctrl_utils_free_map, }; static int pic32_pinmux_get_functions_count(struct pinctrl_dev *pctldev) diff --git a/drivers/pinctrl/pinctrl-pistachio.c b/drivers/pinctrl/pinctrl-pistachio.c index 856f736cb1a6..846fe91aa155 100644 --- a/drivers/pinctrl/pinctrl-pistachio.c +++ b/drivers/pinctrl/pinctrl-pistachio.c @@ -913,7 +913,7 @@ static const struct pinctrl_ops pistachio_pinctrl_ops = { .get_group_name = pistachio_pinctrl_get_group_name, .get_group_pins = pistachio_pinctrl_get_group_pins, .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, - .dt_free_map = pinctrl_utils_dt_free_map, + .dt_free_map = pinctrl_utils_free_map, }; static int pistachio_pinmux_get_functions_count(struct pinctrl_dev *pctldev) diff --git a/drivers/pinctrl/pinctrl-tb10x.c b/drivers/pinctrl/pinctrl-tb10x.c index 6546b9bb2e06..620af57f10ad 100644 --- a/drivers/pinctrl/pinctrl-tb10x.c +++ b/drivers/pinctrl/pinctrl-tb10x.c @@ -582,7 +582,7 @@ static struct pinctrl_ops tb10x_pinctrl_ops = { .get_group_name = tb10x_get_group_name, .get_group_pins = tb10x_get_group_pins, .dt_node_to_map = tb10x_dt_node_to_map, - .dt_free_map = pinctrl_utils_dt_free_map, + .dt_free_map = pinctrl_utils_free_map, }; static int tb10x_get_functions_count(struct pinctrl_dev *pctl) diff --git a/drivers/pinctrl/pinctrl-utils.c b/drivers/pinctrl/pinctrl-utils.c index d77693f2cc1b..9189fbafb102 100644 --- a/drivers/pinctrl/pinctrl-utils.c +++ b/drivers/pinctrl/pinctrl-utils.c @@ -122,7 +122,7 @@ int pinctrl_utils_add_config(struct pinctrl_dev *pctldev, } EXPORT_SYMBOL_GPL(pinctrl_utils_add_config); -void pinctrl_utils_dt_free_map(struct pinctrl_dev *pctldev, +void pinctrl_utils_free_map(struct pinctrl_dev *pctldev, struct pinctrl_map *map, unsigned num_maps) { int i; @@ -139,4 +139,4 @@ void pinctrl_utils_dt_free_map(struct pinctrl_dev *pctldev, } kfree(map); } -EXPORT_SYMBOL_GPL(pinctrl_utils_dt_free_map); +EXPORT_SYMBOL_GPL(pinctrl_utils_free_map); diff --git a/drivers/pinctrl/pinctrl-utils.h b/drivers/pinctrl/pinctrl-utils.h index d0ffe1ce200f..8f9f2d28c5b8 100644 --- a/drivers/pinctrl/pinctrl-utils.h +++ b/drivers/pinctrl/pinctrl-utils.h @@ -37,7 +37,7 @@ int pinctrl_utils_add_map_configs(struct pinctrl_dev *pctldev, int pinctrl_utils_add_config(struct pinctrl_dev *pctldev, unsigned long **configs, unsigned *num_configs, unsigned long config); -void pinctrl_utils_dt_free_map(struct pinctrl_dev *pctldev, +void pinctrl_utils_free_map(struct pinctrl_dev *pctldev, struct pinctrl_map *map, unsigned num_maps); #endif /* __PINCTRL_UTILS_H__ */ diff --git a/drivers/pinctrl/pinctrl-zynq.c b/drivers/pinctrl/pinctrl-zynq.c index 76f1abd71e31..3f1b55f675a5 100644 --- a/drivers/pinctrl/pinctrl-zynq.c +++ b/drivers/pinctrl/pinctrl-zynq.c @@ -862,7 +862,7 @@ static const struct pinctrl_ops zynq_pctrl_ops = { .get_group_name = zynq_pctrl_get_group_name, .get_group_pins = zynq_pctrl_get_group_pins, .dt_node_to_map = pinconf_generic_dt_node_to_map_all, - .dt_free_map = pinctrl_utils_dt_free_map, + .dt_free_map = pinctrl_utils_free_map, }; /* pinmux */ diff --git a/drivers/pinctrl/pxa/pinctrl-pxa2xx.c b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c index f553313bc2ef..6098685f0116 100644 --- a/drivers/pinctrl/pxa/pinctrl-pxa2xx.c +++ b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c @@ -57,7 +57,7 @@ static int pxa2xx_pctrl_get_group_pins(struct pinctrl_dev *pctldev, static const struct pinctrl_ops pxa2xx_pctl_ops = { #ifdef CONFIG_OF .dt_node_to_map = pinconf_generic_dt_node_to_map_all, - .dt_free_map = pinctrl_utils_dt_free_map, + .dt_free_map = pinctrl_utils_free_map, #endif .get_groups_count = pxa2xx_pctrl_get_groups_count, .get_group_name = pxa2xx_pctrl_get_group_name, diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index 8777cf083eef..f9322d4c2294 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c @@ -101,7 +101,7 @@ static const struct pinctrl_ops msm_pinctrl_ops = { .get_group_name = msm_get_group_name, .get_group_pins = msm_get_group_pins, .dt_node_to_map = pinconf_generic_dt_node_to_map_group, - .dt_free_map = pinctrl_utils_dt_free_map, + .dt_free_map = pinctrl_utils_free_map, }; static int msm_get_functions_count(struct pinctrl_dev *pctldev) diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c index 4e12ded3c773..857ccfa67986 100644 --- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c +++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c @@ -212,7 +212,7 @@ static const struct pinctrl_ops pmic_gpio_pinctrl_ops = { .get_group_name = pmic_gpio_get_group_name, .get_group_pins = pmic_gpio_get_group_pins, .dt_node_to_map = pinconf_generic_dt_node_to_map_group, - .dt_free_map = pinctrl_utils_dt_free_map, + .dt_free_map = pinctrl_utils_free_map, }; static int pmic_gpio_get_functions_count(struct pinctrl_dev *pctldev) diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c b/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c index 2a3e5490a483..469660055809 100644 --- a/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c +++ b/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c @@ -235,7 +235,7 @@ static const struct pinctrl_ops pmic_mpp_pinctrl_ops = { .get_group_name = pmic_mpp_get_group_name, .get_group_pins = pmic_mpp_get_group_pins, .dt_node_to_map = pinconf_generic_dt_node_to_map_group, - .dt_free_map = pinctrl_utils_dt_free_map, + .dt_free_map = pinctrl_utils_free_map, }; static int pmic_mpp_get_functions_count(struct pinctrl_dev *pctldev) diff --git a/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c b/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c index cd8580d9741d..ecd784b6c743 100644 --- a/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c +++ b/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c @@ -200,7 +200,7 @@ static const struct pinctrl_ops pm8xxx_pinctrl_ops = { .get_group_name = pm8xxx_get_group_name, .get_group_pins = pm8xxx_get_group_pins, .dt_node_to_map = pinconf_generic_dt_node_to_map_group, - .dt_free_map = pinctrl_utils_dt_free_map, + .dt_free_map = pinctrl_utils_free_map, }; static int pm8xxx_get_functions_count(struct pinctrl_dev *pctldev) diff --git a/drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c b/drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c index 54a5402a9079..ac79021eb261 100644 --- a/drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c +++ b/drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c @@ -277,7 +277,7 @@ static const struct pinctrl_ops pm8xxx_pinctrl_ops = { .get_group_name = pm8xxx_get_group_name, .get_group_pins = pm8xxx_get_group_pins, .dt_node_to_map = pinconf_generic_dt_node_to_map_group, - .dt_free_map = pinctrl_utils_dt_free_map, + .dt_free_map = pinctrl_utils_free_map, }; static int pm8xxx_get_functions_count(struct pinctrl_dev *pctldev) diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c index 8deb566ed4cd..b97b7c01f942 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c @@ -358,7 +358,7 @@ static int stm32_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev, ret = stm32_pctrl_dt_subnode_to_map(pctldev, np, map, &reserved_maps, num_maps); if (ret < 0) { - pinctrl_utils_dt_free_map(pctldev, *map, *num_maps); + pinctrl_utils_free_map(pctldev, *map, *num_maps); return ret; } } @@ -396,7 +396,7 @@ static int stm32_pctrl_get_group_pins(struct pinctrl_dev *pctldev, static const struct pinctrl_ops stm32_pctrl_ops = { .dt_node_to_map = stm32_pctrl_dt_node_to_map, - .dt_free_map = pinctrl_utils_dt_free_map, + .dt_free_map = pinctrl_utils_free_map, .get_groups_count = stm32_pctrl_get_groups_count, .get_group_name = stm32_pctrl_get_group_name, .get_group_pins = stm32_pctrl_get_group_pins, diff --git a/drivers/pinctrl/tegra/pinctrl-tegra-xusb.c b/drivers/pinctrl/tegra/pinctrl-tegra-xusb.c index 2f06029c9405..e58b5f344b34 100644 --- a/drivers/pinctrl/tegra/pinctrl-tegra-xusb.c +++ b/drivers/pinctrl/tegra/pinctrl-tegra-xusb.c @@ -267,7 +267,7 @@ static const struct pinctrl_ops tegra_xusb_padctl_pinctrl_ops = { .get_group_name = tegra_xusb_padctl_get_group_name, .get_group_pins = tegra_xusb_padctl_get_group_pins, .dt_node_to_map = tegra_xusb_padctl_dt_node_to_map, - .dt_free_map = pinctrl_utils_dt_free_map, + .dt_free_map = pinctrl_utils_free_map, }; static int tegra_xusb_padctl_get_functions_count(struct pinctrl_dev *pinctrl) diff --git a/drivers/pinctrl/tegra/pinctrl-tegra.c b/drivers/pinctrl/tegra/pinctrl-tegra.c index 49388822c0e9..3f7fce9075ab 100644 --- a/drivers/pinctrl/tegra/pinctrl-tegra.c +++ b/drivers/pinctrl/tegra/pinctrl-tegra.c @@ -215,7 +215,7 @@ static int tegra_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, ret = tegra_pinctrl_dt_subnode_to_map(pctldev, np, map, &reserved_maps, num_maps); if (ret < 0) { - pinctrl_utils_dt_free_map(pctldev, *map, + pinctrl_utils_free_map(pctldev, *map, *num_maps); of_node_put(np); return ret; @@ -233,7 +233,7 @@ static const struct pinctrl_ops tegra_pinctrl_ops = { .pin_dbg_show = tegra_pinctrl_pin_dbg_show, #endif .dt_node_to_map = tegra_pinctrl_dt_node_to_map, - .dt_free_map = pinctrl_utils_dt_free_map, + .dt_free_map = pinctrl_utils_free_map, }; static int tegra_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev) diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c index 589872cc8adb..c9e4a852afa5 100644 --- a/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c @@ -115,7 +115,7 @@ static const struct pinctrl_ops uniphier_pctlops = { .pin_dbg_show = uniphier_pctl_pin_dbg_show, #endif .dt_node_to_map = pinconf_generic_dt_node_to_map_all, - .dt_free_map = pinctrl_utils_dt_free_map, + .dt_free_map = pinctrl_utils_free_map, }; static int uniphier_conf_pin_bias_get(struct pinctrl_dev *pctldev, -- cgit v1.2.3 From 5b421c57e0a9cb1187c2fe203d01fbfb651cb061 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 1 Mar 2016 16:16:23 +0200 Subject: drm/i915: Disable FDI RX before DDI_BUF_CTL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bspec is confused w.r.t. the HSW/BDW FDI disable sequence. It lists FDI RX disable both as step 13 and step 18 in the sequence. But I dug up an old BUN mail from Art that moved the FDI RX disable to happen before DDI_BUF_CTL disable. That BUN did not renumber the steps and just added a note: "Workaround: Disable PCH FDI Receiver before disabling DDI_BUF_CTL." The BUN described the symptoms of the fixed issue as: "PCH display underflow and a black screen on the analog CRT port that happened after a FDI re-train" I suppose later someone tried to renumber the steps to match, but forgot to remove the FDI RX disable from its old position in the sequence. They also forgot to update the note describing what should be done in case of an FDI training failure. Currently it says: "To retry FDI training, follow the Disable Sequence steps to Disable FDI, but skip the steps related to clocks and PLLs (16, 19, and 20), ..." It should really say "17, 20, and 21" with the current sequence because those are the steps that deal with PLLs and whatnot, after step 13 became FDI RX disable. And had the step 18 FDI RX disable been removed, as I suspect it should have, the note should actually say "17, 19, and 20". So, let's move the FDI RX disable to happen before DDI_BUF_CTL disable, as that would appear to be the correct order based on the BUN. Note that Art has since unconfused the spec, and so this patch should now match the steps listed in the spec. v2: Add a note that the spec is now correct Cc: Paulo Zanoni Cc: Art Runyan Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1456841783-4779-1-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Paulo Zanoni --- drivers/gpu/drm/i915/intel_ddi.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 2758622a5c2d..766156f88ef4 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -629,6 +629,10 @@ void hsw_fdi_link_train(struct drm_crtc *crtc) break; } + rx_ctl_val &= ~FDI_RX_ENABLE; + I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val); + POSTING_READ(FDI_RX_CTL(PIPE_A)); + temp = I915_READ(DDI_BUF_CTL(PORT_E)); temp &= ~DDI_BUF_CTL_ENABLE; I915_WRITE(DDI_BUF_CTL(PORT_E), temp); @@ -643,10 +647,6 @@ void hsw_fdi_link_train(struct drm_crtc *crtc) intel_wait_ddi_buf_idle(dev_priv, PORT_E); - rx_ctl_val &= ~FDI_RX_ENABLE; - I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val); - POSTING_READ(FDI_RX_CTL(PIPE_A)); - /* Reset FDI_RX_MISC pwrdn lanes */ temp = I915_READ(FDI_RX_MISC(PIPE_A)); temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK); @@ -1911,12 +1911,18 @@ void intel_ddi_fdi_disable(struct drm_crtc *crtc) struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); uint32_t val; - intel_ddi_post_disable(intel_encoder); - + /* + * Bspec lists this as both step 13 (before DDI_BUF_CTL disable) + * and step 18 (after clearing PORT_CLK_SEL). Based on a BUN, + * step 13 is the correct place for it. Step 18 is where it was + * originally before the BUN. + */ val = I915_READ(FDI_RX_CTL(PIPE_A)); val &= ~FDI_RX_ENABLE; I915_WRITE(FDI_RX_CTL(PIPE_A), val); + intel_ddi_post_disable(intel_encoder); + val = I915_READ(FDI_RX_MISC(PIPE_A)); val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK); val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2); -- cgit v1.2.3 From 27878ede4fec7b929c3010710ba4d55c617c621d Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 15 Mar 2016 16:39:54 +0200 Subject: drm/i915: Throw out BUGs from DPLL/PCH functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These BUGs don't serve any purpose IMO. Throw them out. Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1458052809-23426-2-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/intel_display.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e6b5ee51739b..cc607acf3df6 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1617,9 +1617,6 @@ static void i9xx_enable_pll(struct intel_crtc *crtc) assert_pipe_disabled(dev_priv, crtc->pipe); - /* No really, not for ILK+ */ - BUG_ON(INTEL_INFO(dev)->gen >= 5); - /* PLL is protected by panel, make sure we can write it */ if (IS_MOBILE(dev) && !IS_I830(dev)) assert_panel_unlocked(dev_priv, crtc->pipe); @@ -1795,9 +1792,6 @@ static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv, i915_reg_t reg; uint32_t val, pipeconf_val; - /* PCH only available on ILK+ */ - BUG_ON(!HAS_PCH_SPLIT(dev)); - /* Make sure PCH DPLL is enabled */ assert_shared_dpll_enabled(dev_priv, intel_crtc->config->shared_dpll); @@ -1851,9 +1845,6 @@ static void lpt_enable_pch_transcoder(struct drm_i915_private *dev_priv, { u32 val, pipeconf_val; - /* PCH only available on ILK+ */ - BUG_ON(!HAS_PCH_SPLIT(dev_priv->dev)); - /* FDI must be feeding us bits for PCH ports */ assert_fdi_tx_enabled(dev_priv, (enum pipe) cpu_transcoder); assert_fdi_rx_enabled(dev_priv, TRANSCODER_A); -- cgit v1.2.3 From 03ed5cbfacfb35a5d3aeeb39ebec63437917e7f1 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 15 Mar 2016 16:39:55 +0200 Subject: drm/i915: Make {vlv,chv}_{disable,update}_pll() more similar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The VLV and CHV DPLL disable and update are almost identical in how the DPLL/DPLL_MD registers need to be set up. But the code looks more different than it really is. Try to bring them into line. Note that we now leave the refclock always enabled for both DPLLs in the dual channel PHY. But that's perfectly fine since it's the same clock, and we anyway already do that when turning the disp2d power well on. v2: s/chv_update_pll/chv_compute_dpll/ v3: Add a note that we leave refclocks enabled for both DPLLs (Jani) Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1458052809-23426-3-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/intel_display.c | 63 ++++++++++++++---------------------- 1 file changed, 25 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index cc607acf3df6..05287480078d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1715,16 +1715,13 @@ static void vlv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) /* Make sure the pipe isn't still relying on us */ assert_pipe_disabled(dev_priv, pipe); - /* - * Leave integrated clock source and reference clock enabled for pipe B. - * The latter is needed for VGA hotplug / manual detection. - */ - val = DPLL_VGA_MODE_DIS; - if (pipe == PIPE_B) - val = DPLL_INTEGRATED_CRI_CLK_VLV | DPLL_REF_CLK_ENABLE_VLV; + val = DPLL_INTEGRATED_REF_CLK_VLV | + DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS; + if (pipe != PIPE_A) + val |= DPLL_INTEGRATED_CRI_CLK_VLV; + I915_WRITE(DPLL(pipe), val); POSTING_READ(DPLL(pipe)); - } static void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) @@ -1735,11 +1732,11 @@ static void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) /* Make sure the pipe isn't still relying on us */ assert_pipe_disabled(dev_priv, pipe); - /* Set PLL en = 0 */ val = DPLL_SSC_REF_CLK_CHV | DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS; if (pipe != PIPE_A) val |= DPLL_INTEGRATED_CRI_CLK_VLV; + I915_WRITE(DPLL(pipe), val); POSTING_READ(DPLL(pipe)); @@ -7156,24 +7153,27 @@ void intel_dp_set_m_n(struct intel_crtc *crtc, enum link_m_n_set m_n) static void vlv_compute_dpll(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { - u32 dpll, dpll_md; + pipe_config->dpll_hw_state.dpll = DPLL_INTEGRATED_REF_CLK_VLV | + DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS | + DPLL_VCO_ENABLE | DPLL_EXT_BUFFER_ENABLE_VLV; + if (crtc->pipe != PIPE_A) + pipe_config->dpll_hw_state.dpll |= DPLL_INTEGRATED_CRI_CLK_VLV; - /* - * Enable DPIO clock input. We should never disable the reference - * clock for pipe B, since VGA hotplug / manual detection depends - * on it. - */ - dpll = DPLL_EXT_BUFFER_ENABLE_VLV | DPLL_REF_CLK_ENABLE_VLV | - DPLL_VGA_MODE_DIS | DPLL_INTEGRATED_REF_CLK_VLV; - /* We should never disable this, set it here for state tracking */ - if (crtc->pipe == PIPE_B) - dpll |= DPLL_INTEGRATED_CRI_CLK_VLV; - dpll |= DPLL_VCO_ENABLE; - pipe_config->dpll_hw_state.dpll = dpll; + pipe_config->dpll_hw_state.dpll_md = + (pipe_config->pixel_multiplier - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT; +} + +static void chv_compute_dpll(struct intel_crtc *crtc, + struct intel_crtc_state *pipe_config) +{ + pipe_config->dpll_hw_state.dpll = DPLL_SSC_REF_CLK_CHV | + DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS | + DPLL_VCO_ENABLE; + if (crtc->pipe != PIPE_A) + pipe_config->dpll_hw_state.dpll |= DPLL_INTEGRATED_CRI_CLK_VLV; - dpll_md = (pipe_config->pixel_multiplier - 1) - << DPLL_MD_UDI_MULTIPLIER_SHIFT; - pipe_config->dpll_hw_state.dpll_md = dpll_md; + pipe_config->dpll_hw_state.dpll_md = + (pipe_config->pixel_multiplier - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT; } static void vlv_prepare_pll(struct intel_crtc *crtc, @@ -7267,19 +7267,6 @@ static void vlv_prepare_pll(struct intel_crtc *crtc, mutex_unlock(&dev_priv->sb_lock); } -static void chv_compute_dpll(struct intel_crtc *crtc, - struct intel_crtc_state *pipe_config) -{ - pipe_config->dpll_hw_state.dpll = DPLL_SSC_REF_CLK_CHV | - DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS | - DPLL_VCO_ENABLE; - if (crtc->pipe != PIPE_A) - pipe_config->dpll_hw_state.dpll |= DPLL_INTEGRATED_CRI_CLK_VLV; - - pipe_config->dpll_hw_state.dpll_md = - (pipe_config->pixel_multiplier - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT; -} - static void chv_prepare_pll(struct intel_crtc *crtc, const struct intel_crtc_state *pipe_config) { -- cgit v1.2.3 From c231775c2df845abc193666a5aec552c3ad3740f Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 15 Mar 2016 16:39:56 +0200 Subject: drm/i915: Implement WaPixelRepeatModeFixForC0:chv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DPLL_MD(PIPE_C) is AWOL on CHV. Instead of fixing it someone added chicken bits to propagate the pixel multiplier from DPLL_MD(PIPE_B) to either pipe B or C. So do that to make pixel repeat work on pipes B and C. Pipe A is fine without any tricks. Fortunately the pixel repeat propagation appears to be a oneshot operation, so once the value has been written we can clear the chicken bits. So it is still possible to drive pipe B and C with different pixel multipliers simultaneosly. Looks like DPLL_VGA_MODE_DIS must also be set in DPLL(PIPE_B) for this to work. But since we keep that bit always set in all DPLLs there's no problem. This of course means we can't reliably read out the pixel multiplier for pipes B and C. That would make the state checker unhappy, so I added shadow copies of those registers in to dev_priv. The other option would have been to skip pixel multiplier, dpll_md an dotclock checks entirely on CHV, but that feels like a serious loss of cross checking, so just pretending that we have working DPLL MD registers seemed better. Obviously with the shadow copies we can't detect if the pixel multiplier was properly configured, nor can we take over its state from the BIOS, but hopefully people won't have displays that would be limitd to such crappy modes. There is one strange flicker still remaining. It's visible on pipe C/HDMID when HDMIB is enabled while driven by pipe B. It doesn't occur if pipe A drives HDMIB, nor is there any glitch on pipe B/HDMIB when port C/HDMID starts up. I don't have a board with HDMIC so not sure if it happens there too. So I'm not sure if it's somehow tied in with this strange linkage between pipe B and C. Sadly I was unable to find an enable sequence that would avoid the glitch, but at least it's not fatal ie. the output recovers afterwards. Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1458052809-23426-4-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/i915_drv.h | 7 +++++++ drivers/gpu/drm/i915/i915_reg.h | 4 ++++ drivers/gpu/drm/i915/intel_display.c | 30 ++++++++++++++++++++++++++---- 3 files changed, 37 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d3ebb2fa46fa..dd187727c813 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1900,7 +1900,14 @@ struct drm_i915_private { u32 fdi_rx_config; + /* Shadow for DISPLAY_PHY_CONTROL which can't be safely read */ u32 chv_phy_control; + /* + * Shadows for CHV DPLL_MD regs to keep the state + * checker somewhat working in the presence hardware + * crappiness (can't read out DPLL_MD for pipes B & C). + */ + u32 chv_dpll_md[I915_MAX_PIPES]; u32 suspend_count; bool suspended_to_idle; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 6df3c59fb192..12f510381273 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4786,6 +4786,10 @@ enum skl_disp_power_wells { #define CBR_PND_DEADLINE_DISABLE (1<<31) #define CBR_PWM_CLOCK_MUX_SELECT (1<<30) +#define CBR4_VLV _MMIO(VLV_DISPLAY_BASE + 0x70450) +#define CBR_DPLLBMD_PIPE_C (1<<29) +#define CBR_DPLLBMD_PIPE_B (1<<18) + /* FIFO watermark sizes etc */ #define G4X_FIFO_LINE_SIZE 64 #define I915_FIFO_LINE_SIZE 64 diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 05287480078d..3fdce859758a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1591,9 +1591,27 @@ static void chv_enable_pll(struct intel_crtc *crtc, if (wait_for(((I915_READ(DPLL(pipe)) & DPLL_LOCK_VLV) == DPLL_LOCK_VLV), 1)) DRM_ERROR("PLL %d failed to lock\n", pipe); - /* not sure when this should be written */ - I915_WRITE(DPLL_MD(pipe), pipe_config->dpll_hw_state.dpll_md); - POSTING_READ(DPLL_MD(pipe)); + if (pipe != PIPE_A) { + /* + * WaPixelRepeatModeFixForC0:chv + * + * DPLLCMD is AWOL. Use chicken bits to propagate + * the value from DPLLBMD to either pipe B or C. + */ + I915_WRITE(CBR4_VLV, pipe == PIPE_B ? CBR_DPLLBMD_PIPE_B : CBR_DPLLBMD_PIPE_C); + I915_WRITE(DPLL_MD(PIPE_B), pipe_config->dpll_hw_state.dpll_md); + I915_WRITE(CBR4_VLV, 0); + dev_priv->chv_dpll_md[pipe] = pipe_config->dpll_hw_state.dpll_md; + + /* + * DPLLB VGA mode also seems to cause problems. + * We should always have it disabled. + */ + WARN_ON((I915_READ(DPLL(PIPE_B)) & DPLL_VGA_MODE_DIS) == 0); + } else { + I915_WRITE(DPLL_MD(pipe), pipe_config->dpll_hw_state.dpll_md); + POSTING_READ(DPLL_MD(pipe)); + } } static int intel_num_dvo_pipes(struct drm_device *dev) @@ -8156,7 +8174,11 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, i9xx_get_pfit_config(crtc, pipe_config); if (INTEL_INFO(dev)->gen >= 4) { - tmp = I915_READ(DPLL_MD(crtc->pipe)); + /* No way to read it out on pipes B and C */ + if (IS_CHERRYVIEW(dev) && crtc->pipe != PIPE_A) + tmp = dev_priv->chv_dpll_md[crtc->pipe]; + else + tmp = I915_READ(DPLL_MD(crtc->pipe)); pipe_config->pixel_multiplier = ((tmp & DPLL_MD_UDI_MULTIPLIER_MASK) >> DPLL_MD_UDI_MULTIPLIER_SHIFT) + 1; -- cgit v1.2.3 From 8bd3f301ab6638d84f3e1c3c7e9ea2bf5b6880c2 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 15 Mar 2016 16:39:57 +0200 Subject: drm/i915: Add a local pipe variable to vlv_enable_pll() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoid redundant crtc->pipe lookups by giving vlv_enable_pll() a local pipe variable. Also makes it look more like the corresponding CHV code. While at is change the CHV code to enum pipe from int, Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1458052809-23426-5-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/intel_display.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3fdce859758a..6a95c31ac3fe 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1528,24 +1528,25 @@ static void vlv_enable_pll(struct intel_crtc *crtc, { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - i915_reg_t reg = DPLL(crtc->pipe); + enum pipe pipe = crtc->pipe; + i915_reg_t reg = DPLL(pipe); u32 dpll = pipe_config->dpll_hw_state.dpll; - assert_pipe_disabled(dev_priv, crtc->pipe); + assert_pipe_disabled(dev_priv, pipe); /* PLL is protected by panel, make sure we can write it */ if (IS_MOBILE(dev_priv->dev)) - assert_panel_unlocked(dev_priv, crtc->pipe); + assert_panel_unlocked(dev_priv, pipe); I915_WRITE(reg, dpll); POSTING_READ(reg); udelay(150); if (wait_for(((I915_READ(reg) & DPLL_LOCK_VLV) == DPLL_LOCK_VLV), 1)) - DRM_ERROR("DPLL %d failed to lock\n", crtc->pipe); + DRM_ERROR("DPLL %d failed to lock\n", pipe); - I915_WRITE(DPLL_MD(crtc->pipe), pipe_config->dpll_hw_state.dpll_md); - POSTING_READ(DPLL_MD(crtc->pipe)); + I915_WRITE(DPLL_MD(pipe), pipe_config->dpll_hw_state.dpll_md); + POSTING_READ(DPLL_MD(pipe)); /* We do this three times for luck */ I915_WRITE(reg, dpll); @@ -1564,11 +1565,11 @@ static void chv_enable_pll(struct intel_crtc *crtc, { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - int pipe = crtc->pipe; + enum pipe pipe = crtc->pipe; enum dpio_channel port = vlv_pipe_to_channel(pipe); u32 tmp; - assert_pipe_disabled(dev_priv, crtc->pipe); + assert_pipe_disabled(dev_priv, pipe); mutex_lock(&dev_priv->sb_lock); -- cgit v1.2.3 From 7d1a83cb68172a225c45243e955d9ee41eada8e9 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 15 Mar 2016 16:39:58 +0200 Subject: drm/i915: assert_panel_unlocked() in chv_enable_pll() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Supposedly the power sequencer still locks out the DPLL registers on CHV, so let's issue a warning if it's still locked when enabling the DPLL. Also drop the redundant IS_MOBILE() check for VLV when we check the same thing. Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1458052809-23426-6-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/intel_display.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 6a95c31ac3fe..4fbff487cf2b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1535,8 +1535,7 @@ static void vlv_enable_pll(struct intel_crtc *crtc, assert_pipe_disabled(dev_priv, pipe); /* PLL is protected by panel, make sure we can write it */ - if (IS_MOBILE(dev_priv->dev)) - assert_panel_unlocked(dev_priv, pipe); + assert_panel_unlocked(dev_priv, pipe); I915_WRITE(reg, dpll); POSTING_READ(reg); @@ -1571,6 +1570,9 @@ static void chv_enable_pll(struct intel_crtc *crtc, assert_pipe_disabled(dev_priv, pipe); + /* PLL is protected by panel, make sure we can write it */ + assert_panel_unlocked(dev_priv, pipe); + mutex_lock(&dev_priv->sb_lock); /* Enable back the 10bit clock to display controller */ -- cgit v1.2.3 From 5593946921834a63d89c595ef8459c50d30f5438 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 15 Mar 2016 16:39:59 +0200 Subject: drm/i915: Remove the "three times for luck" trick from vlv_enable_pll() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit VLV DPLL is somewhat sane and doesn't run on luck. Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1458052809-23426-7-git-send-email-ville.syrjala@linux.intel.com Acked-by: Jani Nikula --- drivers/gpu/drm/i915/intel_display.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 4fbff487cf2b..cf16bdbbda47 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1546,17 +1546,6 @@ static void vlv_enable_pll(struct intel_crtc *crtc, I915_WRITE(DPLL_MD(pipe), pipe_config->dpll_hw_state.dpll_md); POSTING_READ(DPLL_MD(pipe)); - - /* We do this three times for luck */ - I915_WRITE(reg, dpll); - POSTING_READ(reg); - udelay(150); /* wait for warmup */ - I915_WRITE(reg, dpll); - POSTING_READ(reg); - udelay(150); /* wait for warmup */ - I915_WRITE(reg, dpll); - POSTING_READ(reg); - udelay(150); /* wait for warmup */ } static void chv_enable_pll(struct intel_crtc *crtc, -- cgit v1.2.3 From fca0ce2a5caf6ae7d9d8510fb87ae6195b40057a Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 21 Mar 2016 14:43:22 +0000 Subject: drm/i915: Fix plane init failure paths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Deal with errors from drm_universal_plane_init() in primary and cursor plane init paths (sprites were already covered). Also make the code neater by using goto for error handling. v2: Rebased due to drm_universal_plane_init() 'name' parameter v3: Another rebase due to s/""/NULL/ v4: Rebased on drm-nightly (Matthew Auld) v5: Fix email address (Matthew Auld) Signed-off-by: Ville Syrjälä Reviewed-by: Matthew Auld Link: http://patchwork.freedesktop.org/patch/msgid/1458571402-32749-1-git-send-email-matthew.auld@intel.com --- drivers/gpu/drm/i915/intel_display.c | 64 ++++++++++++++++++++++-------------- drivers/gpu/drm/i915/intel_sprite.c | 34 +++++++++++-------- 2 files changed, 60 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index cf16bdbbda47..af74cdba7081 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13947,20 +13947,19 @@ const struct drm_plane_funcs intel_plane_funcs = { static struct drm_plane *intel_primary_plane_create(struct drm_device *dev, int pipe) { - struct intel_plane *primary; - struct intel_plane_state *state; + struct intel_plane *primary = NULL; + struct intel_plane_state *state = NULL; const uint32_t *intel_primary_formats; unsigned int num_formats; + int ret; primary = kzalloc(sizeof(*primary), GFP_KERNEL); - if (primary == NULL) - return NULL; + if (!primary) + goto fail; state = intel_create_plane_state(&primary->base); - if (!state) { - kfree(primary); - return NULL; - } + if (!state) + goto fail; primary->base.state = &state->base; primary->can_scale = false; @@ -14002,10 +14001,12 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev, primary->disable_plane = i9xx_disable_primary_plane; } - drm_universal_plane_init(dev, &primary->base, 0, - &intel_plane_funcs, - intel_primary_formats, num_formats, - DRM_PLANE_TYPE_PRIMARY, NULL); + ret = drm_universal_plane_init(dev, &primary->base, 0, + &intel_plane_funcs, + intel_primary_formats, num_formats, + DRM_PLANE_TYPE_PRIMARY, NULL); + if (ret) + goto fail; if (INTEL_INFO(dev)->gen >= 4) intel_create_rotation_property(dev, primary); @@ -14013,6 +14014,12 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev, drm_plane_helper_add(&primary->base, &intel_plane_helper_funcs); return &primary->base; + +fail: + kfree(state); + kfree(primary); + + return NULL; } void intel_create_rotation_property(struct drm_device *dev, struct intel_plane *plane) @@ -14129,18 +14136,17 @@ intel_update_cursor_plane(struct drm_plane *plane, static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev, int pipe) { - struct intel_plane *cursor; - struct intel_plane_state *state; + struct intel_plane *cursor = NULL; + struct intel_plane_state *state = NULL; + int ret; cursor = kzalloc(sizeof(*cursor), GFP_KERNEL); - if (cursor == NULL) - return NULL; + if (!cursor) + goto fail; state = intel_create_plane_state(&cursor->base); - if (!state) { - kfree(cursor); - return NULL; - } + if (!state) + goto fail; cursor->base.state = &state->base; cursor->can_scale = false; @@ -14152,11 +14158,13 @@ static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev, cursor->update_plane = intel_update_cursor_plane; cursor->disable_plane = intel_disable_cursor_plane; - drm_universal_plane_init(dev, &cursor->base, 0, - &intel_plane_funcs, - intel_cursor_formats, - ARRAY_SIZE(intel_cursor_formats), - DRM_PLANE_TYPE_CURSOR, NULL); + ret = drm_universal_plane_init(dev, &cursor->base, 0, + &intel_plane_funcs, + intel_cursor_formats, + ARRAY_SIZE(intel_cursor_formats), + DRM_PLANE_TYPE_CURSOR, NULL); + if (ret) + goto fail; if (INTEL_INFO(dev)->gen >= 4) { if (!dev->mode_config.rotation_property) @@ -14176,6 +14184,12 @@ static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev, drm_plane_helper_add(&cursor->base, &intel_plane_helper_funcs); return &cursor->base; + +fail: + kfree(state); + kfree(cursor); + + return NULL; } static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_crtc, diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 8821533561b1..0f3e2303e0e9 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -1025,8 +1025,8 @@ static uint32_t skl_plane_formats[] = { int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane) { - struct intel_plane *intel_plane; - struct intel_plane_state *state; + struct intel_plane *intel_plane = NULL; + struct intel_plane_state *state = NULL; unsigned long possible_crtcs; const uint32_t *plane_formats; int num_plane_formats; @@ -1036,13 +1036,15 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane) return -ENODEV; intel_plane = kzalloc(sizeof(*intel_plane), GFP_KERNEL); - if (!intel_plane) - return -ENOMEM; + if (!intel_plane) { + ret = -ENOMEM; + goto fail; + } state = intel_create_plane_state(&intel_plane->base); if (!state) { - kfree(intel_plane); - return -ENOMEM; + ret = -ENOMEM; + goto fail; } intel_plane->base.state = &state->base; @@ -1097,28 +1099,34 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane) num_plane_formats = ARRAY_SIZE(skl_plane_formats); break; default: - kfree(intel_plane); - return -ENODEV; + MISSING_CASE(INTEL_INFO(dev)->gen); + ret = -ENODEV; + goto fail; } intel_plane->pipe = pipe; intel_plane->plane = plane; intel_plane->frontbuffer_bit = INTEL_FRONTBUFFER_SPRITE(pipe, plane); intel_plane->check_plane = intel_check_sprite_plane; + possible_crtcs = (1 << pipe); + ret = drm_universal_plane_init(dev, &intel_plane->base, possible_crtcs, &intel_plane_funcs, plane_formats, num_plane_formats, DRM_PLANE_TYPE_OVERLAY, NULL); - if (ret) { - kfree(intel_plane); - goto out; - } + if (ret) + goto fail; intel_create_rotation_property(dev, intel_plane); drm_plane_helper_add(&intel_plane->base, &intel_plane_helper_funcs); -out: + return 0; + +fail: + kfree(state); + kfree(intel_plane); + return ret; } -- cgit v1.2.3 From a454018505f2e875441603b18dbbb912d422f7d1 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Sun, 27 Mar 2016 11:26:13 +0200 Subject: clk: unconditionally recurse into clk/mvebu/ The drivers/clk/mvebu directory is only being built when CONFIG_PLAT_ORION=y. As we are going to support additional mvebu platforms in drivers/clk/mvebu, which don't have CONFIG_PLAT_ORION=y, we need to recurse into this directory regardless of the value of CONFIG_PLAT_ORION. Since all files in drivers/clk/mvebu/ are already conditionally compiled depending on various Kconfig options, we can recurse unconditionally into drivers/clk/mvebu without any other change. Signed-off-by: Thomas Petazzoni Signed-off-by: Stephen Boyd --- drivers/clk/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 46869d696e4d..f9ad66e60b48 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -61,7 +61,7 @@ obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/ ifeq ($(CONFIG_COMMON_CLK), y) obj-$(CONFIG_ARCH_MMP) += mmp/ endif -obj-$(CONFIG_PLAT_ORION) += mvebu/ +obj-y += mvebu/ obj-$(CONFIG_ARCH_MESON) += meson/ obj-$(CONFIG_ARCH_MXS) += mxs/ obj-$(CONFIG_MACH_PISTACHIO) += pistachio/ -- cgit v1.2.3 From 91307cbeca7fd372342aaea7e814a19156ee8e64 Mon Sep 17 00:00:00 2001 From: Slawomir Stepien Date: Thu, 24 Mar 2016 17:06:01 +0100 Subject: iio: potentiometer: mcp4531: use pointer to access model parameters Use const pointer to element from model configuration array rather then array index, as it will not change anyway. Signed-off-by: Slawomir Stepien Signed-off-by: Peter Rosin Signed-off-by: Jonathan Cameron --- drivers/iio/potentiometer/mcp4531.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/potentiometer/mcp4531.c b/drivers/iio/potentiometer/mcp4531.c index 0db67fe14766..3b72e1a595db 100644 --- a/drivers/iio/potentiometer/mcp4531.c +++ b/drivers/iio/potentiometer/mcp4531.c @@ -79,7 +79,7 @@ static const struct mcp4531_cfg mcp4531_cfg[] = { struct mcp4531_data { struct i2c_client *client; - unsigned long devid; + const struct mcp4531_cfg *cfg; }; #define MCP4531_CHANNEL(ch) { \ @@ -113,8 +113,8 @@ static int mcp4531_read_raw(struct iio_dev *indio_dev, *val = ret; return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: - *val = 1000 * mcp4531_cfg[data->devid].kohms; - *val2 = mcp4531_cfg[data->devid].max_pos; + *val = 1000 * data->cfg->kohms; + *val2 = data->cfg->max_pos; return IIO_VAL_FRACTIONAL; } @@ -130,7 +130,7 @@ static int mcp4531_write_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - if (val > mcp4531_cfg[data->devid].max_pos || val < 0) + if (val > data->cfg->max_pos || val < 0) return -EINVAL; break; default: @@ -152,7 +152,6 @@ static int mcp4531_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct device *dev = &client->dev; - unsigned long devid = id->driver_data; struct mcp4531_data *data; struct iio_dev *indio_dev; @@ -168,12 +167,12 @@ static int mcp4531_probe(struct i2c_client *client, data = iio_priv(indio_dev); i2c_set_clientdata(client, indio_dev); data->client = client; - data->devid = devid; + data->cfg = &mcp4531_cfg[id->driver_data]; indio_dev->dev.parent = dev; indio_dev->info = &mcp4531_info; indio_dev->channels = mcp4531_channels; - indio_dev->num_channels = mcp4531_cfg[devid].wipers; + indio_dev->num_channels = data->cfg->wipers; indio_dev->name = client->name; return devm_iio_device_register(dev, indio_dev); -- cgit v1.2.3 From 23e758b36898d5ff6cc0cd2e54c498b24a15b0dd Mon Sep 17 00:00:00 2001 From: Irina Tirdea Date: Thu, 24 Mar 2016 11:29:26 +0200 Subject: iio: accel: bmc150: use available_scan_masks Use available_scan_masks to allow the iio core to select the data to send to userspace depending on which axes are enabled, instead of doing this in the driver's interrupt handler. Signed-off-by: Irina Tirdea Signed-off-by: Jonathan Cameron --- drivers/iio/accel/bmc150-accel-core.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c index c73331f7782b..cc52366ad4ad 100644 --- a/drivers/iio/accel/bmc150-accel-core.c +++ b/drivers/iio/accel/bmc150-accel-core.c @@ -138,6 +138,7 @@ enum bmc150_accel_axis { AXIS_X, AXIS_Y, AXIS_Z, + AXIS_MAX, }; enum bmc150_power_modes { @@ -1104,6 +1105,10 @@ static const struct iio_info bmc150_accel_info_fifo = { .driver_module = THIS_MODULE, }; +static const unsigned long bmc150_accel_scan_masks[] = { + BIT(AXIS_X) | BIT(AXIS_Y) | BIT(AXIS_Z), + 0}; + static irqreturn_t bmc150_accel_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; @@ -1113,8 +1118,7 @@ static irqreturn_t bmc150_accel_trigger_handler(int irq, void *p) unsigned int raw_val; mutex_lock(&data->mutex); - for_each_set_bit(bit, indio_dev->active_scan_mask, - indio_dev->masklength) { + for (bit = 0; bit < AXIS_MAX; bit++) { ret = regmap_bulk_read(data->regmap, BMC150_ACCEL_AXIS_TO_REG(bit), &raw_val, 2); @@ -1574,6 +1578,7 @@ int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq, indio_dev->channels = data->chip_info->channels; indio_dev->num_channels = data->chip_info->num_channels; indio_dev->name = name ? name : data->chip_info->name; + indio_dev->available_scan_masks = bmc150_accel_scan_masks; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->info = &bmc150_accel_info; -- cgit v1.2.3 From 1715e0ccd3b8cd4c1ee76076e1e7452b113be193 Mon Sep 17 00:00:00 2001 From: Irina Tirdea Date: Thu, 24 Mar 2016 11:29:27 +0200 Subject: iio: accel: bmc150: optimize transfers in trigger handler Some i2c busses (e.g.: Synopsys DesignWare I2C adapter) need to enable/disable the bus at each i2c transfer and must wait for the enable/disable to happen before sending the data. When reading data in the trigger handler, the bmc150 accel driver does one bus transfer for each axis. This has an impact on the frequency of the accelerometer at high sample rates due to additional delays introduced by the bus at each transfer. Reading all axis values in one bus transfer reduces the delays introduced by the bus. Signed-off-by: Irina Tirdea Signed-off-by: Jonathan Cameron --- drivers/iio/accel/bmc150-accel-core.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c index cc52366ad4ad..58df97df562b 100644 --- a/drivers/iio/accel/bmc150-accel-core.c +++ b/drivers/iio/accel/bmc150-accel-core.c @@ -989,6 +989,7 @@ static const struct iio_event_spec bmc150_accel_event = { .realbits = (bits), \ .storagebits = 16, \ .shift = 16 - (bits), \ + .endianness = IIO_LE, \ }, \ .event_spec = &bmc150_accel_event, \ .num_event_specs = 1 \ @@ -1114,21 +1115,14 @@ static irqreturn_t bmc150_accel_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct bmc150_accel_data *data = iio_priv(indio_dev); - int bit, ret, i = 0; - unsigned int raw_val; + int ret; mutex_lock(&data->mutex); - for (bit = 0; bit < AXIS_MAX; bit++) { - ret = regmap_bulk_read(data->regmap, - BMC150_ACCEL_AXIS_TO_REG(bit), &raw_val, - 2); - if (ret < 0) { - mutex_unlock(&data->mutex); - goto err_read; - } - data->buffer[i++] = raw_val; - } + ret = regmap_bulk_read(data->regmap, BMC150_ACCEL_REG_XOUT_L, + data->buffer, AXIS_MAX * 2); mutex_unlock(&data->mutex); + if (ret < 0) + goto err_read; iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, pf->timestamp); -- cgit v1.2.3 From ee8c5419e06e3a002995f5d1f57c9b5aead331e6 Mon Sep 17 00:00:00 2001 From: Irina Tirdea Date: Thu, 24 Mar 2016 11:29:28 +0200 Subject: iio: gyro: bmg160: use available_scan_masks Use available_scan_masks to allow the iio core to select the data to send to userspace depending on which axes are enabled, instead of doing this in the driver's interrupt handler. Signed-off-by: Irina Tirdea Signed-off-by: Jonathan Cameron --- drivers/iio/gyro/bmg160_core.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c index bbce3b09ac45..8d6e5b132016 100644 --- a/drivers/iio/gyro/bmg160_core.c +++ b/drivers/iio/gyro/bmg160_core.c @@ -116,6 +116,7 @@ enum bmg160_axis { AXIS_X, AXIS_Y, AXIS_Z, + AXIS_MAX, }; static const struct { @@ -763,6 +764,10 @@ static const struct iio_info bmg160_info = { .driver_module = THIS_MODULE, }; +static const unsigned long bmg160_accel_scan_masks[] = { + BIT(AXIS_X) | BIT(AXIS_Y) | BIT(AXIS_Z), + 0}; + static irqreturn_t bmg160_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; @@ -772,8 +777,7 @@ static irqreturn_t bmg160_trigger_handler(int irq, void *p) unsigned int val; mutex_lock(&data->mutex); - for_each_set_bit(bit, indio_dev->active_scan_mask, - indio_dev->masklength) { + for (bit = 0; bit < AXIS_MAX; bit++) { ret = regmap_bulk_read(data->regmap, BMG160_AXIS_TO_REG(bit), &val, 2); if (ret < 0) { @@ -1019,6 +1023,7 @@ int bmg160_core_probe(struct device *dev, struct regmap *regmap, int irq, indio_dev->channels = bmg160_channels; indio_dev->num_channels = ARRAY_SIZE(bmg160_channels); indio_dev->name = name; + indio_dev->available_scan_masks = bmg160_accel_scan_masks; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->info = &bmg160_info; -- cgit v1.2.3 From 7e3d1eb123d804d2b1088782f458aed5eb36c684 Mon Sep 17 00:00:00 2001 From: Irina Tirdea Date: Thu, 24 Mar 2016 11:29:29 +0200 Subject: iio: accel: bmg160: optimize transfers in trigger handler Some i2c busses (e.g.: Synopsys DesignWare I2C adapter) need to enable/disable the bus at each i2c transfer and must wait for the enable/disable to happen before sending the data. When reading data in the trigger handler, the bmg160 gyro driver does one bus transfer for each axis. This has an impact on the frequency of the accelerometer at high sample rates due to additional delays introduced by the bus at each transfer. Reading all axis values in one bus transfer reduces the delays introduced by the bus. Signed-off-by: Irina Tirdea Signed-off-by: Jonathan Cameron --- drivers/iio/gyro/bmg160_core.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c index 8d6e5b132016..43570b8f686d 100644 --- a/drivers/iio/gyro/bmg160_core.c +++ b/drivers/iio/gyro/bmg160_core.c @@ -734,6 +734,7 @@ static const struct iio_event_spec bmg160_event = { .sign = 's', \ .realbits = 16, \ .storagebits = 16, \ + .endianness = IIO_LE, \ }, \ .event_spec = &bmg160_event, \ .num_event_specs = 1 \ @@ -773,20 +774,14 @@ static irqreturn_t bmg160_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct bmg160_data *data = iio_priv(indio_dev); - int bit, ret, i = 0; - unsigned int val; + int ret; mutex_lock(&data->mutex); - for (bit = 0; bit < AXIS_MAX; bit++) { - ret = regmap_bulk_read(data->regmap, BMG160_AXIS_TO_REG(bit), - &val, 2); - if (ret < 0) { - mutex_unlock(&data->mutex); - goto err; - } - data->buffer[i++] = ret; - } + ret = regmap_bulk_read(data->regmap, BMG160_REG_XOUT_L, + data->buffer, AXIS_MAX * 2); mutex_unlock(&data->mutex); + if (ret < 0) + goto err; iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, pf->timestamp); -- cgit v1.2.3 From 09cf1b321ad353eeaeddcfd33771b34ce2a61640 Mon Sep 17 00:00:00 2001 From: Adriana Reus Date: Thu, 24 Mar 2016 11:29:30 +0200 Subject: iio: accel: kxcjk-1013: use available_scan_masks Use available_scan_masks to allow the iio core to select the data to send to userspace depending on which axes are enabled, instead of doing this in the driver's interrupt handler. Signed-off-by: Adriana Reus Signed-off-by: Irina Tirdea Acked-by: Srinivas Pandruvada Signed-off-by: Jonathan Cameron --- drivers/iio/accel/kxcjk-1013.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c index edec1d099e91..3861fe99e8ea 100644 --- a/drivers/iio/accel/kxcjk-1013.c +++ b/drivers/iio/accel/kxcjk-1013.c @@ -115,6 +115,7 @@ enum kxcjk1013_axis { AXIS_X, AXIS_Y, AXIS_Z, + AXIS_MAX, }; enum kxcjk1013_mode { @@ -953,6 +954,8 @@ static const struct iio_info kxcjk1013_info = { .driver_module = THIS_MODULE, }; +static const unsigned long kxcjk1013_scan_masks[] = {0x7, 0}; + static irqreturn_t kxcjk1013_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; @@ -962,8 +965,7 @@ static irqreturn_t kxcjk1013_trigger_handler(int irq, void *p) mutex_lock(&data->mutex); - for_each_set_bit(bit, indio_dev->active_scan_mask, - indio_dev->masklength) { + for (bit = 0; bit < AXIS_MAX; bit++) { ret = kxcjk1013_get_acc_reg(data, bit); if (ret < 0) { mutex_unlock(&data->mutex); @@ -1204,6 +1206,7 @@ static int kxcjk1013_probe(struct i2c_client *client, indio_dev->dev.parent = &client->dev; indio_dev->channels = kxcjk1013_channels; indio_dev->num_channels = ARRAY_SIZE(kxcjk1013_channels); + indio_dev->available_scan_masks = kxcjk1013_scan_masks; indio_dev->name = name; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->info = &kxcjk1013_info; -- cgit v1.2.3 From 65ae47b0ec535a008e53578abc11082f3b742f75 Mon Sep 17 00:00:00 2001 From: Adriana Reus Date: Thu, 24 Mar 2016 11:29:31 +0200 Subject: iio: accel: kxcjk-1013: optimize i2c transfers in trigger handler Some i2c busses (e.g.: Synopsys DesignWare I2C adapter) need to enable/disable the bus at each i2c transfer and must wait for the enable/disable to happen before sending the data. When reading data in the trigger handler, the kxcjk-1013 accel driver does one i2c transfer for each axis. This has an impact on the frequency of the accelerometer at high sample rates due to additional delays introduced by the i2c bus at each transfer. Reading all axis values in one i2c transfer reduces the delays introduced by the i2c bus. Uses i2c_smbus_read_i2c_block_data_or_emulated that will fallback to reading each axis as a separate word in case i2c block read is not supported. Signed-off-by: Adriana Reus Signed-off-by: Irina Tirdea Acked-by: Jonathan Cameron Acked-by: Srinivas Pandruvada Signed-off-by: Jonathan Cameron --- drivers/iio/accel/kxcjk-1013.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c index 3861fe99e8ea..488185684c40 100644 --- a/drivers/iio/accel/kxcjk-1013.c +++ b/drivers/iio/accel/kxcjk-1013.c @@ -923,7 +923,7 @@ static const struct iio_event_spec kxcjk1013_event = { .realbits = 12, \ .storagebits = 16, \ .shift = 4, \ - .endianness = IIO_CPU, \ + .endianness = IIO_LE, \ }, \ .event_spec = &kxcjk1013_event, \ .num_event_specs = 1 \ @@ -961,19 +961,16 @@ static irqreturn_t kxcjk1013_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct kxcjk1013_data *data = iio_priv(indio_dev); - int bit, ret, i = 0; + int ret; mutex_lock(&data->mutex); - - for (bit = 0; bit < AXIS_MAX; bit++) { - ret = kxcjk1013_get_acc_reg(data, bit); - if (ret < 0) { - mutex_unlock(&data->mutex); - goto err; - } - data->buffer[i++] = ret; - } + ret = i2c_smbus_read_i2c_block_data_or_emulated(data->client, + KXCJK1013_REG_XOUT_L, + AXIS_MAX * 2, + (u8 *)data->buffer); mutex_unlock(&data->mutex); + if (ret < 0) + goto err; iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, data->timestamp); -- cgit v1.2.3 From b1532909decca12e0527473870cec1d57677f916 Mon Sep 17 00:00:00 2001 From: Irina Tirdea Date: Thu, 24 Mar 2016 11:08:38 +0200 Subject: iio: remove unused gpio consumer.h include GPIO handling code has been removed from the drivers (since this is now handled by the ACPI core) in commit 0f0796509c07 ("iio: remove gpio interrupt probing from drivers that use a single interrupt"). Remove the include for linux/gpio/consumer.h since it is no longer used. Signed-off-by: Irina Tirdea Signed-off-by: Jonathan Cameron --- drivers/iio/accel/bmc150-accel-core.c | 1 - drivers/iio/accel/kxcjk-1013.c | 1 - drivers/iio/accel/mma9553.c | 1 - drivers/iio/accel/stk8312.c | 1 - drivers/iio/accel/stk8ba50.c | 1 - drivers/iio/imu/kmx61.c | 1 - drivers/iio/light/stk3310.c | 1 - drivers/iio/magnetometer/bmc150_magn.c | 1 - 8 files changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c index 58df97df562b..f3d096f3c539 100644 --- a/drivers/iio/accel/bmc150-accel-core.c +++ b/drivers/iio/accel/bmc150-accel-core.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c index 488185684c40..bfe219a8bea2 100644 --- a/drivers/iio/accel/kxcjk-1013.c +++ b/drivers/iio/accel/kxcjk-1013.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/iio/accel/mma9553.c b/drivers/iio/accel/mma9553.c index fa7d36217c4b..bb05f3efddca 100644 --- a/drivers/iio/accel/mma9553.c +++ b/drivers/iio/accel/mma9553.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/iio/accel/stk8312.c b/drivers/iio/accel/stk8312.c index 85fe7f7247c1..e31023dc5f1b 100644 --- a/drivers/iio/accel/stk8312.c +++ b/drivers/iio/accel/stk8312.c @@ -11,7 +11,6 @@ */ #include -#include #include #include #include diff --git a/drivers/iio/accel/stk8ba50.c b/drivers/iio/accel/stk8ba50.c index 5709d9eb8f34..300d955bad00 100644 --- a/drivers/iio/accel/stk8ba50.c +++ b/drivers/iio/accel/stk8ba50.c @@ -11,7 +11,6 @@ */ #include -#include #include #include #include diff --git a/drivers/iio/imu/kmx61.c b/drivers/iio/imu/kmx61.c index e5306b4e020e..2e7dd5754a56 100644 --- a/drivers/iio/imu/kmx61.c +++ b/drivers/iio/imu/kmx61.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/iio/light/stk3310.c b/drivers/iio/light/stk3310.c index 42d334ba612e..9e847f8f4f0c 100644 --- a/drivers/iio/light/stk3310.c +++ b/drivers/iio/light/stk3310.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/iio/magnetometer/bmc150_magn.c b/drivers/iio/magnetometer/bmc150_magn.c index ffcb75ea64fb..0e9da189dc4c 100644 --- a/drivers/iio/magnetometer/bmc150_magn.c +++ b/drivers/iio/magnetometer/bmc150_magn.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3 From fb12b6c725a3936bedaa7fac87432f0ad0d01599 Mon Sep 17 00:00:00 2001 From: Irina Tirdea Date: Thu, 24 Mar 2016 11:05:09 +0200 Subject: iio: remove gpio interrupt probing from drivers that use a single interrupt Commit 845c877009cf014b ("i2c / ACPI: Assign IRQ for devices that have GpioInt automatically") automatically assigns the first ACPI GPIO interrupt in client->irq, so we can remove the probing code from drivers that use only one interrupt. Commit 0f0796509c07c1c7 ("iio: remove gpio interrupt probing from drivers that use a single interrupt") removes gpio interrupt probing from most drivers. This patch cleans the remaining ones. Signed-off-by: Irina Tirdea Signed-off-by: Jonathan Cameron --- drivers/iio/accel/mxc4005.c | 29 ----------------------------- drivers/iio/gyro/bmg160_core.c | 28 ---------------------------- 2 files changed, 57 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/accel/mxc4005.c b/drivers/iio/accel/mxc4005.c index e72e218c2696..c23f47af7256 100644 --- a/drivers/iio/accel/mxc4005.c +++ b/drivers/iio/accel/mxc4005.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -380,31 +379,6 @@ static const struct iio_trigger_ops mxc4005_trigger_ops = { .owner = THIS_MODULE, }; -static int mxc4005_gpio_probe(struct i2c_client *client, - struct mxc4005_data *data) -{ - struct device *dev; - struct gpio_desc *gpio; - int ret; - - if (!client) - return -EINVAL; - - dev = &client->dev; - - gpio = devm_gpiod_get_index(dev, "mxc4005_int", 0, GPIOD_IN); - if (IS_ERR(gpio)) { - dev_err(dev, "failed to get acpi gpio index\n"); - return PTR_ERR(gpio); - } - - ret = gpiod_to_irq(gpio); - - dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret); - - return ret; -} - static int mxc4005_chip_init(struct mxc4005_data *data) { int ret; @@ -470,9 +444,6 @@ static int mxc4005_probe(struct i2c_client *client, return ret; } - if (client->irq < 0) - client->irq = mxc4005_gpio_probe(client, data); - if (client->irq > 0) { data->dready_trig = devm_iio_trigger_alloc(&client->dev, "%s-dev%d", diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c index 43570b8f686d..2493bb17a03d 100644 --- a/drivers/iio/gyro/bmg160_core.c +++ b/drivers/iio/gyro/bmg160_core.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -31,7 +30,6 @@ #include "bmg160.h" #define BMG160_IRQ_NAME "bmg160_event" -#define BMG160_GPIO_NAME "gpio_int" #define BMG160_REG_CHIP_ID 0x00 #define BMG160_CHIP_ID_VAL 0x0F @@ -954,29 +952,6 @@ static const struct iio_buffer_setup_ops bmg160_buffer_setup_ops = { .postdisable = bmg160_buffer_postdisable, }; -static int bmg160_gpio_probe(struct bmg160_data *data) - -{ - struct device *dev; - struct gpio_desc *gpio; - - dev = data->dev; - - /* data ready gpio interrupt pin */ - gpio = devm_gpiod_get_index(dev, BMG160_GPIO_NAME, 0, GPIOD_IN); - if (IS_ERR(gpio)) { - dev_err(dev, "acpi gpio get index failed\n"); - return PTR_ERR(gpio); - } - - data->irq = gpiod_to_irq(gpio); - - dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), - data->irq); - - return 0; -} - static const char *bmg160_match_acpi_device(struct device *dev) { const struct acpi_device_id *id; @@ -1022,9 +997,6 @@ int bmg160_core_probe(struct device *dev, struct regmap *regmap, int irq, indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->info = &bmg160_info; - if (data->irq <= 0) - bmg160_gpio_probe(data); - if (data->irq > 0) { ret = devm_request_threaded_irq(dev, data->irq, -- cgit v1.2.3 From 6154a108faafe5f7fe08cee933b899b013b457d9 Mon Sep 17 00:00:00 2001 From: Ksenija Stanojevic Date: Wed, 23 Mar 2016 12:06:34 +0100 Subject: Staging: iio: ad7606: Fix sparse endian warning Fix following sparse warning: warning: cast to restricted __be16 Signed-off-by: Ksenija Stanojevic Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/ad7606_spi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/adc/ad7606_spi.c b/drivers/staging/iio/adc/ad7606_spi.c index d873a5164595..825da0769936 100644 --- a/drivers/staging/iio/adc/ad7606_spi.c +++ b/drivers/staging/iio/adc/ad7606_spi.c @@ -21,7 +21,8 @@ static int ad7606_spi_read_block(struct device *dev, { struct spi_device *spi = to_spi_device(dev); int i, ret; - unsigned short *data = buf; + unsigned short *data; + __be16 *bdata = buf; ret = spi_read(spi, buf, count * 2); if (ret < 0) { @@ -30,7 +31,7 @@ static int ad7606_spi_read_block(struct device *dev, } for (i = 0; i < count; i++) - data[i] = be16_to_cpu(data[i]); + data[i] = be16_to_cpu(bdata[i]); return 0; } -- cgit v1.2.3 From 22d199a53910e2b1666bf873f10779a66844c126 Mon Sep 17 00:00:00 2001 From: Slawomir Stepien Date: Wed, 23 Mar 2016 09:57:20 +0100 Subject: iio: potentiometer: add driver for Microchip MCP413X/414X/415X/416X/423X/424X/425X/426X The following functionalities are supported: - write, read from volatile memory Datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/22060b.pdf Signed-off-by: Slawomir Stepien Reviewed-by: Joachim Eastwood Signed-off-by: Jonathan Cameron --- .../bindings/iio/potentiometer/mcp4131.txt | 84 ++++ drivers/iio/potentiometer/Kconfig | 18 + drivers/iio/potentiometer/Makefile | 1 + drivers/iio/potentiometer/mcp4131.c | 494 +++++++++++++++++++++ 4 files changed, 597 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/potentiometer/mcp4131.txt create mode 100644 drivers/iio/potentiometer/mcp4131.c (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/iio/potentiometer/mcp4131.txt b/Documentation/devicetree/bindings/iio/potentiometer/mcp4131.txt new file mode 100644 index 000000000000..3ccba16f7035 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/potentiometer/mcp4131.txt @@ -0,0 +1,84 @@ +* Microchip MCP413X/414X/415X/416X/423X/424X/425X/426X Digital Potentiometer + driver + +The node for this driver must be a child node of a SPI controller, hence +all mandatory properties described in + + Documentation/devicetree/bindings/spi/spi-bus.txt + +must be specified. + +Required properties: + - compatible: Must be one of the following, depending on the + model: + "microchip,mcp4131-502" + "microchip,mcp4131-103" + "microchip,mcp4131-503" + "microchip,mcp4131-104" + "microchip,mcp4132-502" + "microchip,mcp4132-103" + "microchip,mcp4132-503" + "microchip,mcp4132-104" + "microchip,mcp4141-502" + "microchip,mcp4141-103" + "microchip,mcp4141-503" + "microchip,mcp4141-104" + "microchip,mcp4142-502" + "microchip,mcp4142-103" + "microchip,mcp4142-503" + "microchip,mcp4142-104" + "microchip,mcp4151-502" + "microchip,mcp4151-103" + "microchip,mcp4151-503" + "microchip,mcp4151-104" + "microchip,mcp4152-502" + "microchip,mcp4152-103" + "microchip,mcp4152-503" + "microchip,mcp4152-104" + "microchip,mcp4161-502" + "microchip,mcp4161-103" + "microchip,mcp4161-503" + "microchip,mcp4161-104" + "microchip,mcp4162-502" + "microchip,mcp4162-103" + "microchip,mcp4162-503" + "microchip,mcp4162-104" + "microchip,mcp4231-502" + "microchip,mcp4231-103" + "microchip,mcp4231-503" + "microchip,mcp4231-104" + "microchip,mcp4232-502" + "microchip,mcp4232-103" + "microchip,mcp4232-503" + "microchip,mcp4232-104" + "microchip,mcp4241-502" + "microchip,mcp4241-103" + "microchip,mcp4241-503" + "microchip,mcp4241-104" + "microchip,mcp4242-502" + "microchip,mcp4242-103" + "microchip,mcp4242-503" + "microchip,mcp4242-104" + "microchip,mcp4251-502" + "microchip,mcp4251-103" + "microchip,mcp4251-503" + "microchip,mcp4251-104" + "microchip,mcp4252-502" + "microchip,mcp4252-103" + "microchip,mcp4252-503" + "microchip,mcp4252-104" + "microchip,mcp4261-502" + "microchip,mcp4261-103" + "microchip,mcp4261-503" + "microchip,mcp4261-104" + "microchip,mcp4262-502" + "microchip,mcp4262-103" + "microchip,mcp4262-503" + "microchip,mcp4262-104" + +Example: +mcp4131: mcp4131@0 { + compatible = "mcp4131-502"; + reg = <0>; + spi-max-frequency = <500000>; +}; diff --git a/drivers/iio/potentiometer/Kconfig b/drivers/iio/potentiometer/Kconfig index ffc735c168fb..7ea069bbca2d 100644 --- a/drivers/iio/potentiometer/Kconfig +++ b/drivers/iio/potentiometer/Kconfig @@ -5,6 +5,24 @@ menu "Digital potentiometers" +config MCP4131 + tristate "Microchip MCP413X/414X/415X/416X/423X/424X/425X/426X Digital Potentiometer driver" + depends on SPI + help + Say yes here to build support for the Microchip + MCP4131, MCP4132, + MCP4141, MCP4142, + MCP4151, MCP4152, + MCP4161, MCP4162, + MCP4231, MCP4232, + MCP4241, MCP4242, + MCP4251, MCP4252, + MCP4261, MCP4262, + digital potentiomenter chips. + + To compile this driver as a module, choose M here: the + module will be called mcp4131. + config MCP4531 tristate "Microchip MCP45xx/MCP46xx Digital Potentiometer driver" depends on I2C diff --git a/drivers/iio/potentiometer/Makefile b/drivers/iio/potentiometer/Makefile index b563b492b486..91a80f8db24d 100644 --- a/drivers/iio/potentiometer/Makefile +++ b/drivers/iio/potentiometer/Makefile @@ -3,5 +3,6 @@ # # When adding new entries keep the list in alphabetical order +obj-$(CONFIG_MCP4131) += mcp4131.o obj-$(CONFIG_MCP4531) += mcp4531.o obj-$(CONFIG_TPL0102) += tpl0102.o diff --git a/drivers/iio/potentiometer/mcp4131.c b/drivers/iio/potentiometer/mcp4131.c new file mode 100644 index 000000000000..4e7e2c6c522c --- /dev/null +++ b/drivers/iio/potentiometer/mcp4131.c @@ -0,0 +1,494 @@ +/* + * Industrial I/O driver for Microchip digital potentiometers + * + * Copyright (c) 2016 Slawomir Stepien + * Based on: Peter Rosin's code from mcp4531.c + * + * Datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/22060b.pdf + * + * DEVID #Wipers #Positions Resistor Opts (kOhm) + * mcp4131 1 129 5, 10, 50, 100 + * mcp4132 1 129 5, 10, 50, 100 + * mcp4141 1 129 5, 10, 50, 100 + * mcp4142 1 129 5, 10, 50, 100 + * mcp4151 1 257 5, 10, 50, 100 + * mcp4152 1 257 5, 10, 50, 100 + * mcp4161 1 257 5, 10, 50, 100 + * mcp4162 1 257 5, 10, 50, 100 + * mcp4231 2 129 5, 10, 50, 100 + * mcp4232 2 129 5, 10, 50, 100 + * mcp4241 2 129 5, 10, 50, 100 + * mcp4242 2 129 5, 10, 50, 100 + * mcp4251 2 257 5, 10, 50, 100 + * mcp4252 2 257 5, 10, 50, 100 + * mcp4261 2 257 5, 10, 50, 100 + * mcp4262 2 257 5, 10, 50, 100 + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +/* + * TODO: + * 1. Write wiper setting to EEPROM for EEPROM capable models. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MCP4131_WRITE (0x00 << 2) +#define MCP4131_READ (0x03 << 2) + +#define MCP4131_WIPER_SHIFT 4 +#define MCP4131_CMDERR(r) ((r[0]) & 0x02) +#define MCP4131_RAW(r) ((r[0]) == 0xff ? 0x100 : (r[1])) + +struct mcp4131_cfg { + int wipers; + int max_pos; + int kohms; +}; + +enum mcp4131_type { + MCP413x_502 = 0, + MCP413x_103, + MCP413x_503, + MCP413x_104, + MCP414x_502, + MCP414x_103, + MCP414x_503, + MCP414x_104, + MCP415x_502, + MCP415x_103, + MCP415x_503, + MCP415x_104, + MCP416x_502, + MCP416x_103, + MCP416x_503, + MCP416x_104, + MCP423x_502, + MCP423x_103, + MCP423x_503, + MCP423x_104, + MCP424x_502, + MCP424x_103, + MCP424x_503, + MCP424x_104, + MCP425x_502, + MCP425x_103, + MCP425x_503, + MCP425x_104, + MCP426x_502, + MCP426x_103, + MCP426x_503, + MCP426x_104, +}; + +static const struct mcp4131_cfg mcp4131_cfg[] = { + [MCP413x_502] = { .wipers = 1, .max_pos = 128, .kohms = 5, }, + [MCP413x_103] = { .wipers = 1, .max_pos = 128, .kohms = 10, }, + [MCP413x_503] = { .wipers = 1, .max_pos = 128, .kohms = 50, }, + [MCP413x_104] = { .wipers = 1, .max_pos = 128, .kohms = 100, }, + [MCP414x_502] = { .wipers = 1, .max_pos = 128, .kohms = 5, }, + [MCP414x_103] = { .wipers = 1, .max_pos = 128, .kohms = 10, }, + [MCP414x_503] = { .wipers = 1, .max_pos = 128, .kohms = 50, }, + [MCP414x_104] = { .wipers = 1, .max_pos = 128, .kohms = 100, }, + [MCP415x_502] = { .wipers = 1, .max_pos = 256, .kohms = 5, }, + [MCP415x_103] = { .wipers = 1, .max_pos = 256, .kohms = 10, }, + [MCP415x_503] = { .wipers = 1, .max_pos = 256, .kohms = 50, }, + [MCP415x_104] = { .wipers = 1, .max_pos = 256, .kohms = 100, }, + [MCP416x_502] = { .wipers = 1, .max_pos = 256, .kohms = 5, }, + [MCP416x_103] = { .wipers = 1, .max_pos = 256, .kohms = 10, }, + [MCP416x_503] = { .wipers = 1, .max_pos = 256, .kohms = 50, }, + [MCP416x_104] = { .wipers = 1, .max_pos = 256, .kohms = 100, }, + [MCP423x_502] = { .wipers = 2, .max_pos = 128, .kohms = 5, }, + [MCP423x_103] = { .wipers = 2, .max_pos = 128, .kohms = 10, }, + [MCP423x_503] = { .wipers = 2, .max_pos = 128, .kohms = 50, }, + [MCP423x_104] = { .wipers = 2, .max_pos = 128, .kohms = 100, }, + [MCP424x_502] = { .wipers = 2, .max_pos = 128, .kohms = 5, }, + [MCP424x_103] = { .wipers = 2, .max_pos = 128, .kohms = 10, }, + [MCP424x_503] = { .wipers = 2, .max_pos = 128, .kohms = 50, }, + [MCP424x_104] = { .wipers = 2, .max_pos = 128, .kohms = 100, }, + [MCP425x_502] = { .wipers = 2, .max_pos = 256, .kohms = 5, }, + [MCP425x_103] = { .wipers = 2, .max_pos = 256, .kohms = 10, }, + [MCP425x_503] = { .wipers = 2, .max_pos = 256, .kohms = 50, }, + [MCP425x_104] = { .wipers = 2, .max_pos = 256, .kohms = 100, }, + [MCP426x_502] = { .wipers = 2, .max_pos = 256, .kohms = 5, }, + [MCP426x_103] = { .wipers = 2, .max_pos = 256, .kohms = 10, }, + [MCP426x_503] = { .wipers = 2, .max_pos = 256, .kohms = 50, }, + [MCP426x_104] = { .wipers = 2, .max_pos = 256, .kohms = 100, }, +}; + +struct mcp4131_data { + struct spi_device *spi; + const struct mcp4131_cfg *cfg; + struct mutex lock; + u8 buf[2] ____cacheline_aligned; +}; + +#define MCP4131_CHANNEL(ch) { \ + .type = IIO_RESISTANCE, \ + .indexed = 1, \ + .output = 1, \ + .channel = (ch), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ +} + +static const struct iio_chan_spec mcp4131_channels[] = { + MCP4131_CHANNEL(0), + MCP4131_CHANNEL(1), +}; + +static int mcp4131_read(struct spi_device *spi, void *buf, size_t len) +{ + struct spi_transfer t = { + .tx_buf = buf, /* We need to send addr, cmd and 12 bits */ + .rx_buf = buf, + .len = len, + }; + struct spi_message m; + + spi_message_init(&m); + spi_message_add_tail(&t, &m); + + return spi_sync(spi, &m); +} + +static int mcp4131_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + int err; + struct mcp4131_data *data = iio_priv(indio_dev); + int address = chan->channel; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + mutex_lock(&data->lock); + + data->buf[0] = (address << MCP4131_WIPER_SHIFT) | MCP4131_READ; + data->buf[1] = 0; + + err = mcp4131_read(data->spi, data->buf, 2); + if (err) { + mutex_unlock(&data->lock); + return err; + } + + /* Error, bad address/command combination */ + if (!MCP4131_CMDERR(data->buf)) { + mutex_unlock(&data->lock); + return -EIO; + } + + *val = MCP4131_RAW(data->buf); + mutex_unlock(&data->lock); + + return IIO_VAL_INT; + + case IIO_CHAN_INFO_SCALE: + *val = 1000 * data->cfg->kohms; + *val2 = data->cfg->max_pos; + return IIO_VAL_FRACTIONAL; + } + + return -EINVAL; +} + +static int mcp4131_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + int err; + struct mcp4131_data *data = iio_priv(indio_dev); + int address = chan->channel << MCP4131_WIPER_SHIFT; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + if (val > data->cfg->max_pos || val < 0) + return -EINVAL; + break; + + default: + return -EINVAL; + } + + mutex_lock(&data->lock); + + data->buf[0] = address << MCP4131_WIPER_SHIFT; + data->buf[0] |= MCP4131_WRITE | (val >> 8); + data->buf[1] = val & 0xFF; /* 8 bits here */ + + err = spi_write(data->spi, data->buf, 2); + mutex_unlock(&data->lock); + + return err; +} + +static const struct iio_info mcp4131_info = { + .read_raw = mcp4131_read_raw, + .write_raw = mcp4131_write_raw, + .driver_module = THIS_MODULE, +}; + +static int mcp4131_probe(struct spi_device *spi) +{ + int err; + struct device *dev = &spi->dev; + unsigned long devid = spi_get_device_id(spi)->driver_data; + struct mcp4131_data *data; + struct iio_dev *indio_dev; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + data = iio_priv(indio_dev); + spi_set_drvdata(spi, indio_dev); + data->spi = spi; + data->cfg = &mcp4131_cfg[devid]; + + mutex_init(&data->lock); + + indio_dev->dev.parent = dev; + indio_dev->info = &mcp4131_info; + indio_dev->channels = mcp4131_channels; + indio_dev->num_channels = data->cfg->wipers; + indio_dev->name = spi_get_device_id(spi)->name; + + err = devm_iio_device_register(dev, indio_dev); + if (err) { + dev_info(&spi->dev, "Unable to register %s\n", indio_dev->name); + return err; + } + + return 0; +} + +#if defined(CONFIG_OF) +static const struct of_device_id mcp4131_dt_ids[] = { + { .compatible = "microchip,mcp4131-502", + .data = &mcp4131_cfg[MCP413x_502] }, + { .compatible = "microchip,mcp4131-103", + .data = &mcp4131_cfg[MCP413x_103] }, + { .compatible = "microchip,mcp4131-503", + .data = &mcp4131_cfg[MCP413x_503] }, + { .compatible = "microchip,mcp4131-104", + .data = &mcp4131_cfg[MCP413x_104] }, + { .compatible = "microchip,mcp4132-502", + .data = &mcp4131_cfg[MCP413x_502] }, + { .compatible = "microchip,mcp4132-103", + .data = &mcp4131_cfg[MCP413x_103] }, + { .compatible = "microchip,mcp4132-503", + .data = &mcp4131_cfg[MCP413x_503] }, + { .compatible = "microchip,mcp4132-104", + .data = &mcp4131_cfg[MCP413x_104] }, + { .compatible = "microchip,mcp4141-502", + .data = &mcp4131_cfg[MCP414x_502] }, + { .compatible = "microchip,mcp4141-103", + .data = &mcp4131_cfg[MCP414x_103] }, + { .compatible = "microchip,mcp4141-503", + .data = &mcp4131_cfg[MCP414x_503] }, + { .compatible = "microchip,mcp4141-104", + .data = &mcp4131_cfg[MCP414x_104] }, + { .compatible = "microchip,mcp4142-502", + .data = &mcp4131_cfg[MCP414x_502] }, + { .compatible = "microchip,mcp4142-103", + .data = &mcp4131_cfg[MCP414x_103] }, + { .compatible = "microchip,mcp4142-503", + .data = &mcp4131_cfg[MCP414x_503] }, + { .compatible = "microchip,mcp4142-104", + .data = &mcp4131_cfg[MCP414x_104] }, + { .compatible = "microchip,mcp4151-502", + .data = &mcp4131_cfg[MCP415x_502] }, + { .compatible = "microchip,mcp4151-103", + .data = &mcp4131_cfg[MCP415x_103] }, + { .compatible = "microchip,mcp4151-503", + .data = &mcp4131_cfg[MCP415x_503] }, + { .compatible = "microchip,mcp4151-104", + .data = &mcp4131_cfg[MCP415x_104] }, + { .compatible = "microchip,mcp4152-502", + .data = &mcp4131_cfg[MCP415x_502] }, + { .compatible = "microchip,mcp4152-103", + .data = &mcp4131_cfg[MCP415x_103] }, + { .compatible = "microchip,mcp4152-503", + .data = &mcp4131_cfg[MCP415x_503] }, + { .compatible = "microchip,mcp4152-104", + .data = &mcp4131_cfg[MCP415x_104] }, + { .compatible = "microchip,mcp4161-502", + .data = &mcp4131_cfg[MCP416x_502] }, + { .compatible = "microchip,mcp4161-103", + .data = &mcp4131_cfg[MCP416x_103] }, + { .compatible = "microchip,mcp4161-503", + .data = &mcp4131_cfg[MCP416x_503] }, + { .compatible = "microchip,mcp4161-104", + .data = &mcp4131_cfg[MCP416x_104] }, + { .compatible = "microchip,mcp4162-502", + .data = &mcp4131_cfg[MCP416x_502] }, + { .compatible = "microchip,mcp4162-103", + .data = &mcp4131_cfg[MCP416x_103] }, + { .compatible = "microchip,mcp4162-503", + .data = &mcp4131_cfg[MCP416x_503] }, + { .compatible = "microchip,mcp4162-104", + .data = &mcp4131_cfg[MCP416x_104] }, + { .compatible = "microchip,mcp4231-502", + .data = &mcp4131_cfg[MCP423x_502] }, + { .compatible = "microchip,mcp4231-103", + .data = &mcp4131_cfg[MCP423x_103] }, + { .compatible = "microchip,mcp4231-503", + .data = &mcp4131_cfg[MCP423x_503] }, + { .compatible = "microchip,mcp4231-104", + .data = &mcp4131_cfg[MCP423x_104] }, + { .compatible = "microchip,mcp4232-502", + .data = &mcp4131_cfg[MCP423x_502] }, + { .compatible = "microchip,mcp4232-103", + .data = &mcp4131_cfg[MCP423x_103] }, + { .compatible = "microchip,mcp4232-503", + .data = &mcp4131_cfg[MCP423x_503] }, + { .compatible = "microchip,mcp4232-104", + .data = &mcp4131_cfg[MCP423x_104] }, + { .compatible = "microchip,mcp4241-502", + .data = &mcp4131_cfg[MCP424x_502] }, + { .compatible = "microchip,mcp4241-103", + .data = &mcp4131_cfg[MCP424x_103] }, + { .compatible = "microchip,mcp4241-503", + .data = &mcp4131_cfg[MCP424x_503] }, + { .compatible = "microchip,mcp4241-104", + .data = &mcp4131_cfg[MCP424x_104] }, + { .compatible = "microchip,mcp4242-502", + .data = &mcp4131_cfg[MCP424x_502] }, + { .compatible = "microchip,mcp4242-103", + .data = &mcp4131_cfg[MCP424x_103] }, + { .compatible = "microchip,mcp4242-503", + .data = &mcp4131_cfg[MCP424x_503] }, + { .compatible = "microchip,mcp4242-104", + .data = &mcp4131_cfg[MCP424x_104] }, + { .compatible = "microchip,mcp4251-502", + .data = &mcp4131_cfg[MCP425x_502] }, + { .compatible = "microchip,mcp4251-103", + .data = &mcp4131_cfg[MCP425x_103] }, + { .compatible = "microchip,mcp4251-503", + .data = &mcp4131_cfg[MCP425x_503] }, + { .compatible = "microchip,mcp4251-104", + .data = &mcp4131_cfg[MCP425x_104] }, + { .compatible = "microchip,mcp4252-502", + .data = &mcp4131_cfg[MCP425x_502] }, + { .compatible = "microchip,mcp4252-103", + .data = &mcp4131_cfg[MCP425x_103] }, + { .compatible = "microchip,mcp4252-503", + .data = &mcp4131_cfg[MCP425x_503] }, + { .compatible = "microchip,mcp4252-104", + .data = &mcp4131_cfg[MCP425x_104] }, + { .compatible = "microchip,mcp4261-502", + .data = &mcp4131_cfg[MCP426x_502] }, + { .compatible = "microchip,mcp4261-103", + .data = &mcp4131_cfg[MCP426x_103] }, + { .compatible = "microchip,mcp4261-503", + .data = &mcp4131_cfg[MCP426x_503] }, + { .compatible = "microchip,mcp4261-104", + .data = &mcp4131_cfg[MCP426x_104] }, + { .compatible = "microchip,mcp4262-502", + .data = &mcp4131_cfg[MCP426x_502] }, + { .compatible = "microchip,mcp4262-103", + .data = &mcp4131_cfg[MCP426x_103] }, + { .compatible = "microchip,mcp4262-503", + .data = &mcp4131_cfg[MCP426x_503] }, + { .compatible = "microchip,mcp4262-104", + .data = &mcp4131_cfg[MCP426x_104] }, + {} +}; +MODULE_DEVICE_TABLE(of, mcp4131_dt_ids); +#endif /* CONFIG_OF */ + +static const struct spi_device_id mcp4131_id[] = { + { "mcp4131-502", MCP413x_502 }, + { "mcp4131-103", MCP413x_103 }, + { "mcp4131-503", MCP413x_503 }, + { "mcp4131-104", MCP413x_104 }, + { "mcp4132-502", MCP413x_502 }, + { "mcp4132-103", MCP413x_103 }, + { "mcp4132-503", MCP413x_503 }, + { "mcp4132-104", MCP413x_104 }, + { "mcp4141-502", MCP414x_502 }, + { "mcp4141-103", MCP414x_103 }, + { "mcp4141-503", MCP414x_503 }, + { "mcp4141-104", MCP414x_104 }, + { "mcp4142-502", MCP414x_502 }, + { "mcp4142-103", MCP414x_103 }, + { "mcp4142-503", MCP414x_503 }, + { "mcp4142-104", MCP414x_104 }, + { "mcp4151-502", MCP415x_502 }, + { "mcp4151-103", MCP415x_103 }, + { "mcp4151-503", MCP415x_503 }, + { "mcp4151-104", MCP415x_104 }, + { "mcp4152-502", MCP415x_502 }, + { "mcp4152-103", MCP415x_103 }, + { "mcp4152-503", MCP415x_503 }, + { "mcp4152-104", MCP415x_104 }, + { "mcp4161-502", MCP416x_502 }, + { "mcp4161-103", MCP416x_103 }, + { "mcp4161-503", MCP416x_503 }, + { "mcp4161-104", MCP416x_104 }, + { "mcp4162-502", MCP416x_502 }, + { "mcp4162-103", MCP416x_103 }, + { "mcp4162-503", MCP416x_503 }, + { "mcp4162-104", MCP416x_104 }, + { "mcp4231-502", MCP423x_502 }, + { "mcp4231-103", MCP423x_103 }, + { "mcp4231-503", MCP423x_503 }, + { "mcp4231-104", MCP423x_104 }, + { "mcp4232-502", MCP423x_502 }, + { "mcp4232-103", MCP423x_103 }, + { "mcp4232-503", MCP423x_503 }, + { "mcp4232-104", MCP423x_104 }, + { "mcp4241-502", MCP424x_502 }, + { "mcp4241-103", MCP424x_103 }, + { "mcp4241-503", MCP424x_503 }, + { "mcp4241-104", MCP424x_104 }, + { "mcp4242-502", MCP424x_502 }, + { "mcp4242-103", MCP424x_103 }, + { "mcp4242-503", MCP424x_503 }, + { "mcp4242-104", MCP424x_104 }, + { "mcp4251-502", MCP425x_502 }, + { "mcp4251-103", MCP425x_103 }, + { "mcp4251-503", MCP425x_503 }, + { "mcp4251-104", MCP425x_104 }, + { "mcp4252-502", MCP425x_502 }, + { "mcp4252-103", MCP425x_103 }, + { "mcp4252-503", MCP425x_503 }, + { "mcp4252-104", MCP425x_104 }, + { "mcp4261-502", MCP426x_502 }, + { "mcp4261-103", MCP426x_103 }, + { "mcp4261-503", MCP426x_503 }, + { "mcp4261-104", MCP426x_104 }, + { "mcp4262-502", MCP426x_502 }, + { "mcp4262-103", MCP426x_103 }, + { "mcp4262-503", MCP426x_503 }, + { "mcp4262-104", MCP426x_104 }, + {} +}; +MODULE_DEVICE_TABLE(spi, mcp4131_id); + +static struct spi_driver mcp4131_driver = { + .driver = { + .name = "mcp4131", + .of_match_table = of_match_ptr(mcp4131_dt_ids), + }, + .probe = mcp4131_probe, + .id_table = mcp4131_id, +}; + +module_spi_driver(mcp4131_driver); + +MODULE_AUTHOR("Slawomir Stepien "); +MODULE_DESCRIPTION("MCP4131 digital potentiometer"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 94b24230196da3cd6bd58235137f9a7438983c73 Mon Sep 17 00:00:00 2001 From: Ludovic Desroches Date: Tue, 22 Mar 2016 17:08:45 +0100 Subject: iio:adc:at91-sama5d2: cleanup mode register use Do not erase previous configuration of the mode register when setting the sampling frequency. Signed-off-by: Ludovic Desroches Signed-off-by: Jonathan Cameron --- drivers/iio/adc/at91-sama5d2_adc.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c index 5bc038f23609..01ba1068613e 100644 --- a/drivers/iio/adc/at91-sama5d2_adc.c +++ b/drivers/iio/adc/at91-sama5d2_adc.c @@ -66,8 +66,10 @@ #define AT91_SAMA5D2_MR_PRESCAL(v) ((v) << AT91_SAMA5D2_MR_PRESCAL_OFFSET) #define AT91_SAMA5D2_MR_PRESCAL_OFFSET 8 #define AT91_SAMA5D2_MR_PRESCAL_MAX 0xff +#define AT91_SAMA5D2_MR_PRESCAL_MASK GENMASK(15, 8) /* Startup Time */ #define AT91_SAMA5D2_MR_STARTUP(v) ((v) << 16) +#define AT91_SAMA5D2_MR_STARTUP_MASK GENMASK(19, 16) /* Analog Change */ #define AT91_SAMA5D2_MR_ANACH BIT(23) /* Tracking Time */ @@ -226,7 +228,7 @@ static unsigned at91_adc_startup_time(unsigned startup_time_min, static void at91_adc_setup_samp_freq(struct at91_adc_state *st, unsigned freq) { struct iio_dev *indio_dev = iio_priv_to_dev(st); - unsigned f_per, prescal, startup; + unsigned f_per, prescal, startup, mr; f_per = clk_get_rate(st->per_clk); prescal = (f_per / (2 * freq)) - 1; @@ -234,10 +236,11 @@ static void at91_adc_setup_samp_freq(struct at91_adc_state *st, unsigned freq) startup = at91_adc_startup_time(st->soc_info.startup_time, freq / 1000); - at91_adc_writel(st, AT91_SAMA5D2_MR, - AT91_SAMA5D2_MR_TRANSFER(2) - | AT91_SAMA5D2_MR_STARTUP(startup) - | AT91_SAMA5D2_MR_PRESCAL(prescal)); + mr = at91_adc_readl(st, AT91_SAMA5D2_MR); + mr &= ~(AT91_SAMA5D2_MR_STARTUP_MASK | AT91_SAMA5D2_MR_PRESCAL_MASK); + mr |= AT91_SAMA5D2_MR_STARTUP(startup); + mr |= AT91_SAMA5D2_MR_PRESCAL(prescal); + at91_adc_writel(st, AT91_SAMA5D2_MR, mr); dev_dbg(&indio_dev->dev, "freq: %u, startup: %u, prescal: %u\n", freq, startup, prescal); @@ -444,6 +447,8 @@ static int at91_adc_probe(struct platform_device *pdev) at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST); at91_adc_writel(st, AT91_SAMA5D2_IDR, 0xffffffff); + /* Transfer field must be set to 2 according to the datasheet. */ + at91_adc_writel(st, AT91_SAMA5D2_MR, AT91_SAMA5D2_MR_TRANSFER(2)); at91_adc_setup_samp_freq(st, st->soc_info.min_sample_rate); -- cgit v1.2.3 From d65113222c27e2ca0b292a5163ea294428d481b2 Mon Sep 17 00:00:00 2001 From: Ludovic Desroches Date: Tue, 22 Mar 2016 17:08:46 +0100 Subject: iio:adc:at91-sama5d2: add support for differential conversions Add signed differential channels and update the voltage scale for differential conversions. Signed-off-by: Ludovic Desroches Signed-off-by: Jonathan Cameron --- drivers/iio/adc/at91-sama5d2_adc.c | 71 ++++++++++++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c index 01ba1068613e..07adb1070fc2 100644 --- a/drivers/iio/adc/at91-sama5d2_adc.c +++ b/drivers/iio/adc/at91-sama5d2_adc.c @@ -113,8 +113,11 @@ #define AT91_SAMA5D2_CWR 0x44 /* Channel Gain Register */ #define AT91_SAMA5D2_CGR 0x48 + /* Channel Offset Register */ #define AT91_SAMA5D2_COR 0x4c +#define AT91_SAMA5D2_COR_DIFF_OFFSET 16 + /* Channel Data Register 0 */ #define AT91_SAMA5D2_CDR0 0x50 /* Analog Control Register */ @@ -142,7 +145,7 @@ /* Version Register */ #define AT91_SAMA5D2_VERSION 0xfc -#define AT91_SAMA5D2_CHAN(num, addr) \ +#define AT91_SAMA5D2_CHAN_SINGLE(num, addr) \ { \ .type = IIO_VOLTAGE, \ .channel = num, \ @@ -158,6 +161,24 @@ .indexed = 1, \ } +#define AT91_SAMA5D2_CHAN_DIFF(num, num2, addr) \ + { \ + .type = IIO_VOLTAGE, \ + .differential = 1, \ + .channel = num, \ + .channel2 = num2, \ + .address = addr, \ + .scan_type = { \ + .sign = 's', \ + .realbits = 12, \ + }, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),\ + .datasheet_name = "CH"#num"-CH"#num2, \ + .indexed = 1, \ + } + #define at91_adc_readl(st, reg) readl_relaxed(st->base + reg) #define at91_adc_writel(st, reg, val) writel_relaxed(val, st->base + reg) @@ -187,18 +208,24 @@ struct at91_adc_state { }; static const struct iio_chan_spec at91_adc_channels[] = { - AT91_SAMA5D2_CHAN(0, 0x50), - AT91_SAMA5D2_CHAN(1, 0x54), - AT91_SAMA5D2_CHAN(2, 0x58), - AT91_SAMA5D2_CHAN(3, 0x5c), - AT91_SAMA5D2_CHAN(4, 0x60), - AT91_SAMA5D2_CHAN(5, 0x64), - AT91_SAMA5D2_CHAN(6, 0x68), - AT91_SAMA5D2_CHAN(7, 0x6c), - AT91_SAMA5D2_CHAN(8, 0x70), - AT91_SAMA5D2_CHAN(9, 0x74), - AT91_SAMA5D2_CHAN(10, 0x78), - AT91_SAMA5D2_CHAN(11, 0x7c), + AT91_SAMA5D2_CHAN_SINGLE(0, 0x50), + AT91_SAMA5D2_CHAN_SINGLE(1, 0x54), + AT91_SAMA5D2_CHAN_SINGLE(2, 0x58), + AT91_SAMA5D2_CHAN_SINGLE(3, 0x5c), + AT91_SAMA5D2_CHAN_SINGLE(4, 0x60), + AT91_SAMA5D2_CHAN_SINGLE(5, 0x64), + AT91_SAMA5D2_CHAN_SINGLE(6, 0x68), + AT91_SAMA5D2_CHAN_SINGLE(7, 0x6c), + AT91_SAMA5D2_CHAN_SINGLE(8, 0x70), + AT91_SAMA5D2_CHAN_SINGLE(9, 0x74), + AT91_SAMA5D2_CHAN_SINGLE(10, 0x78), + AT91_SAMA5D2_CHAN_SINGLE(11, 0x7c), + AT91_SAMA5D2_CHAN_DIFF(0, 1, 0x50), + AT91_SAMA5D2_CHAN_DIFF(2, 3, 0x58), + AT91_SAMA5D2_CHAN_DIFF(4, 5, 0x60), + AT91_SAMA5D2_CHAN_DIFF(6, 7, 0x68), + AT91_SAMA5D2_CHAN_DIFF(8, 9, 0x70), + AT91_SAMA5D2_CHAN_DIFF(10, 11, 0x78), }; static unsigned at91_adc_startup_time(unsigned startup_time_min, @@ -281,6 +308,7 @@ static int at91_adc_read_raw(struct iio_dev *indio_dev, int *val, int *val2, long mask) { struct at91_adc_state *st = iio_priv(indio_dev); + u32 cor = 0; int ret; switch (mask) { @@ -289,6 +317,11 @@ static int at91_adc_read_raw(struct iio_dev *indio_dev, st->chan = chan; + if (chan->differential) + cor = (BIT(chan->channel) | BIT(chan->channel2)) << + AT91_SAMA5D2_COR_DIFF_OFFSET; + + at91_adc_writel(st, AT91_SAMA5D2_COR, cor); at91_adc_writel(st, AT91_SAMA5D2_CHER, BIT(chan->channel)); at91_adc_writel(st, AT91_SAMA5D2_IER, BIT(chan->channel)); at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_START); @@ -301,6 +334,8 @@ static int at91_adc_read_raw(struct iio_dev *indio_dev, if (ret > 0) { *val = st->conversion_value; + if (chan->scan_type.sign == 's') + *val = sign_extend32(*val, 11); ret = IIO_VAL_INT; st->conversion_done = false; } @@ -313,6 +348,8 @@ static int at91_adc_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_SCALE: *val = st->vref_uv / 1000; + if (chan->differential) + *val *= 2; *val2 = chan->scan_type.realbits; return IIO_VAL_FRACTIONAL_LOG2; @@ -447,8 +484,12 @@ static int at91_adc_probe(struct platform_device *pdev) at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST); at91_adc_writel(st, AT91_SAMA5D2_IDR, 0xffffffff); - /* Transfer field must be set to 2 according to the datasheet. */ - at91_adc_writel(st, AT91_SAMA5D2_MR, AT91_SAMA5D2_MR_TRANSFER(2)); + /* + * Transfer field must be set to 2 according to the datasheet and + * allows different analog settings for each channel. + */ + at91_adc_writel(st, AT91_SAMA5D2_MR, + AT91_SAMA5D2_MR_TRANSFER(2) | AT91_SAMA5D2_MR_ANACH); at91_adc_setup_samp_freq(st, st->soc_info.min_sample_rate); -- cgit v1.2.3 From eaa3476a7ee27c9927531781c8b25365d77e3030 Mon Sep 17 00:00:00 2001 From: Marc Titinger Date: Fri, 11 Mar 2016 15:52:30 +0100 Subject: iio: ina2xx-adc: fix scale for VShunt The scale would result in uV instead of expected mV. Mostly cosmetic, since the value of 'Power' was computed OK. Signed-off-by: Marc Titinger Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ina2xx-adc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c index 4e56fe3580bf..502f2fbe8aef 100644 --- a/drivers/iio/adc/ina2xx-adc.c +++ b/drivers/iio/adc/ina2xx-adc.c @@ -185,9 +185,9 @@ static int ina2xx_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_SCALE: switch (chan->address) { case INA2XX_SHUNT_VOLTAGE: - /* processed (mV) = raw*1000/shunt_div */ + /* processed (mV) = raw/shunt_div */ *val2 = chip->config->shunt_div; - *val = 1000; + *val = 1; return IIO_VAL_FRACTIONAL; case INA2XX_BUS_VOLTAGE: -- cgit v1.2.3 From 2c5ff1f9a6240d7d2d0928021cb76e421d6aacaf Mon Sep 17 00:00:00 2001 From: Peter Meerwald-Stadler Date: Sun, 20 Mar 2016 16:20:22 +0100 Subject: iio: Add modifier for UV light Signed-off-by: Peter Meerwald-Stadler Signed-off-by: Jonathan Cameron --- Documentation/ABI/testing/sysfs-bus-iio | 4 +++- drivers/iio/industrialio-core.c | 1 + include/uapi/linux/iio/types.h | 1 + tools/iio/iio_event_monitor.c | 2 ++ 4 files changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index 17a9210fa6b5..6fb9180e7661 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -1255,12 +1255,14 @@ Description: What: /sys/.../iio:deviceX/in_intensityY_raw What: /sys/.../iio:deviceX/in_intensityY_ir_raw What: /sys/.../iio:deviceX/in_intensityY_both_raw +What: /sys/.../iio:deviceX/in_intensityY_uv_raw KernelVersion: 3.4 Contact: linux-iio@vger.kernel.org Description: Unit-less light intensity. Modifiers both and ir indicate that measurements contains visible and infrared light - components or just infrared light, respectively. + components or just infrared light, respectively. Modifier uv indicates + that measurements contain ultraviolet light components. What: /sys/.../iio:deviceX/in_intensity_red_integration_time What: /sys/.../iio:deviceX/in_intensity_green_integration_time diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 2e768bc99f05..88353ae0ec07 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -101,6 +101,7 @@ static const char * const iio_modifier_names[] = { [IIO_MOD_LIGHT_RED] = "red", [IIO_MOD_LIGHT_GREEN] = "green", [IIO_MOD_LIGHT_BLUE] = "blue", + [IIO_MOD_LIGHT_UV] = "uv", [IIO_MOD_QUATERNION] = "quaternion", [IIO_MOD_TEMP_AMBIENT] = "ambient", [IIO_MOD_TEMP_OBJECT] = "object", diff --git a/include/uapi/linux/iio/types.h b/include/uapi/linux/iio/types.h index c077617f3304..9337eceb9f9d 100644 --- a/include/uapi/linux/iio/types.h +++ b/include/uapi/linux/iio/types.h @@ -77,6 +77,7 @@ enum iio_modifier { IIO_MOD_Q, IIO_MOD_CO2, IIO_MOD_VOC, + IIO_MOD_LIGHT_UV, }; enum iio_event_type { diff --git a/tools/iio/iio_event_monitor.c b/tools/iio/iio_event_monitor.c index 90980f586f7a..8d7d9797480b 100644 --- a/tools/iio/iio_event_monitor.c +++ b/tools/iio/iio_event_monitor.c @@ -93,6 +93,7 @@ static const char * const iio_modifier_names[] = { [IIO_MOD_LIGHT_RED] = "red", [IIO_MOD_LIGHT_GREEN] = "green", [IIO_MOD_LIGHT_BLUE] = "blue", + [IIO_MOD_LIGHT_UV] = "uv", [IIO_MOD_QUATERNION] = "quaternion", [IIO_MOD_TEMP_AMBIENT] = "ambient", [IIO_MOD_TEMP_OBJECT] = "object", @@ -172,6 +173,7 @@ static bool event_is_known(struct iio_event_data *event) case IIO_MOD_LIGHT_RED: case IIO_MOD_LIGHT_GREEN: case IIO_MOD_LIGHT_BLUE: + case IIO_MOD_LIGHT_UV: case IIO_MOD_QUATERNION: case IIO_MOD_TEMP_AMBIENT: case IIO_MOD_TEMP_OBJECT: -- cgit v1.2.3 From d409404cf6e201c2980c7148484c350f33a7912e Mon Sep 17 00:00:00 2001 From: Peter Meerwald-Stadler Date: Sun, 20 Mar 2016 16:20:23 +0100 Subject: iio: Add channel for UV index UV index indicating strength of sunburn-producing ultraviolet (UV) radiation Signed-off-by: Peter Meerwald-Stadler Signed-off-by: Jonathan Cameron --- Documentation/ABI/testing/sysfs-bus-iio | 9 +++++++++ drivers/iio/industrialio-core.c | 1 + include/uapi/linux/iio/types.h | 1 + tools/iio/iio_event_monitor.c | 2 ++ 4 files changed, 13 insertions(+) (limited to 'drivers') diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index 6fb9180e7661..f155eff910f9 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -1264,6 +1264,15 @@ Description: components or just infrared light, respectively. Modifier uv indicates that measurements contain ultraviolet light components. +What: /sys/.../iio:deviceX/in_uvindex_input +KernelVersion: 4.6 +Contact: linux-iio@vger.kernel.org +Description: + UV light intensity index measuring the human skin's response to + different wavelength of sunlight weighted according to the + standardised CIE Erythemal Action Spectrum. UV index values range + from 0 (low) to >=11 (extreme). + What: /sys/.../iio:deviceX/in_intensity_red_integration_time What: /sys/.../iio:deviceX/in_intensity_green_integration_time What: /sys/.../iio:deviceX/in_intensity_blue_integration_time diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 88353ae0ec07..190a5939fd8c 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -79,6 +79,7 @@ static const char * const iio_chan_type_name_spec[] = { [IIO_CONCENTRATION] = "concentration", [IIO_RESISTANCE] = "resistance", [IIO_PH] = "ph", + [IIO_UVINDEX] = "uvindex", }; static const char * const iio_modifier_names[] = { diff --git a/include/uapi/linux/iio/types.h b/include/uapi/linux/iio/types.h index 9337eceb9f9d..b0916fc72cce 100644 --- a/include/uapi/linux/iio/types.h +++ b/include/uapi/linux/iio/types.h @@ -38,6 +38,7 @@ enum iio_chan_type { IIO_CONCENTRATION, IIO_RESISTANCE, IIO_PH, + IIO_UVINDEX, }; enum iio_modifier { diff --git a/tools/iio/iio_event_monitor.c b/tools/iio/iio_event_monitor.c index 8d7d9797480b..d9b7e0f306c6 100644 --- a/tools/iio/iio_event_monitor.c +++ b/tools/iio/iio_event_monitor.c @@ -56,6 +56,7 @@ static const char * const iio_chan_type_name_spec[] = { [IIO_CONCENTRATION] = "concentration", [IIO_RESISTANCE] = "resistance", [IIO_PH] = "ph", + [IIO_UVINDEX] = "uvindex", }; static const char * const iio_ev_type_text[] = { @@ -147,6 +148,7 @@ static bool event_is_known(struct iio_event_data *event) case IIO_CONCENTRATION: case IIO_RESISTANCE: case IIO_PH: + case IIO_UVINDEX: break; default: return false; -- cgit v1.2.3 From fa4c9c93e93f429bb8a8b01c53d54d6bd53a3028 Mon Sep 17 00:00:00 2001 From: Crestez Dan Leonard Date: Tue, 29 Mar 2016 19:14:27 +0300 Subject: hp206c: Initial support for reading sensor values Signed-off-by: Crestez Dan Leonard Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/Kconfig | 10 + drivers/iio/pressure/Makefile | 1 + drivers/iio/pressure/hp206c.c | 426 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 437 insertions(+) create mode 100644 drivers/iio/pressure/hp206c.c (limited to 'drivers') diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig index 31c0e1fd2202..8de0192adea6 100644 --- a/drivers/iio/pressure/Kconfig +++ b/drivers/iio/pressure/Kconfig @@ -148,4 +148,14 @@ config T5403 To compile this driver as a module, choose M here: the module will be called t5403. +config HP206C + tristate "HOPERF HP206C precision barometer and altimeter sensor" + depends on I2C + help + Say yes here to build support for the HOPREF HP206C precision + barometer and altimeter sensor. + + This driver can also be built as a module. If so, the module will + be called hp206c. + endmenu diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile index d336af14f3fe..6e60863c1086 100644 --- a/drivers/iio/pressure/Makefile +++ b/drivers/iio/pressure/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_IIO_ST_PRESS) += st_pressure.o st_pressure-y := st_pressure_core.o st_pressure-$(CONFIG_IIO_BUFFER) += st_pressure_buffer.o obj-$(CONFIG_T5403) += t5403.o +obj-$(CONFIG_HP206C) += hp206c.o obj-$(CONFIG_IIO_ST_PRESS_I2C) += st_pressure_i2c.o obj-$(CONFIG_IIO_ST_PRESS_SPI) += st_pressure_spi.o diff --git a/drivers/iio/pressure/hp206c.c b/drivers/iio/pressure/hp206c.c new file mode 100644 index 000000000000..90f2b6e4a920 --- /dev/null +++ b/drivers/iio/pressure/hp206c.c @@ -0,0 +1,426 @@ +/* + * hp206c.c - HOPERF HP206C precision barometer and altimeter sensor + * + * Copyright (c) 2016, Intel Corporation. + * + * This file is subject to the terms and conditions of version 2 of + * the GNU General Public License. See the file COPYING in the main + * directory of this archive for more details. + * + * (7-bit I2C slave address 0x76) + * + * Datasheet: + * http://www.hoperf.com/upload/sensor/HP206C_DataSheet_EN_V2.0.pdf + */ + +#include +#include +#include +#include +#include +#include +#include + +/* I2C commands: */ +#define HP206C_CMD_SOFT_RST 0x06 + +#define HP206C_CMD_ADC_CVT 0x40 + +#define HP206C_CMD_ADC_CVT_OSR_4096 0x00 +#define HP206C_CMD_ADC_CVT_OSR_2048 0x04 +#define HP206C_CMD_ADC_CVT_OSR_1024 0x08 +#define HP206C_CMD_ADC_CVT_OSR_512 0x0c +#define HP206C_CMD_ADC_CVT_OSR_256 0x10 +#define HP206C_CMD_ADC_CVT_OSR_128 0x14 + +#define HP206C_CMD_ADC_CVT_CHNL_PT 0x00 +#define HP206C_CMD_ADC_CVT_CHNL_T 0x02 + +#define HP206C_CMD_READ_P 0x30 +#define HP206C_CMD_READ_T 0x32 + +#define HP206C_CMD_READ_REG 0x80 +#define HP206C_CMD_WRITE_REG 0xc0 + +#define HP206C_REG_INT_EN 0x0b +#define HP206C_REG_INT_CFG 0x0c + +#define HP206C_REG_INT_SRC 0x0d +#define HP206C_FLAG_DEV_RDY 0x40 + +#define HP206C_REG_PARA 0x0f +#define HP206C_FLAG_CMPS_EN 0x80 + +/* Maximum spin for DEV_RDY */ +#define HP206C_MAX_DEV_RDY_WAIT_COUNT 20 +#define HP206C_DEV_RDY_WAIT_US 20000 + +struct hp206c_data { + struct mutex mutex; + struct i2c_client *client; + int temp_osr_index; + int pres_osr_index; +}; + +struct hp206c_osr_setting { + u8 osr_mask; + unsigned int temp_conv_time_us; + unsigned int pres_conv_time_us; +}; + +/* Data from Table 5 in datasheet. */ +static const struct hp206c_osr_setting hp206c_osr_settings[] = { + { HP206C_CMD_ADC_CVT_OSR_4096, 65600, 131100 }, + { HP206C_CMD_ADC_CVT_OSR_2048, 32800, 65600 }, + { HP206C_CMD_ADC_CVT_OSR_1024, 16400, 32800 }, + { HP206C_CMD_ADC_CVT_OSR_512, 8200, 16400 }, + { HP206C_CMD_ADC_CVT_OSR_256, 4100, 8200 }, + { HP206C_CMD_ADC_CVT_OSR_128, 2100, 4100 }, +}; +static const int hp206c_osr_rates[] = { 4096, 2048, 1024, 512, 256, 128 }; +static const char hp206c_osr_rates_str[] = "4096 2048 1024 512 256 128"; + +static inline int hp206c_read_reg(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, HP206C_CMD_READ_REG | reg); +} + +static inline int hp206c_write_reg(struct i2c_client *client, u8 reg, u8 val) +{ + return i2c_smbus_write_byte_data(client, + HP206C_CMD_WRITE_REG | reg, val); +} + +static int hp206c_read_20bit(struct i2c_client *client, u8 cmd) +{ + int ret; + u8 values[3]; + + ret = i2c_smbus_read_i2c_block_data(client, cmd, 3, values); + if (ret < 0) + return ret; + if (ret != 3) + return -EIO; + return ((values[0] & 0xF) << 16) | (values[1] << 8) | (values[2]); +} + +/* Spin for max 160ms until DEV_RDY is 1, or return error. */ +static int hp206c_wait_dev_rdy(struct iio_dev *indio_dev) +{ + int ret; + int count = 0; + struct hp206c_data *data = iio_priv(indio_dev); + struct i2c_client *client = data->client; + + while (++count <= HP206C_MAX_DEV_RDY_WAIT_COUNT) { + ret = hp206c_read_reg(client, HP206C_REG_INT_SRC); + if (ret < 0) { + dev_err(&indio_dev->dev, "Failed READ_REG INT_SRC: %d\n", ret); + return ret; + } + if (ret & HP206C_FLAG_DEV_RDY) + return 0; + usleep_range(HP206C_DEV_RDY_WAIT_US, HP206C_DEV_RDY_WAIT_US * 3 / 2); + } + return -ETIMEDOUT; +} + +static int hp206c_set_compensation(struct i2c_client *client, bool enabled) +{ + int val; + + val = hp206c_read_reg(client, HP206C_REG_PARA); + if (val < 0) + return val; + if (enabled) + val |= HP206C_FLAG_CMPS_EN; + else + val &= ~HP206C_FLAG_CMPS_EN; + + return hp206c_write_reg(client, HP206C_REG_PARA, val); +} + +/* Do a soft reset */ +static int hp206c_soft_reset(struct iio_dev *indio_dev) +{ + int ret; + struct hp206c_data *data = iio_priv(indio_dev); + struct i2c_client *client = data->client; + + ret = i2c_smbus_write_byte(client, HP206C_CMD_SOFT_RST); + if (ret) { + dev_err(&client->dev, "Failed to reset device: %d\n", ret); + return ret; + } + + usleep_range(400, 600); + + ret = hp206c_wait_dev_rdy(indio_dev); + if (ret) { + dev_err(&client->dev, "Device not ready after soft reset: %d\n", ret); + return ret; + } + + ret = hp206c_set_compensation(client, true); + if (ret) + dev_err(&client->dev, "Failed to enable compensation: %d\n", ret); + return ret; +} + +static int hp206c_conv_and_read(struct iio_dev *indio_dev, + u8 conv_cmd, u8 read_cmd, + unsigned int sleep_us) +{ + int ret; + struct hp206c_data *data = iio_priv(indio_dev); + struct i2c_client *client = data->client; + + ret = hp206c_wait_dev_rdy(indio_dev); + if (ret < 0) { + dev_err(&indio_dev->dev, "Device not ready: %d\n", ret); + return ret; + } + + ret = i2c_smbus_write_byte(client, conv_cmd); + if (ret < 0) { + dev_err(&indio_dev->dev, "Failed convert: %d\n", ret); + return ret; + } + + usleep_range(sleep_us, sleep_us * 3 / 2); + + ret = hp206c_wait_dev_rdy(indio_dev); + if (ret < 0) { + dev_err(&indio_dev->dev, "Device not ready: %d\n", ret); + return ret; + } + + ret = hp206c_read_20bit(client, read_cmd); + if (ret < 0) + dev_err(&indio_dev->dev, "Failed read: %d\n", ret); + + return ret; +} + +static int hp206c_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, + int *val2, long mask) +{ + int ret; + struct hp206c_data *data = iio_priv(indio_dev); + const struct hp206c_osr_setting *osr_setting; + u8 conv_cmd; + + mutex_lock(&data->mutex); + + switch (mask) { + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: + switch (chan->type) { + case IIO_TEMP: + *val = hp206c_osr_rates[data->temp_osr_index]; + ret = IIO_VAL_INT; + break; + + case IIO_PRESSURE: + *val = hp206c_osr_rates[data->pres_osr_index]; + ret = IIO_VAL_INT; + break; + default: + ret = -EINVAL; + } + break; + + case IIO_CHAN_INFO_RAW: + switch (chan->type) { + case IIO_TEMP: + osr_setting = &hp206c_osr_settings[data->temp_osr_index]; + conv_cmd = HP206C_CMD_ADC_CVT | + osr_setting->osr_mask | + HP206C_CMD_ADC_CVT_CHNL_T; + ret = hp206c_conv_and_read(indio_dev, + conv_cmd, + HP206C_CMD_READ_T, + osr_setting->temp_conv_time_us); + if (ret >= 0) { + /* 20 significant bits are provided. + * Extend sign over the rest. + */ + *val = sign_extend32(ret, 19); + ret = IIO_VAL_INT; + } + break; + + case IIO_PRESSURE: + osr_setting = &hp206c_osr_settings[data->pres_osr_index]; + conv_cmd = HP206C_CMD_ADC_CVT | + osr_setting->osr_mask | + HP206C_CMD_ADC_CVT_CHNL_PT; + ret = hp206c_conv_and_read(indio_dev, + conv_cmd, + HP206C_CMD_READ_P, + osr_setting->pres_conv_time_us); + if (ret >= 0) { + *val = ret; + ret = IIO_VAL_INT; + } + break; + default: + ret = -EINVAL; + } + break; + + case IIO_CHAN_INFO_SCALE: + switch (chan->type) { + case IIO_TEMP: + *val = 0; + *val2 = 10000; + ret = IIO_VAL_INT_PLUS_MICRO; + break; + + case IIO_PRESSURE: + *val = 0; + *val2 = 1000; + ret = IIO_VAL_INT_PLUS_MICRO; + break; + default: + ret = -EINVAL; + } + break; + + default: + ret = -EINVAL; + } + + mutex_unlock(&data->mutex); + return ret; +} + +static int hp206c_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + int ret = 0; + struct hp206c_data *data = iio_priv(indio_dev); + + if (mask != IIO_CHAN_INFO_OVERSAMPLING_RATIO) + return -EINVAL; + mutex_lock(&data->mutex); + switch (chan->type) { + case IIO_TEMP: + data->temp_osr_index = find_closest_descending(val, + hp206c_osr_rates, ARRAY_SIZE(hp206c_osr_rates)); + break; + case IIO_PRESSURE: + data->pres_osr_index = find_closest_descending(val, + hp206c_osr_rates, ARRAY_SIZE(hp206c_osr_rates)); + break; + default: + ret = -EINVAL; + } + mutex_unlock(&data->mutex); + return ret; +} + +static const struct iio_chan_spec hp206c_channels[] = { + { + .type = IIO_TEMP, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), + }, + { + .type = IIO_PRESSURE, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), + } +}; + +static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(hp206c_osr_rates_str); + +static struct attribute *hp206c_attributes[] = { + &iio_const_attr_sampling_frequency_available.dev_attr.attr, + NULL, +}; + +static const struct attribute_group hp206c_attribute_group = { + .attrs = hp206c_attributes, +}; + +static const struct iio_info hp206c_info = { + .attrs = &hp206c_attribute_group, + .read_raw = hp206c_read_raw, + .write_raw = hp206c_write_raw, + .driver_module = THIS_MODULE, +}; + +static int hp206c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct iio_dev *indio_dev; + struct hp206c_data *data; + int ret; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE | + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { + dev_err(&client->dev, "Adapter does not support " + "all required i2c functionality\n"); + return -ENODEV; + } + + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + data = iio_priv(indio_dev); + data->client = client; + mutex_init(&data->mutex); + + indio_dev->info = &hp206c_info; + indio_dev->name = id->name; + indio_dev->dev.parent = &client->dev; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = hp206c_channels; + indio_dev->num_channels = ARRAY_SIZE(hp206c_channels); + + i2c_set_clientdata(client, indio_dev); + + /* Do a soft reset on probe */ + ret = hp206c_soft_reset(indio_dev); + if (ret) { + dev_err(&client->dev, "Failed to reset on startup: %d\n", ret); + return -ENODEV; + } + + return devm_iio_device_register(&client->dev, indio_dev); +} + +static const struct i2c_device_id hp206c_id[] = { + {"hp206c"}, + {} +}; + +#ifdef CONFIG_ACPI +static const struct acpi_device_id hp206c_acpi_match[] = { + {"HOP206C", 0}, + { }, +}; +MODULE_DEVICE_TABLE(acpi, hp206c_acpi_match); +#endif + +static struct i2c_driver hp206c_driver = { + .probe = hp206c_probe, + .id_table = hp206c_id, + .driver = { + .name = "hp206c", + .acpi_match_table = ACPI_PTR(hp206c_acpi_match), + }, +}; + +module_i2c_driver(hp206c_driver); + +MODULE_DESCRIPTION("HOPERF HP206C precision barometer and altimeter sensor"); +MODULE_AUTHOR("Leonard Crestez "); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 486294f184c05cff116160bb731cbb679f047621 Mon Sep 17 00:00:00 2001 From: Irina Tirdea Date: Tue, 29 Mar 2016 15:21:21 +0300 Subject: iio: accel: bmc150: use common definition for regmap conf bmc150_i2c_regmap_conf is defined three times (in bmc150-accel-core.c, bmc150-accel-i2c.c and and bmc150-accel-spi.c), although the definition is the same. Use one common definition for bmc150_i2c_regmap_conf in all included files. Signed-off-by: Irina Tirdea Signed-off-by: Jonathan Cameron --- drivers/iio/accel/bmc150-accel-core.c | 3 ++- drivers/iio/accel/bmc150-accel-i2c.c | 7 +------ drivers/iio/accel/bmc150-accel-spi.c | 8 +------- drivers/iio/accel/bmc150-accel.h | 1 + 4 files changed, 5 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c index f3d096f3c539..e631ee9a6a77 100644 --- a/drivers/iio/accel/bmc150-accel-core.c +++ b/drivers/iio/accel/bmc150-accel-core.c @@ -246,11 +246,12 @@ static const struct { {500000, BMC150_ACCEL_SLEEP_500_MS}, {1000000, BMC150_ACCEL_SLEEP_1_SEC} }; -static const struct regmap_config bmc150_i2c_regmap_conf = { +const struct regmap_config bmc150_regmap_conf = { .reg_bits = 8, .val_bits = 8, .max_register = 0x3f, }; +EXPORT_SYMBOL_GPL(bmc150_regmap_conf); static int bmc150_accel_set_mode(struct bmc150_accel_data *data, enum bmc150_power_modes mode, diff --git a/drivers/iio/accel/bmc150-accel-i2c.c b/drivers/iio/accel/bmc150-accel-i2c.c index b41404ba32fc..8ca8041267ef 100644 --- a/drivers/iio/accel/bmc150-accel-i2c.c +++ b/drivers/iio/accel/bmc150-accel-i2c.c @@ -28,11 +28,6 @@ #include "bmc150-accel.h" -static const struct regmap_config bmc150_i2c_regmap_conf = { - .reg_bits = 8, - .val_bits = 8, -}; - static int bmc150_accel_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -43,7 +38,7 @@ static int bmc150_accel_probe(struct i2c_client *client, i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK); - regmap = devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf); + regmap = devm_regmap_init_i2c(client, &bmc150_regmap_conf); if (IS_ERR(regmap)) { dev_err(&client->dev, "Failed to initialize i2c regmap\n"); return PTR_ERR(regmap); diff --git a/drivers/iio/accel/bmc150-accel-spi.c b/drivers/iio/accel/bmc150-accel-spi.c index 16b66f2a7204..006794a70a1f 100644 --- a/drivers/iio/accel/bmc150-accel-spi.c +++ b/drivers/iio/accel/bmc150-accel-spi.c @@ -25,18 +25,12 @@ #include "bmc150-accel.h" -static const struct regmap_config bmc150_spi_regmap_conf = { - .reg_bits = 8, - .val_bits = 8, - .max_register = 0x3f, -}; - static int bmc150_accel_probe(struct spi_device *spi) { struct regmap *regmap; const struct spi_device_id *id = spi_get_device_id(spi); - regmap = devm_regmap_init_spi(spi, &bmc150_spi_regmap_conf); + regmap = devm_regmap_init_spi(spi, &bmc150_regmap_conf); if (IS_ERR(regmap)) { dev_err(&spi->dev, "Failed to initialize spi regmap\n"); return PTR_ERR(regmap); diff --git a/drivers/iio/accel/bmc150-accel.h b/drivers/iio/accel/bmc150-accel.h index ba0335987f94..38a8b11f8c19 100644 --- a/drivers/iio/accel/bmc150-accel.h +++ b/drivers/iio/accel/bmc150-accel.h @@ -16,5 +16,6 @@ int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq, const char *name, bool block_supported); int bmc150_accel_core_remove(struct device *dev); extern const struct dev_pm_ops bmc150_accel_pm_ops; +extern const struct regmap_config bmc150_regmap_conf; #endif /* _BMC150_ACCEL_H_ */ -- cgit v1.2.3 From 188c1ab7769dd7c092f9b1be5f69aa34d4a6f9d6 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 3 Apr 2016 14:14:20 +0100 Subject: drm/i915: Add struct_mutex locking for debugs/i915_gem_framebuffer Since describe_obj() looks at state guarded by the struct_mutex, we need to be holding it. [ 580.201054] drv_suspend: starting subtest debugfs-reader [ 580.239652] ------------[ cut here ]------------ [ 580.239696] WARNING: CPU: 0 PID: 920 at include/linux/list_check.h:25 describe_obj+0x419/0x440() [ 580.239725] CPU: 0 PID: 920 Comm: cat Not tainted 4.5.0-rc6+ #835 [ 580.239745] Hardware name: /NUC5CPYB, BIOS PYBSWCEL.86A.0027.2015.0507.1758 05/07/2015 [ 580.239767] 0000000000000000 ffff88027554fcf8 ffffffff812c1135 0000000000000000 [ 580.239815] ffffffff8193dc42 ffff88027554fd30 ffffffff8107419d ffff880071727c00 [ 580.239858] ffff8802757d8000 ffffffff818f693c ffffffff818f693c ffff8802757b9048 [ 580.239896] Call Trace: [ 580.239917] [] dump_stack+0x67/0x92 [ 580.239939] [] warn_slowpath_common+0x7d/0xb0 [ 580.239959] [] warn_slowpath_null+0x1a/0x20 [ 580.239981] [] describe_obj+0x419/0x440 [ 580.240006] [] i915_gem_framebuffer_info+0xa2/0x100 [ 580.240033] [] seq_read+0xe6/0x3b0 [ 580.240059] [] __vfs_read+0x28/0xd0 [ 580.240085] [] ? SyS_fadvise64+0x228/0x2c0 [ 580.240112] [] vfs_read+0x82/0x110 [ 580.240137] [] SyS_read+0x49/0xa0 [ 580.240162] [] entry_SYSCALL_64_fastpath+0x12/0x6b [ 580.240187] ---[ end trace 3e2cbf34576c9878 ]--- [ 580.281900] ------------[ cut here ]------------ Signed-off-by: Chris Wilson Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1459689261-7920-1-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_debugfs.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 74f227415765..6b384d7738f1 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -134,6 +134,8 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) int pin_count = 0; enum intel_engine_id id; + lockdep_assert_held(&obj->base.dev->struct_mutex); + seq_printf(m, "%pK: %s%s%s%s %8zdKiB %02x %02x [ ", &obj->base, obj->active ? "*" : " ", @@ -1894,6 +1896,11 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data) struct drm_device *dev = node->minor->dev; struct intel_framebuffer *fbdev_fb = NULL; struct drm_framebuffer *drm_fb; + int ret; + + ret = mutex_lock_interruptible(&dev->struct_mutex); + if (ret) + return ret; #ifdef CONFIG_DRM_FBDEV_EMULATION if (to_i915(dev)->fbdev) { @@ -1928,6 +1935,7 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data) seq_putc(m, '\n'); } mutex_unlock(&dev->mode_config.fb_lock); + mutex_unlock(&dev->struct_mutex); return 0; } -- cgit v1.2.3 From a156e64dd6bf609ae5c366e1676e580dca239e3e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 3 Apr 2016 14:14:21 +0100 Subject: drm/i915: Show PCI power state under debugfs/i915_runtime_pm_status As the current PCI power state is an essential feature of runtime pm, include it in the debugfs/i915_runtime_pm_status. v2: Use pci_power_name() Signed-off-by: Chris Wilson Cc: Imre Deak Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1459689261-7920-2-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_debugfs.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 6b384d7738f1..0b25228c202e 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2694,10 +2694,8 @@ static int i915_runtime_pm_status(struct seq_file *m, void *unused) struct drm_device *dev = node->minor->dev; struct drm_i915_private *dev_priv = dev->dev_private; - if (!HAS_RUNTIME_PM(dev)) { - seq_puts(m, "not supported\n"); - return 0; - } + if (!HAS_RUNTIME_PM(dev_priv)) + seq_puts(m, "Runtime power management not supported\n"); seq_printf(m, "GPU idle: %s\n", yesno(!dev_priv->mm.busy)); seq_printf(m, "IRQs disabled: %s\n", @@ -2708,6 +2706,9 @@ static int i915_runtime_pm_status(struct seq_file *m, void *unused) #else seq_printf(m, "Device Power Management (CONFIG_PM) disabled\n"); #endif + seq_printf(m, "PCI device power state: %s [%d]\n", + pci_power_name(dev_priv->dev->pdev->current_state), + dev_priv->dev->pdev->current_state); return 0; } -- cgit v1.2.3 From fddcca5107051adf9e4481d2a79ae0616577fd2c Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 29 Feb 2016 13:20:28 +0100 Subject: mtd: avoid stack overflow in MTD CFI code When map_word gets too large, we use a lot of kernel stack, and for MTD_MAP_BANK_WIDTH_32, this means we use more than the recommended 1024 bytes in a number of functions: drivers/mtd/chips/cfi_cmdset_0020.c: In function 'cfi_staa_write_buffers': drivers/mtd/chips/cfi_cmdset_0020.c:651:1: warning: the frame size of 1336 bytes is larger than 1024 bytes [-Wframe-larger-than=] drivers/mtd/chips/cfi_cmdset_0020.c: In function 'cfi_staa_erase_varsize': drivers/mtd/chips/cfi_cmdset_0020.c:972:1: warning: the frame size of 1208 bytes is larger than 1024 bytes [-Wframe-larger-than=] drivers/mtd/chips/cfi_cmdset_0001.c: In function 'do_write_buffer': drivers/mtd/chips/cfi_cmdset_0001.c:1835:1: warning: the frame size of 1240 bytes is larger than 1024 bytes [-Wframe-larger-than=] This can be avoided if all operations on the map word are done indirectly and the stack gets reused between the calls. We can mostly achieve this by selecting MTD_COMPLEX_MAPPINGS whenever MTD_MAP_BANK_WIDTH_32 is set, but for the case that no other bank width is enabled, we also need to use a non-constant map_bankwidth() to convince the compiler to use less stack. Signed-off-by: Arnd Bergmann [Brian: this patch mostly achieves its goal by forcing MTD_COMPLEX_MAPPINGS (and the accompanying indirection) for 256-bit mappings; the rest of the change is mostly a wash, though it helps reduce stack size slightly. If we really care about supporting 256-bit mappings though, we should consider rewriting some of this code to avoid keeping and assigning so many 256-bit objects on the stack.] Signed-off-by: Brian Norris --- drivers/mtd/chips/Kconfig | 1 + include/linux/mtd/map.h | 19 +++++++------------ 2 files changed, 8 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig index 3b3dabce58de..bbfa1f129266 100644 --- a/drivers/mtd/chips/Kconfig +++ b/drivers/mtd/chips/Kconfig @@ -115,6 +115,7 @@ config MTD_MAP_BANK_WIDTH_16 config MTD_MAP_BANK_WIDTH_32 bool "Support 256-bit buswidth" if MTD_CFI_GEOMETRY + select MTD_COMPLEX_MAPPINGS if HAS_IOMEM default n help If you wish to support CFI devices on a physical bus which is diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h index 5e0eb7ccabd4..3aa56e3104bb 100644 --- a/include/linux/mtd/map.h +++ b/include/linux/mtd/map.h @@ -122,18 +122,13 @@ #endif #ifdef CONFIG_MTD_MAP_BANK_WIDTH_32 -# ifdef map_bankwidth -# undef map_bankwidth -# define map_bankwidth(map) ((map)->bankwidth) -# undef map_bankwidth_is_large -# define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8) -# undef map_words -# define map_words(map) map_calc_words(map) -# else -# define map_bankwidth(map) 32 -# define map_bankwidth_is_large(map) (1) -# define map_words(map) map_calc_words(map) -# endif +/* always use indirect access for 256-bit to preserve kernel stack */ +# undef map_bankwidth +# define map_bankwidth(map) ((map)->bankwidth) +# undef map_bankwidth_is_large +# define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8) +# undef map_words +# define map_words(map) map_calc_words(map) #define map_bankwidth_is_32(map) (map_bankwidth(map) == 32) #undef MAX_MAP_BANKWIDTH #define MAX_MAP_BANKWIDTH 32 -- cgit v1.2.3 From 5651d6aaf489d1db48c253cf884b40214e91c2c5 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 26 Feb 2016 11:50:28 +0100 Subject: mtd: bcm47xxsflash: use ioremap_cache() instead of KSEG0ADDR() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using KSEG0ADDR makes code highly MIPS dependent and not portable. Thanks to the fix a68f376 ("MIPS: io.h: Define `ioremap_cache'") we can use ioremap_cache which is generic and supported on MIPS as well now. KSEG0ADDR was translating 0x1c000000 into 0x9c000000. With ioremap_cache we use MIPS's __ioremap (and then remap_area_pages). This results in different address (e.g. 0xc0080000) but it still should be cached as expected and it was successfully tested with BCM47186B0. Other than that drivers/bcma/driver_chipcommon_sflash.c nicely setups a struct resource for access window, but we wren't using it. Use it now and drop duplicated info. Signed-off-by: Brian Norris Signed-off-by: Rafał Miłecki --- drivers/bcma/driver_chipcommon_sflash.c | 1 - drivers/mtd/devices/bcm47xxsflash.c | 29 ++++++++++++++++++++++++----- drivers/mtd/devices/bcm47xxsflash.h | 3 ++- include/linux/bcma/bcma_driver_chipcommon.h | 1 - 4 files changed, 26 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/bcma/driver_chipcommon_sflash.c b/drivers/bcma/driver_chipcommon_sflash.c index 04d706ca5f43..35b13a08ca3e 100644 --- a/drivers/bcma/driver_chipcommon_sflash.c +++ b/drivers/bcma/driver_chipcommon_sflash.c @@ -146,7 +146,6 @@ int bcma_sflash_init(struct bcma_drv_cc *cc) return -ENOTSUPP; } - sflash->window = BCMA_SOC_FLASH2; sflash->blocksize = e->blocksize; sflash->numblocks = e->numblocks; sflash->size = sflash->blocksize * sflash->numblocks; diff --git a/drivers/mtd/devices/bcm47xxsflash.c b/drivers/mtd/devices/bcm47xxsflash.c index 347bb83db864..1c65c15b31a1 100644 --- a/drivers/mtd/devices/bcm47xxsflash.c +++ b/drivers/mtd/devices/bcm47xxsflash.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -109,8 +110,7 @@ static int bcm47xxsflash_read(struct mtd_info *mtd, loff_t from, size_t len, if ((from + len) > mtd->size) return -EINVAL; - memcpy_fromio(buf, (void __iomem *)KSEG0ADDR(b47s->window + from), - len); + memcpy_fromio(buf, b47s->window + from, len); *retlen = len; return len; @@ -275,15 +275,33 @@ static void bcm47xxsflash_bcma_cc_write(struct bcm47xxsflash *b47s, u16 offset, static int bcm47xxsflash_bcma_probe(struct platform_device *pdev) { - struct bcma_sflash *sflash = dev_get_platdata(&pdev->dev); + struct device *dev = &pdev->dev; + struct bcma_sflash *sflash = dev_get_platdata(dev); struct bcm47xxsflash *b47s; + struct resource *res; int err; - b47s = devm_kzalloc(&pdev->dev, sizeof(*b47s), GFP_KERNEL); + b47s = devm_kzalloc(dev, sizeof(*b47s), GFP_KERNEL); if (!b47s) return -ENOMEM; sflash->priv = b47s; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "invalid resource\n"); + return -EINVAL; + } + if (!devm_request_mem_region(dev, res->start, resource_size(res), + res->name)) { + dev_err(dev, "can't request region for resource %pR\n", res); + return -EBUSY; + } + b47s->window = ioremap_cache(res->start, resource_size(res)); + if (!b47s->window) { + dev_err(dev, "ioremap failed for resource %pR\n", res); + return -ENOMEM; + } + b47s->bcma_cc = container_of(sflash, struct bcma_drv_cc, sflash); b47s->cc_read = bcm47xxsflash_bcma_cc_read; b47s->cc_write = bcm47xxsflash_bcma_cc_write; @@ -297,7 +315,6 @@ static int bcm47xxsflash_bcma_probe(struct platform_device *pdev) break; } - b47s->window = sflash->window; b47s->blocksize = sflash->blocksize; b47s->numblocks = sflash->numblocks; b47s->size = sflash->size; @@ -306,6 +323,7 @@ static int bcm47xxsflash_bcma_probe(struct platform_device *pdev) err = mtd_device_parse_register(&b47s->mtd, probes, NULL, NULL, 0); if (err) { pr_err("Failed to register MTD device: %d\n", err); + iounmap(b47s->window); return err; } @@ -321,6 +339,7 @@ static int bcm47xxsflash_bcma_remove(struct platform_device *pdev) struct bcm47xxsflash *b47s = sflash->priv; mtd_device_unregister(&b47s->mtd); + iounmap(b47s->window); return 0; } diff --git a/drivers/mtd/devices/bcm47xxsflash.h b/drivers/mtd/devices/bcm47xxsflash.h index fe93daf4f489..1564b62b412e 100644 --- a/drivers/mtd/devices/bcm47xxsflash.h +++ b/drivers/mtd/devices/bcm47xxsflash.h @@ -65,7 +65,8 @@ struct bcm47xxsflash { enum bcm47xxsflash_type type; - u32 window; + void __iomem *window; + u32 blocksize; u16 numblocks; u32 size; diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h index 846513c73606..a5ac2cad5cb7 100644 --- a/include/linux/bcma/bcma_driver_chipcommon.h +++ b/include/linux/bcma/bcma_driver_chipcommon.h @@ -587,7 +587,6 @@ struct mtd_info; struct bcma_sflash { bool present; - u32 window; u32 blocksize; u16 numblocks; u32 size; -- cgit v1.2.3 From 183aec16445f6e08c4ea6e3d5cb8f8c3d56339c1 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 3 Apr 2016 21:59:14 +0100 Subject: drm/i915/ddi: Silence compiler warning for unknown output type Silences src/drivers/gpu/drm/i915/intel_ddi.c: warning: 'port' may be used uninitialized in this function [-Wuninitialized] Reported-by: Geert Uytterhoeven Signed-off-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1459717154-27607-1-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_ddi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 766156f88ef4..921edf183d22 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -315,6 +315,9 @@ static void ddi_get_encoder_port(struct intel_encoder *intel_encoder, *dig_port = enc_to_mst(encoder)->primary; *port = (*dig_port)->port; break; + default: + WARN(1, "Invalid DDI encoder type %d\n", intel_encoder->type); + /* fallthrough and treat as unknown */ case INTEL_OUTPUT_DISPLAYPORT: case INTEL_OUTPUT_EDP: case INTEL_OUTPUT_HDMI: @@ -326,9 +329,6 @@ static void ddi_get_encoder_port(struct intel_encoder *intel_encoder, *dig_port = NULL; *port = PORT_E; break; - default: - WARN(1, "Invalid DDI encoder type %d\n", intel_encoder->type); - break; } } -- cgit v1.2.3 From 7769aea2a27db8f12859dcecce37a3da44ab588b Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Thu, 25 Feb 2016 08:57:52 +0100 Subject: mtd: pxa2xx-flash: switch back from memremap to ioremap_cached This reverts commit 06968a54790d ("mtd: pxa2xx-flash: switch from ioremap_cache to memremap"), since NOR with memory semantics in array mode and RAM are not necessarily the same thing, and architectures may implement ioremap_cached() and memremap() with different memory attributes. For this reason, ioremap_cached() has been brought back from the dead on the ARM side, so switch this driver back to using it instead of memremap(). Cc: David Woodhouse Acked-by: Brian Norris Acked-by: Dan Williams Signed-off-by: Ard Biesheuvel --- drivers/mtd/maps/pxa2xx-flash.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c index 7497090e9900..2cde28ed95c9 100644 --- a/drivers/mtd/maps/pxa2xx-flash.c +++ b/drivers/mtd/maps/pxa2xx-flash.c @@ -71,8 +71,8 @@ static int pxa2xx_flash_probe(struct platform_device *pdev) info->map.name); return -ENOMEM; } - info->map.cached = memremap(info->map.phys, info->map.size, - MEMREMAP_WB); + info->map.cached = + ioremap_cached(info->map.phys, info->map.size); if (!info->map.cached) printk(KERN_WARNING "Failed to ioremap cached %s\n", info->map.name); @@ -111,7 +111,7 @@ static int pxa2xx_flash_remove(struct platform_device *dev) map_destroy(info->mtd); iounmap(info->map.virt); if (info->map.cached) - memunmap(info->map.cached); + iounmap(info->map.cached); kfree(info); return 0; } -- cgit v1.2.3 From 27af5eea54d161e1636001a7f2b5efd3b7a3d1f9 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Mon, 4 Apr 2016 12:11:56 +0100 Subject: drm/i915: Move execlists irq handler to a bottom half Doing a lot of work in the interrupt handler introduces huge latencies to the system as a whole. Most dramatic effect can be seen by running an all engine stress test like igt/gem_exec_nop/all where, when the kernel config is lean enough, the whole system can be brought into multi-second periods of complete non-interactivty. That can look for example like this: NMI watchdog: BUG: soft lockup - CPU#0 stuck for 23s! [kworker/u8:3:143] Modules linked in: [redacted for brevity] CPU: 0 PID: 143 Comm: kworker/u8:3 Tainted: G U L 4.5.0-160321+ #183 Hardware name: Intel Corporation Broadwell Client platform/WhiteTip Mountain 1 Workqueue: i915 gen6_pm_rps_work [i915] task: ffff8800aae88000 ti: ffff8800aae90000 task.ti: ffff8800aae90000 RIP: 0010:[] [] __do_softirq+0x72/0x1d0 RSP: 0000:ffff88014f403f38 EFLAGS: 00000206 RAX: ffff8800aae94000 RBX: 0000000000000000 RCX: 00000000000006e0 RDX: 0000000000000020 RSI: 0000000004208060 RDI: 0000000000215d80 RBP: ffff88014f403f80 R08: 0000000b1b42c180 R09: 0000000000000022 R10: 0000000000000004 R11: 00000000ffffffff R12: 000000000000a030 R13: 0000000000000082 R14: ffff8800aa4d0080 R15: 0000000000000082 FS: 0000000000000000(0000) GS:ffff88014f400000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007fa53b90c000 CR3: 0000000001a0a000 CR4: 00000000001406f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Stack: 042080601b33869f ffff8800aae94000 00000000fffc2678 ffff88010000000a 0000000000000000 000000000000a030 0000000000005302 ffff8800aa4d0080 0000000000000206 ffff88014f403f90 ffffffff8104a716 ffff88014f403fa8 Call Trace: [] irq_exit+0x86/0x90 [] smp_apic_timer_interrupt+0x3d/0x50 [] apic_timer_interrupt+0x7c/0x90 [] ? gen8_write64+0x1a0/0x1a0 [i915] [] ? _raw_spin_unlock_irqrestore+0x9/0x20 [] gen8_write32+0x104/0x1a0 [i915] [] ? n_tty_receive_buf_common+0x372/0xae0 [] gen6_set_rps_thresholds+0x1be/0x330 [i915] [] gen6_set_rps+0x70/0x200 [i915] [] intel_set_rps+0x25/0x30 [i915] [] gen6_pm_rps_work+0x10d/0x2e0 [i915] [] ? finish_task_switch+0x72/0x1c0 [] process_one_work+0x139/0x350 [] worker_thread+0x126/0x490 [] ? rescuer_thread+0x320/0x320 [] kthread+0xc4/0xe0 [] ? kthread_create_on_node+0x170/0x170 [] ret_from_fork+0x3f/0x70 [] ? kthread_create_on_node+0x170/0x170 I could not explain, or find a code path, which would explain a +20 second lockup, but from some instrumentation it was apparent the interrupts off proportion of time was between 10-25% under heavy load which is quite bad. When a interrupt "cliff" is reached, which was >~320k irq/s on my machine, the whole system goes into a terrible state of the above described multi-second lockups. By moving the GT interrupt handling to a tasklet in a most simple way, the problem above disappears completely. Testing the effect on sytem-wide latencies using igt/gem_syslatency shows the following before this patch: gem_syslatency: cycles=1532739, latency mean=416531.829us max=2499237us gem_syslatency: cycles=1839434, latency mean=1458099.157us max=4998944us gem_syslatency: cycles=1432570, latency mean=2688.451us max=1201185us gem_syslatency: cycles=1533543, latency mean=416520.499us max=2498886us This shows that the unrelated process is experiencing huge delays in its wake-up latency. After the patch the results look like this: gem_syslatency: cycles=808907, latency mean=53.133us max=1640us gem_syslatency: cycles=862154, latency mean=62.778us max=2117us gem_syslatency: cycles=856039, latency mean=58.079us max=2123us gem_syslatency: cycles=841683, latency mean=56.914us max=1667us Showing a huge improvement in the unrelated process wake-up latency. It also shows an approximate halving in the number of total empty batches submitted during the test. This may not be worrying since the test puts the driver under a very unrealistic load with ncpu threads doing empty batch submission to all GPU engines each. Another benefit compared to the hard-irq handling is that now work on all engines can be dispatched in parallel since we can have up to number of CPUs active tasklets. (While previously a single hard-irq would serially dispatch on one engine after another.) More interesting scenario with regards to throughput is "gem_latency -n 100" which shows 25% better throughput and CPU usage, and 14% better dispatch latencies. I did not find any gains or regressions with Synmark2 or GLbench under light testing. More benchmarking is certainly required. v2: * execlists_lock should be taken as spin_lock_bh when queuing work from userspace now. (Chris Wilson) * uncore.lock must be taken with spin_lock_irq when submitting requests since that now runs from either softirq or process context. v3: * Expanded commit message with more testing data; * converted missed locking sites to _bh; * added execlist_lock comment. (Chris Wilson) v4: * Mention dispatch parallelism in commit. (Chris Wilson) * Do not hold uncore.lock over MMIO reads since the block is already serialised per-engine via the tasklet itself. (Chris Wilson) * intel_lrc_irq_handler should be static. (Chris Wilson) * Cancel/sync the tasklet on GPU reset. (Chris Wilson) * Document and WARN that tasklet cannot be active/pending on engine cleanup. (Chris Wilson/Imre Deak) Signed-off-by: Tvrtko Ursulin Cc: Chris Wilson Cc: Imre Deak Testcase: igt/gem_exec_nop/all Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94350 Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1459768316-6670-1-git-send-email-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/i915_debugfs.c | 5 ++--- drivers/gpu/drm/i915/i915_gem.c | 10 +++++---- drivers/gpu/drm/i915/i915_irq.c | 2 +- drivers/gpu/drm/i915/intel_lrc.c | 36 ++++++++++++++++++++------------- drivers/gpu/drm/i915/intel_lrc.h | 1 - drivers/gpu/drm/i915/intel_ringbuffer.h | 3 ++- 6 files changed, 33 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 0b25228c202e..a2e3af02c292 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2100,7 +2100,6 @@ static int i915_execlists(struct seq_file *m, void *data) for_each_engine(engine, dev_priv) { struct drm_i915_gem_request *head_req = NULL; int count = 0; - unsigned long flags; seq_printf(m, "%s\n", engine->name); @@ -2127,13 +2126,13 @@ static int i915_execlists(struct seq_file *m, void *data) i, status, ctx_id); } - spin_lock_irqsave(&engine->execlist_lock, flags); + spin_lock_bh(&engine->execlist_lock); list_for_each(cursor, &engine->execlist_queue) count++; head_req = list_first_entry_or_null(&engine->execlist_queue, struct drm_i915_gem_request, execlist_link); - spin_unlock_irqrestore(&engine->execlist_lock, flags); + spin_unlock_bh(&engine->execlist_lock); seq_printf(m, "\t%d requests in queue\n", count); if (head_req) { diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index ca96fc12cdf4..40f90c7e718a 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2842,13 +2842,15 @@ static void i915_gem_reset_engine_cleanup(struct drm_i915_private *dev_priv, */ if (i915.enable_execlists) { - spin_lock_irq(&engine->execlist_lock); + /* Ensure irq handler finishes or is cancelled. */ + tasklet_kill(&engine->irq_tasklet); + spin_lock_bh(&engine->execlist_lock); /* list_splice_tail_init checks for empty lists */ list_splice_tail_init(&engine->execlist_queue, &engine->execlist_retired_req_list); + spin_unlock_bh(&engine->execlist_lock); - spin_unlock_irq(&engine->execlist_lock); intel_execlists_retire_requests(engine); } @@ -2968,9 +2970,9 @@ i915_gem_retire_requests(struct drm_device *dev) i915_gem_retire_requests_ring(engine); idle &= list_empty(&engine->request_list); if (i915.enable_execlists) { - spin_lock_irq(&engine->execlist_lock); + spin_lock_bh(&engine->execlist_lock); idle &= list_empty(&engine->execlist_queue); - spin_unlock_irq(&engine->execlist_lock); + spin_unlock_bh(&engine->execlist_lock); intel_execlists_retire_requests(engine); } diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a9c18137e3f5..c85eb8dec2dc 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1323,7 +1323,7 @@ gen8_cs_irq_handler(struct intel_engine_cs *engine, u32 iir, int test_shift) if (iir & (GT_RENDER_USER_INTERRUPT << test_shift)) notify_ring(engine); if (iir & (GT_CONTEXT_SWITCH_INTERRUPT << test_shift)) - intel_lrc_irq_handler(engine); + tasklet_schedule(&engine->irq_tasklet); } static irqreturn_t gen8_gt_irq_handler(struct drm_i915_private *dev_priv, diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 5d4ca3b11ae2..a1db6a02cf23 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -131,6 +131,7 @@ * preemption, but just sampling the new tail pointer). * */ +#include #include #include @@ -418,20 +419,18 @@ static void execlists_submit_requests(struct drm_i915_gem_request *rq0, { struct drm_i915_private *dev_priv = rq0->i915; - /* BUG_ON(!irqs_disabled()); */ - execlists_update_context(rq0); if (rq1) execlists_update_context(rq1); - spin_lock(&dev_priv->uncore.lock); + spin_lock_irq(&dev_priv->uncore.lock); intel_uncore_forcewake_get__locked(dev_priv, FORCEWAKE_ALL); execlists_elsp_write(rq0, rq1); intel_uncore_forcewake_put__locked(dev_priv, FORCEWAKE_ALL); - spin_unlock(&dev_priv->uncore.lock); + spin_unlock_irq(&dev_priv->uncore.lock); } static void execlists_context_unqueue(struct intel_engine_cs *engine) @@ -538,13 +537,14 @@ get_context_status(struct intel_engine_cs *engine, unsigned int read_pointer, /** * intel_lrc_irq_handler() - handle Context Switch interrupts - * @ring: Engine Command Streamer to handle. + * @engine: Engine Command Streamer to handle. * * Check the unread Context Status Buffers and manage the submission of new * contexts to the ELSP accordingly. */ -void intel_lrc_irq_handler(struct intel_engine_cs *engine) +static void intel_lrc_irq_handler(unsigned long data) { + struct intel_engine_cs *engine = (struct intel_engine_cs *)data; struct drm_i915_private *dev_priv = engine->dev->dev_private; u32 status_pointer; unsigned int read_pointer, write_pointer; @@ -552,8 +552,7 @@ void intel_lrc_irq_handler(struct intel_engine_cs *engine) unsigned int csb_read = 0, i; unsigned int submit_contexts = 0; - spin_lock(&dev_priv->uncore.lock); - intel_uncore_forcewake_get__locked(dev_priv, FORCEWAKE_ALL); + intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); status_pointer = I915_READ_FW(RING_CONTEXT_STATUS_PTR(engine)); @@ -578,8 +577,7 @@ void intel_lrc_irq_handler(struct intel_engine_cs *engine) _MASKED_FIELD(GEN8_CSB_READ_PTR_MASK, engine->next_context_status_buffer << 8)); - intel_uncore_forcewake_put__locked(dev_priv, FORCEWAKE_ALL); - spin_unlock(&dev_priv->uncore.lock); + intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); spin_lock(&engine->execlist_lock); @@ -621,7 +619,7 @@ static void execlists_context_queue(struct drm_i915_gem_request *request) i915_gem_request_reference(request); - spin_lock_irq(&engine->execlist_lock); + spin_lock_bh(&engine->execlist_lock); list_for_each_entry(cursor, &engine->execlist_queue, execlist_link) if (++num_elements > 2) @@ -646,7 +644,7 @@ static void execlists_context_queue(struct drm_i915_gem_request *request) if (num_elements == 0) execlists_context_unqueue(engine); - spin_unlock_irq(&engine->execlist_lock); + spin_unlock_bh(&engine->execlist_lock); } static int logical_ring_invalidate_all_caches(struct drm_i915_gem_request *req) @@ -1033,9 +1031,9 @@ void intel_execlists_retire_requests(struct intel_engine_cs *engine) return; INIT_LIST_HEAD(&retired_list); - spin_lock_irq(&engine->execlist_lock); + spin_lock_bh(&engine->execlist_lock); list_replace_init(&engine->execlist_retired_req_list, &retired_list); - spin_unlock_irq(&engine->execlist_lock); + spin_unlock_bh(&engine->execlist_lock); list_for_each_entry_safe(req, tmp, &retired_list, execlist_link) { struct intel_context *ctx = req->ctx; @@ -2016,6 +2014,13 @@ void intel_logical_ring_cleanup(struct intel_engine_cs *engine) if (!intel_engine_initialized(engine)) return; + /* + * Tasklet cannot be active at this point due intel_mark_active/idle + * so this is just for documentation. + */ + if (WARN_ON(test_bit(TASKLET_STATE_SCHED, &engine->irq_tasklet.state))) + tasklet_kill(&engine->irq_tasklet); + dev_priv = engine->dev->dev_private; if (engine->buffer) { @@ -2089,6 +2094,9 @@ logical_ring_init(struct drm_device *dev, struct intel_engine_cs *engine) INIT_LIST_HEAD(&engine->execlist_retired_req_list); spin_lock_init(&engine->execlist_lock); + tasklet_init(&engine->irq_tasklet, + intel_lrc_irq_handler, (unsigned long)engine); + logical_ring_init_platform_invariants(engine); ret = i915_cmd_parser_init_ring(engine); diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index a17cb12221ba..0b0853eee91e 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -118,7 +118,6 @@ int intel_execlists_submission(struct i915_execbuffer_params *params, struct drm_i915_gem_execbuffer2 *args, struct list_head *vmas); -void intel_lrc_irq_handler(struct intel_engine_cs *engine); void intel_execlists_retire_requests(struct intel_engine_cs *engine); #endif /* _INTEL_LRC_H_ */ diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 221a94627aab..18074ab55f61 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -266,7 +266,8 @@ struct intel_engine_cs { } semaphore; /* Execlists */ - spinlock_t execlist_lock; + struct tasklet_struct irq_tasklet; + spinlock_t execlist_lock; /* used inside tasklet, use spin_lock_bh */ struct list_head execlist_queue; struct list_head execlist_retired_req_list; unsigned int next_context_status_buffer; -- cgit v1.2.3 From ef859312c3a16b42f398e6dbb14de23bffd5dd41 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Mon, 14 Mar 2016 16:51:09 +0200 Subject: dmaengine: core: Use dev_ functions for debug and error prints According to dmaengine kerneldoc the struct dma_chan has always a non-NULL pointer to DMA device and a test in dma_async_device_register() validates that DMA device must also point to struct device. All pr_ prints except one in dma_channel_table_init() have valid DMA channel or DMA device pointer available which allow convert them to use dev_ functions and thus able to show the associated DMA device. Signed-off-by: Jarkko Nikula Signed-off-by: Vinod Koul --- drivers/dma/dmaengine.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 0cb259c59916..a7131d4141d8 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -289,7 +289,7 @@ enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie) do { status = dma_async_is_tx_complete(chan, cookie, NULL, NULL); if (time_after_eq(jiffies, dma_sync_wait_timeout)) { - pr_err("%s: timeout!\n", __func__); + dev_err(chan->device->dev, "%s: timeout!\n", __func__); return DMA_ERROR; } if (status != DMA_IN_PROGRESS) @@ -518,7 +518,7 @@ static struct dma_chan *private_candidate(const dma_cap_mask_t *mask, struct dma_chan *chan; if (mask && !__dma_device_satisfies_mask(dev, mask)) { - pr_debug("%s: wrong capabilities\n", __func__); + dev_dbg(dev->dev, "%s: wrong capabilities\n", __func__); return NULL; } /* devices with multiple channels need special handling as we need to @@ -533,12 +533,12 @@ static struct dma_chan *private_candidate(const dma_cap_mask_t *mask, list_for_each_entry(chan, &dev->channels, device_node) { if (chan->client_count) { - pr_debug("%s: %s busy\n", + dev_dbg(dev->dev, "%s: %s busy\n", __func__, dma_chan_name(chan)); continue; } if (fn && !fn(chan, fn_param)) { - pr_debug("%s: %s filter said false\n", + dev_dbg(dev->dev, "%s: %s filter said false\n", __func__, dma_chan_name(chan)); continue; } @@ -567,11 +567,12 @@ static struct dma_chan *find_candidate(struct dma_device *device, if (err) { if (err == -ENODEV) { - pr_debug("%s: %s module removed\n", __func__, - dma_chan_name(chan)); + dev_dbg(device->dev, "%s: %s module removed\n", + __func__, dma_chan_name(chan)); list_del_rcu(&device->global_node); } else - pr_debug("%s: failed to get %s: (%d)\n", + dev_dbg(device->dev, + "%s: failed to get %s: (%d)\n", __func__, dma_chan_name(chan), err); if (--device->privatecnt == 0) @@ -602,7 +603,8 @@ struct dma_chan *dma_get_slave_channel(struct dma_chan *chan) device->privatecnt++; err = dma_chan_get(chan); if (err) { - pr_debug("%s: failed to get %s: (%d)\n", + dev_dbg(chan->device->dev, + "%s: failed to get %s: (%d)\n", __func__, dma_chan_name(chan), err); chan = NULL; if (--device->privatecnt == 0) @@ -662,7 +664,7 @@ struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask, } mutex_unlock(&dma_list_mutex); - pr_debug("%s: %s (%s)\n", + dev_dbg(chan->device->dev, "%s: %s (%s)\n", __func__, chan ? "success" : "fail", chan ? dma_chan_name(chan) : NULL); @@ -814,8 +816,9 @@ void dmaengine_get(void) list_del_rcu(&device->global_node); break; } else if (err) - pr_debug("%s: failed to get %s: (%d)\n", - __func__, dma_chan_name(chan), err); + dev_dbg(chan->device->dev, + "%s: failed to get %s: (%d)\n", + __func__, dma_chan_name(chan), err); } } @@ -1222,8 +1225,9 @@ dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx) while (tx->cookie == -EBUSY) { if (time_after_eq(jiffies, dma_sync_wait_timeout)) { - pr_err("%s timeout waiting for descriptor submission\n", - __func__); + dev_err(tx->chan->device->dev, + "%s timeout waiting for descriptor submission\n", + __func__); return DMA_ERROR; } cpu_relax(); -- cgit v1.2.3 From c8f5c4c7c82c916faf4699927801c8038d1fac51 Mon Sep 17 00:00:00 2001 From: Cristina Ciocan Date: Fri, 1 Apr 2016 14:00:02 +0300 Subject: pinctrl: baytrail: Add pin control data structures In order to implement pin control for Baytrail, we need data structures in which to store and pass along pin, group, function, community and SOC data information. Baytrail has 3 GPIO controllers. Add SCORE, NCORE and SUS controller data: - pins (for all controllers), - pad map for pins (for all controllers; we need this since pads are not ordered), - groups (for SCORE and SUS controllers), - functions (for SCORE and SUS controllers), - communities (for all controllers), - soc specific data gathering all of the above and the ACPI UID (for all controllers) This information is useful for pin control functionality. NCORE data is lighter than the other two controllers' due to lack of pin documentation in the public datasheet. Datasheet: http://www.intel.com/content/www/us/en/embedded/products/bay-trail/atom-e3800-family-datasheet.html Signed-off-by: Cristina Ciocan Acked-by: Mika Westerberg Signed-off-by: Linus Walleij --- drivers/pinctrl/intel/pinctrl-baytrail.c | 628 +++++++++++++++++++++++++++++-- 1 file changed, 606 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index 21b79a446d5a..364f56c3991d 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -73,17 +73,207 @@ #define BYT_NCORE_ACPI_UID "2" #define BYT_SUS_ACPI_UID "3" -/* - * Baytrail gpio controller consist of three separate sub-controllers called - * SCORE, NCORE and SUS. The sub-controllers are identified by their acpi UID. - * - * GPIO numbering is _not_ ordered meaning that gpio # 0 in ACPI namespace does - * _not_ correspond to the first gpio register at controller's gpio base. - * There is no logic or pattern in mapping gpio numbers to registers (pads) so - * each sub-controller needs to have its own mapping table - */ +struct byt_gpio_pin_context { + u32 conf0; + u32 val; +}; + +struct byt_simple_func_mux { + const char *name; + unsigned short func; +}; + +struct byt_mixed_func_mux { + const char *name; + const unsigned short *func_values; +}; + +struct byt_pingroup { + const char *name; + const unsigned int *pins; + size_t npins; + unsigned short has_simple_funcs; + union { + const struct byt_simple_func_mux *simple_funcs; + const struct byt_mixed_func_mux *mixed_funcs; + }; + size_t nfuncs; +}; + +struct byt_function { + const char *name; + const char * const *groups; + size_t ngroups; +}; + +struct byt_community { + unsigned int pin_base; + size_t npins; + const unsigned int *pad_map; + void __iomem *reg_base; +}; + +#define SIMPLE_FUNC(n, f) \ + { \ + .name = (n), \ + .func = (f), \ + } +#define MIXED_FUNC(n, f) \ + { \ + .name = (n), \ + .func_values = (f), \ + } + +#define PIN_GROUP_SIMPLE(n, p, f) \ + { \ + .name = (n), \ + .pins = (p), \ + .npins = ARRAY_SIZE((p)), \ + .has_simple_funcs = 1, \ + .simple_funcs = (f), \ + .nfuncs = ARRAY_SIZE((f)), \ + } +#define PIN_GROUP_MIXED(n, p, f) \ + { \ + .name = (n), \ + .pins = (p), \ + .npins = ARRAY_SIZE((p)), \ + .has_simple_funcs = 0, \ + .mixed_funcs = (f), \ + .nfuncs = ARRAY_SIZE((f)), \ + } + +#define FUNCTION(n, g) \ + { \ + .name = (n), \ + .groups = (g), \ + .ngroups = ARRAY_SIZE((g)), \ + } + +#define COMMUNITY(p, n, map) \ + { \ + .pin_base = (p), \ + .npins = (n), \ + .pad_map = (map),\ + } -/* score_pins[gpio_nr] = pad_nr */ +struct byt_pinctrl_soc_data { + const char *uid; + const struct pinctrl_pin_desc *pins; + size_t npins; + const struct byt_pingroup *groups; + size_t ngroups; + const struct byt_function *functions; + size_t nfunctions; + const struct byt_community *communities; + size_t ncommunities; +}; + +/* SCORE pins, aka GPIOC_ or GPIO_S0_SC[] */ +static const struct pinctrl_pin_desc byt_score_pins[] = { + PINCTRL_PIN(0, "SATA_GP0"), + PINCTRL_PIN(1, "SATA_GP1"), + PINCTRL_PIN(2, "SATA_LED#"), + PINCTRL_PIN(3, "PCIE_CLKREQ0"), + PINCTRL_PIN(4, "PCIE_CLKREQ1"), + PINCTRL_PIN(5, "PCIE_CLKREQ2"), + PINCTRL_PIN(6, "PCIE_CLKREQ3"), + PINCTRL_PIN(7, "SD3_WP"), + PINCTRL_PIN(8, "HDA_RST"), + PINCTRL_PIN(9, "HDA_SYNC"), + PINCTRL_PIN(10, "HDA_CLK"), + PINCTRL_PIN(11, "HDA_SDO"), + PINCTRL_PIN(12, "HDA_SDI0"), + PINCTRL_PIN(13, "HDA_SDI1"), + PINCTRL_PIN(14, "GPIO_S0_SC14"), + PINCTRL_PIN(15, "GPIO_S0_SC15"), + PINCTRL_PIN(16, "MMC1_CLK"), + PINCTRL_PIN(17, "MMC1_D0"), + PINCTRL_PIN(18, "MMC1_D1"), + PINCTRL_PIN(19, "MMC1_D2"), + PINCTRL_PIN(20, "MMC1_D3"), + PINCTRL_PIN(21, "MMC1_D4"), + PINCTRL_PIN(22, "MMC1_D5"), + PINCTRL_PIN(23, "MMC1_D6"), + PINCTRL_PIN(24, "MMC1_D7"), + PINCTRL_PIN(25, "MMC1_CMD"), + PINCTRL_PIN(26, "MMC1_RST"), + PINCTRL_PIN(27, "SD2_CLK"), + PINCTRL_PIN(28, "SD2_D0"), + PINCTRL_PIN(29, "SD2_D1"), + PINCTRL_PIN(30, "SD2_D2"), + PINCTRL_PIN(31, "SD2_D3_CD"), + PINCTRL_PIN(32, "SD2_CMD"), + PINCTRL_PIN(33, "SD3_CLK"), + PINCTRL_PIN(34, "SD3_D0"), + PINCTRL_PIN(35, "SD3_D1"), + PINCTRL_PIN(36, "SD3_D2"), + PINCTRL_PIN(37, "SD3_D3"), + PINCTRL_PIN(38, "SD3_CD"), + PINCTRL_PIN(39, "SD3_CMD"), + PINCTRL_PIN(40, "SD3_1P8EN"), + PINCTRL_PIN(41, "SD3_PWREN#"), + PINCTRL_PIN(42, "ILB_LPC_AD0"), + PINCTRL_PIN(43, "ILB_LPC_AD1"), + PINCTRL_PIN(44, "ILB_LPC_AD2"), + PINCTRL_PIN(45, "ILB_LPC_AD3"), + PINCTRL_PIN(46, "ILB_LPC_FRAME"), + PINCTRL_PIN(47, "ILB_LPC_CLK0"), + PINCTRL_PIN(48, "ILB_LPC_CLK1"), + PINCTRL_PIN(49, "ILB_LPC_CLKRUN"), + PINCTRL_PIN(50, "ILB_LPC_SERIRQ"), + PINCTRL_PIN(51, "PCU_SMB_DATA"), + PINCTRL_PIN(52, "PCU_SMB_CLK"), + PINCTRL_PIN(53, "PCU_SMB_ALERT"), + PINCTRL_PIN(54, "ILB_8254_SPKR"), + PINCTRL_PIN(55, "GPIO_S0_SC55"), + PINCTRL_PIN(56, "GPIO_S0_SC56"), + PINCTRL_PIN(57, "GPIO_S0_SC57"), + PINCTRL_PIN(58, "GPIO_S0_SC58"), + PINCTRL_PIN(59, "GPIO_S0_SC59"), + PINCTRL_PIN(60, "GPIO_S0_SC60"), + PINCTRL_PIN(61, "GPIO_S0_SC61"), + PINCTRL_PIN(62, "LPE_I2S2_CLK"), + PINCTRL_PIN(63, "LPE_I2S2_FRM"), + PINCTRL_PIN(64, "LPE_I2S2_DATAIN"), + PINCTRL_PIN(65, "LPE_I2S2_DATAOUT"), + PINCTRL_PIN(66, "SIO_SPI_CS"), + PINCTRL_PIN(67, "SIO_SPI_MISO"), + PINCTRL_PIN(68, "SIO_SPI_MOSI"), + PINCTRL_PIN(69, "SIO_SPI_CLK"), + PINCTRL_PIN(70, "SIO_UART1_RXD"), + PINCTRL_PIN(71, "SIO_UART1_TXD"), + PINCTRL_PIN(72, "SIO_UART1_RTS"), + PINCTRL_PIN(73, "SIO_UART1_CTS"), + PINCTRL_PIN(74, "SIO_UART2_RXD"), + PINCTRL_PIN(75, "SIO_UART2_TXD"), + PINCTRL_PIN(76, "SIO_UART2_RTS"), + PINCTRL_PIN(77, "SIO_UART2_CTS"), + PINCTRL_PIN(78, "SIO_I2C0_DATA"), + PINCTRL_PIN(79, "SIO_I2C0_CLK"), + PINCTRL_PIN(80, "SIO_I2C1_DATA"), + PINCTRL_PIN(81, "SIO_I2C1_CLK"), + PINCTRL_PIN(82, "SIO_I2C2_DATA"), + PINCTRL_PIN(83, "SIO_I2C2_CLK"), + PINCTRL_PIN(84, "SIO_I2C3_DATA"), + PINCTRL_PIN(85, "SIO_I2C3_CLK"), + PINCTRL_PIN(86, "SIO_I2C4_DATA"), + PINCTRL_PIN(87, "SIO_I2C4_CLK"), + PINCTRL_PIN(88, "SIO_I2C5_DATA"), + PINCTRL_PIN(89, "SIO_I2C5_CLK"), + PINCTRL_PIN(90, "SIO_I2C6_DATA"), + PINCTRL_PIN(91, "SIO_I2C6_CLK"), + PINCTRL_PIN(92, "GPIO_S0_SC92"), + PINCTRL_PIN(93, "GPIO_S0_SC93"), + PINCTRL_PIN(94, "SIO_PWM0"), + PINCTRL_PIN(95, "SIO_PWM1"), + PINCTRL_PIN(96, "PMC_PLT_CLK0"), + PINCTRL_PIN(97, "PMC_PLT_CLK1"), + PINCTRL_PIN(98, "PMC_PLT_CLK2"), + PINCTRL_PIN(99, "PMC_PLT_CLK3"), + PINCTRL_PIN(100, "PMC_PLT_CLK4"), + PINCTRL_PIN(101, "PMC_PLT_CLK5"), +}; static unsigned const score_pins[BYT_NGPIO_SCORE] = { 85, 89, 93, 96, 99, 102, 98, 101, 34, 37, @@ -99,13 +289,285 @@ static unsigned const score_pins[BYT_NGPIO_SCORE] = { 97, 100, }; -static unsigned const ncore_pins[BYT_NGPIO_NCORE] = { - 19, 18, 17, 20, 21, 22, 24, 25, 23, 16, - 14, 15, 12, 26, 27, 1, 4, 8, 11, 0, - 3, 6, 10, 13, 2, 5, 9, 7, +static const unsigned int byt_score_pins_map[BYT_NGPIO_SCORE] = { + 85, 89, 93, 96, 99, 102, 98, 101, 34, 37, + 36, 38, 39, 35, 40, 84, 62, 61, 64, 59, + 54, 56, 60, 55, 63, 57, 51, 50, 53, 47, + 52, 49, 48, 43, 46, 41, 45, 42, 58, 44, + 95, 105, 70, 68, 67, 66, 69, 71, 65, 72, + 86, 90, 88, 92, 103, 77, 79, 83, 78, 81, + 80, 82, 13, 12, 15, 14, 17, 18, 19, 16, + 2, 1, 0, 4, 6, 7, 9, 8, 33, 32, + 31, 30, 29, 27, 25, 28, 26, 23, 21, 20, + 24, 22, 5, 3, 10, 11, 106, 87, 91, 104, + 97, 100, +}; + +/* SCORE groups */ +static const unsigned int byt_score_uart1_pins[] = { 70, 71, 72, 73 }; +static const unsigned int byt_score_uart2_pins[] = { 74, 75, 76, 77 }; +static const struct byt_simple_func_mux byt_score_uart_mux[] = { + SIMPLE_FUNC("uart", 1), +}; + +static const unsigned int byt_score_pwm0_pins[] = { 94 }; +static const unsigned int byt_score_pwm1_pins[] = { 95 }; +static const struct byt_simple_func_mux byt_score_pwm_mux[] = { + SIMPLE_FUNC("pwm", 1), +}; + +static const unsigned int byt_score_sio_spi_pins[] = { 66, 67, 68, 69 }; +static const struct byt_simple_func_mux byt_score_spi_mux[] = { + SIMPLE_FUNC("spi", 1), +}; + +static const unsigned int byt_score_i2c5_pins[] = { 88, 89 }; +static const unsigned int byt_score_i2c6_pins[] = { 90, 91 }; +static const unsigned int byt_score_i2c4_pins[] = { 86, 87 }; +static const unsigned int byt_score_i2c3_pins[] = { 84, 85 }; +static const unsigned int byt_score_i2c2_pins[] = { 82, 83 }; +static const unsigned int byt_score_i2c1_pins[] = { 80, 81 }; +static const unsigned int byt_score_i2c0_pins[] = { 78, 79 }; +static const struct byt_simple_func_mux byt_score_i2c_mux[] = { + SIMPLE_FUNC("i2c", 1), +}; + +static const unsigned int byt_score_ssp0_pins[] = { 8, 9, 10, 11 }; +static const unsigned int byt_score_ssp1_pins[] = { 12, 13, 14, 15 }; +static const unsigned int byt_score_ssp2_pins[] = { 62, 63, 64, 65 }; +static const struct byt_simple_func_mux byt_score_ssp_mux[] = { + SIMPLE_FUNC("ssp", 1), +}; + +static const unsigned int byt_score_sdcard_pins[] = { + 7, 33, 34, 35, 36, 37, 38, 39, 40, 41, +}; +static const unsigned short byt_score_sdcard_mux_values[] = { + 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; +static const struct byt_mixed_func_mux byt_score_sdcard_mux[] = { + MIXED_FUNC("sdcard", byt_score_sdcard_mux_values), +}; + +static const unsigned int byt_score_sdio_pins[] = { 27, 28, 29, 30, 31, 32 }; +static const struct byt_simple_func_mux byt_score_sdio_mux[] = { + SIMPLE_FUNC("sdio", 1), +}; + +static const unsigned int byt_score_emmc_pins[] = { + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, +}; +static const struct byt_simple_func_mux byt_score_emmc_mux[] = { + SIMPLE_FUNC("emmc", 1), +}; + +static const unsigned int byt_score_ilb_lpc_pins[] = { + 42, 43, 44, 45, 46, 47, 48, 49, 50, +}; +static const struct byt_simple_func_mux byt_score_lpc_mux[] = { + SIMPLE_FUNC("lpc", 1), +}; + +static const unsigned int byt_score_sata_pins[] = { 0, 1, 2 }; +static const struct byt_simple_func_mux byt_score_sata_mux[] = { + SIMPLE_FUNC("sata", 1), +}; + +static const unsigned int byt_score_plt_clk0_pins[] = { 96 }; +static const unsigned int byt_score_plt_clk1_pins[] = { 97 }; +static const unsigned int byt_score_plt_clk2_pins[] = { 98 }; +static const unsigned int byt_score_plt_clk4_pins[] = { 99 }; +static const unsigned int byt_score_plt_clk5_pins[] = { 100 }; +static const unsigned int byt_score_plt_clk3_pins[] = { 101 }; +static const struct byt_simple_func_mux byt_score_plt_clk_mux[] = { + SIMPLE_FUNC("plt_clk", 1), }; -static unsigned const sus_pins[BYT_NGPIO_SUS] = { +static const unsigned int byt_score_smbus_pins[] = { 51, 52, 53 }; +static const struct byt_simple_func_mux byt_score_smbus_mux[] = { + SIMPLE_FUNC("smbus", 1), +}; + +static const struct byt_pingroup byt_score_groups[] = { + PIN_GROUP_SIMPLE("uart1_grp", + byt_score_uart1_pins, byt_score_uart_mux), + PIN_GROUP_SIMPLE("uart2_grp", + byt_score_uart2_pins, byt_score_uart_mux), + PIN_GROUP_SIMPLE("pwm0_grp", + byt_score_pwm0_pins, byt_score_pwm_mux), + PIN_GROUP_SIMPLE("pwm1_grp", + byt_score_pwm1_pins, byt_score_pwm_mux), + PIN_GROUP_SIMPLE("ssp2_grp", + byt_score_ssp2_pins, byt_score_pwm_mux), + PIN_GROUP_SIMPLE("sio_spi_grp", + byt_score_sio_spi_pins, byt_score_spi_mux), + PIN_GROUP_SIMPLE("i2c5_grp", + byt_score_i2c5_pins, byt_score_i2c_mux), + PIN_GROUP_SIMPLE("i2c6_grp", + byt_score_i2c6_pins, byt_score_i2c_mux), + PIN_GROUP_SIMPLE("i2c4_grp", + byt_score_i2c4_pins, byt_score_i2c_mux), + PIN_GROUP_SIMPLE("i2c3_grp", + byt_score_i2c3_pins, byt_score_i2c_mux), + PIN_GROUP_SIMPLE("i2c2_grp", + byt_score_i2c2_pins, byt_score_i2c_mux), + PIN_GROUP_SIMPLE("i2c1_grp", + byt_score_i2c1_pins, byt_score_i2c_mux), + PIN_GROUP_SIMPLE("i2c0_grp", + byt_score_i2c0_pins, byt_score_i2c_mux), + PIN_GROUP_SIMPLE("ssp0_grp", + byt_score_ssp0_pins, byt_score_ssp_mux), + PIN_GROUP_SIMPLE("ssp1_grp", + byt_score_ssp1_pins, byt_score_ssp_mux), + PIN_GROUP_MIXED("sdcard_grp", + byt_score_sdcard_pins, byt_score_sdcard_mux), + PIN_GROUP_SIMPLE("sdio_grp", + byt_score_sdio_pins, byt_score_sdio_mux), + PIN_GROUP_SIMPLE("emmc_grp", + byt_score_emmc_pins, byt_score_emmc_mux), + PIN_GROUP_SIMPLE("lpc_grp", + byt_score_ilb_lpc_pins, byt_score_lpc_mux), + PIN_GROUP_SIMPLE("sata_grp", + byt_score_sata_pins, byt_score_sata_mux), + PIN_GROUP_SIMPLE("plt_clk0_grp", + byt_score_plt_clk0_pins, byt_score_plt_clk_mux), + PIN_GROUP_SIMPLE("plt_clk1_grp", + byt_score_plt_clk1_pins, byt_score_plt_clk_mux), + PIN_GROUP_SIMPLE("plt_clk2_grp", + byt_score_plt_clk2_pins, byt_score_plt_clk_mux), + PIN_GROUP_SIMPLE("plt_clk3_grp", + byt_score_plt_clk3_pins, byt_score_plt_clk_mux), + PIN_GROUP_SIMPLE("plt_clk4_grp", + byt_score_plt_clk4_pins, byt_score_plt_clk_mux), + PIN_GROUP_SIMPLE("plt_clk5_grp", + byt_score_plt_clk5_pins, byt_score_plt_clk_mux), + PIN_GROUP_SIMPLE("smbus_grp", + byt_score_smbus_pins, byt_score_smbus_mux), +}; + +static const char * const byt_score_uart_groups[] = { + "uart1_grp", "uart2_grp", +}; +static const char * const byt_score_pwm_groups[] = { + "pwm0_grp", "pwm1_grp", +}; +static const char * const byt_score_ssp_groups[] = { + "ssp0_grp", "ssp1_grp", "ssp2_grp", +}; +static const char * const byt_score_spi_groups[] = { "sio_spi_grp" }; +static const char * const byt_score_i2c_groups[] = { + "i2c0_grp", "i2c1_grp", "i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp", + "i2c6_grp", +}; +static const char * const byt_score_sdcard_groups[] = { "sdcard_grp" }; +static const char * const byt_score_sdio_groups[] = { "sdio_grp" }; +static const char * const byt_score_emmc_groups[] = { "emmc_grp" }; +static const char * const byt_score_lpc_groups[] = { "lpc_grp" }; +static const char * const byt_score_sata_groups[] = { "sata_grp" }; +static const char * const byt_score_plt_clk_groups[] = { + "plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp", + "plt_clk4_grp", "plt_clk5_grp", +}; +static const char * const byt_score_smbus_groups[] = { "smbus_grp" }; +static const char * const byt_score_gpio_groups[] = { + "uart1_grp", "uart2_grp", "pwm0_grp", "pwm1_grp", "ssp0_grp", + "ssp1_grp", "ssp2_grp", "sio_spi_grp", "i2c0_grp", "i2c1_grp", + "i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp", "i2c6_grp", + "sdcard_grp", "sdio_grp", "emmc_grp", "lpc_grp", "sata_grp", + "plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp", + "plt_clk4_grp", "plt_clk5_grp", "smbus_grp", + +}; + +static const struct byt_function byt_score_functions[] = { + FUNCTION("uart", byt_score_uart_groups), + FUNCTION("pwm", byt_score_pwm_groups), + FUNCTION("ssp", byt_score_ssp_groups), + FUNCTION("spi", byt_score_spi_groups), + FUNCTION("i2c", byt_score_i2c_groups), + FUNCTION("sdcard", byt_score_sdcard_groups), + FUNCTION("sdio", byt_score_sdio_groups), + FUNCTION("emmc", byt_score_emmc_groups), + FUNCTION("lpc", byt_score_lpc_groups), + FUNCTION("sata", byt_score_sata_groups), + FUNCTION("plt_clk", byt_score_plt_clk_groups), + FUNCTION("smbus", byt_score_smbus_groups), + FUNCTION("gpio", byt_score_gpio_groups), +}; + +static const struct byt_community byt_score_communities[] = { + COMMUNITY(0, BYT_NGPIO_SCORE, byt_score_pins_map), +}; + +static const struct byt_pinctrl_soc_data byt_score_soc_data = { + .uid = BYT_SCORE_ACPI_UID, + .pins = byt_score_pins, + .npins = ARRAY_SIZE(byt_score_pins), + .groups = byt_score_groups, + .ngroups = ARRAY_SIZE(byt_score_groups), + .functions = byt_score_functions, + .nfunctions = ARRAY_SIZE(byt_score_functions), + .communities = byt_score_communities, + .ncommunities = ARRAY_SIZE(byt_score_communities), +}; + +/* SUS pins, aka GPIOS_ or GPIO_S5[] */ +static const struct pinctrl_pin_desc byt_sus_pins[] = { + PINCTRL_PIN(0, "GPIO_S50"), + PINCTRL_PIN(1, "GPIO_S51"), + PINCTRL_PIN(2, "GPIO_S52"), + PINCTRL_PIN(3, "GPIO_S53"), + PINCTRL_PIN(4, "GPIO_S54"), + PINCTRL_PIN(5, "GPIO_S55"), + PINCTRL_PIN(6, "GPIO_S56"), + PINCTRL_PIN(7, "GPIO_S57"), + PINCTRL_PIN(8, "GPIO_S58"), + PINCTRL_PIN(9, "GPIO_S59"), + PINCTRL_PIN(10, "GPIO_S510"), + PINCTRL_PIN(11, "PMC_SUSPWRDNACK"), + PINCTRL_PIN(12, "PMC_SUSCLK0"), + PINCTRL_PIN(13, "GPIO_S513"), + PINCTRL_PIN(14, "USB_ULPI_RST"), + PINCTRL_PIN(15, "PMC_WAKE_PCIE0#"), + PINCTRL_PIN(16, "PMC_PWRBTN"), + PINCTRL_PIN(17, "GPIO_S517"), + PINCTRL_PIN(18, "PMC_SUS_STAT"), + PINCTRL_PIN(19, "USB_OC0"), + PINCTRL_PIN(20, "USB_OC1"), + PINCTRL_PIN(21, "PCU_SPI_CS1"), + PINCTRL_PIN(22, "GPIO_S522"), + PINCTRL_PIN(23, "GPIO_S523"), + PINCTRL_PIN(24, "GPIO_S524"), + PINCTRL_PIN(25, "GPIO_S525"), + PINCTRL_PIN(26, "GPIO_S526"), + PINCTRL_PIN(27, "GPIO_S527"), + PINCTRL_PIN(28, "GPIO_S528"), + PINCTRL_PIN(29, "GPIO_S529"), + PINCTRL_PIN(30, "GPIO_S530"), + PINCTRL_PIN(31, "USB_ULPI_CLK"), + PINCTRL_PIN(32, "USB_ULPI_DATA0"), + PINCTRL_PIN(33, "USB_ULPI_DATA1"), + PINCTRL_PIN(34, "USB_ULPI_DATA2"), + PINCTRL_PIN(35, "USB_ULPI_DATA3"), + PINCTRL_PIN(36, "USB_ULPI_DATA4"), + PINCTRL_PIN(37, "USB_ULPI_DATA5"), + PINCTRL_PIN(38, "USB_ULPI_DATA6"), + PINCTRL_PIN(39, "USB_ULPI_DATA7"), + PINCTRL_PIN(40, "USB_ULPI_DIR"), + PINCTRL_PIN(41, "USB_ULPI_NXT"), + PINCTRL_PIN(42, "USB_ULPI_STP"), + PINCTRL_PIN(43, "USB_ULPI_REFCLK"), +}; + +static const unsigned int sus_pins[BYT_NGPIO_SUS] = { + 29, 33, 30, 31, 32, 34, 36, 35, 38, 37, + 18, 7, 11, 20, 17, 1, 8, 10, 19, 12, + 0, 2, 23, 39, 28, 27, 22, 21, 24, 25, + 26, 51, 56, 54, 49, 55, 48, 57, 50, 58, + 52, 53, 59, 40, +}; + +static const unsigned int byt_sus_pins_map[BYT_NGPIO_SUS] = { 29, 33, 30, 31, 32, 34, 36, 35, 38, 37, 18, 7, 11, 20, 17, 1, 8, 10, 19, 12, 0, 2, 23, 39, 28, 27, 22, 21, 24, 25, @@ -113,6 +575,126 @@ static unsigned const sus_pins[BYT_NGPIO_SUS] = { 52, 53, 59, 40, }; +static const unsigned int byt_sus_usb_over_current_pins[] = { 19, 20 }; +static const struct byt_simple_func_mux byt_sus_usb_oc_mux[] = { + SIMPLE_FUNC("usb", 0), + SIMPLE_FUNC("gpio", 1), +}; + +static const unsigned int byt_sus_usb_ulpi_pins[] = { + 14, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, +}; +static const unsigned short byt_sus_usb_ulpi_mode_values[] = { + 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; +static const unsigned short byt_sus_usb_ulpi_gpio_mode_values[] = { + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; +static const struct byt_mixed_func_mux byt_sus_usb_ulpi_mux[] = { + MIXED_FUNC("usb", byt_sus_usb_ulpi_mode_values), + MIXED_FUNC("gpio", byt_sus_usb_ulpi_gpio_mode_values), +}; + +static const unsigned int byt_sus_pcu_spi_pins[] = { 21 }; +static const struct byt_simple_func_mux byt_sus_pcu_spi_mux[] = { + SIMPLE_FUNC("spi", 0), + SIMPLE_FUNC("gpio", 1), +}; + +static const struct byt_pingroup byt_sus_groups[] = { + PIN_GROUP_SIMPLE("usb_oc_grp", + byt_sus_usb_over_current_pins, byt_sus_usb_oc_mux), + PIN_GROUP_MIXED("usb_ulpi_grp", + byt_sus_usb_ulpi_pins, byt_sus_usb_ulpi_mux), + PIN_GROUP_SIMPLE("pcu_spi_grp", + byt_sus_pcu_spi_pins, byt_sus_pcu_spi_mux), +}; + +static const char * const byt_sus_usb_groups[] = { + "usb_oc_grp", "usb_ulpi_grp", +}; +static const char * const byt_sus_spi_groups[] = { "pcu_spi_grp" }; +static const char * const byt_sus_gpio_groups[] = { + "usb_oc_grp", "usb_ulpi_grp", "pcu_spi_grp", +}; + +static const struct byt_function byt_sus_functions[] = { + FUNCTION("usb", byt_sus_usb_groups), + FUNCTION("spi", byt_sus_spi_groups), + FUNCTION("gpio", byt_sus_gpio_groups), +}; + +static const struct byt_community byt_sus_communities[] = { + COMMUNITY(0, BYT_NGPIO_SUS, byt_sus_pins_map), +}; + +static const struct byt_pinctrl_soc_data byt_sus_soc_data = { + .uid = BYT_SUS_ACPI_UID, + .pins = byt_sus_pins, + .npins = ARRAY_SIZE(byt_sus_pins), + .groups = byt_sus_groups, + .ngroups = ARRAY_SIZE(byt_sus_groups), + .functions = byt_sus_functions, + .nfunctions = ARRAY_SIZE(byt_sus_functions), + .communities = byt_sus_communities, + .ncommunities = ARRAY_SIZE(byt_sus_communities), +}; + +static const struct pinctrl_pin_desc byt_ncore_pins[] = { + PINCTRL_PIN(0, "GPIO_NCORE0"), + PINCTRL_PIN(1, "GPIO_NCORE1"), + PINCTRL_PIN(2, "GPIO_NCORE2"), + PINCTRL_PIN(3, "GPIO_NCORE3"), + PINCTRL_PIN(4, "GPIO_NCORE4"), + PINCTRL_PIN(5, "GPIO_NCORE5"), + PINCTRL_PIN(6, "GPIO_NCORE6"), + PINCTRL_PIN(7, "GPIO_NCORE7"), + PINCTRL_PIN(8, "GPIO_NCORE8"), + PINCTRL_PIN(9, "GPIO_NCORE9"), + PINCTRL_PIN(10, "GPIO_NCORE10"), + PINCTRL_PIN(11, "GPIO_NCORE11"), + PINCTRL_PIN(12, "GPIO_NCORE12"), + PINCTRL_PIN(13, "GPIO_NCORE13"), + PINCTRL_PIN(14, "GPIO_NCORE14"), + PINCTRL_PIN(15, "GPIO_NCORE15"), + PINCTRL_PIN(16, "GPIO_NCORE16"), + PINCTRL_PIN(17, "GPIO_NCORE17"), + PINCTRL_PIN(18, "GPIO_NCORE18"), + PINCTRL_PIN(19, "GPIO_NCORE19"), + PINCTRL_PIN(20, "GPIO_NCORE20"), + PINCTRL_PIN(21, "GPIO_NCORE21"), + PINCTRL_PIN(22, "GPIO_NCORE22"), + PINCTRL_PIN(23, "GPIO_NCORE23"), + PINCTRL_PIN(24, "GPIO_NCORE24"), + PINCTRL_PIN(25, "GPIO_NCORE25"), + PINCTRL_PIN(26, "GPIO_NCORE26"), + PINCTRL_PIN(27, "GPIO_NCORE27"), +}; + +static unsigned const byt_ncore_pins_map[BYT_NGPIO_NCORE] = { + 19, 18, 17, 20, 21, 22, 24, 25, 23, 16, + 14, 15, 12, 26, 27, 1, 4, 8, 11, 0, + 3, 6, 10, 13, 2, 5, 9, 7, +}; + +static const struct byt_community byt_ncore_communities[] = { + COMMUNITY(0, BYT_NGPIO_NCORE, byt_ncore_pins_map), +}; + +static const struct byt_pinctrl_soc_data byt_ncore_soc_data = { + .uid = BYT_NCORE_ACPI_UID, + .pins = byt_ncore_pins, + .npins = ARRAY_SIZE(byt_ncore_pins), + .communities = byt_ncore_communities, + .ncommunities = ARRAY_SIZE(byt_ncore_communities), +}; + +static unsigned const ncore_pins[BYT_NGPIO_NCORE] = { + 19, 18, 17, 20, 21, 22, 24, 25, 23, 16, + 14, 15, 12, 26, 27, 1, 4, 8, 11, 0, + 3, 6, 10, 13, 2, 5, 9, 7, +}; + static struct pinctrl_gpio_range byt_ranges[] = { { .name = BYT_SCORE_ACPI_UID, /* match with acpi _UID in probe */ @@ -133,11 +715,6 @@ static struct pinctrl_gpio_range byt_ranges[] = { }, }; -struct byt_gpio_pin_context { - u32 conf0; - u32 val; -}; - struct byt_gpio { struct gpio_chip chip; struct platform_device *pdev; @@ -147,6 +724,13 @@ struct byt_gpio { struct byt_gpio_pin_context *saved_context; }; +static const struct byt_pinctrl_soc_data *byt_soc_data[] = { + &byt_score_soc_data, + &byt_sus_soc_data, + &byt_ncore_soc_data, + NULL, +}; + static void __iomem *byt_gpio_reg(struct gpio_chip *chip, unsigned offset, int reg) { @@ -713,8 +1297,8 @@ static const struct dev_pm_ops byt_gpio_pm_ops = { }; static const struct acpi_device_id byt_gpio_acpi_match[] = { - { "INT33B2", 0 }, - { "INT33FC", 0 }, + { "INT33B2", (kernel_ulong_t)byt_soc_data }, + { "INT33FC", (kernel_ulong_t)byt_soc_data }, { } }; MODULE_DEVICE_TABLE(acpi, byt_gpio_acpi_match); -- cgit v1.2.3 From c501d0b149de1248fa9c29c906bf70f3b87b8bd8 Mon Sep 17 00:00:00 2001 From: Cristina Ciocan Date: Fri, 1 Apr 2016 14:00:03 +0300 Subject: pinctrl: baytrail: Add pin control operations Add implementation for: - pin control, group information retrieval: count, name and pins - pin muxing: - function information (count, name and groups) - mux setting - gpio control (enable, disable, set direction) - pin configuration: - pull disable - pull up/down and pull strength - debounce - any other option is treated as not supported. Signed-off-by: Cristina Ciocan Acked-by: Mika Westerberg Signed-off-by: Linus Walleij --- drivers/pinctrl/intel/Kconfig | 3 + drivers/pinctrl/intel/pinctrl-baytrail.c | 560 +++++++++++++++++++++++++++++-- 2 files changed, 528 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/intel/Kconfig b/drivers/pinctrl/intel/Kconfig index 4d2efad6553c..1c74e038b7b0 100644 --- a/drivers/pinctrl/intel/Kconfig +++ b/drivers/pinctrl/intel/Kconfig @@ -6,6 +6,9 @@ config PINCTRL_BAYTRAIL bool "Intel Baytrail GPIO pin control" depends on GPIOLIB && ACPI select GPIOLIB_IRQCHIP + select PINMUX + select PINCONF + select GENERIC_PINCONF help driver for memory mapped GPIO functionality on Intel Baytrail platforms. Supports 3 banks with 102, 28 and 44 gpios. diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index 364f56c3991d..415d2d5554b5 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -27,6 +27,9 @@ #include #include #include +#include +#include +#include /* memory mapped register offsets */ #define BYT_CONF0_REG 0x000 @@ -73,6 +76,14 @@ #define BYT_NCORE_ACPI_UID "2" #define BYT_SUS_ACPI_UID "3" +/* + * This is the function value most pins have for GPIO muxing. If the value + * differs from the default one, it must be explicitly mentioned. Otherwise, the + * pin control implementation will set the muxing value to default GPIO if it + * does not find a match for the requested function. + */ +#define BYT_DEFAULT_GPIO_MUX 0 + struct byt_gpio_pin_context { u32 conf0; u32 val; @@ -722,6 +733,8 @@ struct byt_gpio { void __iomem *reg_base; struct pinctrl_gpio_range *range; struct byt_gpio_pin_context *saved_context; + const struct byt_pinctrl_soc_data *soc_data; + struct byt_community *communities_copy; }; static const struct byt_pinctrl_soc_data *byt_soc_data[] = { @@ -731,52 +744,252 @@ static const struct byt_pinctrl_soc_data *byt_soc_data[] = { NULL, }; -static void __iomem *byt_gpio_reg(struct gpio_chip *chip, unsigned offset, - int reg) +static struct byt_community *byt_get_community(struct byt_gpio *vg, + unsigned int pin) { - struct byt_gpio *vg = gpiochip_get_data(chip); - u32 reg_offset; + struct byt_community *comm; + int i; + + for (i = 0; i < vg->soc_data->ncommunities; i++) { + comm = vg->communities_copy + i; + if (pin < comm->pin_base + comm->npins && pin >= comm->pin_base) + return comm; + } + return NULL; +} + +static void __iomem *byt_gpio_reg(struct byt_gpio *vg, unsigned int offset, + int reg) +{ + struct byt_community *comm = byt_get_community(vg, offset); + u32 reg_offset = 0; + + if (!comm) + return NULL; + + offset -= comm->pin_base; if (reg == BYT_INT_STAT_REG) reg_offset = (offset / 32) * 4; else - reg_offset = vg->range->pins[offset] * 16; + reg_offset = comm->pad_map[offset] * 16; + + return comm->reg_base + reg_offset + reg; +} + +static int byt_get_groups_count(struct pinctrl_dev *pctldev) +{ + struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); + + return vg->soc_data->ngroups; +} + +static const char *byt_get_group_name(struct pinctrl_dev *pctldev, + unsigned int selector) +{ + struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); + + return vg->soc_data->groups[selector].name; +} + +static int byt_get_group_pins(struct pinctrl_dev *pctldev, + unsigned int selector, + const unsigned int **pins, + unsigned int *num_pins) +{ + struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); + + *pins = vg->soc_data->groups[selector].pins; + *num_pins = vg->soc_data->groups[selector].npins; + + return 0; +} + +static const struct pinctrl_ops byt_pinctrl_ops = { + .get_groups_count = byt_get_groups_count, + .get_group_name = byt_get_group_name, + .get_group_pins = byt_get_group_pins, +}; + +static int byt_get_functions_count(struct pinctrl_dev *pctldev) +{ + struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); + + return vg->soc_data->nfunctions; +} + +static const char *byt_get_function_name(struct pinctrl_dev *pctldev, + unsigned int selector) +{ + struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); + + return vg->soc_data->functions[selector].name; +} + +static int byt_get_function_groups(struct pinctrl_dev *pctldev, + unsigned int selector, + const char * const **groups, + unsigned int *num_groups) +{ + struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); + + *groups = vg->soc_data->functions[selector].groups; + *num_groups = vg->soc_data->functions[selector].ngroups; + + return 0; +} + +static int byt_get_group_simple_mux(const struct byt_pingroup group, + const char *func_name, + unsigned short *func) +{ + int i; + + for (i = 0; i < group.nfuncs; i++) { + if (!strcmp(group.simple_funcs[i].name, func_name)) { + *func = group.simple_funcs[i].func; + return 0; + } + } + + return 1; +} + +static int byt_get_group_mixed_mux(const struct byt_pingroup group, + const char *func_name, + const unsigned short **func) +{ + int i; + + for (i = 0; i < group.nfuncs; i++) { + if (!strcmp(group.mixed_funcs[i].name, func_name)) { + *func = group.mixed_funcs[i].func_values; + return 0; + } + } - return vg->reg_base + reg_offset + reg; + return 1; } -static void byt_gpio_clear_triggering(struct byt_gpio *vg, unsigned offset) +static void byt_set_group_simple_mux(struct byt_gpio *vg, + const struct byt_pingroup group, + unsigned short func) { - void __iomem *reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG); unsigned long flags; - u32 value; + int i; raw_spin_lock_irqsave(&vg->lock, flags); - value = readl(reg); - value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL); - writel(value, reg); + + for (i = 0; i < group.npins; i++) { + void __iomem *padcfg0; + u32 value; + + padcfg0 = byt_gpio_reg(vg, group.pins[i], BYT_CONF0_REG); + if (!padcfg0) { + dev_warn(&vg->pdev->dev, + "Group %s, pin %i not muxed (no padcfg0)\n", + group.name, i); + continue; + } + + value = readl(padcfg0); + value &= ~BYT_PIN_MUX; + value |= func; + writel(value, padcfg0); + } + raw_spin_unlock_irqrestore(&vg->lock, flags); } +static void byt_set_group_mixed_mux(struct byt_gpio *vg, + const struct byt_pingroup group, + const unsigned short *func) +{ + unsigned long flags; + int i; + + raw_spin_lock_irqsave(&vg->lock, flags); + + for (i = 0; i < group.npins; i++) { + void __iomem *padcfg0; + u32 value; + + padcfg0 = byt_gpio_reg(vg, group.pins[i], BYT_CONF0_REG); + if (!padcfg0) { + dev_warn(&vg->pdev->dev, + "Group %s, pin %i not muxed (no padcfg0)\n", + group.name, i); + continue; + } + + value = readl(padcfg0); + value &= ~BYT_PIN_MUX; + value |= func[i]; + writel(value, padcfg0); + } + + raw_spin_unlock_irqrestore(&vg->lock, flags); +} + +static int byt_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector, + unsigned int group_selector) +{ + struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); + const struct byt_function func = vg->soc_data->functions[func_selector]; + const struct byt_pingroup group = vg->soc_data->groups[group_selector]; + const unsigned short *mixed_func; + unsigned short simple_func; + int ret = 1; + + if (group.has_simple_funcs) + ret = byt_get_group_simple_mux(group, func.name, &simple_func); + else + ret = byt_get_group_mixed_mux(group, func.name, &mixed_func); + + if (ret) + byt_set_group_simple_mux(vg, group, BYT_DEFAULT_GPIO_MUX); + else if (group.has_simple_funcs) + byt_set_group_simple_mux(vg, group, simple_func); + else + byt_set_group_mixed_mux(vg, group, mixed_func); + + return 0; +} + static u32 byt_get_gpio_mux(struct byt_gpio *vg, unsigned offset) { /* SCORE pin 92-93 */ - if (!strcmp(vg->range->name, BYT_SCORE_ACPI_UID) && - offset >= 92 && offset <= 93) + if (!strcmp(vg->soc_data->uid, BYT_SCORE_ACPI_UID) && + offset >= 92 && offset <= 93) return 1; /* SUS pin 11-21 */ - if (!strcmp(vg->range->name, BYT_SUS_ACPI_UID) && - offset >= 11 && offset <= 21) + if (!strcmp(vg->soc_data->uid, BYT_SUS_ACPI_UID) && + offset >= 11 && offset <= 21) return 1; return 0; } -static int byt_gpio_request(struct gpio_chip *chip, unsigned offset) +static void byt_gpio_clear_triggering(struct byt_gpio *vg, unsigned int offset) { - struct byt_gpio *vg = gpiochip_get_data(chip); - void __iomem *reg = byt_gpio_reg(chip, offset, BYT_CONF0_REG); + void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); + unsigned long flags; + u32 value; + + raw_spin_lock_irqsave(&vg->lock, flags); + value = readl(reg); + value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL); + writel(value, reg); + raw_spin_unlock_irqrestore(&vg->lock, flags); +} + +static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev, + struct pinctrl_gpio_range *range, + unsigned int offset) +{ + struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); + void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); u32 value, gpio_mux; unsigned long flags; @@ -817,13 +1030,102 @@ static void byt_gpio_free(struct gpio_chip *chip, unsigned offset) pm_runtime_put(&vg->pdev->dev); } +static void byt_gpio_disable_free(struct pinctrl_dev *pctl_dev, + struct pinctrl_gpio_range *range, + unsigned int offset) +{ + struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); + + byt_gpio_clear_triggering(vg, offset); + pm_runtime_put(&vg->pdev->dev); +} + +static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, + struct pinctrl_gpio_range *range, + unsigned int offset, + bool input) +{ + struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); + void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); + void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); + unsigned long flags; + u32 value; + + raw_spin_lock_irqsave(&vg->lock, flags); + + value = readl(val_reg); + value &= ~BYT_DIR_MASK; + if (input) + value |= BYT_OUTPUT_EN; + else + /* + * Before making any direction modifications, do a check if gpio + * is set for direct IRQ. On baytrail, setting GPIO to output + * does not make sense, so let's at least warn the caller before + * they shoot themselves in the foot. + */ + WARN(readl(conf_reg) & BYT_DIRECT_IRQ_EN, + "Potential Error: Setting GPIO with direct_irq_en to output"); + writel(value, val_reg); + + raw_spin_unlock_irqrestore(&vg->lock, flags); + + return 0; +} + +static const struct pinmux_ops byt_pinmux_ops = { + .get_functions_count = byt_get_functions_count, + .get_function_name = byt_get_function_name, + .get_function_groups = byt_get_function_groups, + .set_mux = byt_set_mux, + .gpio_request_enable = byt_gpio_request_enable, + .gpio_disable_free = byt_gpio_disable_free, + .gpio_set_direction = byt_gpio_set_direction, +}; + +static int byt_gpio_request(struct gpio_chip *chip, unsigned int offset) +{ + struct byt_gpio *vg = gpiochip_get_data(chip); + void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); + u32 value, gpio_mux; + unsigned long flags; + + raw_spin_lock_irqsave(&vg->lock, flags); + + /* + * In most cases, func pin mux 000 means GPIO function. + * But, some pins may have func pin mux 001 represents + * GPIO function. + * + * Because there are devices out there where some pins were not + * configured correctly we allow changing the mux value from + * request (but print out warning about that). + */ + value = readl(reg) & BYT_PIN_MUX; + gpio_mux = byt_get_gpio_mux(vg, offset); + if (WARN_ON(gpio_mux != value)) { + value = readl(reg) & ~BYT_PIN_MUX; + value |= gpio_mux; + writel(value, reg); + + dev_warn(&vg->pdev->dev, + "pin %u forcibly re-configured as GPIO\n", offset); + } + + raw_spin_unlock_irqrestore(&vg->lock, flags); + + pm_runtime_get(&vg->pdev->dev); + + return 0; +} + static int byt_irq_type(struct irq_data *d, unsigned type) { struct byt_gpio *vg = gpiochip_get_data(irq_data_get_irq_chip_data(d)); u32 offset = irqd_to_hwirq(d); u32 value; unsigned long flags; - void __iomem *reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG); + void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); if (offset >= vg->chip.ngpio) return -EINVAL; @@ -832,7 +1134,7 @@ static int byt_irq_type(struct irq_data *d, unsigned type) value = readl(reg); WARN(value & BYT_DIRECT_IRQ_EN, - "Bad pad config for io mode, force direct_irq_en bit clearing"); + "Bad pad config for io mode, force direct_irq_en bit clearing"); /* For level trigges the BYT_TRIG_POS and BYT_TRIG_NEG bits * are used to indicate high and low level triggering @@ -852,10 +1154,198 @@ static int byt_irq_type(struct irq_data *d, unsigned type) return 0; } +static void byt_get_pull_strength(u32 reg, u16 *strength) +{ + switch (reg & BYT_PULL_STR_MASK) { + case BYT_PULL_STR_2K: + *strength = 2000; + break; + case BYT_PULL_STR_10K: + *strength = 10000; + break; + case BYT_PULL_STR_20K: + *strength = 20000; + break; + case BYT_PULL_STR_40K: + *strength = 40000; + break; + } +} + +static int byt_set_pull_strength(u32 *reg, u16 strength) +{ + *reg &= ~BYT_PULL_STR_MASK; + + switch (strength) { + case 2000: + *reg |= BYT_PULL_STR_2K; + break; + case 10000: + *reg |= BYT_PULL_STR_10K; + break; + case 20000: + *reg |= BYT_PULL_STR_20K; + break; + case 40000: + *reg |= BYT_PULL_STR_40K; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int byt_pin_config_get(struct pinctrl_dev *pctl_dev, unsigned int offset, + unsigned long *config) +{ + struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); + enum pin_config_param param = pinconf_to_config_param(*config); + void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); + void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); + unsigned long flags; + u32 conf, pull, val; + u16 arg = 0; + + raw_spin_lock_irqsave(&vg->lock, flags); + conf = readl(conf_reg); + pull = conf & BYT_PULL_ASSIGN_MASK; + val = readl(val_reg); + raw_spin_unlock_irqrestore(&vg->lock, flags); + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + if (pull) + return -EINVAL; + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + /* Pull assignment is only applicable in input mode */ + if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_DOWN) + return -EINVAL; + + byt_get_pull_strength(conf, &arg); + + break; + case PIN_CONFIG_BIAS_PULL_UP: + /* Pull assignment is only applicable in input mode */ + if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_UP) + return -EINVAL; + + byt_get_pull_strength(conf, &arg); + + break; + default: + return -ENOTSUPP; + } + + *config = pinconf_to_config_packed(param, arg); + + return 0; +} + +static int byt_pin_config_set(struct pinctrl_dev *pctl_dev, + unsigned int offset, + unsigned long *configs, + unsigned int num_configs) +{ + struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); + unsigned int param, arg; + void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); + void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); + unsigned long flags; + u32 conf, val; + int i, ret = 0; + + raw_spin_lock_irqsave(&vg->lock, flags); + + conf = readl(conf_reg); + val = readl(val_reg); + + for (i = 0; i < num_configs; i++) { + param = pinconf_to_config_param(configs[i]); + arg = pinconf_to_config_argument(configs[i]); + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + conf &= ~BYT_PULL_ASSIGN_MASK; + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + /* Set default strength value in case none is given */ + if (arg == 1) + arg = 2000; + + /* + * Pull assignment is only applicable in input mode. If + * chip is not in input mode, set it and warn about it. + */ + if (val & BYT_INPUT_EN) { + val &= ~BYT_INPUT_EN; + writel(val, val_reg); + dev_warn(&vg->pdev->dev, + "pin %u forcibly set to input mode\n", + offset); + } + + conf &= ~BYT_PULL_ASSIGN_MASK; + conf |= BYT_PULL_ASSIGN_DOWN; + ret = byt_set_pull_strength(&conf, arg); + + break; + case PIN_CONFIG_BIAS_PULL_UP: + /* Set default strength value in case none is given */ + if (arg == 1) + arg = 2000; + + /* + * Pull assignment is only applicable in input mode. If + * chip is not in input mode, set it and warn about it. + */ + if (val & BYT_INPUT_EN) { + val &= ~BYT_INPUT_EN; + writel(val, val_reg); + dev_warn(&vg->pdev->dev, + "pin %u forcibly set to input mode\n", + offset); + } + + conf &= ~BYT_PULL_ASSIGN_MASK; + conf |= BYT_PULL_ASSIGN_UP; + ret = byt_set_pull_strength(&conf, arg); + + break; + default: + ret = -ENOTSUPP; + } + + if (ret) + break; + } + + if (!ret) + writel(conf, conf_reg); + + raw_spin_unlock_irqrestore(&vg->lock, flags); + + return ret; +} + +static const struct pinconf_ops byt_pinconf_ops = { + .is_generic = true, + .pin_config_get = byt_pin_config_get, + .pin_config_set = byt_pin_config_set, +}; + +static const struct pinctrl_desc byt_pinctrl_desc = { + .pctlops = &byt_pinctrl_ops, + .pmxops = &byt_pinmux_ops, + .confops = &byt_pinconf_ops, + .owner = THIS_MODULE, +}; + static int byt_gpio_get(struct gpio_chip *chip, unsigned offset) { - void __iomem *reg = byt_gpio_reg(chip, offset, BYT_VAL_REG); struct byt_gpio *vg = gpiochip_get_data(chip); + void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); unsigned long flags; u32 val; @@ -869,7 +1359,7 @@ static int byt_gpio_get(struct gpio_chip *chip, unsigned offset) static void byt_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { struct byt_gpio *vg = gpiochip_get_data(chip); - void __iomem *reg = byt_gpio_reg(chip, offset, BYT_VAL_REG); + void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); unsigned long flags; u32 old_val; @@ -888,7 +1378,7 @@ static void byt_gpio_set(struct gpio_chip *chip, unsigned offset, int value) static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned offset) { struct byt_gpio *vg = gpiochip_get_data(chip); - void __iomem *reg = byt_gpio_reg(chip, offset, BYT_VAL_REG); + void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); unsigned long flags; u32 value; @@ -907,8 +1397,8 @@ static int byt_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int value) { struct byt_gpio *vg = gpiochip_get_data(chip); - void __iomem *conf_reg = byt_gpio_reg(chip, gpio, BYT_CONF0_REG); - void __iomem *reg = byt_gpio_reg(chip, gpio, BYT_VAL_REG); + void __iomem *conf_reg = byt_gpio_reg(vg, gpio, BYT_CONF0_REG); + void __iomem *reg = byt_gpio_reg(vg, gpio, BYT_VAL_REG); unsigned long flags; u32 reg_val; @@ -1019,7 +1509,7 @@ static void byt_gpio_irq_handler(struct irq_desc *desc) /* check from GPIO controller which pin triggered the interrupt */ for (base = 0; base < vg->chip.ngpio; base += 32) { - reg = byt_gpio_reg(&vg->chip, base, BYT_INT_STAT_REG); + reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG); pending = readl(reg); for_each_set_bit(pin, &pending, 32) { virq = irq_find_mapping(vg->chip.irqdomain, base + pin); @@ -1037,7 +1527,7 @@ static void byt_irq_ack(struct irq_data *d) void __iomem *reg; raw_spin_lock(&vg->lock); - reg = byt_gpio_reg(&vg->chip, offset, BYT_INT_STAT_REG); + reg = byt_gpio_reg(vg, offset, BYT_INT_STAT_REG); writel(BIT(offset % 32), reg); raw_spin_unlock(&vg->lock); } @@ -1051,7 +1541,7 @@ static void byt_irq_unmask(struct irq_data *d) void __iomem *reg; u32 value; - reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG); + reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); raw_spin_lock_irqsave(&vg->lock, flags); value = readl(reg); @@ -1106,7 +1596,7 @@ static void byt_gpio_irq_init_hw(struct byt_gpio *vg) * interrupts from misconfigured pins. */ for (i = 0; i < vg->chip.ngpio; i++) { - value = readl(byt_gpio_reg(&vg->chip, i, BYT_CONF0_REG)); + value = readl(byt_gpio_reg(vg, i, BYT_CONF0_REG)); if ((value & BYT_PIN_MUX) == byt_get_gpio_mux(vg, i) && !(value & BYT_DIRECT_IRQ_EN)) { byt_gpio_clear_triggering(vg, i); @@ -1116,7 +1606,7 @@ static void byt_gpio_irq_init_hw(struct byt_gpio *vg) /* clear interrupt status trigger registers */ for (base = 0; base < vg->chip.ngpio; base += 32) { - reg = byt_gpio_reg(&vg->chip, base, BYT_INT_STAT_REG); + reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG); writel(0xffffffff, reg); /* make sure trigger bits are cleared, if not then a pin might be misconfigured in bios */ @@ -1226,11 +1716,11 @@ static int byt_gpio_suspend(struct device *dev) void __iomem *reg; u32 value; - reg = byt_gpio_reg(&vg->chip, i, BYT_CONF0_REG); + reg = byt_gpio_reg(vg, i, BYT_CONF0_REG); value = readl(reg) & BYT_CONF0_RESTORE_MASK; vg->saved_context[i].conf0 = value; - reg = byt_gpio_reg(&vg->chip, i, BYT_VAL_REG); + reg = byt_gpio_reg(vg, i, BYT_VAL_REG); value = readl(reg) & BYT_VAL_RESTORE_MASK; vg->saved_context[i].val = value; } @@ -1248,7 +1738,7 @@ static int byt_gpio_resume(struct device *dev) void __iomem *reg; u32 value; - reg = byt_gpio_reg(&vg->chip, i, BYT_CONF0_REG); + reg = byt_gpio_reg(vg, i, BYT_CONF0_REG); value = readl(reg); if ((value & BYT_CONF0_RESTORE_MASK) != vg->saved_context[i].conf0) { @@ -1258,7 +1748,7 @@ static int byt_gpio_resume(struct device *dev) dev_info(dev, "restored pin %d conf0 %#08x", i, value); } - reg = byt_gpio_reg(&vg->chip, i, BYT_VAL_REG); + reg = byt_gpio_reg(vg, i, BYT_VAL_REG); value = readl(reg); if ((value & BYT_VAL_RESTORE_MASK) != vg->saved_context[i].val) { -- cgit v1.2.3 From 86e3ef812fe3df8298c0bee81b0c786006a9c85c Mon Sep 17 00:00:00 2001 From: Cristina Ciocan Date: Fri, 1 Apr 2016 14:00:04 +0300 Subject: pinctrl: baytrail: Update gpio chip operations This patch updates the gpio chip implementation in order to interact with the pin control model: the chip contains reference to SOC data and pin/group/community information is retrieved through the SOC reference. Signed-off-by: Cristina Ciocan Acked-by: Mika Westerberg Signed-off-by: Linus Walleij --- drivers/pinctrl/intel/pinctrl-baytrail.c | 97 ++++++++++++++++++++++---------- 1 file changed, 68 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index 415d2d5554b5..a24b51e47f00 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -1363,44 +1364,45 @@ static void byt_gpio_set(struct gpio_chip *chip, unsigned offset, int value) unsigned long flags; u32 old_val; - raw_spin_lock_irqsave(&vg->lock, flags); + if (!reg) + return; + raw_spin_lock_irqsave(&vg->lock, flags); old_val = readl(reg); - if (value) writel(old_val | BYT_LEVEL, reg); else writel(old_val & ~BYT_LEVEL, reg); - raw_spin_unlock_irqrestore(&vg->lock, flags); } -static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned offset) +static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) { struct byt_gpio *vg = gpiochip_get_data(chip); void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); unsigned long flags; u32 value; - raw_spin_lock_irqsave(&vg->lock, flags); - - value = readl(reg) | BYT_DIR_MASK; - value &= ~BYT_INPUT_EN; /* active low */ - writel(value, reg); + if (!reg) + return -EINVAL; + raw_spin_lock_irqsave(&vg->lock, flags); + value = readl(reg); raw_spin_unlock_irqrestore(&vg->lock, flags); - return 0; + if (!(value & BYT_OUTPUT_EN)) + return GPIOF_DIR_OUT; + if (!(value & BYT_INPUT_EN)) + return GPIOF_DIR_IN; + + return -EINVAL; } -static int byt_gpio_direction_output(struct gpio_chip *chip, - unsigned gpio, int value) +static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) { struct byt_gpio *vg = gpiochip_get_data(chip); - void __iomem *conf_reg = byt_gpio_reg(vg, gpio, BYT_CONF0_REG); - void __iomem *reg = byt_gpio_reg(vg, gpio, BYT_VAL_REG); + void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); unsigned long flags; - u32 reg_val; raw_spin_lock_irqsave(&vg->lock, flags); @@ -1413,15 +1415,18 @@ static int byt_gpio_direction_output(struct gpio_chip *chip, WARN(readl(conf_reg) & BYT_DIRECT_IRQ_EN, "Potential Error: Setting GPIO with direct_irq_en to output"); - reg_val = readl(reg) | BYT_DIR_MASK; - reg_val &= ~(BYT_OUTPUT_EN | BYT_INPUT_EN); + return pinctrl_gpio_direction_input(chip->base + offset); +} - if (value) - writel(reg_val | BYT_LEVEL, reg); - else - writel(reg_val & ~BYT_LEVEL, reg); +static int byt_gpio_direction_output(struct gpio_chip *chip, + unsigned int offset, int value) +{ + int ret = pinctrl_gpio_direction_output(chip->base + offset); - raw_spin_unlock_irqrestore(&vg->lock, flags); + if (ret) + return ret; + + byt_gpio_set(chip, offset, value); return 0; } @@ -1430,20 +1435,42 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) { struct byt_gpio *vg = gpiochip_get_data(chip); int i; - u32 conf0, val, offs; + u32 conf0, val; - for (i = 0; i < vg->chip.ngpio; i++) { + for (i = 0; i < vg->soc_data->npins; i++) { + const struct byt_community *comm; const char *pull_str = NULL; const char *pull = NULL; + void __iomem *reg; unsigned long flags; const char *label; - offs = vg->range->pins[i] * 16; + unsigned int pin; raw_spin_lock_irqsave(&vg->lock, flags); - conf0 = readl(vg->reg_base + offs + BYT_CONF0_REG); - val = readl(vg->reg_base + offs + BYT_VAL_REG); + pin = vg->soc_data->pins[i].number; + reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); + if (!reg) { + seq_printf(s, + "Could not retrieve pin %i conf0 reg\n", + pin); + continue; + } + conf0 = readl(reg); + + reg = byt_gpio_reg(vg, pin, BYT_VAL_REG); + if (!reg) { + seq_printf(s, + "Could not retrieve pin %i val reg\n", pin); + } + val = readl(reg); raw_spin_unlock_irqrestore(&vg->lock, flags); + comm = byt_get_community(vg, pin); + if (!comm) { + seq_printf(s, + "Could not get community for pin %i\n", pin); + continue; + } label = gpiochip_is_requested(chip, i); if (!label) label = "Unrequested"; @@ -1474,12 +1501,12 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) seq_printf(s, " gpio-%-3d (%-20.20s) %s %s %s pad-%-3d offset:0x%03x mux:%d %s%s%s", - i, + pin, label, val & BYT_INPUT_EN ? " " : "in", val & BYT_OUTPUT_EN ? " " : "out", val & BYT_LEVEL ? "hi" : "lo", - vg->range->pins[i], offs, + comm->pad_map[i], comm->pad_map[i] * 32, conf0 & 0x7, conf0 & BYT_TRIG_NEG ? " fall" : " ", conf0 & BYT_TRIG_POS ? " rise" : " ", @@ -1519,6 +1546,18 @@ static void byt_gpio_irq_handler(struct irq_desc *desc) chip->irq_eoi(data); } +static const struct gpio_chip byt_gpio_chip = { + .owner = THIS_MODULE, + .request = gpiochip_generic_request, + .free = gpiochip_generic_free, + .get_direction = byt_gpio_get_direction, + .direction_input = byt_gpio_direction_input, + .direction_output = byt_gpio_direction_output, + .get = byt_gpio_get, + .set = byt_gpio_set, + .dbg_show = byt_gpio_dbg_show, +}; + static void byt_irq_ack(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); -- cgit v1.2.3 From 9f573b98ca502ad495641ce42fcc18ccb32f5827 Mon Sep 17 00:00:00 2001 From: Cristina Ciocan Date: Fri, 1 Apr 2016 14:00:05 +0300 Subject: pinctrl: baytrail: Update irq chip operations This patch updates the irq chip implementation in order to interact with the pin control chip model: the chip contains reference to SOC data and pin/group/community information is retrieved through the SOC reference. Signed-off-by: Cristina Ciocan Acked-by: Mika Westerberg Signed-off-by: Linus Walleij --- drivers/pinctrl/intel/pinctrl-baytrail.c | 97 +++++++++++++++++--------------- 1 file changed, 51 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index a24b51e47f00..f7c752b4bb6d 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -1120,41 +1120,6 @@ static int byt_gpio_request(struct gpio_chip *chip, unsigned int offset) return 0; } -static int byt_irq_type(struct irq_data *d, unsigned type) -{ - struct byt_gpio *vg = gpiochip_get_data(irq_data_get_irq_chip_data(d)); - u32 offset = irqd_to_hwirq(d); - u32 value; - unsigned long flags; - void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); - - if (offset >= vg->chip.ngpio) - return -EINVAL; - - raw_spin_lock_irqsave(&vg->lock, flags); - value = readl(reg); - - WARN(value & BYT_DIRECT_IRQ_EN, - "Bad pad config for io mode, force direct_irq_en bit clearing"); - - /* For level trigges the BYT_TRIG_POS and BYT_TRIG_NEG bits - * are used to indicate high and low level triggering - */ - value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS | BYT_TRIG_NEG | - BYT_TRIG_LVL); - - writel(value, reg); - - if (type & IRQ_TYPE_EDGE_BOTH) - irq_set_handler_locked(d, handle_edge_irq); - else if (type & IRQ_TYPE_LEVEL_MASK) - irq_set_handler_locked(d, handle_level_irq); - - raw_spin_unlock_irqrestore(&vg->lock, flags); - - return 0; -} - static void byt_get_pull_strength(u32 reg, u16 *strength) { switch (reg & BYT_PULL_STR_MASK) { @@ -1565,12 +1530,23 @@ static void byt_irq_ack(struct irq_data *d) unsigned offset = irqd_to_hwirq(d); void __iomem *reg; - raw_spin_lock(&vg->lock); reg = byt_gpio_reg(vg, offset, BYT_INT_STAT_REG); + if (!reg) + return; + + raw_spin_lock(&vg->lock); writel(BIT(offset % 32), reg); raw_spin_unlock(&vg->lock); } +static void byt_irq_mask(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct byt_gpio *vg = gpiochip_get_data(gc); + + byt_gpio_clear_triggering(vg, irqd_to_hwirq(d)); +} + static void byt_irq_unmask(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); @@ -1581,6 +1557,8 @@ static void byt_irq_unmask(struct irq_data *d) u32 value; reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); + if (!reg) + return; raw_spin_lock_irqsave(&vg->lock, flags); value = readl(reg); @@ -1606,21 +1584,48 @@ static void byt_irq_unmask(struct irq_data *d) raw_spin_unlock_irqrestore(&vg->lock, flags); } -static void byt_irq_mask(struct irq_data *d) +static int byt_irq_type(struct irq_data *d, unsigned int type) { - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct byt_gpio *vg = gpiochip_get_data(gc); + struct byt_gpio *vg = gpiochip_get_data(irq_data_get_irq_chip_data(d)); + u32 offset = irqd_to_hwirq(d); + u32 value; + unsigned long flags; + void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); - byt_gpio_clear_triggering(vg, irqd_to_hwirq(d)); + if (!reg || offset >= vg->chip.ngpio) + return -EINVAL; + + raw_spin_lock_irqsave(&vg->lock, flags); + value = readl(reg); + + WARN(value & BYT_DIRECT_IRQ_EN, + "Bad pad config for io mode, force direct_irq_en bit clearing"); + + /* For level trigges the BYT_TRIG_POS and BYT_TRIG_NEG bits + * are used to indicate high and low level triggering + */ + value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS | BYT_TRIG_NEG | + BYT_TRIG_LVL); + + writel(value, reg); + + if (type & IRQ_TYPE_EDGE_BOTH) + irq_set_handler_locked(d, handle_edge_irq); + else if (type & IRQ_TYPE_LEVEL_MASK) + irq_set_handler_locked(d, handle_level_irq); + + raw_spin_unlock_irqrestore(&vg->lock, flags); + + return 0; } static struct irq_chip byt_irqchip = { - .name = "BYT-GPIO", - .irq_ack = byt_irq_ack, - .irq_mask = byt_irq_mask, - .irq_unmask = byt_irq_unmask, - .irq_set_type = byt_irq_type, - .flags = IRQCHIP_SKIP_SET_WAKE, + .name = "BYT-GPIO", + .irq_ack = byt_irq_ack, + .irq_mask = byt_irq_mask, + .irq_unmask = byt_irq_unmask, + .irq_set_type = byt_irq_type, + .flags = IRQCHIP_SKIP_SET_WAKE, }; static void byt_gpio_irq_init_hw(struct byt_gpio *vg) -- cgit v1.2.3 From 71e6ca61e82667c5c0de4aa779a4438d6568262f Mon Sep 17 00:00:00 2001 From: Cristina Ciocan Date: Fri, 1 Apr 2016 14:00:06 +0300 Subject: pinctrl: baytrail: Register pin control handling This patch updates device's probing, removal and irq handling in order to register it as pinctrl device. Pin control data is matched by ACPI UID, since it is passed along as driver data in acpi_device_id structure. Signed-off-by: Cristina Ciocan Acked-by: Mika Westerberg Signed-off-by: Linus Walleij --- drivers/pinctrl/intel/pinctrl-baytrail.c | 447 +++++++++++++++---------------- 1 file changed, 221 insertions(+), 226 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index f7c752b4bb6d..b087b0030617 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -181,6 +181,17 @@ struct byt_pinctrl_soc_data { size_t ncommunities; }; +struct byt_gpio { + struct gpio_chip chip; + struct platform_device *pdev; + struct pinctrl_dev *pctl_dev; + struct pinctrl_desc pctl_desc; + raw_spinlock_t lock; + const struct byt_pinctrl_soc_data *soc_data; + struct byt_community *communities_copy; + struct byt_gpio_pin_context *saved_context; +}; + /* SCORE pins, aka GPIOC_ or GPIO_S0_SC[] */ static const struct pinctrl_pin_desc byt_score_pins[] = { PINCTRL_PIN(0, "SATA_GP0"), @@ -287,20 +298,6 @@ static const struct pinctrl_pin_desc byt_score_pins[] = { PINCTRL_PIN(101, "PMC_PLT_CLK5"), }; -static unsigned const score_pins[BYT_NGPIO_SCORE] = { - 85, 89, 93, 96, 99, 102, 98, 101, 34, 37, - 36, 38, 39, 35, 40, 84, 62, 61, 64, 59, - 54, 56, 60, 55, 63, 57, 51, 50, 53, 47, - 52, 49, 48, 43, 46, 41, 45, 42, 58, 44, - 95, 105, 70, 68, 67, 66, 69, 71, 65, 72, - 86, 90, 88, 92, 103, 77, 79, 83, 78, 81, - 80, 82, 13, 12, 15, 14, 17, 18, 19, 16, - 2, 1, 0, 4, 6, 7, 9, 8, 33, 32, - 31, 30, 29, 27, 25, 28, 26, 23, 21, 20, - 24, 22, 5, 3, 10, 11, 106, 87, 91, 104, - 97, 100, -}; - static const unsigned int byt_score_pins_map[BYT_NGPIO_SCORE] = { 85, 89, 93, 96, 99, 102, 98, 101, 34, 37, 36, 38, 39, 35, 40, 84, 62, 61, 64, 59, @@ -571,14 +568,6 @@ static const struct pinctrl_pin_desc byt_sus_pins[] = { PINCTRL_PIN(43, "USB_ULPI_REFCLK"), }; -static const unsigned int sus_pins[BYT_NGPIO_SUS] = { - 29, 33, 30, 31, 32, 34, 36, 35, 38, 37, - 18, 7, 11, 20, 17, 1, 8, 10, 19, 12, - 0, 2, 23, 39, 28, 27, 22, 21, 24, 25, - 26, 51, 56, 54, 49, 55, 48, 57, 50, 58, - 52, 53, 59, 40, -}; - static const unsigned int byt_sus_pins_map[BYT_NGPIO_SUS] = { 29, 33, 30, 31, 32, 34, 36, 35, 38, 37, 18, 7, 11, 20, 17, 1, 8, 10, 19, 12, @@ -701,43 +690,6 @@ static const struct byt_pinctrl_soc_data byt_ncore_soc_data = { .ncommunities = ARRAY_SIZE(byt_ncore_communities), }; -static unsigned const ncore_pins[BYT_NGPIO_NCORE] = { - 19, 18, 17, 20, 21, 22, 24, 25, 23, 16, - 14, 15, 12, 26, 27, 1, 4, 8, 11, 0, - 3, 6, 10, 13, 2, 5, 9, 7, -}; - -static struct pinctrl_gpio_range byt_ranges[] = { - { - .name = BYT_SCORE_ACPI_UID, /* match with acpi _UID in probe */ - .npins = BYT_NGPIO_SCORE, - .pins = score_pins, - }, - { - .name = BYT_NCORE_ACPI_UID, - .npins = BYT_NGPIO_NCORE, - .pins = ncore_pins, - }, - { - .name = BYT_SUS_ACPI_UID, - .npins = BYT_NGPIO_SUS, - .pins = sus_pins, - }, - { - }, -}; - -struct byt_gpio { - struct gpio_chip chip; - struct platform_device *pdev; - raw_spinlock_t lock; - void __iomem *reg_base; - struct pinctrl_gpio_range *range; - struct byt_gpio_pin_context *saved_context; - const struct byt_pinctrl_soc_data *soc_data; - struct byt_community *communities_copy; -}; - static const struct byt_pinctrl_soc_data *byt_soc_data[] = { &byt_score_soc_data, &byt_sus_soc_data, @@ -1023,14 +975,6 @@ static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev, return 0; } -static void byt_gpio_free(struct gpio_chip *chip, unsigned offset) -{ - struct byt_gpio *vg = gpiochip_get_data(chip); - - byt_gpio_clear_triggering(vg, offset); - pm_runtime_put(&vg->pdev->dev); -} - static void byt_gpio_disable_free(struct pinctrl_dev *pctl_dev, struct pinctrl_gpio_range *range, unsigned int offset) @@ -1084,42 +1028,6 @@ static const struct pinmux_ops byt_pinmux_ops = { .gpio_set_direction = byt_gpio_set_direction, }; -static int byt_gpio_request(struct gpio_chip *chip, unsigned int offset) -{ - struct byt_gpio *vg = gpiochip_get_data(chip); - void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); - u32 value, gpio_mux; - unsigned long flags; - - raw_spin_lock_irqsave(&vg->lock, flags); - - /* - * In most cases, func pin mux 000 means GPIO function. - * But, some pins may have func pin mux 001 represents - * GPIO function. - * - * Because there are devices out there where some pins were not - * configured correctly we allow changing the mux value from - * request (but print out warning about that). - */ - value = readl(reg) & BYT_PIN_MUX; - gpio_mux = byt_get_gpio_mux(vg, offset); - if (WARN_ON(gpio_mux != value)) { - value = readl(reg) & ~BYT_PIN_MUX; - value |= gpio_mux; - writel(value, reg); - - dev_warn(&vg->pdev->dev, - "pin %u forcibly re-configured as GPIO\n", offset); - } - - raw_spin_unlock_irqrestore(&vg->lock, flags); - - pm_runtime_get(&vg->pdev->dev); - - return 0; -} - static void byt_get_pull_strength(u32 reg, u16 *strength) { switch (reg & BYT_PULL_STR_MASK) { @@ -1365,21 +1273,6 @@ static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) { - struct byt_gpio *vg = gpiochip_get_data(chip); - void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); - unsigned long flags; - - raw_spin_lock_irqsave(&vg->lock, flags); - - /* - * Before making any direction modifications, do a check if gpio - * is set for direct IRQ. On baytrail, setting GPIO to output does - * not make sense, so let's at least warn the caller before they shoot - * themselves in the foot. - */ - WARN(readl(conf_reg) & BYT_DIRECT_IRQ_EN, - "Potential Error: Setting GPIO with direct_irq_en to output"); - return pinctrl_gpio_direction_input(chip->base + offset); } @@ -1489,28 +1382,6 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) } } -static void byt_gpio_irq_handler(struct irq_desc *desc) -{ - struct irq_data *data = irq_desc_get_irq_data(desc); - struct byt_gpio *vg = gpiochip_get_data(irq_desc_get_handler_data(desc)); - struct irq_chip *chip = irq_data_get_irq_chip(data); - u32 base, pin; - void __iomem *reg; - unsigned long pending; - unsigned virq; - - /* check from GPIO controller which pin triggered the interrupt */ - for (base = 0; base < vg->chip.ngpio; base += 32) { - reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG); - pending = readl(reg); - for_each_set_bit(pin, &pending, 32) { - virq = irq_find_mapping(vg->chip.irqdomain, base + pin); - generic_handle_irq(virq); - } - } - chip->irq_eoi(data); -} - static const struct gpio_chip byt_gpio_chip = { .owner = THIS_MODULE, .request = gpiochip_generic_request, @@ -1628,6 +1499,37 @@ static struct irq_chip byt_irqchip = { .flags = IRQCHIP_SKIP_SET_WAKE, }; +static void byt_gpio_irq_handler(struct irq_desc *desc) +{ + struct irq_data *data = irq_desc_get_irq_data(desc); + struct byt_gpio *vg = gpiochip_get_data( + irq_desc_get_handler_data(desc)); + struct irq_chip *chip = irq_data_get_irq_chip(data); + u32 base, pin; + void __iomem *reg; + unsigned long pending; + unsigned int virq; + + /* check from GPIO controller which pin triggered the interrupt */ + for (base = 0; base < vg->chip.ngpio; base += 32) { + reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG); + + if (!reg) { + dev_warn(&vg->pdev->dev, + "Pin %i: could not retrieve interrupt status register\n", + base); + continue; + } + + pending = readl(reg); + for_each_set_bit(pin, &pending, 32) { + virq = irq_find_mapping(vg->chip.irqdomain, base + pin); + generic_handle_irq(virq); + } + } + chip->irq_eoi(data); +} + static void byt_gpio_irq_init_hw(struct byt_gpio *vg) { void __iomem *reg; @@ -1639,8 +1541,18 @@ static void byt_gpio_irq_init_hw(struct byt_gpio *vg) * do not use direct IRQ mode. This will prevent spurious * interrupts from misconfigured pins. */ - for (i = 0; i < vg->chip.ngpio; i++) { - value = readl(byt_gpio_reg(vg, i, BYT_CONF0_REG)); + for (i = 0; i < vg->soc_data->npins; i++) { + unsigned int pin = vg->soc_data->pins[i].number; + + reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); + if (!reg) { + dev_warn(&vg->pdev->dev, + "Pin %i: could not retrieve conf0 register\n", + i); + continue; + } + + value = readl(reg); if ((value & BYT_PIN_MUX) == byt_get_gpio_mux(vg, i) && !(value & BYT_DIRECT_IRQ_EN)) { byt_gpio_clear_triggering(vg, i); @@ -1649,8 +1561,16 @@ static void byt_gpio_irq_init_hw(struct byt_gpio *vg) } /* clear interrupt status trigger registers */ - for (base = 0; base < vg->chip.ngpio; base += 32) { + for (base = 0; base < vg->soc_data->npins; base += 32) { reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG); + + if (!reg) { + dev_warn(&vg->pdev->dev, + "Pin %i: could not retrieve irq status reg\n", + base); + continue; + } + writel(0xffffffff, reg); /* make sure trigger bits are cleared, if not then a pin might be misconfigured in bios */ @@ -1661,82 +1581,47 @@ static void byt_gpio_irq_init_hw(struct byt_gpio *vg) } } -static int byt_gpio_probe(struct platform_device *pdev) +static int byt_gpio_probe(struct byt_gpio *vg) { - struct byt_gpio *vg; struct gpio_chip *gc; - struct resource *mem_rc, *irq_rc; - struct device *dev = &pdev->dev; - struct acpi_device *acpi_dev; - struct pinctrl_gpio_range *range; - acpi_handle handle = ACPI_HANDLE(dev); + struct resource *irq_rc; int ret; - if (acpi_bus_get_device(handle, &acpi_dev)) - return -ENODEV; - - vg = devm_kzalloc(dev, sizeof(struct byt_gpio), GFP_KERNEL); - if (!vg) { - dev_err(&pdev->dev, "can't allocate byt_gpio chip data\n"); - return -ENOMEM; - } - - for (range = byt_ranges; range->name; range++) { - if (!strcmp(acpi_dev->pnp.unique_id, range->name)) { - vg->chip.ngpio = range->npins; - vg->range = range; - break; - } - } - - if (!vg->chip.ngpio || !vg->range) - return -ENODEV; - - vg->pdev = pdev; - platform_set_drvdata(pdev, vg); - - mem_rc = platform_get_resource(pdev, IORESOURCE_MEM, 0); - vg->reg_base = devm_ioremap_resource(dev, mem_rc); - if (IS_ERR(vg->reg_base)) - return PTR_ERR(vg->reg_base); - - raw_spin_lock_init(&vg->lock); - - gc = &vg->chip; - gc->label = dev_name(&pdev->dev); - gc->owner = THIS_MODULE; - gc->request = byt_gpio_request; - gc->free = byt_gpio_free; - gc->direction_input = byt_gpio_direction_input; - gc->direction_output = byt_gpio_direction_output; - gc->get = byt_gpio_get; - gc->set = byt_gpio_set; - gc->dbg_show = byt_gpio_dbg_show; - gc->base = -1; - gc->can_sleep = false; - gc->parent = dev; + /* Set up gpio chip */ + vg->chip = byt_gpio_chip; + gc = &vg->chip; + gc->label = dev_name(&vg->pdev->dev); + gc->base = -1; + gc->can_sleep = false; + gc->parent = &vg->pdev->dev; + gc->ngpio = vg->soc_data->npins; #ifdef CONFIG_PM_SLEEP - vg->saved_context = devm_kcalloc(&pdev->dev, gc->ngpio, + vg->saved_context = devm_kcalloc(&vg->pdev->dev, gc->ngpio, sizeof(*vg->saved_context), GFP_KERNEL); #endif - ret = gpiochip_add_data(gc, vg); if (ret) { - dev_err(&pdev->dev, "failed adding byt-gpio chip\n"); + dev_err(&vg->pdev->dev, "failed adding byt-gpio chip\n"); return ret; } + ret = gpiochip_add_pin_range(&vg->chip, dev_name(&vg->pdev->dev), + 0, 0, vg->soc_data->npins); + if (ret) { + dev_err(&vg->pdev->dev, "failed to add GPIO pin range\n"); + goto fail; + } + /* set up interrupts */ - irq_rc = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + irq_rc = platform_get_resource(vg->pdev, IORESOURCE_IRQ, 0); if (irq_rc && irq_rc->start) { byt_gpio_irq_init_hw(vg); ret = gpiochip_irqchip_add(gc, &byt_irqchip, 0, handle_simple_irq, IRQ_TYPE_NONE); if (ret) { - dev_err(dev, "failed to add irqchip\n"); - gpiochip_remove(gc); - return ret; + dev_err(&vg->pdev->dev, "failed to add irqchip\n"); + goto fail; } gpiochip_set_chained_irqchip(gc, &byt_irqchip, @@ -1744,7 +1629,120 @@ static int byt_gpio_probe(struct platform_device *pdev) byt_gpio_irq_handler); } - pm_runtime_enable(dev); + return ret; + +fail: + gpiochip_remove(&vg->chip); + + return ret; +} + +static int byt_set_soc_data(struct byt_gpio *vg, + const struct byt_pinctrl_soc_data *soc_data) +{ + int i; + + vg->soc_data = soc_data; + vg->communities_copy = devm_kcalloc(&vg->pdev->dev, + soc_data->ncommunities, + sizeof(*vg->communities_copy), + GFP_KERNEL); + if (!vg->communities_copy) + return -ENOMEM; + + for (i = 0; i < soc_data->ncommunities; i++) { + struct byt_community *comm = vg->communities_copy + i; + struct resource *mem_rc; + + *comm = vg->soc_data->communities[i]; + + mem_rc = platform_get_resource(vg->pdev, IORESOURCE_MEM, 0); + comm->reg_base = devm_ioremap_resource(&vg->pdev->dev, mem_rc); + if (IS_ERR(comm->reg_base)) + return PTR_ERR(comm->reg_base); + } + + return 0; +} + +static const struct acpi_device_id byt_gpio_acpi_match[] = { + { "INT33B2", (kernel_ulong_t)byt_soc_data }, + { "INT33FC", (kernel_ulong_t)byt_soc_data }, + { } +}; +MODULE_DEVICE_TABLE(acpi, byt_gpio_acpi_match); + +static int byt_pinctrl_probe(struct platform_device *pdev) +{ + const struct byt_pinctrl_soc_data *soc_data = NULL; + const struct byt_pinctrl_soc_data **soc_table; + const struct acpi_device_id *acpi_id; + struct acpi_device *acpi_dev; + struct byt_gpio *vg; + int i, ret; + + acpi_dev = ACPI_COMPANION(&pdev->dev); + if (!acpi_dev) + return -ENODEV; + + acpi_id = acpi_match_device(byt_gpio_acpi_match, &pdev->dev); + if (!acpi_id) + return -ENODEV; + + soc_table = (const struct byt_pinctrl_soc_data **)acpi_id->driver_data; + + for (i = 0; soc_table[i]; i++) { + if (!strcmp(acpi_dev->pnp.unique_id, soc_table[i]->uid)) { + soc_data = soc_table[i]; + break; + } + } + + if (!soc_data) + return -ENODEV; + + vg = devm_kzalloc(&pdev->dev, sizeof(*vg), GFP_KERNEL); + if (!vg) + return -ENOMEM; + + vg->pdev = pdev; + ret = byt_set_soc_data(vg, soc_data); + if (ret) { + dev_err(&pdev->dev, "failed to set soc data\n"); + return ret; + } + + vg->pctl_desc = byt_pinctrl_desc; + vg->pctl_desc.name = dev_name(&pdev->dev); + vg->pctl_desc.pins = vg->soc_data->pins; + vg->pctl_desc.npins = vg->soc_data->npins; + + vg->pctl_dev = pinctrl_register(&vg->pctl_desc, &pdev->dev, vg); + if (IS_ERR(vg->pctl_dev)) { + dev_err(&pdev->dev, "failed to register pinctrl driver\n"); + return PTR_ERR(vg->pctl_dev); + } + + ret = byt_gpio_probe(vg); + if (ret) { + pinctrl_unregister(vg->pctl_dev); + return ret; + } + + platform_set_drvdata(pdev, vg); + raw_spin_lock_init(&vg->lock); + pm_runtime_enable(&pdev->dev); + + return 0; +} + +static int byt_pinctrl_remove(struct platform_device *pdev) +{ + struct byt_gpio *vg = platform_get_drvdata(pdev); + + pm_runtime_disable(&pdev->dev); + gpiochip_remove(&vg->chip); + pinctrl_unregister(vg->pctl_dev); return 0; } @@ -1756,15 +1754,22 @@ static int byt_gpio_suspend(struct device *dev) struct byt_gpio *vg = platform_get_drvdata(pdev); int i; - for (i = 0; i < vg->chip.ngpio; i++) { + for (i = 0; i < vg->soc_data->npins; i++) { void __iomem *reg; u32 value; + unsigned int pin = vg->soc_data->pins[i].number; - reg = byt_gpio_reg(vg, i, BYT_CONF0_REG); + reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); + if (!reg) { + dev_warn(&vg->pdev->dev, + "Pin %i: could not retrieve conf0 register\n", + i); + continue; + } value = readl(reg) & BYT_CONF0_RESTORE_MASK; vg->saved_context[i].conf0 = value; - reg = byt_gpio_reg(vg, i, BYT_VAL_REG); + reg = byt_gpio_reg(vg, pin, BYT_VAL_REG); value = readl(reg) & BYT_VAL_RESTORE_MASK; vg->saved_context[i].val = value; } @@ -1778,11 +1783,18 @@ static int byt_gpio_resume(struct device *dev) struct byt_gpio *vg = platform_get_drvdata(pdev); int i; - for (i = 0; i < vg->chip.ngpio; i++) { + for (i = 0; i < vg->soc_data->npins; i++) { void __iomem *reg; u32 value; + unsigned int pin = vg->soc_data->pins[i].number; - reg = byt_gpio_reg(vg, i, BYT_CONF0_REG); + reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); + if (!reg) { + dev_warn(&vg->pdev->dev, + "Pin %i: could not retrieve conf0 register\n", + i); + continue; + } value = readl(reg); if ((value & BYT_CONF0_RESTORE_MASK) != vg->saved_context[i].conf0) { @@ -1792,7 +1804,7 @@ static int byt_gpio_resume(struct device *dev) dev_info(dev, "restored pin %d conf0 %#08x", i, value); } - reg = byt_gpio_reg(vg, i, BYT_VAL_REG); + reg = byt_gpio_reg(vg, pin, BYT_VAL_REG); value = readl(reg); if ((value & BYT_VAL_RESTORE_MASK) != vg->saved_context[i].val) { @@ -1830,26 +1842,9 @@ static const struct dev_pm_ops byt_gpio_pm_ops = { NULL) }; -static const struct acpi_device_id byt_gpio_acpi_match[] = { - { "INT33B2", (kernel_ulong_t)byt_soc_data }, - { "INT33FC", (kernel_ulong_t)byt_soc_data }, - { } -}; -MODULE_DEVICE_TABLE(acpi, byt_gpio_acpi_match); - -static int byt_gpio_remove(struct platform_device *pdev) -{ - struct byt_gpio *vg = platform_get_drvdata(pdev); - - pm_runtime_disable(&pdev->dev); - gpiochip_remove(&vg->chip); - - return 0; -} - static struct platform_driver byt_gpio_driver = { - .probe = byt_gpio_probe, - .remove = byt_gpio_remove, + .probe = byt_pinctrl_probe, + .remove = byt_pinctrl_remove, .driver = { .name = "byt_gpio", .pm = &byt_gpio_pm_ops, -- cgit v1.2.3 From 658b476c742fe379e7020309fd590a27b457a4c1 Mon Sep 17 00:00:00 2001 From: Cristina Ciocan Date: Fri, 1 Apr 2016 14:00:07 +0300 Subject: pinctrl: baytrail: Add debounce configuration Make debounce setting and getting functionality available when configurating a certain pin. Signed-off-by: Cristina Ciocan Acked-by: Mika Westerberg Signed-off-by: Linus Walleij --- drivers/pinctrl/intel/pinctrl-baytrail.c | 83 +++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index b087b0030617..6dcf43ab9efe 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -38,6 +38,7 @@ #define BYT_VAL_REG 0x008 #define BYT_DFT_REG 0x00c #define BYT_INT_STAT_REG 0x800 +#define BYT_DEBOUNCE_REG 0x9d0 /* BYT_CONF0_REG register bits */ #define BYT_IODEN BIT(31) @@ -45,6 +46,7 @@ #define BYT_TRIG_NEG BIT(26) #define BYT_TRIG_POS BIT(25) #define BYT_TRIG_LVL BIT(24) +#define BYT_DEBOUNCE_EN BIT(20) #define BYT_PULL_STR_SHIFT 9 #define BYT_PULL_STR_MASK (3 << BYT_PULL_STR_SHIFT) #define BYT_PULL_STR_2K (0 << BYT_PULL_STR_SHIFT) @@ -69,6 +71,16 @@ BYT_PIN_MUX) #define BYT_VAL_RESTORE_MASK (BYT_DIR_MASK | BYT_LEVEL) +/* BYT_DEBOUNCE_REG bits */ +#define BYT_DEBOUNCE_PULSE_MASK 0x7 +#define BYT_DEBOUNCE_PULSE_375US 1 +#define BYT_DEBOUNCE_PULSE_750US 2 +#define BYT_DEBOUNCE_PULSE_1500US 3 +#define BYT_DEBOUNCE_PULSE_3MS 4 +#define BYT_DEBOUNCE_PULSE_6MS 5 +#define BYT_DEBOUNCE_PULSE_12MS 6 +#define BYT_DEBOUNCE_PULSE_24MS 7 + #define BYT_NGPIO_SCORE 102 #define BYT_NGPIO_NCORE 28 #define BYT_NGPIO_SUS 44 @@ -1078,7 +1090,7 @@ static int byt_pin_config_get(struct pinctrl_dev *pctl_dev, unsigned int offset, void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); unsigned long flags; - u32 conf, pull, val; + u32 conf, pull, val, debounce; u16 arg = 0; raw_spin_lock_irqsave(&vg->lock, flags); @@ -1107,6 +1119,41 @@ static int byt_pin_config_get(struct pinctrl_dev *pctl_dev, unsigned int offset, byt_get_pull_strength(conf, &arg); + break; + case PIN_CONFIG_INPUT_DEBOUNCE: + if (!(conf & BYT_DEBOUNCE_EN)) + return -EINVAL; + + raw_spin_lock_irqsave(&vg->lock, flags); + debounce = readl(byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG)); + raw_spin_unlock_irqrestore(&vg->lock, flags); + + switch (debounce & BYT_DEBOUNCE_PULSE_MASK) { + case BYT_DEBOUNCE_PULSE_375US: + arg = 375; + break; + case BYT_DEBOUNCE_PULSE_750US: + arg = 750; + break; + case BYT_DEBOUNCE_PULSE_1500US: + arg = 1500; + break; + case BYT_DEBOUNCE_PULSE_3MS: + arg = 3000; + break; + case BYT_DEBOUNCE_PULSE_6MS: + arg = 6000; + break; + case BYT_DEBOUNCE_PULSE_12MS: + arg = 12000; + break; + case BYT_DEBOUNCE_PULSE_24MS: + arg = 24000; + break; + default: + return -EINVAL; + } + break; default: return -ENOTSUPP; @@ -1127,7 +1174,7 @@ static int byt_pin_config_set(struct pinctrl_dev *pctl_dev, void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); unsigned long flags; - u32 conf, val; + u32 conf, val, debounce; int i, ret = 0; raw_spin_lock_irqsave(&vg->lock, flags); @@ -1186,6 +1233,38 @@ static int byt_pin_config_set(struct pinctrl_dev *pctl_dev, conf |= BYT_PULL_ASSIGN_UP; ret = byt_set_pull_strength(&conf, arg); + break; + case PIN_CONFIG_INPUT_DEBOUNCE: + debounce = readl(byt_gpio_reg(vg, offset, + BYT_DEBOUNCE_REG)); + conf &= ~BYT_DEBOUNCE_PULSE_MASK; + + switch (arg) { + case 375: + conf |= BYT_DEBOUNCE_PULSE_375US; + break; + case 750: + conf |= BYT_DEBOUNCE_PULSE_750US; + break; + case 1500: + conf |= BYT_DEBOUNCE_PULSE_1500US; + break; + case 3000: + conf |= BYT_DEBOUNCE_PULSE_3MS; + break; + case 6000: + conf |= BYT_DEBOUNCE_PULSE_6MS; + break; + case 12000: + conf |= BYT_DEBOUNCE_PULSE_12MS; + break; + case 24000: + conf |= BYT_DEBOUNCE_PULSE_24MS; + break; + default: + ret = -EINVAL; + } + break; default: ret = -ENOTSUPP; -- cgit v1.2.3 From 5b01e4b9efa0b78672cbbea830c9fbcc7f239e29 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 4 Apr 2016 11:43:54 +0200 Subject: libata: Implement NCQ autosense Some newer devices support NCQ autosense (cf ACS-4), so we should be using it to retrieve the sense code and speed up recovery. Signed-off-by: Hannes Reinecke Signed-off-by: Tejun Heo --- drivers/ata/libata-eh.c | 12 ++++++++++++ drivers/ata/libata-scsi.c | 7 ++++++- drivers/ata/libata.h | 1 + include/linux/ata.h | 2 ++ 4 files changed, 21 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 961acc788f44..8c8355f0792e 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -1600,6 +1600,8 @@ static int ata_eh_read_log_10h(struct ata_device *dev, tf->hob_lbah = buf[10]; tf->nsect = buf[12]; tf->hob_nsect = buf[13]; + if (ata_id_has_ncq_autosense(dev->id)) + tf->auxiliary = buf[14] << 16 | buf[15] << 8 | buf[16]; return 0; } @@ -1797,6 +1799,16 @@ void ata_eh_analyze_ncq_error(struct ata_link *link) memcpy(&qc->result_tf, &tf, sizeof(tf)); qc->result_tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_LBA | ATA_TFLAG_LBA48; qc->err_mask |= AC_ERR_DEV | AC_ERR_NCQ; + if (qc->result_tf.auxiliary) { + char sense_key, asc, ascq; + + sense_key = (qc->result_tf.auxiliary >> 16) & 0xff; + asc = (qc->result_tf.auxiliary >> 8) & 0xff; + ascq = qc->result_tf.auxiliary & 0xff; + ata_scsi_set_sense(qc->scsicmd, sense_key, asc, ascq); + qc->flags |= ATA_QCFLAG_SENSE_VALID; + } + ehc->i.err_mask &= ~AC_ERR_DEV; } diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 567859ce0512..6dc2fadfd7c5 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -270,8 +270,11 @@ DEVICE_ATTR(unload_heads, S_IRUGO | S_IWUSR, ata_scsi_park_show, ata_scsi_park_store); EXPORT_SYMBOL_GPL(dev_attr_unload_heads); -static void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq) +void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq) { + if (!cmd) + return; + cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; scsi_build_sense_buffer(0, cmd->sense_buffer, sk, asc, ascq); @@ -1784,6 +1787,8 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) if (((cdb[0] == ATA_16) || (cdb[0] == ATA_12)) && ((cdb[2] & 0x20) || need_sense)) ata_gen_passthru_sense(qc); + else if (qc->flags & ATA_QCFLAG_SENSE_VALID) + cmd->result = SAM_STAT_CHECK_CONDITION; else if (need_sense) ata_gen_ata_sense(qc); else diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index f840ca18a7c0..8cfdd9616d16 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -137,6 +137,7 @@ extern int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht); extern void ata_scsi_scan_host(struct ata_port *ap, int sync); extern int ata_scsi_offline_dev(struct ata_device *dev); +extern void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq); extern void ata_scsi_media_change_notify(struct ata_device *dev); extern void ata_scsi_hotplug(struct work_struct *work); extern void ata_schedule_scsi_eh(struct Scsi_Host *shost); diff --git a/include/linux/ata.h b/include/linux/ata.h index c1a2f345cbe6..e797e1b53006 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -528,6 +528,8 @@ struct ata_bmdma_prd { #define ata_id_cdb_intr(id) (((id)[ATA_ID_CONFIG] & 0x60) == 0x20) #define ata_id_has_da(id) ((id)[ATA_ID_SATA_CAPABILITY_2] & (1 << 4)) #define ata_id_has_devslp(id) ((id)[ATA_ID_FEATURE_SUPP] & (1 << 8)) +#define ata_id_has_ncq_autosense(id) \ + ((id)[ATA_ID_FEATURE_SUPP] & (1 << 7)) static inline bool ata_id_has_hipm(const u16 *id) { -- cgit v1.2.3 From e87fd28cf9a2d9018ac4b6dd92f0b417714bc18d Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 4 Apr 2016 11:43:55 +0200 Subject: libata: Implement support for sense data reporting ACS-4 defines a sense data reporting feature set. This patch implements support for it. tj: Cosmetic formatting updates. Signed-off-by: Hannes Reinecke Signed-off-by: Tejun Heo --- drivers/ata/libata-core.c | 20 +++++++++++++- drivers/ata/libata-eh.c | 68 ++++++++++++++++++++++++++++++++++++++++++++--- include/linux/ata.h | 16 +++++++++++ 3 files changed, 99 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 55e257c268dd..f991f786227e 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2148,6 +2148,24 @@ static int ata_dev_config_ncq(struct ata_device *dev, return 0; } +static void ata_dev_config_sense_reporting(struct ata_device *dev) +{ + unsigned int err_mask; + + if (!ata_id_has_sense_reporting(dev->id)) + return; + + if (ata_id_sense_reporting_enabled(dev->id)) + return; + + err_mask = ata_dev_set_feature(dev, SETFEATURE_SENSE_DATA, 0x1); + if (err_mask) { + ata_dev_dbg(dev, + "failed to enable Sense Data Reporting, Emask 0x%x\n", + err_mask); + } +} + /** * ata_dev_configure - Configure the specified ATA/ATAPI device * @dev: Target device to configure @@ -2370,7 +2388,7 @@ int ata_dev_configure(struct ata_device *dev) dev->devslp_timing[i] = sata_setting[j]; } } - + ata_dev_config_sense_reporting(dev); dev->cdb_len = 16; } diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 8c8355f0792e..170e891e79af 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -1637,6 +1637,56 @@ unsigned int atapi_eh_tur(struct ata_device *dev, u8 *r_sense_key) return err_mask; } +/** + * ata_eh_request_sense - perform REQUEST_SENSE_DATA_EXT + * @dev: device to perform REQUEST_SENSE_SENSE_DATA_EXT to + * @cmd: scsi command for which the sense code should be set + * + * Perform REQUEST_SENSE_DATA_EXT after the device reported CHECK + * SENSE. This function is an EH helper. + * + * LOCKING: + * Kernel thread context (may sleep). + */ +static void ata_eh_request_sense(struct ata_queued_cmd *qc, + struct scsi_cmnd *cmd) +{ + struct ata_device *dev = qc->dev; + struct ata_taskfile tf; + unsigned int err_mask; + + if (qc->ap->pflags & ATA_PFLAG_FROZEN) { + ata_dev_warn(dev, "sense data available but port frozen\n"); + return; + } + + if (!cmd) + return; + + if (!ata_id_sense_reporting_enabled(dev->id)) { + ata_dev_warn(qc->dev, "sense data reporting disabled\n"); + return; + } + + DPRINTK("ATA request sense\n"); + + ata_tf_init(dev, &tf); + tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; + tf.flags |= ATA_TFLAG_LBA | ATA_TFLAG_LBA48; + tf.command = ATA_CMD_REQ_SENSE_DATA; + tf.protocol = ATA_PROT_NODATA; + + err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0); + /* Ignore err_mask; ATA_ERR might be set */ + if (tf.command & ATA_SENSE) { + ata_scsi_set_sense(cmd, tf.lbah, tf.lbam, tf.lbal); + qc->flags |= ATA_QCFLAG_SENSE_VALID; + } else { + ata_dev_warn(dev, "request sense failed stat %02x emask %x\n", + tf.command, err_mask); + } +} + /** * atapi_eh_request_sense - perform ATAPI REQUEST_SENSE * @dev: device to perform REQUEST_SENSE to @@ -1838,14 +1888,23 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc, return ATA_EH_RESET; } - if (stat & (ATA_ERR | ATA_DF)) + if (stat & (ATA_ERR | ATA_DF)) { qc->err_mask |= AC_ERR_DEV; - else + /* + * Sense data reporting does not work if the + * device fault bit is set. + */ + if (stat & ATA_DF) + stat &= ~ATA_SENSE; + } else { return 0; + } switch (qc->dev->class) { case ATA_DEV_ATA: case ATA_DEV_ZAC: + if (stat & ATA_SENSE) + ata_eh_request_sense(qc, qc->scsicmd); if (err & ATA_ICRC) qc->err_mask |= AC_ERR_ATA_BUS; if (err & (ATA_UNC | ATA_AMNF)) @@ -2581,14 +2640,15 @@ static void ata_eh_link_report(struct ata_link *link) #ifdef CONFIG_ATA_VERBOSE_ERROR if (res->command & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ | - ATA_ERR)) { + ATA_SENSE | ATA_ERR)) { if (res->command & ATA_BUSY) ata_dev_err(qc->dev, "status: { Busy }\n"); else - ata_dev_err(qc->dev, "status: { %s%s%s%s}\n", + ata_dev_err(qc->dev, "status: { %s%s%s%s%s}\n", res->command & ATA_DRDY ? "DRDY " : "", res->command & ATA_DF ? "DF " : "", res->command & ATA_DRQ ? "DRQ " : "", + res->command & ATA_SENSE ? "SENSE " : "", res->command & ATA_ERR ? "ERR " : ""); } diff --git a/include/linux/ata.h b/include/linux/ata.h index e797e1b53006..00aebc4c83ad 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -385,6 +385,8 @@ enum { SATA_SSP = 0x06, /* Software Settings Preservation */ SATA_DEVSLP = 0x09, /* Device Sleep */ + SETFEATURE_SENSE_DATA = 0xC3, /* Sense Data Reporting feature */ + /* feature values for SET_MAX */ ATA_SET_MAX_ADDR = 0x00, ATA_SET_MAX_PASSWD = 0x01, @@ -718,6 +720,20 @@ static inline bool ata_id_has_read_log_dma_ext(const u16 *id) return false; } +static inline bool ata_id_has_sense_reporting(const u16 *id) +{ + if (!(id[ATA_ID_CFS_ENABLE_2] & (1 << 15))) + return false; + return id[ATA_ID_COMMAND_SET_3] & (1 << 6); +} + +static inline bool ata_id_sense_reporting_enabled(const u16 *id) +{ + if (!(id[ATA_ID_CFS_ENABLE_2] & (1 << 15))) + return false; + return id[ATA_ID_COMMAND_SET_4] & (1 << 6); +} + /** * ata_id_major_version - get ATA level of drive * @id: Identify data -- cgit v1.2.3 From 5e6acd1c8c4dc9a7c16208aeac3de09151ee6233 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 4 Apr 2016 11:43:56 +0200 Subject: libata-scsi: sanitize ata_gen_ata_sense() ata_to_sense_error() is called conditionally, so we should be generating a default sense if the condition is not met. Signed-off-by: Hannes Reinecke Signed-off-by: Tejun Heo --- drivers/ata/libata-scsi.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 6dc2fadfd7c5..e331077ee446 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1074,6 +1074,12 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc) ata_to_sense_error(qc->ap->print_id, tf->command, tf->feature, &sb[1], &sb[2], &sb[3], verbose); sb[1] &= 0x0f; + } else { + /* Could not decode error */ + ata_dev_warn(dev, "could not decode error status 0x%x err_mask 0x%x\n", + tf->command, qc->err_mask); + ata_scsi_set_sense(cmd, ABORTED_COMMAND, 0, 0); + return; } block = ata_tf_read_block(&qc->result_tf, dev); -- cgit v1.2.3 From cffd1ee991c566bca937392cfacdafbe3b7b58c6 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 4 Apr 2016 11:43:57 +0200 Subject: libata: sanitize ata_tf_read_block() Return U64_MAX if ata_tf_read_block() could not decode the LBA address, and do not set the information sense descriptor in ata_gen_ata_sense() in these cases. tj: s/(u64)-1/U64_MAX/ Signed-off-by: Hannes Reinecke Signed-off-by: Tejun Heo --- drivers/ata/libata-core.c | 4 ++-- drivers/ata/libata-scsi.c | 2 ++ drivers/ata/libata.h | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index f991f786227e..7bdb2c4e357f 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -695,7 +695,7 @@ static int ata_rwcmd_protocol(struct ata_taskfile *tf, struct ata_device *dev) * RETURNS: * Block address read from @tf. */ -u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev) +u64 ata_tf_read_block(const struct ata_taskfile *tf, struct ata_device *dev) { u64 block = 0; @@ -720,7 +720,7 @@ u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev) if (!sect) { ata_dev_warn(dev, "device reported invalid CHS sector 0\n"); - sect = 1; /* oh well */ + return U64_MAX; } block = (cyl * dev->heads + head) * dev->sectors + sect - 1; diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index e331077ee446..fc23d3f4282d 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1083,6 +1083,8 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc) } block = ata_tf_read_block(&qc->result_tf, dev); + if (block == U64_MAX) + return; /* information sense data descriptor */ sb[7] = 12; diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 8cfdd9616d16..507c22f7a63b 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -67,7 +67,8 @@ extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int tag); extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev, u64 block, u32 n_block, unsigned int tf_flags, unsigned int tag); -extern u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev); +extern u64 ata_tf_read_block(const struct ata_taskfile *tf, + struct ata_device *dev); extern unsigned ata_exec_internal(struct ata_device *dev, struct ata_taskfile *tf, const u8 *cdb, int dma_dir, void *buf, unsigned int buflen, -- cgit v1.2.3 From cf8b49b0af39b8e8fa358623acda57f01251b6d4 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 4 Apr 2016 11:43:58 +0200 Subject: libata-scsi: use scsi_set_sense_information() Use scsi_set_sense_information() instead of hand-crafted function. Signed-off-by: Hannes Reinecke Signed-off-by: Tejun Heo --- drivers/ata/libata-scsi.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index fc23d3f4282d..47b103d9baac 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1055,7 +1055,6 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc) struct scsi_cmnd *cmd = qc->scsicmd; struct ata_taskfile *tf = &qc->result_tf; unsigned char *sb = cmd->sense_buffer; - unsigned char *desc = sb + 8; int verbose = qc->ap->ops->error_handler == NULL; u64 block; @@ -1086,18 +1085,7 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc) if (block == U64_MAX) return; - /* information sense data descriptor */ - sb[7] = 12; - desc[0] = 0x00; - desc[1] = 10; - - desc[2] |= 0x80; /* valid */ - desc[6] = block >> 40; - desc[7] = block >> 32; - desc[8] = block >> 24; - desc[9] = block >> 16; - desc[10] = block >> 8; - desc[11] = block; + scsi_set_sense_information(sb, SCSI_SENSE_BUFFERSIZE, block); } static void ata_scsi_sdev_config(struct scsi_device *sdev) -- cgit v1.2.3 From 492bf62107347aca764070dbc9d412da6bda73d1 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 4 Apr 2016 11:43:59 +0200 Subject: libata-eh: Set 'information' field for autosense If NCQ autosense or the sense data reporting feature is enabled the LBA of the offending command should be stored in the sense data 'information' field. tj: s/(u64)-1/U64_MAX/ Signed-off-by: Hannes Reinecke Signed-off-by: Tejun Heo --- drivers/ata/libata-eh.c | 2 ++ drivers/ata/libata-scsi.c | 17 +++++++++++++++++ drivers/ata/libata.h | 3 +++ 3 files changed, 22 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 170e891e79af..e4e0e2e80c20 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -1856,6 +1856,8 @@ void ata_eh_analyze_ncq_error(struct ata_link *link) asc = (qc->result_tf.auxiliary >> 8) & 0xff; ascq = qc->result_tf.auxiliary & 0xff; ata_scsi_set_sense(qc->scsicmd, sense_key, asc, ascq); + ata_scsi_set_sense_information(dev, qc->scsicmd, + &qc->result_tf); qc->flags |= ATA_QCFLAG_SENSE_VALID; } diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 47b103d9baac..97e8f6b0494c 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -280,6 +280,23 @@ void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq) scsi_build_sense_buffer(0, cmd->sense_buffer, sk, asc, ascq); } +void ata_scsi_set_sense_information(struct ata_device *dev, + struct scsi_cmnd *cmd, + const struct ata_taskfile *tf) +{ + u64 information; + + if (!cmd) + return; + + information = ata_tf_read_block(tf, dev); + if (information == U64_MAX) + return; + + scsi_set_sense_information(cmd->sense_buffer, + SCSI_SENSE_BUFFERSIZE, information); +} + static ssize_t ata_scsi_em_message_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 507c22f7a63b..dbc67604b3c5 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -139,6 +139,9 @@ extern int ata_scsi_add_hosts(struct ata_host *host, extern void ata_scsi_scan_host(struct ata_port *ap, int sync); extern int ata_scsi_offline_dev(struct ata_device *dev); extern void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq); +extern void ata_scsi_set_sense_information(struct ata_device *dev, + struct scsi_cmnd *cmd, + const struct ata_taskfile *tf); extern void ata_scsi_media_change_notify(struct ata_device *dev); extern void ata_scsi_hotplug(struct work_struct *work); extern void ata_schedule_scsi_eh(struct Scsi_Host *shost); -- cgit v1.2.3 From b525e7731b90ebc7a70a095fc5d5363408b94274 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 4 Apr 2016 11:44:00 +0200 Subject: libata-scsi: use ata_scsi_set_sense() Use ata_scsi_set_sense() throughout to ensure the sense code format is consistent. Signed-off-by: Hannes Reinecke Signed-off-by: Tejun Heo --- drivers/ata/libata-scsi.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 97e8f6b0494c..3c33f32c04c4 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1000,6 +1000,7 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc) unsigned char *sb = cmd->sense_buffer; unsigned char *desc = sb + 8; int verbose = qc->ap->ops->error_handler == NULL; + u8 sense_key, asc, ascq; memset(sb, 0, SCSI_SENSE_BUFFERSIZE); @@ -1012,12 +1013,11 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc) if (qc->err_mask || tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { ata_to_sense_error(qc->ap->print_id, tf->command, tf->feature, - &sb[1], &sb[2], &sb[3], verbose); - sb[1] &= 0x0f; + &sense_key, &asc, &ascq, verbose); + ata_scsi_set_sense(cmd, sense_key, asc, ascq); } else { - sb[1] = RECOVERED_ERROR; - sb[2] = 0; - sb[3] = 0x1D; + /* ATA PASS-THROUGH INFORMATION AVAILABLE */ + ata_scsi_set_sense(cmd, RECOVERED_ERROR, 0, 0x1D); } /* @@ -1074,22 +1074,20 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc) unsigned char *sb = cmd->sense_buffer; int verbose = qc->ap->ops->error_handler == NULL; u64 block; + u8 sense_key, asc, ascq; memset(sb, 0, SCSI_SENSE_BUFFERSIZE); cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; - /* sense data is current and format is descriptor */ - sb[0] = 0x72; - /* Use ata_to_sense_error() to map status register bits * onto sense key, asc & ascq. */ if (qc->err_mask || tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { ata_to_sense_error(qc->ap->print_id, tf->command, tf->feature, - &sb[1], &sb[2], &sb[3], verbose); - sb[1] &= 0x0f; + &sense_key, &asc, &ascq, verbose); + ata_scsi_set_sense(cmd, sense_key, asc, ascq); } else { /* Could not decode error */ ata_dev_warn(dev, "could not decode error status 0x%x err_mask 0x%x\n", -- cgit v1.2.3 From 3852e37382664a06cd006bb389a8223e32cedf45 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 4 Apr 2016 11:44:01 +0200 Subject: libata: evaluate SCSI sense code Whenever a sense code is set it would need to be evaluated to update the error mask. tj: Cosmetic formatting updates. Signed-off-by: Hannes Reinecke Signed-off-by: Tejun Heo --- drivers/ata/libata-eh.c | 29 ++++++++++++++++++++--------- drivers/scsi/scsi_error.c | 3 ++- include/scsi/scsi_eh.h | 1 + 3 files changed, 23 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index e4e0e2e80c20..e37258b78e01 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -1920,20 +1920,31 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc, tmp = atapi_eh_request_sense(qc->dev, qc->scsicmd->sense_buffer, qc->result_tf.feature >> 4); - if (!tmp) { - /* ATA_QCFLAG_SENSE_VALID is used to - * tell atapi_qc_complete() that sense - * data is already valid. - * - * TODO: interpret sense data and set - * appropriate err_mask. - */ + if (!tmp) qc->flags |= ATA_QCFLAG_SENSE_VALID; - } else + else qc->err_mask |= tmp; } } + if (qc->flags & ATA_QCFLAG_SENSE_VALID) { + int ret = scsi_check_sense(qc->scsicmd); + /* + * SUCCESS here means that the sense code could + * evaluated and should be passed to the upper layers + * for correct evaluation. + * FAILED means the sense code could not interpreted + * and the device would need to be reset. + * NEEDS_RETRY and ADD_TO_MLQUEUE means that the + * command would need to be retried. + */ + if (ret == NEEDS_RETRY || ret == ADD_TO_MLQUEUE) { + qc->flags |= ATA_QCFLAG_RETRY; + qc->err_mask |= AC_ERR_OTHER; + } else if (ret != SUCCESS) { + qc->err_mask |= AC_ERR_HSM; + } + } if (qc->err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT | AC_ERR_ATA_BUS)) action |= ATA_EH_RESET; diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 984ddcb4786d..a8b610eaa0ca 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -452,7 +452,7 @@ static void scsi_report_sense(struct scsi_device *sdev, * When a deferred error is detected the current command has * not been executed and needs retrying. */ -static int scsi_check_sense(struct scsi_cmnd *scmd) +int scsi_check_sense(struct scsi_cmnd *scmd) { struct scsi_device *sdev = scmd->device; struct scsi_sense_hdr sshdr; @@ -602,6 +602,7 @@ static int scsi_check_sense(struct scsi_cmnd *scmd) return SUCCESS; } } +EXPORT_SYMBOL_GPL(scsi_check_sense); static void scsi_handle_queue_ramp_up(struct scsi_device *sdev) { diff --git a/include/scsi/scsi_eh.h b/include/scsi/scsi_eh.h index dbb8c640e26f..98d366b55770 100644 --- a/include/scsi/scsi_eh.h +++ b/include/scsi/scsi_eh.h @@ -16,6 +16,7 @@ extern void scsi_report_device_reset(struct Scsi_Host *, int, int); extern int scsi_block_when_processing_errors(struct scsi_device *); extern bool scsi_command_normalize_sense(const struct scsi_cmnd *cmd, struct scsi_sense_hdr *sshdr); +extern int scsi_check_sense(struct scsi_cmnd *); static inline bool scsi_sense_is_deferred(const struct scsi_sense_hdr *sshdr) { -- cgit v1.2.3 From 11093cb1ef56147fe33f5750b1eab347bdef30db Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 4 Apr 2016 11:44:02 +0200 Subject: libata-scsi: generate correct ATA pass-through sense Generate ATA pass-through sense for both fixed and descriptor format sense. Signed-off-by: Hannes Reinecke Signed-off-by: Tejun Heo --- drivers/ata/libata-scsi.c | 93 ++++++++++++++++++++++++++++++----------------- 1 file changed, 59 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 3c33f32c04c4..0da03c019f27 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1016,43 +1016,68 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc) &sense_key, &asc, &ascq, verbose); ata_scsi_set_sense(cmd, sense_key, asc, ascq); } else { - /* ATA PASS-THROUGH INFORMATION AVAILABLE */ - ata_scsi_set_sense(cmd, RECOVERED_ERROR, 0, 0x1D); + /* + * ATA PASS-THROUGH INFORMATION AVAILABLE + * Always in descriptor format sense. + */ + scsi_build_sense_buffer(1, cmd->sense_buffer, + RECOVERED_ERROR, 0, 0x1D); } - /* - * Sense data is current and format is descriptor. - */ - sb[0] = 0x72; - - desc[0] = 0x09; - - /* set length of additional sense data */ - sb[7] = 14; - desc[1] = 12; - - /* - * Copy registers into sense buffer. - */ - desc[2] = 0x00; - desc[3] = tf->feature; /* == error reg */ - desc[5] = tf->nsect; - desc[7] = tf->lbal; - desc[9] = tf->lbam; - desc[11] = tf->lbah; - desc[12] = tf->device; - desc[13] = tf->command; /* == status reg */ + if ((cmd->sense_buffer[0] & 0x7f) >= 0x72) { + u8 len; + + /* descriptor format */ + len = sb[7]; + desc = (char *)scsi_sense_desc_find(sb, len + 8, 9); + if (!desc) { + if (SCSI_SENSE_BUFFERSIZE < len + 14) + return; + sb[7] = len + 14; + desc = sb + 8 + len; + } + desc[0] = 9; + desc[1] = 12; + /* + * Copy registers into sense buffer. + */ + desc[2] = 0x00; + desc[3] = tf->feature; /* == error reg */ + desc[5] = tf->nsect; + desc[7] = tf->lbal; + desc[9] = tf->lbam; + desc[11] = tf->lbah; + desc[12] = tf->device; + desc[13] = tf->command; /* == status reg */ - /* - * Fill in Extend bit, and the high order bytes - * if applicable. - */ - if (tf->flags & ATA_TFLAG_LBA48) { - desc[2] |= 0x01; - desc[4] = tf->hob_nsect; - desc[6] = tf->hob_lbal; - desc[8] = tf->hob_lbam; - desc[10] = tf->hob_lbah; + /* + * Fill in Extend bit, and the high order bytes + * if applicable. + */ + if (tf->flags & ATA_TFLAG_LBA48) { + desc[2] |= 0x01; + desc[4] = tf->hob_nsect; + desc[6] = tf->hob_lbal; + desc[8] = tf->hob_lbam; + desc[10] = tf->hob_lbah; + } + } else { + /* Fixed sense format */ + desc[0] = tf->feature; + desc[1] = tf->command; /* status */ + desc[2] = tf->device; + desc[3] = tf->nsect; + desc[0] = 0; + if (tf->flags & ATA_TFLAG_LBA48) { + desc[8] |= 0x80; + if (tf->hob_nsect) + desc[8] |= 0x40; + if (tf->hob_lbal || tf->hob_lbam || tf->hob_lbah) + desc[8] |= 0x20; + } + desc[9] = tf->lbal; + desc[10] = tf->lbam; + desc[11] = tf->lbah; } } -- cgit v1.2.3 From 06dbde5f3a44248fc02e24d662ac4849202abb48 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 4 Apr 2016 11:44:03 +0200 Subject: libata: Implement control mode page to select sense format Implement MODE SELECT for the control mode page to allow the OS to switch to descriptor sense. tj: Dropped s/sb/cmd->sense_buffer/ in ata_gen_ata_sense(). Added @dev description to ata_msense_ctl_mode(). Signed-off-by: Hannes Reinecke Signed-off-by: Tejun Heo --- drivers/ata/libata-eh.c | 4 +- drivers/ata/libata-scsi.c | 116 ++++++++++++++++++++++++++++++++++------------ drivers/ata/libata.h | 3 +- include/linux/libata.h | 1 + 4 files changed, 91 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index e37258b78e01..5b340ce4eeac 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -1679,7 +1679,7 @@ static void ata_eh_request_sense(struct ata_queued_cmd *qc, err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0); /* Ignore err_mask; ATA_ERR might be set */ if (tf.command & ATA_SENSE) { - ata_scsi_set_sense(cmd, tf.lbah, tf.lbam, tf.lbal); + ata_scsi_set_sense(dev, cmd, tf.lbah, tf.lbam, tf.lbal); qc->flags |= ATA_QCFLAG_SENSE_VALID; } else { ata_dev_warn(dev, "request sense failed stat %02x emask %x\n", @@ -1855,7 +1855,7 @@ void ata_eh_analyze_ncq_error(struct ata_link *link) sense_key = (qc->result_tf.auxiliary >> 16) & 0xff; asc = (qc->result_tf.auxiliary >> 8) & 0xff; ascq = qc->result_tf.auxiliary & 0xff; - ata_scsi_set_sense(qc->scsicmd, sense_key, asc, ascq); + ata_scsi_set_sense(dev, qc->scsicmd, sense_key, asc, ascq); ata_scsi_set_sense_information(dev, qc->scsicmd, &qc->result_tf); qc->flags |= ATA_QCFLAG_SENSE_VALID; diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 0da03c019f27..2389247bdf6f 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -270,14 +270,17 @@ DEVICE_ATTR(unload_heads, S_IRUGO | S_IWUSR, ata_scsi_park_show, ata_scsi_park_store); EXPORT_SYMBOL_GPL(dev_attr_unload_heads); -void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq) +void ata_scsi_set_sense(struct ata_device *dev, struct scsi_cmnd *cmd, + u8 sk, u8 asc, u8 ascq) { + bool d_sense = (dev->flags & ATA_DFLAG_D_SENSE); + if (!cmd) return; cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; - scsi_build_sense_buffer(0, cmd->sense_buffer, sk, asc, ascq); + scsi_build_sense_buffer(d_sense, cmd->sense_buffer, sk, asc, ascq); } void ata_scsi_set_sense_information(struct ata_device *dev, @@ -384,9 +387,10 @@ struct device_attribute *ata_common_sdev_attrs[] = { }; EXPORT_SYMBOL_GPL(ata_common_sdev_attrs); -static void ata_scsi_invalid_field(struct scsi_cmnd *cmd) +static void ata_scsi_invalid_field(struct ata_device *dev, + struct scsi_cmnd *cmd) { - ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, 0x24, 0x0); + ata_scsi_set_sense(dev, cmd, ILLEGAL_REQUEST, 0x24, 0x0); /* "Invalid field in cbd" */ cmd->scsi_done(cmd); } @@ -1014,7 +1018,7 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc) tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { ata_to_sense_error(qc->ap->print_id, tf->command, tf->feature, &sense_key, &asc, &ascq, verbose); - ata_scsi_set_sense(cmd, sense_key, asc, ascq); + ata_scsi_set_sense(qc->dev, cmd, sense_key, asc, ascq); } else { /* * ATA PASS-THROUGH INFORMATION AVAILABLE @@ -1112,12 +1116,12 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc) tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { ata_to_sense_error(qc->ap->print_id, tf->command, tf->feature, &sense_key, &asc, &ascq, verbose); - ata_scsi_set_sense(cmd, sense_key, asc, ascq); + ata_scsi_set_sense(dev, cmd, sense_key, asc, ascq); } else { /* Could not decode error */ ata_dev_warn(dev, "could not decode error status 0x%x err_mask 0x%x\n", tf->command, qc->err_mask); - ata_scsi_set_sense(cmd, ABORTED_COMMAND, 0, 0); + ata_scsi_set_sense(dev, cmd, ABORTED_COMMAND, 0, 0); return; } @@ -1440,7 +1444,7 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) return 0; invalid_fld: - ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0); + ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x24, 0x0); /* "Invalid field in cbd" */ return 1; skip: @@ -1679,12 +1683,12 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc) return 0; invalid_fld: - ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0); + ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x24, 0x0); /* "Invalid field in cbd" */ return 1; out_of_range: - ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x21, 0x0); + ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x21, 0x0); /* "Logical Block Address out of range" */ return 1; @@ -1781,12 +1785,12 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc) goto out_of_range; /* treat all other errors as -EINVAL, fall through */ invalid_fld: - ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0); + ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x24, 0x0); /* "Invalid field in cbd" */ return 1; out_of_range: - ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x21, 0x0); + ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x21, 0x0); /* "Logical Block Address out of range" */ return 1; @@ -2358,6 +2362,7 @@ static unsigned int ata_msense_caching(u16 *id, u8 *buf, bool changeable) /** * ata_msense_ctl_mode - Simulate MODE SENSE control mode page + * @dev: ATA device of interest * @buf: output buffer * @changeable: whether changeable parameters are requested * @@ -2366,9 +2371,12 @@ static unsigned int ata_msense_caching(u16 *id, u8 *buf, bool changeable) * LOCKING: * None. */ -static unsigned int ata_msense_ctl_mode(u8 *buf, bool changeable) +static unsigned int ata_msense_ctl_mode(struct ata_device *dev, u8 *buf, + bool changeable) { modecpy(buf, def_control_mpage, sizeof(def_control_mpage), changeable); + if (changeable && (dev->flags & ATA_DFLAG_D_SENSE)) + buf[2] |= (1 << 2); /* Descriptor sense requested */ return sizeof(def_control_mpage); } @@ -2482,13 +2490,13 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf) break; case CONTROL_MPAGE: - p += ata_msense_ctl_mode(p, page_control == 1); + p += ata_msense_ctl_mode(args->dev, p, page_control == 1); break; case ALL_MPAGES: p += ata_msense_rw_recovery(p, page_control == 1); p += ata_msense_caching(args->id, p, page_control == 1); - p += ata_msense_ctl_mode(p, page_control == 1); + p += ata_msense_ctl_mode(args->dev, p, page_control == 1); break; default: /* invalid page code */ @@ -2521,12 +2529,12 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf) return 0; invalid_fld: - ata_scsi_set_sense(args->cmd, ILLEGAL_REQUEST, 0x24, 0x0); + ata_scsi_set_sense(dev, args->cmd, ILLEGAL_REQUEST, 0x24, 0x0); /* "Invalid field in cbd" */ return 1; saving_not_supp: - ata_scsi_set_sense(args->cmd, ILLEGAL_REQUEST, 0x39, 0x0); + ata_scsi_set_sense(dev, args->cmd, ILLEGAL_REQUEST, 0x39, 0x0); /* "Saving parameters not supported" */ return 1; } @@ -3163,7 +3171,7 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) return 0; invalid_fld: - ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x00); + ata_scsi_set_sense(dev, scmd, ILLEGAL_REQUEST, 0x24, 0x00); /* "Invalid field in cdb" */ return 1; } @@ -3228,7 +3236,7 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc) return 0; invalid_fld: - ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x00); + ata_scsi_set_sense(dev, scmd, ILLEGAL_REQUEST, 0x24, 0x00); /* "Invalid field in cdb" */ return 1; } @@ -3279,6 +3287,51 @@ static int ata_mselect_caching(struct ata_queued_cmd *qc, return 0; } +/** + * ata_mselect_control - Simulate MODE SELECT for control page + * @qc: Storage for translated ATA taskfile + * @buf: input buffer + * @len: number of valid bytes in the input buffer + * + * Prepare a taskfile to modify caching information for the device. + * + * LOCKING: + * None. + */ +static int ata_mselect_control(struct ata_queued_cmd *qc, + const u8 *buf, int len) +{ + struct ata_device *dev = qc->dev; + char mpage[CONTROL_MPAGE_LEN]; + u8 d_sense; + + /* + * The first two bytes of def_control_mpage are a header, so offsets + * in mpage are off by 2 compared to buf. Same for len. + */ + + if (len != CONTROL_MPAGE_LEN - 2) + return -EINVAL; + + d_sense = buf[0] & (1 << 2); + + /* + * Check that read-only bits are not modified. + */ + ata_msense_ctl_mode(dev, mpage, false); + mpage[2] &= ~(1 << 2); + mpage[2] |= d_sense; + if (memcmp(mpage + 2, buf, CONTROL_MPAGE_LEN - 2) != 0) + return -EINVAL; + if (d_sense & (1 << 2)) + dev->flags |= ATA_DFLAG_D_SENSE; + else + dev->flags &= ~ATA_DFLAG_D_SENSE; + qc->scsicmd->result = SAM_STAT_GOOD; + qc->scsicmd->scsi_done(qc->scsicmd); + return 0; +} + /** * ata_scsiop_mode_select - Simulate MODE SELECT 6, 10 commands * @qc: Storage for translated ATA taskfile @@ -3381,7 +3434,10 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc) if (ata_mselect_caching(qc, p, pg_len) < 0) goto invalid_param; break; - + case CONTROL_MPAGE: + if (ata_mselect_control(qc, p, pg_len) < 0) + goto invalid_param; + break; default: /* invalid page code */ goto invalid_param; } @@ -3397,17 +3453,17 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc) invalid_fld: /* "Invalid field in CDB" */ - ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0); + ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x24, 0x0); return 1; invalid_param: /* "Invalid field in parameter list" */ - ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x26, 0x0); + ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x26, 0x0); return 1; invalid_param_len: /* "Parameter list length error" */ - ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x1a, 0x0); + ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x1a, 0x0); return 1; skip: @@ -3611,12 +3667,12 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) switch(scsicmd[0]) { /* TODO: worth improving? */ case FORMAT_UNIT: - ata_scsi_invalid_field(cmd); + ata_scsi_invalid_field(dev, cmd); break; case INQUIRY: if (scsicmd[1] & 2) /* is CmdDt set? */ - ata_scsi_invalid_field(cmd); + ata_scsi_invalid_field(dev, cmd); else if ((scsicmd[1] & 1) == 0) /* is EVPD clear? */ ata_scsi_rbuf_fill(&args, ata_scsiop_inq_std); else switch (scsicmd[2]) { @@ -3642,7 +3698,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b2); break; default: - ata_scsi_invalid_field(cmd); + ata_scsi_invalid_field(dev, cmd); break; } break; @@ -3660,7 +3716,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) if ((scsicmd[1] & 0x1f) == SAI_READ_CAPACITY_16) ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap); else - ata_scsi_invalid_field(cmd); + ata_scsi_invalid_field(dev, cmd); break; case REPORT_LUNS: @@ -3668,7 +3724,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) break; case REQUEST_SENSE: - ata_scsi_set_sense(cmd, 0, 0, 0); + ata_scsi_set_sense(dev, cmd, 0, 0, 0); cmd->result = (DRIVER_SENSE << 24); cmd->scsi_done(cmd); break; @@ -3692,12 +3748,12 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) if ((tmp8 == 0x4) && (!scsicmd[3]) && (!scsicmd[4])) ata_scsi_rbuf_fill(&args, ata_scsiop_noop); else - ata_scsi_invalid_field(cmd); + ata_scsi_invalid_field(dev, cmd); break; /* all other commands */ default: - ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, 0x20, 0x0); + ata_scsi_set_sense(dev, cmd, ILLEGAL_REQUEST, 0x20, 0x0); /* "Invalid command operation code" */ cmd->scsi_done(cmd); break; diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index dbc67604b3c5..3b301a48007c 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -138,7 +138,8 @@ extern int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht); extern void ata_scsi_scan_host(struct ata_port *ap, int sync); extern int ata_scsi_offline_dev(struct ata_device *dev); -extern void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq); +extern void ata_scsi_set_sense(struct ata_device *dev, + struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq); extern void ata_scsi_set_sense_information(struct ata_device *dev, struct scsi_cmnd *cmd, const struct ata_taskfile *tf); diff --git a/include/linux/libata.h b/include/linux/libata.h index 2c4ebef79d0c..a418bca0df0d 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -180,6 +180,7 @@ enum { ATA_DFLAG_DA = (1 << 26), /* device supports Device Attention */ ATA_DFLAG_DEVSLP = (1 << 27), /* device supports Device Sleep */ ATA_DFLAG_ACPI_DISABLED = (1 << 28), /* ACPI for the device is disabled */ + ATA_DFLAG_D_SENSE = (1 << 29), /* Descriptor sense requested */ ATA_DEV_UNKNOWN = 0, /* unknown device */ ATA_DEV_ATA = 1, /* ATA device */ -- cgit v1.2.3 From 78db6e30281aa056a6773cb4def00afc158c097f Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 4 Apr 2016 11:44:04 +0200 Subject: scsi: add scsi_set_sense_field_pointer() Add a function to set the field pointer for SCSI sense codes. Signed-off-by: Hannes Reinecke Signed-off-by: Tejun Heo --- drivers/scsi/scsi_common.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++ include/scsi/scsi_common.h | 1 + 2 files changed, 54 insertions(+) (limited to 'drivers') diff --git a/drivers/scsi/scsi_common.c b/drivers/scsi/scsi_common.c index ce79de822e46..b1383a71400e 100644 --- a/drivers/scsi/scsi_common.c +++ b/drivers/scsi/scsi_common.c @@ -293,3 +293,56 @@ int scsi_set_sense_information(u8 *buf, int buf_len, u64 info) return 0; } EXPORT_SYMBOL(scsi_set_sense_information); + +/** + * scsi_set_sense_field_pointer - set the field pointer sense key + * specific information in a formatted sense data buffer + * @buf: Where to build sense data + * @buf_len: buffer length + * @fp: field pointer to be set + * @bp: bit pointer to be set + * @cd: command/data bit + * + * Return value: + * 0 on success or EINVAL for invalid sense buffer length + */ +int scsi_set_sense_field_pointer(u8 *buf, int buf_len, u16 fp, u8 bp, bool cd) +{ + u8 *ucp, len; + + if ((buf[0] & 0x7f) == 0x72) { + len = buf[7]; + ucp = (char *)scsi_sense_desc_find(buf, len + 8, 2); + if (!ucp) { + buf[7] = len + 8; + ucp = buf + 8 + len; + } + + if (buf_len < len + 8) + /* Not enough room for info */ + return -EINVAL; + + ucp[0] = 2; + ucp[1] = 6; + ucp[4] = 0x80; /* Valid bit */ + if (cd) + ucp[4] |= 0x40; + if (bp < 0x8) + ucp[4] |= 0x8 | bp; + put_unaligned_be16(fp, &ucp[5]); + } else if ((buf[0] & 0x7f) == 0x70) { + len = buf[7]; + if (len < 18) + buf[7] = 18; + + buf[15] = 0x80; + if (cd) + buf[15] |= 0x40; + if (bp < 0x8) + buf[15] |= 0x8 | bp; + put_unaligned_be16(fp, &buf[16]); + } + + return 0; +} +EXPORT_SYMBOL(scsi_set_sense_field_pointer); diff --git a/include/scsi/scsi_common.h b/include/scsi/scsi_common.h index 11571b2a831e..20bf7eaef05a 100644 --- a/include/scsi/scsi_common.h +++ b/include/scsi/scsi_common.h @@ -63,6 +63,7 @@ extern bool scsi_normalize_sense(const u8 *sense_buffer, int sb_len, extern void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq); int scsi_set_sense_information(u8 *buf, int buf_len, u64 info); +int scsi_set_sense_field_pointer(u8 *buf, int buf_len, u16 fp, u8 bp, bool cd); extern const u8 * scsi_sense_desc_find(const u8 * sense_buffer, int sb_len, int desc_type); -- cgit v1.2.3 From bcfc867d467c98aba23ce0331455282936c04b73 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 4 Apr 2016 11:44:05 +0200 Subject: libata-scsi: Set field pointer in sense code If the sense code is 'Invalid field in CDB' we should be setting the field pointer to the offending byte. Signed-off-by: Hannes Reinecke Signed-off-by: Tejun Heo --- drivers/ata/libata-scsi.c | 155 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 108 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 2389247bdf6f..062cb2eee8de 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -300,6 +300,15 @@ void ata_scsi_set_sense_information(struct ata_device *dev, SCSI_SENSE_BUFFERSIZE, information); } +static void ata_scsi_set_invalid_field(struct ata_device *dev, + struct scsi_cmnd *cmd, u16 field) +{ + ata_scsi_set_sense(dev, cmd, ILLEGAL_REQUEST, 0x24, 0x0); + /* "Invalid field in cbd" */ + scsi_set_sense_field_pointer(cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE, + field, 0xff, 1); +} + static ssize_t ata_scsi_em_message_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -388,10 +397,9 @@ struct device_attribute *ata_common_sdev_attrs[] = { EXPORT_SYMBOL_GPL(ata_common_sdev_attrs); static void ata_scsi_invalid_field(struct ata_device *dev, - struct scsi_cmnd *cmd) + struct scsi_cmnd *cmd, u16 field) { - ata_scsi_set_sense(dev, cmd, ILLEGAL_REQUEST, 0x24, 0x0); - /* "Invalid field in cbd" */ + ata_scsi_set_invalid_field(dev, cmd, field); cmd->scsi_done(cmd); } @@ -1386,19 +1394,26 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) struct scsi_cmnd *scmd = qc->scsicmd; struct ata_taskfile *tf = &qc->tf; const u8 *cdb = scmd->cmnd; + u16 fp; - if (scmd->cmd_len < 5) + if (scmd->cmd_len < 5) { + fp = 4; goto invalid_fld; + } tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; tf->protocol = ATA_PROT_NODATA; if (cdb[1] & 0x1) { ; /* ignore IMMED bit, violates sat-r05 */ } - if (cdb[4] & 0x2) + if (cdb[4] & 0x2) { + fp = 4; goto invalid_fld; /* LOEJ bit set not supported */ - if (((cdb[4] >> 4) & 0xf) != 0) + } + if (((cdb[4] >> 4) & 0xf) != 0) { + fp = 4; goto invalid_fld; /* power conditions not supported */ + } if (cdb[4] & 0x1) { tf->nsect = 1; /* 1 sector, lba=0 */ @@ -1444,8 +1459,7 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) return 0; invalid_fld: - ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x24, 0x0); - /* "Invalid field in cbd" */ + ata_scsi_set_invalid_field(qc->dev, scmd, fp); return 1; skip: scmd->result = SAM_STAT_GOOD; @@ -1596,20 +1610,27 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc) const u8 *cdb = scmd->cmnd; u64 block; u32 n_block; + u16 fp; tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; tf->protocol = ATA_PROT_NODATA; if (cdb[0] == VERIFY) { - if (scmd->cmd_len < 10) + if (scmd->cmd_len < 10) { + fp = 9; goto invalid_fld; + } scsi_10_lba_len(cdb, &block, &n_block); } else if (cdb[0] == VERIFY_16) { - if (scmd->cmd_len < 16) + if (scmd->cmd_len < 16) { + fp = 15; goto invalid_fld; + } scsi_16_lba_len(cdb, &block, &n_block); - } else + } else { + fp = 0; goto invalid_fld; + } if (!n_block) goto nothing_to_do; @@ -1683,8 +1704,7 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc) return 0; invalid_fld: - ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x24, 0x0); - /* "Invalid field in cbd" */ + ata_scsi_set_invalid_field(qc->dev, scmd, fp); return 1; out_of_range: @@ -1723,6 +1743,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc) u64 block; u32 n_block; int rc; + u16 fp = 0; if (cdb[0] == WRITE_10 || cdb[0] == WRITE_6 || cdb[0] == WRITE_16) tf_flags |= ATA_TFLAG_WRITE; @@ -1731,16 +1752,20 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc) switch (cdb[0]) { case READ_10: case WRITE_10: - if (unlikely(scmd->cmd_len < 10)) + if (unlikely(scmd->cmd_len < 10)) { + fp = 9; goto invalid_fld; + } scsi_10_lba_len(cdb, &block, &n_block); if (cdb[1] & (1 << 3)) tf_flags |= ATA_TFLAG_FUA; break; case READ_6: case WRITE_6: - if (unlikely(scmd->cmd_len < 6)) + if (unlikely(scmd->cmd_len < 6)) { + fp = 5; goto invalid_fld; + } scsi_6_lba_len(cdb, &block, &n_block); /* for 6-byte r/w commands, transfer length 0 @@ -1751,14 +1776,17 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc) break; case READ_16: case WRITE_16: - if (unlikely(scmd->cmd_len < 16)) + if (unlikely(scmd->cmd_len < 16)) { + fp = 15; goto invalid_fld; + } scsi_16_lba_len(cdb, &block, &n_block); if (cdb[1] & (1 << 3)) tf_flags |= ATA_TFLAG_FUA; break; default: DPRINTK("no-byte command\n"); + fp = 0; goto invalid_fld; } @@ -1785,8 +1813,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc) goto out_of_range; /* treat all other errors as -EINVAL, fall through */ invalid_fld: - ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x24, 0x0); - /* "Invalid field in cbd" */ + ata_scsi_set_invalid_field(qc->dev, scmd, fp); return 1; out_of_range: @@ -2445,6 +2472,7 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf) u8 pg, spg; unsigned int ebd, page_control, six_byte; u8 dpofua; + u16 fp; VPRINTK("ENTER\n"); @@ -2463,6 +2491,7 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf) case 3: /* saved */ goto saving_not_supp; default: + fp = 2; goto invalid_fld; } @@ -2477,8 +2506,10 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf) * No mode subpages supported (yet) but asking for _all_ * subpages may be valid */ - if (spg && (spg != ALL_SUB_MPAGES)) + if (spg && (spg != ALL_SUB_MPAGES)) { + fp = 3; goto invalid_fld; + } switch(pg) { case RW_RECOVERY_MPAGE: @@ -2500,6 +2531,7 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf) break; default: /* invalid page code */ + fp = 2; goto invalid_fld; } @@ -2529,8 +2561,7 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf) return 0; invalid_fld: - ata_scsi_set_sense(dev, args->cmd, ILLEGAL_REQUEST, 0x24, 0x0); - /* "Invalid field in cbd" */ + ata_scsi_set_invalid_field(dev, args->cmd, fp); return 1; saving_not_supp: @@ -2991,9 +3022,12 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) struct scsi_cmnd *scmd = qc->scsicmd; struct ata_device *dev = qc->dev; const u8 *cdb = scmd->cmnd; + u16 fp; - if ((tf->protocol = ata_scsi_map_proto(cdb[1])) == ATA_PROT_UNKNOWN) + if ((tf->protocol = ata_scsi_map_proto(cdb[1])) == ATA_PROT_UNKNOWN) { + fp = 1; goto invalid_fld; + } /* enable LBA */ tf->flags |= ATA_TFLAG_LBA; @@ -3057,8 +3091,10 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) case ATA_CMD_READ_LONG_ONCE: case ATA_CMD_WRITE_LONG: case ATA_CMD_WRITE_LONG_ONCE: - if (tf->protocol != ATA_PROT_PIO || tf->nsect != 1) + if (tf->protocol != ATA_PROT_PIO || tf->nsect != 1) { + fp = 1; goto invalid_fld; + } qc->sect_size = scsi_bufflen(scmd); break; @@ -3121,12 +3157,16 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) ata_qc_set_pc_nbytes(qc); /* We may not issue DMA commands if no DMA mode is set */ - if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0) + if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0) { + fp = 1; goto invalid_fld; + } /* sanity check for pio multi commands */ - if ((cdb[1] & 0xe0) && !is_multi_taskfile(tf)) + if ((cdb[1] & 0xe0) && !is_multi_taskfile(tf)) { + fp = 1; goto invalid_fld; + } if (is_multi_taskfile(tf)) { unsigned int multi_count = 1 << (cdb[1] >> 5); @@ -3147,8 +3187,10 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) * ->set_dmamode(), and ->post_set_mode() hooks). */ if (tf->command == ATA_CMD_SET_FEATURES && - tf->feature == SETFEATURES_XFER) + tf->feature == SETFEATURES_XFER) { + fp = (cdb[0] == ATA_16) ? 4 : 3; goto invalid_fld; + } /* * Filter TPM commands by default. These provide an @@ -3165,14 +3207,15 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) * so that we comply with the TC consortium stated goal that the user * can turn off TC features of their system. */ - if (tf->command >= 0x5C && tf->command <= 0x5F && !libata_allow_tpm) + if (tf->command >= 0x5C && tf->command <= 0x5F && !libata_allow_tpm) { + fp = (cdb[0] == ATA_16) ? 14 : 9; goto invalid_fld; + } return 0; invalid_fld: - ata_scsi_set_sense(dev, scmd, ILLEGAL_REQUEST, 0x24, 0x00); - /* "Invalid field in cdb" */ + ata_scsi_set_invalid_field(dev, scmd, fp); return 1; } @@ -3186,25 +3229,30 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc) u32 n_block; u32 size; void *buf; + u16 fp; /* we may not issue DMA commands if no DMA mode is set */ if (unlikely(!dev->dma_mode)) - goto invalid_fld; + goto invalid_opcode; - if (unlikely(scmd->cmd_len < 16)) + if (unlikely(scmd->cmd_len < 16)) { + fp = 15; goto invalid_fld; + } scsi_16_lba_len(cdb, &block, &n_block); /* for now we only support WRITE SAME with the unmap bit set */ - if (unlikely(!(cdb[1] & 0x8))) + if (unlikely(!(cdb[1] & 0x8))) { + fp = 1; goto invalid_fld; + } /* * WRITE SAME always has a sector sized buffer as payload, this * should never be a multiple entry S/G list. */ if (!scsi_sg_count(scmd)) - goto invalid_fld; + goto invalid_param_len; buf = page_address(sg_page(scsi_sglist(scmd))); size = ata_set_lba_range_entries(buf, 512, block, n_block); @@ -3235,9 +3283,16 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc) return 0; - invalid_fld: - ata_scsi_set_sense(dev, scmd, ILLEGAL_REQUEST, 0x24, 0x00); - /* "Invalid field in cdb" */ +invalid_fld: + ata_scsi_set_invalid_field(dev, scmd, fp); + return 1; +invalid_param_len: + /* "Parameter list length error" */ + ata_scsi_set_sense(dev, scmd, ILLEGAL_REQUEST, 0x1a, 0x0); + return 1; +invalid_opcode: + /* "Invalid command operation code" */ + ata_scsi_set_sense(dev, scmd, ILLEGAL_REQUEST, 0x20, 0x0); return 1; } @@ -3351,27 +3406,34 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc) u8 pg, spg; unsigned six_byte, pg_len, hdr_len, bd_len; int len; + u16 fp; VPRINTK("ENTER\n"); six_byte = (cdb[0] == MODE_SELECT); if (six_byte) { - if (scmd->cmd_len < 5) + if (scmd->cmd_len < 5) { + fp = 4; goto invalid_fld; + } len = cdb[4]; hdr_len = 4; } else { - if (scmd->cmd_len < 9) + if (scmd->cmd_len < 9) { + fp = 8; goto invalid_fld; + } len = (cdb[7] << 8) + cdb[8]; hdr_len = 8; } /* We only support PF=1, SP=0. */ - if ((cdb[1] & 0x11) != 0x10) + if ((cdb[1] & 0x11) != 0x10) { + fp = 1; goto invalid_fld; + } /* Test early for possible overrun. */ if (!scsi_sg_count(scmd) || scsi_sglist(scmd)->length < len) @@ -3452,8 +3514,7 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc) return 0; invalid_fld: - /* "Invalid field in CDB" */ - ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x24, 0x0); + ata_scsi_set_invalid_field(qc->dev, scmd, fp); return 1; invalid_param: @@ -3667,12 +3728,12 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) switch(scsicmd[0]) { /* TODO: worth improving? */ case FORMAT_UNIT: - ata_scsi_invalid_field(dev, cmd); + ata_scsi_invalid_field(dev, cmd, 0); break; case INQUIRY: - if (scsicmd[1] & 2) /* is CmdDt set? */ - ata_scsi_invalid_field(dev, cmd); + if (scsicmd[1] & 2) /* is CmdDt set? */ + ata_scsi_invalid_field(dev, cmd, 1); else if ((scsicmd[1] & 1) == 0) /* is EVPD clear? */ ata_scsi_rbuf_fill(&args, ata_scsiop_inq_std); else switch (scsicmd[2]) { @@ -3698,7 +3759,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b2); break; default: - ata_scsi_invalid_field(dev, cmd); + ata_scsi_invalid_field(dev, cmd, 2); break; } break; @@ -3716,7 +3777,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) if ((scsicmd[1] & 0x1f) == SAI_READ_CAPACITY_16) ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap); else - ata_scsi_invalid_field(dev, cmd); + ata_scsi_invalid_field(dev, cmd, 1); break; case REPORT_LUNS: @@ -3748,7 +3809,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) if ((tmp8 == 0x4) && (!scsicmd[3]) && (!scsicmd[4])) ata_scsi_rbuf_fill(&args, ata_scsiop_noop); else - ata_scsi_invalid_field(dev, cmd); + ata_scsi_invalid_field(dev, cmd, 1); break; /* all other commands */ -- cgit v1.2.3 From 0df10b84af88a482beea982f5f27a2e42157f600 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 4 Apr 2016 11:44:06 +0200 Subject: libata-scsi: set bit pointer for sense code information When generating a sense code of 'Invalid field in CDB' we should be setting the bit pointer where appropriate. Signed-off-by: Hannes Reinecke Signed-off-by: Tejun Heo --- drivers/ata/libata-scsi.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 062cb2eee8de..339a373250f3 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -301,12 +301,12 @@ void ata_scsi_set_sense_information(struct ata_device *dev, } static void ata_scsi_set_invalid_field(struct ata_device *dev, - struct scsi_cmnd *cmd, u16 field) + struct scsi_cmnd *cmd, u16 field, u8 bit) { ata_scsi_set_sense(dev, cmd, ILLEGAL_REQUEST, 0x24, 0x0); /* "Invalid field in cbd" */ scsi_set_sense_field_pointer(cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE, - field, 0xff, 1); + field, bit, 1); } static ssize_t @@ -399,7 +399,7 @@ EXPORT_SYMBOL_GPL(ata_common_sdev_attrs); static void ata_scsi_invalid_field(struct ata_device *dev, struct scsi_cmnd *cmd, u16 field) { - ata_scsi_set_invalid_field(dev, cmd, field); + ata_scsi_set_invalid_field(dev, cmd, field, 0xff); cmd->scsi_done(cmd); } @@ -1395,6 +1395,7 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) struct ata_taskfile *tf = &qc->tf; const u8 *cdb = scmd->cmnd; u16 fp; + u8 bp = 0xff; if (scmd->cmd_len < 5) { fp = 4; @@ -1408,10 +1409,12 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) } if (cdb[4] & 0x2) { fp = 4; + bp = 1; goto invalid_fld; /* LOEJ bit set not supported */ } if (((cdb[4] >> 4) & 0xf) != 0) { fp = 4; + bp = 3; goto invalid_fld; /* power conditions not supported */ } @@ -1459,7 +1462,7 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) return 0; invalid_fld: - ata_scsi_set_invalid_field(qc->dev, scmd, fp); + ata_scsi_set_invalid_field(qc->dev, scmd, fp, bp); return 1; skip: scmd->result = SAM_STAT_GOOD; @@ -1704,7 +1707,7 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc) return 0; invalid_fld: - ata_scsi_set_invalid_field(qc->dev, scmd, fp); + ata_scsi_set_invalid_field(qc->dev, scmd, fp, 0xff); return 1; out_of_range: @@ -1813,7 +1816,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc) goto out_of_range; /* treat all other errors as -EINVAL, fall through */ invalid_fld: - ata_scsi_set_invalid_field(qc->dev, scmd, fp); + ata_scsi_set_invalid_field(qc->dev, scmd, fp, 0xff); return 1; out_of_range: @@ -2471,7 +2474,7 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf) }; u8 pg, spg; unsigned int ebd, page_control, six_byte; - u8 dpofua; + u8 dpofua, bp = 0xff; u16 fp; VPRINTK("ENTER\n"); @@ -2492,6 +2495,7 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf) goto saving_not_supp; default: fp = 2; + bp = 6; goto invalid_fld; } @@ -2561,7 +2565,7 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf) return 0; invalid_fld: - ata_scsi_set_invalid_field(dev, args->cmd, fp); + ata_scsi_set_invalid_field(dev, args->cmd, fp, bp); return 1; saving_not_supp: @@ -3215,7 +3219,7 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) return 0; invalid_fld: - ata_scsi_set_invalid_field(dev, scmd, fp); + ata_scsi_set_invalid_field(dev, scmd, fp, 0xff); return 1; } @@ -3230,6 +3234,7 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc) u32 size; void *buf; u16 fp; + u8 bp = 0xff; /* we may not issue DMA commands if no DMA mode is set */ if (unlikely(!dev->dma_mode)) @@ -3244,6 +3249,7 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc) /* for now we only support WRITE SAME with the unmap bit set */ if (unlikely(!(cdb[1] & 0x8))) { fp = 1; + bp = 3; goto invalid_fld; } @@ -3284,7 +3290,7 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc) return 0; invalid_fld: - ata_scsi_set_invalid_field(dev, scmd, fp); + ata_scsi_set_invalid_field(dev, scmd, fp, bp); return 1; invalid_param_len: /* "Parameter list length error" */ @@ -3407,6 +3413,7 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc) unsigned six_byte, pg_len, hdr_len, bd_len; int len; u16 fp; + u8 bp; VPRINTK("ENTER\n"); @@ -3432,6 +3439,7 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc) /* We only support PF=1, SP=0. */ if ((cdb[1] & 0x11) != 0x10) { fp = 1; + bp = (cdb[1] & 0x01) ? 1 : 5; goto invalid_fld; } @@ -3514,7 +3522,7 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc) return 0; invalid_fld: - ata_scsi_set_invalid_field(qc->dev, scmd, fp); + ata_scsi_set_invalid_field(qc->dev, scmd, fp, bp); return 1; invalid_param: -- cgit v1.2.3 From 7780081c1f04a4ea31331b5579ca010cc1f26c74 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 4 Apr 2016 11:44:07 +0200 Subject: libata-scsi: Set information sense field for invalid parameter Whenever the sense key is set to 'invalid parameter' we should be filling out the sense-key specific information field in the sense buffer. tj: Added description of @fp for ata_mselect_*(). Signed-off-by: Hannes Reinecke Signed-off-by: Tejun Heo --- drivers/ata/libata-scsi.c | 81 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 61 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 339a373250f3..8b61d63ab0be 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -309,6 +309,15 @@ static void ata_scsi_set_invalid_field(struct ata_device *dev, field, bit, 1); } +static void ata_scsi_set_invalid_parameter(struct ata_device *dev, + struct scsi_cmnd *cmd, u16 field) +{ + /* "Invalid field in parameter list" */ + ata_scsi_set_sense(dev, cmd, ILLEGAL_REQUEST, 0x26, 0x0); + scsi_set_sense_field_pointer(cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE, + field, 0xff, 0); +} + static ssize_t ata_scsi_em_message_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -3307,6 +3316,7 @@ invalid_opcode: * @qc: Storage for translated ATA taskfile * @buf: input buffer * @len: number of valid bytes in the input buffer + * @fp: out parameter for the failed field on error * * Prepare a taskfile to modify caching information for the device. * @@ -3314,20 +3324,26 @@ invalid_opcode: * None. */ static int ata_mselect_caching(struct ata_queued_cmd *qc, - const u8 *buf, int len) + const u8 *buf, int len, u16 *fp) { struct ata_taskfile *tf = &qc->tf; struct ata_device *dev = qc->dev; char mpage[CACHE_MPAGE_LEN]; u8 wce; + int i; /* * The first two bytes of def_cache_mpage are a header, so offsets * in mpage are off by 2 compared to buf. Same for len. */ - if (len != CACHE_MPAGE_LEN - 2) + if (len != CACHE_MPAGE_LEN - 2) { + if (len < CACHE_MPAGE_LEN - 2) + *fp = len; + else + *fp = CACHE_MPAGE_LEN - 2; return -EINVAL; + } wce = buf[0] & (1 << 2); @@ -3335,10 +3351,14 @@ static int ata_mselect_caching(struct ata_queued_cmd *qc, * Check that read-only bits are not modified. */ ata_msense_caching(dev->id, mpage, false); - mpage[2] &= ~(1 << 2); - mpage[2] |= wce; - if (memcmp(mpage + 2, buf, CACHE_MPAGE_LEN - 2) != 0) - return -EINVAL; + for (i = 0; i < CACHE_MPAGE_LEN - 2; i++) { + if (i == 0) + continue; + if (mpage[i + 2] != buf[i]) { + *fp = i; + return -EINVAL; + } + } tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; tf->protocol = ATA_PROT_NODATA; @@ -3353,6 +3373,7 @@ static int ata_mselect_caching(struct ata_queued_cmd *qc, * @qc: Storage for translated ATA taskfile * @buf: input buffer * @len: number of valid bytes in the input buffer + * @fp: out parameter for the failed field on error * * Prepare a taskfile to modify caching information for the device. * @@ -3360,19 +3381,25 @@ static int ata_mselect_caching(struct ata_queued_cmd *qc, * None. */ static int ata_mselect_control(struct ata_queued_cmd *qc, - const u8 *buf, int len) + const u8 *buf, int len, u16 *fp) { struct ata_device *dev = qc->dev; char mpage[CONTROL_MPAGE_LEN]; u8 d_sense; + int i; /* * The first two bytes of def_control_mpage are a header, so offsets * in mpage are off by 2 compared to buf. Same for len. */ - if (len != CONTROL_MPAGE_LEN - 2) + if (len != CONTROL_MPAGE_LEN - 2) { + if (len < CONTROL_MPAGE_LEN - 2) + *fp = len; + else + *fp = CONTROL_MPAGE_LEN - 2; return -EINVAL; + } d_sense = buf[0] & (1 << 2); @@ -3380,10 +3407,14 @@ static int ata_mselect_control(struct ata_queued_cmd *qc, * Check that read-only bits are not modified. */ ata_msense_ctl_mode(dev, mpage, false); - mpage[2] &= ~(1 << 2); - mpage[2] |= d_sense; - if (memcmp(mpage + 2, buf, CONTROL_MPAGE_LEN - 2) != 0) - return -EINVAL; + for (i = 0; i < CONTROL_MPAGE_LEN - 2; i++) { + if (i == 0) + continue; + if (mpage[2 + i] != buf[i]) { + *fp = i; + return -EINVAL; + } + } if (d_sense & (1 << 2)) dev->flags |= ATA_DFLAG_D_SENSE; else @@ -3412,8 +3443,8 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc) u8 pg, spg; unsigned six_byte, pg_len, hdr_len, bd_len; int len; - u16 fp; - u8 bp; + u16 fp = (u16)-1; + u8 bp = 0xff; VPRINTK("ENTER\n"); @@ -3462,8 +3493,11 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc) p += hdr_len; if (len < bd_len) goto invalid_param_len; - if (bd_len != 0 && bd_len != 8) + if (bd_len != 0 && bd_len != 8) { + fp = (six_byte) ? 3 : 6; + fp += bd_len + hdr_len; goto invalid_param; + } len -= bd_len; p += bd_len; @@ -3494,21 +3528,29 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc) * No mode subpages supported (yet) but asking for _all_ * subpages may be valid */ - if (spg && (spg != ALL_SUB_MPAGES)) + if (spg && (spg != ALL_SUB_MPAGES)) { + fp = (p[0] & 0x40) ? 1 : 0; + fp += hdr_len + bd_len; goto invalid_param; + } if (pg_len > len) goto invalid_param_len; switch (pg) { case CACHE_MPAGE: - if (ata_mselect_caching(qc, p, pg_len) < 0) + if (ata_mselect_caching(qc, p, pg_len, &fp) < 0) { + fp += hdr_len + bd_len; goto invalid_param; + } break; case CONTROL_MPAGE: - if (ata_mselect_control(qc, p, pg_len) < 0) + if (ata_mselect_control(qc, p, pg_len, &fp) < 0) { + fp += hdr_len + bd_len; goto invalid_param; + } break; default: /* invalid page code */ + fp = bd_len + hdr_len; goto invalid_param; } @@ -3526,8 +3568,7 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc) return 1; invalid_param: - /* "Invalid field in parameter list" */ - ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x26, 0x0); + ata_scsi_set_invalid_parameter(qc->dev, scmd, fp); return 1; invalid_param_len: -- cgit v1.2.3 From 2d4d689f3ec56ad1eca6c899f418aeb6c0cf43ca Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 18 Mar 2016 14:26:34 +0200 Subject: dmaengine: hsu: allow more than 3 descriptors Current code allows only up to 3 descriptors to be programmed to the hardware since it is used wrong calculations. Change % to min_t() to allow as many descriptors as user supplied. At once it could be programmed up to 4 descriptors due to hardware limitations. The issue was found under stress test, so it might not bother ordinary users. Signed-off-by: Andy Shevchenko Signed-off-by: Vinod Koul --- drivers/dma/hsu/hsu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/hsu/hsu.c b/drivers/dma/hsu/hsu.c index eef145edb936..6fce5ed2fc40 100644 --- a/drivers/dma/hsu/hsu.c +++ b/drivers/dma/hsu/hsu.c @@ -77,8 +77,8 @@ static void hsu_dma_chan_start(struct hsu_dma_chan *hsuc) hsu_chan_writel(hsuc, HSU_CH_MTSR, mtsr); /* Set descriptors */ - count = (desc->nents - desc->active) % HSU_DMA_CHAN_NR_DESC; - for (i = 0; i < count; i++) { + count = desc->nents - desc->active; + for (i = 0; i < count && i < HSU_DMA_CHAN_NR_DESC; i++) { hsu_chan_writel(hsuc, HSU_CH_DxSAR(i), desc->sg[i].addr); hsu_chan_writel(hsuc, HSU_CH_DxTSR(i), desc->sg[i].len); -- cgit v1.2.3 From c36a0176ba678fd1a4bf985fd62f43dd4f4d4a03 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 18 Mar 2016 14:26:35 +0200 Subject: dmaengine: hsu: don't check direction of timeouted channel The timeout capability is only available on the so called DMA write channels, i.e. associated with UART Rx FIFO. It means we don't need to check the direction of the channel to handle timeouts. Signed-off-by: Andy Shevchenko Signed-off-by: Vinod Koul --- drivers/dma/hsu/hsu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/dma/hsu/hsu.c b/drivers/dma/hsu/hsu.c index 6fce5ed2fc40..1817b7bc9576 100644 --- a/drivers/dma/hsu/hsu.c +++ b/drivers/dma/hsu/hsu.c @@ -160,7 +160,7 @@ irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, unsigned short nr) return IRQ_NONE; /* Timeout IRQ, need wait some time, see Errata 2 */ - if (hsuc->direction == DMA_DEV_TO_MEM && (sr & HSU_CH_SR_DESCTO_ANY)) + if (sr & HSU_CH_SR_DESCTO_ANY) udelay(2); sr &= ~HSU_CH_SR_DESCTO_ANY; -- cgit v1.2.3 From 17b3cf4233d77698df0e5ff39303c145ac355d6a Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 18 Mar 2016 14:26:36 +0200 Subject: dmaengine: hsu: set maximum allowed segment size for DMA This tells, for example, IOMMU what the maximum size of a segment the DMA controller can send. Signed-off-by: Andy Shevchenko Signed-off-by: Vinod Koul --- drivers/dma/hsu/hsu.c | 2 ++ drivers/dma/hsu/hsu.h | 4 ++++ 2 files changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/dma/hsu/hsu.c b/drivers/dma/hsu/hsu.c index 1817b7bc9576..59d1e7c6fd0f 100644 --- a/drivers/dma/hsu/hsu.c +++ b/drivers/dma/hsu/hsu.c @@ -417,6 +417,8 @@ int hsu_dma_probe(struct hsu_dma_chip *chip) hsu->dma.dev = chip->dev; + dma_set_max_seg_size(hsu->dma.dev, HSU_CH_DxTSR_MASK); + ret = dma_async_device_register(&hsu->dma); if (ret) return ret; diff --git a/drivers/dma/hsu/hsu.h b/drivers/dma/hsu/hsu.h index 578a8ee8cd05..50a9d1bda253 100644 --- a/drivers/dma/hsu/hsu.h +++ b/drivers/dma/hsu/hsu.h @@ -55,6 +55,10 @@ #define HSU_CH_DCR_CHEI BIT(23) #define HSU_CH_DCR_CHTOI(x) BIT(24 + (x)) +/* Bits in HSU_CH_DxTSR */ +#define HSU_CH_DxTSR_MASK GENMASK(15, 0) +#define HSU_CH_DxTSR_TSR(x) ((x) & HSU_CH_DxTSR_MASK) + struct hsu_dma_sg { dma_addr_t addr; unsigned int len; -- cgit v1.2.3 From 237ec70903bcf50768138b6c663c67ef1f946cc8 Mon Sep 17 00:00:00 2001 From: Mario Six Date: Fri, 18 Mar 2016 14:57:19 +0100 Subject: dmaengine: mpc512x: Fix hanging DMA device transfer for MPC8308 Since the MPC8308 has no external request lines to initiate DMA transfers, all transfers must be triggered by software. Because of this, the current implementation of DMA transfers from and to devices on MPC8308 SoCs using major and minor loops is faulty: After the completion of the first major loop, the DMA engine resets the start flag in the channel's TCD, thus halting the transfer. The driver would have to set the start bit again to trigger the next iteration of the major loop; on MPC512x SoCs, this is done via the external request lines, so in this case, the driver doesn't have to interfer in any way. This has the effect that on MPC8308s, every DMA transfer to or from a device hangs after executing the first major loop. The patch fixes this behavior by using just one major loop for the whole DMA transfer on MPC8308s. Signed-off-by: Mario Six Signed-off-by: Vinod Koul --- drivers/dma/mpc512x_dma.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c index aae76fb39adc..3a9104a1041c 100644 --- a/drivers/dma/mpc512x_dma.c +++ b/drivers/dma/mpc512x_dma.c @@ -760,21 +760,31 @@ mpc_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, tcd->ssize = MPC_DMA_TSIZE_4; tcd->dsize = MPC_DMA_TSIZE_4; - len = sg_dma_len(sg); - tcd->nbytes = tcd_nunits * 4; - if (!IS_ALIGNED(len, tcd->nbytes)) - goto err_prep; - - iter = len / tcd->nbytes; - if (iter >= 1 << 15) { - /* len is too big */ - goto err_prep; + if (mdma->is_mpc8308) { + tcd->nbytes = sg_dma_len(sg); + if (!IS_ALIGNED(tcd->nbytes, 4)) + goto err_prep; + + /* No major loops for MPC8303 */ + tcd->biter = 1; + tcd->citer = 1; + } else { + len = sg_dma_len(sg); + tcd->nbytes = tcd_nunits * 4; + if (!IS_ALIGNED(len, tcd->nbytes)) + goto err_prep; + + iter = len / tcd->nbytes; + if (iter >= 1 << 15) { + /* len is too big */ + goto err_prep; + } + /* citer_linkch contains the high bits of iter */ + tcd->biter = iter & 0x1ff; + tcd->biter_linkch = iter >> 9; + tcd->citer = tcd->biter; + tcd->citer_linkch = tcd->biter_linkch; } - /* citer_linkch contains the high bits of iter */ - tcd->biter = iter & 0x1ff; - tcd->biter_linkch = iter >> 9; - tcd->citer = tcd->biter; - tcd->citer_linkch = tcd->biter_linkch; tcd->e_sg = 0; tcd->d_req = 1; -- cgit v1.2.3 From 899ed9dd4f2d007dfad66cd074b8ff26a0894ae8 Mon Sep 17 00:00:00 2001 From: Mario Six Date: Fri, 18 Mar 2016 14:57:20 +0100 Subject: dmaengine: mpc512x: Implement additional chunk sizes for DMA transfers This patch extends the capabilities of the driver to handle DMA transfers to and from devices of 1, 2, 4, 16 (for MPC512x), and 32 byte widths. Signed-off-by: Mario Six Signed-off-by: Vinod Koul --- drivers/dma/mpc512x_dma.c | 112 +++++++++++++++++++++++++++++++--------------- 1 file changed, 76 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c index 3a9104a1041c..1a161a8d68f3 100644 --- a/drivers/dma/mpc512x_dma.c +++ b/drivers/dma/mpc512x_dma.c @@ -3,6 +3,7 @@ * Copyright (C) Semihalf 2009 * Copyright (C) Ilya Yanok, Emcraft Systems 2010 * Copyright (C) Alexander Popov, Promcontroller 2014 + * Copyright (C) Mario Six, Guntermann & Drunck GmbH, 2016 * * Written by Piotr Ziecik . Hardware description * (defines, structures and comments) was taken from MPC5121 DMA driver @@ -26,18 +27,19 @@ */ /* - * MPC512x and MPC8308 DMA driver. It supports - * memory to memory data transfers (tested using dmatest module) and - * data transfers between memory and peripheral I/O memory - * by means of slave scatter/gather with these limitations: - * - chunked transfers (described by s/g lists with more than one item) - * are refused as long as proper support for scatter/gather is missing; - * - transfers on MPC8308 always start from software as this SoC appears - * not to have external request lines for peripheral flow control; - * - only peripheral devices with 4-byte FIFO access register are supported; - * - minimal memory <-> I/O memory transfer chunk is 4 bytes and consequently - * source and destination addresses must be 4-byte aligned - * and transfer size must be aligned on (4 * maxburst) boundary; + * MPC512x and MPC8308 DMA driver. It supports memory to memory data transfers + * (tested using dmatest module) and data transfers between memory and + * peripheral I/O memory by means of slave scatter/gather with these + * limitations: + * - chunked transfers (described by s/g lists with more than one item) are + * refused as long as proper support for scatter/gather is missing + * - transfers on MPC8308 always start from software as this SoC does not have + * external request lines for peripheral flow control + * - memory <-> I/O memory transfer chunks of sizes of 1, 2, 4, 16 (for + * MPC512x), and 32 bytes are supported, and, consequently, source + * addresses and destination addresses must be aligned accordingly; + * furthermore, for MPC512x SoCs, the transfer size must be aligned on + * (chunk size * maxburst) */ #include @@ -213,8 +215,10 @@ struct mpc_dma_chan { /* Settings for access to peripheral FIFO */ dma_addr_t src_per_paddr; u32 src_tcd_nunits; + u8 swidth; dma_addr_t dst_per_paddr; u32 dst_tcd_nunits; + u8 dwidth; /* Lock for this structure */ spinlock_t lock; @@ -684,6 +688,15 @@ mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, dma_addr_t src, return &mdesc->desc; } +inline u8 buswidth_to_dmatsize(u8 buswidth) +{ + u8 res; + + for (res = 0; buswidth > 1; buswidth /= 2) + res++; + return res; +} + static struct dma_async_tx_descriptor * mpc_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, unsigned int sg_len, enum dma_transfer_direction direction, @@ -742,27 +755,32 @@ mpc_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, memset(tcd, 0, sizeof(struct mpc_dma_tcd)); - if (!IS_ALIGNED(sg_dma_address(sg), 4)) - goto err_prep; - if (direction == DMA_DEV_TO_MEM) { tcd->saddr = per_paddr; tcd->daddr = sg_dma_address(sg); + + if (!IS_ALIGNED(sg_dma_address(sg), mchan->dwidth)) + goto err_prep; + tcd->soff = 0; - tcd->doff = 4; + tcd->doff = mchan->dwidth; } else { tcd->saddr = sg_dma_address(sg); tcd->daddr = per_paddr; - tcd->soff = 4; + + if (!IS_ALIGNED(sg_dma_address(sg), mchan->swidth)) + goto err_prep; + + tcd->soff = mchan->swidth; tcd->doff = 0; } - tcd->ssize = MPC_DMA_TSIZE_4; - tcd->dsize = MPC_DMA_TSIZE_4; + tcd->ssize = buswidth_to_dmatsize(mchan->swidth); + tcd->dsize = buswidth_to_dmatsize(mchan->dwidth); if (mdma->is_mpc8308) { tcd->nbytes = sg_dma_len(sg); - if (!IS_ALIGNED(tcd->nbytes, 4)) + if (!IS_ALIGNED(tcd->nbytes, mchan->swidth)) goto err_prep; /* No major loops for MPC8303 */ @@ -770,7 +788,7 @@ mpc_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, tcd->citer = 1; } else { len = sg_dma_len(sg); - tcd->nbytes = tcd_nunits * 4; + tcd->nbytes = tcd_nunits * tcd->ssize; if (!IS_ALIGNED(len, tcd->nbytes)) goto err_prep; @@ -806,40 +824,62 @@ err_prep: return NULL; } +inline bool is_buswidth_valid(u8 buswidth, bool is_mpc8308) +{ + switch (buswidth) { + case 16: + if (is_mpc8308) + return false; + case 1: + case 2: + case 4: + case 32: + break; + default: + return false; + } + + return true; +} + static int mpc_dma_device_config(struct dma_chan *chan, struct dma_slave_config *cfg) { struct mpc_dma_chan *mchan = dma_chan_to_mpc_dma_chan(chan); + struct mpc_dma *mdma = dma_chan_to_mpc_dma(&mchan->chan); unsigned long flags; /* * Software constraints: - * - only transfers between a peripheral device and - * memory are supported; - * - only peripheral devices with 4-byte FIFO access register - * are supported; - * - minimal transfer chunk is 4 bytes and consequently - * source and destination addresses must be 4-byte aligned - * and transfer size must be aligned on (4 * maxburst) - * boundary; - * - during the transfer RAM address is being incremented by - * the size of minimal transfer chunk; - * - peripheral port's address is constant during the transfer. + * - only transfers between a peripheral device and memory are + * supported + * - transfer chunk sizes of 1, 2, 4, 16 (for MPC512x), and 32 bytes + * are supported, and, consequently, source addresses and + * destination addresses; must be aligned accordingly; furthermore, + * for MPC512x SoCs, the transfer size must be aligned on (chunk + * size * maxburst) + * - during the transfer, the RAM address is incremented by the size + * of transfer chunk + * - the peripheral port's address is constant during the transfer. */ - if (cfg->src_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES || - cfg->dst_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES || - !IS_ALIGNED(cfg->src_addr, 4) || - !IS_ALIGNED(cfg->dst_addr, 4)) { + if (!IS_ALIGNED(cfg->src_addr, cfg->src_addr_width) || + !IS_ALIGNED(cfg->dst_addr, cfg->dst_addr_width)) { return -EINVAL; } + if (!is_buswidth_valid(cfg->src_addr_width, mdma->is_mpc8308) || + !is_buswidth_valid(cfg->dst_addr_width, mdma->is_mpc8308)) + return -EINVAL; + spin_lock_irqsave(&mchan->lock, flags); mchan->src_per_paddr = cfg->src_addr; mchan->src_tcd_nunits = cfg->src_maxburst; + mchan->swidth = cfg->src_addr_width; mchan->dst_per_paddr = cfg->dst_addr; mchan->dst_tcd_nunits = cfg->dst_maxburst; + mchan->dwidth = cfg->dst_addr_width; /* Apply defaults */ if (mchan->src_tcd_nunits == 0) -- cgit v1.2.3 From 77fc397661e714c2bc4f96ae38f6776c15cc85ab Mon Sep 17 00:00:00 2001 From: Mario Six Date: Fri, 18 Mar 2016 14:57:21 +0100 Subject: dmaengine: mpc512x: Fix code style Signed-off-by: Mario Six Signed-off-by: Vinod Koul --- drivers/dma/mpc512x_dma.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c index 1a161a8d68f3..ccadafa51d5e 100644 --- a/drivers/dma/mpc512x_dma.c +++ b/drivers/dma/mpc512x_dma.c @@ -251,6 +251,7 @@ static inline struct mpc_dma_chan *dma_chan_to_mpc_dma_chan(struct dma_chan *c) static inline struct mpc_dma *dma_chan_to_mpc_dma(struct dma_chan *c) { struct mpc_dma_chan *mchan = dma_chan_to_mpc_dma_chan(c); + return container_of(mchan, struct mpc_dma, channels[c->chan_id]); } @@ -258,9 +259,9 @@ static inline struct mpc_dma *dma_chan_to_mpc_dma(struct dma_chan *c) * Execute all queued DMA descriptors. * * Following requirements must be met while calling mpc_dma_execute(): - * a) mchan->lock is acquired, - * b) mchan->active list is empty, - * c) mchan->queued list contains at least one entry. + * a) mchan->lock is acquired, + * b) mchan->active list is empty, + * c) mchan->queued list contains at least one entry. */ static void mpc_dma_execute(struct mpc_dma_chan *mchan) { @@ -450,20 +451,15 @@ static void mpc_dma_tasklet(unsigned long data) if (es & MPC_DMA_DMAES_SAE) dev_err(mdma->dma.dev, "- Source Address Error\n"); if (es & MPC_DMA_DMAES_SOE) - dev_err(mdma->dma.dev, "- Source Offset" - " Configuration Error\n"); + dev_err(mdma->dma.dev, "- Source Offset Configuration Error\n"); if (es & MPC_DMA_DMAES_DAE) - dev_err(mdma->dma.dev, "- Destination Address" - " Error\n"); + dev_err(mdma->dma.dev, "- Destination Address Error\n"); if (es & MPC_DMA_DMAES_DOE) - dev_err(mdma->dma.dev, "- Destination Offset" - " Configuration Error\n"); + dev_err(mdma->dma.dev, "- Destination Offset Configuration Error\n"); if (es & MPC_DMA_DMAES_NCE) - dev_err(mdma->dma.dev, "- NBytes/Citter" - " Configuration Error\n"); + dev_err(mdma->dma.dev, "- NBytes/Citter Configuration Error\n"); if (es & MPC_DMA_DMAES_SGE) - dev_err(mdma->dma.dev, "- Scatter/Gather" - " Configuration Error\n"); + dev_err(mdma->dma.dev, "- Scatter/Gather Configuration Error\n"); if (es & MPC_DMA_DMAES_SBE) dev_err(mdma->dma.dev, "- Source Bus Error\n"); if (es & MPC_DMA_DMAES_DBE) @@ -522,8 +518,8 @@ static int mpc_dma_alloc_chan_resources(struct dma_chan *chan) for (i = 0; i < MPC_DMA_DESCRIPTORS; i++) { mdesc = kzalloc(sizeof(struct mpc_dma_desc), GFP_KERNEL); if (!mdesc) { - dev_notice(mdma->dma.dev, "Memory allocation error. " - "Allocated only %u descriptors\n", i); + dev_notice(mdma->dma.dev, + "Memory allocation error. Allocated only %u descriptors\n", i); break; } @@ -925,7 +921,6 @@ static int mpc_dma_probe(struct platform_device *op) mdma = devm_kzalloc(dev, sizeof(struct mpc_dma), GFP_KERNEL); if (!mdma) { - dev_err(dev, "Memory exhausted!\n"); retval = -ENOMEM; goto err; } @@ -1049,7 +1044,8 @@ static int mpc_dma_probe(struct platform_device *op) out_be32(&mdma->regs->dmaerrl, 0xFFFF); } else { out_be32(&mdma->regs->dmacr, MPC_DMA_DMACR_EDCG | - MPC_DMA_DMACR_ERGA | MPC_DMA_DMACR_ERCA); + MPC_DMA_DMACR_ERGA | + MPC_DMA_DMACR_ERCA); /* Disable hardware DMA requests */ out_be32(&mdma->regs->dmaerqh, 0); -- cgit v1.2.3 From 1bcb9f8ceb67803960871ecf4ed2d365a2a919c8 Mon Sep 17 00:00:00 2001 From: Purna Chandra Mandal Date: Fri, 1 Apr 2016 16:48:50 +0530 Subject: spi: spi-pic32: Add PIC32 SPI master driver The PIC32 SPI driver is capable of performing SPI transfers using PIO or external DMA engine. GPIO controlled /CS support is made default in the driver for correct operation of the controller. This can be enabled by adding "cs-gpios" property of the SPI node in board dts file. Signed-off-by: Purna Chandra Mandal Signed-off-by: Mark Brown --- drivers/spi/Kconfig | 6 + drivers/spi/Makefile | 1 + drivers/spi/spi-pic32.c | 888 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 895 insertions(+) create mode 100644 drivers/spi/spi-pic32.c (limited to 'drivers') diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 9d8c84bb1544..8a8ff5051c64 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -436,6 +436,12 @@ config SPI_ORION help This enables using the SPI master controller on the Orion chips. +config SPI_PIC32 + tristate "Microchip PIC32 series SPI" + depends on MACH_PIC32 || COMPILE_TEST + help + SPI driver for Microchip PIC32 SPI master controller. + config SPI_PL022 tristate "ARM AMBA PL022 SSP controller" depends on ARM_AMBA diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index fbb255c5a608..06019ed11fac 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -62,6 +62,7 @@ obj-$(CONFIG_SPI_OMAP_100K) += spi-omap-100k.o obj-$(CONFIG_SPI_OMAP24XX) += spi-omap2-mcspi.o obj-$(CONFIG_SPI_TI_QSPI) += spi-ti-qspi.o obj-$(CONFIG_SPI_ORION) += spi-orion.o +obj-$(CONFIG_SPI_PIC32) += spi-pic32.o obj-$(CONFIG_SPI_PL022) += spi-pl022.o obj-$(CONFIG_SPI_PPC4xx) += spi-ppc4xx.o spi-pxa2xx-platform-objs := spi-pxa2xx.o spi-pxa2xx-dma.o diff --git a/drivers/spi/spi-pic32.c b/drivers/spi/spi-pic32.c new file mode 100644 index 000000000000..f8313ea11a34 --- /dev/null +++ b/drivers/spi/spi-pic32.c @@ -0,0 +1,888 @@ +/* + * Microchip PIC32 SPI controller driver. + * + * Purna Chandra Mandal + * Copyright (c) 2016, Microchip Technology Inc. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* SPI controller registers */ +struct pic32_spi_regs { + u32 ctrl; + u32 ctrl_clr; + u32 ctrl_set; + u32 ctrl_inv; + u32 status; + u32 status_clr; + u32 status_set; + u32 status_inv; + u32 buf; + u32 dontuse[3]; + u32 baud; + u32 dontuse2[3]; + u32 ctrl2; + u32 ctrl2_clr; + u32 ctrl2_set; + u32 ctrl2_inv; +}; + +/* Bit fields of SPI Control Register */ +#define CTRL_RX_INT_SHIFT 0 /* Rx interrupt generation */ +#define RX_FIFO_EMTPY 0 +#define RX_FIFO_NOT_EMPTY 1 /* not empty */ +#define RX_FIFO_HALF_FULL 2 /* full by half or more */ +#define RX_FIFO_FULL 3 /* completely full */ + +#define CTRL_TX_INT_SHIFT 2 /* TX interrupt generation */ +#define TX_FIFO_ALL_EMPTY 0 /* completely empty */ +#define TX_FIFO_EMTPY 1 /* empty */ +#define TX_FIFO_HALF_EMPTY 2 /* empty by half or more */ +#define TX_FIFO_NOT_FULL 3 /* atleast one empty */ + +#define CTRL_MSTEN BIT(5) /* enable master mode */ +#define CTRL_CKP BIT(6) /* active low */ +#define CTRL_CKE BIT(8) /* Tx on falling edge */ +#define CTRL_SMP BIT(9) /* Rx at middle or end of tx */ +#define CTRL_BPW_MASK 0x03 /* bits per word/sample */ +#define CTRL_BPW_SHIFT 10 +#define PIC32_BPW_8 0 +#define PIC32_BPW_16 1 +#define PIC32_BPW_32 2 +#define CTRL_SIDL BIT(13) /* sleep when idle */ +#define CTRL_ON BIT(15) /* enable macro */ +#define CTRL_ENHBUF BIT(16) /* enable enhanced buffering */ +#define CTRL_MCLKSEL BIT(23) /* select clock source */ +#define CTRL_MSSEN BIT(28) /* macro driven /SS */ +#define CTRL_FRMEN BIT(31) /* enable framing mode */ + +/* Bit fields of SPI Status Register */ +#define STAT_RF_EMPTY BIT(5) /* RX Fifo empty */ +#define STAT_RX_OV BIT(6) /* err, s/w needs to clear */ +#define STAT_TX_UR BIT(8) /* UR in Framed SPI modes */ +#define STAT_FRM_ERR BIT(12) /* Multiple Frame Sync pulse */ +#define STAT_TF_LVL_MASK 0x1F +#define STAT_TF_LVL_SHIFT 16 +#define STAT_RF_LVL_MASK 0x1F +#define STAT_RF_LVL_SHIFT 24 + +/* Bit fields of SPI Baud Register */ +#define BAUD_MASK 0x1ff + +/* Bit fields of SPI Control2 Register */ +#define CTRL2_TX_UR_EN BIT(10) /* Enable int on Tx under-run */ +#define CTRL2_RX_OV_EN BIT(11) /* Enable int on Rx over-run */ +#define CTRL2_FRM_ERR_EN BIT(12) /* Enable frame err int */ + +/* Minimum DMA transfer size */ +#define PIC32_DMA_LEN_MIN 64 + +struct pic32_spi { + dma_addr_t dma_base; + struct pic32_spi_regs __iomem *regs; + int fault_irq; + int rx_irq; + int tx_irq; + u32 fifo_n_byte; /* FIFO depth in bytes */ + struct clk *clk; + struct spi_master *master; + /* Current controller setting */ + u32 speed_hz; /* spi-clk rate */ + u32 mode; + u32 bits_per_word; + u32 fifo_n_elm; /* FIFO depth in words */ +#define PIC32F_DMA_PREP 0 /* DMA chnls configured */ + unsigned long flags; + /* Current transfer state */ + struct completion xfer_done; + /* PIO transfer specific */ + const void *tx; + const void *tx_end; + const void *rx; + const void *rx_end; + int len; + void (*rx_fifo)(struct pic32_spi *); + void (*tx_fifo)(struct pic32_spi *); +}; + +static inline void pic32_spi_enable(struct pic32_spi *pic32s) +{ + writel(CTRL_ON | CTRL_SIDL, &pic32s->regs->ctrl_set); +} + +static inline void pic32_spi_disable(struct pic32_spi *pic32s) +{ + writel(CTRL_ON | CTRL_SIDL, &pic32s->regs->ctrl_clr); + + /* avoid SPI registers read/write at immediate next CPU clock */ + ndelay(20); +} + +static void pic32_spi_set_clk_rate(struct pic32_spi *pic32s, u32 spi_ck) +{ + u32 div; + + /* div = (clk_in / 2 * spi_ck) - 1 */ + div = DIV_ROUND_CLOSEST(clk_get_rate(pic32s->clk), 2 * spi_ck) - 1; + + writel(div & BAUD_MASK, &pic32s->regs->baud); +} + +static inline u32 pic32_rx_fifo_level(struct pic32_spi *pic32s) +{ + u32 sr = readl(&pic32s->regs->status); + + return (sr >> STAT_RF_LVL_SHIFT) & STAT_RF_LVL_MASK; +} + +static inline u32 pic32_tx_fifo_level(struct pic32_spi *pic32s) +{ + u32 sr = readl(&pic32s->regs->status); + + return (sr >> STAT_TF_LVL_SHIFT) & STAT_TF_LVL_MASK; +} + +/* Return the max entries we can fill into tx fifo */ +static u32 pic32_tx_max(struct pic32_spi *pic32s, int n_bytes) +{ + u32 tx_left, tx_room, rxtx_gap; + + tx_left = (pic32s->tx_end - pic32s->tx) / n_bytes; + tx_room = pic32s->fifo_n_elm - pic32_tx_fifo_level(pic32s); + + /* + * Another concern is about the tx/rx mismatch, we + * though to use (pic32s->fifo_n_byte - rxfl - txfl) as + * one maximum value for tx, but it doesn't cover the + * data which is out of tx/rx fifo and inside the + * shift registers. So a ctrl from sw point of + * view is taken. + */ + rxtx_gap = ((pic32s->rx_end - pic32s->rx) - + (pic32s->tx_end - pic32s->tx)) / n_bytes; + return min3(tx_left, tx_room, (u32)(pic32s->fifo_n_elm - rxtx_gap)); +} + +/* Return the max entries we should read out of rx fifo */ +static u32 pic32_rx_max(struct pic32_spi *pic32s, int n_bytes) +{ + u32 rx_left = (pic32s->rx_end - pic32s->rx) / n_bytes; + + return min_t(u32, rx_left, pic32_rx_fifo_level(pic32s)); +} + +#define BUILD_SPI_FIFO_RW(__name, __type, __bwl) \ +static void pic32_spi_rx_##__name(struct pic32_spi *pic32s) \ +{ \ + __type v; \ + u32 mx = pic32_rx_max(pic32s, sizeof(__type)); \ + for (; mx; mx--) { \ + v = read##__bwl(&pic32s->regs->buf); \ + if (pic32s->rx_end - pic32s->len) \ + *(__type *)(pic32s->rx) = v; \ + pic32s->rx += sizeof(__type); \ + } \ +} \ + \ +static void pic32_spi_tx_##__name(struct pic32_spi *pic32s) \ +{ \ + __type v; \ + u32 mx = pic32_tx_max(pic32s, sizeof(__type)); \ + for (; mx ; mx--) { \ + v = (__type)~0U; \ + if (pic32s->tx_end - pic32s->len) \ + v = *(__type *)(pic32s->tx); \ + write##__bwl(v, &pic32s->regs->buf); \ + pic32s->tx += sizeof(__type); \ + } \ +} + +BUILD_SPI_FIFO_RW(byte, u8, b); +BUILD_SPI_FIFO_RW(word, u16, w); +BUILD_SPI_FIFO_RW(dword, u32, l); + +static void pic32_err_stop(struct pic32_spi *pic32s, const char *msg) +{ + /* disable all interrupts */ + disable_irq_nosync(pic32s->fault_irq); + disable_irq_nosync(pic32s->rx_irq); + disable_irq_nosync(pic32s->tx_irq); + + /* Show err message and abort xfer with err */ + dev_err(&pic32s->master->dev, "%s\n", msg); + if (pic32s->master->cur_msg) + pic32s->master->cur_msg->status = -EIO; + complete(&pic32s->xfer_done); +} + +static irqreturn_t pic32_spi_fault_irq(int irq, void *dev_id) +{ + struct pic32_spi *pic32s = dev_id; + u32 status; + + status = readl(&pic32s->regs->status); + + /* Error handling */ + if (status & (STAT_RX_OV | STAT_TX_UR)) { + writel(STAT_RX_OV, &pic32s->regs->status_clr); + writel(STAT_TX_UR, &pic32s->regs->status_clr); + pic32_err_stop(pic32s, "err_irq: fifo ov/ur-run\n"); + return IRQ_HANDLED; + } + + if (status & STAT_FRM_ERR) { + pic32_err_stop(pic32s, "err_irq: frame error"); + return IRQ_HANDLED; + } + + if (!pic32s->master->cur_msg) { + pic32_err_stop(pic32s, "err_irq: no mesg"); + return IRQ_NONE; + } + + return IRQ_NONE; +} + +static irqreturn_t pic32_spi_rx_irq(int irq, void *dev_id) +{ + struct pic32_spi *pic32s = dev_id; + + pic32s->rx_fifo(pic32s); + + /* rx complete ? */ + if (pic32s->rx_end == pic32s->rx) { + /* disable all interrupts */ + disable_irq_nosync(pic32s->fault_irq); + disable_irq_nosync(pic32s->rx_irq); + + /* complete current xfer */ + complete(&pic32s->xfer_done); + } + + return IRQ_HANDLED; +} + +static irqreturn_t pic32_spi_tx_irq(int irq, void *dev_id) +{ + struct pic32_spi *pic32s = dev_id; + + pic32s->tx_fifo(pic32s); + + /* tx complete? disable tx interrupt */ + if (pic32s->tx_end == pic32s->tx) + disable_irq_nosync(pic32s->tx_irq); + + return IRQ_HANDLED; +} + +static void pic32_spi_dma_rx_notify(void *data) +{ + struct pic32_spi *pic32s = data; + + complete(&pic32s->xfer_done); +} + +static int pic32_spi_dma_transfer(struct pic32_spi *pic32s, + struct spi_transfer *xfer) +{ + struct spi_master *master = pic32s->master; + struct dma_async_tx_descriptor *desc_rx; + struct dma_async_tx_descriptor *desc_tx; + dma_cookie_t cookie; + int ret; + + if (!master->dma_rx || !master->dma_tx) + return -ENODEV; + + desc_rx = dmaengine_prep_slave_sg(master->dma_rx, + xfer->rx_sg.sgl, + xfer->rx_sg.nents, + DMA_FROM_DEVICE, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + if (!desc_rx) { + ret = -EINVAL; + goto err_dma; + } + + desc_tx = dmaengine_prep_slave_sg(master->dma_tx, + xfer->tx_sg.sgl, + xfer->tx_sg.nents, + DMA_TO_DEVICE, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + if (!desc_tx) { + ret = -EINVAL; + goto err_dma; + } + + /* Put callback on the RX transfer, that should finish last */ + desc_rx->callback = pic32_spi_dma_rx_notify; + desc_rx->callback_param = pic32s; + + cookie = dmaengine_submit(desc_rx); + ret = dma_submit_error(cookie); + if (ret) + goto err_dma; + + cookie = dmaengine_submit(desc_tx); + ret = dma_submit_error(cookie); + if (ret) + goto err_dma_tx; + + dma_async_issue_pending(master->dma_rx); + dma_async_issue_pending(master->dma_tx); + + return 0; + +err_dma_tx: + dmaengine_terminate_all(master->dma_rx); +err_dma: + return ret; +} + +static int pic32_spi_dma_config(struct pic32_spi *pic32s, u32 dma_width) +{ + int buf_offset = offsetof(struct pic32_spi_regs, buf); + struct spi_master *master = pic32s->master; + struct dma_slave_config cfg; + int ret; + + cfg.device_fc = true; + cfg.src_addr = pic32s->dma_base + buf_offset; + cfg.dst_addr = pic32s->dma_base + buf_offset; + cfg.src_maxburst = pic32s->fifo_n_elm / 2; /* fill one-half */ + cfg.dst_maxburst = pic32s->fifo_n_elm / 2; /* drain one-half */ + cfg.src_addr_width = dma_width; + cfg.dst_addr_width = dma_width; + /* tx channel */ + cfg.slave_id = pic32s->tx_irq; + cfg.direction = DMA_MEM_TO_DEV; + ret = dmaengine_slave_config(master->dma_tx, &cfg); + if (ret) { + dev_err(&master->dev, "tx channel setup failed\n"); + return ret; + } + /* rx channel */ + cfg.slave_id = pic32s->rx_irq; + cfg.direction = DMA_DEV_TO_MEM; + ret = dmaengine_slave_config(master->dma_rx, &cfg); + if (ret) + dev_err(&master->dev, "rx channel setup failed\n"); + + return ret; +} + +static int pic32_spi_set_word_size(struct pic32_spi *pic32s, u8 bits_per_word) +{ + enum dma_slave_buswidth dmawidth; + u32 buswidth, v; + + switch (bits_per_word) { + case 8: + pic32s->rx_fifo = pic32_spi_rx_byte; + pic32s->tx_fifo = pic32_spi_tx_byte; + buswidth = PIC32_BPW_8; + dmawidth = DMA_SLAVE_BUSWIDTH_1_BYTE; + break; + case 16: + pic32s->rx_fifo = pic32_spi_rx_word; + pic32s->tx_fifo = pic32_spi_tx_word; + buswidth = PIC32_BPW_16; + dmawidth = DMA_SLAVE_BUSWIDTH_2_BYTES; + break; + case 32: + pic32s->rx_fifo = pic32_spi_rx_dword; + pic32s->tx_fifo = pic32_spi_tx_dword; + buswidth = PIC32_BPW_32; + dmawidth = DMA_SLAVE_BUSWIDTH_4_BYTES; + break; + default: + /* not supported */ + return -EINVAL; + } + + /* calculate maximum number of words fifos can hold */ + pic32s->fifo_n_elm = DIV_ROUND_UP(pic32s->fifo_n_byte, + bits_per_word / 8); + /* set word size */ + v = readl(&pic32s->regs->ctrl); + v &= ~(CTRL_BPW_MASK << CTRL_BPW_SHIFT); + v |= buswidth << CTRL_BPW_SHIFT; + writel(v, &pic32s->regs->ctrl); + + /* re-configure dma width, if required */ + if (test_bit(PIC32F_DMA_PREP, &pic32s->flags)) + pic32_spi_dma_config(pic32s, dmawidth); + + return 0; +} + +static int pic32_spi_prepare_hardware(struct spi_master *master) +{ + struct pic32_spi *pic32s = spi_master_get_devdata(master); + + pic32_spi_enable(pic32s); + + return 0; +} + +static int pic32_spi_prepare_message(struct spi_master *master, + struct spi_message *msg) +{ + struct pic32_spi *pic32s = spi_master_get_devdata(master); + struct spi_device *spi = msg->spi; + u32 val; + + /* set device specific bits_per_word */ + if (pic32s->bits_per_word != spi->bits_per_word) { + pic32_spi_set_word_size(pic32s, spi->bits_per_word); + pic32s->bits_per_word = spi->bits_per_word; + } + + /* device specific speed change */ + if (pic32s->speed_hz != spi->max_speed_hz) { + pic32_spi_set_clk_rate(pic32s, spi->max_speed_hz); + pic32s->speed_hz = spi->max_speed_hz; + } + + /* device specific mode change */ + if (pic32s->mode != spi->mode) { + val = readl(&pic32s->regs->ctrl); + /* active low */ + if (spi->mode & SPI_CPOL) + val |= CTRL_CKP; + else + val &= ~CTRL_CKP; + /* tx on rising edge */ + if (spi->mode & SPI_CPHA) + val &= ~CTRL_CKE; + else + val |= CTRL_CKE; + + /* rx at end of tx */ + val |= CTRL_SMP; + writel(val, &pic32s->regs->ctrl); + pic32s->mode = spi->mode; + } + + return 0; +} + +static bool pic32_spi_can_dma(struct spi_master *master, + struct spi_device *spi, + struct spi_transfer *xfer) +{ + struct pic32_spi *pic32s = spi_master_get_devdata(master); + + /* skip using DMA on small size transfer to avoid overhead.*/ + return (xfer->len >= PIC32_DMA_LEN_MIN) && + test_bit(PIC32F_DMA_PREP, &pic32s->flags); +} + +static int pic32_spi_one_transfer(struct spi_master *master, + struct spi_device *spi, + struct spi_transfer *transfer) +{ + struct pic32_spi *pic32s; + bool dma_issued = false; + int ret; + + pic32s = spi_master_get_devdata(master); + + /* handle transfer specific word size change */ + if (transfer->bits_per_word && + (transfer->bits_per_word != pic32s->bits_per_word)) { + ret = pic32_spi_set_word_size(pic32s, transfer->bits_per_word); + if (ret) + return ret; + pic32s->bits_per_word = transfer->bits_per_word; + } + + /* handle transfer specific speed change */ + if (transfer->speed_hz && (transfer->speed_hz != pic32s->speed_hz)) { + pic32_spi_set_clk_rate(pic32s, transfer->speed_hz); + pic32s->speed_hz = transfer->speed_hz; + } + + reinit_completion(&pic32s->xfer_done); + + /* transact by DMA mode */ + if (transfer->rx_sg.nents && transfer->tx_sg.nents) { + ret = pic32_spi_dma_transfer(pic32s, transfer); + if (ret) { + dev_err(&spi->dev, "dma submit error\n"); + return ret; + } + + /* DMA issued */ + dma_issued = true; + } else { + /* set current transfer information */ + pic32s->tx = (const void *)transfer->tx_buf; + pic32s->rx = (const void *)transfer->rx_buf; + pic32s->tx_end = pic32s->tx + transfer->len; + pic32s->rx_end = pic32s->rx + transfer->len; + pic32s->len = transfer->len; + + /* transact by interrupt driven PIO */ + enable_irq(pic32s->fault_irq); + enable_irq(pic32s->rx_irq); + enable_irq(pic32s->tx_irq); + } + + /* wait for completion */ + ret = wait_for_completion_timeout(&pic32s->xfer_done, 2 * HZ); + if (ret <= 0) { + dev_err(&spi->dev, "wait error/timedout\n"); + if (dma_issued) { + dmaengine_terminate_all(master->dma_rx); + dmaengine_terminate_all(master->dma_rx); + } + ret = -ETIMEDOUT; + } else { + ret = 0; + } + + return ret; +} + +static int pic32_spi_unprepare_message(struct spi_master *master, + struct spi_message *msg) +{ + /* nothing to do */ + return 0; +} + +static int pic32_spi_unprepare_hardware(struct spi_master *master) +{ + struct pic32_spi *pic32s = spi_master_get_devdata(master); + + pic32_spi_disable(pic32s); + + return 0; +} + +/* This may be called multiple times by same spi dev */ +static int pic32_spi_setup(struct spi_device *spi) +{ + if (!spi->max_speed_hz) { + dev_err(&spi->dev, "No max speed HZ parameter\n"); + return -EINVAL; + } + + switch (spi->bits_per_word) { + case 8: + case 16: + case 32: + break; + default: + dev_err(&spi->dev, "Invalid bits_per_word defined\n"); + return -EINVAL; + } + + /* PIC32 spi controller can drive /CS during transfer depending + * on tx fifo fill-level. /CS will stay asserted as long as TX + * fifo is non-empty, else will be deasserted indicating + * completion of the ongoing transfer. This might result into + * unreliable/erroneous SPI transactions. + * To avoid that we will always handle /CS by toggling GPIO. + */ + if (!gpio_is_valid(spi->cs_gpio)) + return -EINVAL; + + gpio_direction_output(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH)); + + return 0; +} + +static void pic32_spi_cleanup(struct spi_device *spi) +{ + /* de-activate cs-gpio */ + gpio_direction_output(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH)); +} + +static void pic32_spi_dma_prep(struct pic32_spi *pic32s, struct device *dev) +{ + struct spi_master *master = pic32s->master; + dma_cap_mask_t mask; + + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); + + master->dma_rx = dma_request_slave_channel_compat(mask, NULL, NULL, + dev, "spi-rx"); + if (!master->dma_rx) { + dev_warn(dev, "RX channel not found.\n"); + goto out_err; + } + + master->dma_tx = dma_request_slave_channel_compat(mask, NULL, NULL, + dev, "spi-tx"); + if (!master->dma_tx) { + dev_warn(dev, "TX channel not found.\n"); + goto out_err; + } + + if (pic32_spi_dma_config(pic32s, DMA_SLAVE_BUSWIDTH_1_BYTE)) + goto out_err; + + /* DMA chnls allocated and prepared */ + set_bit(PIC32F_DMA_PREP, &pic32s->flags); + + return; + +out_err: + if (master->dma_rx) + dma_release_channel(master->dma_rx); + + if (master->dma_tx) + dma_release_channel(master->dma_tx); +} + +static void pic32_spi_dma_unprep(struct pic32_spi *pic32s) +{ + if (!test_bit(PIC32F_DMA_PREP, &pic32s->flags)) + return; + + clear_bit(PIC32F_DMA_PREP, &pic32s->flags); + if (pic32s->master->dma_rx) + dma_release_channel(pic32s->master->dma_rx); + + if (pic32s->master->dma_tx) + dma_release_channel(pic32s->master->dma_tx); +} + +static void pic32_spi_hw_init(struct pic32_spi *pic32s) +{ + u32 ctrl; + + /* disable hardware */ + pic32_spi_disable(pic32s); + + ctrl = readl(&pic32s->regs->ctrl); + /* enable enhanced fifo of 128bit deep */ + ctrl |= CTRL_ENHBUF; + pic32s->fifo_n_byte = 16; + + /* disable framing mode */ + ctrl &= ~CTRL_FRMEN; + + /* enable master mode while disabled */ + ctrl |= CTRL_MSTEN; + + /* set tx fifo threshold interrupt */ + ctrl &= ~(0x3 << CTRL_TX_INT_SHIFT); + ctrl |= (TX_FIFO_HALF_EMPTY << CTRL_TX_INT_SHIFT); + + /* set rx fifo threshold interrupt */ + ctrl &= ~(0x3 << CTRL_RX_INT_SHIFT); + ctrl |= (RX_FIFO_NOT_EMPTY << CTRL_RX_INT_SHIFT); + + /* select clk source */ + ctrl &= ~CTRL_MCLKSEL; + + /* set manual /CS mode */ + ctrl &= ~CTRL_MSSEN; + + writel(ctrl, &pic32s->regs->ctrl); + + /* enable error reporting */ + ctrl = CTRL2_TX_UR_EN | CTRL2_RX_OV_EN | CTRL2_FRM_ERR_EN; + writel(ctrl, &pic32s->regs->ctrl2_set); +} + +static int pic32_spi_hw_probe(struct platform_device *pdev, + struct pic32_spi *pic32s) +{ + struct resource *mem; + int ret; + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + pic32s->regs = devm_ioremap_resource(&pdev->dev, mem); + if (!pic32s->regs) { + dev_err(&pdev->dev, "ioremap() failed\n"); + return -ENOMEM; + } + pic32s->dma_base = mem->start; + + /* get irq resources: err-irq, rx-irq, tx-irq */ + pic32s->fault_irq = platform_get_irq_byname(pdev, "fault"); + if (pic32s->fault_irq < 0) { + dev_err(&pdev->dev, "fault-irq not found\n"); + return pic32s->fault_irq; + } + + pic32s->rx_irq = platform_get_irq_byname(pdev, "rx"); + if (pic32s->rx_irq < 0) { + dev_err(&pdev->dev, "rx-irq not found\n"); + return pic32s->rx_irq; + } + + pic32s->tx_irq = platform_get_irq_byname(pdev, "tx"); + if (pic32s->tx_irq < 0) { + dev_err(&pdev->dev, "tx-irq not found\n"); + return pic32s->tx_irq; + } + + /* get clock */ + pic32s->clk = devm_clk_get(&pdev->dev, "mck0"); + if (IS_ERR(pic32s->clk)) { + dev_err(&pdev->dev, "clk not found\n"); + ret = PTR_ERR(pic32s->clk); + goto err_unmap_mem; + } + + ret = clk_prepare_enable(pic32s->clk); + if (ret) + goto err_unmap_mem; + + pic32_spi_hw_init(pic32s); + + return 0; + +err_unmap_mem: + dev_err(&pdev->dev, "%s failed, err %d\n", __func__, ret); + return ret; +} + +static int pic32_spi_probe(struct platform_device *pdev) +{ + struct spi_master *master; + struct pic32_spi *pic32s; + int ret; + + master = spi_alloc_master(&pdev->dev, sizeof(*pic32s)); + if (!master) + return -ENOMEM; + + pic32s = spi_master_get_devdata(master); + pic32s->master = master; + + ret = pic32_spi_hw_probe(pdev, pic32s); + if (ret) + goto err_master; + + master->dev.of_node = of_node_get(pdev->dev.of_node); + master->mode_bits = SPI_MODE_3 | SPI_MODE_0 | SPI_CS_HIGH; + master->num_chipselect = 1; /* single chip-select */ + master->max_speed_hz = clk_get_rate(pic32s->clk); + master->setup = pic32_spi_setup; + master->cleanup = pic32_spi_cleanup; + master->flags = SPI_MASTER_MUST_TX | SPI_MASTER_MUST_RX; + master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 32); + master->transfer_one = pic32_spi_one_transfer; + master->prepare_message = pic32_spi_prepare_message; + master->unprepare_message = pic32_spi_unprepare_message; + master->prepare_transfer_hardware = pic32_spi_prepare_hardware; + master->unprepare_transfer_hardware = pic32_spi_unprepare_hardware; + + /* optional DMA support */ + pic32_spi_dma_prep(pic32s, &pdev->dev); + if (test_bit(PIC32F_DMA_PREP, &pic32s->flags)) + master->can_dma = pic32_spi_can_dma; + + init_completion(&pic32s->xfer_done); + pic32s->mode = -1; + + /* install irq handlers (with irq-disabled) */ + irq_set_status_flags(pic32s->fault_irq, IRQ_NOAUTOEN); + ret = devm_request_irq(&pdev->dev, pic32s->fault_irq, + pic32_spi_fault_irq, IRQF_NO_THREAD, + dev_name(&pdev->dev), pic32s); + if (ret < 0) { + dev_err(&pdev->dev, "request fault-irq %d\n", pic32s->rx_irq); + goto err_bailout; + } + + /* receive interrupt handler */ + irq_set_status_flags(pic32s->rx_irq, IRQ_NOAUTOEN); + ret = devm_request_irq(&pdev->dev, pic32s->rx_irq, + pic32_spi_rx_irq, IRQF_NO_THREAD, + dev_name(&pdev->dev), pic32s); + if (ret < 0) { + dev_err(&pdev->dev, "request rx-irq %d\n", pic32s->rx_irq); + goto err_bailout; + } + + /* transmit interrupt handler */ + irq_set_status_flags(pic32s->tx_irq, IRQ_NOAUTOEN); + ret = devm_request_irq(&pdev->dev, pic32s->tx_irq, + pic32_spi_tx_irq, IRQF_NO_THREAD, + dev_name(&pdev->dev), pic32s); + if (ret < 0) { + dev_err(&pdev->dev, "request tx-irq %d\n", pic32s->tx_irq); + goto err_bailout; + } + + /* register master */ + ret = devm_spi_register_master(&pdev->dev, master); + if (ret) { + dev_err(&master->dev, "failed registering spi master\n"); + goto err_bailout; + } + + platform_set_drvdata(pdev, pic32s); + + return 0; + +err_bailout: + clk_disable_unprepare(pic32s->clk); +err_master: + spi_master_put(master); + return ret; +} + +static int pic32_spi_remove(struct platform_device *pdev) +{ + struct pic32_spi *pic32s; + + pic32s = platform_get_drvdata(pdev); + pic32_spi_disable(pic32s); + clk_disable_unprepare(pic32s->clk); + pic32_spi_dma_unprep(pic32s); + + return 0; +} + +static const struct of_device_id pic32_spi_of_match[] = { + {.compatible = "microchip,pic32mzda-spi",}, + {}, +}; +MODULE_DEVICE_TABLE(of, pic32_spi_of_match); + +static struct platform_driver pic32_spi_driver = { + .driver = { + .name = "spi-pic32", + .of_match_table = of_match_ptr(pic32_spi_of_match), + }, + .probe = pic32_spi_probe, + .remove = pic32_spi_remove, +}; + +module_platform_driver(pic32_spi_driver); + +MODULE_AUTHOR("Purna Chandra Mandal "); +MODULE_DESCRIPTION("Microchip SPI driver for PIC32 SPI controller."); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 77ed2c5745d93416992857d124f35834b62b3e70 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Tue, 8 Mar 2016 20:01:32 +0900 Subject: android,lowmemorykiller: Don't abuse TIF_MEMDIE. Currently, lowmemorykiller (LMK) is using TIF_MEMDIE for two purposes. One is to remember processes killed by LMK, and the other is to accelerate termination of processes killed by LMK. But since LMK is invoked as a memory shrinker function, there still should be some memory available. It is very likely that memory allocations by processes killed by LMK will succeed without using ALLOC_NO_WATERMARKS via TIF_MEMDIE. Even if their allocations cannot escape from memory allocation loop unless they use ALLOC_NO_WATERMARKS, lowmem_deathpending_timeout can guarantee forward progress by choosing next victim process. On the other hand, mark_oom_victim() assumes that it must be called with oom_lock held and it must not be called after oom_killer_disable() was called. But LMK is calling it without holding oom_lock and checking oom_killer_disabled. It is possible that LMK calls mark_oom_victim() due to allocation requests by kernel threads after current thread returned from oom_killer_disabled(). This will break synchronization for PM/suspend. This patch introduces per a task_struct flag for remembering processes killed by LMK, and replaces TIF_MEMDIE with that flag. By applying this patch, assumption by mark_oom_victim() becomes true. Signed-off-by: Tetsuo Handa Acked-by: Michal Hocko Cc: Arve Hjonnevag Cc: Riley Andrews Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/lowmemorykiller.c | 9 ++------- include/linux/sched.h | 4 ++++ 2 files changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index 2509e5df7244..c79f22425fa8 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -131,7 +131,7 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc) if (!p) continue; - if (test_tsk_thread_flag(p, TIF_MEMDIE) && + if (task_lmk_waiting(p) && p->mm && time_before_eq(jiffies, lowmem_deathpending_timeout)) { task_unlock(p); rcu_read_unlock(); @@ -162,13 +162,8 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc) if (selected) { task_lock(selected); send_sig(SIGKILL, selected, 0); - /* - * FIXME: lowmemorykiller shouldn't abuse global OOM killer - * infrastructure. There is no real reason why the selected - * task should have access to the memory reserves. - */ if (selected->mm) - mark_oom_victim(selected); + task_set_lmk_waiting(selected); task_unlock(selected); lowmem_print(1, "Killing '%s' (%d), adj %hd,\n" " to free %ldkB on behalf of '%s' (%d) because\n" diff --git a/include/linux/sched.h b/include/linux/sched.h index 60bba7e032dc..9dff190e6a0a 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -2184,6 +2184,7 @@ static inline void memalloc_noio_restore(unsigned int flags) #define PFA_NO_NEW_PRIVS 0 /* May not gain new privileges. */ #define PFA_SPREAD_PAGE 1 /* Spread page cache over cpuset */ #define PFA_SPREAD_SLAB 2 /* Spread some slab caches over cpuset */ +#define PFA_LMK_WAITING 3 /* Lowmemorykiller is waiting */ #define TASK_PFA_TEST(name, func) \ @@ -2207,6 +2208,9 @@ TASK_PFA_TEST(SPREAD_SLAB, spread_slab) TASK_PFA_SET(SPREAD_SLAB, spread_slab) TASK_PFA_CLEAR(SPREAD_SLAB, spread_slab) +TASK_PFA_TEST(LMK_WAITING, lmk_waiting) +TASK_PFA_SET(LMK_WAITING, lmk_waiting) + /* * task->jobctl flags */ -- cgit v1.2.3 From 8670a56ff70ec1fcbb95bd05a478c5a8361fee53 Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Fri, 1 Apr 2016 17:28:22 +0900 Subject: staging: dgnc: remove too many traverse pointer The "ch->ch_bd" is already assined to "bd" but this is only for checking null or MAGIC number. in the dgnc_tty_ioctl function, bd can be used for referencing to board_ops structure. Signed-off-by: Daeseok Youn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_tty.c | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index d617fca682dc..5d8da411edc6 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -2518,6 +2518,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct dgnc_board *bd; + struct board_ops *ch_bd_ops; struct channel_t *ch; struct un_t *un; int rc; @@ -2539,6 +2540,8 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, if (!bd || bd->magic != DGNC_BOARD_MAGIC) return -ENODEV; + ch_bd_ops = bd->bd_ops; + spin_lock_irqsave(&ch->ch_lock, flags); if (un->un_open_count <= 0) { @@ -2563,7 +2566,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, if (rc) return rc; - rc = ch->ch_bd->bd_ops->drain(tty, 0); + rc = ch_bd_ops->drain(tty, 0); if (rc) return -EINTR; @@ -2571,7 +2574,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, spin_lock_irqsave(&ch->ch_lock, flags); if (((cmd == TCSBRK) && (!arg)) || (cmd == TCSBRKP)) - ch->ch_bd->bd_ops->send_break(ch, 250); + ch_bd_ops->send_break(ch, 250); spin_unlock_irqrestore(&ch->ch_lock, flags); @@ -2588,13 +2591,13 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, if (rc) return rc; - rc = ch->ch_bd->bd_ops->drain(tty, 0); + rc = ch_bd_ops->drain(tty, 0); if (rc) return -EINTR; spin_lock_irqsave(&ch->ch_lock, flags); - ch->ch_bd->bd_ops->send_break(ch, 250); + ch_bd_ops->send_break(ch, 250); spin_unlock_irqrestore(&ch->ch_lock, flags); @@ -2606,13 +2609,13 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, if (rc) return rc; - rc = ch->ch_bd->bd_ops->drain(tty, 0); + rc = ch_bd_ops->drain(tty, 0); if (rc) return -EINTR; spin_lock_irqsave(&ch->ch_lock, flags); - ch->ch_bd->bd_ops->send_break(ch, 250); + ch_bd_ops->send_break(ch, 250); spin_unlock_irqrestore(&ch->ch_lock, flags); @@ -2641,7 +2644,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, spin_lock_irqsave(&ch->ch_lock, flags); tty->termios.c_cflag = ((tty->termios.c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0)); - ch->ch_bd->bd_ops->param(tty); + ch_bd_ops->param(tty); spin_unlock_irqrestore(&ch->ch_lock, flags); return 0; @@ -2678,7 +2681,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, if ((arg == TCIFLUSH) || (arg == TCIOFLUSH)) { ch->ch_r_head = ch->ch_r_tail; - ch->ch_bd->bd_ops->flush_uart_read(ch); + ch_bd_ops->flush_uart_read(ch); /* Force queue flow control to be released, if needed */ dgnc_check_queue_flow_control(ch); } @@ -2686,7 +2689,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, if ((arg == TCOFLUSH) || (arg == TCIOFLUSH)) { if (!(un->un_type == DGNC_PRINT)) { ch->ch_w_head = ch->ch_w_tail; - ch->ch_bd->bd_ops->flush_uart_write(ch); + ch_bd_ops->flush_uart_write(ch); if (ch->ch_tun.un_flags & (UN_LOW|UN_EMPTY)) { ch->ch_tun.un_flags &= @@ -2720,14 +2723,14 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, /* flush rx */ ch->ch_flags &= ~CH_STOP; ch->ch_r_head = ch->ch_r_tail; - ch->ch_bd->bd_ops->flush_uart_read(ch); + ch_bd_ops->flush_uart_read(ch); /* Force queue flow control to be released, if needed */ dgnc_check_queue_flow_control(ch); } /* now wait for all the output to drain */ spin_unlock_irqrestore(&ch->ch_lock, flags); - rc = ch->ch_bd->bd_ops->drain(tty, 0); + rc = ch_bd_ops->drain(tty, 0); if (rc) return -EINTR; @@ -2737,7 +2740,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, case TCSETAW: spin_unlock_irqrestore(&ch->ch_lock, flags); - rc = ch->ch_bd->bd_ops->drain(tty, 0); + rc = ch_bd_ops->drain(tty, 0); if (rc) return -EINTR; @@ -2760,7 +2763,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, /* set information for ditty */ if (cmd == (DIGI_SETAW)) { spin_unlock_irqrestore(&ch->ch_lock, flags); - rc = ch->ch_bd->bd_ops->drain(tty, 0); + rc = ch_bd_ops->drain(tty, 0); if (rc) return -EINTR; @@ -2793,7 +2796,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, else ch->ch_flags &= ~(CH_LOOPBACK); - ch->ch_bd->bd_ops->param(tty); + ch_bd_ops->param(tty); spin_unlock_irqrestore(&ch->ch_lock, flags); return 0; } @@ -2813,7 +2816,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, return rc; spin_lock_irqsave(&ch->ch_lock, flags); dgnc_set_custom_speed(ch, new_rate); - ch->ch_bd->bd_ops->param(tty); + ch_bd_ops->param(tty); spin_unlock_irqrestore(&ch->ch_lock, flags); return 0; } @@ -2834,7 +2837,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, if (rc) return rc; spin_lock_irqsave(&ch->ch_lock, flags); - ch->ch_bd->bd_ops->send_immediate_char(ch, c); + ch_bd_ops->send_immediate_char(ch, c); spin_unlock_irqrestore(&ch->ch_lock, flags); return 0; } @@ -2922,7 +2925,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, /* * Is the UART empty? Add that value to whats in our TX queue. */ - count = buf.txbuf + ch->ch_bd->bd_ops->get_uart_bytes_left(ch); + count = buf.txbuf + ch_bd_ops->get_uart_bytes_left(ch); /* * Figure out how much data the RealPort Server believes should -- cgit v1.2.3 From b9f8463728eb0dd46b9f2b34ee59b12e358b4ce7 Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Fri, 1 Apr 2016 17:28:44 +0900 Subject: staging: dgnc: fix CamelCase in dgnc_tty.c fix checkpatch.pl warning about 'Avoid CamelCase' Signed-off-by: Daeseok Youn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_tty.c | 2 +- drivers/staging/dgnc/digi.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index 5d8da411edc6..074988d99639 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -2931,7 +2931,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, * Figure out how much data the RealPort Server believes should * be in our TX queue. */ - tdist = (buf.tIn - buf.tOut) & 0xffff; + tdist = (buf.tx_in - buf.tx_out) & 0xffff; /* * If we have more data than the RealPort Server believes we diff --git a/drivers/staging/dgnc/digi.h b/drivers/staging/dgnc/digi.h index 523a2d34f747..5b983e6f5ee2 100644 --- a/drivers/staging/dgnc/digi.h +++ b/drivers/staging/dgnc/digi.h @@ -109,8 +109,8 @@ struct digi_info { struct digi_getbuffer /* Struct for holding buffer use counts */ { - unsigned long tIn; - unsigned long tOut; + unsigned long tx_in; + unsigned long tx_out; unsigned long rxbuf; unsigned long txbuf; unsigned long txdone; -- cgit v1.2.3 From 148e45dc87cb76ba89e80da264bc692cc91a5149 Mon Sep 17 00:00:00 2001 From: Clifton Barnes Date: Thu, 31 Mar 2016 18:53:14 -0400 Subject: staging: vme: fix bare use of 'unsigned' fix checkpatch.pl warning about 'Prefer 'unsigned int' to bare use of 'unsigned'' Signed-off-by: Clifton Barnes Acked-by: Martyn Welch Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/devices/vme_pio2_gpio.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vme/devices/vme_pio2_gpio.c b/drivers/staging/vme/devices/vme_pio2_gpio.c index df992c3cb5ce..f52a9ed75871 100644 --- a/drivers/staging/vme/devices/vme_pio2_gpio.c +++ b/drivers/staging/vme/devices/vme_pio2_gpio.c @@ -97,7 +97,7 @@ static void pio2_gpio_set(struct gpio_chip *chip, } /* Directionality configured at board build - send appropriate response */ -static int pio2_gpio_dir_in(struct gpio_chip *chip, unsigned offset) +static int pio2_gpio_dir_in(struct gpio_chip *chip, unsigned int offset) { int data; struct pio2_card *card = gpio_to_pio2_card(chip); @@ -116,7 +116,8 @@ static int pio2_gpio_dir_in(struct gpio_chip *chip, unsigned offset) } /* Directionality configured at board build - send appropriate response */ -static int pio2_gpio_dir_out(struct gpio_chip *chip, unsigned offset, int value) +static int pio2_gpio_dir_out(struct gpio_chip *chip, + unsigned int offset, int value) { int data; struct pio2_card *card = gpio_to_pio2_card(chip); -- cgit v1.2.3 From 3424e3a4f844c0a62128feb388d04ed6b65f6b20 Mon Sep 17 00:00:00 2001 From: Yakir Yang Date: Tue, 29 Mar 2016 09:57:03 +0800 Subject: drm: bridge: analogix/dp: split exynos dp driver to bridge directory Split the dp core driver from exynos directory to bridge directory, and rename the core driver to analogix_dp_*, rename the platform code to exynos_dp. Beside the new analogix_dp driver would export six hooks. "analogix_dp_bind()" and "analogix_dp_unbind()" "analogix_dp_suspned()" and "analogix_dp_resume()" "analogix_dp_detect()" and "analogix_dp_get_modes()" The bind/unbind symbols is used for analogix platform driver to connect with analogix_dp core driver. And the detect/get_modes is used for analogix platform driver to init the connector. They reason why connector need register in helper driver is rockchip drm haven't implement the atomic API, but Exynos drm have implement it, so there would need two different connector helper functions, that's why we leave the connector register in helper driver. Acked-by: Inki Dae Tested-by: Caesar Wang Tested-by: Douglas Anderson Tested-by: Heiko Stuebner Tested-by: Javier Martinez Canillas Signed-off-by: Yakir Yang Signed-off-by: Heiko Stuebner --- drivers/gpu/drm/bridge/Kconfig | 2 + drivers/gpu/drm/bridge/Makefile | 1 + drivers/gpu/drm/bridge/analogix/Kconfig | 3 + drivers/gpu/drm/bridge/analogix/Makefile | 2 + drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 1351 +++++++++++++++++++ drivers/gpu/drm/bridge/analogix/analogix_dp_core.h | 277 ++++ drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 1263 ++++++++++++++++++ drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h | 366 ++++++ drivers/gpu/drm/exynos/Kconfig | 3 +- drivers/gpu/drm/exynos/Makefile | 2 +- drivers/gpu/drm/exynos/exynos_dp_core.c | 1353 ++------------------ drivers/gpu/drm/exynos/exynos_dp_core.h | 282 ---- drivers/gpu/drm/exynos/exynos_dp_reg.c | 1263 ------------------ drivers/gpu/drm/exynos/exynos_dp_reg.h | 366 ------ include/drm/bridge/analogix_dp.h | 40 + 15 files changed, 3392 insertions(+), 3182 deletions(-) create mode 100644 drivers/gpu/drm/bridge/analogix/Kconfig create mode 100644 drivers/gpu/drm/bridge/analogix/Makefile create mode 100644 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c create mode 100644 drivers/gpu/drm/bridge/analogix/analogix_dp_core.h create mode 100644 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c create mode 100644 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h delete mode 100644 drivers/gpu/drm/exynos/exynos_dp_core.h delete mode 100644 drivers/gpu/drm/exynos/exynos_dp_reg.c delete mode 100644 drivers/gpu/drm/exynos/exynos_dp_reg.h create mode 100644 include/drm/bridge/analogix_dp.h (limited to 'drivers') diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index 27e2022de89d..efd94e00c3e5 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -40,4 +40,6 @@ config DRM_PARADE_PS8622 ---help--- Parade eDP-LVDS bridge chip driver. +source "drivers/gpu/drm/bridge/analogix/Kconfig" + endmenu diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index f13c33d67c03..ff821f4b5833 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o +obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/ diff --git a/drivers/gpu/drm/bridge/analogix/Kconfig b/drivers/gpu/drm/bridge/analogix/Kconfig new file mode 100644 index 000000000000..80f286fa3a69 --- /dev/null +++ b/drivers/gpu/drm/bridge/analogix/Kconfig @@ -0,0 +1,3 @@ +config DRM_ANALOGIX_DP + tristate + depends on DRM diff --git a/drivers/gpu/drm/bridge/analogix/Makefile b/drivers/gpu/drm/bridge/analogix/Makefile new file mode 100644 index 000000000000..cd4010ba6890 --- /dev/null +++ b/drivers/gpu/drm/bridge/analogix/Makefile @@ -0,0 +1,2 @@ +analogix_dp-objs := analogix_dp_core.o analogix_dp_reg.o +obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix_dp.o diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c new file mode 100644 index 000000000000..392c29691d34 --- /dev/null +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -0,0 +1,1351 @@ +/* +* Analogix DP (Display Port) core interface driver. +* +* Copyright (C) 2012 Samsung Electronics Co., Ltd. +* Author: Jingoo Han +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at your +* option) any later version. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "analogix_dp_core.h" + +#define to_dp(nm) container_of(nm, struct analogix_dp_device, nm) + +struct bridge_init { + struct i2c_client *client; + struct device_node *node; +}; + +static void analogix_dp_init_dp(struct analogix_dp_device *dp) +{ + analogix_dp_reset(dp); + + analogix_dp_swreset(dp); + + analogix_dp_init_analog_param(dp); + analogix_dp_init_interrupt(dp); + + /* SW defined function Normal operation */ + analogix_dp_enable_sw_function(dp); + + analogix_dp_config_interrupt(dp); + analogix_dp_init_analog_func(dp); + + analogix_dp_init_hpd(dp); + analogix_dp_init_aux(dp); +} + +static int analogix_dp_detect_hpd(struct analogix_dp_device *dp) +{ + int timeout_loop = 0; + + while (analogix_dp_get_plug_in_status(dp) != 0) { + timeout_loop++; + if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { + dev_err(dp->dev, "failed to get hpd plug status\n"); + return -ETIMEDOUT; + } + usleep_range(10, 11); + } + + return 0; +} + +static unsigned char analogix_dp_calc_edid_check_sum(unsigned char *edid_data) +{ + int i; + unsigned char sum = 0; + + for (i = 0; i < EDID_BLOCK_LENGTH; i++) + sum = sum + edid_data[i]; + + return sum; +} + +static int analogix_dp_read_edid(struct analogix_dp_device *dp) +{ + unsigned char edid[EDID_BLOCK_LENGTH * 2]; + unsigned int extend_block = 0; + unsigned char sum; + unsigned char test_vector; + int retval; + + /* + * EDID device address is 0x50. + * However, if necessary, you must have set upper address + * into E-EDID in I2C device, 0x30. + */ + + /* Read Extension Flag, Number of 128-byte EDID extension blocks */ + retval = analogix_dp_read_byte_from_i2c(dp, I2C_EDID_DEVICE_ADDR, + EDID_EXTENSION_FLAG, + &extend_block); + if (retval) + return retval; + + if (extend_block > 0) { + dev_dbg(dp->dev, "EDID data includes a single extension!\n"); + + /* Read EDID data */ + retval = analogix_dp_read_bytes_from_i2c(dp, I2C_EDID_DEVICE_ADDR, + EDID_HEADER_PATTERN, + EDID_BLOCK_LENGTH, + &edid[EDID_HEADER_PATTERN]); + if (retval != 0) { + dev_err(dp->dev, "EDID Read failed!\n"); + return -EIO; + } + sum = analogix_dp_calc_edid_check_sum(edid); + if (sum != 0) { + dev_err(dp->dev, "EDID bad checksum!\n"); + return -EIO; + } + + /* Read additional EDID data */ + retval = analogix_dp_read_bytes_from_i2c(dp, + I2C_EDID_DEVICE_ADDR, + EDID_BLOCK_LENGTH, + EDID_BLOCK_LENGTH, + &edid[EDID_BLOCK_LENGTH]); + if (retval != 0) { + dev_err(dp->dev, "EDID Read failed!\n"); + return -EIO; + } + sum = analogix_dp_calc_edid_check_sum(&edid[EDID_BLOCK_LENGTH]); + if (sum != 0) { + dev_err(dp->dev, "EDID bad checksum!\n"); + return -EIO; + } + + analogix_dp_read_byte_from_dpcd(dp, DP_TEST_REQUEST, + &test_vector); + if (test_vector & DP_TEST_LINK_EDID_READ) { + analogix_dp_write_byte_to_dpcd(dp, + DP_TEST_EDID_CHECKSUM, + edid[EDID_BLOCK_LENGTH + EDID_CHECKSUM]); + analogix_dp_write_byte_to_dpcd(dp, + DP_TEST_RESPONSE, + DP_TEST_EDID_CHECKSUM_WRITE); + } + } else { + dev_info(dp->dev, "EDID data does not include any extensions.\n"); + + /* Read EDID data */ + retval = analogix_dp_read_bytes_from_i2c(dp, + I2C_EDID_DEVICE_ADDR, + EDID_HEADER_PATTERN, + EDID_BLOCK_LENGTH, + &edid[EDID_HEADER_PATTERN]); + if (retval != 0) { + dev_err(dp->dev, "EDID Read failed!\n"); + return -EIO; + } + sum = analogix_dp_calc_edid_check_sum(edid); + if (sum != 0) { + dev_err(dp->dev, "EDID bad checksum!\n"); + return -EIO; + } + + analogix_dp_read_byte_from_dpcd(dp, + DP_TEST_REQUEST, + &test_vector); + if (test_vector & DP_TEST_LINK_EDID_READ) { + analogix_dp_write_byte_to_dpcd(dp, + DP_TEST_EDID_CHECKSUM, + edid[EDID_CHECKSUM]); + analogix_dp_write_byte_to_dpcd(dp, + DP_TEST_RESPONSE, + DP_TEST_EDID_CHECKSUM_WRITE); + } + } + + dev_dbg(dp->dev, "EDID Read success!\n"); + return 0; +} + +static int analogix_dp_handle_edid(struct analogix_dp_device *dp) +{ + u8 buf[12]; + int i; + int retval; + + /* Read DPCD DP_DPCD_REV~RECEIVE_PORT1_CAP_1 */ + retval = analogix_dp_read_bytes_from_dpcd(dp, DP_DPCD_REV, + 12, buf); + if (retval) + return retval; + + /* Read EDID */ + for (i = 0; i < 3; i++) { + retval = analogix_dp_read_edid(dp); + if (!retval) + break; + } + + return retval; +} + +static void analogix_dp_enable_rx_to_enhanced_mode(struct analogix_dp_device *dp, + bool enable) +{ + u8 data; + + analogix_dp_read_byte_from_dpcd(dp, DP_LANE_COUNT_SET, &data); + + if (enable) + analogix_dp_write_byte_to_dpcd(dp, DP_LANE_COUNT_SET, + DP_LANE_COUNT_ENHANCED_FRAME_EN | + DPCD_LANE_COUNT_SET(data)); + else + analogix_dp_write_byte_to_dpcd(dp, DP_LANE_COUNT_SET, + DPCD_LANE_COUNT_SET(data)); +} + +static int analogix_dp_is_enhanced_mode_available(struct analogix_dp_device *dp) +{ + u8 data; + int retval; + + analogix_dp_read_byte_from_dpcd(dp, DP_MAX_LANE_COUNT, &data); + retval = DPCD_ENHANCED_FRAME_CAP(data); + + return retval; +} + +static void analogix_dp_set_enhanced_mode(struct analogix_dp_device *dp) +{ + u8 data; + + data = analogix_dp_is_enhanced_mode_available(dp); + analogix_dp_enable_rx_to_enhanced_mode(dp, data); + analogix_dp_enable_enhanced_mode(dp, data); +} + +static void analogix_dp_training_pattern_dis(struct analogix_dp_device *dp) +{ + analogix_dp_set_training_pattern(dp, DP_NONE); + + analogix_dp_write_byte_to_dpcd(dp, + DP_TRAINING_PATTERN_SET, + DP_TRAINING_PATTERN_DISABLE); +} + +static void analogix_dp_set_lane_lane_pre_emphasis(struct analogix_dp_device *dp, + int pre_emphasis, int lane) +{ + switch (lane) { + case 0: + analogix_dp_set_lane0_pre_emphasis(dp, pre_emphasis); + break; + case 1: + analogix_dp_set_lane1_pre_emphasis(dp, pre_emphasis); + break; + + case 2: + analogix_dp_set_lane2_pre_emphasis(dp, pre_emphasis); + break; + + case 3: + analogix_dp_set_lane3_pre_emphasis(dp, pre_emphasis); + break; + } +} + +static int analogix_dp_link_start(struct analogix_dp_device *dp) +{ + u8 buf[4]; + int lane, lane_count, pll_tries, retval; + + lane_count = dp->link_train.lane_count; + + dp->link_train.lt_state = CLOCK_RECOVERY; + dp->link_train.eq_loop = 0; + + for (lane = 0; lane < lane_count; lane++) + dp->link_train.cr_loop[lane] = 0; + + /* Set link rate and count as you want to establish*/ + analogix_dp_set_link_bandwidth(dp, dp->link_train.link_rate); + analogix_dp_set_lane_count(dp, dp->link_train.lane_count); + + /* Setup RX configuration */ + buf[0] = dp->link_train.link_rate; + buf[1] = dp->link_train.lane_count; + retval = analogix_dp_write_bytes_to_dpcd(dp, DP_LINK_BW_SET, + 2, buf); + if (retval) + return retval; + + /* Set TX pre-emphasis to minimum */ + for (lane = 0; lane < lane_count; lane++) + analogix_dp_set_lane_lane_pre_emphasis(dp, + PRE_EMPHASIS_LEVEL_0, lane); + + /* Wait for PLL lock */ + pll_tries = 0; + while (analogix_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) { + if (pll_tries == DP_TIMEOUT_LOOP_COUNT) { + dev_err(dp->dev, "Wait for PLL lock timed out\n"); + return -ETIMEDOUT; + } + + pll_tries++; + usleep_range(90, 120); + } + + /* Set training pattern 1 */ + analogix_dp_set_training_pattern(dp, TRAINING_PTN1); + + /* Set RX training pattern */ + retval = analogix_dp_write_byte_to_dpcd(dp, + DP_TRAINING_PATTERN_SET, + DP_LINK_SCRAMBLING_DISABLE | DP_TRAINING_PATTERN_1); + if (retval) + return retval; + + for (lane = 0; lane < lane_count; lane++) + buf[lane] = DP_TRAIN_PRE_EMPH_LEVEL_0 | + DP_TRAIN_VOLTAGE_SWING_LEVEL_0; + + retval = analogix_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET, + lane_count, buf); + + return retval; +} + +static unsigned char analogix_dp_get_lane_status(u8 link_status[2], int lane) +{ + int shift = (lane & 1) * 4; + u8 link_value = link_status[lane>>1]; + + return (link_value >> shift) & 0xf; +} + +static int analogix_dp_clock_recovery_ok(u8 link_status[2], int lane_count) +{ + int lane; + u8 lane_status; + + for (lane = 0; lane < lane_count; lane++) { + lane_status = analogix_dp_get_lane_status(link_status, lane); + if ((lane_status & DP_LANE_CR_DONE) == 0) + return -EINVAL; + } + return 0; +} + +static int analogix_dp_channel_eq_ok(u8 link_status[2], u8 link_align, + int lane_count) +{ + int lane; + u8 lane_status; + + if ((link_align & DP_INTERLANE_ALIGN_DONE) == 0) + return -EINVAL; + + for (lane = 0; lane < lane_count; lane++) { + lane_status = analogix_dp_get_lane_status(link_status, lane); + lane_status &= DP_CHANNEL_EQ_BITS; + if (lane_status != DP_CHANNEL_EQ_BITS) + return -EINVAL; + } + + return 0; +} + +static unsigned char analogix_dp_get_adjust_request_voltage(u8 adjust_request[2], + int lane) +{ + int shift = (lane & 1) * 4; + u8 link_value = adjust_request[lane>>1]; + + return (link_value >> shift) & 0x3; +} + +static unsigned char analogix_dp_get_adjust_request_pre_emphasis( + u8 adjust_request[2], + int lane) +{ + int shift = (lane & 1) * 4; + u8 link_value = adjust_request[lane>>1]; + + return ((link_value >> shift) & 0xc) >> 2; +} + +static void analogix_dp_set_lane_link_training(struct analogix_dp_device *dp, + u8 training_lane_set, int lane) +{ + switch (lane) { + case 0: + analogix_dp_set_lane0_link_training(dp, training_lane_set); + break; + case 1: + analogix_dp_set_lane1_link_training(dp, training_lane_set); + break; + + case 2: + analogix_dp_set_lane2_link_training(dp, training_lane_set); + break; + + case 3: + analogix_dp_set_lane3_link_training(dp, training_lane_set); + break; + } +} + +static unsigned int analogix_dp_get_lane_link_training( + struct analogix_dp_device *dp, + int lane) +{ + u32 reg; + + switch (lane) { + case 0: + reg = analogix_dp_get_lane0_link_training(dp); + break; + case 1: + reg = analogix_dp_get_lane1_link_training(dp); + break; + case 2: + reg = analogix_dp_get_lane2_link_training(dp); + break; + case 3: + reg = analogix_dp_get_lane3_link_training(dp); + break; + default: + WARN_ON(1); + return 0; + } + + return reg; +} + +static void analogix_dp_reduce_link_rate(struct analogix_dp_device *dp) +{ + analogix_dp_training_pattern_dis(dp); + analogix_dp_set_enhanced_mode(dp); + + dp->link_train.lt_state = FAILED; +} + +static void analogix_dp_get_adjust_training_lane(struct analogix_dp_device *dp, + u8 adjust_request[2]) +{ + int lane, lane_count; + u8 voltage_swing, pre_emphasis, training_lane; + + lane_count = dp->link_train.lane_count; + for (lane = 0; lane < lane_count; lane++) { + voltage_swing = analogix_dp_get_adjust_request_voltage( + adjust_request, lane); + pre_emphasis = analogix_dp_get_adjust_request_pre_emphasis( + adjust_request, lane); + training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) | + DPCD_PRE_EMPHASIS_SET(pre_emphasis); + + if (voltage_swing == VOLTAGE_LEVEL_3) + training_lane |= DP_TRAIN_MAX_SWING_REACHED; + if (pre_emphasis == PRE_EMPHASIS_LEVEL_3) + training_lane |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; + + dp->link_train.training_lane[lane] = training_lane; + } +} + +static int analogix_dp_process_clock_recovery(struct analogix_dp_device *dp) +{ + int lane, lane_count, retval; + u8 voltage_swing, pre_emphasis, training_lane; + u8 link_status[2], adjust_request[2]; + + usleep_range(100, 101); + + lane_count = dp->link_train.lane_count; + + retval = analogix_dp_read_bytes_from_dpcd(dp, + DP_LANE0_1_STATUS, 2, link_status); + if (retval) + return retval; + + retval = analogix_dp_read_bytes_from_dpcd(dp, + DP_ADJUST_REQUEST_LANE0_1, 2, adjust_request); + if (retval) + return retval; + + if (analogix_dp_clock_recovery_ok(link_status, lane_count) == 0) { + /* set training pattern 2 for EQ */ + analogix_dp_set_training_pattern(dp, TRAINING_PTN2); + + retval = analogix_dp_write_byte_to_dpcd(dp, + DP_TRAINING_PATTERN_SET, + DP_LINK_SCRAMBLING_DISABLE | + DP_TRAINING_PATTERN_2); + if (retval) + return retval; + + dev_info(dp->dev, "Link Training Clock Recovery success\n"); + dp->link_train.lt_state = EQUALIZER_TRAINING; + } else { + for (lane = 0; lane < lane_count; lane++) { + training_lane = analogix_dp_get_lane_link_training( + dp, lane); + voltage_swing = analogix_dp_get_adjust_request_voltage( + adjust_request, lane); + pre_emphasis = analogix_dp_get_adjust_request_pre_emphasis( + adjust_request, lane); + + if (DPCD_VOLTAGE_SWING_GET(training_lane) == + voltage_swing && + DPCD_PRE_EMPHASIS_GET(training_lane) == + pre_emphasis) + dp->link_train.cr_loop[lane]++; + + if (dp->link_train.cr_loop[lane] == MAX_CR_LOOP || + voltage_swing == VOLTAGE_LEVEL_3 || + pre_emphasis == PRE_EMPHASIS_LEVEL_3) { + dev_err(dp->dev, "CR Max reached (%d,%d,%d)\n", + dp->link_train.cr_loop[lane], + voltage_swing, pre_emphasis); + analogix_dp_reduce_link_rate(dp); + return -EIO; + } + } + } + + analogix_dp_get_adjust_training_lane(dp, adjust_request); + + for (lane = 0; lane < lane_count; lane++) + analogix_dp_set_lane_link_training(dp, + dp->link_train.training_lane[lane], lane); + + retval = analogix_dp_write_bytes_to_dpcd(dp, + DP_TRAINING_LANE0_SET, lane_count, + dp->link_train.training_lane); + if (retval) + return retval; + + return retval; +} + +static int analogix_dp_process_equalizer_training(struct analogix_dp_device *dp) +{ + int lane, lane_count, retval; + u32 reg; + u8 link_align, link_status[2], adjust_request[2]; + + usleep_range(400, 401); + + lane_count = dp->link_train.lane_count; + + retval = analogix_dp_read_bytes_from_dpcd(dp, + DP_LANE0_1_STATUS, 2, link_status); + if (retval) + return retval; + + if (analogix_dp_clock_recovery_ok(link_status, lane_count)) { + analogix_dp_reduce_link_rate(dp); + return -EIO; + } + + retval = analogix_dp_read_bytes_from_dpcd(dp, + DP_ADJUST_REQUEST_LANE0_1, 2, adjust_request); + if (retval) + return retval; + + retval = analogix_dp_read_byte_from_dpcd(dp, + DP_LANE_ALIGN_STATUS_UPDATED, &link_align); + if (retval) + return retval; + + analogix_dp_get_adjust_training_lane(dp, adjust_request); + + if (!analogix_dp_channel_eq_ok(link_status, link_align, lane_count)) { + /* traing pattern Set to Normal */ + analogix_dp_training_pattern_dis(dp); + + dev_info(dp->dev, "Link Training success!\n"); + + analogix_dp_get_link_bandwidth(dp, ®); + dp->link_train.link_rate = reg; + dev_dbg(dp->dev, "final bandwidth = %.2x\n", + dp->link_train.link_rate); + + analogix_dp_get_lane_count(dp, ®); + dp->link_train.lane_count = reg; + dev_dbg(dp->dev, "final lane count = %.2x\n", + dp->link_train.lane_count); + + /* set enhanced mode if available */ + analogix_dp_set_enhanced_mode(dp); + dp->link_train.lt_state = FINISHED; + + return 0; + } + + /* not all locked */ + dp->link_train.eq_loop++; + + if (dp->link_train.eq_loop > MAX_EQ_LOOP) { + dev_err(dp->dev, "EQ Max loop\n"); + analogix_dp_reduce_link_rate(dp); + return -EIO; + } + + for (lane = 0; lane < lane_count; lane++) + analogix_dp_set_lane_link_training(dp, + dp->link_train.training_lane[lane], lane); + + retval = analogix_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET, + lane_count, dp->link_train.training_lane); + + return retval; +} + +static void analogix_dp_get_max_rx_bandwidth(struct analogix_dp_device *dp, + u8 *bandwidth) +{ + u8 data; + + /* + * For DP rev.1.1, Maximum link rate of Main Link lanes + * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps + */ + analogix_dp_read_byte_from_dpcd(dp, DP_MAX_LINK_RATE, &data); + *bandwidth = data; +} + +static void analogix_dp_get_max_rx_lane_count(struct analogix_dp_device *dp, + u8 *lane_count) +{ + u8 data; + + /* + * For DP rev.1.1, Maximum number of Main Link lanes + * 0x01 = 1 lane, 0x02 = 2 lanes, 0x04 = 4 lanes + */ + analogix_dp_read_byte_from_dpcd(dp, DP_MAX_LANE_COUNT, &data); + *lane_count = DPCD_MAX_LANE_COUNT(data); +} + +static void analogix_dp_init_training(struct analogix_dp_device *dp, + enum link_lane_count_type max_lane, + enum link_rate_type max_rate) +{ + /* + * MACRO_RST must be applied after the PLL_LOCK to avoid + * the DP inter pair skew issue for at least 10 us + */ + analogix_dp_reset_macro(dp); + + /* Initialize by reading RX's DPCD */ + analogix_dp_get_max_rx_bandwidth(dp, &dp->link_train.link_rate); + analogix_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count); + + if ((dp->link_train.link_rate != LINK_RATE_1_62GBPS) && + (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) { + dev_err(dp->dev, "Rx Max Link Rate is abnormal :%x !\n", + dp->link_train.link_rate); + dp->link_train.link_rate = LINK_RATE_1_62GBPS; + } + + if (dp->link_train.lane_count == 0) { + dev_err(dp->dev, "Rx Max Lane count is abnormal :%x !\n", + dp->link_train.lane_count); + dp->link_train.lane_count = (u8)LANE_COUNT1; + } + + /* Setup TX lane count & rate */ + if (dp->link_train.lane_count > max_lane) + dp->link_train.lane_count = max_lane; + if (dp->link_train.link_rate > max_rate) + dp->link_train.link_rate = max_rate; + + /* All DP analog module power up */ + analogix_dp_set_analog_power_down(dp, POWER_ALL, 0); +} + +static int analogix_dp_sw_link_training(struct analogix_dp_device *dp) +{ + int retval = 0, training_finished = 0; + + dp->link_train.lt_state = START; + + /* Process here */ + while (!retval && !training_finished) { + switch (dp->link_train.lt_state) { + case START: + retval = analogix_dp_link_start(dp); + if (retval) + dev_err(dp->dev, "LT link start failed!\n"); + break; + case CLOCK_RECOVERY: + retval = analogix_dp_process_clock_recovery(dp); + if (retval) + dev_err(dp->dev, "LT CR failed!\n"); + break; + case EQUALIZER_TRAINING: + retval = analogix_dp_process_equalizer_training(dp); + if (retval) + dev_err(dp->dev, "LT EQ failed!\n"); + break; + case FINISHED: + training_finished = 1; + break; + case FAILED: + return -EREMOTEIO; + } + } + if (retval) + dev_err(dp->dev, "eDP link training failed (%d)\n", retval); + + return retval; +} + +static int analogix_dp_set_link_train(struct analogix_dp_device *dp, + u32 count, + u32 bwtype) +{ + int i; + int retval; + + for (i = 0; i < DP_TIMEOUT_LOOP_COUNT; i++) { + analogix_dp_init_training(dp, count, bwtype); + retval = analogix_dp_sw_link_training(dp); + if (retval == 0) + break; + + usleep_range(100, 110); + } + + return retval; +} + +static int analogix_dp_config_video(struct analogix_dp_device *dp) +{ + int retval = 0; + int timeout_loop = 0; + int done_count = 0; + + analogix_dp_config_video_slave_mode(dp); + + analogix_dp_set_video_color_format(dp); + + if (analogix_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) { + dev_err(dp->dev, "PLL is not locked yet.\n"); + return -EINVAL; + } + + for (;;) { + timeout_loop++; + if (analogix_dp_is_slave_video_stream_clock_on(dp) == 0) + break; + if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { + dev_err(dp->dev, "Timeout of video streamclk ok\n"); + return -ETIMEDOUT; + } + + usleep_range(1, 2); + } + + /* Set to use the register calculated M/N video */ + analogix_dp_set_video_cr_mn(dp, CALCULATED_M, 0, 0); + + /* For video bist, Video timing must be generated by register */ + analogix_dp_set_video_timing_mode(dp, VIDEO_TIMING_FROM_CAPTURE); + + /* Disable video mute */ + analogix_dp_enable_video_mute(dp, 0); + + /* Configure video slave mode */ + analogix_dp_enable_video_master(dp, 0); + + timeout_loop = 0; + + for (;;) { + timeout_loop++; + if (analogix_dp_is_video_stream_on(dp) == 0) { + done_count++; + if (done_count > 10) + break; + } else if (done_count) { + done_count = 0; + } + if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { + dev_err(dp->dev, "Timeout of video streamclk ok\n"); + return -ETIMEDOUT; + } + + usleep_range(1000, 1001); + } + + if (retval != 0) + dev_err(dp->dev, "Video stream is not detected!\n"); + + return retval; +} + +static void analogix_dp_enable_scramble(struct analogix_dp_device *dp, bool enable) +{ + u8 data; + + if (enable) { + analogix_dp_enable_scrambling(dp); + + analogix_dp_read_byte_from_dpcd(dp, + DP_TRAINING_PATTERN_SET, + &data); + analogix_dp_write_byte_to_dpcd(dp, + DP_TRAINING_PATTERN_SET, + (u8)(data & ~DP_LINK_SCRAMBLING_DISABLE)); + } else { + analogix_dp_disable_scrambling(dp); + + analogix_dp_read_byte_from_dpcd(dp, + DP_TRAINING_PATTERN_SET, + &data); + analogix_dp_write_byte_to_dpcd(dp, + DP_TRAINING_PATTERN_SET, + (u8)(data | DP_LINK_SCRAMBLING_DISABLE)); + } +} + +static irqreturn_t analogix_dp_irq_handler(int irq, void *arg) +{ + struct analogix_dp_device *dp = arg; + + enum dp_irq_type irq_type; + + irq_type = analogix_dp_get_irq_type(dp); + switch (irq_type) { + case DP_IRQ_TYPE_HP_CABLE_IN: + dev_dbg(dp->dev, "Received irq - cable in\n"); + schedule_work(&dp->hotplug_work); + analogix_dp_clear_hotplug_interrupts(dp); + break; + case DP_IRQ_TYPE_HP_CABLE_OUT: + dev_dbg(dp->dev, "Received irq - cable out\n"); + analogix_dp_clear_hotplug_interrupts(dp); + break; + case DP_IRQ_TYPE_HP_CHANGE: + /* + * We get these change notifications once in a while, but there + * is nothing we can do with them. Just ignore it for now and + * only handle cable changes. + */ + dev_dbg(dp->dev, "Received irq - hotplug change; ignoring.\n"); + analogix_dp_clear_hotplug_interrupts(dp); + break; + default: + dev_err(dp->dev, "Received irq - unknown type!\n"); + break; + } + return IRQ_HANDLED; +} + +static void analogix_dp_hotplug(struct work_struct *work) +{ + struct analogix_dp_device *dp; + + dp = container_of(work, struct analogix_dp_device, hotplug_work); + + if (dp->drm_dev) + drm_helper_hpd_irq_event(dp->drm_dev); +} + +static void analogix_dp_commit(struct analogix_dp_device *dp) +{ + int ret; + + /* Keep the panel disabled while we configure video */ + if (dp->plat_data->panel) { + if (drm_panel_disable(dp->plat_data->panel)) + DRM_ERROR("failed to disable the panel\n"); + } + + ret = analogix_dp_detect_hpd(dp); + if (ret) { + /* Cable has been disconnected, we're done */ + return; + } + + ret = analogix_dp_handle_edid(dp); + if (ret) { + dev_err(dp->dev, "unable to handle edid\n"); + return; + } + + ret = analogix_dp_set_link_train(dp, dp->video_info->lane_count, + dp->video_info->link_rate); + if (ret) { + dev_err(dp->dev, "unable to do link train\n"); + return; + } + + analogix_dp_enable_scramble(dp, 1); + analogix_dp_enable_rx_to_enhanced_mode(dp, 1); + analogix_dp_enable_enhanced_mode(dp, 1); + + analogix_dp_set_lane_count(dp, dp->video_info->lane_count); + analogix_dp_set_link_bandwidth(dp, dp->video_info->link_rate); + + analogix_dp_init_video(dp); + ret = analogix_dp_config_video(dp); + if (ret) + dev_err(dp->dev, "unable to config video\n"); + + /* Safe to enable the panel now */ + if (dp->plat_data->panel) { + if (drm_panel_enable(dp->plat_data->panel)) + DRM_ERROR("failed to enable the panel\n"); + } + + /* Enable video */ + analogix_dp_start_video(dp); +} + +int analogix_dp_get_modes(struct drm_connector *connector) +{ + struct analogix_dp_device *dp = to_dp(connector); + int num_modes = 0; + + if (dp->plat_data->panel) + num_modes += drm_panel_get_modes(dp->plat_data->panel); + + if (dp->plat_data->get_modes) + num_modes += dp->plat_data->get_modes(dp->plat_data); + + return num_modes; +} + +static struct drm_encoder * +analogix_dp_best_encoder(struct drm_connector *connector) +{ + struct analogix_dp_device *dp = to_dp(connector); + + return dp->encoder; +} + +static const struct drm_connector_helper_funcs analogix_dp_connector_helper_funcs = { + .get_modes = analogix_dp_get_modes, + .best_encoder = analogix_dp_best_encoder, +}; + +enum drm_connector_status +analogix_dp_detect(struct drm_connector *connector, bool force) +{ + return connector_status_connected; +} + +static void analogix_dp_connector_destroy(struct drm_connector *connector) +{ + drm_connector_unregister(connector); + drm_connector_cleanup(connector); +} + +static const struct drm_connector_funcs analogix_dp_connector_funcs = { + .dpms = drm_atomic_helper_connector_dpms, + .fill_modes = drm_helper_probe_single_connector_modes, + .detect = analogix_dp_detect, + .destroy = analogix_dp_connector_destroy, + .reset = drm_atomic_helper_connector_reset, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, +}; + +static int analogix_dp_bridge_attach(struct drm_bridge *bridge) +{ + struct analogix_dp_device *dp = bridge->driver_private; + struct drm_encoder *encoder = dp->encoder; + struct drm_connector *connector = &dp->connector; + int ret; + + if (!bridge->encoder) { + DRM_ERROR("Parent encoder object not found"); + return -ENODEV; + } + + connector->polled = DRM_CONNECTOR_POLL_HPD; + + ret = drm_connector_init(dp->drm_dev, connector, + &analogix_dp_connector_funcs, + DRM_MODE_CONNECTOR_eDP); + if (ret) { + DRM_ERROR("Failed to initialize connector with drm\n"); + return ret; + } + + drm_connector_helper_add(connector, + &analogix_dp_connector_helper_funcs); + drm_mode_connector_attach_encoder(connector, encoder); + + /* + * NOTE: the connector registration is implemented in analogix + * platform driver, that to say connector would be exist after + * plat_data->attch return, that's why we record the connector + * point after plat attached. + */ + if (dp->plat_data->attach) { + ret = dp->plat_data->attach(dp->plat_data, bridge, connector); + if (ret) { + DRM_ERROR("Failed at platform attch func\n"); + return ret; + } + } + + if (dp->plat_data->panel) { + ret = drm_panel_attach(dp->plat_data->panel, &dp->connector); + if (ret) { + DRM_ERROR("Failed to attach panel\n"); + return ret; + } + } + + return 0; +} + +static void analogix_dp_bridge_enable(struct drm_bridge *bridge) +{ + struct analogix_dp_device *dp = bridge->driver_private; + + if (dp->dpms_mode == DRM_MODE_DPMS_ON) + return; + + pm_runtime_get_sync(dp->dev); + + if (dp->plat_data->panel) { + if (drm_panel_prepare(dp->plat_data->panel)) { + DRM_ERROR("failed to setup the panel\n"); + return; + } + } + + if (dp->plat_data->power_on) + dp->plat_data->power_on(dp->plat_data); + + phy_power_on(dp->phy); + analogix_dp_init_dp(dp); + enable_irq(dp->irq); + analogix_dp_commit(dp); + + dp->dpms_mode = DRM_MODE_DPMS_ON; +} + +static void analogix_dp_bridge_disable(struct drm_bridge *bridge) +{ + struct analogix_dp_device *dp = bridge->driver_private; + + if (dp->dpms_mode != DRM_MODE_DPMS_ON) + return; + + if (dp->plat_data->panel) { + if (drm_panel_disable(dp->plat_data->panel)) { + DRM_ERROR("failed to disable the panel\n"); + return; + } + } + + disable_irq(dp->irq); + flush_work(&dp->hotplug_work); + phy_power_off(dp->phy); + + if (dp->plat_data->power_off) + dp->plat_data->power_off(dp->plat_data); + + if (dp->plat_data->panel) { + if (drm_panel_unprepare(dp->plat_data->panel)) + DRM_ERROR("failed to turnoff the panel\n"); + } + + pm_runtime_put_sync(dp->dev); + + dp->dpms_mode = DRM_MODE_DPMS_OFF; +} + +static void analogix_dp_bridge_nop(struct drm_bridge *bridge) +{ + /* do nothing */ +} + +static const struct drm_bridge_funcs analogix_dp_bridge_funcs = { + .enable = analogix_dp_bridge_enable, + .disable = analogix_dp_bridge_disable, + .pre_enable = analogix_dp_bridge_nop, + .post_disable = analogix_dp_bridge_nop, + .attach = analogix_dp_bridge_attach, +}; + +static int analogix_dp_create_bridge(struct drm_device *drm_dev, + struct analogix_dp_device *dp) +{ + struct drm_bridge *bridge; + int ret; + + bridge = devm_kzalloc(drm_dev->dev, sizeof(*bridge), GFP_KERNEL); + if (!bridge) { + DRM_ERROR("failed to allocate for drm bridge\n"); + return -ENOMEM; + } + + dp->bridge = bridge; + + dp->encoder->bridge = bridge; + bridge->driver_private = dp; + bridge->encoder = dp->encoder; + bridge->funcs = &analogix_dp_bridge_funcs; + + ret = drm_bridge_attach(drm_dev, bridge); + if (ret) { + DRM_ERROR("failed to attach drm bridge\n"); + return -EINVAL; + } + + return 0; +} + +static struct video_info *analogix_dp_dt_parse_pdata(struct device *dev) +{ + struct device_node *dp_node = dev->of_node; + struct video_info *dp_video_config; + + dp_video_config = devm_kzalloc(dev, + sizeof(*dp_video_config), GFP_KERNEL); + if (!dp_video_config) + return ERR_PTR(-ENOMEM); + + dp_video_config->h_sync_polarity = + of_property_read_bool(dp_node, "hsync-active-high"); + + dp_video_config->v_sync_polarity = + of_property_read_bool(dp_node, "vsync-active-high"); + + dp_video_config->interlaced = + of_property_read_bool(dp_node, "interlaced"); + + if (of_property_read_u32(dp_node, "samsung,color-space", + &dp_video_config->color_space)) { + dev_err(dev, "failed to get color-space\n"); + return ERR_PTR(-EINVAL); + } + + if (of_property_read_u32(dp_node, "samsung,dynamic-range", + &dp_video_config->dynamic_range)) { + dev_err(dev, "failed to get dynamic-range\n"); + return ERR_PTR(-EINVAL); + } + + if (of_property_read_u32(dp_node, "samsung,ycbcr-coeff", + &dp_video_config->ycbcr_coeff)) { + dev_err(dev, "failed to get ycbcr-coeff\n"); + return ERR_PTR(-EINVAL); + } + + if (of_property_read_u32(dp_node, "samsung,color-depth", + &dp_video_config->color_depth)) { + dev_err(dev, "failed to get color-depth\n"); + return ERR_PTR(-EINVAL); + } + + if (of_property_read_u32(dp_node, "samsung,link-rate", + &dp_video_config->link_rate)) { + dev_err(dev, "failed to get link-rate\n"); + return ERR_PTR(-EINVAL); + } + + if (of_property_read_u32(dp_node, "samsung,lane-count", + &dp_video_config->lane_count)) { + dev_err(dev, "failed to get lane-count\n"); + return ERR_PTR(-EINVAL); + } + + return dp_video_config; +} + +int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev, + struct analogix_dp_plat_data *plat_data) +{ + struct platform_device *pdev = to_platform_device(dev); + struct analogix_dp_device *dp; + struct resource *res; + unsigned int irq_flags; + int ret; + + if (!plat_data) { + dev_err(dev, "Invalided input plat_data\n"); + return -EINVAL; + } + + dp = devm_kzalloc(dev, sizeof(struct analogix_dp_device), GFP_KERNEL); + if (!dp) + return -ENOMEM; + + dev_set_drvdata(dev, dp); + + dp->dev = &pdev->dev; + dp->dpms_mode = DRM_MODE_DPMS_OFF; + + /* + * platform dp driver need containor_of the plat_data to get + * the driver private data, so we need to store the point of + * plat_data, not the context of plat_data. + */ + dp->plat_data = plat_data; + + dp->video_info = analogix_dp_dt_parse_pdata(&pdev->dev); + if (IS_ERR(dp->video_info)) + return PTR_ERR(dp->video_info); + + dp->phy = devm_phy_get(dp->dev, "dp"); + if (IS_ERR(dp->phy)) { + dev_err(dp->dev, "no DP phy configured\n"); + ret = PTR_ERR(dp->phy); + if (ret) { + /* + * phy itself is not enabled, so we can move forward + * assigning NULL to phy pointer. + */ + if (ret == -ENOSYS || ret == -ENODEV) + dp->phy = NULL; + else + return ret; + } + } + + dp->clock = devm_clk_get(&pdev->dev, "dp"); + if (IS_ERR(dp->clock)) { + dev_err(&pdev->dev, "failed to get clock\n"); + return PTR_ERR(dp->clock); + } + + clk_prepare_enable(dp->clock); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + dp->reg_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(dp->reg_base)) + return PTR_ERR(dp->reg_base); + + dp->hpd_gpio = of_get_named_gpio(dev->of_node, "hpd-gpios", 0); + if (!gpio_is_valid(dp->hpd_gpio)) + dp->hpd_gpio = of_get_named_gpio(dev->of_node, + "samsung,hpd-gpio", 0); + + if (gpio_is_valid(dp->hpd_gpio)) { + /* + * Set up the hotplug GPIO from the device tree as an interrupt. + * Simply specifying a different interrupt in the device tree + * doesn't work since we handle hotplug rather differently when + * using a GPIO. We also need the actual GPIO specifier so + * that we can get the current state of the GPIO. + */ + ret = devm_gpio_request_one(&pdev->dev, dp->hpd_gpio, GPIOF_IN, + "hpd_gpio"); + if (ret) { + dev_err(&pdev->dev, "failed to get hpd gpio\n"); + return ret; + } + dp->irq = gpio_to_irq(dp->hpd_gpio); + irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; + } else { + dp->hpd_gpio = -ENODEV; + dp->irq = platform_get_irq(pdev, 0); + irq_flags = 0; + } + + if (dp->irq == -ENXIO) { + dev_err(&pdev->dev, "failed to get irq\n"); + return -ENODEV; + } + + INIT_WORK(&dp->hotplug_work, analogix_dp_hotplug); + + pm_runtime_enable(dev); + + ret = devm_request_irq(&pdev->dev, dp->irq, analogix_dp_irq_handler, + irq_flags, "analogix-dp", dp); + if (ret) { + dev_err(&pdev->dev, "failed to request irq\n"); + goto err_disable_pm_runtime; + } + disable_irq(dp->irq); + + dp->drm_dev = drm_dev; + dp->encoder = dp->plat_data->encoder; + + ret = analogix_dp_create_bridge(drm_dev, dp); + if (ret) { + DRM_ERROR("failed to create bridge (%d)\n", ret); + drm_encoder_cleanup(dp->encoder); + goto err_disable_pm_runtime; + } + + return 0; + +err_disable_pm_runtime: + pm_runtime_disable(dev); + + return ret; +} +EXPORT_SYMBOL_GPL(analogix_dp_bind); + +void analogix_dp_unbind(struct device *dev, struct device *master, + void *data) +{ + struct analogix_dp_device *dp = dev_get_drvdata(dev); + + analogix_dp_bridge_disable(dp->bridge); + pm_runtime_disable(dev); +} +EXPORT_SYMBOL_GPL(analogix_dp_unbind); + +#ifdef CONFIG_PM +int analogix_dp_suspend(struct device *dev) +{ + struct analogix_dp_device *dp = dev_get_drvdata(dev); + + clk_disable_unprepare(dp->clock); + return 0; +} +EXPORT_SYMBOL_GPL(analogix_dp_suspend); + +int analogix_dp_resume(struct device *dev) +{ + struct analogix_dp_device *dp = dev_get_drvdata(dev); + int ret; + + ret = clk_prepare_enable(dp->clock); + if (ret < 0) { + DRM_ERROR("Failed to prepare_enable the clock clk [%d]\n", ret); + return ret; + } + + return 0; +} +EXPORT_SYMBOL_GPL(analogix_dp_resume); +#endif + +MODULE_AUTHOR("Jingoo Han "); +MODULE_DESCRIPTION("Analogix DP Core Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h new file mode 100644 index 000000000000..0fff7451e3df --- /dev/null +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h @@ -0,0 +1,277 @@ +/* + * Header file for Analogix DP (Display Port) core interface driver. + * + * Copyright (C) 2012 Samsung Electronics Co., Ltd. + * Author: Jingoo Han + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef _ANALOGIX_DP_CORE_H +#define _ANALOGIX_DP_CORE_H + +#include +#include + +#define DP_TIMEOUT_LOOP_COUNT 100 +#define MAX_CR_LOOP 5 +#define MAX_EQ_LOOP 5 + +enum link_rate_type { + LINK_RATE_1_62GBPS = 0x06, + LINK_RATE_2_70GBPS = 0x0a +}; + +enum link_lane_count_type { + LANE_COUNT1 = 1, + LANE_COUNT2 = 2, + LANE_COUNT4 = 4 +}; + +enum link_training_state { + START, + CLOCK_RECOVERY, + EQUALIZER_TRAINING, + FINISHED, + FAILED +}; + +enum voltage_swing_level { + VOLTAGE_LEVEL_0, + VOLTAGE_LEVEL_1, + VOLTAGE_LEVEL_2, + VOLTAGE_LEVEL_3, +}; + +enum pre_emphasis_level { + PRE_EMPHASIS_LEVEL_0, + PRE_EMPHASIS_LEVEL_1, + PRE_EMPHASIS_LEVEL_2, + PRE_EMPHASIS_LEVEL_3, +}; + +enum pattern_set { + PRBS7, + D10_2, + TRAINING_PTN1, + TRAINING_PTN2, + DP_NONE +}; + +enum color_space { + COLOR_RGB, + COLOR_YCBCR422, + COLOR_YCBCR444 +}; + +enum color_depth { + COLOR_6, + COLOR_8, + COLOR_10, + COLOR_12 +}; + +enum color_coefficient { + COLOR_YCBCR601, + COLOR_YCBCR709 +}; + +enum dynamic_range { + VESA, + CEA +}; + +enum pll_status { + PLL_UNLOCKED, + PLL_LOCKED +}; + +enum clock_recovery_m_value_type { + CALCULATED_M, + REGISTER_M +}; + +enum video_timing_recognition_type { + VIDEO_TIMING_FROM_CAPTURE, + VIDEO_TIMING_FROM_REGISTER +}; + +enum analog_power_block { + AUX_BLOCK, + CH0_BLOCK, + CH1_BLOCK, + CH2_BLOCK, + CH3_BLOCK, + ANALOG_TOTAL, + POWER_ALL +}; + +enum dp_irq_type { + DP_IRQ_TYPE_HP_CABLE_IN, + DP_IRQ_TYPE_HP_CABLE_OUT, + DP_IRQ_TYPE_HP_CHANGE, + DP_IRQ_TYPE_UNKNOWN, +}; + +struct video_info { + char *name; + + bool h_sync_polarity; + bool v_sync_polarity; + bool interlaced; + + enum color_space color_space; + enum dynamic_range dynamic_range; + enum color_coefficient ycbcr_coeff; + enum color_depth color_depth; + + enum link_rate_type link_rate; + enum link_lane_count_type lane_count; +}; + +struct link_train { + int eq_loop; + int cr_loop[4]; + + u8 link_rate; + u8 lane_count; + u8 training_lane[4]; + + enum link_training_state lt_state; +}; + +struct analogix_dp_device { + struct drm_encoder *encoder; + struct device *dev; + struct drm_device *drm_dev; + struct drm_connector connector; + struct drm_bridge *bridge; + struct clk *clock; + unsigned int irq; + void __iomem *reg_base; + + struct video_info *video_info; + struct link_train link_train; + struct work_struct hotplug_work; + struct phy *phy; + int dpms_mode; + int hpd_gpio; + + struct analogix_dp_plat_data *plat_data; +}; + +/* analogix_dp_reg.c */ +void analogix_dp_enable_video_mute(struct analogix_dp_device *dp, bool enable); +void analogix_dp_stop_video(struct analogix_dp_device *dp); +void analogix_dp_lane_swap(struct analogix_dp_device *dp, bool enable); +void analogix_dp_init_analog_param(struct analogix_dp_device *dp); +void analogix_dp_init_interrupt(struct analogix_dp_device *dp); +void analogix_dp_reset(struct analogix_dp_device *dp); +void analogix_dp_swreset(struct analogix_dp_device *dp); +void analogix_dp_config_interrupt(struct analogix_dp_device *dp); +enum pll_status analogix_dp_get_pll_lock_status(struct analogix_dp_device *dp); +void analogix_dp_set_pll_power_down(struct analogix_dp_device *dp, bool enable); +void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp, + enum analog_power_block block, + bool enable); +void analogix_dp_init_analog_func(struct analogix_dp_device *dp); +void analogix_dp_init_hpd(struct analogix_dp_device *dp); +enum dp_irq_type analogix_dp_get_irq_type(struct analogix_dp_device *dp); +void analogix_dp_clear_hotplug_interrupts(struct analogix_dp_device *dp); +void analogix_dp_reset_aux(struct analogix_dp_device *dp); +void analogix_dp_init_aux(struct analogix_dp_device *dp); +int analogix_dp_get_plug_in_status(struct analogix_dp_device *dp); +void analogix_dp_enable_sw_function(struct analogix_dp_device *dp); +int analogix_dp_start_aux_transaction(struct analogix_dp_device *dp); +int analogix_dp_write_byte_to_dpcd(struct analogix_dp_device *dp, + unsigned int reg_addr, + unsigned char data); +int analogix_dp_read_byte_from_dpcd(struct analogix_dp_device *dp, + unsigned int reg_addr, + unsigned char *data); +int analogix_dp_write_bytes_to_dpcd(struct analogix_dp_device *dp, + unsigned int reg_addr, + unsigned int count, + unsigned char data[]); +int analogix_dp_read_bytes_from_dpcd(struct analogix_dp_device *dp, + unsigned int reg_addr, + unsigned int count, + unsigned char data[]); +int analogix_dp_select_i2c_device(struct analogix_dp_device *dp, + unsigned int device_addr, + unsigned int reg_addr); +int analogix_dp_read_byte_from_i2c(struct analogix_dp_device *dp, + unsigned int device_addr, + unsigned int reg_addr, + unsigned int *data); +int analogix_dp_read_bytes_from_i2c(struct analogix_dp_device *dp, + unsigned int device_addr, + unsigned int reg_addr, + unsigned int count, + unsigned char edid[]); +void analogix_dp_set_link_bandwidth(struct analogix_dp_device *dp, u32 bwtype); +void analogix_dp_get_link_bandwidth(struct analogix_dp_device *dp, u32 *bwtype); +void analogix_dp_set_lane_count(struct analogix_dp_device *dp, u32 count); +void analogix_dp_get_lane_count(struct analogix_dp_device *dp, u32 *count); +void analogix_dp_enable_enhanced_mode(struct analogix_dp_device *dp, bool enable); +void analogix_dp_set_training_pattern(struct analogix_dp_device *dp, + enum pattern_set pattern); +void analogix_dp_set_lane0_pre_emphasis(struct analogix_dp_device *dp, u32 level); +void analogix_dp_set_lane1_pre_emphasis(struct analogix_dp_device *dp, u32 level); +void analogix_dp_set_lane2_pre_emphasis(struct analogix_dp_device *dp, u32 level); +void analogix_dp_set_lane3_pre_emphasis(struct analogix_dp_device *dp, u32 level); +void analogix_dp_set_lane0_link_training(struct analogix_dp_device *dp, + u32 training_lane); +void analogix_dp_set_lane1_link_training(struct analogix_dp_device *dp, + u32 training_lane); +void analogix_dp_set_lane2_link_training(struct analogix_dp_device *dp, + u32 training_lane); +void analogix_dp_set_lane3_link_training(struct analogix_dp_device *dp, + u32 training_lane); +u32 analogix_dp_get_lane0_link_training(struct analogix_dp_device *dp); +u32 analogix_dp_get_lane1_link_training(struct analogix_dp_device *dp); +u32 analogix_dp_get_lane2_link_training(struct analogix_dp_device *dp); +u32 analogix_dp_get_lane3_link_training(struct analogix_dp_device *dp); +void analogix_dp_reset_macro(struct analogix_dp_device *dp); +void analogix_dp_init_video(struct analogix_dp_device *dp); + +void analogix_dp_set_video_color_format(struct analogix_dp_device *dp); +int analogix_dp_is_slave_video_stream_clock_on(struct analogix_dp_device *dp); +void analogix_dp_set_video_cr_mn(struct analogix_dp_device *dp, + enum clock_recovery_m_value_type type, + u32 m_value, + u32 n_value); +void analogix_dp_set_video_timing_mode(struct analogix_dp_device *dp, u32 type); +void analogix_dp_enable_video_master(struct analogix_dp_device *dp, bool enable); +void analogix_dp_start_video(struct analogix_dp_device *dp); +int analogix_dp_is_video_stream_on(struct analogix_dp_device *dp); +void analogix_dp_config_video_slave_mode(struct analogix_dp_device *dp); +void analogix_dp_enable_scrambling(struct analogix_dp_device *dp); +void analogix_dp_disable_scrambling(struct analogix_dp_device *dp); + +/* I2C EDID Chip ID, Slave Address */ +#define I2C_EDID_DEVICE_ADDR 0x50 +#define I2C_E_EDID_DEVICE_ADDR 0x30 + +#define EDID_BLOCK_LENGTH 0x80 +#define EDID_HEADER_PATTERN 0x00 +#define EDID_EXTENSION_FLAG 0x7e +#define EDID_CHECKSUM 0x7f + +/* DP_MAX_LANE_COUNT */ +#define DPCD_ENHANCED_FRAME_CAP(x) (((x) >> 7) & 0x1) +#define DPCD_MAX_LANE_COUNT(x) ((x) & 0x1f) + +/* DP_LANE_COUNT_SET */ +#define DPCD_LANE_COUNT_SET(x) ((x) & 0x1f) + +/* DP_TRAINING_LANE0_SET */ +#define DPCD_PRE_EMPHASIS_SET(x) (((x) & 0x3) << 3) +#define DPCD_PRE_EMPHASIS_GET(x) (((x) >> 3) & 0x3) +#define DPCD_VOLTAGE_SWING_SET(x) (((x) & 0x3) << 0) +#define DPCD_VOLTAGE_SWING_GET(x) (((x) >> 0) & 0x3) + +#endif /* _ANALOGIX_DP_CORE_H */ diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c new file mode 100644 index 000000000000..0b926ea38a22 --- /dev/null +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c @@ -0,0 +1,1263 @@ +/* + * Analogix DP (Display port) core register interface driver. + * + * Copyright (C) 2012 Samsung Electronics Co., Ltd. + * Author: Jingoo Han + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include + +#include "analogix_dp_core.h" +#include "analogix_dp_reg.h" + +#define COMMON_INT_MASK_1 0 +#define COMMON_INT_MASK_2 0 +#define COMMON_INT_MASK_3 0 +#define COMMON_INT_MASK_4 (HOTPLUG_CHG | HPD_LOST | PLUG) +#define INT_STA_MASK INT_HPD + +void analogix_dp_enable_video_mute(struct analogix_dp_device *dp, bool enable) +{ + u32 reg; + + if (enable) { + reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); + reg |= HDCP_VIDEO_MUTE; + writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); + } else { + reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); + reg &= ~HDCP_VIDEO_MUTE; + writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); + } +} + +void analogix_dp_stop_video(struct analogix_dp_device *dp) +{ + u32 reg; + + reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); + reg &= ~VIDEO_EN; + writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); +} + +void analogix_dp_lane_swap(struct analogix_dp_device *dp, bool enable) +{ + u32 reg; + + if (enable) + reg = LANE3_MAP_LOGIC_LANE_0 | LANE2_MAP_LOGIC_LANE_1 | + LANE1_MAP_LOGIC_LANE_2 | LANE0_MAP_LOGIC_LANE_3; + else + reg = LANE3_MAP_LOGIC_LANE_3 | LANE2_MAP_LOGIC_LANE_2 | + LANE1_MAP_LOGIC_LANE_1 | LANE0_MAP_LOGIC_LANE_0; + + writel(reg, dp->reg_base + EXYNOS_DP_LANE_MAP); +} + +void analogix_dp_init_analog_param(struct analogix_dp_device *dp) +{ + u32 reg; + + reg = TX_TERMINAL_CTRL_50_OHM; + writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_1); + + reg = SEL_24M | TX_DVDD_BIT_1_0625V; + writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_2); + + reg = DRIVE_DVDD_BIT_1_0625V | VCO_BIT_600_MICRO; + writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_3); + + reg = PD_RING_OSC | AUX_TERMINAL_CTRL_50_OHM | + TX_CUR1_2X | TX_CUR_16_MA; + writel(reg, dp->reg_base + EXYNOS_DP_PLL_FILTER_CTL_1); + + reg = CH3_AMP_400_MV | CH2_AMP_400_MV | + CH1_AMP_400_MV | CH0_AMP_400_MV; + writel(reg, dp->reg_base + EXYNOS_DP_TX_AMP_TUNING_CTL); +} + +void analogix_dp_init_interrupt(struct analogix_dp_device *dp) +{ + /* Set interrupt pin assertion polarity as high */ + writel(INT_POL1 | INT_POL0, dp->reg_base + EXYNOS_DP_INT_CTL); + + /* Clear pending regisers */ + writel(0xff, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1); + writel(0x4f, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_2); + writel(0xe0, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_3); + writel(0xe7, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4); + writel(0x63, dp->reg_base + EXYNOS_DP_INT_STA); + + /* 0:mask,1: unmask */ + writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_1); + writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_2); + writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_3); + writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_4); + writel(0x00, dp->reg_base + EXYNOS_DP_INT_STA_MASK); +} + +void analogix_dp_reset(struct analogix_dp_device *dp) +{ + u32 reg; + + analogix_dp_stop_video(dp); + analogix_dp_enable_video_mute(dp, 0); + + reg = MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N | + AUD_FIFO_FUNC_EN_N | AUD_FUNC_EN_N | + HDCP_FUNC_EN_N | SW_FUNC_EN_N; + writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1); + + reg = SSC_FUNC_EN_N | AUX_FUNC_EN_N | + SERDES_FIFO_FUNC_EN_N | + LS_CLK_DOMAIN_FUNC_EN_N; + writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2); + + usleep_range(20, 30); + + analogix_dp_lane_swap(dp, 0); + + writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_1); + writel(0x40, dp->reg_base + EXYNOS_DP_SYS_CTL_2); + writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_3); + writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_4); + + writel(0x0, dp->reg_base + EXYNOS_DP_PKT_SEND_CTL); + writel(0x0, dp->reg_base + EXYNOS_DP_HDCP_CTL); + + writel(0x5e, dp->reg_base + EXYNOS_DP_HPD_DEGLITCH_L); + writel(0x1a, dp->reg_base + EXYNOS_DP_HPD_DEGLITCH_H); + + writel(0x10, dp->reg_base + EXYNOS_DP_LINK_DEBUG_CTL); + + writel(0x0, dp->reg_base + EXYNOS_DP_PHY_TEST); + + writel(0x0, dp->reg_base + EXYNOS_DP_VIDEO_FIFO_THRD); + writel(0x20, dp->reg_base + EXYNOS_DP_AUDIO_MARGIN); + + writel(0x4, dp->reg_base + EXYNOS_DP_M_VID_GEN_FILTER_TH); + writel(0x2, dp->reg_base + EXYNOS_DP_M_AUD_GEN_FILTER_TH); + + writel(0x00000101, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); +} + +void analogix_dp_swreset(struct analogix_dp_device *dp) +{ + writel(RESET_DP_TX, dp->reg_base + EXYNOS_DP_TX_SW_RESET); +} + +void analogix_dp_config_interrupt(struct analogix_dp_device *dp) +{ + u32 reg; + + /* 0: mask, 1: unmask */ + reg = COMMON_INT_MASK_1; + writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_1); + + reg = COMMON_INT_MASK_2; + writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_2); + + reg = COMMON_INT_MASK_3; + writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_3); + + reg = COMMON_INT_MASK_4; + writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_4); + + reg = INT_STA_MASK; + writel(reg, dp->reg_base + EXYNOS_DP_INT_STA_MASK); +} + +enum pll_status analogix_dp_get_pll_lock_status(struct analogix_dp_device *dp) +{ + u32 reg; + + reg = readl(dp->reg_base + EXYNOS_DP_DEBUG_CTL); + if (reg & PLL_LOCK) + return PLL_LOCKED; + else + return PLL_UNLOCKED; +} + +void analogix_dp_set_pll_power_down(struct analogix_dp_device *dp, bool enable) +{ + u32 reg; + + if (enable) { + reg = readl(dp->reg_base + EXYNOS_DP_PLL_CTL); + reg |= DP_PLL_PD; + writel(reg, dp->reg_base + EXYNOS_DP_PLL_CTL); + } else { + reg = readl(dp->reg_base + EXYNOS_DP_PLL_CTL); + reg &= ~DP_PLL_PD; + writel(reg, dp->reg_base + EXYNOS_DP_PLL_CTL); + } +} + +void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp, + enum analog_power_block block, + bool enable) +{ + u32 reg; + + switch (block) { + case AUX_BLOCK: + if (enable) { + reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); + reg |= AUX_PD; + writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); + } else { + reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); + reg &= ~AUX_PD; + writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); + } + break; + case CH0_BLOCK: + if (enable) { + reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); + reg |= CH0_PD; + writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); + } else { + reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); + reg &= ~CH0_PD; + writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); + } + break; + case CH1_BLOCK: + if (enable) { + reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); + reg |= CH1_PD; + writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); + } else { + reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); + reg &= ~CH1_PD; + writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); + } + break; + case CH2_BLOCK: + if (enable) { + reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); + reg |= CH2_PD; + writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); + } else { + reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); + reg &= ~CH2_PD; + writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); + } + break; + case CH3_BLOCK: + if (enable) { + reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); + reg |= CH3_PD; + writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); + } else { + reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); + reg &= ~CH3_PD; + writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); + } + break; + case ANALOG_TOTAL: + if (enable) { + reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); + reg |= DP_PHY_PD; + writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); + } else { + reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); + reg &= ~DP_PHY_PD; + writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); + } + break; + case POWER_ALL: + if (enable) { + reg = DP_PHY_PD | AUX_PD | CH3_PD | CH2_PD | + CH1_PD | CH0_PD; + writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); + } else { + writel(0x00, dp->reg_base + EXYNOS_DP_PHY_PD); + } + break; + default: + break; + } +} + +void analogix_dp_init_analog_func(struct analogix_dp_device *dp) +{ + u32 reg; + int timeout_loop = 0; + + analogix_dp_set_analog_power_down(dp, POWER_ALL, 0); + + reg = PLL_LOCK_CHG; + writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1); + + reg = readl(dp->reg_base + EXYNOS_DP_DEBUG_CTL); + reg &= ~(F_PLL_LOCK | PLL_LOCK_CTRL); + writel(reg, dp->reg_base + EXYNOS_DP_DEBUG_CTL); + + /* Power up PLL */ + if (analogix_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) { + analogix_dp_set_pll_power_down(dp, 0); + + while (analogix_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) { + timeout_loop++; + if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { + dev_err(dp->dev, "failed to get pll lock status\n"); + return; + } + usleep_range(10, 20); + } + } + + /* Enable Serdes FIFO function and Link symbol clock domain module */ + reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2); + reg &= ~(SERDES_FIFO_FUNC_EN_N | LS_CLK_DOMAIN_FUNC_EN_N + | AUX_FUNC_EN_N); + writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2); +} + +void analogix_dp_clear_hotplug_interrupts(struct analogix_dp_device *dp) +{ + u32 reg; + + if (gpio_is_valid(dp->hpd_gpio)) + return; + + reg = HOTPLUG_CHG | HPD_LOST | PLUG; + writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4); + + reg = INT_HPD; + writel(reg, dp->reg_base + EXYNOS_DP_INT_STA); +} + +void analogix_dp_init_hpd(struct analogix_dp_device *dp) +{ + u32 reg; + + if (gpio_is_valid(dp->hpd_gpio)) + return; + + analogix_dp_clear_hotplug_interrupts(dp); + + reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3); + reg &= ~(F_HPD | HPD_CTRL); + writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3); +} + +enum dp_irq_type analogix_dp_get_irq_type(struct analogix_dp_device *dp) +{ + u32 reg; + + if (gpio_is_valid(dp->hpd_gpio)) { + reg = gpio_get_value(dp->hpd_gpio); + if (reg) + return DP_IRQ_TYPE_HP_CABLE_IN; + else + return DP_IRQ_TYPE_HP_CABLE_OUT; + } else { + /* Parse hotplug interrupt status register */ + reg = readl(dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4); + + if (reg & PLUG) + return DP_IRQ_TYPE_HP_CABLE_IN; + + if (reg & HPD_LOST) + return DP_IRQ_TYPE_HP_CABLE_OUT; + + if (reg & HOTPLUG_CHG) + return DP_IRQ_TYPE_HP_CHANGE; + + return DP_IRQ_TYPE_UNKNOWN; + } +} + +void analogix_dp_reset_aux(struct analogix_dp_device *dp) +{ + u32 reg; + + /* Disable AUX channel module */ + reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2); + reg |= AUX_FUNC_EN_N; + writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2); +} + +void analogix_dp_init_aux(struct analogix_dp_device *dp) +{ + u32 reg; + + /* Clear inerrupts related to AUX channel */ + reg = RPLY_RECEIV | AUX_ERR; + writel(reg, dp->reg_base + EXYNOS_DP_INT_STA); + + analogix_dp_reset_aux(dp); + + /* Disable AUX transaction H/W retry */ + reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0)| + AUX_HW_RETRY_INTERVAL_600_MICROSECONDS; + writel(reg, dp->reg_base + EXYNOS_DP_AUX_HW_RETRY_CTL); + + /* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */ + reg = DEFER_CTRL_EN | DEFER_COUNT(1); + writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_DEFER_CTL); + + /* Enable AUX channel module */ + reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2); + reg &= ~AUX_FUNC_EN_N; + writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2); +} + +int analogix_dp_get_plug_in_status(struct analogix_dp_device *dp) +{ + u32 reg; + + if (gpio_is_valid(dp->hpd_gpio)) { + if (gpio_get_value(dp->hpd_gpio)) + return 0; + } else { + reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3); + if (reg & HPD_STATUS) + return 0; + } + + return -EINVAL; +} + +void analogix_dp_enable_sw_function(struct analogix_dp_device *dp) +{ + u32 reg; + + reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_1); + reg &= ~SW_FUNC_EN_N; + writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1); +} + +int analogix_dp_start_aux_transaction(struct analogix_dp_device *dp) +{ + int reg; + int retval = 0; + int timeout_loop = 0; + + /* Enable AUX CH operation */ + reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2); + reg |= AUX_EN; + writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2); + + /* Is AUX CH command reply received? */ + reg = readl(dp->reg_base + EXYNOS_DP_INT_STA); + while (!(reg & RPLY_RECEIV)) { + timeout_loop++; + if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { + dev_err(dp->dev, "AUX CH command reply failed!\n"); + return -ETIMEDOUT; + } + reg = readl(dp->reg_base + EXYNOS_DP_INT_STA); + usleep_range(10, 11); + } + + /* Clear interrupt source for AUX CH command reply */ + writel(RPLY_RECEIV, dp->reg_base + EXYNOS_DP_INT_STA); + + /* Clear interrupt source for AUX CH access error */ + reg = readl(dp->reg_base + EXYNOS_DP_INT_STA); + if (reg & AUX_ERR) { + writel(AUX_ERR, dp->reg_base + EXYNOS_DP_INT_STA); + return -EREMOTEIO; + } + + /* Check AUX CH error access status */ + reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_STA); + if ((reg & AUX_STATUS_MASK) != 0) { + dev_err(dp->dev, "AUX CH error happens: %d\n\n", + reg & AUX_STATUS_MASK); + return -EREMOTEIO; + } + + return retval; +} + +int analogix_dp_write_byte_to_dpcd(struct analogix_dp_device *dp, + unsigned int reg_addr, + unsigned char data) +{ + u32 reg; + int i; + int retval; + + for (i = 0; i < 3; i++) { + /* Clear AUX CH data buffer */ + reg = BUF_CLR; + writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); + + /* Select DPCD device address */ + reg = AUX_ADDR_7_0(reg_addr); + writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); + reg = AUX_ADDR_15_8(reg_addr); + writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8); + reg = AUX_ADDR_19_16(reg_addr); + writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16); + + /* Write data buffer */ + reg = (unsigned int)data; + writel(reg, dp->reg_base + EXYNOS_DP_BUF_DATA_0); + + /* + * Set DisplayPort transaction and write 1 byte + * If bit 3 is 1, DisplayPort transaction. + * If Bit 3 is 0, I2C transaction. + */ + reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE; + writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); + + /* Start AUX transaction */ + retval = analogix_dp_start_aux_transaction(dp); + if (retval == 0) + break; + else + dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", + __func__); + } + + return retval; +} + +int analogix_dp_read_byte_from_dpcd(struct analogix_dp_device *dp, + unsigned int reg_addr, + unsigned char *data) +{ + u32 reg; + int i; + int retval; + + for (i = 0; i < 3; i++) { + /* Clear AUX CH data buffer */ + reg = BUF_CLR; + writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); + + /* Select DPCD device address */ + reg = AUX_ADDR_7_0(reg_addr); + writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); + reg = AUX_ADDR_15_8(reg_addr); + writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8); + reg = AUX_ADDR_19_16(reg_addr); + writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16); + + /* + * Set DisplayPort transaction and read 1 byte + * If bit 3 is 1, DisplayPort transaction. + * If Bit 3 is 0, I2C transaction. + */ + reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ; + writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); + + /* Start AUX transaction */ + retval = analogix_dp_start_aux_transaction(dp); + if (retval == 0) + break; + else + dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", + __func__); + } + + /* Read data buffer */ + reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0); + *data = (unsigned char)(reg & 0xff); + + return retval; +} + +int analogix_dp_write_bytes_to_dpcd(struct analogix_dp_device *dp, + unsigned int reg_addr, + unsigned int count, + unsigned char data[]) +{ + u32 reg; + unsigned int start_offset; + unsigned int cur_data_count; + unsigned int cur_data_idx; + int i; + int retval = 0; + + /* Clear AUX CH data buffer */ + reg = BUF_CLR; + writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); + + start_offset = 0; + while (start_offset < count) { + /* Buffer size of AUX CH is 16 * 4bytes */ + if ((count - start_offset) > 16) + cur_data_count = 16; + else + cur_data_count = count - start_offset; + + for (i = 0; i < 3; i++) { + /* Select DPCD device address */ + reg = AUX_ADDR_7_0(reg_addr + start_offset); + writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); + reg = AUX_ADDR_15_8(reg_addr + start_offset); + writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8); + reg = AUX_ADDR_19_16(reg_addr + start_offset); + writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16); + + for (cur_data_idx = 0; cur_data_idx < cur_data_count; + cur_data_idx++) { + reg = data[start_offset + cur_data_idx]; + writel(reg, dp->reg_base + EXYNOS_DP_BUF_DATA_0 + + 4 * cur_data_idx); + } + + /* + * Set DisplayPort transaction and write + * If bit 3 is 1, DisplayPort transaction. + * If Bit 3 is 0, I2C transaction. + */ + reg = AUX_LENGTH(cur_data_count) | + AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE; + writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); + + /* Start AUX transaction */ + retval = analogix_dp_start_aux_transaction(dp); + if (retval == 0) + break; + else + dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", + __func__); + } + + start_offset += cur_data_count; + } + + return retval; +} + +int analogix_dp_read_bytes_from_dpcd(struct analogix_dp_device *dp, + unsigned int reg_addr, + unsigned int count, + unsigned char data[]) +{ + u32 reg; + unsigned int start_offset; + unsigned int cur_data_count; + unsigned int cur_data_idx; + int i; + int retval = 0; + + /* Clear AUX CH data buffer */ + reg = BUF_CLR; + writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); + + start_offset = 0; + while (start_offset < count) { + /* Buffer size of AUX CH is 16 * 4bytes */ + if ((count - start_offset) > 16) + cur_data_count = 16; + else + cur_data_count = count - start_offset; + + /* AUX CH Request Transaction process */ + for (i = 0; i < 3; i++) { + /* Select DPCD device address */ + reg = AUX_ADDR_7_0(reg_addr + start_offset); + writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); + reg = AUX_ADDR_15_8(reg_addr + start_offset); + writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8); + reg = AUX_ADDR_19_16(reg_addr + start_offset); + writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16); + + /* + * Set DisplayPort transaction and read + * If bit 3 is 1, DisplayPort transaction. + * If Bit 3 is 0, I2C transaction. + */ + reg = AUX_LENGTH(cur_data_count) | + AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ; + writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); + + /* Start AUX transaction */ + retval = analogix_dp_start_aux_transaction(dp); + if (retval == 0) + break; + else + dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", + __func__); + } + + for (cur_data_idx = 0; cur_data_idx < cur_data_count; + cur_data_idx++) { + reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0 + + 4 * cur_data_idx); + data[start_offset + cur_data_idx] = + (unsigned char)reg; + } + + start_offset += cur_data_count; + } + + return retval; +} + +int analogix_dp_select_i2c_device(struct analogix_dp_device *dp, + unsigned int device_addr, + unsigned int reg_addr) +{ + u32 reg; + int retval; + + /* Set EDID device address */ + reg = device_addr; + writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); + writel(0x0, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8); + writel(0x0, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16); + + /* Set offset from base address of EDID device */ + writel(reg_addr, dp->reg_base + EXYNOS_DP_BUF_DATA_0); + + /* + * Set I2C transaction and write address + * If bit 3 is 1, DisplayPort transaction. + * If Bit 3 is 0, I2C transaction. + */ + reg = AUX_TX_COMM_I2C_TRANSACTION | AUX_TX_COMM_MOT | + AUX_TX_COMM_WRITE; + writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); + + /* Start AUX transaction */ + retval = analogix_dp_start_aux_transaction(dp); + if (retval != 0) + dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__); + + return retval; +} + +int analogix_dp_read_byte_from_i2c(struct analogix_dp_device *dp, + unsigned int device_addr, + unsigned int reg_addr, + unsigned int *data) +{ + u32 reg; + int i; + int retval; + + for (i = 0; i < 3; i++) { + /* Clear AUX CH data buffer */ + reg = BUF_CLR; + writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); + + /* Select EDID device */ + retval = analogix_dp_select_i2c_device(dp, device_addr, reg_addr); + if (retval != 0) + continue; + + /* + * Set I2C transaction and read data + * If bit 3 is 1, DisplayPort transaction. + * If Bit 3 is 0, I2C transaction. + */ + reg = AUX_TX_COMM_I2C_TRANSACTION | + AUX_TX_COMM_READ; + writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); + + /* Start AUX transaction */ + retval = analogix_dp_start_aux_transaction(dp); + if (retval == 0) + break; + else + dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", + __func__); + } + + /* Read data */ + if (retval == 0) + *data = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0); + + return retval; +} + +int analogix_dp_read_bytes_from_i2c(struct analogix_dp_device *dp, + unsigned int device_addr, + unsigned int reg_addr, + unsigned int count, + unsigned char edid[]) +{ + u32 reg; + unsigned int i, j; + unsigned int cur_data_idx; + unsigned int defer = 0; + int retval = 0; + + for (i = 0; i < count; i += 16) { + for (j = 0; j < 3; j++) { + /* Clear AUX CH data buffer */ + reg = BUF_CLR; + writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); + + /* Set normal AUX CH command */ + reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2); + reg &= ~ADDR_ONLY; + writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2); + + /* + * If Rx sends defer, Tx sends only reads + * request without sending address + */ + if (!defer) + retval = analogix_dp_select_i2c_device(dp, + device_addr, reg_addr + i); + else + defer = 0; + + if (retval == 0) { + /* + * Set I2C transaction and write data + * If bit 3 is 1, DisplayPort transaction. + * If Bit 3 is 0, I2C transaction. + */ + reg = AUX_LENGTH(16) | + AUX_TX_COMM_I2C_TRANSACTION | + AUX_TX_COMM_READ; + writel(reg, dp->reg_base + + EXYNOS_DP_AUX_CH_CTL_1); + + /* Start AUX transaction */ + retval = analogix_dp_start_aux_transaction(dp); + if (retval == 0) + break; + else + dev_dbg(dp->dev, + "%s: Aux Transaction fail!\n", + __func__); + } + /* Check if Rx sends defer */ + reg = readl(dp->reg_base + EXYNOS_DP_AUX_RX_COMM); + if (reg == AUX_RX_COMM_AUX_DEFER || + reg == AUX_RX_COMM_I2C_DEFER) { + dev_err(dp->dev, "Defer: %d\n\n", reg); + defer = 1; + } + } + + for (cur_data_idx = 0; cur_data_idx < 16; cur_data_idx++) { + reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0 + + 4 * cur_data_idx); + edid[i + cur_data_idx] = (unsigned char)reg; + } + } + + return retval; +} + +void analogix_dp_set_link_bandwidth(struct analogix_dp_device *dp, u32 bwtype) +{ + u32 reg; + + reg = bwtype; + if ((bwtype == LINK_RATE_2_70GBPS) || (bwtype == LINK_RATE_1_62GBPS)) + writel(reg, dp->reg_base + EXYNOS_DP_LINK_BW_SET); +} + +void analogix_dp_get_link_bandwidth(struct analogix_dp_device *dp, u32 *bwtype) +{ + u32 reg; + + reg = readl(dp->reg_base + EXYNOS_DP_LINK_BW_SET); + *bwtype = reg; +} + +void analogix_dp_set_lane_count(struct analogix_dp_device *dp, u32 count) +{ + u32 reg; + + reg = count; + writel(reg, dp->reg_base + EXYNOS_DP_LANE_COUNT_SET); +} + +void analogix_dp_get_lane_count(struct analogix_dp_device *dp, u32 *count) +{ + u32 reg; + + reg = readl(dp->reg_base + EXYNOS_DP_LANE_COUNT_SET); + *count = reg; +} + +void analogix_dp_enable_enhanced_mode(struct analogix_dp_device *dp, bool enable) +{ + u32 reg; + + if (enable) { + reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4); + reg |= ENHANCED; + writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4); + } else { + reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4); + reg &= ~ENHANCED; + writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4); + } +} + +void analogix_dp_set_training_pattern(struct analogix_dp_device *dp, + enum pattern_set pattern) +{ + u32 reg; + + switch (pattern) { + case PRBS7: + reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_PRBS7; + writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); + break; + case D10_2: + reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_D10_2; + writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); + break; + case TRAINING_PTN1: + reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN1; + writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); + break; + case TRAINING_PTN2: + reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN2; + writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); + break; + case DP_NONE: + reg = SCRAMBLING_ENABLE | + LINK_QUAL_PATTERN_SET_DISABLE | + SW_TRAINING_PATTERN_SET_NORMAL; + writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); + break; + default: + break; + } +} + +void analogix_dp_set_lane0_pre_emphasis(struct analogix_dp_device *dp, u32 level) +{ + u32 reg; + + reg = readl(dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL); + reg &= ~PRE_EMPHASIS_SET_MASK; + reg |= level << PRE_EMPHASIS_SET_SHIFT; + writel(reg, dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL); +} + +void analogix_dp_set_lane1_pre_emphasis(struct analogix_dp_device *dp, u32 level) +{ + u32 reg; + + reg = readl(dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL); + reg &= ~PRE_EMPHASIS_SET_MASK; + reg |= level << PRE_EMPHASIS_SET_SHIFT; + writel(reg, dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL); +} + +void analogix_dp_set_lane2_pre_emphasis(struct analogix_dp_device *dp, u32 level) +{ + u32 reg; + + reg = readl(dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL); + reg &= ~PRE_EMPHASIS_SET_MASK; + reg |= level << PRE_EMPHASIS_SET_SHIFT; + writel(reg, dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL); +} + +void analogix_dp_set_lane3_pre_emphasis(struct analogix_dp_device *dp, u32 level) +{ + u32 reg; + + reg = readl(dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL); + reg &= ~PRE_EMPHASIS_SET_MASK; + reg |= level << PRE_EMPHASIS_SET_SHIFT; + writel(reg, dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL); +} + +void analogix_dp_set_lane0_link_training(struct analogix_dp_device *dp, + u32 training_lane) +{ + u32 reg; + + reg = training_lane; + writel(reg, dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL); +} + +void analogix_dp_set_lane1_link_training(struct analogix_dp_device *dp, + u32 training_lane) +{ + u32 reg; + + reg = training_lane; + writel(reg, dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL); +} + +void analogix_dp_set_lane2_link_training(struct analogix_dp_device *dp, + u32 training_lane) +{ + u32 reg; + + reg = training_lane; + writel(reg, dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL); +} + +void analogix_dp_set_lane3_link_training(struct analogix_dp_device *dp, + u32 training_lane) +{ + u32 reg; + + reg = training_lane; + writel(reg, dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL); +} + +u32 analogix_dp_get_lane0_link_training(struct analogix_dp_device *dp) +{ + u32 reg; + + reg = readl(dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL); + return reg; +} + +u32 analogix_dp_get_lane1_link_training(struct analogix_dp_device *dp) +{ + u32 reg; + + reg = readl(dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL); + return reg; +} + +u32 analogix_dp_get_lane2_link_training(struct analogix_dp_device *dp) +{ + u32 reg; + + reg = readl(dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL); + return reg; +} + +u32 analogix_dp_get_lane3_link_training(struct analogix_dp_device *dp) +{ + u32 reg; + + reg = readl(dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL); + return reg; +} + +void analogix_dp_reset_macro(struct analogix_dp_device *dp) +{ + u32 reg; + + reg = readl(dp->reg_base + EXYNOS_DP_PHY_TEST); + reg |= MACRO_RST; + writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST); + + /* 10 us is the minimum reset time. */ + usleep_range(10, 20); + + reg &= ~MACRO_RST; + writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST); +} + +void analogix_dp_init_video(struct analogix_dp_device *dp) +{ + u32 reg; + + reg = VSYNC_DET | VID_FORMAT_CHG | VID_CLK_CHG; + writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1); + + reg = 0x0; + writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_1); + + reg = CHA_CRI(4) | CHA_CTRL; + writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_2); + + reg = 0x0; + writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3); + + reg = VID_HRES_TH(2) | VID_VRES_TH(0); + writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_8); +} + +void analogix_dp_set_video_color_format(struct analogix_dp_device *dp) +{ + u32 reg; + + /* Configure the input color depth, color space, dynamic range */ + reg = (dp->video_info->dynamic_range << IN_D_RANGE_SHIFT) | + (dp->video_info->color_depth << IN_BPC_SHIFT) | + (dp->video_info->color_space << IN_COLOR_F_SHIFT); + writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_2); + + /* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */ + reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_3); + reg &= ~IN_YC_COEFFI_MASK; + if (dp->video_info->ycbcr_coeff) + reg |= IN_YC_COEFFI_ITU709; + else + reg |= IN_YC_COEFFI_ITU601; + writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_3); +} + +int analogix_dp_is_slave_video_stream_clock_on(struct analogix_dp_device *dp) +{ + u32 reg; + + reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_1); + writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_1); + + reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_1); + + if (!(reg & DET_STA)) { + dev_dbg(dp->dev, "Input stream clock not detected.\n"); + return -EINVAL; + } + + reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_2); + writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_2); + + reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_2); + dev_dbg(dp->dev, "wait SYS_CTL_2.\n"); + + if (reg & CHA_STA) { + dev_dbg(dp->dev, "Input stream clk is changing\n"); + return -EINVAL; + } + + return 0; +} + +void analogix_dp_set_video_cr_mn(struct analogix_dp_device *dp, + enum clock_recovery_m_value_type type, + u32 m_value, + u32 n_value) +{ + u32 reg; + + if (type == REGISTER_M) { + reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4); + reg |= FIX_M_VID; + writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4); + reg = m_value & 0xff; + writel(reg, dp->reg_base + EXYNOS_DP_M_VID_0); + reg = (m_value >> 8) & 0xff; + writel(reg, dp->reg_base + EXYNOS_DP_M_VID_1); + reg = (m_value >> 16) & 0xff; + writel(reg, dp->reg_base + EXYNOS_DP_M_VID_2); + + reg = n_value & 0xff; + writel(reg, dp->reg_base + EXYNOS_DP_N_VID_0); + reg = (n_value >> 8) & 0xff; + writel(reg, dp->reg_base + EXYNOS_DP_N_VID_1); + reg = (n_value >> 16) & 0xff; + writel(reg, dp->reg_base + EXYNOS_DP_N_VID_2); + } else { + reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4); + reg &= ~FIX_M_VID; + writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4); + + writel(0x00, dp->reg_base + EXYNOS_DP_N_VID_0); + writel(0x80, dp->reg_base + EXYNOS_DP_N_VID_1); + writel(0x00, dp->reg_base + EXYNOS_DP_N_VID_2); + } +} + +void analogix_dp_set_video_timing_mode(struct analogix_dp_device *dp, u32 type) +{ + u32 reg; + + if (type == VIDEO_TIMING_FROM_CAPTURE) { + reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); + reg &= ~FORMAT_SEL; + writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); + } else { + reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); + reg |= FORMAT_SEL; + writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); + } +} + +void analogix_dp_enable_video_master(struct analogix_dp_device *dp, bool enable) +{ + u32 reg; + + if (enable) { + reg = readl(dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); + reg &= ~VIDEO_MODE_MASK; + reg |= VIDEO_MASTER_MODE_EN | VIDEO_MODE_MASTER_MODE; + writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); + } else { + reg = readl(dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); + reg &= ~VIDEO_MODE_MASK; + reg |= VIDEO_MODE_SLAVE_MODE; + writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); + } +} + +void analogix_dp_start_video(struct analogix_dp_device *dp) +{ + u32 reg; + + reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); + reg |= VIDEO_EN; + writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); +} + +int analogix_dp_is_video_stream_on(struct analogix_dp_device *dp) +{ + u32 reg; + + reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3); + writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3); + + reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3); + if (!(reg & STRM_VALID)) { + dev_dbg(dp->dev, "Input video stream is not detected.\n"); + return -EINVAL; + } + + return 0; +} + +void analogix_dp_config_video_slave_mode(struct analogix_dp_device *dp) +{ + u32 reg; + + reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_1); + reg &= ~(MASTER_VID_FUNC_EN_N|SLAVE_VID_FUNC_EN_N); + reg |= MASTER_VID_FUNC_EN_N; + writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1); + + reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); + reg &= ~INTERACE_SCAN_CFG; + reg |= (dp->video_info->interlaced << 2); + writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); + + reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); + reg &= ~VSYNC_POLARITY_CFG; + reg |= (dp->video_info->v_sync_polarity << 1); + writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); + + reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); + reg &= ~HSYNC_POLARITY_CFG; + reg |= (dp->video_info->h_sync_polarity << 0); + writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); + + reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE; + writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); +} + +void analogix_dp_enable_scrambling(struct analogix_dp_device *dp) +{ + u32 reg; + + reg = readl(dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); + reg &= ~SCRAMBLING_DISABLE; + writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); +} + +void analogix_dp_disable_scrambling(struct analogix_dp_device *dp) +{ + u32 reg; + + reg = readl(dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); + reg |= SCRAMBLING_DISABLE; + writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); +} diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h new file mode 100644 index 000000000000..b9661c9e8dc6 --- /dev/null +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h @@ -0,0 +1,366 @@ +/* + * Register definition file for Analogix DP core driver + * + * Copyright (C) 2012 Samsung Electronics Co., Ltd. + * Author: Jingoo Han + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _ANALOGIX_DP_REG_H +#define _ANALOGIX_DP_REG_H + +#define EXYNOS_DP_TX_SW_RESET 0x14 +#define EXYNOS_DP_FUNC_EN_1 0x18 +#define EXYNOS_DP_FUNC_EN_2 0x1C +#define EXYNOS_DP_VIDEO_CTL_1 0x20 +#define EXYNOS_DP_VIDEO_CTL_2 0x24 +#define EXYNOS_DP_VIDEO_CTL_3 0x28 + +#define EXYNOS_DP_VIDEO_CTL_8 0x3C +#define EXYNOS_DP_VIDEO_CTL_10 0x44 + +#define EXYNOS_DP_LANE_MAP 0x35C + +#define EXYNOS_DP_ANALOG_CTL_1 0x370 +#define EXYNOS_DP_ANALOG_CTL_2 0x374 +#define EXYNOS_DP_ANALOG_CTL_3 0x378 +#define EXYNOS_DP_PLL_FILTER_CTL_1 0x37C +#define EXYNOS_DP_TX_AMP_TUNING_CTL 0x380 + +#define EXYNOS_DP_AUX_HW_RETRY_CTL 0x390 + +#define EXYNOS_DP_COMMON_INT_STA_1 0x3C4 +#define EXYNOS_DP_COMMON_INT_STA_2 0x3C8 +#define EXYNOS_DP_COMMON_INT_STA_3 0x3CC +#define EXYNOS_DP_COMMON_INT_STA_4 0x3D0 +#define EXYNOS_DP_INT_STA 0x3DC +#define EXYNOS_DP_COMMON_INT_MASK_1 0x3E0 +#define EXYNOS_DP_COMMON_INT_MASK_2 0x3E4 +#define EXYNOS_DP_COMMON_INT_MASK_3 0x3E8 +#define EXYNOS_DP_COMMON_INT_MASK_4 0x3EC +#define EXYNOS_DP_INT_STA_MASK 0x3F8 +#define EXYNOS_DP_INT_CTL 0x3FC + +#define EXYNOS_DP_SYS_CTL_1 0x600 +#define EXYNOS_DP_SYS_CTL_2 0x604 +#define EXYNOS_DP_SYS_CTL_3 0x608 +#define EXYNOS_DP_SYS_CTL_4 0x60C + +#define EXYNOS_DP_PKT_SEND_CTL 0x640 +#define EXYNOS_DP_HDCP_CTL 0x648 + +#define EXYNOS_DP_LINK_BW_SET 0x680 +#define EXYNOS_DP_LANE_COUNT_SET 0x684 +#define EXYNOS_DP_TRAINING_PTN_SET 0x688 +#define EXYNOS_DP_LN0_LINK_TRAINING_CTL 0x68C +#define EXYNOS_DP_LN1_LINK_TRAINING_CTL 0x690 +#define EXYNOS_DP_LN2_LINK_TRAINING_CTL 0x694 +#define EXYNOS_DP_LN3_LINK_TRAINING_CTL 0x698 + +#define EXYNOS_DP_DEBUG_CTL 0x6C0 +#define EXYNOS_DP_HPD_DEGLITCH_L 0x6C4 +#define EXYNOS_DP_HPD_DEGLITCH_H 0x6C8 +#define EXYNOS_DP_LINK_DEBUG_CTL 0x6E0 + +#define EXYNOS_DP_M_VID_0 0x700 +#define EXYNOS_DP_M_VID_1 0x704 +#define EXYNOS_DP_M_VID_2 0x708 +#define EXYNOS_DP_N_VID_0 0x70C +#define EXYNOS_DP_N_VID_1 0x710 +#define EXYNOS_DP_N_VID_2 0x714 + +#define EXYNOS_DP_PLL_CTL 0x71C +#define EXYNOS_DP_PHY_PD 0x720 +#define EXYNOS_DP_PHY_TEST 0x724 + +#define EXYNOS_DP_VIDEO_FIFO_THRD 0x730 +#define EXYNOS_DP_AUDIO_MARGIN 0x73C + +#define EXYNOS_DP_M_VID_GEN_FILTER_TH 0x764 +#define EXYNOS_DP_M_AUD_GEN_FILTER_TH 0x778 +#define EXYNOS_DP_AUX_CH_STA 0x780 +#define EXYNOS_DP_AUX_CH_DEFER_CTL 0x788 +#define EXYNOS_DP_AUX_RX_COMM 0x78C +#define EXYNOS_DP_BUFFER_DATA_CTL 0x790 +#define EXYNOS_DP_AUX_CH_CTL_1 0x794 +#define EXYNOS_DP_AUX_ADDR_7_0 0x798 +#define EXYNOS_DP_AUX_ADDR_15_8 0x79C +#define EXYNOS_DP_AUX_ADDR_19_16 0x7A0 +#define EXYNOS_DP_AUX_CH_CTL_2 0x7A4 + +#define EXYNOS_DP_BUF_DATA_0 0x7C0 + +#define EXYNOS_DP_SOC_GENERAL_CTL 0x800 + +/* EXYNOS_DP_TX_SW_RESET */ +#define RESET_DP_TX (0x1 << 0) + +/* EXYNOS_DP_FUNC_EN_1 */ +#define MASTER_VID_FUNC_EN_N (0x1 << 7) +#define SLAVE_VID_FUNC_EN_N (0x1 << 5) +#define AUD_FIFO_FUNC_EN_N (0x1 << 4) +#define AUD_FUNC_EN_N (0x1 << 3) +#define HDCP_FUNC_EN_N (0x1 << 2) +#define CRC_FUNC_EN_N (0x1 << 1) +#define SW_FUNC_EN_N (0x1 << 0) + +/* EXYNOS_DP_FUNC_EN_2 */ +#define SSC_FUNC_EN_N (0x1 << 7) +#define AUX_FUNC_EN_N (0x1 << 2) +#define SERDES_FIFO_FUNC_EN_N (0x1 << 1) +#define LS_CLK_DOMAIN_FUNC_EN_N (0x1 << 0) + +/* EXYNOS_DP_VIDEO_CTL_1 */ +#define VIDEO_EN (0x1 << 7) +#define HDCP_VIDEO_MUTE (0x1 << 6) + +/* EXYNOS_DP_VIDEO_CTL_1 */ +#define IN_D_RANGE_MASK (0x1 << 7) +#define IN_D_RANGE_SHIFT (7) +#define IN_D_RANGE_CEA (0x1 << 7) +#define IN_D_RANGE_VESA (0x0 << 7) +#define IN_BPC_MASK (0x7 << 4) +#define IN_BPC_SHIFT (4) +#define IN_BPC_12_BITS (0x3 << 4) +#define IN_BPC_10_BITS (0x2 << 4) +#define IN_BPC_8_BITS (0x1 << 4) +#define IN_BPC_6_BITS (0x0 << 4) +#define IN_COLOR_F_MASK (0x3 << 0) +#define IN_COLOR_F_SHIFT (0) +#define IN_COLOR_F_YCBCR444 (0x2 << 0) +#define IN_COLOR_F_YCBCR422 (0x1 << 0) +#define IN_COLOR_F_RGB (0x0 << 0) + +/* EXYNOS_DP_VIDEO_CTL_3 */ +#define IN_YC_COEFFI_MASK (0x1 << 7) +#define IN_YC_COEFFI_SHIFT (7) +#define IN_YC_COEFFI_ITU709 (0x1 << 7) +#define IN_YC_COEFFI_ITU601 (0x0 << 7) +#define VID_CHK_UPDATE_TYPE_MASK (0x1 << 4) +#define VID_CHK_UPDATE_TYPE_SHIFT (4) +#define VID_CHK_UPDATE_TYPE_1 (0x1 << 4) +#define VID_CHK_UPDATE_TYPE_0 (0x0 << 4) + +/* EXYNOS_DP_VIDEO_CTL_8 */ +#define VID_HRES_TH(x) (((x) & 0xf) << 4) +#define VID_VRES_TH(x) (((x) & 0xf) << 0) + +/* EXYNOS_DP_VIDEO_CTL_10 */ +#define FORMAT_SEL (0x1 << 4) +#define INTERACE_SCAN_CFG (0x1 << 2) +#define VSYNC_POLARITY_CFG (0x1 << 1) +#define HSYNC_POLARITY_CFG (0x1 << 0) + +/* EXYNOS_DP_LANE_MAP */ +#define LANE3_MAP_LOGIC_LANE_0 (0x0 << 6) +#define LANE3_MAP_LOGIC_LANE_1 (0x1 << 6) +#define LANE3_MAP_LOGIC_LANE_2 (0x2 << 6) +#define LANE3_MAP_LOGIC_LANE_3 (0x3 << 6) +#define LANE2_MAP_LOGIC_LANE_0 (0x0 << 4) +#define LANE2_MAP_LOGIC_LANE_1 (0x1 << 4) +#define LANE2_MAP_LOGIC_LANE_2 (0x2 << 4) +#define LANE2_MAP_LOGIC_LANE_3 (0x3 << 4) +#define LANE1_MAP_LOGIC_LANE_0 (0x0 << 2) +#define LANE1_MAP_LOGIC_LANE_1 (0x1 << 2) +#define LANE1_MAP_LOGIC_LANE_2 (0x2 << 2) +#define LANE1_MAP_LOGIC_LANE_3 (0x3 << 2) +#define LANE0_MAP_LOGIC_LANE_0 (0x0 << 0) +#define LANE0_MAP_LOGIC_LANE_1 (0x1 << 0) +#define LANE0_MAP_LOGIC_LANE_2 (0x2 << 0) +#define LANE0_MAP_LOGIC_LANE_3 (0x3 << 0) + +/* EXYNOS_DP_ANALOG_CTL_1 */ +#define TX_TERMINAL_CTRL_50_OHM (0x1 << 4) + +/* EXYNOS_DP_ANALOG_CTL_2 */ +#define SEL_24M (0x1 << 3) +#define TX_DVDD_BIT_1_0625V (0x4 << 0) + +/* EXYNOS_DP_ANALOG_CTL_3 */ +#define DRIVE_DVDD_BIT_1_0625V (0x4 << 5) +#define VCO_BIT_600_MICRO (0x5 << 0) + +/* EXYNOS_DP_PLL_FILTER_CTL_1 */ +#define PD_RING_OSC (0x1 << 6) +#define AUX_TERMINAL_CTRL_50_OHM (0x2 << 4) +#define TX_CUR1_2X (0x1 << 2) +#define TX_CUR_16_MA (0x3 << 0) + +/* EXYNOS_DP_TX_AMP_TUNING_CTL */ +#define CH3_AMP_400_MV (0x0 << 24) +#define CH2_AMP_400_MV (0x0 << 16) +#define CH1_AMP_400_MV (0x0 << 8) +#define CH0_AMP_400_MV (0x0 << 0) + +/* EXYNOS_DP_AUX_HW_RETRY_CTL */ +#define AUX_BIT_PERIOD_EXPECTED_DELAY(x) (((x) & 0x7) << 8) +#define AUX_HW_RETRY_INTERVAL_MASK (0x3 << 3) +#define AUX_HW_RETRY_INTERVAL_600_MICROSECONDS (0x0 << 3) +#define AUX_HW_RETRY_INTERVAL_800_MICROSECONDS (0x1 << 3) +#define AUX_HW_RETRY_INTERVAL_1000_MICROSECONDS (0x2 << 3) +#define AUX_HW_RETRY_INTERVAL_1800_MICROSECONDS (0x3 << 3) +#define AUX_HW_RETRY_COUNT_SEL(x) (((x) & 0x7) << 0) + +/* EXYNOS_DP_COMMON_INT_STA_1 */ +#define VSYNC_DET (0x1 << 7) +#define PLL_LOCK_CHG (0x1 << 6) +#define SPDIF_ERR (0x1 << 5) +#define SPDIF_UNSTBL (0x1 << 4) +#define VID_FORMAT_CHG (0x1 << 3) +#define AUD_CLK_CHG (0x1 << 2) +#define VID_CLK_CHG (0x1 << 1) +#define SW_INT (0x1 << 0) + +/* EXYNOS_DP_COMMON_INT_STA_2 */ +#define ENC_EN_CHG (0x1 << 6) +#define HW_BKSV_RDY (0x1 << 3) +#define HW_SHA_DONE (0x1 << 2) +#define HW_AUTH_STATE_CHG (0x1 << 1) +#define HW_AUTH_DONE (0x1 << 0) + +/* EXYNOS_DP_COMMON_INT_STA_3 */ +#define AFIFO_UNDER (0x1 << 7) +#define AFIFO_OVER (0x1 << 6) +#define R0_CHK_FLAG (0x1 << 5) + +/* EXYNOS_DP_COMMON_INT_STA_4 */ +#define PSR_ACTIVE (0x1 << 7) +#define PSR_INACTIVE (0x1 << 6) +#define SPDIF_BI_PHASE_ERR (0x1 << 5) +#define HOTPLUG_CHG (0x1 << 2) +#define HPD_LOST (0x1 << 1) +#define PLUG (0x1 << 0) + +/* EXYNOS_DP_INT_STA */ +#define INT_HPD (0x1 << 6) +#define HW_TRAINING_FINISH (0x1 << 5) +#define RPLY_RECEIV (0x1 << 1) +#define AUX_ERR (0x1 << 0) + +/* EXYNOS_DP_INT_CTL */ +#define SOFT_INT_CTRL (0x1 << 2) +#define INT_POL1 (0x1 << 1) +#define INT_POL0 (0x1 << 0) + +/* EXYNOS_DP_SYS_CTL_1 */ +#define DET_STA (0x1 << 2) +#define FORCE_DET (0x1 << 1) +#define DET_CTRL (0x1 << 0) + +/* EXYNOS_DP_SYS_CTL_2 */ +#define CHA_CRI(x) (((x) & 0xf) << 4) +#define CHA_STA (0x1 << 2) +#define FORCE_CHA (0x1 << 1) +#define CHA_CTRL (0x1 << 0) + +/* EXYNOS_DP_SYS_CTL_3 */ +#define HPD_STATUS (0x1 << 6) +#define F_HPD (0x1 << 5) +#define HPD_CTRL (0x1 << 4) +#define HDCP_RDY (0x1 << 3) +#define STRM_VALID (0x1 << 2) +#define F_VALID (0x1 << 1) +#define VALID_CTRL (0x1 << 0) + +/* EXYNOS_DP_SYS_CTL_4 */ +#define FIX_M_AUD (0x1 << 4) +#define ENHANCED (0x1 << 3) +#define FIX_M_VID (0x1 << 2) +#define M_VID_UPDATE_CTRL (0x3 << 0) + +/* EXYNOS_DP_TRAINING_PTN_SET */ +#define SCRAMBLER_TYPE (0x1 << 9) +#define HW_LINK_TRAINING_PATTERN (0x1 << 8) +#define SCRAMBLING_DISABLE (0x1 << 5) +#define SCRAMBLING_ENABLE (0x0 << 5) +#define LINK_QUAL_PATTERN_SET_MASK (0x3 << 2) +#define LINK_QUAL_PATTERN_SET_PRBS7 (0x3 << 2) +#define LINK_QUAL_PATTERN_SET_D10_2 (0x1 << 2) +#define LINK_QUAL_PATTERN_SET_DISABLE (0x0 << 2) +#define SW_TRAINING_PATTERN_SET_MASK (0x3 << 0) +#define SW_TRAINING_PATTERN_SET_PTN2 (0x2 << 0) +#define SW_TRAINING_PATTERN_SET_PTN1 (0x1 << 0) +#define SW_TRAINING_PATTERN_SET_NORMAL (0x0 << 0) + +/* EXYNOS_DP_LN0_LINK_TRAINING_CTL */ +#define PRE_EMPHASIS_SET_MASK (0x3 << 3) +#define PRE_EMPHASIS_SET_SHIFT (3) + +/* EXYNOS_DP_DEBUG_CTL */ +#define PLL_LOCK (0x1 << 4) +#define F_PLL_LOCK (0x1 << 3) +#define PLL_LOCK_CTRL (0x1 << 2) +#define PN_INV (0x1 << 0) + +/* EXYNOS_DP_PLL_CTL */ +#define DP_PLL_PD (0x1 << 7) +#define DP_PLL_RESET (0x1 << 6) +#define DP_PLL_LOOP_BIT_DEFAULT (0x1 << 4) +#define DP_PLL_REF_BIT_1_1250V (0x5 << 0) +#define DP_PLL_REF_BIT_1_2500V (0x7 << 0) + +/* EXYNOS_DP_PHY_PD */ +#define DP_PHY_PD (0x1 << 5) +#define AUX_PD (0x1 << 4) +#define CH3_PD (0x1 << 3) +#define CH2_PD (0x1 << 2) +#define CH1_PD (0x1 << 1) +#define CH0_PD (0x1 << 0) + +/* EXYNOS_DP_PHY_TEST */ +#define MACRO_RST (0x1 << 5) +#define CH1_TEST (0x1 << 1) +#define CH0_TEST (0x1 << 0) + +/* EXYNOS_DP_AUX_CH_STA */ +#define AUX_BUSY (0x1 << 4) +#define AUX_STATUS_MASK (0xf << 0) + +/* EXYNOS_DP_AUX_CH_DEFER_CTL */ +#define DEFER_CTRL_EN (0x1 << 7) +#define DEFER_COUNT(x) (((x) & 0x7f) << 0) + +/* EXYNOS_DP_AUX_RX_COMM */ +#define AUX_RX_COMM_I2C_DEFER (0x2 << 2) +#define AUX_RX_COMM_AUX_DEFER (0x2 << 0) + +/* EXYNOS_DP_BUFFER_DATA_CTL */ +#define BUF_CLR (0x1 << 7) +#define BUF_DATA_COUNT(x) (((x) & 0x1f) << 0) + +/* EXYNOS_DP_AUX_CH_CTL_1 */ +#define AUX_LENGTH(x) (((x - 1) & 0xf) << 4) +#define AUX_TX_COMM_MASK (0xf << 0) +#define AUX_TX_COMM_DP_TRANSACTION (0x1 << 3) +#define AUX_TX_COMM_I2C_TRANSACTION (0x0 << 3) +#define AUX_TX_COMM_MOT (0x1 << 2) +#define AUX_TX_COMM_WRITE (0x0 << 0) +#define AUX_TX_COMM_READ (0x1 << 0) + +/* EXYNOS_DP_AUX_ADDR_7_0 */ +#define AUX_ADDR_7_0(x) (((x) >> 0) & 0xff) + +/* EXYNOS_DP_AUX_ADDR_15_8 */ +#define AUX_ADDR_15_8(x) (((x) >> 8) & 0xff) + +/* EXYNOS_DP_AUX_ADDR_19_16 */ +#define AUX_ADDR_19_16(x) (((x) >> 16) & 0x0f) + +/* EXYNOS_DP_AUX_CH_CTL_2 */ +#define ADDR_ONLY (0x1 << 1) +#define AUX_EN (0x1 << 0) + +/* EXYNOS_DP_SOC_GENERAL_CTL */ +#define AUDIO_MODE_SPDIF_MODE (0x1 << 8) +#define AUDIO_MODE_MASTER_MODE (0x0 << 8) +#define MASTER_VIDEO_INTERLACE_EN (0x1 << 4) +#define VIDEO_MASTER_CLK_SEL (0x1 << 2) +#define VIDEO_MASTER_MODE_EN (0x1 << 1) +#define VIDEO_MODE_MASK (0x1 << 0) +#define VIDEO_MODE_SLAVE_MODE (0x1 << 0) +#define VIDEO_MODE_MASTER_MODE (0x0 << 0) + +#endif /* _ANALOGIX_DP_REG_H */ diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig index f17d39279596..2fadd8275fa5 100644 --- a/drivers/gpu/drm/exynos/Kconfig +++ b/drivers/gpu/drm/exynos/Kconfig @@ -71,8 +71,9 @@ config DRM_EXYNOS_DSI This enables support for Exynos MIPI-DSI device. config DRM_EXYNOS_DP - bool "Display Port" + bool "EXYNOS specific extensions for Analogix DP driver" depends on DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON + select DRM_ANALOGIX_DP default DRM_EXYNOS select DRM_PANEL help diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile index 968b31c522b2..2bdd949eff24 100644 --- a/drivers/gpu/drm/exynos/Makefile +++ b/drivers/gpu/drm/exynos/Makefile @@ -12,7 +12,7 @@ exynosdrm-$(CONFIG_DRM_EXYNOS5433_DECON) += exynos5433_drm_decon.o exynosdrm-$(CONFIG_DRM_EXYNOS7_DECON) += exynos7_drm_decon.o exynosdrm-$(CONFIG_DRM_EXYNOS_DPI) += exynos_drm_dpi.o exynosdrm-$(CONFIG_DRM_EXYNOS_DSI) += exynos_drm_dsi.o -exynosdrm-$(CONFIG_DRM_EXYNOS_DP) += exynos_dp_core.o exynos_dp_reg.o +exynosdrm-$(CONFIG_DRM_EXYNOS_DP) += exynos_dp_core.o exynosdrm-$(CONFIG_DRM_EXYNOS_MIXER) += exynos_mixer.o exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI) += exynos_hdmi.o exynosdrm-$(CONFIG_DRM_EXYNOS_VIDI) += exynos_drm_vidi.o diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c index cff8dc788820..845679448206 100644 --- a/drivers/gpu/drm/exynos/exynos_dp_core.c +++ b/drivers/gpu/drm/exynos/exynos_dp_core.c @@ -14,967 +14,76 @@ #include #include #include -#include -#include -#include -#include #include -#include #include -#include #include