From patchwork Wed Sep 4 09:00:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chen-Yu Tsai X-Patchwork-Id: 825405 Received: from mail-pf1-f171.google.com (mail-pf1-f171.google.com [209.85.210.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ADFE31CEE80 for ; Wed, 4 Sep 2024 09:00:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725440434; cv=none; b=NCzsTU4On0nH23zZMZcIUXOfVPRTgqeei6ktzfb6PpAHQcgv+xq//TaYIqv+5xcgv2PLgNgJ7dtat+lwfCyAY3lmKVYNQHk7qqRArKaQR+erDVLLeRy8y5Wch5eHmWsH22TUVhoqEgpBMKKp9Nq01ZdMCEdx65ZT0nmKxGO7KkM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725440434; c=relaxed/simple; bh=GK2iV7hMvsjSokJ5lrwH0JIQORr559M1Qg4L1f7m7ec=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hVXhFR9Gshs2B6g4fyDr+jSJbbDVrarmMCxDnzudxEND39vhnLox0vFPKGY4Udic098Yxn31jnayxMSycbLPTb18TJABJaINHXIc5ekv1E1d3nw4RaoZoO3LkjEoH2fD+axmwHGq16qjmZeB19Hq4y3UWdnJ23rCVj/y3/oObOQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=WOIfX3hj; arc=none smtp.client-ip=209.85.210.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="WOIfX3hj" Received: by mail-pf1-f171.google.com with SMTP id d2e1a72fcca58-717849c0dcaso17767b3a.3 for ; Wed, 04 Sep 2024 02:00:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1725440432; x=1726045232; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=2M921d4gJ85snm6ehV18l9ZU1Po4pieq34BYMUnhsNU=; b=WOIfX3hjDg/B6nOWJFqswDzkv7RJSVszP3PIL9DHoaFqKV5rLQRNtrECXlXT2HoxwS eJg0sBYagroXd4yEeAofcZC3h/Ncp58ACaS8xXhwKD10S5B0z5vxjBRTibKTmn98yoYB s088umVKcgwYX9w+HHCqAW7EtzgUa+qeVl8sc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725440432; x=1726045232; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=2M921d4gJ85snm6ehV18l9ZU1Po4pieq34BYMUnhsNU=; b=g+7rBaQUaJjDUa2EnLTe6QbHE3VRTjjs/q8cmrXdhlWD+Yw2HnKe2BhHiVkr6IpZZM DcJqjSa6vz7e5WK/hY7eU3oH1xB7catP/di1V0sC4IssNfZdq1m58cm+xKGtjAeNew6L 5HVddgKUQpmeQZXU97hbo3AXMfNwTA0/ME41eDvLDOQ1hNeHZCKbVJu0szsn/ehjO3zG sc0FjxHDGWpn7wP86tAetdMTJlm0YsXTYPu5Rvu7irScFP31D/Bk5tPQ1fLSi8auMtJg 1L/XNQwkgIxFDV9kX84RdG1LvdeWgRK6jGPX/sHf4c/UQPtBZk0rzbXaLfCW2C5UUdb1 eekg== X-Forwarded-Encrypted: i=1; AJvYcCVW5011VIAoutzfs8QxA7K6339kO9TLUxBZMtGDpUN7resvCqbfdzvOoueHp8isARMuq058EXI85RM=@vger.kernel.org X-Gm-Message-State: AOJu0YxBWs39SVKtv+rxPXWRqhEYsNke92zlSomVUnl9u7G6yzsB7hMz KvfCWrYczFc8PK9gDSq5Abj04P+wVEAgyQ+QBAw0XUywnluIDjZXvQ84B4eWzA== X-Google-Smtp-Source: AGHT+IF/MVW4wrOQrl8cYkGW2jFbuYY69p3WFoLB5FjxApHmcb1+fCtPnl3w/uoQeTGzo0ajB2S9PQ== X-Received: by 2002:a05:6a00:66d9:b0:710:e4db:a6fc with SMTP id d2e1a72fcca58-7173b6b63demr14365184b3a.27.1725440430497; Wed, 04 Sep 2024 02:00:30 -0700 (PDT) Received: from wenstp920.tpe.corp.google.com ([2401:fa00:1:10:83fc:5c8e:13bd:d165]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-717785b5183sm1153279b3a.197.2024.09.04.02.00.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Sep 2024 02:00:30 -0700 (PDT) From: Chen-Yu Tsai To: Rob Herring , Saravana Kannan , Matthias Brugger , AngeloGioacchino Del Regno , Wolfram Sang , Benson Leung , Tzung-Bi Shih , Mark Brown , Liam Girdwood Cc: Chen-Yu Tsai , chrome-platform@lists.linux.dev, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-kernel@vger.kernel.org, Douglas Anderson , Johan Hovold , Jiri Kosina , Andy Shevchenko , linux-i2c@vger.kernel.org Subject: [PATCH v6 02/12] of: base: Add for_each_child_of_node_with_prefix_scoped() Date: Wed, 4 Sep 2024 17:00:04 +0800 Message-ID: <20240904090016.2841572-3-wenst@chromium.org> X-Mailer: git-send-email 2.46.0.469.g59c65b2a67-goog In-Reply-To: <20240904090016.2841572-1-wenst@chromium.org> References: <20240904090016.2841572-1-wenst@chromium.org> Precedence: bulk X-Mailing-List: linux-i2c@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 There are cases where drivers would go through child device nodes and operate on only the ones whose node name starts with a given prefix. Provide a helper for these users. This will mainly be used in a subsequent patch that implements a hardware component prober for I2C busses. Signed-off-by: Chen-Yu Tsai --- Changes since v5: - New patch --- drivers/of/base.c | 35 +++++++++++++++++++++++++++++++++++ include/linux/of.h | 9 +++++++++ 2 files changed, 44 insertions(+) diff --git a/drivers/of/base.c b/drivers/of/base.c index 20603d3c9931..d3c123b3261a 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -628,6 +628,41 @@ struct device_node *of_get_next_child(const struct device_node *node, } EXPORT_SYMBOL(of_get_next_child); +/** + * of_get_next_child_with_prefix - Find the next child node with prefix + * @node: parent node + * @prev: previous child of the parent node, or NULL to get first + * + * This function is like of_get_next_child(), except that it automatically + * skips any nodes whose name doesn't have the given prefix. + * + * Return: A node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_get_next_child_with_prefix(const struct device_node *node, + struct device_node *prev, + const char *prefix) +{ + struct device_node *next; + unsigned long flags; + + if (!node) + return NULL; + + raw_spin_lock_irqsave(&devtree_lock, flags); + next = prev ? prev->sibling : node->child; + for (; next; next = next->sibling) { + if (!of_node_name_prefix(next, prefix)) + continue; + if (of_node_get(next)) + break; + } + of_node_put(prev); + raw_spin_unlock_irqrestore(&devtree_lock, flags); + return next; +} +EXPORT_SYMBOL(of_get_next_child_with_prefix); + static struct device_node *of_get_next_status_child(const struct device_node *node, struct device_node *prev, bool (*checker)(const struct device_node *)) diff --git a/include/linux/of.h b/include/linux/of.h index 046283be1cd3..acc0d5b98417 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -289,6 +289,9 @@ extern struct device_node *of_get_parent(const struct device_node *node); extern struct device_node *of_get_next_parent(struct device_node *node); extern struct device_node *of_get_next_child(const struct device_node *node, struct device_node *prev); +extern struct device_node *of_get_next_child_with_prefix(const struct device_node *node, + struct device_node *prev, + const char *prefix); extern struct device_node *of_get_next_available_child( const struct device_node *node, struct device_node *prev); extern struct device_node *of_get_next_reserved_child( @@ -1468,6 +1471,12 @@ static inline int of_property_read_s32(const struct device_node *np, child != NULL; \ child = of_get_next_child(parent, child)) +#define for_each_child_of_node_with_prefix_scoped(parent, child, prefix) \ + for (struct device_node *child __free(device_node) = \ + of_get_next_child_with_prefix(parent, NULL, prefix); \ + child != NULL; \ + child = of_get_next_child_with_prefix(parent, child, prefix)) + #define for_each_available_child_of_node(parent, child) \ for (child = of_get_next_available_child(parent, NULL); child != NULL; \ child = of_get_next_available_child(parent, child)) From patchwork Wed Sep 4 09:00:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chen-Yu Tsai X-Patchwork-Id: 825404 Received: from mail-pf1-f170.google.com (mail-pf1-f170.google.com [209.85.210.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8EFDA1CF2B5 for ; Wed, 4 Sep 2024 09:00:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725440440; cv=none; b=oWF+9OgcTfXIFRp+CgsWnz5mKLzZ0R11D4M9WD53pgnQkcvvKe9Cys++6tud05+EH18+yq0hD0kUmnEDh3atCkqyLKxLxenTSOvy6ERrIs91L3BLK7iIfGdqadkie0Y6C48P1FhPmjB7G79DA8zI6ZXNBzgOau+nooYhlizupZw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725440440; c=relaxed/simple; bh=vfouHZ0OIsqMydCSjbbh9j+9aQPzT5coh1Y7d+J5JLY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nf/v1NTnY3lASm2+DSqPdY9NGtO91KIngJLAdL196hyPtUb7ql+K5E+wGWXNK8zhOPdF6PIev7gsHIDMBgadLCM5Hn+xNDqpYnFEStglQhFyHU8S9AJ6vtOciIVWKQPVrPfC94Z1E70gFKvXcPCw0YR5gC+MaGz4WHndEujd5Io= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=TsTjsS65; arc=none smtp.client-ip=209.85.210.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="TsTjsS65" Received: by mail-pf1-f170.google.com with SMTP id d2e1a72fcca58-7176645e501so1963890b3a.1 for ; Wed, 04 Sep 2024 02:00:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1725440438; x=1726045238; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=b0sbG/jw58dFVSs3/2Q1ZWzAnnopRuiveILCTgaftSY=; b=TsTjsS65B3VlAtj0fcmcNx4Y2WPTTocs8Bqn/+3UoIRruTcibCyzitSpCl2Frqu6pf cLvd+if/yl6ajW79KuWUtOMhsxQ8H9DPG5aYRTi9B+tfhRpPdY8vE9KGM5cCjBr0qRie 05vuCqU63YRbK5KS1mQosOmsmWlW23dOVM2ak= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725440438; x=1726045238; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=b0sbG/jw58dFVSs3/2Q1ZWzAnnopRuiveILCTgaftSY=; b=DBcZLazQjl+Ba8y3wUpekXQ7J+3bpheujhGALckR3mjw9Hr8x/H0wR3+9yRaivx/k/ EY9PTK0UdGUjrEhvN2vGxT9gRh2d6Ru35aka198WPGVfmm4t2bk2+vG40UcSw57/27TA Q4UJf/EWXa3Rt/WW/j1tjcw2t9yxgPO1Znc1e6AJ0SfpqU0E0Gwr2piTTiwGm1uc/w1z MFRiK7kDn0wnkr5rQAc1+Xco/rQHD1FmhGeLVAJYTvD0KCqy/MZekFtJwwQoh25LpYzM meEzSnvKrEIaVJUbQlGqBXvJlpwRi7A2G6VWrSe6HOXr7AEcq5bQAl7LPJhlSQMbEbq6 23UA== X-Forwarded-Encrypted: i=1; AJvYcCVYJQnZgcjM4uz6i2oDOn5j3oz8QFBMUDyvhO/x4XxSnNCmX/hY2gAqVRnDMkEVbYbdFhWpAqqbL9I=@vger.kernel.org X-Gm-Message-State: AOJu0YzhUNEejjR70VLhqUJZGQNAuTavkjiLwspeW0ZQSoM7PKhlM0fP kTAs7H99HKiHBKvcXhDedc7VDVa6aj7N894qNt705F4HmzYHf095raL+WrETLw== X-Google-Smtp-Source: AGHT+IFJnhX8EeVHE/Pb/2Pe1cdA+zN3kwfbn5THcKUWQl9Uebvww0bAh3IhVagxcNqMcqnK8VZyqg== X-Received: by 2002:a05:6a21:6e4b:b0:1c6:ac08:8dd2 with SMTP id adf61e73a8af0-1ced6087aaemr11569081637.15.1725440437588; Wed, 04 Sep 2024 02:00:37 -0700 (PDT) Received: from wenstp920.tpe.corp.google.com ([2401:fa00:1:10:83fc:5c8e:13bd:d165]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-717785b5183sm1153279b3a.197.2024.09.04.02.00.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Sep 2024 02:00:37 -0700 (PDT) From: Chen-Yu Tsai To: Rob Herring , Saravana Kannan , Matthias Brugger , AngeloGioacchino Del Regno , Wolfram Sang , Benson Leung , Tzung-Bi Shih , Mark Brown , Liam Girdwood Cc: Chen-Yu Tsai , chrome-platform@lists.linux.dev, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-kernel@vger.kernel.org, Douglas Anderson , Johan Hovold , Jiri Kosina , Andy Shevchenko , linux-i2c@vger.kernel.org Subject: [PATCH v6 04/12] regulator: Split up _regulator_get() Date: Wed, 4 Sep 2024 17:00:06 +0800 Message-ID: <20240904090016.2841572-5-wenst@chromium.org> X-Mailer: git-send-email 2.46.0.469.g59c65b2a67-goog In-Reply-To: <20240904090016.2841572-1-wenst@chromium.org> References: <20240904090016.2841572-1-wenst@chromium.org> Precedence: bulk X-Mailing-List: linux-i2c@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 _regulator_get() contains a lot of common code doing checks prior to the regulator lookup and housekeeping work after the lookup. Almost all the code could be shared with a OF-specific variant of _regulator_get(). Split out the common parts so that they can be reused. The OF-specific version of _regulator_get() will be added in a subsequent patch. No functional changes were made. Signed-off-by: Chen-Yu Tsai --- Changes since v5: - Fixed kerneldoc "Return" section format for _regulator_get_common() - Slightly reworded return value description Changes since v4: - New patch --- drivers/regulator/core.c | 54 ++++++++++++++++++++++++++++-------- drivers/regulator/internal.h | 4 +++ 2 files changed, 47 insertions(+), 11 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 835a5531d045..d60c86477ac2 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2103,26 +2103,43 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) return ret; } -/* Internal regulator request function */ -struct regulator *_regulator_get(struct device *dev, const char *id, - enum regulator_get_type get_type) +/* common pre-checks for regulator requests */ +int _regulator_get_common_check(struct device *dev, const char *id, + enum regulator_get_type get_type) { - struct regulator_dev *rdev; - struct regulator *regulator; - struct device_link *link; - int ret; - if (get_type >= MAX_GET_TYPE) { dev_err(dev, "invalid type %d in %s\n", get_type, __func__); - return ERR_PTR(-EINVAL); + return -EINVAL; } if (id == NULL) { dev_err(dev, "regulator request with no identifier\n"); - return ERR_PTR(-EINVAL); + return -EINVAL; } - rdev = regulator_dev_lookup(dev, id); + return 0; +} + +/** + * _regulator_get_common - Common code for regulator requests + * @rdev: regulator device pointer as returned by *regulator_dev_lookup() + * Its reference count is expected to have been incremented. + * @dev: device used for dev_printk messages + * @id: Supply name or regulator ID + * @get_type: enum regulator_get_type value corresponding to type of request + * + * Returns: pointer to struct regulator corresponding to @rdev, or ERR_PTR() + * encoded error. + * + * This function should be chained with *regulator_dev_lookup() functions. + */ +struct regulator *_regulator_get_common(struct regulator_dev *rdev, struct device *dev, + const char *id, enum regulator_get_type get_type) +{ + struct regulator *regulator; + struct device_link *link; + int ret; + if (IS_ERR(rdev)) { ret = PTR_ERR(rdev); @@ -2238,6 +2255,21 @@ struct regulator *_regulator_get(struct device *dev, const char *id, return regulator; } +/* Internal regulator request function */ +struct regulator *_regulator_get(struct device *dev, const char *id, + enum regulator_get_type get_type) +{ + struct regulator_dev *rdev; + int ret; + + ret = _regulator_get_common_check(dev, id, get_type); + if (ret) + return ERR_PTR(ret); + + rdev = regulator_dev_lookup(dev, id); + return _regulator_get_common(rdev, dev, id, get_type); +} + /** * regulator_get - lookup and obtain a reference to a regulator. * @dev: device for regulator "consumer" diff --git a/drivers/regulator/internal.h b/drivers/regulator/internal.h index 8e5506c5ee94..5b43f802468d 100644 --- a/drivers/regulator/internal.h +++ b/drivers/regulator/internal.h @@ -121,6 +121,10 @@ enum regulator_get_type { MAX_GET_TYPE }; +int _regulator_get_common_check(struct device *dev, const char *id, + enum regulator_get_type get_type); +struct regulator *_regulator_get_common(struct regulator_dev *rdev, struct device *dev, + const char *id, enum regulator_get_type get_type); struct regulator *_regulator_get(struct device *dev, const char *id, enum regulator_get_type get_type); int _regulator_bulk_get(struct device *dev, int num_consumers, From patchwork Wed Sep 4 09:00:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chen-Yu Tsai X-Patchwork-Id: 825403 Received: from mail-pf1-f181.google.com (mail-pf1-f181.google.com [209.85.210.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 632F41CF5F7 for ; Wed, 4 Sep 2024 09:00:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725440446; cv=none; b=lsr03xrHng1fJkG8I0hyhoe4qzsGaoPgeOaXbukydjW0Yi7sfpQm5zmKgs26+upzHf5TR/W2kuX3ZyVWMMef1JZ/aUMD9qt+C/Hs+j1MIxRAXw0cMe7YVIuibdJU4pEwUbfonbsydtoOIXpKkIOxF5uJnBWEwbKy6spbHQ4kP2Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725440446; c=relaxed/simple; bh=rtIMsOt6wo4AfcXvwPWe+CMfwtVUeU2YX21kuRORNiY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=sIYgzfp5SmtOR+noF9b0xQakgUnFq+5xpHESqdQGacmIykP/vZloUillCV6oA9PQzjw0kRgQ7PdaJYcUaEHXseB1ywXNkOLc7E5TJRHbI6w5sch9aqwXZlPbuGyVfSt7NEsEIMf48LbfFQlH02p2GTnBrpaR3ZCTlDPaTjLbSKY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=FKJzTyPn; arc=none smtp.client-ip=209.85.210.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="FKJzTyPn" Received: by mail-pf1-f181.google.com with SMTP id d2e1a72fcca58-715c160e231so5298726b3a.0 for ; Wed, 04 Sep 2024 02:00:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1725440445; x=1726045245; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=oXe0bTAdK4fzeVHk0iwWr+4YgaeXrtwwmT3G1fAlM0c=; b=FKJzTyPnsNejt0Lnh3J5Sh1NLRMCC41wBPRch0fpvePChGV50iTl9dRyvor0vVQuF0 9M0K0nl1Q5xJiMHC1KSowBKDXJzKWhWaDQ1HMNqsSJ9D0TgLhR+P1GcLJJ1T0C354KVD F2AO9GCHqgoDEdhnzm1qghDRre8y0Q8VoHVZY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725440445; x=1726045245; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=oXe0bTAdK4fzeVHk0iwWr+4YgaeXrtwwmT3G1fAlM0c=; b=H+qsKTnMQJkMIXD2h63RvFoALcdrhq2AENQctUQiTQVybq7IOHlJgcIX5wfypUXMjU Z7zKTyg1Z/L+KRC7vynv/FpJkiAqKjup9LdoxPAAgpRftwXoE0WN69al0E163Ki7WWhn Em29NPPQQi0aqy6Zv+ziI3rA66m29wet8buqxKqO4cHbn1UIBfkoTPRDC6kUCkPv/YCp wykbLzzAn1UAFpsSI/tu8U7hHAIMrpR9HTX0wlSnsQEqLK45GNI6UpTf+ArUHp/+YVLc FQySwM6XyQj6n2VajaTcytsgG/iohqDiqoSCVheVThm4mO0k4g8NGBq18IwBigD6Ct7h R4Sg== X-Forwarded-Encrypted: i=1; AJvYcCX9CfXXsxcxQdryGKS9goop5nh4g2BxcEhAddz6qa1OK9hj7rwFHhWFmGSof/xhtn3X+Vl3K+3OIuw=@vger.kernel.org X-Gm-Message-State: AOJu0YzlK6kGlSE5tRbAXjEOYme6qYDj7hQUP0wWKFoK2J1iyaWmJ9nU BgzNqqoJwhuYFTRw2YRwWjuhOw4tDLD9n+8eRKXLg5RXhBEku5d1pB0yvhykIQ== X-Google-Smtp-Source: AGHT+IGxijmAvO+pYlgJ7hjMKsPERsrObcLBwxYEKhBRWkHQTmof+srMssUjYemzBoLP7fiuqVV5Ew== X-Received: by 2002:a05:6a20:d48c:b0:1be:c929:e269 with SMTP id adf61e73a8af0-1cce10ab242mr24768495637.34.1725440444657; Wed, 04 Sep 2024 02:00:44 -0700 (PDT) Received: from wenstp920.tpe.corp.google.com ([2401:fa00:1:10:83fc:5c8e:13bd:d165]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-717785b5183sm1153279b3a.197.2024.09.04.02.00.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Sep 2024 02:00:44 -0700 (PDT) From: Chen-Yu Tsai To: Rob Herring , Saravana Kannan , Matthias Brugger , AngeloGioacchino Del Regno , Wolfram Sang , Benson Leung , Tzung-Bi Shih , Mark Brown , Liam Girdwood Cc: Chen-Yu Tsai , chrome-platform@lists.linux.dev, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-kernel@vger.kernel.org, Douglas Anderson , Johan Hovold , Jiri Kosina , Andy Shevchenko , linux-i2c@vger.kernel.org Subject: [PATCH v6 06/12] gpiolib: Add gpio_get_property_name_length() Date: Wed, 4 Sep 2024 17:00:08 +0800 Message-ID: <20240904090016.2841572-7-wenst@chromium.org> X-Mailer: git-send-email 2.46.0.469.g59c65b2a67-goog In-Reply-To: <20240904090016.2841572-1-wenst@chromium.org> References: <20240904090016.2841572-1-wenst@chromium.org> Precedence: bulk X-Mailing-List: linux-i2c@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The I2C device tree component prober needs to get and toggle GPIO lines for the components it intends to probe. These components may not use the same name for their GPIO lines, so the prober must go through the device tree, check each property to see it is a GPIO property, and get the GPIO line. Instead of duplicating the GPIO suffixes, or exporting them to the prober to do pattern matching, simply add and export a new function that does the pattern matching and returns the length of the GPIO name. The caller can then use that to copy out the name if it needs to. Andy suggested a much shorter implementation. Suggested-by: Andy Shevchenko Signed-off-by: Chen-Yu Tsai --- Changes since v5: - Changed function name to "gpio_get_property_name_length()" - Changed argument name to "propname" - Clarified return value for "*-" case - Reworked according to Andy's suggestion - Added stub function Changes since v4: - new patch --- drivers/gpio/gpiolib.c | 25 +++++++++++++++++++++++++ include/linux/gpio/consumer.h | 7 +++++++ 2 files changed, 32 insertions(+) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 3903d0a75304..86527cc7991b 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -4295,6 +4295,31 @@ struct gpio_desc *fwnode_gpiod_get_index(struct fwnode_handle *fwnode, } EXPORT_SYMBOL_GPL(fwnode_gpiod_get_index); +/** + * gpio_get_property_name_length - Returns the GPIO name length from a property name + * @propname: name of the property to check + * + * This function checks if the given property name matches the GPIO property + * patterns, and returns the length of the name of the GPIO. The pattern is + * "*-" or just "". + * + * Returns: + * The length of the string before '-' if it matches + * "*-", or 0 if no name part, just the suffix, or + * -EINVAL if the string doesn't match the pattern. + */ +int gpio_get_property_name_length(const char *propname) +{ + const char *dash = strrchr(propname, '-'); + + for (const char *const *p = gpio_suffixes; *p; p++) + if (!strcmp(dash ? dash + 1 : propname, *p)) + return dash ? dash - propname : 0; + + return -EINVAL; +} +EXPORT_SYMBOL_GPL(gpio_get_property_name_length); + /** * gpiod_count - return the number of GPIOs associated with a device / function * or -ENOENT if no GPIO has been assigned to the requested function diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h index db2dfbae8edb..494dde33ca44 100644 --- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h @@ -56,6 +56,8 @@ enum gpiod_flags { #ifdef CONFIG_GPIOLIB +int gpio_get_property_name_length(const char *propname); + /* Return the number of GPIOs associated with a device / function */ int gpiod_count(struct device *dev, const char *con_id); @@ -188,6 +190,11 @@ struct gpio_desc *devm_fwnode_gpiod_get_index(struct device *dev, #include +static inline int gpio_get_property_name_length(const char *propname) +{ + return ERR_PTR(-ENOSYS); +} + static inline int gpiod_count(struct device *dev, const char *con_id) { return 0; From patchwork Wed Sep 4 09:00:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chen-Yu Tsai X-Patchwork-Id: 825402 Received: from mail-pf1-f173.google.com (mail-pf1-f173.google.com [209.85.210.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 186821CFEAB for ; Wed, 4 Sep 2024 09:00:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725440454; cv=none; b=SS9iCChu5QwaFGS1NKuv0Rfk+8smlmWZ4kWn0QVBbPWMmEAsYPK4PcvqneP+/z0OrHlTWd5Lu3V9JJBqcFwMpNP2zqql9cboB/7V+UipuQi6Mq8e616C0OhKVK6HG1KFWXMCf60PzuWOq55S7ShIotqzlzQIDrOkYOHbNIcUT68= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725440454; c=relaxed/simple; bh=a+9IMV7TAc0Mf9NyOqoJsvZxnZwYcqZ+hL5syojxIYI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=A6t9yPG9JojiZqWSkTiOpLzZvjG3GT5YCH5dLV0y7xN040NHD/4ojV+l/+LK8L9dKxRj9EwyC6AI48kmugeq9yMRHRLbHKuLJnRkKBZu93WezaKFYzuYcZaTXyymjdfmN4CzcJZMK9qXfffQyc6eWlsTYDSzunn9NychReZT1x0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=JZS4hm0Z; arc=none smtp.client-ip=209.85.210.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="JZS4hm0Z" Received: by mail-pf1-f173.google.com with SMTP id d2e1a72fcca58-71774dcd09aso1097219b3a.0 for ; Wed, 04 Sep 2024 02:00:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1725440452; x=1726045252; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=3ed6jqfoQQgVNg3s8z2id6R5BmVDPgmpZejNIbOkDt8=; b=JZS4hm0Z3Myk+264AlULChTGTk1VNgfDiTUXbveNEvrfasMPPTOyXcr0RnM+cFXjyd W74LpcFgFjdf4WcKuZmtRIEJlPotoSNqX4nMbs9naKjzEto56N6N1Q4B5ZD50lsJFNNm LR5vhWcqbNC3SKg4GgrWBkzPWWtJdApoWzW1c= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725440452; x=1726045252; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=3ed6jqfoQQgVNg3s8z2id6R5BmVDPgmpZejNIbOkDt8=; b=qgMQRXHV6ioeOzAD2uOVsIu9XcACUs49lv5dxVwjyG2SZg+gKmdMPyH6/13/Pjt9EY BW5E3VIAy89KJ3+JQqDP2OlsYt+0WC9wgWdr4hdrfVcaR7zwkvs+IRhg99rF7Yeo02Ux gOwSMiJ5aO45ayvTv9Mg0NYxDijsdknqAhaPN0ku4kxSgw1nsUZa89++iH7LzvL9++dI JzpZqLqWru4PbFJAB2i1Cvexgv5oTw661LkR6Sr6QFzbLrOaIgZFcA5lElsy3DbY6fh0 c+6ieymhav2sRo5ZtSAVNbTGT9kaLc+2t9/nrYjt9ZmQ6+4aptYGYbzlAKVivoPJjvVX jlqA== X-Forwarded-Encrypted: i=1; AJvYcCUymBRMfiaNpqCDOZ5EbRBujaCD/MWakBLUFef1O/6nWwwz5LjGg3IpeNrF1C21UfjFF/S2a+8gCAc=@vger.kernel.org X-Gm-Message-State: AOJu0YwLjNC0QU64CX9WZfPrO2X/QBYyKP5cFEfDxBadcpSpnPxQ90gv V6U4V4195jJ5MFhzC/cPSNR9eRrMqWUO9l+1Z9B4yAI4+dwMgGN/7FFK7sTNcWMesNim96pl5Dw = X-Google-Smtp-Source: AGHT+IHgy+GLE/Elk7AlgRjkOzPzYZQvWSrVWrXb8ZopFFo9Tqw+tlmxWy6NqFA6LVTclmTWOYnewQ== X-Received: by 2002:a05:6a00:2da8:b0:70e:8070:f9d0 with SMTP id d2e1a72fcca58-7173fa40bcfmr10345406b3a.9.1725440452151; Wed, 04 Sep 2024 02:00:52 -0700 (PDT) Received: from wenstp920.tpe.corp.google.com ([2401:fa00:1:10:83fc:5c8e:13bd:d165]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-717785b5183sm1153279b3a.197.2024.09.04.02.00.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Sep 2024 02:00:51 -0700 (PDT) From: Chen-Yu Tsai To: Rob Herring , Saravana Kannan , Matthias Brugger , AngeloGioacchino Del Regno , Wolfram Sang , Benson Leung , Tzung-Bi Shih , Mark Brown , Liam Girdwood Cc: Chen-Yu Tsai , chrome-platform@lists.linux.dev, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-kernel@vger.kernel.org, Douglas Anderson , Johan Hovold , Jiri Kosina , Andy Shevchenko , linux-i2c@vger.kernel.org Subject: [PATCH v6 08/12] i2c: Introduce OF component probe function Date: Wed, 4 Sep 2024 17:00:10 +0800 Message-ID: <20240904090016.2841572-9-wenst@chromium.org> X-Mailer: git-send-email 2.46.0.469.g59c65b2a67-goog In-Reply-To: <20240904090016.2841572-1-wenst@chromium.org> References: <20240904090016.2841572-1-wenst@chromium.org> Precedence: bulk X-Mailing-List: linux-i2c@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Some devices are designed and manufactured with some components having multiple drop-in replacement options. These components are often connected to the mainboard via ribbon cables, having the same signals and pin assignments across all options. These may include the display panel and touchscreen on laptops and tablets, and the trackpad on laptops. Sometimes which component option is used in a particular device can be detected by some firmware provided identifier, other times that information is not available, and the kernel has to try to probe each device. This change attempts to make the "probe each device" case cleaner. The current approach is to have all options added and enabled in the device tree. The kernel would then bind each device and run each driver's probe function. This works, but has been broken before due to the introduction of asynchronous probing, causing multiple instances requesting "shared" resources, such as pinmuxes, GPIO pins, interrupt lines, at the same time, with only one instance succeeding. Work arounds for these include moving the pinmux to the parent I2C controller, using GPIO hogs or pinmux settings to keep the GPIO pins in some fixed configuration, and requesting the interrupt line very late. Such configurations can be seen on the MT8183 Krane Chromebook tablets, and the Qualcomm sc8280xp-based Lenovo Thinkpad 13S. Instead of this delicate dance between drivers and device tree quirks, this change introduces a simple I2C component probe. function For a given class of devices on the same I2C bus, it will go through all of them, doing a simple I2C read transfer and see which one of them responds. It will then enable the device that responds. This requires some minor modifications in the existing device tree. The status for all the device nodes for the component options must be set to "failed-needs-probe". This makes it clear that some mechanism is needed to enable one of them, and also prevents the prober and device drivers running at the same time. Signed-off-by: Chen-Yu Tsai --- Changes since v5: - Fixed indent in Makefile - Split regulator and GPIO TODO items - Reversed final conditional in i2c_of_probe_enable_node() Changes since v4: - Split code into helper functions - Use scoped helpers and __free() to reduce error path Changes since v3: - Complete kernel-doc - Return different error if I2C controller is disabled - Expand comment to explain assumptions and constraints - Split for-loop finding target node and operations on target node - Add missing i2c_put_adapter() - Move prober code to separate file Rob also asked why there was a limitation of "exactly one touchscreen will be enabled across the whole tree". The use case this prober currently targets is a component on consumer electronics (tablet or laptop) being swapped out due to cost or supply reasons. Designs with multiple components of the same type are pretty rare. The way the next patch is written also assumes this for efficiency reasons. Changes since v2: - New patch split out from "of: Introduce hardware prober driver" - Addressed Rob's comments - Move i2c prober to i2c subsystem - Use of_node_is_available() to check if node is enabled. - Use OF changeset API to update status property - Addressed Andy's comments - Probe function now accepts "struct device *dev" instead to reduce line length and dereferences - Move "ret = 0" to just before for_each_child_of_node(i2c_node, node) --- drivers/i2c/Makefile | 1 + drivers/i2c/i2c-core-of-prober.c | 158 +++++++++++++++++++++++++++++++ include/linux/i2c.h | 4 + 3 files changed, 163 insertions(+) create mode 100644 drivers/i2c/i2c-core-of-prober.c diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index f12d6b10a85e..c539cdc1e305 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -9,6 +9,7 @@ i2c-core-objs := i2c-core-base.o i2c-core-smbus.o i2c-core-$(CONFIG_ACPI) += i2c-core-acpi.o i2c-core-$(CONFIG_I2C_SLAVE) += i2c-core-slave.o i2c-core-$(CONFIG_OF) += i2c-core-of.o +i2c-core-$(CONFIG_OF_DYNAMIC) += i2c-core-of-prober.o obj-$(CONFIG_I2C_SMBUS) += i2c-smbus.o obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o diff --git a/drivers/i2c/i2c-core-of-prober.c b/drivers/i2c/i2c-core-of-prober.c new file mode 100644 index 000000000000..64d7631f4885 --- /dev/null +++ b/drivers/i2c/i2c-core-of-prober.c @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Linux I2C core OF component prober code + * + * Copyright (C) 2024 Google LLC + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Some devices, such as Google Hana Chromebooks, are produced by multiple + * vendors each using their preferred components. Such components are all + * in the device tree. Instead of having all of them enabled and having each + * driver separately try and probe its device while fighting over shared + * resources, they can be marked as "fail-needs-probe" and have a prober + * figure out which one is actually used beforehand. + * + * This prober assumes such drop-in parts are on the same I2C bus, have + * non-conflicting addresses, and can be directly probed by seeing which + * address responds. + * + * TODO: + * - Support handling common regulators. + * - Support handling common GPIOs. + * - Support I2C muxes + */ + +static struct device_node *i2c_of_probe_get_i2c_node(struct device *dev, const char *type) +{ + struct device_node *node __free(device_node) = of_find_node_by_name(NULL, type); + if (!node) + return dev_err_ptr_probe(dev, -ENODEV, "Could not find %s device node\n", type); + + struct device_node *i2c_node __free(device_node) = of_get_parent(node); + if (!of_node_name_eq(i2c_node, "i2c")) + return dev_err_ptr_probe(dev, -EINVAL, "%s device isn't on I2C bus\n", type); + + if (!of_device_is_available(i2c_node)) + return dev_err_ptr_probe(dev, -ENODEV, "I2C controller not available\n"); + + return no_free_ptr(i2c_node); +} + +static int i2c_of_probe_enable_node(struct device *dev, struct device_node *node) +{ + int ret; + + dev_info(dev, "Enabling %pOF\n", node); + + struct of_changeset *ocs __free(kfree) = kzalloc(sizeof(*ocs), GFP_KERNEL); + if (!ocs) + return -ENOMEM; + + of_changeset_init(ocs); + ret = of_changeset_update_prop_string(ocs, node, "status", "okay"); + if (ret) + return ret; + + ret = of_changeset_apply(ocs); + if (ret) { + /* ocs needs to be explicitly cleaned up before being freed. */ + of_changeset_destroy(ocs); + } else { + /* + * ocs is intentionally kept around as it needs to + * exist as long as the change is applied. + */ + void *ptr __always_unused = no_free_ptr(ocs); + } + + return ret; +} + +/** + * i2c_of_probe_component() - probe for devices of "type" on the same i2c bus + * @dev: &struct device of the caller, only used for dev_* printk messages + * @type: a string to match the device node name prefix to probe for + * + * Probe for possible I2C components of the same "type" on the same I2C bus + * that have their status marked as "fail". + * + * Assumes that across the entire device tree the only instances of nodes + * prefixed with "type" are the ones that need handling for second source + * components. In other words, if type is "touchscreen", then all device + * nodes named "touchscreen*" are the ones that need probing. There cannot + * be another "touchscreen" node that is already enabled. + * + * Assumes that for each "type" of component, only one actually exists. In + * other words, only one matching and existing device will be enabled. + * + * Context: Process context only. Does non-atomic I2C transfers. + * Should only be used from a driver probe function, as the function + * can return -EPROBE_DEFER if the I2C adapter is unavailable. + * Return: 0 on success or no-op, error code otherwise. + * A no-op can happen when it seems like the device tree already + * has components of the type to be probed already enabled. This + * can happen when the device tree had not been updated to mark + * the status of the to-be-probed components as "fail". Or this + * function was already run with the same parameters and succeeded + * in enabling a component. The latter could happen if the user + * had multiple types of components to probe, and one of them down + * the list caused a deferred probe. This is expected behavior. + */ +int i2c_of_probe_component(struct device *dev, const char *type) +{ + struct i2c_adapter *i2c; + int ret; + + struct device_node *i2c_node __free(device_node) = i2c_of_probe_get_i2c_node(dev, type); + if (IS_ERR(i2c_node)) + return PTR_ERR(i2c_node); + + for_each_child_of_node_scoped(i2c_node, node) { + if (!of_node_name_prefix(node, type)) + continue; + if (!of_device_is_available(node)) + continue; + + /* + * Device tree has component already enabled. Either the + * device tree isn't supported or we already probed once. + */ + return 0; + } + + i2c = of_get_i2c_adapter_by_node(i2c_node); + if (!i2c) + return dev_err_probe(dev, -EPROBE_DEFER, "Couldn't get I2C adapter\n"); + + ret = 0; + for_each_child_of_node_scoped(i2c_node, node) { + union i2c_smbus_data data; + u32 addr; + + if (!of_node_name_prefix(node, type)) + continue; + if (of_property_read_u32(node, "reg", &addr)) + continue; + if (i2c_smbus_xfer(i2c, addr, 0, I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &data) < 0) + continue; + + /* Found a device that is responding */ + ret = i2c_of_probe_enable_node(dev, node); + break; + } + + i2c_put_adapter(i2c); + + return ret; +} +EXPORT_SYMBOL_GPL(i2c_of_probe_component); diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 388ce71a29a9..c6c16731243d 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -1033,6 +1033,10 @@ const struct of_device_id int of_i2c_get_board_info(struct device *dev, struct device_node *node, struct i2c_board_info *info); +#if IS_ENABLED(CONFIG_OF_DYNAMIC) +int i2c_of_probe_component(struct device *dev, const char *type); +#endif + #else static inline struct i2c_client *of_find_i2c_device_by_node(struct device_node *node) From patchwork Wed Sep 4 09:00:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chen-Yu Tsai X-Patchwork-Id: 825401 Received: from mail-pf1-f176.google.com (mail-pf1-f176.google.com [209.85.210.176]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5C44B1D0145 for ; Wed, 4 Sep 2024 09:01:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.176 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725440462; cv=none; b=o4C7j9vFdxRh7jkz2WzpK5nL8sODz161Lfc4XsQ/cBGD87WaslkuYcq3IInFXD6cJlhVnCT1sA7nNznt1RrES8Twk2RNZmJIBztLx0trolS0CnlhNqf8lQSR4E1+7hNGG9oxiPQ+ZvQcTv7/rEbn/P2+rqrUkS1zKc2MAMXPRzI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725440462; c=relaxed/simple; bh=4K305JIRgo5Lt75f2UfKKVi9Egt/vEF85rIFriq9DXc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=sMkYqCm7fh+99feMiR6+QP6ijfNZtJIvsbkG6Jf2WLPa9x5pDg5/XNMZVG5d2vLEh1zarN4SQv8MgoJX/077EGcy+osGhCNDnqQp4/YarLKFouuMT6MlcD82TcFNYfSIN+177cJ9kSnaiFLByYxsmA4qJIWGV++8fS2YyoJbo74= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=LeEDUwzC; arc=none smtp.client-ip=209.85.210.176 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="LeEDUwzC" Received: by mail-pf1-f176.google.com with SMTP id d2e1a72fcca58-7143165f23fso5032531b3a.1 for ; Wed, 04 Sep 2024 02:01:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1725440459; x=1726045259; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=DwAJluv0Exq9EadYfBSyNeJ8D4Ka/sU/iYmJbm5J4eo=; b=LeEDUwzCaIOKV3GR1pJDR0BbLlVGzv7YEmM20hEe87dm7fwZitVx8VO56BZiS8gXEq dYeNRAvK33FGpvS/8ev3GUC/ShayTJJVhqggfnZOVGlmQiHLYpCMC+T3j8+Y1TQxGN2A vou+TtuI0Ru7HKUV+LaWXlWC3czAMQ8f5umBU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725440459; x=1726045259; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=DwAJluv0Exq9EadYfBSyNeJ8D4Ka/sU/iYmJbm5J4eo=; b=kl8Qs99luaTJn4cfXynUYBvyrc9fh188lhkSfUolqT6dR/zLT3pe0WntNz/oNBayTf 45MtxTC9aNtZyVykrunjV+tXpzvGABSVb+p2ci0kDcE9h7jG0WqLptFirRAeUUTFVvqN WOXqU+p3dRqb43XPlW5xvp/99316CNZrOcejDRqwH+40a/YqZ+u0JJjV06WLr+zdzIn7 NSCDy/T2fPPTwQP23cT9ieknTQLzrB8qDfVYMklUWH429MONFk5TbwHcD/+ekk1aYS9d KNrvlS+orTCJLfH2U6W89/mXUcyY6z85NJoaP4g7gcHPrvQ9hZUcpzg3j0Vda1vsCFyV CmNA== X-Forwarded-Encrypted: i=1; AJvYcCWLAUFurUPY1tkGY+EPn7WXP6MwFyT8kHE6PoC7MoZmM6IzV1NhPhUxNLwRuvee4qb69y4UC/JyPys=@vger.kernel.org X-Gm-Message-State: AOJu0Yz69T37MTXqINFO8RIRORNYJqNb2N0lyFAYK226v/xIstssxFOM QJQnw7YlMSMFGBhrQSS8LXTfmaFpw6PNcskc3PZTSdxBvzBp8Aqpz/O7rXwahg== X-Google-Smtp-Source: AGHT+IFFqCnmeBWZ9aXSqOpUywkoxinPfwTNU43tOQwWBlrfj1Rm3kLKZ4eIZFoE+WAsIUVUCM7mHQ== X-Received: by 2002:a05:6a21:1813:b0:1cd:f065:4ef7 with SMTP id adf61e73a8af0-1ced0469052mr12363435637.19.1725440459454; Wed, 04 Sep 2024 02:00:59 -0700 (PDT) Received: from wenstp920.tpe.corp.google.com ([2401:fa00:1:10:83fc:5c8e:13bd:d165]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-717785b5183sm1153279b3a.197.2024.09.04.02.00.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Sep 2024 02:00:59 -0700 (PDT) From: Chen-Yu Tsai To: Rob Herring , Saravana Kannan , Matthias Brugger , AngeloGioacchino Del Regno , Wolfram Sang , Benson Leung , Tzung-Bi Shih , Mark Brown , Liam Girdwood Cc: Chen-Yu Tsai , chrome-platform@lists.linux.dev, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-kernel@vger.kernel.org, Douglas Anderson , Johan Hovold , Jiri Kosina , Andy Shevchenko , linux-i2c@vger.kernel.org Subject: [PATCH v6 10/12] i2c: of-prober: Add GPIO support Date: Wed, 4 Sep 2024 17:00:12 +0800 Message-ID: <20240904090016.2841572-11-wenst@chromium.org> X-Mailer: git-send-email 2.46.0.469.g59c65b2a67-goog In-Reply-To: <20240904090016.2841572-1-wenst@chromium.org> References: <20240904090016.2841572-1-wenst@chromium.org> Precedence: bulk X-Mailing-List: linux-i2c@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This adds GPIO management to the I2C OF component prober. Components that the prober intends to probe likely require their regulator supplies be enabled, and GPIOs be toggled to enable them or bring them out of reset before they will respond to probe attempts. regulator support was added in the previous patch. Without specific knowledge of each component's resource names or power sequencing requirements, the prober can only enable the regulator supplies all at once, and toggle the GPIOs all at once. Luckily, reset pins tend to be active low, while enable pins tend to be active high, so setting the raw status of all GPIO pins to high should work. The wait time before and after resources are enabled are collected from existing drivers and device trees. The prober collects resources from all possible components and enables them together, instead of enabling resources and probing each component one by one. The latter approach does not provide any boot time benefits over simply enabling each component and letting each driver probe sequentially. The prober will also deduplicate the resources, since on a component swap out or co-layout design, the resources are always the same. While duplicate regulator supplies won't cause much issue, shared GPIOs don't work reliably, especially with other drivers. For the same reason, the prober will release the GPIOs before the successfully probed component is actually enabled. Signed-off-by: Chen-Yu Tsai --- Changes since v5: - Renamed "con" to "propname" in i2c_of_probe_get_gpiod() - Copy string first and check return value of strscpy() for overflow in i2c_of_probe_get_gpiod() - Add parenthesis around "enable" and "reset" GPIO names in comments - Split resource count debug message into two separate lines - Split out GPIO helper from i2c_of_probe_enable_res() to keep code cleaner following the previous patch - Adopted options for customizing power sequencing delay following previous patch Changes since v4: - Split out from previous patch - Moved GPIO property name check to common function in gpiolib.c in new patch - Moved i2c_of_probe_free_gpios() into for_each_child_of_node_scoped() - Rewrote in gpiod_*_array-esque fashion --- drivers/i2c/i2c-core-of-prober.c | 143 ++++++++++++++++++++++++++++++- include/linux/i2c.h | 2 + 2 files changed, 144 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/i2c-core-of-prober.c b/drivers/i2c/i2c-core-of-prober.c index 56b06ad7aa64..04242ff86e69 100644 --- a/drivers/i2c/i2c-core-of-prober.c +++ b/drivers/i2c/i2c-core-of-prober.c @@ -5,16 +5,19 @@ * Copyright (C) 2024 Google LLC */ +#include #include #include #include #include #include +#include #include #include #include #include #include +#include /* * Some devices, such as Google Hana Chromebooks, are produced by multiple @@ -29,12 +32,14 @@ * address responds. * * TODO: - * - Support handling common GPIOs. + * - Support inverted polarity GPIOs, such as electrical high to "disable". + * Seen on some OmniVision camera sensors. * - Support I2C muxes */ struct i2c_of_probe_data { const struct i2c_of_probe_opts *opts; + struct gpio_descs *gpiods; struct regulator_bulk_data *regulators; unsigned int regulators_num; }; @@ -85,10 +90,90 @@ static void i2c_of_probe_free_regulators(struct i2c_of_probe_data *data) regulator_bulk_free(data->regulators_num, data->regulators); data->regulators_num = 0; data->regulators = NULL; +}; + +/* + * Returns 1 if property is GPIO and GPIO successfully requested, + * 0 if not a GPIO property, or error if request for GPIO failed. + */ +static int i2c_of_probe_get_gpiod(struct device_node *node, struct property *prop, + struct i2c_of_probe_data *data) +{ + struct fwnode_handle *fwnode = of_fwnode_handle(node); + struct gpio_descs *gpiods; + struct gpio_desc *gpiod; + char propname[32]; /* 32 is max size of property name */ + char *con_id = NULL; + size_t new_size; + int len, ret; + + len = gpio_get_property_name_length(prop->name); + if (len < 0) + return 0; + + ret = strscpy(propname, prop->name); + if (ret < 0) { + pr_err("%pOF: length of GPIO name \"%s\" exceeds current limit\n", + node, prop->name); + return -EINVAL; + } + + if (len > 0) { + /* "len < ARRAY_SIZE(propname)" guaranteed by strscpy() above */ + propname[len] = '\0'; + con_id = propname; + } + + /* + * GPIO descriptors are not reference counted. GPIOD_FLAGS_BIT_NONEXCLUSIVE + * can't differentiate between GPIOs shared between devices to be probed and + * other devices (which is incorrect). If the initial request fails with + * -EBUSY, retry with GPIOD_FLAGS_BIT_NONEXCLUSIVE and see if it matches + * any existing ones. + */ + gpiod = fwnode_gpiod_get_index(fwnode, con_id, 0, GPIOD_ASIS, "i2c-of-prober"); + if (IS_ERR(gpiod)) { + if (PTR_ERR(gpiod) != -EBUSY || !data->gpiods) + return PTR_ERR(gpiod); + + gpiod = fwnode_gpiod_get_index(fwnode, con_id, 0, + GPIOD_ASIS | GPIOD_FLAGS_BIT_NONEXCLUSIVE, + "i2c-of-prober"); + for (unsigned int i = 0; i < data->gpiods->ndescs; i++) + if (gpiod == data->gpiods->desc[i]) + return 1; + + return -EBUSY; + } + + new_size = struct_size(gpiods, desc, data->gpiods ? data->gpiods->ndescs + 1 : 1); + gpiods = krealloc(data->gpiods, new_size, GFP_KERNEL); + if (!gpiods) { + gpiod_put(gpiod); + return -ENOMEM; + } + + data->gpiods = gpiods; + data->gpiods->desc[data->gpiods->ndescs++] = gpiod; + + return 1; +} + +/* + * This is split into two functions because in the normal flow the GPIOs + * have to be released before the actual driver probes so that the latter + * can acquire them. + */ +static void i2c_of_probe_free_gpios(struct i2c_of_probe_data *data) +{ + if (data->gpiods) + gpiod_put_array(data->gpiods); + data->gpiods = NULL; } static void i2c_of_probe_free_res(struct i2c_of_probe_data *data) { + i2c_of_probe_free_gpios(data); i2c_of_probe_free_regulators(data); } @@ -104,6 +189,18 @@ static int i2c_of_probe_get_res(struct device *dev, struct device_node *node, goto err_cleanup; } + for_each_property_of_node(node, prop) { + dev_dbg(dev, "Trying property %pOF/%s\n", node, prop->name); + + /* GPIOs */ + ret = i2c_of_probe_get_gpiod(node, prop, data); + if (ret < 0) { + dev_err_probe(dev, ret, "Failed to get GPIO from %pOF/%s\n", + node, prop->name); + goto err_cleanup; + } + } + return 0; err_cleanup: @@ -131,6 +228,37 @@ static void i2c_of_probe_disable_regulators(struct i2c_of_probe_data *data) regulator_bulk_disable(data->regulators_num, data->regulators); } +static int i2c_of_probe_set_gpios(struct device *dev, struct i2c_of_probe_data *data) +{ + int ret; + int gpio_i; + + if (!data->gpiods) + return 0; + + for (gpio_i = 0; gpio_i < data->gpiods->ndescs; gpio_i++) { + /* + * "reset" GPIOs normally have opposite polarity compared to + * "enable" GPIOs. Instead of parsing the flags again, simply + * set the raw value to high. + */ + dev_dbg(dev, "Setting GPIO %d\n", gpio_i); + ret = gpiod_direction_output_raw(data->gpiods->desc[gpio_i], 1); + if (ret) + goto disable_gpios; + } + + msleep(data->opts->post_reset_deassert_delay_ms); + + return 0; + +disable_gpios: + for (gpio_i--; gpio_i >= 0; gpio_i--) + gpiod_set_raw_value_cansleep(data->gpiods->desc[gpio_i], 0); + + return ret; +} + static int i2c_of_probe_enable_res(struct device *dev, struct i2c_of_probe_data *data) { int ret; @@ -139,7 +267,15 @@ static int i2c_of_probe_enable_res(struct device *dev, struct i2c_of_probe_data if (ret) return ret; + ret = i2c_of_probe_set_gpios(dev, data); + if (ret) + goto err_disable_regulators; + return 0; + +err_disable_regulators: + i2c_of_probe_disable_regulators(data); + return ret; } static struct device_node *i2c_of_probe_get_i2c_node(struct device *dev, const char *type) @@ -191,6 +327,8 @@ static int i2c_of_probe_enable_node(struct device *dev, struct device_node *node static const struct i2c_of_probe_opts i2c_of_probe_opts_default = { /* largest post-power-on pre-reset-deassert delay seen among drivers */ .post_power_on_delay_ms = 500, + /* largest post-reset-deassert delay seen in tree for Elan I2C HID */ + .post_reset_deassert_delay_ms = 300, }; /** @@ -264,6 +402,8 @@ int i2c_of_probe_component(struct device *dev, const char *type, const struct i2 } dev_dbg(dev, "Resources: # of regulator supplies = %d\n", probe_data.regulators_num); + dev_dbg(dev, "Resources: # of GPIOs = %d\n", + probe_data.gpiods ? probe_data.gpiods->ndescs : 0); /* Enable resources */ ret = i2c_of_probe_enable_res(dev, &probe_data); @@ -283,6 +423,7 @@ int i2c_of_probe_component(struct device *dev, const char *type, const struct i2 continue; /* Found a device that is responding */ + i2c_of_probe_free_gpios(&probe_data); ret = i2c_of_probe_enable_node(dev, node); break; } diff --git a/include/linux/i2c.h b/include/linux/i2c.h index dbcdb8edbf6f..0da1edddb5a2 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -1037,9 +1037,11 @@ int of_i2c_get_board_info(struct device *dev, struct device_node *node, /** * i2c_of_probe_opts - I2C OF component prober customization options * @post_power_on_delay_us: Delay in ms after regulators are powered on. Passed to msleep(). + * @post_reset_deassert_delay_ms: Delay in ms after GPIOs are set. Passed to msleep(). */ struct i2c_of_probe_opts { unsigned int post_power_on_delay_ms; + unsigned int post_reset_deassert_delay_ms; }; int i2c_of_probe_component(struct device *dev, const char *type, const struct i2c_of_probe_opts *opts); From patchwork Wed Sep 4 09:00:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chen-Yu Tsai X-Patchwork-Id: 825400 Received: from mail-pf1-f180.google.com (mail-pf1-f180.google.com [209.85.210.180]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 78E301D049A for ; Wed, 4 Sep 2024 09:01:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725440469; cv=none; b=GgB4tQr1xunhJIEbdj1dWlxihHFe9AfRLCe+4/EZfytdzA2LFYjQCYSQQnEHLQNURqcFUyX3c4wr8flFMhe3uqtzquR8KuZ3Dun24wE1acz16DIwizcSNz2Rgz9Uab4CxlppKYvQk802OJAk4oqzYX4OX/Mqq+2xe/wQeFZfsL0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725440469; c=relaxed/simple; bh=TETkVZ+20vH6yp0NjKmhwjdtI4t+kdGs8b4C7PTUYyA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mneRjjtgyHqBinfk90Q+8k476PBwb02S6G9T0P1NuzMEzEBdDOKpdSDp1NsshwNxR4m14pA96teBr9m93EbjKypAwSlusLLJrLdukl8JuGbcV7ibdVtKem2Cz1EvjLoc5SS3qXBgp6R82+WMVYiymVQuTkOIZYsK8l8vPYQMSgY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=TgZu5xSF; arc=none smtp.client-ip=209.85.210.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="TgZu5xSF" Received: by mail-pf1-f180.google.com with SMTP id d2e1a72fcca58-71781f42f75so91284b3a.1 for ; Wed, 04 Sep 2024 02:01:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1725440467; x=1726045267; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=uBItDi4n14IYuM9iuwfGhl3IjynLmMqAt1J2tlAZIYM=; b=TgZu5xSFoaaEDs2wdJ0y9EDpKJDt6H7iAIl0bLwVn+HDI4FD4eRvZpj3yaYNfw4vh4 XW9OMs9BzgnAy3g4SRPho3gKJejgrxdct+E9FcMnwhW3P48ZWHAmRIwHaNcDI79MNLrd ngmCYaLoonK3CPzp7aSVzu+Us6FaAwVwOZYCI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725440467; x=1726045267; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=uBItDi4n14IYuM9iuwfGhl3IjynLmMqAt1J2tlAZIYM=; b=iL4uzpfr6cUhxpuU1eRkUyAz0cmp/EWy8YqTVeTj8wgNcEuVtg/X0FvSMCLRju+kMW jx4mkiMFM4fB1LEawpELTddd81hLk5Ekl15RXlfW7zDf3+DvWJCH/ZaVcZAj4oFhFiq4 yvNv3GZugKnAlgS9pBjcY+VCOVfbiwzvsAZU9mJPBV2XKpHtPzJCr37ggHDMUYc6/1hB w9fk5AEZRlrHQlVCT/D6rStoPNHX4j5Uq1p0gz6CohlMwaHfKULAMXrnpO3Mx4qsFdCF munT8TvvkTchUGY2CQ//ChcqiLKwLEQ20GteiHgiT0xn0dqoTeaKL+vtpL6YqoIKRUBK QK2g== X-Forwarded-Encrypted: i=1; AJvYcCVPX655vGpBhBPt+Jc2M3pw12JmJlYnzKcPpBfvpW1Y7i0EU9S/CMXSUEMQxF/9Ox93wplBLA5vloA=@vger.kernel.org X-Gm-Message-State: AOJu0YyL9J3H2Z8Dg8TtDezyItR0U2EA6qZxB6gewq9JS6y7mz0tBtZj NU+p/ViCiEMl/3tCgPo2npXGh7S+OrPMxJNLRWuErEyRpC8DfCZLk8uEun//jw== X-Google-Smtp-Source: AGHT+IH2qucxlwAjWUMwLjsKdIgEfhg67bYq6GG+aNowoHtwaNabhMzLvVoNZUyf17AzUzRmQ7DIlg== X-Received: by 2002:a05:6a00:9282:b0:704:2563:5079 with SMTP id d2e1a72fcca58-7173d0069b0mr16668781b3a.27.1725440466605; Wed, 04 Sep 2024 02:01:06 -0700 (PDT) Received: from wenstp920.tpe.corp.google.com ([2401:fa00:1:10:83fc:5c8e:13bd:d165]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-717785b5183sm1153279b3a.197.2024.09.04.02.01.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Sep 2024 02:01:06 -0700 (PDT) From: Chen-Yu Tsai To: Rob Herring , Saravana Kannan , Matthias Brugger , AngeloGioacchino Del Regno , Wolfram Sang , Benson Leung , Tzung-Bi Shih , Mark Brown , Liam Girdwood Cc: Chen-Yu Tsai , chrome-platform@lists.linux.dev, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-kernel@vger.kernel.org, Douglas Anderson , Johan Hovold , Jiri Kosina , Andy Shevchenko , linux-i2c@vger.kernel.org Subject: [PATCH v6 12/12] arm64: dts: mediatek: mt8173-elm-hana: Mark touchscreens and trackpads as fail Date: Wed, 4 Sep 2024 17:00:14 +0800 Message-ID: <20240904090016.2841572-13-wenst@chromium.org> X-Mailer: git-send-email 2.46.0.469.g59c65b2a67-goog In-Reply-To: <20240904090016.2841572-1-wenst@chromium.org> References: <20240904090016.2841572-1-wenst@chromium.org> Precedence: bulk X-Mailing-List: linux-i2c@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Instead of having them all available, mark them all as "fail-needs-probe" and have the implementation try to probe which one is present. Also remove the shared resource workaround by moving the pinctrl entry for the trackpad interrupt line back into the individual trackpad nodes. Signed-off-by: Chen-Yu Tsai --- Changes since v4: - Rebased Changes since v3: - Also remove second source workaround, i.e. move the interrupt line pinctrl entry from the i2c node back to the components. Changes since v2: - Drop class from status --- arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi | 13 +++++++++++++ arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi | 4 ++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi index 8d1cbc92bce3..251e084bf7de 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi @@ -14,6 +14,7 @@ touchscreen2: touchscreen@34 { compatible = "melfas,mip4_ts"; reg = <0x34>; interrupts-extended = <&pio 88 IRQ_TYPE_LEVEL_LOW>; + status = "fail-needs-probe"; }; /* @@ -26,6 +27,7 @@ touchscreen3: touchscreen@20 { reg = <0x20>; hid-descr-addr = <0x0020>; interrupts-extended = <&pio 88 IRQ_TYPE_LEVEL_LOW>; + status = "fail-needs-probe"; }; /* Lenovo Ideapad C330 uses G2Touch touchscreen as a 2nd source touchscreen */ @@ -47,9 +49,12 @@ &i2c4 { trackpad2: trackpad@2c { compatible = "hid-over-i2c"; interrupts-extended = <&pio 117 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&trackpad_irq>; reg = <0x2c>; hid-descr-addr = <0x0020>; wakeup-source; + status = "fail-needs-probe"; }; }; @@ -74,3 +79,11 @@ pins_wp { }; }; }; + +&touchscreen { + status = "fail-needs-probe"; +}; + +&trackpad { + status = "fail-needs-probe"; +}; diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi index b4d85147b77b..eee64461421f 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi @@ -358,12 +358,12 @@ touchscreen: touchscreen@10 { &i2c4 { clock-frequency = <400000>; status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&trackpad_irq>; trackpad: trackpad@15 { compatible = "elan,ekth3000"; interrupts-extended = <&pio 117 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&trackpad_irq>; reg = <0x15>; vcc-supply = <&mt6397_vgp6_reg>; wakeup-source;