Message ID | 20230221133307.20287-3-andriy.shevchenko@linux.intel.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:5915:0:0:0:0:0 with SMTP id v21csp12433wrd; Tue, 21 Feb 2023 05:38:25 -0800 (PST) X-Google-Smtp-Source: AK7set85AkzqX3R3fBIkgKkOUCsqjH7K833WsBcDeISL0sXiWwdlRf4wWpw5cdkEFI/gQUtWIndA X-Received: by 2002:a17:90b:4b0f:b0:230:f96d:4bcc with SMTP id lx15-20020a17090b4b0f00b00230f96d4bccmr7039808pjb.39.1676986705582; Tue, 21 Feb 2023 05:38:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1676986705; cv=none; d=google.com; s=arc-20160816; b=QF1rxBN8vBYV9x+11vLF6nGrZZUI+hwjRggovAGt0ty4jKS7EjLEmhegybritSi1SB l8cs7VS1xjFMOu2imrtZM8UrFaLSaiuOGaGpOoch1tTyysAHpWjvCFub1bEHLrf2WsH2 Nd9UeRtfskc2B//3Sn007tEAr6h3kRRrl570CpCDHIdIOZgw6zbfQR+lpDyYvwzLkrGU 6msDTf/iz2VAyOvfQJm/Re0KQfwwVKnP6dk25dxDWGK3vow4tVhQYpJgT5R8wXHUzlwn 0xPz/RIqMQyYcipggf6ql+DcjA8IaXFyW6cc1TJVXE4AB2vMjuqC8EtPHdMGyuIa32qM 7RlQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=7pKABacFTvbdiyNrDGUS44/7Dt/SYilxldUv+Q6RI7c=; b=Mlj0WrOuh7FtuXIhBJn7YC8lDTZv+S1jkSUXi9bwhn9BG1NJR8xeRZh2TODRtBGVcT JpKLIKfHjgQW2LmB+GfX2VuHbBeH9a2zcWhKEYLz389Bx7XnBYPs3rVcox+e5zKWk4uj pjsKh2PmRVqX7wbMXMnxRrCSmRI+bC/DPxL8EGYgMA/SAZbXHS/P8rNAwIpVS7QlfDqd RDrmnIVx68juZeXghLU7tJZfVSajNHfKdv3SyUKVgI+3MThhFbghRmLz4N3ToPItFDD7 ngIm1ajlWXJy5t+Y+GNOy3nIQxEAWH72117FejlT2L4lgM4RbTM2+GjuWEdIcvDBTKuy 3dJg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=TrU6pYmM; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id p12-20020a17090ad30c00b00230c06399e8si3580251pju.89.2023.02.21.05.38.12; Tue, 21 Feb 2023 05:38:25 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=TrU6pYmM; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234100AbjBUNcp (ORCPT <rfc822;kloczko.tomasz@gmail.com> + 99 others); Tue, 21 Feb 2023 08:32:45 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49374 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233863AbjBUNck (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Tue, 21 Feb 2023 08:32:40 -0500 Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8307A29146; Tue, 21 Feb 2023 05:32:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1676986353; x=1708522353; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=gAs7mmCUMTX3mc/WGDDKZyUzsOVaQDT07IZYG1MzAGI=; b=TrU6pYmM8FfBW2VuPud+pk/QZsysvTks1MJpl1Oy/Ll+pswcJy7z9tzR R+W2tbLyV0bIuZzEIRvASrYbnCYpjJtTnZEsaj6GZXLat7YnZQrQLXwl0 a1H1+JHJuWIxsBTEC0wKra0nZbwEZTUxdN4msVXgJxZLrMMHIWv0iL2g4 Fc0bZCjarZQpJ9aVUREkkqeUNxdYTGIV1qgYlafdmPxKfXnbdXE2kXD1S 25UGhWPP0HZbQTxpd2xxoG0QFDokvLrF+k2TySZoIkdRxoNRcpNyb6YCP 5GOgc9uGcQf+WbEs7789JgwOMzU4WqZno6hngGLmtB4WqHgrRUc6DLxKS w==; X-IronPort-AV: E=McAfee;i="6500,9779,10627"; a="360101507" X-IronPort-AV: E=Sophos;i="5.97,315,1669104000"; d="scan'208";a="360101507" Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Feb 2023 05:32:33 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10627"; a="671656027" X-IronPort-AV: E=Sophos;i="5.97,315,1669104000"; d="scan'208";a="671656027" Received: from black.fi.intel.com ([10.237.72.28]) by orsmga002.jf.intel.com with ESMTP; 21 Feb 2023 05:32:29 -0800 Received: by black.fi.intel.com (Postfix, from userid 1003) id EBD06367; Tue, 21 Feb 2023 15:33:09 +0200 (EET) From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> To: Andy Shevchenko <andriy.shevchenko@linux.intel.com>, "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>, Raul E Rangel <rrangel@chromium.org>, Wolfram Sang <wsa@kernel.org>, linux-kernel@vger.kernel.org, linux-i2c@vger.kernel.org, linux-usb@vger.kernel.org Cc: Robin van der Gracht <robin@protonic.nl>, Miguel Ojeda <ojeda@kernel.org>, Heikki Krogerus <heikki.krogerus@linux.intel.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org> Subject: [PATCH v1 2/3] auxdisplay: ht16k33: Make use of device_get_match_data() Date: Tue, 21 Feb 2023 15:33:06 +0200 Message-Id: <20230221133307.20287-3-andriy.shevchenko@linux.intel.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230221133307.20287-1-andriy.shevchenko@linux.intel.com> References: <20230221133307.20287-1-andriy.shevchenko@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-4.3 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_EF,RCVD_IN_DNSWL_MED, RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1758448011660906001?= X-GMAIL-MSGID: =?utf-8?q?1758448011660906001?= |
Series |
i2c: stop using i2c_of_match_device()
|
|
Commit Message
Andy Shevchenko
Feb. 21, 2023, 1:33 p.m. UTC
Switching to use device_get_match_data() helps getting of
i2c_of_match_device() API.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
drivers/auxdisplay/ht16k33.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
Comments
On Tue, Feb 21, 2023 at 03:33:06PM +0200, Andy Shevchenko wrote: > Switching to use device_get_match_data() helps getting of > i2c_of_match_device() API. ... > - id = i2c_of_match_device(dev->driver->of_match_table, client); > - if (id) > - priv->type = (uintptr_t)id->data; > + priv->type = (uintptr_t)device_get_match_data(dev); Looking closer the I²C ID table should provide DISP_MATRIX to keep default and this needs to be not dropped. So, the question is what to do with unknown type then, return -EINVAL from probe()? P.S. I would like to collect other comments anyway, so I will send a v2 later.
Hello Andy, On 2023-02-21 14:40, Andy Shevchenko wrote: > On Tue, Feb 21, 2023 at 03:33:06PM +0200, Andy Shevchenko wrote: >> Switching to use device_get_match_data() helps getting of >> i2c_of_match_device() API. > > ... > >> - id = i2c_of_match_device(dev->driver->of_match_table, client); >> - if (id) >> - priv->type = (uintptr_t)id->data; >> + priv->type = (uintptr_t)device_get_match_data(dev); > > Looking closer the I²C ID table should provide DISP_MATRIX to keep > default and > this needs to be not dropped. > > So, the question is what to do with unknown type then, return -EINVAL > from > probe()? If you leave out your addition of the DISP_UNKNOWN type, the default type will be DISP_MATRIX if no match is found, which is as it is now. In that case the following change should suffice: @@ -713,7 +715,6 @@ static int ht16k33_seg_probe(struct device *dev, struct ht16k33_priv *priv, static int ht16k33_probe(struct i2c_client *client) { struct device *dev = &client->dev; - const struct of_device_id *id; struct ht16k33_priv *priv; uint32_t dft_brightness; int err; @@ -728,9 +729,8 @@ static int ht16k33_probe(struct i2c_client *client) return -ENOMEM; priv->client = client; - id = i2c_of_match_device(dev->driver->of_match_table, client); - if (id) - priv->type = (uintptr_t)id->data; + priv->type = (uintptr_t)device_get_match_data(dev); + i2c_set_clientdata(client, priv); err = ht16k33_initialize(priv); Or do you think falling back to DISP_MATRIX if no match is found is wrong? Kind regards, Robin
On Tue, Feb 21, 2023 at 05:10:00PM +0100, Robin van der Gracht wrote: > On 2023-02-21 14:40, Andy Shevchenko wrote: > > On Tue, Feb 21, 2023 at 03:33:06PM +0200, Andy Shevchenko wrote: > > > Switching to use device_get_match_data() helps getting of > > > i2c_of_match_device() API. ... > > > - id = i2c_of_match_device(dev->driver->of_match_table, client); > > > - if (id) > > > - priv->type = (uintptr_t)id->data; > > > + priv->type = (uintptr_t)device_get_match_data(dev); > > > > Looking closer the I²C ID table should provide DISP_MATRIX to keep > > default and this needs to be not dropped. > > > > So, the question is what to do with unknown type then, return -EINVAL > > from probe()? > > If you leave out your addition of the DISP_UNKNOWN type, the default type > will be DISP_MATRIX if no match is found, which is as it is now. > > In that case the following change should suffice: > > @@ -713,7 +715,6 @@ static int ht16k33_seg_probe(struct device *dev, struct > ht16k33_priv *priv, > static int ht16k33_probe(struct i2c_client *client) > { > struct device *dev = &client->dev; > - const struct of_device_id *id; > struct ht16k33_priv *priv; > uint32_t dft_brightness; > int err; > @@ -728,9 +729,8 @@ static int ht16k33_probe(struct i2c_client *client) > return -ENOMEM; > > priv->client = client; > - id = i2c_of_match_device(dev->driver->of_match_table, client); > - if (id) > - priv->type = (uintptr_t)id->data; > + priv->type = (uintptr_t)device_get_match_data(dev); > + > i2c_set_clientdata(client, priv); > > err = ht16k33_initialize(priv); > > Or do you think falling back to DISP_MATRIX if no match is found is wrong? First of all, the I²C ID table should actually use DISP_MATRIX. Second, there are two points: - It would be nice to check if the OF ID table doesn't provide a setting (shouldn't we try I²C ID table and then, if still nothing, bail out?) - The I²C ID table can be extended in the future with another entry which may want to have different default
On 2023-02-21 18:48, Andy Shevchenko wrote: > On Tue, Feb 21, 2023 at 05:10:00PM +0100, Robin van der Gracht wrote: >> On 2023-02-21 14:40, Andy Shevchenko wrote: >> > On Tue, Feb 21, 2023 at 03:33:06PM +0200, Andy Shevchenko wrote: >> > > Switching to use device_get_match_data() helps getting of >> > > i2c_of_match_device() API. > > ... > >> > > - id = i2c_of_match_device(dev->driver->of_match_table, client); >> > > - if (id) >> > > - priv->type = (uintptr_t)id->data; >> > > + priv->type = (uintptr_t)device_get_match_data(dev); >> > >> > Looking closer the I²C ID table should provide DISP_MATRIX to keep >> > default and this needs to be not dropped. >> > >> > So, the question is what to do with unknown type then, return -EINVAL >> > from probe()? >> >> If you leave out your addition of the DISP_UNKNOWN type, the default >> type >> will be DISP_MATRIX if no match is found, which is as it is now. >> >> In that case the following change should suffice: >> >> @@ -713,7 +715,6 @@ static int ht16k33_seg_probe(struct device *dev, >> struct >> ht16k33_priv *priv, >> static int ht16k33_probe(struct i2c_client *client) >> { >> struct device *dev = &client->dev; >> - const struct of_device_id *id; >> struct ht16k33_priv *priv; >> uint32_t dft_brightness; >> int err; >> @@ -728,9 +729,8 @@ static int ht16k33_probe(struct i2c_client >> *client) >> return -ENOMEM; >> >> priv->client = client; >> - id = i2c_of_match_device(dev->driver->of_match_table, client); >> - if (id) >> - priv->type = (uintptr_t)id->data; >> + priv->type = (uintptr_t)device_get_match_data(dev); >> + >> i2c_set_clientdata(client, priv); >> >> err = ht16k33_initialize(priv); >> >> Or do you think falling back to DISP_MATRIX if no match is found is >> wrong? > > First of all, the I²C ID table should actually use DISP_MATRIX. > > Second, there are two points: > > - It would be nice to check if the OF ID table doesn't provide a > setting > (shouldn't we try I²C ID table and then, if still nothing, bail out?) > > - The I²C ID table can be extended in the future with another entry > which > may want to have different default For my understanding, please correct me if I'm wrong; For all methods of instantiation during ht16k33 probe, i2c_of_match_device() matches the compatible strings in the OF ID table due to a call to i2c_of_match_device_sysfs(). device_get_match_data() only matches the compatible strings in the OF ID table for devicetree instantiation because of_match_device() won't match is there is no actual of_node. So with only device_get_match_data() and a non devicetree instantiation, priv->type will always be (uintptr_t)NULL = 0 = DISP_MATRIX. Which effectively breaks i.e. user-space instantiation for other display types which now do work due to i2c_of_match_device(). (so my suggestion above is not sufficient). Are you proposing extending and searching the I2C ID table to work around that? Kind regards,
On Wed, Feb 22, 2023 at 05:46:00PM +0100, Robin van der Gracht wrote: > On 2023-02-21 18:48, Andy Shevchenko wrote: > > On Tue, Feb 21, 2023 at 05:10:00PM +0100, Robin van der Gracht wrote: > > > On 2023-02-21 14:40, Andy Shevchenko wrote: > > > > On Tue, Feb 21, 2023 at 03:33:06PM +0200, Andy Shevchenko wrote: ... > > > > > - id = i2c_of_match_device(dev->driver->of_match_table, client); > > > > > - if (id) > > > > > - priv->type = (uintptr_t)id->data; > > > > > + priv->type = (uintptr_t)device_get_match_data(dev); > > > > > > > > Looking closer the I²C ID table should provide DISP_MATRIX to keep > > > > default and > > > > this needs to be not dropped. ^^^^^ (1) > > > > So, the question is what to do with unknown type then, return -EINVAL > > > > from probe()? > > > > > > If you leave out your addition of the DISP_UNKNOWN type, the default > > > type > > > will be DISP_MATRIX if no match is found, which is as it is now. > > > > > > In that case the following change should suffice: > > > > > > @@ -713,7 +715,6 @@ static int ht16k33_seg_probe(struct device *dev, > > > struct > > > ht16k33_priv *priv, > > > static int ht16k33_probe(struct i2c_client *client) > > > { > > > struct device *dev = &client->dev; > > > - const struct of_device_id *id; > > > struct ht16k33_priv *priv; > > > uint32_t dft_brightness; > > > int err; > > > @@ -728,9 +729,8 @@ static int ht16k33_probe(struct i2c_client > > > *client) > > > return -ENOMEM; > > > > > > priv->client = client; > > > - id = i2c_of_match_device(dev->driver->of_match_table, client); > > > - if (id) > > > - priv->type = (uintptr_t)id->data; > > > + priv->type = (uintptr_t)device_get_match_data(dev); > > > + > > > i2c_set_clientdata(client, priv); > > > > > > err = ht16k33_initialize(priv); > > > > > > Or do you think falling back to DISP_MATRIX if no match is found is > > > wrong? > > > > First of all, the I²C ID table should actually use DISP_MATRIX. > > > > Second, there are two points: > > > > - It would be nice to check if the OF ID table doesn't provide a setting > > (shouldn't we try I²C ID table and then, if still nothing, bail out?) > > > > - The I²C ID table can be extended in the future with another entry > > which > > may want to have different default > > For my understanding, please correct me if I'm wrong; > > For all methods of instantiation during ht16k33 probe, i2c_of_match_device() > matches the compatible strings in the OF ID table due to a call to > i2c_of_match_device_sysfs(). > > device_get_match_data() only matches the compatible strings in the OF ID > table for devicetree instantiation because of_match_device() won't match > is there is no actual of_node. That's half-true. On ACPI based platforms we may have no of_node and match against OF ID table. > So with only device_get_match_data() and a non devicetree instantiation, > priv->type will always be (uintptr_t)NULL = 0 = DISP_MATRIX. Yes. > Which effectively breaks i.e. user-space instantiation for other display > types which now do work due to i2c_of_match_device(). > (so my suggestion above is not sufficient). > > Are you proposing extending and searching the I2C ID table to work around > that? See (1) above. This is the downside I have noticed after sending this series. So, the I²C ID table match has to be restored, but the above mentioned issues with existing table are not gone, hence they need to be addressed in the next version.
+ Cc: OF bindings people for the mess with the IDs. On Wed, Feb 22, 2023 at 07:01:40PM +0200, Andy Shevchenko wrote: > On Wed, Feb 22, 2023 at 05:46:00PM +0100, Robin van der Gracht wrote: > > On 2023-02-21 18:48, Andy Shevchenko wrote: > > > On Tue, Feb 21, 2023 at 05:10:00PM +0100, Robin van der Gracht wrote: > > > > On 2023-02-21 14:40, Andy Shevchenko wrote: > > > > > On Tue, Feb 21, 2023 at 03:33:06PM +0200, Andy Shevchenko wrote: ... > > > > > > - id = i2c_of_match_device(dev->driver->of_match_table, client); > > > > > > - if (id) > > > > > > - priv->type = (uintptr_t)id->data; > > > > > > + priv->type = (uintptr_t)device_get_match_data(dev); > > > > > > > > > > Looking closer the I²C ID table should provide DISP_MATRIX to keep > > > > > default and > > > > > > this needs to be not dropped. > > ^^^^^ (1) > > > > > > So, the question is what to do with unknown type then, return -EINVAL > > > > > from probe()? > > > > > > > > If you leave out your addition of the DISP_UNKNOWN type, the default > > > > type > > > > will be DISP_MATRIX if no match is found, which is as it is now. > > > > > > > > In that case the following change should suffice: > > > > > > > > @@ -713,7 +715,6 @@ static int ht16k33_seg_probe(struct device *dev, > > > > struct > > > > ht16k33_priv *priv, > > > > static int ht16k33_probe(struct i2c_client *client) > > > > { > > > > struct device *dev = &client->dev; > > > > - const struct of_device_id *id; > > > > struct ht16k33_priv *priv; > > > > uint32_t dft_brightness; > > > > int err; > > > > @@ -728,9 +729,8 @@ static int ht16k33_probe(struct i2c_client > > > > *client) > > > > return -ENOMEM; > > > > > > > > priv->client = client; > > > > - id = i2c_of_match_device(dev->driver->of_match_table, client); > > > > - if (id) > > > > - priv->type = (uintptr_t)id->data; > > > > + priv->type = (uintptr_t)device_get_match_data(dev); > > > > + > > > > i2c_set_clientdata(client, priv); > > > > > > > > err = ht16k33_initialize(priv); > > > > > > > > Or do you think falling back to DISP_MATRIX if no match is found is > > > > wrong? > > > > > > First of all, the I²C ID table should actually use DISP_MATRIX. > > > > > > Second, there are two points: > > > > > > - It would be nice to check if the OF ID table doesn't provide a setting > > > (shouldn't we try I²C ID table and then, if still nothing, bail out?) > > > > > > - The I²C ID table can be extended in the future with another entry > > > which > > > may want to have different default > > > > For my understanding, please correct me if I'm wrong; > > > > For all methods of instantiation during ht16k33 probe, i2c_of_match_device() > > matches the compatible strings in the OF ID table due to a call to > > i2c_of_match_device_sysfs(). > > > > device_get_match_data() only matches the compatible strings in the OF ID > > table for devicetree instantiation because of_match_device() won't match > > is there is no actual of_node. > > That's half-true. On ACPI based platforms we may have no of_node and match > against OF ID table. > > > So with only device_get_match_data() and a non devicetree instantiation, > > priv->type will always be (uintptr_t)NULL = 0 = DISP_MATRIX. > > Yes. > > > Which effectively breaks i.e. user-space instantiation for other display > > types which now do work due to i2c_of_match_device(). > > (so my suggestion above is not sufficient). > > > > Are you proposing extending and searching the I2C ID table to work around > > that? > > See (1) above. This is the downside I have noticed after sending this series. > So, the I²C ID table match has to be restored, but the above mentioned issues > with existing table are not gone, hence they need to be addressed in the next > version. I see now what you mean. So, we have even more issues in this driver: - I²C table is not in sync with all devices supported - the OF ID table seems has something really badly formed for adafruit (just a number after a comma) The latter shows how broken it is. The I²C ID table mechanism is used as a backward compatibility to the OF. Unfortunately, user space may not provide the data except in form of DT overlays, so for the legacy enumeration we have only device name, which is a set of 4 digits for adafruit case. Now imagine if by some reason we will get adafruit2 (you name it) with the same schema. How I²C framework can understand that you meant adafruit and not adafruit2? Or did I miss something?
On 22/02/2023 18:20, Andy Shevchenko wrote: >> >>> Which effectively breaks i.e. user-space instantiation for other display >>> types which now do work due to i2c_of_match_device(). >>> (so my suggestion above is not sufficient). >>> >>> Are you proposing extending and searching the I2C ID table to work around >>> that? >> >> See (1) above. This is the downside I have noticed after sending this series. >> So, the I²C ID table match has to be restored, but the above mentioned issues >> with existing table are not gone, hence they need to be addressed in the next >> version. > > I see now what you mean. So, we have even more issues in this driver: > - I²C table is not in sync with all devices supported Does anything actually rely on i2c_device_id table? ACPI would match either via ACPI or OF tables. All modern ARM systems (e.g. imx6) are DT-based. Maybe just drop the I2C ID table? > - the OF ID table seems has something really badly formed for adafruit > (just a number after a comma) Maybe it is a model number? It was documented: Documentation/devicetree/bindings/auxdisplay/holtek,ht16k33.yaml > > The latter shows how broken it is. The I²C ID table mechanism is used as > a backward compatibility to the OF. Unfortunately, user space may not provide > the data except in form of DT overlays, so for the legacy enumeration we > have only device name, which is a set of 4 digits for adafruit case. > > Now imagine if by some reason we will get adafruit2 (you name it) with > the same schema. How I²C framework can understand that you meant adafruit > and not adafruit2? Or did I miss something? > Best regards, Krzysztof
On Wed, Feb 22, 2023 at 07:46:25PM +0100, Krzysztof Kozlowski wrote: > On 22/02/2023 18:20, Andy Shevchenko wrote: > >> > >>> Which effectively breaks i.e. user-space instantiation for other display > >>> types which now do work due to i2c_of_match_device(). > >>> (so my suggestion above is not sufficient). > >>> > >>> Are you proposing extending and searching the I2C ID table to work around > >>> that? > >> > >> See (1) above. This is the downside I have noticed after sending this series. > >> So, the I²C ID table match has to be restored, but the above mentioned issues > >> with existing table are not gone, hence they need to be addressed in the next > >> version. > > > > I see now what you mean. So, we have even more issues in this driver: > > - I²C table is not in sync with all devices supported > > Does anything actually rely on i2c_device_id table? ACPI would match > either via ACPI or OF tables. All modern ARM systems (e.g. imx6) are > DT-based. Maybe just drop the I2C ID table? For I²C it's still possible to enumerate the device via sysfs, which is ABI. > > - the OF ID table seems has something really badly formed for adafruit > > (just a number after a comma) > > Maybe it is a model number? It was documented: > Documentation/devicetree/bindings/auxdisplay/holtek,ht16k33.yaml Yes, it's not a problem for ACPI/DT platforms, the problem is for the above way of enumeration, so if we have more than 1 manufacturer that uses plain numbers for the model, I²C framework may not distinguish which driver to use. I.o.w. the part after comma in the compatible strings of the I²C devices must be unique globally to make that enumeration disambiguous. > > The latter shows how broken it is. The I²C ID table mechanism is used as > > a backward compatibility to the OF. Unfortunately, user space may not provide > > the data except in form of DT overlays, so for the legacy enumeration we > > have only device name, which is a set of 4 digits for adafruit case. > > > > Now imagine if by some reason we will get adafruit2 (you name it) with > > the same schema. How I²C framework can understand that you meant adafruit > > and not adafruit2? Or did I miss something?
On 2023-02-22 18:20, Andy Shevchenko wrote: > + Cc: OF bindings people for the mess with the IDs. > > On Wed, Feb 22, 2023 at 07:01:40PM +0200, Andy Shevchenko wrote: >> On Wed, Feb 22, 2023 at 05:46:00PM +0100, Robin van der Gracht wrote: >> > On 2023-02-21 18:48, Andy Shevchenko wrote: >> > > On Tue, Feb 21, 2023 at 05:10:00PM +0100, Robin van der Gracht wrote: >> > > > On 2023-02-21 14:40, Andy Shevchenko wrote: >> > > > > On Tue, Feb 21, 2023 at 03:33:06PM +0200, Andy Shevchenko wrote: > > ... > >> > > > > > - id = i2c_of_match_device(dev->driver->of_match_table, client); >> > > > > > - if (id) >> > > > > > - priv->type = (uintptr_t)id->data; >> > > > > > + priv->type = (uintptr_t)device_get_match_data(dev); >> > > > > >> > > > > Looking closer the I²C ID table should provide DISP_MATRIX to keep >> > > > > default and >> >> > > > > this needs to be not dropped. >> >> ^^^^^ (1) >> >> > > > > So, the question is what to do with unknown type then, return -EINVAL >> > > > > from probe()? >> > > > >> > > > If you leave out your addition of the DISP_UNKNOWN type, the default >> > > > type >> > > > will be DISP_MATRIX if no match is found, which is as it is now. >> > > > >> > > > In that case the following change should suffice: >> > > > >> > > > @@ -713,7 +715,6 @@ static int ht16k33_seg_probe(struct device *dev, >> > > > struct >> > > > ht16k33_priv *priv, >> > > > static int ht16k33_probe(struct i2c_client *client) >> > > > { >> > > > struct device *dev = &client->dev; >> > > > - const struct of_device_id *id; >> > > > struct ht16k33_priv *priv; >> > > > uint32_t dft_brightness; >> > > > int err; >> > > > @@ -728,9 +729,8 @@ static int ht16k33_probe(struct i2c_client >> > > > *client) >> > > > return -ENOMEM; >> > > > >> > > > priv->client = client; >> > > > - id = i2c_of_match_device(dev->driver->of_match_table, client); >> > > > - if (id) >> > > > - priv->type = (uintptr_t)id->data; >> > > > + priv->type = (uintptr_t)device_get_match_data(dev); >> > > > + >> > > > i2c_set_clientdata(client, priv); >> > > > >> > > > err = ht16k33_initialize(priv); >> > > > >> > > > Or do you think falling back to DISP_MATRIX if no match is found is >> > > > wrong? >> > > >> > > First of all, the I²C ID table should actually use DISP_MATRIX. >> > > >> > > Second, there are two points: >> > > >> > > - It would be nice to check if the OF ID table doesn't provide a setting >> > > (shouldn't we try I²C ID table and then, if still nothing, bail out?) >> > > >> > > - The I²C ID table can be extended in the future with another entry >> > > which >> > > may want to have different default >> > >> > For my understanding, please correct me if I'm wrong; >> > >> > For all methods of instantiation during ht16k33 probe, i2c_of_match_device() >> > matches the compatible strings in the OF ID table due to a call to >> > i2c_of_match_device_sysfs(). >> > >> > device_get_match_data() only matches the compatible strings in the OF ID >> > table for devicetree instantiation because of_match_device() won't match >> > is there is no actual of_node. >> >> That's half-true. On ACPI based platforms we may have no of_node and >> match >> against OF ID table. >> >> > So with only device_get_match_data() and a non devicetree instantiation, >> > priv->type will always be (uintptr_t)NULL = 0 = DISP_MATRIX. >> >> Yes. >> >> > Which effectively breaks i.e. user-space instantiation for other display >> > types which now do work due to i2c_of_match_device(). >> > (so my suggestion above is not sufficient). >> > >> > Are you proposing extending and searching the I2C ID table to work around >> > that? >> >> See (1) above. This is the downside I have noticed after sending this >> series. >> So, the I²C ID table match has to be restored, but the above mentioned >> issues >> with existing table are not gone, hence they need to be addressed in >> the next >> version. > > I see now what you mean. So, we have even more issues in this driver: > - I²C table is not in sync with all devices supported > - the OF ID table seems has something really badly formed for adafruit > (just a number after a comma) > > The latter shows how broken it is. The I²C ID table mechanism is used > as > a backward compatibility to the OF. Unfortunately, user space may not > provide > the data except in form of DT overlays, so for the legacy enumeration > we > have only device name, which is a set of 4 digits for adafruit case. > > Now imagine if by some reason we will get adafruit2 (you name it) with > the same schema. How I²C framework can understand that you meant > adafruit > and not adafruit2? Or did I miss something? I agree. I've added Geert Uytterhoeven to the CC. He added support for the adafruit segment displays. Maybe he has a comment on this. Kind regards, Robin van der Gracht
Hi Andy, On Wed, Feb 22, 2023 at 8:21 PM Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote: > On Wed, Feb 22, 2023 at 07:46:25PM +0100, Krzysztof Kozlowski wrote: > > On 22/02/2023 18:20, Andy Shevchenko wrote: > > >>> Which effectively breaks i.e. user-space instantiation for other display > > >>> types which now do work due to i2c_of_match_device(). > > >>> (so my suggestion above is not sufficient). > > >>> > > >>> Are you proposing extending and searching the I2C ID table to work around > > >>> that? > > >> > > >> See (1) above. This is the downside I have noticed after sending this series. > > >> So, the I²C ID table match has to be restored, but the above mentioned issues > > >> with existing table are not gone, hence they need to be addressed in the next > > >> version. > > > > > > I see now what you mean. So, we have even more issues in this driver: > > > - I²C table is not in sync with all devices supported > > > > Does anything actually rely on i2c_device_id table? ACPI would match > > either via ACPI or OF tables. All modern ARM systems (e.g. imx6) are > > DT-based. Maybe just drop the I2C ID table? > > For I²C it's still possible to enumerate the device via sysfs, which is ABI. Yes, and AFAIK, that worked fine. E.g. echo adafruit,3130 0x70 > /sys/class/i2c/i2c-adapter/.../new_device Cfr. https://lore.kernel.org/all/20211019144520.3613926-3-geert@linux-m68k.org/ Note that that example actually includes the manufacturer. I didn't check whether the I2C core takes that part into account when matching, or just strips it. > > > - the OF ID table seems has something really badly formed for adafruit > > > (just a number after a comma) > > > > Maybe it is a model number? It was documented: > > Documentation/devicetree/bindings/auxdisplay/holtek,ht16k33.yaml > > Yes, it's not a problem for ACPI/DT platforms, the problem is for the above > way of enumeration, so if we have more than 1 manufacturer that uses plain > numbers for the model, I²C framework may not distinguish which driver to use. > > I.o.w. the part after comma in the compatible strings of the I²C devices must > be unique globally to make that enumeration disambiguous. Which is not unique to this driver? I bet you can find other compatible values that become non-unique after stripping the manufacturer. Gr{oetje,eeting}s, Geert
On Thu, Feb 23, 2023 at 10:55:15AM +0100, Geert Uytterhoeven wrote: > On Wed, Feb 22, 2023 at 8:21 PM Andy Shevchenko > <andriy.shevchenko@linux.intel.com> wrote: > > On Wed, Feb 22, 2023 at 07:46:25PM +0100, Krzysztof Kozlowski wrote: ... > > I.o.w. the part after comma in the compatible strings of the I²C devices must > > be unique globally to make that enumeration disambiguous. > > Which is not unique to this driver? > I bet you can find other compatible values that become non-unique > after stripping the manufacturer. Yes, exactly my point. So this all schema is error prone. Hence I would not rely on it at all.
diff --git a/drivers/auxdisplay/ht16k33.c b/drivers/auxdisplay/ht16k33.c index 02425991c159..8e2fd2291ea4 100644 --- a/drivers/auxdisplay/ht16k33.c +++ b/drivers/auxdisplay/ht16k33.c @@ -60,7 +60,8 @@ #define HT16K33_FB_SIZE (HT16K33_MATRIX_LED_MAX_COLS * BYTES_PER_ROW) enum display_type { - DISP_MATRIX = 0, + DISP_UNKNOWN = 0, + DISP_MATRIX, DISP_QUAD_7SEG, DISP_QUAD_14SEG, }; @@ -675,6 +676,7 @@ static int ht16k33_seg_probe(struct device *dev, struct ht16k33_priv *priv, return err; switch (priv->type) { + default: case DISP_MATRIX: /* not handled here */ err = -EINVAL; @@ -713,7 +715,6 @@ static int ht16k33_seg_probe(struct device *dev, struct ht16k33_priv *priv, static int ht16k33_probe(struct i2c_client *client) { struct device *dev = &client->dev; - const struct of_device_id *id; struct ht16k33_priv *priv; uint32_t dft_brightness; int err; @@ -728,9 +729,8 @@ static int ht16k33_probe(struct i2c_client *client) return -ENOMEM; priv->client = client; - id = i2c_of_match_device(dev->driver->of_match_table, client); - if (id) - priv->type = (uintptr_t)id->data; + priv->type = (uintptr_t)device_get_match_data(dev); + i2c_set_clientdata(client, priv); err = ht16k33_initialize(priv); @@ -771,6 +771,9 @@ static int ht16k33_probe(struct i2c_client *client) /* Segment Display */ err = ht16k33_seg_probe(dev, priv, dft_brightness); break; + default: + /* Unknown display; enumerated via user space? */ + err = 0; } return err; } @@ -795,6 +798,8 @@ static void ht16k33_remove(struct i2c_client *client) device_remove_file(&client->dev, &dev_attr_map_seg7); device_remove_file(&client->dev, &dev_attr_map_seg14); break; + default: + break; } }