drm/bridge: synopsys: dw-mipi-dsi: fix deferred dsi host probe breaks dsi device probe
Message ID | 20240112180737.551318-1-farouk.bouabid@theobroma-systems.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel+bounces-24955-ouuuleilei=gmail.com@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:693c:2614:b0:101:6a76:bbe3 with SMTP id mm20csp350003dyc; Fri, 12 Jan 2024 10:09:27 -0800 (PST) X-Google-Smtp-Source: AGHT+IEDmaTzAjpD84cu5leCadI3kojsEbRmPa3CmuY9ta7EIpqZkjSG3njZpNQ3/hIp6weAdBzN X-Received: by 2002:a05:6512:b87:b0:50e:a9db:9b89 with SMTP id b7-20020a0565120b8700b0050ea9db9b89mr1032330lfv.13.1705082967083; Fri, 12 Jan 2024 10:09:27 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1705082967; cv=pass; d=google.com; s=arc-20160816; b=ZF++s4ZnJve/WPP0UDovAwpX0DafcIhxaD0ILOfQHLAvtTD/rTbntcXMzzEOl/AG9v 98iQSN5DcGJKiXwXIj7ro/wSVZowTubCoxNQHuzSahK3ef6IjkoxiUr2nRWxx/qc5nhO 0ulEQIZOQpbueCqkB1Ud/ee3ABJHvpRmwLx8d6qcgICkVsWv0ZUsSwSy0KadeJ8UCGer XjLnYAd+WxodBOGIde0wPgFy8fDV6AKrKW8l8FUmgLmlhsk3oR/IhWMvEnai0ZhTEoF9 nmSJobT9KYnbE48B9vqli2gboacecTwwjMyqIFJUZfl1vI1uXg3Ry0egPRTA0xIIZkwJ 6IiA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=mime-version:list-unsubscribe:list-subscribe:list-id:precedence :content-transfer-encoding:message-id:date:subject:cc:to:from :dkim-signature; bh=8MbqTnf16hJDRVDy4ZeUcvi0Kn7jwlOdRZtBNsoowE0=; fh=C9B5nBaBttByFNMr3kluWGfcrF50Xz2HYy1PwE8EAC0=; b=G9vJr6dtea2B64FRvIw2yKCuBqcQ1upoyF4fbJv38Ee+5gWhcbv+ST1U5T5uRDMPYV KWmT8j6mGMlHayGE3f42S2DStTn0iaSKoMpGQLDRe/jA0l3gWdcT8zLrm/uMZ7560E5+ ouMFu9fkolbyzuz7TeCVzCFxLdOYytDCleoNFDUOvIgWXTG46L1vPDwvnLdbC2mbY8iS MVJj/39nE1ipgG6Z0U4jne7DgKohkTFlbstEm6mEE9Eh/lHRHO7Kqtk4S4aNHS0m9pRN HeetP0TaIzHrREXCIdsgU4StngnBcpSRtt+ATuhLufSTFvEJR+peY482iyHhkCHLdP1p 99+w== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@theobroma-systems.com header.s=selector1 header.b=bjPAeYVv; arc=pass (i=1 spf=pass spfdomain=theobroma-systems.com dkim=pass dkdomain=theobroma-systems.com dmarc=pass fromdomain=theobroma-systems.com); spf=pass (google.com: domain of linux-kernel+bounces-24955-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-24955-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=theobroma-systems.com Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id lc2-20020a170906f90200b00a2cea055e88si373053ejb.431.2024.01.12.10.09.26 for <ouuuleilei@gmail.com> (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 12 Jan 2024 10:09:27 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-24955-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@theobroma-systems.com header.s=selector1 header.b=bjPAeYVv; arc=pass (i=1 spf=pass spfdomain=theobroma-systems.com dkim=pass dkdomain=theobroma-systems.com dmarc=pass fromdomain=theobroma-systems.com); spf=pass (google.com: domain of linux-kernel+bounces-24955-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-24955-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=theobroma-systems.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id 74FF71F240BF for <ouuuleilei@gmail.com>; Fri, 12 Jan 2024 18:09:26 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 80D8E1AABE; Fri, 12 Jan 2024 18:08:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=theobroma-systems.com header.i=@theobroma-systems.com header.b="bjPAeYVv" Received: from EUR04-DB3-obe.outbound.protection.outlook.com (mail-db3eur04on2041.outbound.protection.outlook.com [40.107.6.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4774B17C91 for <linux-kernel@vger.kernel.org>; Fri, 12 Jan 2024 18:07:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=theobroma-systems.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=theobroma-systems.com ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=m056r+427aVT1kwdQR/96bOD6mde9dn6rW2UNdZvD0HkCHbkHTFjvy2mrl7+E4/rgN2mdx/Ey788uG9gmY57koD9L+gK8DN1qLvc8J0sSdf3Db59LQ68Bz4aE4zU8+6GaYLDd23EyGnJ7E2oXPOsuYvdffk2nqJUB7gdJPYciask+UxEP4QUZFZA57wgiVIRxmBxS/QAw4BUbCjrSFDwfd52svELbeDl/jCQ2FnPAutejMazArzky07Jq8F5cwOjiSaAXzlxGHAWA4vck5723wHC0ED/3Qo7qU9Y2VR6gdpkKC6bVZgwGld7MK/UXraMN2Cz9KfhoKwNYPdlxOg9Og== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=8MbqTnf16hJDRVDy4ZeUcvi0Kn7jwlOdRZtBNsoowE0=; b=A0VxeBjQJLBKmNhbBL6+DzXVzgzif8+KCEKJrA+6d6JO394oRzgBERjtKfT+nhun3IvoIsxPMHD7zx282rJAv7QsKwSPQHrk1A/LEvSkBuM2D6Ba8dZgbDvPtnsKl45WAH5UcwjqvWbxGDQJKgoSOrW+uD5kpakosLNYYYJMbgNFnCJck7ixP/xw5iG1Dk6pS2ApM7fPyobhbK1KJqPp0Ce7aaBzIzLTxcZpRNryZCwMPaFVlVKTLOvxXXRSHqSbuFjTrQ1W0p/haYiUlZUMD4SlnmVSANGJ6Q8cRcACU0EhuWo9ByzcecYqBdALanlTW7mltojsu0wM/xuwg2O6vg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=theobroma-systems.com; dmarc=pass action=none header.from=theobroma-systems.com; dkim=pass header.d=theobroma-systems.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=theobroma-systems.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=8MbqTnf16hJDRVDy4ZeUcvi0Kn7jwlOdRZtBNsoowE0=; b=bjPAeYVvGDyHWrF7zICcZ85+9a6vD/kANix6ukiNZIX+C8aN9M5JIfINC5JSPrVf5UOu+ctYhrKGkOT9asWR5DZwos0Zb03Yesi2/CqGePfomMaHxcDmWNgc4581MzMgk6B5TVaXVTtfUJ41rj2PN8vcFaxFolkx9ZA6PNUcj7/f5rrYADFlfUOJ1GsgFgHOzwr5VHm9nljvTcn8zNUt+Et6NskbSjtkfL427TOcS1/3mPxZ7YpD93Ny04nXvYvoa5WZ8kIO4ue86IAbWrc+Wi+uR+azEJA3dgvJN1rRAtQQlQ1B/8fr60NhULRDW0tp7MjLWJ3UPRSQwXx/Pz4w+Q== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=theobroma-systems.com; Received: from VE1PR04MB6382.eurprd04.prod.outlook.com (2603:10a6:803:122::31) by DU0PR04MB9467.eurprd04.prod.outlook.com (2603:10a6:10:35b::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7181.21; Fri, 12 Jan 2024 18:07:51 +0000 Received: from VE1PR04MB6382.eurprd04.prod.outlook.com ([fe80::d4b1:cea8:7085:ec50]) by VE1PR04MB6382.eurprd04.prod.outlook.com ([fe80::d4b1:cea8:7085:ec50%4]) with mapi id 15.20.7181.015; Fri, 12 Jan 2024 18:07:51 +0000 From: Farouk Bouabid <farouk.bouabid@theobroma-systems.com> To: victor.liu@nxp.com, andrzej.hajda@intel.com, neil.armstrong@linaro.org, rfoss@kernel.org, jonas@kwiboo.se, jernej.skrabec@gmail.com, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, airlied@gmail.com, daniel@ffwll.ch, shawnguo@kernel.org, s.hauer@pengutronix.de, kernel@pengutronix.de, festevam@gmail.com, linux-imx@nxp.com, khilman@baylibre.com, jbrunet@baylibre.com, martin.blumenstingl@googlemail.com, hjc@rock-chips.com, heiko@sntech.de, yannick.fertre@foss.st.com, raphael.gallais-pou@foss.st.com, philippe.cornu@foss.st.com, mcoquelin.stm32@gmail.com, alexandre.torgue@foss.st.com, dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-amlogic@lists.infradead.org, linux-rockchip@lists.infradead.org, linux-stm32@st-md-mailman.stormreply.com Cc: quentin.schulz@theobroma-systems.com, bouabid.farouk97@gmail.com, Farouk Bouabid <farouk.bouabid@theobroma-systems.com> Subject: [PATCH] drm/bridge: synopsys: dw-mipi-dsi: fix deferred dsi host probe breaks dsi device probe Date: Fri, 12 Jan 2024 19:07:37 +0100 Message-Id: <20240112180737.551318-1-farouk.bouabid@theobroma-systems.com> X-Mailer: git-send-email 2.34.1 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-ClientProxiedBy: VI1PR07CA0144.eurprd07.prod.outlook.com (2603:10a6:802:16::31) To VE1PR04MB6382.eurprd04.prod.outlook.com (2603:10a6:803:122::31) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: <linux-kernel.vger.kernel.org> List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org> List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org> MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: VE1PR04MB6382:EE_|DU0PR04MB9467:EE_ X-MS-Office365-Filtering-Correlation-Id: 15ae7662-3396-40bf-093f-08dc1399643f X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: yk5HFFpmdrXTkoFGcLiwgk03ea82TAVijCtZL7xyCYN8qb5ESH8cgFV6rS2r6hE9Ie3uQ7mb+Ia1hs3b11EJCpsN6Md5nDwMfmzGvvDW1A6T5tEDYihCMpZbTRffrf4FOxbYPlvG6zQ2jjLS2EUZdIF7UGvPtzgf9+YlWyBVxur8476KH6vjkVqG+Te2yEiZTmXbAsokAR45TDPYK2yydkRkIx0dQEidimzTJzE+UNxUT9Ep083S0hT2I6RacxlEEfxGeLFjaXdSttL6hLQYWVlw8HipGFjH8Kuodaf+MyXdBraEqojvui4fcCgikDlzzfd5/yahN4yz+c85lOBNe89TlzeBC/VGhR3VYEQ5UWVUKjOdw8jJSp8CpUibVz1nXZeQIc9WGCG5ZelIYO9Do9tRSxZrblI/q1yWiC20LvkeqdgidphkZ8sh7+HJFxPWVnRM0QyjKQ6OgHaFeB9yKoGTdiQsNQ8DVi1Cew6TN5OGy8ssG+jRY+miN+T7XVYLtGZbllHPwXdl3FkUCFOua8UT+wkyYxga/DFrRITXy0TwxWd+ZeEEbapR3Nbg1RAKsgEsSh2/kt8trfPbu7+3Yy1QWcBYQPGNt8q3YgU534aqyNt/KLG0K+8X7x5bK4F2DaYT+w8YDXzQIZsC7G3taA== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:VE1PR04MB6382.eurprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230031)(39850400004)(136003)(346002)(366004)(396003)(376002)(230922051799003)(186009)(1800799012)(64100799003)(451199024)(5660300002)(30864003)(86362001)(8676002)(8936002)(4326008)(7416002)(2906002)(7406005)(1076003)(2616005)(38100700002)(26005)(83380400001)(107886003)(52116002)(6506007)(44832011)(6512007)(6666004)(478600001)(66946007)(36756003)(316002)(66556008)(66476007)(921011)(41300700001)(6486002)(38350700005);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: W3UyzkIvmSIrjMIoXL/xXzNcA0gwyY9r7NAAQvY4PpDwKYW78Aw9la2zGe5dCpaVWlp5Pfi/IaNglzjcW3aiR2yT7O3R72GIFE5rSqwaXLzaoOEaogRenl9t5TYI9+ZnawR3puVAHNSgX2WFjyIP1Y9IKFxmr4w7C/JsDe5ocE/yQr+snYxHqIjN+BtxiHNn6NNrUReWKwCSNxobAa9T2CeiwD82yCOwz9mDBe8sJdwThMn8WTQ0BKtvH9gACfLebvXv1UA866J8TyN4O+5/O+roxFESGZABLUk4t2I0gJliy2/8DRpxJ/iXwZbsuX97Tk8wo1S9/8qmwA9scXqhg3/FKe42w4VCKh1KwNESqeGBRffOIoqaM6bdgxsAxtkZCMF4NQh30ngmgZDYKgsyhbvluXpGh7O9gfXut8XWjS5SzN3IjOwmz0g21CMUeKQAAJANwqAnAiML+7eIHdOnVejqG2XR+sS+t3MtPwcGamwt7vt4SLR/1QKrOOd/9mu0K1tgFsy2bk/+amiz2V/aRr6uLIIMqy9fy6A/+6fc8jxzBS9pGrMYPgP+0O7g2rn5o3uguud8cfuhRFBNJCOo/wblN4d/EEiwCGaxaFQWhHJSlRIPnYZD7KkhDhBFyjYfsYHIz1E13s4jfEwpbQWgAvicY98rf0vc33B8lSkJRaVumsWrs00bW/94lGx87ptq/SnQl2rvkeu5TwN95AtYXdm+aWF+EaDRb9TBhT8qYp3r1F0QncJZeoJxlLop9ZUpHKXvT2w9EGwDGU822GN/k+IYRwtpdjoNkxOq4tnedD34P3MvCi81leQsRMUdlyxRlsHmb0TYBr7aKpFl7UVrO17W2Ai7P4TDB3O7aVvqKLX4nsnQ3j16qsRzEvD8qyZ/ixzMKl9BPS6i+GEvE8rjyM/djFG3zSR9367QUEGFkH7b2QmGyEkxLVy4NxqcINfnfpXzvhwxrewh+EPtoKRh/KdOs6XDyFJZcYWMvxQanj5VaSmM9kxxofsvfJDGaZxiHM5gdlu0VDTsPhNflZi70jBj+/dw11JVxynCAx+qcuSJyxF/kZxqmY60bpHR83QCckZb1xQ25HjWVoOxPzTIiAGC5c6Vd/xiXQnXF7jbT4++vHYw9crrCouKivnTH+T80QvgEkBUq/791PQXsCL6lXJca1dEYwP1NYRj1AMai2NUTqGlRxQqMtZt/Gu/ab7XF2ubq/g1tTtjrTnOzK02lboW/rIn50fGf00gQssZyL0AV587FkJYDs7AxM21l9AL/+7FzhbojxSxIkThABg/o/ti0hnGy6yYiFxJ84Lv5elX+qv0SOZ3xkxhsiJdsg5jAXAQGS+hiOWf/5MOdzf1UuezMMkR2+FXjV85iJTu/0NcSxZTO9Xfdgf25WKNI1goka8dTXhJmN2GOmjWA4YHzF1RFu77pL3SWuWLi7WO5+AuzkdNYEjRyqe15aKbYYD9HTwUd5ua7ESeWId6JH8ejs2KbU5HB9AK0K/5OlG+NcJ0A0lEqNvoWuPX76YqI1bbE3eAQDmirNRw3oq/zCTm2A3yt7bsIPHOarUzYz49tTwf9rJgnSg0VJEOyauAKSKNRHFMmr4vZ/i0Khdlh6v5iUulBZDuKJAVWskeRC2ZXuM= X-OriginatorOrg: theobroma-systems.com X-MS-Exchange-CrossTenant-Network-Message-Id: 15ae7662-3396-40bf-093f-08dc1399643f X-MS-Exchange-CrossTenant-AuthSource: VE1PR04MB6382.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Jan 2024 18:07:51.4062 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 5e0e1b52-21b5-4e7b-83bb-514ec460677e X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 1rRjF/cX6hDFIkhssql5kt3+B2HlctKwnEPsCgXj/9DPmgFc7eqEXLJMYj+Sa0quTlfvmCjbj/gYkyBnbctIDD4AwIoGr79lGgaN/ICRU6DKq7FcWkV1/1dGpJaqKnVf X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0PR04MB9467 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1787909077345571530 X-GMAIL-MSGID: 1787909077345571530 |
Series |
drm/bridge: synopsys: dw-mipi-dsi: fix deferred dsi host probe breaks dsi device probe
|
|
Commit Message
Farouk Bouabid
Jan. 12, 2024, 6:07 p.m. UTC
dw-mipi-dsi based drivers such as dw-mipi-dsi-rockchip or dw_mipi_dsi-stm
depend on dw_mipi_dsi_probe() to initialize the dw_mipi_dsi driver
structure (dmd pointer). This structure is only initialized once
dw_mipi_dsi_probe() returns, creating the link between the locally created
structure and the actual dmd pointer.
Probing the dsi host can be deferred in case of dependency to a dsi
phy-supply (eg. "rockchip,px30-dsi-dphy"). Meanwhile dsi-device drivers
like panels (eg. "ltk050h3146w") can already be registered on the bus.
In that case, when attempting, to register the dsi host from
dw_mipi_dsi_probe() using mipi_dsi_host_register(), the panel probe is
called with a dsi-host pointer that is still locally allocated in
dw_mipi_dsi_probe().
While probing, the panel driver tries to attach to a dsi host
(mipi_dsi_attach()) which calls in return for the specific dsi host
attach hook. (e.g. dw_mipi_dsi_rockchip_host_attach()).
dw_mipi_dsi_rockchip uses the component framework.
In the attach hook, the host component is registered which calls in return
for drm_bridge_attach() while trying to bind the component
(dw_mipi_dsi_bind())
drm_bridge_attach() requires a valid drm bridge parameter. However, the
drm bridge (&dmd->bridge) that will be passed, is not yet initialized since
the dw_mipi_dsi_probe() has not yet returned. This call will fail with a
fatal error (invalid bridge) causing the panel to not be probed again.
To simplify the issue: drm_bridge_attach() depends on the result pointer
of dw_mipi_dsi_probe().
While, if the dsi probe is deferred, drm_bridge_attach() is called before
dw_mipi_dsi_probe() returns.
drm_bridge_attach+0x14/0x1ac
dw_mipi_dsi_bind+0x24/0x30
dw_mipi_dsi_rockchip_bind+0x258/0x378
component_bind_all+0x118/0x248
rockchip_drm_bind+0xb0/0x1f8
try_to_bring_up_aggregate_device+0x168/0x1d4
__component_add+0xa4/0x170
component_add+0x14/0x20
dw_mipi_dsi_rockchip_host_attach+0x54/0x144
dw_mipi_dsi_host_attach+0x9c/0xcc
mipi_dsi_attach+0x28/0x3c
ltk050h3146w_probe+0x10c/0x1a4
mipi_dsi_drv_probe+0x20/0x2c
really_probe+0x148/0x2ac
__driver_probe_device+0x78/0x12c
driver_probe_device+0xdc/0x160
__device_attach_driver+0xb8/0x134
bus_for_each_drv+0x80/0xdc
__device_attach+0xa8/0x1b0
device_initial_probe+0x14/0x20
bus_probe_device+0xa8/0xac
device_add+0x5cc/0x778
mipi_dsi_device_register_full+0xd8/0x198
mipi_dsi_host_register+0x98/0x18c
__dw_mipi_dsi_probe+0x290/0x35c
dw_mipi_dsi_probe+0x10/0x6c
dw_mipi_dsi_rockchip_probe+0x208/0x3e4
platform_probe+0x68/0xdc
really_probe+0x148/0x2ac
__driver_probe_device+0x78/0x12c
driver_probe_device+0xdc/0x160
__device_attach_driver+0xb8/0x134
bus_for_each_drv+0x80/0xdc
__device_attach+0xa8/0x1b0
device_initial_probe+0x14/0x20
bus_probe_device+0xa8/0xac
deferred_probe_work_func+0x88/0xc0
process_one_work+0x138/0x260
worker_thread+0x32c/0x438
kthread+0x118/0x11c
ret_from_fork+0x10/0x20
---[ end trace 0000000000000000 ]---
Fix this by initializing directly the dmd pointer in dw_mipi_dsi_probe(),
which requires also initializting the dmd->bridge attributes that are
required in drm_bridge_attach() before calling mipi_dsi_host_register().
Signed-off-by: Farouk Bouabid <farouk.bouabid@theobroma-systems.com>
---
drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c | 4 +-
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 42 ++++++++++---------
drivers/gpu/drm/meson/meson_dw_mipi_dsi.c | 8 ++--
.../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 5 +--
drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 5 +--
include/drm/bridge/dw_mipi_dsi.h | 5 ++-
6 files changed, 35 insertions(+), 34 deletions(-)
Comments
Hi, On 12/01/2024 19:07, Farouk Bouabid wrote: > dw-mipi-dsi based drivers such as dw-mipi-dsi-rockchip or dw_mipi_dsi-stm > depend on dw_mipi_dsi_probe() to initialize the dw_mipi_dsi driver > structure (dmd pointer). This structure is only initialized once > dw_mipi_dsi_probe() returns, creating the link between the locally created > structure and the actual dmd pointer. > > Probing the dsi host can be deferred in case of dependency to a dsi > phy-supply (eg. "rockchip,px30-dsi-dphy"). Meanwhile dsi-device drivers > like panels (eg. "ltk050h3146w") can already be registered on the bus. > In that case, when attempting, to register the dsi host from > dw_mipi_dsi_probe() using mipi_dsi_host_register(), the panel probe is > called with a dsi-host pointer that is still locally allocated in > dw_mipi_dsi_probe(). > > While probing, the panel driver tries to attach to a dsi host > (mipi_dsi_attach()) which calls in return for the specific dsi host > attach hook. (e.g. dw_mipi_dsi_rockchip_host_attach()). > dw_mipi_dsi_rockchip uses the component framework. > In the attach hook, the host component is registered which calls in return > for drm_bridge_attach() while trying to bind the component > (dw_mipi_dsi_bind()) In meson_dw_mipi_dsi I simply fixed this by getting rid of components... Neil > > drm_bridge_attach() requires a valid drm bridge parameter. However, the > drm bridge (&dmd->bridge) that will be passed, is not yet initialized since > the dw_mipi_dsi_probe() has not yet returned. This call will fail with a > fatal error (invalid bridge) causing the panel to not be probed again. > > To simplify the issue: drm_bridge_attach() depends on the result pointer > of dw_mipi_dsi_probe(). > While, if the dsi probe is deferred, drm_bridge_attach() is called before > dw_mipi_dsi_probe() returns. > > drm_bridge_attach+0x14/0x1ac > dw_mipi_dsi_bind+0x24/0x30 > dw_mipi_dsi_rockchip_bind+0x258/0x378 > component_bind_all+0x118/0x248 > rockchip_drm_bind+0xb0/0x1f8 > try_to_bring_up_aggregate_device+0x168/0x1d4 > __component_add+0xa4/0x170 > component_add+0x14/0x20 > dw_mipi_dsi_rockchip_host_attach+0x54/0x144 > dw_mipi_dsi_host_attach+0x9c/0xcc > mipi_dsi_attach+0x28/0x3c > ltk050h3146w_probe+0x10c/0x1a4 > mipi_dsi_drv_probe+0x20/0x2c > really_probe+0x148/0x2ac > __driver_probe_device+0x78/0x12c > driver_probe_device+0xdc/0x160 > __device_attach_driver+0xb8/0x134 > bus_for_each_drv+0x80/0xdc > __device_attach+0xa8/0x1b0 > device_initial_probe+0x14/0x20 > bus_probe_device+0xa8/0xac > device_add+0x5cc/0x778 > mipi_dsi_device_register_full+0xd8/0x198 > mipi_dsi_host_register+0x98/0x18c > __dw_mipi_dsi_probe+0x290/0x35c > dw_mipi_dsi_probe+0x10/0x6c > dw_mipi_dsi_rockchip_probe+0x208/0x3e4 > platform_probe+0x68/0xdc > really_probe+0x148/0x2ac > __driver_probe_device+0x78/0x12c > driver_probe_device+0xdc/0x160 > __device_attach_driver+0xb8/0x134 > bus_for_each_drv+0x80/0xdc > __device_attach+0xa8/0x1b0 > device_initial_probe+0x14/0x20 > bus_probe_device+0xa8/0xac > deferred_probe_work_func+0x88/0xc0 > process_one_work+0x138/0x260 > worker_thread+0x32c/0x438 > kthread+0x118/0x11c > ret_from_fork+0x10/0x20 > ---[ end trace 0000000000000000 ]--- > > Fix this by initializing directly the dmd pointer in dw_mipi_dsi_probe(), > which requires also initializting the dmd->bridge attributes that are > required in drm_bridge_attach() before calling mipi_dsi_host_register(). > > Signed-off-by: Farouk Bouabid <farouk.bouabid@theobroma-systems.com> > --- > drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c | 4 +- > drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 42 ++++++++++--------- > drivers/gpu/drm/meson/meson_dw_mipi_dsi.c | 8 ++-- > .../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 5 +-- > drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 5 +-- > include/drm/bridge/dw_mipi_dsi.h | 5 ++- > 6 files changed, 35 insertions(+), 34 deletions(-) > > diff --git a/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c b/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c > index 3ff30ce80c5b..469976ad3b19 100644 > --- a/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c > +++ b/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c > @@ -881,8 +881,8 @@ static int imx93_dsi_probe(struct platform_device *pdev) > dsi->pdata.priv_data = dsi; > platform_set_drvdata(pdev, dsi); > > - dsi->dmd = dw_mipi_dsi_probe(pdev, &dsi->pdata); > - if (IS_ERR(dsi->dmd)) > + ret = dw_mipi_dsi_probe(pdev, &dsi->pdata, &dsi->dmd); > + if (ret < 0) > return dev_err_probe(dev, PTR_ERR(dsi->dmd), > "failed to probe dw_mipi_dsi\n"); > > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c > index 824fb3c65742..306cba366ba8 100644 > --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c > +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c > @@ -1184,18 +1184,19 @@ static void dw_mipi_dsi_debugfs_remove(struct dw_mipi_dsi *dsi) { } > > #endif /* CONFIG_DEBUG_FS */ > > -static struct dw_mipi_dsi * > -__dw_mipi_dsi_probe(struct platform_device *pdev, > - const struct dw_mipi_dsi_plat_data *plat_data) > +int __dw_mipi_dsi_probe(struct platform_device *pdev, > + const struct dw_mipi_dsi_plat_data *plat_data, struct dw_mipi_dsi **dsi_p) > { > struct device *dev = &pdev->dev; > struct reset_control *apb_rst; > struct dw_mipi_dsi *dsi; > int ret; > > - dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL); > - if (!dsi) > - return ERR_PTR(-ENOMEM); > + *dsi_p = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL); > + if (!*dsi_p) > + return -ENOMEM; > + > + dsi = *dsi_p; > > dsi->dev = dev; > dsi->plat_data = plat_data; > @@ -1203,13 +1204,13 @@ __dw_mipi_dsi_probe(struct platform_device *pdev, > if (!plat_data->phy_ops->init || !plat_data->phy_ops->get_lane_mbps || > !plat_data->phy_ops->get_timing) { > DRM_ERROR("Phy not properly configured\n"); > - return ERR_PTR(-ENODEV); > + return -ENODEV; > } > > if (!plat_data->base) { > dsi->base = devm_platform_ioremap_resource(pdev, 0); > if (IS_ERR(dsi->base)) > - return ERR_PTR(-ENODEV); > + return -ENODEV; > > } else { > dsi->base = plat_data->base; > @@ -1219,7 +1220,7 @@ __dw_mipi_dsi_probe(struct platform_device *pdev, > if (IS_ERR(dsi->pclk)) { > ret = PTR_ERR(dsi->pclk); > dev_err(dev, "Unable to get pclk: %d\n", ret); > - return ERR_PTR(ret); > + return ret; > } > > /* > @@ -1233,14 +1234,14 @@ __dw_mipi_dsi_probe(struct platform_device *pdev, > if (ret != -EPROBE_DEFER) > dev_err(dev, "Unable to get reset control: %d\n", ret); > > - return ERR_PTR(ret); > + return ret; > } > > if (apb_rst) { > ret = clk_prepare_enable(dsi->pclk); > if (ret) { > dev_err(dev, "%s: Failed to enable pclk\n", __func__); > - return ERR_PTR(ret); > + return ret; > } > > reset_control_assert(apb_rst); > @@ -1255,19 +1256,20 @@ __dw_mipi_dsi_probe(struct platform_device *pdev, > > dsi->dsi_host.ops = &dw_mipi_dsi_host_ops; > dsi->dsi_host.dev = dev; > + dsi->bridge.driver_private = dsi; > + dsi->bridge.funcs = &dw_mipi_dsi_bridge_funcs; > + dsi->bridge.of_node = pdev->dev.of_node; > + > ret = mipi_dsi_host_register(&dsi->dsi_host); > if (ret) { > dev_err(dev, "Failed to register MIPI host: %d\n", ret); > pm_runtime_disable(dev); > dw_mipi_dsi_debugfs_remove(dsi); > - return ERR_PTR(ret); > + return ret; > } > > - dsi->bridge.driver_private = dsi; > - dsi->bridge.funcs = &dw_mipi_dsi_bridge_funcs; > - dsi->bridge.of_node = pdev->dev.of_node; > > - return dsi; > + return 0; > } > > static void __dw_mipi_dsi_remove(struct dw_mipi_dsi *dsi) > @@ -1301,11 +1303,11 @@ EXPORT_SYMBOL_GPL(dw_mipi_dsi_get_bridge); > /* > * Probe/remove API, used from platforms based on the DRM bridge API. > */ > -struct dw_mipi_dsi * > -dw_mipi_dsi_probe(struct platform_device *pdev, > - const struct dw_mipi_dsi_plat_data *plat_data) > +int dw_mipi_dsi_probe(struct platform_device *pdev, > + const struct dw_mipi_dsi_plat_data *plat_data, > + struct dw_mipi_dsi **dsi_p) > { > - return __dw_mipi_dsi_probe(pdev, plat_data); > + return __dw_mipi_dsi_probe(pdev, plat_data, dsi_p); > } > EXPORT_SYMBOL_GPL(dw_mipi_dsi_probe); > > diff --git a/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c b/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c > index e5fe4e994f43..b103f3e31f2a 100644 > --- a/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c > +++ b/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c > @@ -262,6 +262,7 @@ static int meson_dw_mipi_dsi_probe(struct platform_device *pdev) > { > struct meson_dw_mipi_dsi *mipi_dsi; > struct device *dev = &pdev->dev; > + int ret; > > mipi_dsi = devm_kzalloc(dev, sizeof(*mipi_dsi), GFP_KERNEL); > if (!mipi_dsi) > @@ -315,10 +316,9 @@ static int meson_dw_mipi_dsi_probe(struct platform_device *pdev) > mipi_dsi->pdata.priv_data = mipi_dsi; > platform_set_drvdata(pdev, mipi_dsi); > > - mipi_dsi->dmd = dw_mipi_dsi_probe(pdev, &mipi_dsi->pdata); > - if (IS_ERR(mipi_dsi->dmd)) > - return dev_err_probe(dev, PTR_ERR(mipi_dsi->dmd), > - "Failed to probe dw_mipi_dsi\n"); > + ret = dw_mipi_dsi_probe(pdev, &mipi_dsi->pdata, &mipi_dsi->dmd); > + if (ret < 0) > + return dev_err_probe(dev, ret, "Failed to probe dw_mipi_dsi\n"); > > return 0; > } > diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c > index 6396f9324dab..4df32747476c 100644 > --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c > +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c > @@ -1457,9 +1457,8 @@ static int dw_mipi_dsi_rockchip_probe(struct platform_device *pdev) > if (IS_ERR(phy_provider)) > return PTR_ERR(phy_provider); > > - dsi->dmd = dw_mipi_dsi_probe(pdev, &dsi->pdata); > - if (IS_ERR(dsi->dmd)) { > - ret = PTR_ERR(dsi->dmd); > + ret = dw_mipi_dsi_probe(pdev, &dsi->pdata, &dsi->dmd); > + if (ret < 0) { > if (ret != -EPROBE_DEFER) > DRM_DEV_ERROR(dev, > "Failed to probe dw_mipi_dsi: %d\n", ret); > diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c > index d5f8c923d7bc..44dbbfc277d8 100644 > --- a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c > +++ b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c > @@ -518,9 +518,8 @@ static int dw_mipi_dsi_stm_probe(struct platform_device *pdev) > > platform_set_drvdata(pdev, dsi); > > - dsi->dsi = dw_mipi_dsi_probe(pdev, &dw_mipi_dsi_stm_plat_data); > - if (IS_ERR(dsi->dsi)) { > - ret = PTR_ERR(dsi->dsi); > + ret = dw_mipi_dsi_probe(pdev, &dw_mipi_dsi_stm_plat_data, &dsi->dsi); > + if (ret < 0) { > dev_err_probe(dev, ret, "Failed to initialize mipi dsi host\n"); > goto err_dsi_probe; > } > diff --git a/include/drm/bridge/dw_mipi_dsi.h b/include/drm/bridge/dw_mipi_dsi.h > index 65d5e68065e3..f073e819251e 100644 > --- a/include/drm/bridge/dw_mipi_dsi.h > +++ b/include/drm/bridge/dw_mipi_dsi.h > @@ -76,9 +76,10 @@ struct dw_mipi_dsi_plat_data { > void *priv_data; > }; > > -struct dw_mipi_dsi *dw_mipi_dsi_probe(struct platform_device *pdev, > +int dw_mipi_dsi_probe(struct platform_device *pdev, > const struct dw_mipi_dsi_plat_data > - *plat_data); > + *plat_data, > + struct dw_mipi_dsi **dsi_p); > void dw_mipi_dsi_remove(struct dw_mipi_dsi *dsi); > int dw_mipi_dsi_bind(struct dw_mipi_dsi *dsi, struct drm_encoder *encoder); > void dw_mipi_dsi_unbind(struct dw_mipi_dsi *dsi);
Am Montag, 15. Januar 2024, 09:45:10 CET schrieb neil.armstrong@linaro.org: > Hi, > > On 12/01/2024 19:07, Farouk Bouabid wrote: > > dw-mipi-dsi based drivers such as dw-mipi-dsi-rockchip or dw_mipi_dsi-stm > > depend on dw_mipi_dsi_probe() to initialize the dw_mipi_dsi driver > > structure (dmd pointer). This structure is only initialized once > > dw_mipi_dsi_probe() returns, creating the link between the locally created > > structure and the actual dmd pointer. > > > > Probing the dsi host can be deferred in case of dependency to a dsi > > phy-supply (eg. "rockchip,px30-dsi-dphy"). Meanwhile dsi-device drivers > > like panels (eg. "ltk050h3146w") can already be registered on the bus. > > In that case, when attempting, to register the dsi host from > > dw_mipi_dsi_probe() using mipi_dsi_host_register(), the panel probe is > > called with a dsi-host pointer that is still locally allocated in > > dw_mipi_dsi_probe(). > > > > While probing, the panel driver tries to attach to a dsi host > > (mipi_dsi_attach()) which calls in return for the specific dsi host > > attach hook. (e.g. dw_mipi_dsi_rockchip_host_attach()). > > dw_mipi_dsi_rockchip uses the component framework. > > In the attach hook, the host component is registered which calls in return > > for drm_bridge_attach() while trying to bind the component > > (dw_mipi_dsi_bind()) > > In meson_dw_mipi_dsi I simply fixed this by getting rid of components... If I remember correctly, the component element is there on Rockchip to facilitate running dual-dsi displays (1 panel driven by 2 dsi controllers), because it allows to wait for both controllers to have probed individually before trying to drive the display. Not sure if there is a better way to do that now. Heiko > > drm_bridge_attach() requires a valid drm bridge parameter. However, the > > drm bridge (&dmd->bridge) that will be passed, is not yet initialized since > > the dw_mipi_dsi_probe() has not yet returned. This call will fail with a > > fatal error (invalid bridge) causing the panel to not be probed again. > > > > To simplify the issue: drm_bridge_attach() depends on the result pointer > > of dw_mipi_dsi_probe(). > > While, if the dsi probe is deferred, drm_bridge_attach() is called before > > dw_mipi_dsi_probe() returns. > > > > drm_bridge_attach+0x14/0x1ac > > dw_mipi_dsi_bind+0x24/0x30 > > dw_mipi_dsi_rockchip_bind+0x258/0x378 > > component_bind_all+0x118/0x248 > > rockchip_drm_bind+0xb0/0x1f8 > > try_to_bring_up_aggregate_device+0x168/0x1d4 > > __component_add+0xa4/0x170 > > component_add+0x14/0x20 > > dw_mipi_dsi_rockchip_host_attach+0x54/0x144 > > dw_mipi_dsi_host_attach+0x9c/0xcc > > mipi_dsi_attach+0x28/0x3c > > ltk050h3146w_probe+0x10c/0x1a4 > > mipi_dsi_drv_probe+0x20/0x2c > > really_probe+0x148/0x2ac > > __driver_probe_device+0x78/0x12c > > driver_probe_device+0xdc/0x160 > > __device_attach_driver+0xb8/0x134 > > bus_for_each_drv+0x80/0xdc > > __device_attach+0xa8/0x1b0 > > device_initial_probe+0x14/0x20 > > bus_probe_device+0xa8/0xac > > device_add+0x5cc/0x778 > > mipi_dsi_device_register_full+0xd8/0x198 > > mipi_dsi_host_register+0x98/0x18c > > __dw_mipi_dsi_probe+0x290/0x35c > > dw_mipi_dsi_probe+0x10/0x6c > > dw_mipi_dsi_rockchip_probe+0x208/0x3e4 > > platform_probe+0x68/0xdc > > really_probe+0x148/0x2ac > > __driver_probe_device+0x78/0x12c > > driver_probe_device+0xdc/0x160 > > __device_attach_driver+0xb8/0x134 > > bus_for_each_drv+0x80/0xdc > > __device_attach+0xa8/0x1b0 > > device_initial_probe+0x14/0x20 > > bus_probe_device+0xa8/0xac > > deferred_probe_work_func+0x88/0xc0 > > process_one_work+0x138/0x260 > > worker_thread+0x32c/0x438 > > kthread+0x118/0x11c > > ret_from_fork+0x10/0x20 > > ---[ end trace 0000000000000000 ]--- > > > > Fix this by initializing directly the dmd pointer in dw_mipi_dsi_probe(), > > which requires also initializting the dmd->bridge attributes that are > > required in drm_bridge_attach() before calling mipi_dsi_host_register(). > > > > Signed-off-by: Farouk Bouabid <farouk.bouabid@theobroma-systems.com> > > --- > > drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c | 4 +- > > drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 42 ++++++++++--------- > > drivers/gpu/drm/meson/meson_dw_mipi_dsi.c | 8 ++-- > > .../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 5 +-- > > drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 5 +-- > > include/drm/bridge/dw_mipi_dsi.h | 5 ++- > > 6 files changed, 35 insertions(+), 34 deletions(-) > > > > diff --git a/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c b/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c > > index 3ff30ce80c5b..469976ad3b19 100644 > > --- a/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c > > +++ b/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c > > @@ -881,8 +881,8 @@ static int imx93_dsi_probe(struct platform_device *pdev) > > dsi->pdata.priv_data = dsi; > > platform_set_drvdata(pdev, dsi); > > > > - dsi->dmd = dw_mipi_dsi_probe(pdev, &dsi->pdata); > > - if (IS_ERR(dsi->dmd)) > > + ret = dw_mipi_dsi_probe(pdev, &dsi->pdata, &dsi->dmd); > > + if (ret < 0) > > return dev_err_probe(dev, PTR_ERR(dsi->dmd), > > "failed to probe dw_mipi_dsi\n"); > > > > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c > > index 824fb3c65742..306cba366ba8 100644 > > --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c > > +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c > > @@ -1184,18 +1184,19 @@ static void dw_mipi_dsi_debugfs_remove(struct dw_mipi_dsi *dsi) { } > > > > #endif /* CONFIG_DEBUG_FS */ > > > > -static struct dw_mipi_dsi * > > -__dw_mipi_dsi_probe(struct platform_device *pdev, > > - const struct dw_mipi_dsi_plat_data *plat_data) > > +int __dw_mipi_dsi_probe(struct platform_device *pdev, > > + const struct dw_mipi_dsi_plat_data *plat_data, struct dw_mipi_dsi **dsi_p) > > { > > struct device *dev = &pdev->dev; > > struct reset_control *apb_rst; > > struct dw_mipi_dsi *dsi; > > int ret; > > > > - dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL); > > - if (!dsi) > > - return ERR_PTR(-ENOMEM); > > + *dsi_p = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL); > > + if (!*dsi_p) > > + return -ENOMEM; > > + > > + dsi = *dsi_p; > > > > dsi->dev = dev; > > dsi->plat_data = plat_data; > > @@ -1203,13 +1204,13 @@ __dw_mipi_dsi_probe(struct platform_device *pdev, > > if (!plat_data->phy_ops->init || !plat_data->phy_ops->get_lane_mbps || > > !plat_data->phy_ops->get_timing) { > > DRM_ERROR("Phy not properly configured\n"); > > - return ERR_PTR(-ENODEV); > > + return -ENODEV; > > } > > > > if (!plat_data->base) { > > dsi->base = devm_platform_ioremap_resource(pdev, 0); > > if (IS_ERR(dsi->base)) > > - return ERR_PTR(-ENODEV); > > + return -ENODEV; > > > > } else { > > dsi->base = plat_data->base; > > @@ -1219,7 +1220,7 @@ __dw_mipi_dsi_probe(struct platform_device *pdev, > > if (IS_ERR(dsi->pclk)) { > > ret = PTR_ERR(dsi->pclk); > > dev_err(dev, "Unable to get pclk: %d\n", ret); > > - return ERR_PTR(ret); > > + return ret; > > } > > > > /* > > @@ -1233,14 +1234,14 @@ __dw_mipi_dsi_probe(struct platform_device *pdev, > > if (ret != -EPROBE_DEFER) > > dev_err(dev, "Unable to get reset control: %d\n", ret); > > > > - return ERR_PTR(ret); > > + return ret; > > } > > > > if (apb_rst) { > > ret = clk_prepare_enable(dsi->pclk); > > if (ret) { > > dev_err(dev, "%s: Failed to enable pclk\n", __func__); > > - return ERR_PTR(ret); > > + return ret; > > } > > > > reset_control_assert(apb_rst); > > @@ -1255,19 +1256,20 @@ __dw_mipi_dsi_probe(struct platform_device *pdev, > > > > dsi->dsi_host.ops = &dw_mipi_dsi_host_ops; > > dsi->dsi_host.dev = dev; > > + dsi->bridge.driver_private = dsi; > > + dsi->bridge.funcs = &dw_mipi_dsi_bridge_funcs; > > + dsi->bridge.of_node = pdev->dev.of_node; > > + > > ret = mipi_dsi_host_register(&dsi->dsi_host); > > if (ret) { > > dev_err(dev, "Failed to register MIPI host: %d\n", ret); > > pm_runtime_disable(dev); > > dw_mipi_dsi_debugfs_remove(dsi); > > - return ERR_PTR(ret); > > + return ret; > > } > > > > - dsi->bridge.driver_private = dsi; > > - dsi->bridge.funcs = &dw_mipi_dsi_bridge_funcs; > > - dsi->bridge.of_node = pdev->dev.of_node; > > > > - return dsi; > > + return 0; > > } > > > > static void __dw_mipi_dsi_remove(struct dw_mipi_dsi *dsi) > > @@ -1301,11 +1303,11 @@ EXPORT_SYMBOL_GPL(dw_mipi_dsi_get_bridge); > > /* > > * Probe/remove API, used from platforms based on the DRM bridge API. > > */ > > -struct dw_mipi_dsi * > > -dw_mipi_dsi_probe(struct platform_device *pdev, > > - const struct dw_mipi_dsi_plat_data *plat_data) > > +int dw_mipi_dsi_probe(struct platform_device *pdev, > > + const struct dw_mipi_dsi_plat_data *plat_data, > > + struct dw_mipi_dsi **dsi_p) > > { > > - return __dw_mipi_dsi_probe(pdev, plat_data); > > + return __dw_mipi_dsi_probe(pdev, plat_data, dsi_p); > > } > > EXPORT_SYMBOL_GPL(dw_mipi_dsi_probe); > > > > diff --git a/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c b/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c > > index e5fe4e994f43..b103f3e31f2a 100644 > > --- a/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c > > +++ b/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c > > @@ -262,6 +262,7 @@ static int meson_dw_mipi_dsi_probe(struct platform_device *pdev) > > { > > struct meson_dw_mipi_dsi *mipi_dsi; > > struct device *dev = &pdev->dev; > > + int ret; > > > > mipi_dsi = devm_kzalloc(dev, sizeof(*mipi_dsi), GFP_KERNEL); > > if (!mipi_dsi) > > @@ -315,10 +316,9 @@ static int meson_dw_mipi_dsi_probe(struct platform_device *pdev) > > mipi_dsi->pdata.priv_data = mipi_dsi; > > platform_set_drvdata(pdev, mipi_dsi); > > > > - mipi_dsi->dmd = dw_mipi_dsi_probe(pdev, &mipi_dsi->pdata); > > - if (IS_ERR(mipi_dsi->dmd)) > > - return dev_err_probe(dev, PTR_ERR(mipi_dsi->dmd), > > - "Failed to probe dw_mipi_dsi\n"); > > + ret = dw_mipi_dsi_probe(pdev, &mipi_dsi->pdata, &mipi_dsi->dmd); > > + if (ret < 0) > > + return dev_err_probe(dev, ret, "Failed to probe dw_mipi_dsi\n"); > > > > return 0; > > } > > diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c > > index 6396f9324dab..4df32747476c 100644 > > --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c > > +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c > > @@ -1457,9 +1457,8 @@ static int dw_mipi_dsi_rockchip_probe(struct platform_device *pdev) > > if (IS_ERR(phy_provider)) > > return PTR_ERR(phy_provider); > > > > - dsi->dmd = dw_mipi_dsi_probe(pdev, &dsi->pdata); > > - if (IS_ERR(dsi->dmd)) { > > - ret = PTR_ERR(dsi->dmd); > > + ret = dw_mipi_dsi_probe(pdev, &dsi->pdata, &dsi->dmd); > > + if (ret < 0) { > > if (ret != -EPROBE_DEFER) > > DRM_DEV_ERROR(dev, > > "Failed to probe dw_mipi_dsi: %d\n", ret); > > diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c > > index d5f8c923d7bc..44dbbfc277d8 100644 > > --- a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c > > +++ b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c > > @@ -518,9 +518,8 @@ static int dw_mipi_dsi_stm_probe(struct platform_device *pdev) > > > > platform_set_drvdata(pdev, dsi); > > > > - dsi->dsi = dw_mipi_dsi_probe(pdev, &dw_mipi_dsi_stm_plat_data); > > - if (IS_ERR(dsi->dsi)) { > > - ret = PTR_ERR(dsi->dsi); > > + ret = dw_mipi_dsi_probe(pdev, &dw_mipi_dsi_stm_plat_data, &dsi->dsi); > > + if (ret < 0) { > > dev_err_probe(dev, ret, "Failed to initialize mipi dsi host\n"); > > goto err_dsi_probe; > > } > > diff --git a/include/drm/bridge/dw_mipi_dsi.h b/include/drm/bridge/dw_mipi_dsi.h > > index 65d5e68065e3..f073e819251e 100644 > > --- a/include/drm/bridge/dw_mipi_dsi.h > > +++ b/include/drm/bridge/dw_mipi_dsi.h > > @@ -76,9 +76,10 @@ struct dw_mipi_dsi_plat_data { > > void *priv_data; > > }; > > > > -struct dw_mipi_dsi *dw_mipi_dsi_probe(struct platform_device *pdev, > > +int dw_mipi_dsi_probe(struct platform_device *pdev, > > const struct dw_mipi_dsi_plat_data > > - *plat_data); > > + *plat_data, > > + struct dw_mipi_dsi **dsi_p); > > void dw_mipi_dsi_remove(struct dw_mipi_dsi *dsi); > > int dw_mipi_dsi_bind(struct dw_mipi_dsi *dsi, struct drm_encoder *encoder); > > void dw_mipi_dsi_unbind(struct dw_mipi_dsi *dsi); > >
On 15/01/2024 11:07, Heiko Stübner wrote: > Am Montag, 15. Januar 2024, 09:45:10 CET schrieb neil.armstrong@linaro.org: >> Hi, >> >> On 12/01/2024 19:07, Farouk Bouabid wrote: >>> dw-mipi-dsi based drivers such as dw-mipi-dsi-rockchip or dw_mipi_dsi-stm >>> depend on dw_mipi_dsi_probe() to initialize the dw_mipi_dsi driver >>> structure (dmd pointer). This structure is only initialized once >>> dw_mipi_dsi_probe() returns, creating the link between the locally created >>> structure and the actual dmd pointer. >>> >>> Probing the dsi host can be deferred in case of dependency to a dsi >>> phy-supply (eg. "rockchip,px30-dsi-dphy"). Meanwhile dsi-device drivers >>> like panels (eg. "ltk050h3146w") can already be registered on the bus. >>> In that case, when attempting, to register the dsi host from >>> dw_mipi_dsi_probe() using mipi_dsi_host_register(), the panel probe is >>> called with a dsi-host pointer that is still locally allocated in >>> dw_mipi_dsi_probe(). >>> >>> While probing, the panel driver tries to attach to a dsi host >>> (mipi_dsi_attach()) which calls in return for the specific dsi host >>> attach hook. (e.g. dw_mipi_dsi_rockchip_host_attach()). >>> dw_mipi_dsi_rockchip uses the component framework. >>> In the attach hook, the host component is registered which calls in return >>> for drm_bridge_attach() while trying to bind the component >>> (dw_mipi_dsi_bind()) >> >> In meson_dw_mipi_dsi I simply fixed this by getting rid of components... > > If I remember correctly, the component element is there on Rockchip to > facilitate running dual-dsi displays (1 panel driven by 2 dsi controllers), > because it allows to wait for both controllers to have probed individually > before trying to drive the display. > > Not sure if there is a better way to do that now. Device links should limit probe deferal to a minimum, at least it works fine on the systems I work on Neil > > > Heiko > > >>> drm_bridge_attach() requires a valid drm bridge parameter. However, the >>> drm bridge (&dmd->bridge) that will be passed, is not yet initialized since >>> the dw_mipi_dsi_probe() has not yet returned. This call will fail with a >>> fatal error (invalid bridge) causing the panel to not be probed again. >>> >>> To simplify the issue: drm_bridge_attach() depends on the result pointer >>> of dw_mipi_dsi_probe(). >>> While, if the dsi probe is deferred, drm_bridge_attach() is called before >>> dw_mipi_dsi_probe() returns. >>> >>> drm_bridge_attach+0x14/0x1ac >>> dw_mipi_dsi_bind+0x24/0x30 >>> dw_mipi_dsi_rockchip_bind+0x258/0x378 >>> component_bind_all+0x118/0x248 >>> rockchip_drm_bind+0xb0/0x1f8 >>> try_to_bring_up_aggregate_device+0x168/0x1d4 >>> __component_add+0xa4/0x170 >>> component_add+0x14/0x20 >>> dw_mipi_dsi_rockchip_host_attach+0x54/0x144 >>> dw_mipi_dsi_host_attach+0x9c/0xcc >>> mipi_dsi_attach+0x28/0x3c >>> ltk050h3146w_probe+0x10c/0x1a4 >>> mipi_dsi_drv_probe+0x20/0x2c >>> really_probe+0x148/0x2ac >>> __driver_probe_device+0x78/0x12c >>> driver_probe_device+0xdc/0x160 >>> __device_attach_driver+0xb8/0x134 >>> bus_for_each_drv+0x80/0xdc >>> __device_attach+0xa8/0x1b0 >>> device_initial_probe+0x14/0x20 >>> bus_probe_device+0xa8/0xac >>> device_add+0x5cc/0x778 >>> mipi_dsi_device_register_full+0xd8/0x198 >>> mipi_dsi_host_register+0x98/0x18c >>> __dw_mipi_dsi_probe+0x290/0x35c >>> dw_mipi_dsi_probe+0x10/0x6c >>> dw_mipi_dsi_rockchip_probe+0x208/0x3e4 >>> platform_probe+0x68/0xdc >>> really_probe+0x148/0x2ac >>> __driver_probe_device+0x78/0x12c >>> driver_probe_device+0xdc/0x160 >>> __device_attach_driver+0xb8/0x134 >>> bus_for_each_drv+0x80/0xdc >>> __device_attach+0xa8/0x1b0 >>> device_initial_probe+0x14/0x20 >>> bus_probe_device+0xa8/0xac >>> deferred_probe_work_func+0x88/0xc0 >>> process_one_work+0x138/0x260 >>> worker_thread+0x32c/0x438 >>> kthread+0x118/0x11c >>> ret_from_fork+0x10/0x20 >>> ---[ end trace 0000000000000000 ]--- >>> >>> Fix this by initializing directly the dmd pointer in dw_mipi_dsi_probe(), >>> which requires also initializting the dmd->bridge attributes that are >>> required in drm_bridge_attach() before calling mipi_dsi_host_register(). >>> >>> Signed-off-by: Farouk Bouabid <farouk.bouabid@theobroma-systems.com> >>> --- >>> drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c | 4 +- >>> drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 42 ++++++++++--------- >>> drivers/gpu/drm/meson/meson_dw_mipi_dsi.c | 8 ++-- >>> .../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 5 +-- >>> drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 5 +-- >>> include/drm/bridge/dw_mipi_dsi.h | 5 ++- >>> 6 files changed, 35 insertions(+), 34 deletions(-) >>> >>> diff --git a/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c b/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c >>> index 3ff30ce80c5b..469976ad3b19 100644 >>> --- a/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c >>> +++ b/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c >>> @@ -881,8 +881,8 @@ static int imx93_dsi_probe(struct platform_device *pdev) >>> dsi->pdata.priv_data = dsi; >>> platform_set_drvdata(pdev, dsi); >>> >>> - dsi->dmd = dw_mipi_dsi_probe(pdev, &dsi->pdata); >>> - if (IS_ERR(dsi->dmd)) >>> + ret = dw_mipi_dsi_probe(pdev, &dsi->pdata, &dsi->dmd); >>> + if (ret < 0) >>> return dev_err_probe(dev, PTR_ERR(dsi->dmd), >>> "failed to probe dw_mipi_dsi\n"); >>> >>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c >>> index 824fb3c65742..306cba366ba8 100644 >>> --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c >>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c >>> @@ -1184,18 +1184,19 @@ static void dw_mipi_dsi_debugfs_remove(struct dw_mipi_dsi *dsi) { } >>> >>> #endif /* CONFIG_DEBUG_FS */ >>> >>> -static struct dw_mipi_dsi * >>> -__dw_mipi_dsi_probe(struct platform_device *pdev, >>> - const struct dw_mipi_dsi_plat_data *plat_data) >>> +int __dw_mipi_dsi_probe(struct platform_device *pdev, >>> + const struct dw_mipi_dsi_plat_data *plat_data, struct dw_mipi_dsi **dsi_p) >>> { >>> struct device *dev = &pdev->dev; >>> struct reset_control *apb_rst; >>> struct dw_mipi_dsi *dsi; >>> int ret; >>> >>> - dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL); >>> - if (!dsi) >>> - return ERR_PTR(-ENOMEM); >>> + *dsi_p = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL); >>> + if (!*dsi_p) >>> + return -ENOMEM; >>> + >>> + dsi = *dsi_p; >>> >>> dsi->dev = dev; >>> dsi->plat_data = plat_data; >>> @@ -1203,13 +1204,13 @@ __dw_mipi_dsi_probe(struct platform_device *pdev, >>> if (!plat_data->phy_ops->init || !plat_data->phy_ops->get_lane_mbps || >>> !plat_data->phy_ops->get_timing) { >>> DRM_ERROR("Phy not properly configured\n"); >>> - return ERR_PTR(-ENODEV); >>> + return -ENODEV; >>> } >>> >>> if (!plat_data->base) { >>> dsi->base = devm_platform_ioremap_resource(pdev, 0); >>> if (IS_ERR(dsi->base)) >>> - return ERR_PTR(-ENODEV); >>> + return -ENODEV; >>> >>> } else { >>> dsi->base = plat_data->base; >>> @@ -1219,7 +1220,7 @@ __dw_mipi_dsi_probe(struct platform_device *pdev, >>> if (IS_ERR(dsi->pclk)) { >>> ret = PTR_ERR(dsi->pclk); >>> dev_err(dev, "Unable to get pclk: %d\n", ret); >>> - return ERR_PTR(ret); >>> + return ret; >>> } >>> >>> /* >>> @@ -1233,14 +1234,14 @@ __dw_mipi_dsi_probe(struct platform_device *pdev, >>> if (ret != -EPROBE_DEFER) >>> dev_err(dev, "Unable to get reset control: %d\n", ret); >>> >>> - return ERR_PTR(ret); >>> + return ret; >>> } >>> >>> if (apb_rst) { >>> ret = clk_prepare_enable(dsi->pclk); >>> if (ret) { >>> dev_err(dev, "%s: Failed to enable pclk\n", __func__); >>> - return ERR_PTR(ret); >>> + return ret; >>> } >>> >>> reset_control_assert(apb_rst); >>> @@ -1255,19 +1256,20 @@ __dw_mipi_dsi_probe(struct platform_device *pdev, >>> >>> dsi->dsi_host.ops = &dw_mipi_dsi_host_ops; >>> dsi->dsi_host.dev = dev; >>> + dsi->bridge.driver_private = dsi; >>> + dsi->bridge.funcs = &dw_mipi_dsi_bridge_funcs; >>> + dsi->bridge.of_node = pdev->dev.of_node; >>> + >>> ret = mipi_dsi_host_register(&dsi->dsi_host); >>> if (ret) { >>> dev_err(dev, "Failed to register MIPI host: %d\n", ret); >>> pm_runtime_disable(dev); >>> dw_mipi_dsi_debugfs_remove(dsi); >>> - return ERR_PTR(ret); >>> + return ret; >>> } >>> >>> - dsi->bridge.driver_private = dsi; >>> - dsi->bridge.funcs = &dw_mipi_dsi_bridge_funcs; >>> - dsi->bridge.of_node = pdev->dev.of_node; >>> >>> - return dsi; >>> + return 0; >>> } >>> >>> static void __dw_mipi_dsi_remove(struct dw_mipi_dsi *dsi) >>> @@ -1301,11 +1303,11 @@ EXPORT_SYMBOL_GPL(dw_mipi_dsi_get_bridge); >>> /* >>> * Probe/remove API, used from platforms based on the DRM bridge API. >>> */ >>> -struct dw_mipi_dsi * >>> -dw_mipi_dsi_probe(struct platform_device *pdev, >>> - const struct dw_mipi_dsi_plat_data *plat_data) >>> +int dw_mipi_dsi_probe(struct platform_device *pdev, >>> + const struct dw_mipi_dsi_plat_data *plat_data, >>> + struct dw_mipi_dsi **dsi_p) >>> { >>> - return __dw_mipi_dsi_probe(pdev, plat_data); >>> + return __dw_mipi_dsi_probe(pdev, plat_data, dsi_p); >>> } >>> EXPORT_SYMBOL_GPL(dw_mipi_dsi_probe); >>> >>> diff --git a/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c b/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c >>> index e5fe4e994f43..b103f3e31f2a 100644 >>> --- a/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c >>> +++ b/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c >>> @@ -262,6 +262,7 @@ static int meson_dw_mipi_dsi_probe(struct platform_device *pdev) >>> { >>> struct meson_dw_mipi_dsi *mipi_dsi; >>> struct device *dev = &pdev->dev; >>> + int ret; >>> >>> mipi_dsi = devm_kzalloc(dev, sizeof(*mipi_dsi), GFP_KERNEL); >>> if (!mipi_dsi) >>> @@ -315,10 +316,9 @@ static int meson_dw_mipi_dsi_probe(struct platform_device *pdev) >>> mipi_dsi->pdata.priv_data = mipi_dsi; >>> platform_set_drvdata(pdev, mipi_dsi); >>> >>> - mipi_dsi->dmd = dw_mipi_dsi_probe(pdev, &mipi_dsi->pdata); >>> - if (IS_ERR(mipi_dsi->dmd)) >>> - return dev_err_probe(dev, PTR_ERR(mipi_dsi->dmd), >>> - "Failed to probe dw_mipi_dsi\n"); >>> + ret = dw_mipi_dsi_probe(pdev, &mipi_dsi->pdata, &mipi_dsi->dmd); >>> + if (ret < 0) >>> + return dev_err_probe(dev, ret, "Failed to probe dw_mipi_dsi\n"); >>> >>> return 0; >>> } >>> diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c >>> index 6396f9324dab..4df32747476c 100644 >>> --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c >>> +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c >>> @@ -1457,9 +1457,8 @@ static int dw_mipi_dsi_rockchip_probe(struct platform_device *pdev) >>> if (IS_ERR(phy_provider)) >>> return PTR_ERR(phy_provider); >>> >>> - dsi->dmd = dw_mipi_dsi_probe(pdev, &dsi->pdata); >>> - if (IS_ERR(dsi->dmd)) { >>> - ret = PTR_ERR(dsi->dmd); >>> + ret = dw_mipi_dsi_probe(pdev, &dsi->pdata, &dsi->dmd); >>> + if (ret < 0) { >>> if (ret != -EPROBE_DEFER) >>> DRM_DEV_ERROR(dev, >>> "Failed to probe dw_mipi_dsi: %d\n", ret); >>> diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c >>> index d5f8c923d7bc..44dbbfc277d8 100644 >>> --- a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c >>> +++ b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c >>> @@ -518,9 +518,8 @@ static int dw_mipi_dsi_stm_probe(struct platform_device *pdev) >>> >>> platform_set_drvdata(pdev, dsi); >>> >>> - dsi->dsi = dw_mipi_dsi_probe(pdev, &dw_mipi_dsi_stm_plat_data); >>> - if (IS_ERR(dsi->dsi)) { >>> - ret = PTR_ERR(dsi->dsi); >>> + ret = dw_mipi_dsi_probe(pdev, &dw_mipi_dsi_stm_plat_data, &dsi->dsi); >>> + if (ret < 0) { >>> dev_err_probe(dev, ret, "Failed to initialize mipi dsi host\n"); >>> goto err_dsi_probe; >>> } >>> diff --git a/include/drm/bridge/dw_mipi_dsi.h b/include/drm/bridge/dw_mipi_dsi.h >>> index 65d5e68065e3..f073e819251e 100644 >>> --- a/include/drm/bridge/dw_mipi_dsi.h >>> +++ b/include/drm/bridge/dw_mipi_dsi.h >>> @@ -76,9 +76,10 @@ struct dw_mipi_dsi_plat_data { >>> void *priv_data; >>> }; >>> >>> -struct dw_mipi_dsi *dw_mipi_dsi_probe(struct platform_device *pdev, >>> +int dw_mipi_dsi_probe(struct platform_device *pdev, >>> const struct dw_mipi_dsi_plat_data >>> - *plat_data); >>> + *plat_data, >>> + struct dw_mipi_dsi **dsi_p); >>> void dw_mipi_dsi_remove(struct dw_mipi_dsi *dsi); >>> int dw_mipi_dsi_bind(struct dw_mipi_dsi *dsi, struct drm_encoder *encoder); >>> void dw_mipi_dsi_unbind(struct dw_mipi_dsi *dsi); >> >> > > > >
Hi Farouk, kernel test robot noticed the following build warnings: [auto build test WARNING on drm-misc/drm-misc-next] [also build test WARNING on drm/drm-next linus/master v6.7 next-20240112] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Farouk-Bouabid/drm-bridge-synopsys-dw-mipi-dsi-fix-deferred-dsi-host-probe-breaks-dsi-device-probe/20240113-020945 base: git://anongit.freedesktop.org/drm/drm-misc drm-misc-next patch link: https://lore.kernel.org/r/20240112180737.551318-1-farouk.bouabid%40theobroma-systems.com patch subject: [PATCH] drm/bridge: synopsys: dw-mipi-dsi: fix deferred dsi host probe breaks dsi device probe config: i386-buildonly-randconfig-002-20240115 (https://download.01.org/0day-ci/archive/20240116/202401160108.j5Lqkppm-lkp@intel.com/config) compiler: gcc-12 (Debian 12.2.0-14) 12.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240116/202401160108.j5Lqkppm-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202401160108.j5Lqkppm-lkp@intel.com/ All warnings (new ones prefixed by >>): >> drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c:1187:5: warning: no previous prototype for '__dw_mipi_dsi_probe' [-Wmissing-prototypes] 1187 | int __dw_mipi_dsi_probe(struct platform_device *pdev, | ^~~~~~~~~~~~~~~~~~~ vim +/__dw_mipi_dsi_probe +1187 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 1186 > 1187 int __dw_mipi_dsi_probe(struct platform_device *pdev, 1188 const struct dw_mipi_dsi_plat_data *plat_data, struct dw_mipi_dsi **dsi_p) 1189 { 1190 struct device *dev = &pdev->dev; 1191 struct reset_control *apb_rst; 1192 struct dw_mipi_dsi *dsi; 1193 int ret; 1194 1195 *dsi_p = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL); 1196 if (!*dsi_p) 1197 return -ENOMEM; 1198 1199 dsi = *dsi_p; 1200 1201 dsi->dev = dev; 1202 dsi->plat_data = plat_data; 1203 1204 if (!plat_data->phy_ops->init || !plat_data->phy_ops->get_lane_mbps || 1205 !plat_data->phy_ops->get_timing) { 1206 DRM_ERROR("Phy not properly configured\n"); 1207 return -ENODEV; 1208 } 1209 1210 if (!plat_data->base) { 1211 dsi->base = devm_platform_ioremap_resource(pdev, 0); 1212 if (IS_ERR(dsi->base)) 1213 return -ENODEV; 1214 1215 } else { 1216 dsi->base = plat_data->base; 1217 } 1218 1219 dsi->pclk = devm_clk_get(dev, "pclk"); 1220 if (IS_ERR(dsi->pclk)) { 1221 ret = PTR_ERR(dsi->pclk); 1222 dev_err(dev, "Unable to get pclk: %d\n", ret); 1223 return ret; 1224 } 1225 1226 /* 1227 * Note that the reset was not defined in the initial device tree, so 1228 * we have to be prepared for it not being found. 1229 */ 1230 apb_rst = devm_reset_control_get_optional_exclusive(dev, "apb"); 1231 if (IS_ERR(apb_rst)) { 1232 ret = PTR_ERR(apb_rst); 1233 1234 if (ret != -EPROBE_DEFER) 1235 dev_err(dev, "Unable to get reset control: %d\n", ret); 1236 1237 return ret; 1238 } 1239 1240 if (apb_rst) { 1241 ret = clk_prepare_enable(dsi->pclk); 1242 if (ret) { 1243 dev_err(dev, "%s: Failed to enable pclk\n", __func__); 1244 return ret; 1245 } 1246 1247 reset_control_assert(apb_rst); 1248 usleep_range(10, 20); 1249 reset_control_deassert(apb_rst); 1250 1251 clk_disable_unprepare(dsi->pclk); 1252 } 1253 1254 dw_mipi_dsi_debugfs_init(dsi); 1255 pm_runtime_enable(dev); 1256 1257 dsi->dsi_host.ops = &dw_mipi_dsi_host_ops; 1258 dsi->dsi_host.dev = dev; 1259 dsi->bridge.driver_private = dsi; 1260 dsi->bridge.funcs = &dw_mipi_dsi_bridge_funcs; 1261 dsi->bridge.of_node = pdev->dev.of_node; 1262 1263 ret = mipi_dsi_host_register(&dsi->dsi_host); 1264 if (ret) { 1265 dev_err(dev, "Failed to register MIPI host: %d\n", ret); 1266 pm_runtime_disable(dev); 1267 dw_mipi_dsi_debugfs_remove(dsi); 1268 return ret; 1269 } 1270 1271 1272 return 0; 1273 } 1274
diff --git a/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c b/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c index 3ff30ce80c5b..469976ad3b19 100644 --- a/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c @@ -881,8 +881,8 @@ static int imx93_dsi_probe(struct platform_device *pdev) dsi->pdata.priv_data = dsi; platform_set_drvdata(pdev, dsi); - dsi->dmd = dw_mipi_dsi_probe(pdev, &dsi->pdata); - if (IS_ERR(dsi->dmd)) + ret = dw_mipi_dsi_probe(pdev, &dsi->pdata, &dsi->dmd); + if (ret < 0) return dev_err_probe(dev, PTR_ERR(dsi->dmd), "failed to probe dw_mipi_dsi\n"); diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c index 824fb3c65742..306cba366ba8 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -1184,18 +1184,19 @@ static void dw_mipi_dsi_debugfs_remove(struct dw_mipi_dsi *dsi) { } #endif /* CONFIG_DEBUG_FS */ -static struct dw_mipi_dsi * -__dw_mipi_dsi_probe(struct platform_device *pdev, - const struct dw_mipi_dsi_plat_data *plat_data) +int __dw_mipi_dsi_probe(struct platform_device *pdev, + const struct dw_mipi_dsi_plat_data *plat_data, struct dw_mipi_dsi **dsi_p) { struct device *dev = &pdev->dev; struct reset_control *apb_rst; struct dw_mipi_dsi *dsi; int ret; - dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL); - if (!dsi) - return ERR_PTR(-ENOMEM); + *dsi_p = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL); + if (!*dsi_p) + return -ENOMEM; + + dsi = *dsi_p; dsi->dev = dev; dsi->plat_data = plat_data; @@ -1203,13 +1204,13 @@ __dw_mipi_dsi_probe(struct platform_device *pdev, if (!plat_data->phy_ops->init || !plat_data->phy_ops->get_lane_mbps || !plat_data->phy_ops->get_timing) { DRM_ERROR("Phy not properly configured\n"); - return ERR_PTR(-ENODEV); + return -ENODEV; } if (!plat_data->base) { dsi->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(dsi->base)) - return ERR_PTR(-ENODEV); + return -ENODEV; } else { dsi->base = plat_data->base; @@ -1219,7 +1220,7 @@ __dw_mipi_dsi_probe(struct platform_device *pdev, if (IS_ERR(dsi->pclk)) { ret = PTR_ERR(dsi->pclk); dev_err(dev, "Unable to get pclk: %d\n", ret); - return ERR_PTR(ret); + return ret; } /* @@ -1233,14 +1234,14 @@ __dw_mipi_dsi_probe(struct platform_device *pdev, if (ret != -EPROBE_DEFER) dev_err(dev, "Unable to get reset control: %d\n", ret); - return ERR_PTR(ret); + return ret; } if (apb_rst) { ret = clk_prepare_enable(dsi->pclk); if (ret) { dev_err(dev, "%s: Failed to enable pclk\n", __func__); - return ERR_PTR(ret); + return ret; } reset_control_assert(apb_rst); @@ -1255,19 +1256,20 @@ __dw_mipi_dsi_probe(struct platform_device *pdev, dsi->dsi_host.ops = &dw_mipi_dsi_host_ops; dsi->dsi_host.dev = dev; + dsi->bridge.driver_private = dsi; + dsi->bridge.funcs = &dw_mipi_dsi_bridge_funcs; + dsi->bridge.of_node = pdev->dev.of_node; + ret = mipi_dsi_host_register(&dsi->dsi_host); if (ret) { dev_err(dev, "Failed to register MIPI host: %d\n", ret); pm_runtime_disable(dev); dw_mipi_dsi_debugfs_remove(dsi); - return ERR_PTR(ret); + return ret; } - dsi->bridge.driver_private = dsi; - dsi->bridge.funcs = &dw_mipi_dsi_bridge_funcs; - dsi->bridge.of_node = pdev->dev.of_node; - return dsi; + return 0; } static void __dw_mipi_dsi_remove(struct dw_mipi_dsi *dsi) @@ -1301,11 +1303,11 @@ EXPORT_SYMBOL_GPL(dw_mipi_dsi_get_bridge); /* * Probe/remove API, used from platforms based on the DRM bridge API. */ -struct dw_mipi_dsi * -dw_mipi_dsi_probe(struct platform_device *pdev, - const struct dw_mipi_dsi_plat_data *plat_data) +int dw_mipi_dsi_probe(struct platform_device *pdev, + const struct dw_mipi_dsi_plat_data *plat_data, + struct dw_mipi_dsi **dsi_p) { - return __dw_mipi_dsi_probe(pdev, plat_data); + return __dw_mipi_dsi_probe(pdev, plat_data, dsi_p); } EXPORT_SYMBOL_GPL(dw_mipi_dsi_probe); diff --git a/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c b/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c index e5fe4e994f43..b103f3e31f2a 100644 --- a/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c +++ b/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c @@ -262,6 +262,7 @@ static int meson_dw_mipi_dsi_probe(struct platform_device *pdev) { struct meson_dw_mipi_dsi *mipi_dsi; struct device *dev = &pdev->dev; + int ret; mipi_dsi = devm_kzalloc(dev, sizeof(*mipi_dsi), GFP_KERNEL); if (!mipi_dsi) @@ -315,10 +316,9 @@ static int meson_dw_mipi_dsi_probe(struct platform_device *pdev) mipi_dsi->pdata.priv_data = mipi_dsi; platform_set_drvdata(pdev, mipi_dsi); - mipi_dsi->dmd = dw_mipi_dsi_probe(pdev, &mipi_dsi->pdata); - if (IS_ERR(mipi_dsi->dmd)) - return dev_err_probe(dev, PTR_ERR(mipi_dsi->dmd), - "Failed to probe dw_mipi_dsi\n"); + ret = dw_mipi_dsi_probe(pdev, &mipi_dsi->pdata, &mipi_dsi->dmd); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to probe dw_mipi_dsi\n"); return 0; } diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c index 6396f9324dab..4df32747476c 100644 --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c @@ -1457,9 +1457,8 @@ static int dw_mipi_dsi_rockchip_probe(struct platform_device *pdev) if (IS_ERR(phy_provider)) return PTR_ERR(phy_provider); - dsi->dmd = dw_mipi_dsi_probe(pdev, &dsi->pdata); - if (IS_ERR(dsi->dmd)) { - ret = PTR_ERR(dsi->dmd); + ret = dw_mipi_dsi_probe(pdev, &dsi->pdata, &dsi->dmd); + if (ret < 0) { if (ret != -EPROBE_DEFER) DRM_DEV_ERROR(dev, "Failed to probe dw_mipi_dsi: %d\n", ret); diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c index d5f8c923d7bc..44dbbfc277d8 100644 --- a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c +++ b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c @@ -518,9 +518,8 @@ static int dw_mipi_dsi_stm_probe(struct platform_device *pdev) platform_set_drvdata(pdev, dsi); - dsi->dsi = dw_mipi_dsi_probe(pdev, &dw_mipi_dsi_stm_plat_data); - if (IS_ERR(dsi->dsi)) { - ret = PTR_ERR(dsi->dsi); + ret = dw_mipi_dsi_probe(pdev, &dw_mipi_dsi_stm_plat_data, &dsi->dsi); + if (ret < 0) { dev_err_probe(dev, ret, "Failed to initialize mipi dsi host\n"); goto err_dsi_probe; } diff --git a/include/drm/bridge/dw_mipi_dsi.h b/include/drm/bridge/dw_mipi_dsi.h index 65d5e68065e3..f073e819251e 100644 --- a/include/drm/bridge/dw_mipi_dsi.h +++ b/include/drm/bridge/dw_mipi_dsi.h @@ -76,9 +76,10 @@ struct dw_mipi_dsi_plat_data { void *priv_data; }; -struct dw_mipi_dsi *dw_mipi_dsi_probe(struct platform_device *pdev, +int dw_mipi_dsi_probe(struct platform_device *pdev, const struct dw_mipi_dsi_plat_data - *plat_data); + *plat_data, + struct dw_mipi_dsi **dsi_p); void dw_mipi_dsi_remove(struct dw_mipi_dsi *dsi); int dw_mipi_dsi_bind(struct dw_mipi_dsi *dsi, struct drm_encoder *encoder); void dw_mipi_dsi_unbind(struct dw_mipi_dsi *dsi);