Received: by 2002:a05:6a10:6d10:0:0:0:0 with SMTP id gq16csp1023511pxb; Fri, 15 Apr 2022 18:42:06 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzvbF5bFkvA7WwmCGqYpcdhmUoMgW5AK11YMCIBeY9SSFxZi23L/HSVmc0+FMYqzCoIfAGR X-Received: by 2002:a17:903:2348:b0:154:dd0:aba4 with SMTP id c8-20020a170903234800b001540dd0aba4mr1684299plh.39.1650073325813; Fri, 15 Apr 2022 18:42:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1650073325; cv=none; d=google.com; s=arc-20160816; b=me/PYkjn5zC50axMPLXpzKRC907zTCh8o2AWY4RYc59gZ88zXQZBBUP1q4vaoc/oJG hWGR4B6BlnOInJmt8/9yHRgZEyNpRarO4YC1kwglznU+aPlvHj8lWMqkTBICJLrloHyh NsMTJBn0EDqesOstQyxDvNQ79433l9YucNqvSNgy5Ucty7ecng9emxc7dC8rdjZJrEvS NcCI7mhtuC1eGcExCaeg/FY1YRXCJZaOe0Qg2r8Be8wo7UVlYTC2Eab+Ej/fLMQSH3VZ mlghwwJ5gx9IjFjV39ALDvLeMzOJ/JaDZB4RIemoKusZzbZr9EZvEIrYXa8vevPlMV1R yluQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:user-agent:from :references:in-reply-to:mime-version:dkim-signature; bh=qPW/tKpzT2OLfeSRQ/n3e2HyIfU7YN+KxUW+wzF8svk=; b=veCAWdpcLZMPl2PS8gLrEzPXvZmYiAVAqk7fRH3gngToP24K7UDc8X+5aUgwvYn5ew VZ87sPBpdMC4eepgbV7nzUJxXZi0Zsl7jdA3YVYxwbOTB6R4WLFa3oczkc0RfZIRlTRC Vq4/juRTfU/mZafsyh1vP9vkUPqyBFYl1HHofqSg8Hq2VzSUxk4Yq6li+7rMLQpjEVcQ ka7PBD7BTDcy1JFX1/wWcCWlUV//U1z+16JQanYOGaCxnQgBJsDKY0769ClamsmhbFhi /9T4MjqNsiSL2U58gMzG/qGS2tk/XF3sqOlL1SScI8Exc9i/9+jANW2ELsGcmInKt5NU bXNw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=PdpQhj7f; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [2620:137:e000::1:18]) by mx.google.com with ESMTPS id u17-20020a170903125100b0015408026bbfsi2881472plh.309.2022.04.15.18.42.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Apr 2022 18:42:05 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) client-ip=2620:137:e000::1:18; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=PdpQhj7f; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 49B60126596; Fri, 15 Apr 2022 18:06:58 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347784AbiDNXy1 (ORCPT + 99 others); Thu, 14 Apr 2022 19:54:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46626 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240890AbiDNXyY (ORCPT ); Thu, 14 Apr 2022 19:54:24 -0400 Received: from mail-oa1-x2b.google.com (mail-oa1-x2b.google.com [IPv6:2001:4860:4864:20::2b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 447497D01C for ; Thu, 14 Apr 2022 16:51:58 -0700 (PDT) Received: by mail-oa1-x2b.google.com with SMTP id 586e51a60fabf-df22f50e0cso6818869fac.3 for ; Thu, 14 Apr 2022 16:51:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=mime-version:in-reply-to:references:from:user-agent:date:message-id :subject:to:cc; bh=qPW/tKpzT2OLfeSRQ/n3e2HyIfU7YN+KxUW+wzF8svk=; b=PdpQhj7fINn7qu87oYF/GhsNSZEgkM4PsGuYww5mHdO4QC2XEsCgTazMbYHrpKHV4v RzQ9lxw3t5eMj7tdzUazdoz+Nbj7ZTiGS4PRPKKE6GSv/k14Ua5PI6g6zJ+zHSvnftCW SRJBCgk6mTzyKuTYBAoraxrYw3OJudMqcmLiQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:in-reply-to:references:from :user-agent:date:message-id:subject:to:cc; bh=qPW/tKpzT2OLfeSRQ/n3e2HyIfU7YN+KxUW+wzF8svk=; b=c3ppdrzIuWXinAbyrmPybCBueRKwpW12YOVasjCuMcuLlGRNhA/HL+LTq6nDnmwfPI L2ko3VStn2AbreqMfk2NzEAbAffhAYWKJ4OUe5Ra0FMgsgWQlGvEQHBpbhCeIS1C9jSw 6rrjxwAr3qj/uLGUT7o1P94pYEVP2141l6wxSA5z1RHlpKDCA3k4djllCDAYPM6Aaxei QQyGXg6KTw4v+fhPgTzRo5Mf1To7B+Aot+Q6CxN9PBT5waR2jbA30xxINvWRB8Bl0/Pa g6mFY5vyXYXdrcFyaGLKRlHV0lO+k9o5YjvN5XqQ8cQFbljSnxfUMBaQVW6p6BBpyjDH jatQ== X-Gm-Message-State: AOAM532U4ZC22NlAml9UAAStTjzFY7ysjvrgKiAkfDlJg+6jIYIYzfwK 8fPRmhTDIqYpau2nQgWyQm7p1jYeWYuoNOfUwTKklQ== X-Received: by 2002:a05:6870:e893:b0:e2:ecbc:e581 with SMTP id q19-20020a056870e89300b000e2ecbce581mr389269oan.193.1649980317590; Thu, 14 Apr 2022 16:51:57 -0700 (PDT) Received: from 753933720722 named unknown by gmailapi.google.com with HTTPREST; Thu, 14 Apr 2022 16:51:57 -0700 MIME-Version: 1.0 In-Reply-To: <20220408193536.RFC.1.I4182ae27e00792842cb86f1433990a0ef9c0a073@changeid> References: <20220409023628.2104952-1-dianders@chromium.org> <20220408193536.RFC.1.I4182ae27e00792842cb86f1433990a0ef9c0a073@changeid> From: Stephen Boyd User-Agent: alot/0.10 Date: Thu, 14 Apr 2022 16:51:57 -0700 Message-ID: Subject: Re: [RFC PATCH 1/6] drm/dp: Helpers to make it easier for drivers to use DP AUX bus properly To: Douglas Anderson , dri-devel@lists.freedesktop.org Cc: Robert Foss , Hsin-Yi Wang , Dmitry Baryshkov , Abhinav Kumar , Sankeerth Billakanti , Philip Chen , Daniel Vetter , David Airlie , Linus Walleij , Lyude Paul , Thomas Zimmermann , linux-kernel@vger.kernel.org Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RDNS_NONE,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Quoting Douglas Anderson (2022-04-08 19:36:23) > As talked about in the kerneldoc for "struct dp_aux_ep_client" in this > patch and also in the past in commit a1e3667a9835 ("drm/bridge: > ti-sn65dsi86: Promote the AUX channel to its own sub-dev"), to use the > DP AUX bus properly we really need two "struct device"s. One "struct > device" is in charge of providing the DP AUX bus and the other is > where we'll try to get a reference to the newly probed endpoint > devices. > > In ti-sn65dsi86 this wasn't too difficult to accomplish. That driver > is already broken up into several "struct devices" anyway because it > also provides a PWM and some GPIOs. Adding one more wasn't that > difficult / ugly. > > When I tried to do the same solution in parade-ps8640, it felt like I > was copying too much boilerplate code. I made the realization that I > didn't _really_ need a separate "driver" for each person that wanted > to do the same thing. By putting all the "driver" related code in a > common place then we could save a bit of hassle. This change > effectively adds a new "ep_client" driver that can be used by > anyone. The devices instantiated by this driver will just call through > to the probe/remove/shutdown calls provided. > > At the moment, the "ep_client" driver is backed by the Linux auxiliary > bus (unfortunate naming--this has nothing to do with DP AUX). I didn't > want to expose this to clients, though, so as far as clients are > concerned they get a vanilla "struct device". > > Signed-off-by: Douglas Anderson > --- Is it correct that the struct dp_aux_ep_client is largely equivalent to a struct dp_aux_ep_device? What's the difference? I think it is a fully probed dp_aux_ep_device? Or a way to tell the driver that calls of_dp_aux_populate_ep_devices() that the endpoint has probed now? I read the commit text but it didn't click until I read the next patch that this is solving a probe ordering/loop problem. The driver that creates the 'struct drm_dp_aux' and populates devices on the DP aux bus with of_dp_aux_populate_ep_devices() wants to be sure that the drm_bridge made by the 'struct dp_aux_ep_driver' probe routine in edp-panel is going to be there before calling drm_of_get_bridge(). of_dp_aux_populate_ep_devices(); [No idea if the bridge is registered yet] drm_of_get_bridge(); The solution is to retry the drm_of_get_bridge() until 'struct dp_aux_ep_driver' probes and registers the next bridge. It looks like a wait_for_completion() on top of drm_of_get_bridge() implemented through driver probe and -EPROBE_DEFER; no disrespect! Is there another problem here that the driver that creates the 'struct drm_dp_aux' and populates devices on the DP aux bus with of_dp_aux_populate_ep_devices() wants to use that same 'struct drm_dp_aux' directly to poke at some 'struct dp_aux_ep_device' that was populated? And the 'struct dp_aux_ep_device' may either not be probed and bound to a 'struct dp_aux_ep_driver' or it may not be powered on because it went to runtime PM suspend? Put another way, I worry that the owner of 'struct drm_dp_aux' wants to use some function in include/drm/dp/drm_dp_helper.h that takes the 'struct drm_dp_aux' directly without considering the device model state of the endpoint device (the 'struct dp_aux_ep_device'). That would be a similar problem as waiting for the endpoint to be powered on and probed. Solving that through a sub-driver feels awkward. What if we had some function like drm_dp_get_aux_ep() that took a 'struct drm_dp_aux' and looked for the endpoint device (there can only be one?), waited for it to be probed, and then powered it up via some pm_runtime_get_sync()? My understanding is that with edp-panel we have two power "domains" of importance, the panel power domain and the DP/eDP power domain. Access to the AUX bus via 'struct drm_dp_aux' needs both power domains to be powered on. If the 'struct dp_aux_ep_device' is in hand, then both power domains can be powered on by making sure the power state of the 'struct dp_aux_ep_device::dev' is enabled. If only the 'struct drm_dp_aux' is in hand then we'll need to do something more like find the child device and power it on. Could the 'struct drm_dp_aux' functions in drm_dp_helper.h do this automatically somehow? Maybe we can drop a variable in 'struct drm_dp_aux' when of_dp_aux_populate_ep_devices() is called that the other side may not be powered up. Then if something tries to transfer on that aux channel it powers on all children of 'struct drm_dp_aux::dev' that are on the 'dp_aux_bus_type' or bails out if those devices haven't probed yet or can't be powered on. > diff --git a/include/drm/dp/drm_dp_aux_bus.h b/include/drm/dp/drm_dp_aux_bus.h > index 4f19b20b1dd6..ecf68b6873bd 100644 > --- a/include/drm/dp/drm_dp_aux_bus.h > +++ b/include/drm/dp/drm_dp_aux_bus.h > @@ -54,4 +54,62 @@ int __dp_aux_dp_driver_register(struct dp_aux_ep_driver *aux_ep_drv, > struct module *owner); > void dp_aux_dp_driver_unregister(struct dp_aux_ep_driver *aux_ep_drv); > > +/** > + * struct dp_aux_ep_device - Helper for clients of DP AUX EP devices dp_aux_ep_client? > + * > + * The DP AUX bus can be a bit tricky to use properly. Usually, the way > + * things work is that: > + * - The DP controller driver provides the DP AUX bus and would like to probe > + * the endpoints on the DP AUX bus (AKA the panel) as part of its probe > + * routine. > + * - The DP controller driver would also like to acquire a reference to the > + * DP AUX endpoints (AKA the panel) as part of its probe. > + * > + * The problem is that the DP AUX endpoints aren't guaranteed to complete their > + * probe right away. They could be probing asynchronously or they simply might > + * fail to acquire some resource and return -EPROBE_DEFER. > + * > + * The best way to solve this is to break the DP controller's probe into > + * two parts. The first part will create the DP AUX bus. The second part will > + * acquire the reference to the DP AUX endpoint. The first part can complete > + * finish with no problems and be "done" even if the second part ends up s/finish// > + * deferring while waiting for the DP AUX endpoint. > + * > + * The dp_aux_ep_client structure and associated functions help with managing > + * this common case. They will create/add a second "struct device" for you. create and add a second > + * In the probe for this second "struct device" (known as the "clientdev" here) > + * you can acquire references to the AUX DP endpoints and can freely return > + * -EPROBE_DEFER if they're not ready yet. > + * > + * A few notes: > + * - The parent of the clientdev is guaranteed to be aux->dev > + * - The of_node of the clientdev is guaranteed to be the same as the of_node > + * of aux->dev, copied with device_set_of_node_from_dev(). > + * - If you're doing "devm" type things in the clientdev's probe you should > + * use the clientdev. This makes lifetimes be managed properly. > + * > + * NOTE: there's no requirement to use these helpers if you have solved the > + * problem described above in some other way. > + */