1. 04 Aug, 2023 12 commits
  2. 03 Aug, 2023 15 commits
  3. 02 Aug, 2023 4 commits
  4. 01 Aug, 2023 9 commits
    • Douglas Anderson's avatar
      HID: i2c-hid: Do panel follower work on the system_wq · 76edfcf4
      Douglas Anderson authored
      Turning on an i2c-hid device can be a slow process. This is why
      i2c-hid devices use PROBE_PREFER_ASYNCHRONOUS. Unfortunately, when
      we're a panel follower the i2c-hid power up sequence now blocks the
      power on of the panel. Let's fix that by scheduling the work on the
      system_wq.
      Reviewed-by: default avatarMaxime Ripard <mripard@kernel.org>
      Reviewed-by: default avatarBenjamin Tissoires <bentiss@kernel.org>
      Acked-by: default avatarBenjamin Tissoires <bentiss@kernel.org>
      Signed-off-by: default avatarDouglas Anderson <dianders@chromium.org>
      Link: https://patchwork.freedesktop.org/patch/msgid/20230727101636.v4.10.I962bb462ede779005341c49320740ed95810021d@changeid
      76edfcf4
    • Douglas Anderson's avatar
      HID: i2c-hid: Support being a panel follower · 96a37bfd
      Douglas Anderson authored
      As talked about in the patch ("drm/panel: Add a way for other devices
      to follow panel state"), we really want to keep the power states of a
      touchscreen and the panel it's attached to in sync with each other. In
      that spirit, add support to i2c-hid to be a panel follower. This will
      let the i2c-hid driver get informed when the panel is powered on and
      off. From there we can match the i2c-hid device's power state to that
      of the panel.
      
      NOTE: this patch specifically _doesn't_ use pm_runtime to keep track
      of / manage the power state of the i2c-hid device, even though my
      first instinct said that would be the way to go. Specific problems
      with using pm_runtime():
      * The initial power up couldn't happen in a runtime resume function
        since it create sub-devices and, apparently, that's not good to do
        in your resume function.
      * Managing our power state with pm_runtime meant fighting to make the
        right thing happen at system suspend to prevent the system from
        trying to resume us only to suspend us again. While this might be
        able to be solved, it added complexity.
      Overall the code without pm_runtime() ended up being smaller and
      easier to understand.
      Reviewed-by: default avatarMaxime Ripard <mripard@kernel.org>
      Reviewed-by: default avatarBenjamin Tissoires <bentiss@kernel.org>
      Acked-by: default avatarBenjamin Tissoires <bentiss@kernel.org>
      Signed-off-by: default avatarDouglas Anderson <dianders@chromium.org>
      Link: https://patchwork.freedesktop.org/patch/msgid/20230727101636.v4.9.Ib1a98309c455cd7e26b931c69993d4fba33bbe15@changeid
      96a37bfd
    • Douglas Anderson's avatar
      HID: i2c-hid: Suspend i2c-hid devices in remove · 5f8838e9
      Douglas Anderson authored
      In the i2c-hid remove() function we currently try to power off,
      depopulate our child device, and free our resources. That's OK, but...
      
      * If the i2c-hid device is on a power rail that can't turn off (either
        an always-on or a shared power rail) we won't try to put the device
        in a low power state during remove(). This probably doesn't matter
        for very many devices but it could be nice in some instances.
      
      * If the i2c-hid device somehow manages to generate an interrupt after
        we tried to power off it is conceivable that the interrupt could
        arrive during or after the call to hid_destroy_device() but before
        the call to free_irq(). That could cause a crash since our IRQ
        handler isn't expecting it. One could imagine this happening in
        the case where we couldn't turn off (see the previous bullet) or,
        possibly, if the interrupt line could glitch shortly after the
        device powered off.
      
      Let's call the suspend code during remove to avoid these issues. That
      will put the device into a low power state and also disable
      interrupts.
      
      Technically, one could consider this a "fix" of commit 4a200c3b
      ("HID: i2c-hid: introduce HID over i2c specification implementation").
      However, since the above bullet points are more theoretical than
      problems seen on real systems and since the remove() of an i2c-hid
      touchscreen isn't terribly likely to be called in production, it's
      probably not worth the bother of trying to backport it.
      Reviewed-by: default avatarBenjamin Tissoires <bentiss@kernel.org>
      Acked-by: default avatarBenjamin Tissoires <bentiss@kernel.org>
      Signed-off-by: default avatarDouglas Anderson <dianders@chromium.org>
      Link: https://patchwork.freedesktop.org/patch/msgid/20230727101636.v4.8.Ic3ecad4a825905f4e4ce2a772b17f3c9cb2d60a2@changeid
      5f8838e9
    • Douglas Anderson's avatar
      HID: i2c-hid: Make suspend and resume into helper functions · d93d2847
      Douglas Anderson authored
      In a future patch we'd like to be able to call the current i2c-hid
      suspend and resume functions from times other than system
      suspend. Move the functions higher up in the file and have them take a
      "struct i2c_hid" to make this simpler. We'll then add tiny wrappers of
      the functions for use with system suspend.
      
      This change is expected to have no functional effect.
      Reviewed-by: default avatarMaxime Ripard <mripard@kernel.org>
      Reviewed-by: default avatarBenjamin Tissoires <bentiss@kernel.org>
      Acked-by: default avatarBenjamin Tissoires <bentiss@kernel.org>
      Signed-off-by: default avatarDouglas Anderson <dianders@chromium.org>
      Link: https://patchwork.freedesktop.org/patch/msgid/20230727101636.v4.7.I5c9894789b8b02f029bf266ae9b4f43c7907a173@changeid
      d93d2847
    • Douglas Anderson's avatar
      HID: i2c-hid: Rearrange probe() to power things up later · 675cd877
      Douglas Anderson authored
      In a future patch, we want to change i2c-hid not to necessarily power
      up the touchscreen during probe. In preparation for that, rearrange
      the probe function so that we put as much stuff _before_ powering up
      the device as possible.
      
      This change is expected to have no functional effect.
      Reviewed-by: default avatarMaxime Ripard <mripard@kernel.org>
      Reviewed-by: default avatarBenjamin Tissoires <bentiss@kernel.org>
      Acked-by: default avatarBenjamin Tissoires <bentiss@kernel.org>
      Signed-off-by: default avatarDouglas Anderson <dianders@chromium.org>
      Link: https://patchwork.freedesktop.org/patch/msgid/20230727101636.v4.6.Ifcc9b0a44895d164788966f9b9511fe094ca8cf9@changeid
      675cd877
    • Douglas Anderson's avatar
      HID: i2c-hid: Switch to SYSTEM_SLEEP_PM_OPS() · a889ee12
      Douglas Anderson authored
      The SYSTEM_SLEEP_PM_OPS() allows us to get rid of '#ifdef
      CONFIG_PM_SLEEP', as talked about in commit 1a3c7bb0 ("PM: core:
      Add new *_PM_OPS macros, deprecate old ones").
      
      This change is expected to have no functional effect.
      Reviewed-by: default avatarMaxime Ripard <mripard@kernel.org>
      Reviewed-by: default avatarBenjamin Tissoires <bentiss@kernel.org>
      Acked-by: default avatarBenjamin Tissoires <bentiss@kernel.org>
      Signed-off-by: default avatarDouglas Anderson <dianders@chromium.org>
      Link: https://patchwork.freedesktop.org/patch/msgid/20230727101636.v4.5.Ib2a2865bd3c0b068432259dfc7d76cebcbb512be@changeid
      a889ee12
    • Douglas Anderson's avatar
      of: property: fw_devlink: Add a devlink for panel followers · fbf0ea2d
      Douglas Anderson authored
      Inform fw_devlink of the fact that a panel follower (like a
      touchscreen) is effectively a consumer of the panel from the purposes
      of fw_devlink.
      
      NOTE: this patch isn't required for correctness but instead optimizes
      probe order / helps avoid deferrals.
      Acked-by: default avatarRob Herring <robh@kernel.org>
      Reviewed-by: default avatarMaxime Ripard <mripard@kernel.org>
      Signed-off-by: default avatarDouglas Anderson <dianders@chromium.org>
      Link: https://patchwork.freedesktop.org/patch/msgid/20230727101636.v4.4.Ibf8e1342b5b7906279db2365aca45e6253857bb3@changeid
      fbf0ea2d
    • Douglas Anderson's avatar
      drm/panel: Add a way for other devices to follow panel state · de087416
      Douglas Anderson authored
      These days, it's fairly common to see panels that have touchscreens
      attached to them. The panel and the touchscreen can somewhat be
      thought of as totally separate devices and, historically, this is how
      Linux has treated them. However, treating them as separate isn't
      necessarily the best way to model the two devices, it was just that
      there was no better way. Specifically, there is little practical
      reason to have the touchscreen powered on when the panel is turned
      off, but if we model the devices separately we have no way to keep the
      two devices' power states in sync with each other.
      
      The issue described above makes it sound as if the problem here is
      just about efficiency. We're wasting power keeping the touchscreen
      powered up when the screen is off. While that's true, the problem can
      go deeper. Specifically, hardware designers see that there's no reason
      to have the touchscreen on while the screen is off and then build
      hardware assuming that software would never turn the touchscreen on
      while the screen is off.
      
      In the very simplest case of hardware designs like this, the
      touchscreen and the panel share some power rails. In most cases, this
      turns out not to be terrible and is, again, just a little less
      efficient. Specifically if we tell Linux that the touchscreen and the
      panel are using the same rails then Linux will keep the rails on when
      _either_ device is turned on. That ends to work OK-ish, but now if you
      turn the panel off not only will the touchscreen remain powered, but
      the power rails for the panel itself won't be switched off, burning
      extra power.
      
      The above two inefficiencies are _extra_ minor when you consider the
      fact that laptops rarely spend much time with the screen off. The main
      use case would be when an external screen (and presumably a power
      supply) is attached.
      
      Unfortunately, it gets worse from here. On sc7180-trogdor-homestar,
      for instance, the display's TCON (timing controller) sometimes crashes
      if you don't power cycle it whenever you stop and restart the video
      stream (like during a modeset). The touchscreen keeping the power
      rails on causes real problems. One proposal in the homestar timeframe
      was to move the touchscreen to an always-on rail, dedicating the main
      power rail to the panel. That caused _different_ problems as talked
      about in commit 557e05fa ("HID: i2c-hid: goodix: Stop tying the
      reset line to the regulator"). The end result of all of this was to
      add an extra regulator to the board, increasing cost.
      
      Recently, Cong Yang posted a patch [1] where things are even worse.
      The panel and touch controller on that system seem even more
      intimately tied together and really can't be thought of separately.
      
      To address this issue, let's start allowing devices to register
      themselves as "panel followers". These devices will get called after a
      panel has been powered on and before a panel is powered off. This
      makes the panel the primary device in charge of the power state, which
      matches how userspace uses it.
      
      The panel follower API should be fairly straightforward to use. The
      current code assumes that panel followers are using device tree and
      have a "panel" property pointing to the panel to follow. More
      flexibility and non-DT implementations could be added as needed.
      
      Right now, panel followers can follow the prepare/unprepare functions.
      There could be arguments made that, instead, they should follow
      enable/disable. I've chosen prepare/unprepare for now since those
      functions are guaranteed to power up/power down the panel and it seems
      better to start the process earlier.
      
      A bit of explaining about why this is a roll-your-own API instead of
      using something more standard:
      1. In standard APIs in Linux, parent devices are automatically powered
         on when a child needs power. Applying that here, it would mean that
         we'd force the panel on any time someone was listening to the
         touchscreen. That, unfortunately, would have broken homestar's need
         (if we hadn't changed the hardware, as per above) where the panel
         absolutely needs to be able to power cycle itself. While one could
         argue that homestar is broken hardware and we shouldn't have the
         API do backflips for it, _officially_ the eDP timing guidelines
         agree with homestar's needs and the panel power sequencing diagrams
         show power going off. It's nice to be able to support this.
      2. We could, conceibably, try to add a new flag to device_link causing
         the parent to be in charge of power. Then we could at least use
         normal pm_runtime APIs. This sounds great, except that we run into
         problems with initial probe. As talked about in the later patch
         ("HID: i2c-hid: Support being a panel follower") the initial power
         on of a panel follower might need to do things (like add
         sub-devices) that aren't allowed in a runtime_resume function.
      
      The above complexities explain why this API isn't using common
      functions. That being said, this patch is very small and
      self-contained, so if someone was later able to adapt it to using more
      common APIs while solving the above issues then that could happen in
      the future.
      
      [1] https://lore.kernel.org/r/20230519032316.3464732-1-yangcong5@huaqin.corp-partner.google.comReviewed-by: default avatarMaxime Ripard <mripard@kernel.org>
      Signed-off-by: default avatarDouglas Anderson <dianders@chromium.org>
      Link: https://patchwork.freedesktop.org/patch/msgid/20230727101636.v4.3.Icd5f96342d2242051c754364f4bee13ef2b986d4@changeid
      de087416
    • Douglas Anderson's avatar
      drm/panel: Check for already prepared/enabled in drm_panel · d2aacaf0
      Douglas Anderson authored
      In a whole pile of panel drivers, we have code to make the
      prepare/unprepare/enable/disable callbacks behave as no-ops if they've
      already been called. It's silly to have this code duplicated
      everywhere. Add it to the core instead so that we can eventually
      delete it from all the drivers. Note: to get some idea of the
      duplicated code, try:
        git grep 'if.*>prepared' -- drivers/gpu/drm/panel
        git grep 'if.*>enabled' -- drivers/gpu/drm/panel
      
      NOTE: arguably, the right thing to do here is actually to skip this
      patch and simply remove all the extra checks from the individual
      drivers. Perhaps the checks were needed at some point in time in the
      past but maybe they no longer are? Certainly as we continue
      transitioning over to "panel_bridge" then we expect there to be much
      less variety in how these calls are made. When we're called as part of
      the bridge chain, things should be pretty simple. In fact, there was
      some discussion in the past about these checks [1], including a
      discussion about whether the checks were needed and whether the calls
      ought to be refcounted. At the time, I decided not to mess with it
      because it felt too risky.
      
      Looking closer at it now, I'm fairly certain that nothing in the
      existing codebase is expecting these calls to be refcounted. The only
      real question is whether someone is already doing something to ensure
      prepare()/unprepare() match and enabled()/disable() match. I would say
      that, even if there is something else ensuring that things match,
      there's enough complexity that adding an extra bool and an extra
      double-check here is a good idea. Let's add a drm_warn() to let people
      know that it's considered a minor error to take advantage of
      drm_panel's double-checking but we'll still make things work fine.
      
      We'll also add an entry to the official DRM todo list to remove the
      now pointless check from the panels after this patch lands and,
      eventually, fixup anyone who is triggering the new warning.
      
      [1] https://lore.kernel.org/r/20210416153909.v4.27.I502f2a92ddd36c3d28d014dd75e170c2d405a0a5@changeidAcked-by: default avatarNeil Armstrong <neil.armstrong@linaro.org>
      Reviewed-by: default avatarMaxime Ripard <mripard@kernel.org>
      Signed-off-by: default avatarDouglas Anderson <dianders@chromium.org>
      Link: https://patchwork.freedesktop.org/patch/msgid/20230727101636.v4.2.I59b417d4c29151cc2eff053369ec4822b606f375@changeid
      d2aacaf0