From 98c5cf7f6fc51f1a8f5f90b3895009cd38dd8f22 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 30 May 2008 11:25:41 +1000 Subject: [PATCH] modesetting: reorganise out crtc/outputs are allocated. Use subclassing from the drivers to allocate the objects. This saves two objects being allocated for each crtc/output and generally makes exit paths cleaner. --- linux-core/drm_crtc.c | 85 +++++++++++++------------------------- linux-core/drm_crtc.h | 33 ++++++++------- linux-core/intel_crt.c | 26 ++++++------ linux-core/intel_display.c | 64 ++++++++++++++-------------- linux-core/intel_drv.h | 5 +++ linux-core/intel_dvo.c | 52 ++++++++++------------- linux-core/intel_lvds.c | 28 ++++++------- linux-core/intel_modes.c | 4 +- linux-core/intel_sdvo.c | 54 +++++++++++------------- linux-core/intel_tv.c | 41 +++++++++--------- shared-core/i915_irq.c | 4 +- 11 files changed, 181 insertions(+), 215 deletions(-) diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index a4a51080..faf70df5 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -232,27 +232,19 @@ void drm_framebuffer_destroy(struct drm_framebuffer *fb) EXPORT_SYMBOL(drm_framebuffer_destroy); /** - * drm_crtc_create - create a new CRTC object + * drm_crtc_init - Initialise a new CRTC object * @dev: DRM device + * @crtc: CRTC object to init * @funcs: callbacks for the new CRTC * * LOCKING: * Caller must hold mode config lock. * - * Creates a new CRTC object and adds it to @dev's mode_config structure. - * - * RETURNS: - * Pointer to new CRTC object or NULL on error. + * Inits a new object created as base part of an driver crtc object. */ -struct drm_crtc *drm_crtc_create(struct drm_device *dev, - const struct drm_crtc_funcs *funcs) +void drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, + const struct drm_crtc_funcs *funcs) { - struct drm_crtc *crtc; - - crtc = kzalloc(sizeof(struct drm_crtc), GFP_KERNEL); - if (!crtc) - return NULL; - crtc->dev = dev; crtc->funcs = funcs; @@ -260,34 +252,28 @@ struct drm_crtc *drm_crtc_create(struct drm_device *dev, list_add_tail(&crtc->head, &dev->mode_config.crtc_list); dev->mode_config.num_crtc++; - - return crtc; } -EXPORT_SYMBOL(drm_crtc_create); +EXPORT_SYMBOL(drm_crtc_init); /** - * drm_crtc_destroy - remove a CRTC object - * @crtc: CRTC to remove + * drm_crtc_cleanup - Cleans up the core crtc usage. + * @crtc: CRTC to cleanup * * LOCKING: * Caller must hold mode config lock. * - * Cleanup @crtc. Calls @crtc's cleanup function, then removes @crtc from - * its associated DRM device's mode_config. Frees it afterwards. + * Cleanup @crtc. Removes from drm modesetting space + * does NOT free object, caller does that. */ -void drm_crtc_destroy(struct drm_crtc *crtc) +void drm_crtc_cleanup(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - if (crtc->funcs->cleanup) - (*crtc->funcs->cleanup)(crtc); - drm_idr_put(dev, crtc->id); list_del(&crtc->head); dev->mode_config.num_crtc--; - kfree(crtc); } -EXPORT_SYMBOL(drm_crtc_destroy); +EXPORT_SYMBOL(drm_crtc_cleanup); /** * drm_crtc_in_use - check if a given CRTC is in a mode_config @@ -481,30 +467,23 @@ void drm_mode_remove(struct drm_output *output, struct drm_display_mode *mode) EXPORT_SYMBOL(drm_mode_remove); /** - * drm_output_create - create a new output + * drm_output_init - Init a preallocated output * @dev: DRM device + * @output: the output to init * @funcs: callbacks for this output * @name: user visible name of the output * * LOCKING: * Caller must hold @dev's mode_config lock. * - * Creates a new drm_output structure and adds it to @dev's mode_config - * structure. - * - * RETURNS: - * Pointer to the new output or NULL on error. + * Initialises a preallocated output. Outputs should be + * subclassed as part of driver output objects. */ -struct drm_output *drm_output_create(struct drm_device *dev, - const struct drm_output_funcs *funcs, - int output_type) +void drm_output_init(struct drm_device *dev, + struct drm_output *output, + const struct drm_output_funcs *funcs, + int output_type) { - struct drm_output *output = NULL; - - output = kzalloc(sizeof(struct drm_output), GFP_KERNEL); - if (!output) - return NULL; - output->dev = dev; output->funcs = funcs; output->id = drm_idr_get(dev, output); @@ -526,30 +505,23 @@ struct drm_output *drm_output_create(struct drm_device *dev, drm_output_attach_property(output, dev->mode_config.dpms_property, 0); mutex_unlock(&dev->mode_config.mutex); - - return output; - } -EXPORT_SYMBOL(drm_output_create); +EXPORT_SYMBOL(drm_output_init); /** - * drm_output_destroy - remove an output - * @output: output to remove + * drm_output_cleanup - cleans up an initialised output + * @output: output to cleanup * * LOCKING: * Caller must hold @dev's mode_config lock. * - * Call @output's cleanup function, then remove the output from the DRM - * mode_config after freeing @output's modes. + * Cleans up the output but doesn't free the object. */ -void drm_output_destroy(struct drm_output *output) +void drm_output_cleanup(struct drm_output *output) { struct drm_device *dev = output->dev; struct drm_display_mode *mode, *t; - if (*output->funcs->cleanup) - (*output->funcs->cleanup)(output); - list_for_each_entry_safe(mode, t, &output->probed_modes, head) drm_mode_remove(output, mode); @@ -563,9 +535,8 @@ void drm_output_destroy(struct drm_output *output) drm_idr_put(dev, output->id); list_del(&output->head); mutex_unlock(&dev->mode_config.mutex); - kfree(output); } -EXPORT_SYMBOL(drm_output_destroy); +EXPORT_SYMBOL(drm_output_cleanup); /** @@ -793,7 +764,7 @@ void drm_mode_config_cleanup(struct drm_device *dev) list_for_each_entry_safe(output, ot, &dev->mode_config.output_list, head) { drm_sysfs_output_remove(output); - drm_output_destroy(output); + output->funcs->destroy(output); } list_for_each_entry_safe(property, pt, &dev->mode_config.property_list, head) { @@ -809,7 +780,7 @@ void drm_mode_config_cleanup(struct drm_device *dev) } list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) { - drm_crtc_destroy(crtc); + crtc->funcs->destroy(crtc); } } diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h index 957ecc2c..b769eb7a 100644 --- a/linux-core/drm_crtc.h +++ b/linux-core/drm_crtc.h @@ -291,7 +291,7 @@ struct drm_output; * @mode_fixup: fixup proposed mode * @mode_set: set the desired mode on the CRTC * @gamma_set: specify color ramp for CRTC - * @cleanup: cleanup driver private state prior to close + * @destroy: deinit and free object. * * The drm_crtc_funcs structure is the central CRTC management structure * in the DRM. Each CRTC controls one or more outputs (note that the name @@ -322,8 +322,8 @@ struct drm_crtc_funcs { /* Set gamma on the CRTC */ void (*gamma_set)(struct drm_crtc *crtc, u16 r, u16 g, u16 b, int regno); - /* Driver cleanup routine */ - void (*cleanup)(struct drm_crtc *crtc); + /* Object destroy routine */ + void (*destroy)(struct drm_crtc *crtc); int (*set_config)(struct drm_mode_set *set); }; @@ -337,7 +337,6 @@ struct drm_crtc_funcs { * @desired_x: desired x for desired_mode * @desired_y: desired y for desired_mode * @funcs: CRTC control functions - * @driver_private: arbitrary driver data * * Each CRTC may have one or more outputs associated with it. This structure * allows the CRTC to be controlled. @@ -359,15 +358,11 @@ struct drm_crtc { struct drm_display_mode *desired_mode; int desired_x, desired_y; const struct drm_crtc_funcs *funcs; - void *driver_private; /* if you are using the helper */ void *helper_private; }; -extern struct drm_crtc *drm_crtc_create(struct drm_device *dev, - const struct drm_crtc_funcs *funcs); - /** * drm_output_funcs - control outputs on a given device * @init: setup this output @@ -380,7 +375,7 @@ extern struct drm_crtc *drm_crtc_create(struct drm_device *dev, * @detect: is this output active? * @get_modes: get mode list for this output * @set_property: property for this output may need update - * @cleanup: output is going away, cleanup + * @destroy: make object go away * * Each CRTC may have one or more outputs attached to it. The functions * below allow the core DRM code to control outputs, enumerate available modes, @@ -395,7 +390,7 @@ struct drm_output_funcs { int (*get_modes)(struct drm_output *output); bool (*set_property)(struct drm_output *output, struct drm_property *property, uint64_t val); - void (*cleanup)(struct drm_output *output); + void (*destroy)(struct drm_output *output); int (*mode_valid)(struct drm_output *output, struct drm_display_mode *mode); @@ -416,7 +411,6 @@ struct drm_output_funcs { * @initial_y: initial y position for this output * @status: output connected? * @funcs: output control functions - * @driver_private: private driver data * * Each output may be connected to one or more CRTCs, or may be clonable by * another output if they can share a CRTC. Each output also has a specific @@ -447,7 +441,6 @@ struct drm_output { struct drm_display_info display_info; const struct drm_output_funcs *funcs; - void *driver_private; struct list_head user_modes; struct drm_property_blob *edid_blob_ptr; @@ -532,13 +525,21 @@ struct drm_mode_config { uint32_t hotplug_counter; }; -struct drm_output *drm_output_create(struct drm_device *dev, - const struct drm_output_funcs *funcs, - int type); + +extern void drm_crtc_init(struct drm_device *dev, + struct drm_crtc *crtc, + const struct drm_crtc_funcs *funcs); +extern void drm_crtc_cleanup(struct drm_crtc *crtc); + +void drm_output_init(struct drm_device *dev, + struct drm_output *output, + const struct drm_output_funcs *funcs, + int output_type); + +void drm_output_cleanup(struct drm_output *output); extern char *drm_get_output_name(struct drm_output *output); extern char *drm_get_dpms_name(int val); -extern void drm_output_destroy(struct drm_output *output); extern void drm_fb_release(struct file *filp); extern struct edid *drm_get_edid(struct drm_output *output, diff --git a/linux-core/intel_crt.c b/linux-core/intel_crt.c index 3c5dae1a..584dea21 100644 --- a/linux-core/intel_crt.c +++ b/linux-core/intel_crt.c @@ -96,7 +96,7 @@ static void intel_crt_mode_set(struct drm_output *output, { struct drm_device *dev = output->dev; struct drm_crtc *crtc = output->crtc; - struct intel_crtc *intel_crtc = crtc->driver_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct drm_i915_private *dev_priv = dev->dev_private; int dpll_md_reg; u32 adpa, dpll_md; @@ -166,7 +166,7 @@ static bool intel_crt_detect_hotplug(struct drm_output *output) static bool intel_crt_detect_ddc(struct drm_output *output) { - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); /* CRT should always be at 0, but check anyway */ if (intel_output->type != INTEL_OUTPUT_ANALOG) @@ -195,10 +195,11 @@ static enum drm_output_status intel_crt_detect(struct drm_output *output) static void intel_crt_destroy(struct drm_output *output) { - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); intel_i2c_destroy(intel_output->ddc_bus); - kfree(output->driver_private); + drm_output_cleanup(output); + kfree(output); } static int intel_crt_get_modes(struct drm_output *output) @@ -235,7 +236,7 @@ static const struct drm_output_funcs intel_crt_output_funcs = { .restore = intel_crt_restore, .detect = intel_crt_detect, .get_modes = intel_crt_get_modes, - .cleanup = intel_crt_destroy, + .destroy = intel_crt_destroy, .set_property = intel_crt_set_property, .mode_valid = intel_crt_mode_valid, @@ -246,24 +247,23 @@ void intel_crt_init(struct drm_device *dev) struct drm_output *output; struct intel_output *intel_output; - output = drm_output_create(dev, &intel_crt_output_funcs, - DRM_MODE_OUTPUT_DAC); - - intel_output = kmalloc(sizeof(struct intel_output), GFP_KERNEL); - if (!intel_output) { - drm_output_destroy(output); + intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL); + if (!intel_output) return; - } + + output = &intel_output->base; + drm_output_init(dev, &intel_output->base, &intel_crt_output_funcs, DRM_MODE_OUTPUT_DAC); + /* Set up the DDC bus. */ intel_output->ddc_bus = intel_i2c_create(dev, GPIOA, "CRTDDC_A"); if (!intel_output->ddc_bus) { dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " "failed.\n"); + intel_crt_destroy(output); return; } intel_output->type = INTEL_OUTPUT_ANALOG; - output->driver_private = intel_output; output->interlace_allowed = 0; output->doublescan_allowed = 0; diff --git a/linux-core/intel_display.c b/linux-core/intel_display.c index a2307a3d..abcf5f5e 100644 --- a/linux-core/intel_display.c +++ b/linux-core/intel_display.c @@ -229,7 +229,7 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type) list_for_each_entry(l_entry, &mode_config->output_list, head) { if (l_entry->crtc == crtc) { - struct intel_output *intel_output = l_entry->driver_private; + struct intel_output *intel_output = to_intel_output(l_entry); if (intel_output->type == type) return true; } @@ -344,7 +344,7 @@ intel_set_vblank(struct drm_device *dev) int vbl_pipe = 0; list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - intel_crtc = crtc->driver_private; + intel_crtc = to_intel_crtc(crtc); if (crtc->enabled) vbl_pipe |= (1<pipe); @@ -366,7 +366,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y) struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_master_private *master_priv; - struct intel_crtc *intel_crtc = crtc->driver_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int pipe = intel_crtc->pipe; unsigned long Start, Offset; int dspbase = (pipe == 0 ? DSPAADDR : DSPBADDR); @@ -454,7 +454,7 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) struct drm_device *dev = crtc->dev; struct drm_i915_master_private *master_priv; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = crtc->driver_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int pipe = intel_crtc->pipe; int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; @@ -694,7 +694,7 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc, { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = crtc->driver_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int pipe = intel_crtc->pipe; int fp_reg = (pipe == 0) ? FPA0 : FPB0; int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; @@ -719,7 +719,7 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc, struct drm_output *output; list_for_each_entry(output, &mode_config->output_list, head) { - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); if (output->crtc != crtc) continue; @@ -947,7 +947,7 @@ 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 = crtc->driver_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int palreg = (intel_crtc->pipe == 0) ? PALETTE_A : PALETTE_B; int i; @@ -969,7 +969,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = crtc->driver_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int pipe = intel_crtc->pipe; uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR; uint32_t base = (pipe == 0) ? CURABASE : CURBBASE; @@ -1027,7 +1027,7 @@ static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = crtc->driver_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int pipe = intel_crtc->pipe; uint32_t temp = 0; uint32_t adder; @@ -1055,8 +1055,8 @@ static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) static void intel_crtc_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, u16 blue, int regno) { - struct intel_crtc *intel_crtc = crtc->driver_private; - + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + intel_crtc->lut_r[regno] = red >> 8; intel_crtc->lut_g[regno] = green >> 8; intel_crtc->lut_b[regno] = blue >> 8; @@ -1087,7 +1087,7 @@ struct drm_crtc *intel_get_load_detect_pipe(struct drm_output *output, int *dpms_mode) { struct drm_device *dev = output->dev; - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); struct intel_crtc *intel_crtc; struct drm_crtc *possible_crtc; struct drm_crtc *supported_crtc =NULL; @@ -1109,7 +1109,7 @@ struct drm_crtc *intel_get_load_detect_pipe(struct drm_output *output, if (output->crtc) { crtc = output->crtc; /* Make sure the crtc and output are running */ - intel_crtc = crtc->driver_private; + intel_crtc = to_intel_crtc(crtc); *dpms_mode = intel_crtc->dpms_mode; if (intel_crtc->dpms_mode != DPMSModeOn) { crtc->funcs->dpms(crtc, DPMSModeOn); @@ -1144,7 +1144,7 @@ struct drm_crtc *intel_get_load_detect_pipe(struct drm_output *output, output->crtc = crtc; intel_output->load_detect_temp = TRUE; - intel_crtc = crtc->driver_private; + intel_crtc = to_intel_crtc(crtc); *dpms_mode = intel_crtc->dpms_mode; if (!crtc->enabled) { @@ -1169,7 +1169,7 @@ struct drm_crtc *intel_get_load_detect_pipe(struct drm_output *output, void intel_release_load_detect_pipe(struct drm_output *output, int dpms_mode) { struct drm_device *dev = output->dev; - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); struct drm_crtc *crtc = output->crtc; if (intel_output->load_detect_temp) { @@ -1191,7 +1191,7 @@ void intel_release_load_detect_pipe(struct drm_output *output, int dpms_mode) static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = crtc->driver_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int pipe = intel_crtc->pipe; u32 dpll = I915_READ((pipe == 0) ? DPLL_A : DPLL_B); u32 fp; @@ -1269,7 +1269,7 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, struct drm_crtc *crtc) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = crtc->driver_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int pipe = intel_crtc->pipe; struct drm_display_mode *mode; int htot = I915_READ((pipe == 0) ? HTOTAL_A : HTOTAL_B); @@ -1297,6 +1297,14 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, return mode; } +static void intel_crtc_destroy(struct drm_crtc *crtc) +{ + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + + drm_crtc_cleanup(crtc); + kfree(intel_crtc); +} + static const struct drm_crtc_helper_funcs intel_helper_funcs = { .mode_fixup = intel_crtc_mode_fixup, .mode_set = intel_crtc_mode_set, @@ -1311,24 +1319,20 @@ static const struct drm_crtc_funcs intel_crtc_funcs = { .cursor_move = intel_crtc_cursor_move, .gamma_set = intel_crtc_gamma_set, .set_config = drm_crtc_helper_set_config, + .destroy = intel_crtc_destroy, }; void intel_crtc_init(struct drm_device *dev, int pipe) { - struct drm_crtc *crtc; struct intel_crtc *intel_crtc; int i; - crtc = drm_crtc_create(dev, &intel_crtc_funcs); - if (crtc == NULL) + intel_crtc = kzalloc(sizeof(struct intel_crtc), GFP_KERNEL); + if (intel_crtc == NULL) return; - intel_crtc = kzalloc(sizeof(struct intel_crtc), GFP_KERNEL); - if (intel_crtc == NULL) { - kfree(crtc); - return; - } + drm_crtc_init(dev, &intel_crtc->base, &intel_crtc_funcs); intel_crtc->pipe = pipe; for (i = 0; i < 256; i++) { @@ -1339,9 +1343,7 @@ void intel_crtc_init(struct drm_device *dev, int pipe) intel_crtc->cursor_addr = 0; intel_crtc->dpms_mode = DPMSModeOff; - drm_crtc_helper_add(crtc, &intel_helper_funcs); - - crtc->driver_private = intel_crtc; + drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); } struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe) @@ -1349,7 +1351,7 @@ struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe) struct drm_crtc *crtc = NULL; list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - struct intel_crtc *intel_crtc = crtc->driver_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); if (intel_crtc->pipe == pipe) break; } @@ -1363,7 +1365,7 @@ int intel_output_clones(struct drm_device *dev, int type_mask) int entry = 0; list_for_each_entry(output, &dev->mode_config.output_list, head) { - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); if (type_mask & (1 << intel_output->type)) index_mask |= (1 << entry); entry++; @@ -1392,7 +1394,7 @@ static void intel_setup_outputs(struct drm_device *dev) intel_tv_init(dev); list_for_each_entry(output, &dev->mode_config.output_list, head) { - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); int crtc_mask = 0, clone_mask = 0; /* valid crtcs */ diff --git a/linux-core/intel_drv.h b/linux-core/intel_drv.h index 9f8ca8dd..82d2d703 100644 --- a/linux-core/intel_drv.h +++ b/linux-core/intel_drv.h @@ -47,6 +47,7 @@ struct intel_i2c_chan { }; struct intel_output { + struct drm_output base; int type; struct intel_i2c_chan *i2c_bus; /* for control functions */ struct intel_i2c_chan *ddc_bus; /* for DDC only stuff */ @@ -55,6 +56,7 @@ struct intel_output { }; struct intel_crtc { + struct drm_crtc base; int pipe; int plane; uint32_t cursor_addr; @@ -62,6 +64,9 @@ struct intel_crtc { int dpms_mode; }; +#define to_intel_crtc(x) container_of(x, struct intel_crtc, base) +#define to_intel_output(x) container_of(x, struct intel_output, base) + struct intel_i2c_chan *intel_i2c_create(struct drm_device *dev, const u32 reg, const char *name); void intel_i2c_destroy(struct intel_i2c_chan *chan); diff --git a/linux-core/intel_dvo.c b/linux-core/intel_dvo.c index 5a7da276..d9f39af6 100644 --- a/linux-core/intel_dvo.c +++ b/linux-core/intel_dvo.c @@ -88,7 +88,7 @@ struct intel_dvo_device intel_dvo_devices[] = { static void intel_dvo_dpms(struct drm_output *output, int mode) { struct drm_i915_private *dev_priv = output->dev->dev_private; - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); struct intel_dvo_device *dvo = intel_output->dev_priv; u32 dvo_reg = dvo->dvo_reg; u32 temp = I915_READ(dvo_reg); @@ -107,7 +107,7 @@ static void intel_dvo_dpms(struct drm_output *output, int mode) static void intel_dvo_save(struct drm_output *output) { struct drm_i915_private *dev_priv = output->dev->dev_private; - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); struct intel_dvo_device *dvo = intel_output->dev_priv; /* Each output should probably just save the registers it touches, @@ -123,7 +123,7 @@ static void intel_dvo_save(struct drm_output *output) static void intel_dvo_restore(struct drm_output *output) { struct drm_i915_private *dev_priv = output->dev->dev_private; - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); struct intel_dvo_device *dvo = intel_output->dev_priv; dvo->dev_ops->restore(dvo); @@ -136,7 +136,7 @@ static void intel_dvo_restore(struct drm_output *output) static int intel_dvo_mode_valid(struct drm_output *output, struct drm_display_mode *mode) { - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); struct intel_dvo_device *dvo = intel_output->dev_priv; if (mode->flags & V_DBLSCAN) @@ -158,7 +158,7 @@ static bool intel_dvo_mode_fixup(struct drm_output *output, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); struct intel_dvo_device *dvo = intel_output->dev_priv; /* If we have timings from the BIOS for the panel, put them in @@ -193,8 +193,8 @@ static void intel_dvo_mode_set(struct drm_output *output, { struct drm_device *dev = output->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = output->crtc->driver_private; - struct intel_output *intel_output = output->driver_private; + struct intel_crtc *intel_crtc = to_intel_crtc(output->crtc); + struct intel_output *intel_output = to_intel_output(output); struct intel_dvo_device *dvo = intel_output->dev_priv; int pipe = intel_crtc->pipe; u32 dvo_val; @@ -249,7 +249,7 @@ static void intel_dvo_mode_set(struct drm_output *output, */ static enum drm_output_status intel_dvo_detect(struct drm_output *output) { - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); struct intel_dvo_device *dvo = intel_output->dev_priv; return dvo->dev_ops->detect(dvo); @@ -257,7 +257,7 @@ static enum drm_output_status intel_dvo_detect(struct drm_output *output) static int intel_dvo_get_modes(struct drm_output *output) { - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); struct intel_dvo_device *dvo = intel_output->dev_priv; /* We should probably have an i2c driver get_modes function for those @@ -291,7 +291,7 @@ static int intel_dvo_get_modes(struct drm_output *output) static void intel_dvo_destroy (struct drm_output *output) { - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); struct intel_dvo_device *dvo = intel_output->dev_priv; if (dvo) { @@ -302,14 +302,12 @@ static void intel_dvo_destroy (struct drm_output *output) /* no need, in i830_dvoices[] now */ //kfree(dvo); } - if (intel_output) { - if (intel_output->i2c_bus) - intel_i2c_destroy(intel_output->i2c_bus); - if (intel_output->ddc_bus) - intel_i2c_destroy(intel_output->ddc_bus); - kfree(intel_output); - output->driver_private = NULL; - } + if (intel_output->i2c_bus) + intel_i2c_destroy(intel_output->i2c_bus); + if (intel_output->ddc_bus) + intel_i2c_destroy(intel_output->ddc_bus); + drm_output_cleanup(output); + kfree(output); } #ifdef RANDR_GET_CRTC_INTERFACE @@ -317,7 +315,7 @@ static struct drm_crtc *intel_dvo_get_crtc(struct drm_output *output) { struct drm_device *dev = output->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); struct intel_dvo_device *dvo = intel_output->dev_priv; int pipe = !!(I915_READ(dvo->dvo_reg) & SDVO_PIPE_B_SELECT); @@ -338,7 +336,7 @@ static const struct drm_output_funcs intel_dvo_output_funcs = { .restore = intel_dvo_restore, .detect = intel_dvo_detect, .get_modes = intel_dvo_get_modes, - .cleanup = intel_dvo_destroy, + .destroy = intel_dvo_destroy, .mode_valid = intel_dvo_mode_valid, }; @@ -353,7 +351,7 @@ intel_dvo_get_current_mode (struct drm_output *output) { struct drm_device *dev = output->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); struct intel_dvo_device *dvo = intel_output->dev_priv; uint32_t dvo_reg = dvo->dvo_reg; uint32_t dvo_val = I915_READ(dvo_reg); @@ -403,7 +401,7 @@ void intel_dvo_init(struct drm_device *dev) /* Now, try to find a controller */ for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) { - struct drm_output *output = NULL; + struct drm_output *output = &intel_output->base; int gpio; dvo = &intel_dvo_devices[i]; @@ -445,22 +443,17 @@ void intel_dvo_init(struct drm_device *dev) switch (dvo->type) { case INTEL_DVO_CHIP_TMDS: connector = ConnectorDVID; - output = drm_output_create(dev, &intel_dvo_output_funcs, + drm_output_init(dev, output, &intel_dvo_output_funcs, DRM_MODE_OUTPUT_TMDS); break; case INTEL_DVO_CHIP_LVDS: connector = ConnectorLVDS; - output = drm_output_create(dev, &intel_dvo_output_funcs, + drm_output_init(dev, output, &intel_dvo_output_funcs, DRM_MODE_OUTPUT_LVDS); break; } - if (output == NULL) { - dvo->dev_ops->destroy(dvo); - goto free_i2c; - } drm_output_helper_add(output, &intel_dvo_helper_funcs); - output->driver_private = intel_output; output->display_info.subpixel_order = SubPixelHorizontalRGB; output->interlace_allowed = false; output->doublescan_allowed = false; @@ -487,7 +480,6 @@ void intel_dvo_init(struct drm_device *dev) return; } -free_i2c: intel_i2c_destroy(intel_output->ddc_bus); /* Didn't find a chip, so tear down. */ if (i2cbus != NULL) diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index f71dd436..6781a47c 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -161,7 +161,7 @@ static bool intel_lvds_mode_fixup(struct drm_output *output, { struct drm_device *dev = output->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = output->crtc->driver_private; + struct intel_crtc *intel_crtc = to_intel_crtc(output->crtc); struct drm_output *tmp_output; /* Should never happen!! */ @@ -241,7 +241,7 @@ static void intel_lvds_mode_set(struct drm_output *output, { struct drm_device *dev = output->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = output->crtc->driver_private; + struct intel_crtc *intel_crtc = to_intel_crtc(output->crtc); u32 pfit_control; /* @@ -326,10 +326,11 @@ static int intel_lvds_get_modes(struct drm_output *output) */ static void intel_lvds_destroy(struct drm_output *output) { - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); intel_i2c_destroy(intel_output->ddc_bus); - kfree(output->driver_private); + drm_output_cleanup(output); + kfree(output); } static const struct drm_output_helper_funcs intel_lvds_helper_funcs = { @@ -345,7 +346,7 @@ static const struct drm_output_funcs intel_lvds_output_funcs = { .restore = intel_lvds_restore, .detect = intel_lvds_detect, .get_modes = intel_lvds_get_modes, - .cleanup = intel_lvds_destroy, + .destroy = intel_lvds_destroy, .mode_valid = intel_lvds_mode_valid, }; @@ -359,27 +360,25 @@ static const struct drm_output_funcs intel_lvds_output_funcs = { void intel_lvds_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_output *output; struct intel_output *intel_output; + struct drm_output *output; struct drm_display_mode *scan; /* *modes, *bios_mode; */ struct drm_crtc *crtc; u32 lvds; int pipe; - output = drm_output_create(dev, &intel_lvds_output_funcs, - DRM_MODE_OUTPUT_LVDS); - if (!output) - return; - intel_output = kmalloc(sizeof(struct intel_output), GFP_KERNEL); if (!intel_output) { - drm_output_destroy(output); return; } + output = &intel_output->base; + drm_output_init(dev, &intel_output->base, &intel_lvds_output_funcs, + DRM_MODE_OUTPUT_LVDS); + intel_output->type = INTEL_OUTPUT_LVDS; + drm_output_helper_add(output, &intel_lvds_helper_funcs); - output->driver_private = intel_output; output->display_info.subpixel_order = SubPixelHorizontalRGB; output->interlace_allowed = FALSE; output->doublescan_allowed = FALSE; @@ -400,6 +399,7 @@ void intel_lvds_init(struct drm_device *dev) if (!intel_output->ddc_bus) { dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " "failed.\n"); + intel_lvds_destroy(output); return; } @@ -487,5 +487,5 @@ out: failed: DRM_DEBUG("No LVDS modes found, disabling.\n"); - drm_output_destroy(output); /* calls intel_lvds_destroy above */ + intel_lvds_destroy(output); } diff --git a/linux-core/intel_modes.c b/linux-core/intel_modes.c index f8bf496c..8e9a506a 100644 --- a/linux-core/intel_modes.c +++ b/linux-core/intel_modes.c @@ -15,7 +15,7 @@ */ bool intel_ddc_probe(struct drm_output *output) { - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); u8 out_buf[] = { 0x0, 0x0}; u8 buf[2]; int ret; @@ -49,7 +49,7 @@ bool intel_ddc_probe(struct drm_output *output) */ int intel_ddc_get_modes(struct drm_output *output) { - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); struct edid *edid; int ret = 0; diff --git a/linux-core/intel_sdvo.c b/linux-core/intel_sdvo.c index 41da034d..f4b1c6ef 100644 --- a/linux-core/intel_sdvo.c +++ b/linux-core/intel_sdvo.c @@ -64,7 +64,7 @@ void intel_sdvo_write_sdvox(struct drm_output *output, u32 val) { struct drm_device *dev = output->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; u32 bval = val, cval = val; int i; @@ -91,7 +91,7 @@ void intel_sdvo_write_sdvox(struct drm_output *output, u32 val) static bool intel_sdvo_read_byte(struct drm_output *output, u8 addr, u8 *ch) { - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; u8 out_buf[2]; u8 buf[2]; @@ -129,7 +129,7 @@ static bool intel_sdvo_read_byte(struct drm_output *output, u8 addr, static bool intel_sdvo_write_byte(struct drm_output *output, int addr, u8 ch) { - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); u8 out_buf[2]; struct i2c_msg msgs[] = { { @@ -201,7 +201,7 @@ const static struct _sdvo_cmd_name { static void intel_sdvo_write_cmd(struct drm_output *output, u8 cmd, void *args, int args_len) { - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; int i; @@ -242,7 +242,7 @@ static const char *cmd_status_names[] = { static u8 intel_sdvo_read_response(struct drm_output *output, void *response, int response_len) { - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; int i; u8 status; @@ -493,7 +493,7 @@ static bool intel_sdvo_set_output_timing(struct drm_output *output, static bool intel_sdvo_get_preferred_input_timing(struct drm_output *output, struct intel_sdvo_dtd *dtd) { - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; u8 status; @@ -563,8 +563,8 @@ static void intel_sdvo_mode_set(struct drm_output *output, struct drm_device *dev = output->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct drm_crtc *crtc = output->crtc; - struct intel_crtc *intel_crtc = crtc->driver_private; - struct intel_output *intel_output = output->driver_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct intel_output *intel_output = to_intel_output(output); struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; u16 width, height; u16 h_blank_len, h_sync_len, v_blank_len, v_sync_len; @@ -693,7 +693,7 @@ static void intel_sdvo_dpms(struct drm_output *output, int mode) { struct drm_device *dev = output->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; u32 temp; @@ -743,7 +743,7 @@ static void intel_sdvo_save(struct drm_output *output) { struct drm_device *dev = output->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; int o; @@ -780,7 +780,7 @@ static void intel_sdvo_restore(struct drm_output *output) { struct drm_device *dev = output->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; int o; int i; @@ -828,7 +828,7 @@ static void intel_sdvo_restore(struct drm_output *output) static int intel_sdvo_mode_valid(struct drm_output *output, struct drm_display_mode *mode) { - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; if (mode->flags & V_DBLSCAN) @@ -863,7 +863,7 @@ struct drm_output* intel_sdvo_find(struct drm_device *dev, int sdvoB) /* find the sdvo output */ list_for_each_entry(output, &dev->mode_config.output_list, head) { - iout = output->driver_private; + iout = to_intel_output(output); if (iout->type != INTEL_OUTPUT_SDVO) continue; @@ -961,15 +961,13 @@ static int intel_sdvo_get_modes(struct drm_output *output) static void intel_sdvo_destroy(struct drm_output *output) { - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); if (intel_output->i2c_bus) intel_i2c_destroy(intel_output->i2c_bus); - if (intel_output) { - kfree(intel_output); - output->driver_private = NULL; - } + drm_output_cleanup(output); + kfree(intel_output); } static const struct drm_output_helper_funcs intel_sdvo_helper_funcs = { @@ -985,7 +983,7 @@ static const struct drm_output_funcs intel_sdvo_output_funcs = { .restore = intel_sdvo_restore, .detect = intel_sdvo_detect, .get_modes = intel_sdvo_get_modes, - .cleanup = intel_sdvo_destroy, + .destroy = intel_sdvo_destroy, .mode_valid = intel_sdvo_mode_valid, }; @@ -1000,21 +998,19 @@ void intel_sdvo_init(struct drm_device *dev, int output_device) int i; int output_type, output_id; - output = drm_output_create(dev, &intel_sdvo_output_funcs, - DRM_MODE_OUTPUT_NONE); - if (!output) - return; - intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); if (!intel_output) { - drm_output_destroy(output); return; } + output = &intel_output->base; + + drm_output_init(dev, output, &intel_sdvo_output_funcs, + DRM_MODE_OUTPUT_NONE); + sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1); intel_output->type = INTEL_OUTPUT_SDVO; drm_output_helper_add(output, &intel_sdvo_helper_funcs); - output->driver_private = intel_output; output->interlace_allowed = 0; output->doublescan_allowed = 0; @@ -1025,7 +1021,7 @@ void intel_sdvo_init(struct drm_device *dev, int output_device) i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC"); if (i2cbus == NULL) { - drm_output_destroy(output); + intel_sdvo_destroy(output); return; } @@ -1049,7 +1045,7 @@ void intel_sdvo_init(struct drm_device *dev, int output_device) if (!intel_sdvo_read_byte(output, i, &ch[i])) { DRM_DEBUG("No SDVO device found on SDVO%c\n", output_device == SDVOB ? 'B' : 'C'); - drm_output_destroy(output); + intel_sdvo_destroy(output); return; } } @@ -1095,7 +1091,7 @@ void intel_sdvo_init(struct drm_device *dev, int output_device) DRM_DEBUG("%s: No active RGB or TMDS outputs (0x%02x%02x)\n", SDVO_NAME(sdvo_priv), bytes[0], bytes[1]); - drm_output_destroy(output); + intel_sdvo_destroy(output); return; } diff --git a/linux-core/intel_tv.c b/linux-core/intel_tv.c index 18fb1f37..e3e78a9f 100644 --- a/linux-core/intel_tv.c +++ b/linux-core/intel_tv.c @@ -920,7 +920,7 @@ intel_tv_save(struct drm_output *output) { struct drm_device *dev = output->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); struct intel_tv_priv *tv_priv = intel_output->dev_priv; int i; @@ -970,7 +970,7 @@ intel_tv_restore(struct drm_output *output) { struct drm_device *dev = output->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); struct intel_tv_priv *tv_priv = intel_output->dev_priv; struct drm_crtc *crtc = output->crtc; struct intel_crtc *intel_crtc; @@ -980,7 +980,7 @@ intel_tv_restore(struct drm_output *output) if (!crtc) return; - intel_crtc = crtc->driver_private; + intel_crtc = to_intel_crtc(crtc); I915_WRITE(TV_H_CTL_1, tv_priv->save_TV_H_CTL_1); I915_WRITE(TV_H_CTL_2, tv_priv->save_TV_H_CTL_2); I915_WRITE(TV_H_CTL_3, tv_priv->save_TV_H_CTL_3); @@ -1069,7 +1069,7 @@ intel_tv_mode_lookup (char *tv_format) static const struct tv_mode * intel_tv_mode_find (struct drm_output *output) { - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); struct intel_tv_priv *tv_priv = intel_output->dev_priv; return intel_tv_mode_lookup(tv_priv->tv_format); @@ -1117,8 +1117,8 @@ intel_tv_mode_set(struct drm_output *output, struct drm_display_mode *mode, struct drm_device *dev = output->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct drm_crtc *crtc = output->crtc; - struct intel_crtc *intel_crtc = crtc->driver_private; - struct intel_output *intel_output = output->driver_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct intel_output *intel_output = to_intel_output(output); struct intel_tv_priv *tv_priv = intel_output->dev_priv; const struct tv_mode *tv_mode = intel_tv_mode_find(output); u32 tv_ctl; @@ -1359,7 +1359,7 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct drm_output *output) { struct drm_device *dev = output->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); u32 pipeastat, pipeastat_save; u32 tv_ctl, save_tv_ctl; u32 tv_dac, save_tv_dac; @@ -1440,7 +1440,7 @@ intel_tv_detect(struct drm_output *output) { struct drm_crtc *crtc; struct drm_display_mode mode; - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); struct intel_tv_priv *tv_priv = intel_output->dev_priv; int dpms_mode; int type = tv_priv->type; @@ -1547,17 +1547,20 @@ intel_tv_get_modes(struct drm_output *output) static void intel_tv_destroy (struct drm_output *output) { - if (output->driver_private) - drm_free(output->driver_private, sizeof(struct intel_tv_priv), - DRM_MEM_DRIVER); + struct intel_output *intel_output = to_intel_output(output); + + drm_output_cleanup(output); + drm_free(intel_output, sizeof(struct intel_output) + sizeof(struct intel_tv_priv), + DRM_MEM_DRIVER); } + static bool intel_tv_set_property(struct drm_output *output, struct drm_property *property, uint64_t val) { struct drm_device *dev = output->dev; - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); struct intel_tv_priv *tv_priv = intel_output->dev_priv; int ret = 0; @@ -1604,7 +1607,7 @@ static const struct drm_output_funcs intel_tv_output_funcs = { .mode_valid = intel_tv_mode_valid, .detect = intel_tv_detect, .get_modes = intel_tv_get_modes, - .cleanup = intel_tv_destroy, + .destroy = intel_tv_destroy, .set_property = intel_tv_set_property, }; @@ -1649,18 +1652,15 @@ intel_tv_init(struct drm_device *dev) (tv_dac_off & TVDAC_STATE_CHG_EN) != 0) return; - output = drm_output_create(dev, &intel_tv_output_funcs, - DRM_MODE_OUTPUT_TVDAC); - - if (!output) - return; - intel_output = drm_calloc(1, sizeof(struct intel_output) + sizeof(struct intel_tv_priv), DRM_MEM_DRIVER); if (!intel_output) { - drm_output_destroy(output); return; } + output = &intel_output->base; + + drm_output_init(dev, output, &intel_tv_output_funcs, + DRM_MODE_OUTPUT_TVDAC); tv_priv = (struct intel_tv_priv *)(intel_output + 1); intel_output->type = INTEL_OUTPUT_TVOUT; @@ -1678,7 +1678,6 @@ intel_tv_init(struct drm_device *dev) tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL); drm_output_helper_add(output, &intel_tv_helper_funcs); - output->driver_private = intel_output; output->interlace_allowed = FALSE; output->doublescan_allowed = FALSE; diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index ccedc70e..abf916ed 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -461,7 +461,7 @@ static void i915_hotplug_tv(struct drm_device *dev) /* find the crt output */ list_for_each_entry(output, &dev->mode_config.output_list, head) { - iout = output->driver_private; + iout = to_intel_output(output); if (iout->type == INTEL_OUTPUT_TVOUT) break; else @@ -488,7 +488,7 @@ static void i915_hotplug_crt(struct drm_device *dev, bool isconnected) /* find the crt output */ list_for_each_entry(output, &dev->mode_config.output_list, head) { - iout = output->driver_private; + iout = to_intel_output(output); if (iout->type == INTEL_OUTPUT_ANALOG) break; else