LCOV - code coverage report
Current view: top level - dev/pci/drm/i915 - intel_hotplug.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 198 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 11 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright © 2015 Intel Corporation
       3             :  *
       4             :  * Permission is hereby granted, free of charge, to any person obtaining a
       5             :  * copy of this software and associated documentation files (the "Software"),
       6             :  * to deal in the Software without restriction, including without limitation
       7             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
       8             :  * and/or sell copies of the Software, and to permit persons to whom the
       9             :  * Software is furnished to do so, subject to the following conditions:
      10             :  *
      11             :  * The above copyright notice and this permission notice (including the next
      12             :  * paragraph) shall be included in all copies or substantial portions of the
      13             :  * Software.
      14             :  *
      15             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      16             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      17             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      18             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      19             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      20             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
      21             :  * IN THE SOFTWARE.
      22             :  */
      23             : 
      24             : #ifdef __linux__
      25             : #include <linux/kernel.h>
      26             : #endif
      27             : 
      28             : #include <dev/pci/drm/drmP.h>
      29             : #include <dev/pci/drm/i915_drm.h>
      30             : 
      31             : #include "i915_drv.h"
      32             : #include "intel_drv.h"
      33             : 
      34             : /**
      35             :  * DOC: Hotplug
      36             :  *
      37             :  * Simply put, hotplug occurs when a display is connected to or disconnected
      38             :  * from the system. However, there may be adapters and docking stations and
      39             :  * Display Port short pulses and MST devices involved, complicating matters.
      40             :  *
      41             :  * Hotplug in i915 is handled in many different levels of abstraction.
      42             :  *
      43             :  * The platform dependent interrupt handling code in i915_irq.c enables,
      44             :  * disables, and does preliminary handling of the interrupts. The interrupt
      45             :  * handlers gather the hotplug detect (HPD) information from relevant registers
      46             :  * into a platform independent mask of hotplug pins that have fired.
      47             :  *
      48             :  * The platform independent interrupt handler intel_hpd_irq_handler() in
      49             :  * intel_hotplug.c does hotplug irq storm detection and mitigation, and passes
      50             :  * further processing to appropriate bottom halves (Display Port specific and
      51             :  * regular hotplug).
      52             :  *
      53             :  * The Display Port work function i915_digport_work_func() calls into
      54             :  * intel_dp_hpd_pulse() via hooks, which handles DP short pulses and DP MST long
      55             :  * pulses, with failures and non-MST long pulses triggering regular hotplug
      56             :  * processing on the connector.
      57             :  *
      58             :  * The regular hotplug work function i915_hotplug_work_func() calls connector
      59             :  * detect hooks, and, if connector status changes, triggers sending of hotplug
      60             :  * uevent to userspace via drm_kms_helper_hotplug_event().
      61             :  *
      62             :  * Finally, the userspace is responsible for triggering a modeset upon receiving
      63             :  * the hotplug uevent, disabling or enabling the crtc as needed.
      64             :  *
      65             :  * The hotplug interrupt storm detection and mitigation code keeps track of the
      66             :  * number of interrupts per hotplug pin per a period of time, and if the number
      67             :  * of interrupts exceeds a certain threshold, the interrupt is disabled for a
      68             :  * while before being re-enabled. The intention is to mitigate issues raising
      69             :  * from broken hardware triggering massive amounts of interrupts and grinding
      70             :  * the system to a halt.
      71             :  *
      72             :  * Current implementation expects that hotplug interrupt storm will not be
      73             :  * seen when display port sink is connected, hence on platforms whose DP
      74             :  * callback is handled by i915_digport_work_func reenabling of hpd is not
      75             :  * performed (it was never expected to be disabled in the first place ;) )
      76             :  * this is specific to DP sinks handled by this routine and any other display
      77             :  * such as HDMI or DVI enabled on the same port will have proper logic since
      78             :  * it will use i915_hotplug_work_func where this logic is handled.
      79             :  */
      80             : 
      81           0 : bool intel_hpd_pin_to_port(enum hpd_pin pin, enum port *port)
      82             : {
      83           0 :         switch (pin) {
      84             :         case HPD_PORT_A:
      85           0 :                 *port = PORT_A;
      86           0 :                 return true;
      87             :         case HPD_PORT_B:
      88           0 :                 *port = PORT_B;
      89           0 :                 return true;
      90             :         case HPD_PORT_C:
      91           0 :                 *port = PORT_C;
      92           0 :                 return true;
      93             :         case HPD_PORT_D:
      94           0 :                 *port = PORT_D;
      95           0 :                 return true;
      96             :         case HPD_PORT_E:
      97           0 :                 *port = PORT_E;
      98           0 :                 return true;
      99             :         default:
     100           0 :                 return false;   /* no hpd */
     101             :         }
     102           0 : }
     103             : 
     104             : #define HPD_STORM_DETECT_PERIOD         1000
     105             : #define HPD_STORM_THRESHOLD             5
     106             : #define HPD_STORM_REENABLE_DELAY        (2 * 60 * 1000)
     107             : 
     108             : /**
     109             :  * intel_hpd_irq_storm_detect - gather stats and detect HPD irq storm on a pin
     110             :  * @dev_priv: private driver data pointer
     111             :  * @pin: the pin to gather stats on
     112             :  *
     113             :  * Gather stats about HPD irqs from the specified @pin, and detect irq
     114             :  * storms. Only the pin specific stats and state are changed, the caller is
     115             :  * responsible for further action.
     116             :  *
     117             :  * @HPD_STORM_THRESHOLD irqs are allowed within @HPD_STORM_DETECT_PERIOD ms,
     118             :  * otherwise it's considered an irq storm, and the irq state is set to
     119             :  * @HPD_MARK_DISABLED.
     120             :  *
     121             :  * Return true if an irq storm was detected on @pin.
     122             :  */
     123           0 : static bool intel_hpd_irq_storm_detect(struct drm_i915_private *dev_priv,
     124             :                                        enum hpd_pin pin)
     125             : {
     126           0 :         unsigned long start = dev_priv->hotplug.stats[pin].last_jiffies;
     127           0 :         unsigned long end = start + msecs_to_jiffies(HPD_STORM_DETECT_PERIOD);
     128             :         bool storm = false;
     129             : 
     130           0 :         if (!time_in_range(jiffies, start, end)) {
     131           0 :                 dev_priv->hotplug.stats[pin].last_jiffies = jiffies;
     132           0 :                 dev_priv->hotplug.stats[pin].count = 0;
     133             :                 DRM_DEBUG_KMS("Received HPD interrupt on PIN %d - cnt: 0\n", pin);
     134           0 :         } else if (dev_priv->hotplug.stats[pin].count > HPD_STORM_THRESHOLD) {
     135           0 :                 dev_priv->hotplug.stats[pin].state = HPD_MARK_DISABLED;
     136             :                 DRM_DEBUG_KMS("HPD interrupt storm detected on PIN %d\n", pin);
     137             :                 storm = true;
     138           0 :         } else {
     139           0 :                 dev_priv->hotplug.stats[pin].count++;
     140             :                 DRM_DEBUG_KMS("Received HPD interrupt on PIN %d - cnt: %d\n", pin,
     141             :                               dev_priv->hotplug.stats[pin].count);
     142             :         }
     143             : 
     144           0 :         return storm;
     145             : }
     146             : 
     147           0 : static void intel_hpd_irq_storm_disable(struct drm_i915_private *dev_priv)
     148             : {
     149           0 :         struct drm_device *dev = dev_priv->dev;
     150           0 :         struct drm_mode_config *mode_config = &dev->mode_config;
     151             :         struct intel_connector *intel_connector;
     152             :         struct intel_encoder *intel_encoder;
     153             :         struct drm_connector *connector;
     154             :         enum hpd_pin pin;
     155             :         bool hpd_disabled = false;
     156             : 
     157           0 :         assert_spin_locked(&dev_priv->irq_lock);
     158             : 
     159           0 :         list_for_each_entry(connector, &mode_config->connector_list, head) {
     160           0 :                 if (connector->polled != DRM_CONNECTOR_POLL_HPD)
     161             :                         continue;
     162             : 
     163           0 :                 intel_connector = to_intel_connector(connector);
     164           0 :                 intel_encoder = intel_connector->encoder;
     165           0 :                 if (!intel_encoder)
     166             :                         continue;
     167             : 
     168           0 :                 pin = intel_encoder->hpd_pin;
     169           0 :                 if (pin == HPD_NONE ||
     170           0 :                     dev_priv->hotplug.stats[pin].state != HPD_MARK_DISABLED)
     171             :                         continue;
     172             : 
     173             :                 DRM_INFO("HPD interrupt storm detected on connector %s: "
     174             :                          "switching from hotplug detection to polling\n",
     175             :                          connector->name);
     176             : 
     177           0 :                 dev_priv->hotplug.stats[pin].state = HPD_DISABLED;
     178           0 :                 connector->polled = DRM_CONNECTOR_POLL_CONNECT
     179             :                         | DRM_CONNECTOR_POLL_DISCONNECT;
     180             :                 hpd_disabled = true;
     181           0 :         }
     182             : 
     183             :         /* Enable polling and queue hotplug re-enabling. */
     184           0 :         if (hpd_disabled) {
     185           0 :                 drm_kms_helper_poll_enable_locked(dev);
     186           0 :                 mod_delayed_work(system_wq, &dev_priv->hotplug.reenable_work,
     187           0 :                                  msecs_to_jiffies(HPD_STORM_REENABLE_DELAY));
     188           0 :         }
     189           0 : }
     190             : 
     191           0 : static void intel_hpd_irq_storm_reenable_work(struct work_struct *work)
     192             : {
     193             :         struct drm_i915_private *dev_priv =
     194           0 :                 container_of(work, typeof(*dev_priv),
     195             :                              hotplug.reenable_work.work);
     196           0 :         struct drm_device *dev = dev_priv->dev;
     197           0 :         struct drm_mode_config *mode_config = &dev->mode_config;
     198             :         int i;
     199             : 
     200           0 :         intel_runtime_pm_get(dev_priv);
     201             : 
     202           0 :         spin_lock_irq(&dev_priv->irq_lock);
     203           0 :         for_each_hpd_pin(i) {
     204             :                 struct drm_connector *connector;
     205             : 
     206           0 :                 if (dev_priv->hotplug.stats[i].state != HPD_DISABLED)
     207           0 :                         continue;
     208             : 
     209           0 :                 dev_priv->hotplug.stats[i].state = HPD_ENABLED;
     210             : 
     211           0 :                 list_for_each_entry(connector, &mode_config->connector_list, head) {
     212           0 :                         struct intel_connector *intel_connector = to_intel_connector(connector);
     213             : 
     214           0 :                         if (intel_connector->encoder->hpd_pin == i) {
     215           0 :                                 if (connector->polled != intel_connector->polled)
     216             :                                         DRM_DEBUG_DRIVER("Reenabling HPD on connector %s\n",
     217             :                                                          connector->name);
     218           0 :                                 connector->polled = intel_connector->polled;
     219           0 :                                 if (!connector->polled)
     220           0 :                                         connector->polled = DRM_CONNECTOR_POLL_HPD;
     221             :                         }
     222             :                 }
     223           0 :         }
     224           0 :         if (dev_priv->display.hpd_irq_setup)
     225           0 :                 dev_priv->display.hpd_irq_setup(dev);
     226           0 :         spin_unlock_irq(&dev_priv->irq_lock);
     227             : 
     228           0 :         intel_runtime_pm_put(dev_priv);
     229           0 : }
     230             : 
     231           0 : static bool intel_hpd_irq_event(struct drm_device *dev,
     232             :                                 struct drm_connector *connector)
     233             : {
     234             :         enum drm_connector_status old_status;
     235             : 
     236           0 :         WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
     237           0 :         old_status = connector->status;
     238             : 
     239           0 :         connector->status = connector->funcs->detect(connector, false);
     240           0 :         if (old_status == connector->status)
     241           0 :                 return false;
     242             : 
     243             :         DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n",
     244             :                       connector->base.id,
     245             :                       connector->name,
     246             :                       drm_get_connector_status_name(old_status),
     247             :                       drm_get_connector_status_name(connector->status));
     248             : 
     249           0 :         return true;
     250           0 : }
     251             : 
     252           0 : static void i915_digport_work_func(struct work_struct *work)
     253             : {
     254             :         struct drm_i915_private *dev_priv =
     255           0 :                 container_of(work, struct drm_i915_private, hotplug.dig_port_work);
     256             :         u32 long_port_mask, short_port_mask;
     257             :         struct intel_digital_port *intel_dig_port;
     258             :         int i;
     259             :         u32 old_bits = 0;
     260             : 
     261           0 :         spin_lock_irq(&dev_priv->irq_lock);
     262           0 :         long_port_mask = dev_priv->hotplug.long_port_mask;
     263           0 :         dev_priv->hotplug.long_port_mask = 0;
     264           0 :         short_port_mask = dev_priv->hotplug.short_port_mask;
     265           0 :         dev_priv->hotplug.short_port_mask = 0;
     266           0 :         spin_unlock_irq(&dev_priv->irq_lock);
     267             : 
     268           0 :         for (i = 0; i < I915_MAX_PORTS; i++) {
     269             :                 bool valid = false;
     270             :                 bool long_hpd = false;
     271           0 :                 intel_dig_port = dev_priv->hotplug.irq_port[i];
     272           0 :                 if (!intel_dig_port || !intel_dig_port->hpd_pulse)
     273           0 :                         continue;
     274             : 
     275           0 :                 if (long_port_mask & (1 << i))  {
     276             :                         valid = true;
     277             :                         long_hpd = true;
     278           0 :                 } else if (short_port_mask & (1 << i))
     279           0 :                         valid = true;
     280             : 
     281           0 :                 if (valid) {
     282             :                         enum irqreturn ret;
     283             : 
     284           0 :                         ret = intel_dig_port->hpd_pulse(intel_dig_port, long_hpd);
     285           0 :                         if (ret == IRQ_NONE) {
     286             :                                 /* fall back to old school hpd */
     287           0 :                                 old_bits |= (1 << intel_dig_port->base.hpd_pin);
     288           0 :                         }
     289           0 :                 }
     290           0 :         }
     291             : 
     292           0 :         if (old_bits) {
     293           0 :                 spin_lock_irq(&dev_priv->irq_lock);
     294           0 :                 dev_priv->hotplug.event_bits |= old_bits;
     295           0 :                 spin_unlock_irq(&dev_priv->irq_lock);
     296           0 :                 schedule_work(&dev_priv->hotplug.hotplug_work);
     297           0 :         }
     298           0 : }
     299             : 
     300             : /*
     301             :  * Handle hotplug events outside the interrupt handler proper.
     302             :  */
     303           0 : static void i915_hotplug_work_func(struct work_struct *work)
     304             : {
     305             :         struct drm_i915_private *dev_priv =
     306           0 :                 container_of(work, struct drm_i915_private, hotplug.hotplug_work);
     307           0 :         struct drm_device *dev = dev_priv->dev;
     308           0 :         struct drm_mode_config *mode_config = &dev->mode_config;
     309             :         struct intel_connector *intel_connector;
     310             :         struct intel_encoder *intel_encoder;
     311             :         struct drm_connector *connector;
     312             :         bool changed = false;
     313             :         u32 hpd_event_bits;
     314             : 
     315           0 :         mutex_lock(&mode_config->mutex);
     316             :         DRM_DEBUG_KMS("running encoder hotplug functions\n");
     317             : 
     318           0 :         spin_lock_irq(&dev_priv->irq_lock);
     319             : 
     320           0 :         hpd_event_bits = dev_priv->hotplug.event_bits;
     321           0 :         dev_priv->hotplug.event_bits = 0;
     322             : 
     323             :         /* Disable hotplug on connectors that hit an irq storm. */
     324           0 :         intel_hpd_irq_storm_disable(dev_priv);
     325             : 
     326           0 :         spin_unlock_irq(&dev_priv->irq_lock);
     327             : 
     328           0 :         list_for_each_entry(connector, &mode_config->connector_list, head) {
     329           0 :                 intel_connector = to_intel_connector(connector);
     330           0 :                 if (!intel_connector->encoder)
     331             :                         continue;
     332             :                 intel_encoder = intel_connector->encoder;
     333           0 :                 if (hpd_event_bits & (1 << intel_encoder->hpd_pin)) {
     334             :                         DRM_DEBUG_KMS("Connector %s (pin %i) received hotplug event.\n",
     335             :                                       connector->name, intel_encoder->hpd_pin);
     336           0 :                         if (intel_encoder->hot_plug)
     337           0 :                                 intel_encoder->hot_plug(intel_encoder);
     338           0 :                         if (intel_hpd_irq_event(dev, connector))
     339           0 :                                 changed = true;
     340             :                 }
     341             :         }
     342           0 :         mutex_unlock(&mode_config->mutex);
     343             : 
     344           0 :         if (changed)
     345           0 :                 drm_kms_helper_hotplug_event(dev);
     346           0 : }
     347             : 
     348             : 
     349             : /**
     350             :  * intel_hpd_irq_handler - main hotplug irq handler
     351             :  * @dev: drm device
     352             :  * @pin_mask: a mask of hpd pins that have triggered the irq
     353             :  * @long_mask: a mask of hpd pins that may be long hpd pulses
     354             :  *
     355             :  * This is the main hotplug irq handler for all platforms. The platform specific
     356             :  * irq handlers call the platform specific hotplug irq handlers, which read and
     357             :  * decode the appropriate registers into bitmasks about hpd pins that have
     358             :  * triggered (@pin_mask), and which of those pins may be long pulses
     359             :  * (@long_mask). The @long_mask is ignored if the port corresponding to the pin
     360             :  * is not a digital port.
     361             :  *
     362             :  * Here, we do hotplug irq storm detection and mitigation, and pass further
     363             :  * processing to appropriate bottom halves.
     364             :  */
     365           0 : void intel_hpd_irq_handler(struct drm_device *dev,
     366             :                            u32 pin_mask, u32 long_mask)
     367             : {
     368           0 :         struct drm_i915_private *dev_priv = dev->dev_private;
     369             :         int i;
     370           0 :         enum port port;
     371             :         bool storm_detected = false;
     372             :         bool queue_dig = false, queue_hp = false;
     373             :         bool is_dig_port;
     374             : 
     375           0 :         if (!pin_mask)
     376           0 :                 return;
     377             : 
     378           0 :         spin_lock(&dev_priv->irq_lock);
     379           0 :         for_each_hpd_pin(i) {
     380           0 :                 if (!(BIT(i) & pin_mask))
     381             :                         continue;
     382             : 
     383           0 :                 is_dig_port = intel_hpd_pin_to_port(i, &port) &&
     384           0 :                               dev_priv->hotplug.irq_port[port];
     385             : 
     386           0 :                 if (is_dig_port) {
     387           0 :                         bool long_hpd = long_mask & BIT(i);
     388             : 
     389             :                         DRM_DEBUG_DRIVER("digital hpd port %c - %s\n", port_name(port),
     390             :                                          long_hpd ? "long" : "short");
     391             :                         /*
     392             :                          * For long HPD pulses we want to have the digital queue happen,
     393             :                          * but we still want HPD storm detection to function.
     394             :                          */
     395             :                         queue_dig = true;
     396           0 :                         if (long_hpd) {
     397           0 :                                 dev_priv->hotplug.long_port_mask |= (1 << port);
     398             :                         } else {
     399             :                                 /* for short HPD just trigger the digital queue */
     400           0 :                                 dev_priv->hotplug.short_port_mask |= (1 << port);
     401           0 :                                 continue;
     402             :                         }
     403           0 :                 }
     404             : 
     405           0 :                 if (dev_priv->hotplug.stats[i].state == HPD_DISABLED) {
     406             :                         /*
     407             :                          * On GMCH platforms the interrupt mask bits only
     408             :                          * prevent irq generation, not the setting of the
     409             :                          * hotplug bits itself. So only WARN about unexpected
     410             :                          * interrupts on saner platforms.
     411             :                          */
     412           0 :                         WARN_ONCE(INTEL_INFO(dev)->gen >= 5 && !IS_VALLEYVIEW(dev),
     413             :                                   "Received HPD interrupt on pin %d although disabled\n", i);
     414           0 :                         continue;
     415             :                 }
     416             : 
     417           0 :                 if (dev_priv->hotplug.stats[i].state != HPD_ENABLED)
     418             :                         continue;
     419             : 
     420           0 :                 if (!is_dig_port) {
     421           0 :                         dev_priv->hotplug.event_bits |= BIT(i);
     422             :                         queue_hp = true;
     423           0 :                 }
     424             : 
     425           0 :                 if (intel_hpd_irq_storm_detect(dev_priv, i)) {
     426           0 :                         dev_priv->hotplug.event_bits &= ~BIT(i);
     427             :                         storm_detected = true;
     428           0 :                 }
     429             :         }
     430             : 
     431           0 :         if (storm_detected)
     432           0 :                 dev_priv->display.hpd_irq_setup(dev);
     433           0 :         spin_unlock(&dev_priv->irq_lock);
     434             : 
     435             :         /*
     436             :          * Our hotplug handler can grab modeset locks (by calling down into the
     437             :          * fb helpers). Hence it must not be run on our own dev-priv->wq work
     438             :          * queue for otherwise the flush_work in the pageflip code will
     439             :          * deadlock.
     440             :          */
     441           0 :         if (queue_dig)
     442           0 :                 queue_work(dev_priv->hotplug.dp_wq, &dev_priv->hotplug.dig_port_work);
     443           0 :         if (queue_hp)
     444           0 :                 schedule_work(&dev_priv->hotplug.hotplug_work);
     445           0 : }
     446             : 
     447             : /**
     448             :  * intel_hpd_init - initializes and enables hpd support
     449             :  * @dev_priv: i915 device instance
     450             :  *
     451             :  * This function enables the hotplug support. It requires that interrupts have
     452             :  * already been enabled with intel_irq_init_hw(). From this point on hotplug and
     453             :  * poll request can run concurrently to other code, so locking rules must be
     454             :  * obeyed.
     455             :  *
     456             :  * This is a separate step from interrupt enabling to simplify the locking rules
     457             :  * in the driver load and resume code.
     458             :  */
     459           0 : void intel_hpd_init(struct drm_i915_private *dev_priv)
     460             : {
     461           0 :         struct drm_device *dev = dev_priv->dev;
     462           0 :         struct drm_mode_config *mode_config = &dev->mode_config;
     463             :         struct drm_connector *connector;
     464             :         int i;
     465             : 
     466           0 :         for_each_hpd_pin(i) {
     467           0 :                 dev_priv->hotplug.stats[i].count = 0;
     468           0 :                 dev_priv->hotplug.stats[i].state = HPD_ENABLED;
     469             :         }
     470           0 :         list_for_each_entry(connector, &mode_config->connector_list, head) {
     471           0 :                 struct intel_connector *intel_connector = to_intel_connector(connector);
     472           0 :                 connector->polled = intel_connector->polled;
     473             : 
     474             :                 /* MST has a dynamic intel_connector->encoder and it's reprobing
     475             :                  * is all handled by the MST helpers. */
     476           0 :                 if (intel_connector->mst_port)
     477           0 :                         continue;
     478             : 
     479           0 :                 if (!connector->polled && I915_HAS_HOTPLUG(dev) &&
     480           0 :                     intel_connector->encoder->hpd_pin > HPD_NONE)
     481           0 :                         connector->polled = DRM_CONNECTOR_POLL_HPD;
     482           0 :         }
     483             : 
     484             :         /*
     485             :          * Interrupt setup is already guaranteed to be single-threaded, this is
     486             :          * just to make the assert_spin_locked checks happy.
     487             :          */
     488           0 :         spin_lock_irq(&dev_priv->irq_lock);
     489           0 :         if (dev_priv->display.hpd_irq_setup)
     490           0 :                 dev_priv->display.hpd_irq_setup(dev);
     491           0 :         spin_unlock_irq(&dev_priv->irq_lock);
     492           0 : }
     493             : 
     494           0 : void intel_hpd_init_work(struct drm_i915_private *dev_priv)
     495             : {
     496           0 :         INIT_WORK(&dev_priv->hotplug.hotplug_work, i915_hotplug_work_func);
     497           0 :         INIT_WORK(&dev_priv->hotplug.dig_port_work, i915_digport_work_func);
     498           0 :         INIT_DELAYED_WORK(&dev_priv->hotplug.reenable_work,
     499             :                           intel_hpd_irq_storm_reenable_work);
     500           0 : }
     501             : 
     502           0 : void intel_hpd_cancel_work(struct drm_i915_private *dev_priv)
     503             : {
     504           0 :         spin_lock_irq(&dev_priv->irq_lock);
     505             : 
     506           0 :         dev_priv->hotplug.long_port_mask = 0;
     507           0 :         dev_priv->hotplug.short_port_mask = 0;
     508           0 :         dev_priv->hotplug.event_bits = 0;
     509             : 
     510           0 :         spin_unlock_irq(&dev_priv->irq_lock);
     511             : 
     512           0 :         cancel_work_sync(&dev_priv->hotplug.dig_port_work);
     513           0 :         cancel_work_sync(&dev_priv->hotplug.hotplug_work);
     514           0 :         cancel_delayed_work_sync(&dev_priv->hotplug.reenable_work);
     515           0 : }

Generated by: LCOV version 1.13