From: Hans de Goede <hdegoede@redhat.com>
To: "Pali Rohár" <pali@kernel.org>
Cc: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>,
"Andy Shevchenko" <andy@kernel.org>,
"Paul Menzel" <pmenzel@molgen.mpg.de>,
"Wolfram Sang" <wsa@kernel.org>,
eric.piel@tremplin-utc.net, "Marius Hoch" <mail@mariushoch.de>,
Dell.Client.Kernel@dell.com,
"Kai Heng Feng" <kai.heng.feng@canonical.com>,
platform-driver-x86@vger.kernel.org,
"Jean Delvare" <jdelvare@suse.com>,
"Andi Shyti" <andi.shyti@kernel.org>,
linux-i2c@vger.kernel.org
Subject: Re: [PATCH v3 3/6] platform/x86: dell-smo8800: Move instantiation of lis3lv02d i2c_client from i2c-i801 to dell-smo8800
Date: Sun, 23 Jun 2024 16:09:56 +0200 [thread overview]
Message-ID: <38fefc37-0599-4dc3-84b4-3e4d0870474c@redhat.com> (raw)
In-Reply-To: <290a60a9-53d1-4bc0-968f-76e69afd784e@redhat.com>
Hi,
On 6/23/24 3:56 PM, Hans de Goede wrote:
> Hi Pali,
>
> On 6/22/24 6:35 PM, Pali Rohár wrote:
>> On Saturday 22 June 2024 17:12:50 Pali Rohár wrote:
>>> On Saturday 22 June 2024 16:26:13 Hans de Goede wrote:
>>>> Hi Pali,
>>>>
>>>> On 6/22/24 4:20 PM, Pali Rohár wrote:
>>>>> On Saturday 22 June 2024 16:06:01 Hans de Goede wrote:
>>>>>> Hi Pali,
>>>>>>
>>>>>> On 6/22/24 3:16 PM, Pali Rohár wrote:
>>>>>>> On Friday 21 June 2024 14:24:58 Hans de Goede wrote:
>>>>>>>> It is not necessary to handle the Dell specific instantiation of
>>>>>>>> i2c_client-s for SMO88xx ACPI devices without an ACPI I2cResource
>>>>>>>> inside the generic i801 I2C adapter driver.
>>>>>>>>
>>>>>>>> The kernel already instantiates platform_device-s for these ACPI devices
>>>>>>>> and the drivers/platform/x86/dell/dell-smo8800.c driver binds to these
>>>>>>>> platform drivers.
>>>>>>>>
>>>>>>>> Move the i2c_client instantiation from the generic i2c-i801 driver to
>>>>>>>> the SMO88xx specific dell-smo8800 driver.
>>>>>>>
>>>>>>> Why it has to be in dell-smo8800 driver? Code for registering lis3lv02d
>>>>>>> and freefall code for smo88xx are basically independent.
>>>>>>>
>>>>>>> lis3lv02d is for accelerometer axes and smo88xx is for freefall hardisk
>>>>>>> detection. The only thing which have these "drivers" common is the ACPI
>>>>>>> detection mechanism based on presence of SMO88?? identifiers from
>>>>>>> acpi_smo8800_ids[] array.
>>>>>>>
>>>>>>> I think it makes both "drivers" cleaner if they are put into separate
>>>>>>> files as they are independent of each one.
>>>>>>>
>>>>>>> What about moving it into drivers/platform/x86/dell/dell-lis3lv02d.c
>>>>>>> instead (or similar name)? And just share list of ACPI ids via some
>>>>>>> header file (or something like that).
>>>>>>
>>>>>> Interesting idea, but that will not work, only 1 driver can bind to
>>>>>> the platform_device instantiated by the ACPI code for the SMO88xx ACPI device.
>>>>>
>>>>> And it is required to bind lis3 device to ACPI code? What is needed is
>>>>> just to check if system matches DMI strings and ACPI strings. You are
>>>>> not binding device to DMI strings, so I think there is no need to bind
>>>>> it neither to ACPI strings.
>>>>
>>>> The driver needs to bind to something ...
>>>
>>> Why?
>>>
>>> Currently in i2c-i801.c file was called just
>>> register_dell_lis3lv02d_i2c_device() function and there was no binding
>>> to anything, no binding to DMI structure and neither no binding to ACPI
>>> structures.
>>>
>>> And if I'm looking correctly at your new function
>>> smo8800_instantiate_i2c_client() it does not bind device neither.
>>> And smo8800_i2c_bus_notify() does not depend on binding.
>>>
>>> So I do not see where is that binding requirement.
>>
>> Now I have tried to do it, to move code into dell-lis3lv02d.c file.
>>
>> Below is example how it could look like. I reused most of your code.
>> I have not tested it. It is just an idea.
>
> Thank you for going through the trouble of writing this proof
> of concept.
>
> The problem with DMI matching, instead of binding to the ACPI
> SMO88xx platform_device is that this will now only load on
> laptops for which we already have the DMI ids.
I guess we could put all of this from the current dell-smo8800.c
code in a .h :
static const struct acpi_device_id smo8800_ids[] = {
{ "SMO8800", 0 },
{ "SMO8801", 0 },
{ "SMO8810", 0 },
{ "SMO8811", 0 },
{ "SMO8820", 0 },
{ "SMO8821", 0 },
{ "SMO8830", 0 },
{ "SMO8831", 0 },
{ "", 0 },
};
MODULE_DEVICE_TABLE(acpi, smo8800_ids);
Andy, I guess this is what you ment with your MODULE_DEVICE_TABLE()
comment?
And then include that .h from both modules. Then both modules
will auto-load and in the dell-lis3lv02d module we can use
module_init() / module_exit() to register the bus-notifier.
Pali, since you have expressed a clear preference for splitting
things and since this solution should not impact functionality
in anyway, I'll do this split for v4 of this series.
I do plan to re-use the existing CONFIG_DELL_SMO8800 Kconfig
value to decide whether or not to build the new dell-lis3lv02d
module. Having 2 separate Kconfig options for this seems unnecessary.
Regards,
Hans
>
> So this looses the warning about the i2c address info missing
> which we currently give when there is a SMO88xx ACPI device
> on laptops not in the DMI table (the current i2c-i801.c code
> has this already). Not giving the warning in turn means we
> cannot inform users about trying the new probe option, which is
> the whole reason to do this patch-set in the first place.
>
> I still believe that keeping this new code in dell-smo8800.c
> is best:
>
> 1. This very much is about handling the SMO88xx ACPI devices
> which makes putting it in the smo8800.c driver the logical /
> the right thing to do.
>
> 2. This only adds 400 lines of code. After this all of
> dell-smo8800.c is only 600 lines. That is very small so
> I really so no pressing need to spread this out over 2 files.
>
> 3. You claim the freefall IRQ and the i2c_client instantiation
> are 2 different things, but they are both for the same chip
> and normally would both be described in the same ACPI device
> node. The manual i2c_client instantation is done to address
> a shortcoming of the SMO88xx ACPI device node, so handling it
> belongs in the smo8800 driver.
>
> Regards,
>
> Hans
>
>
>
>
>> #include <linux/acpi.h>
>> #include <linux/dmi.h>
>> #include <linux/i2c.h>
>> #include <linux/module.h>
>> #include <linux/notifier.h>
>> #include <linux/workqueue.h>
>>
>> static struct work_struct dell_lis3lv02d_i2c_work;
>> static struct i2c_client *dell_lis3lv02d_i2c_dev;
>> static unsigned short dell_lis3lv02d_i2c_addr;
>>
>> static int dell_lis3lv02d_find_i801(struct device *dev, void *data)
>> {
>> struct i2c_adapter *adap, **adap_ret = data;
>>
>> adap = i2c_verify_adapter(dev);
>> if (!adap)
>> return 0;
>>
>> if (!strstarts(adap->name, "SMBus I801 adapter"))
>> return 0;
>>
>> *adap_ret = i2c_get_adapter(adap->nr);
>> return 1;
>> }
>>
>> static void dell_lis3lv02d_instantiate_i2c_client(struct work_struct *work)
>> {
>> struct i2c_board_info info = { };
>> struct i2c_adapter *adap = NULL;
>> struct i2c_client *client;
>>
>> if (dell_lis3lv02d_i2c_dev)
>> return;
>>
>> bus_for_each_dev(&i2c_bus_type, NULL, &adap, dell_lis3lv02d_find_i801);
>> if (!adap)
>> return;
>>
>> info.addr = dell_lis3lv02d_i2c_addr;
>> strscpy(info.type, "lis3lv02d", I2C_NAME_SIZE);
>>
>> client = i2c_new_client_device(adap, &info);
>> if (IS_ERR(client)) {
>> pr_err("error %ld registering %s i2c_client\n",
>> PTR_ERR(client), info.type);
>> return;
>> }
>>
>> dell_lis3lv02d_i2c_dev = client;
>>
>> pr_err("registered %s i2c_client on address 0x%02x\n",
>> info.type, info.addr);
>> }
>>
>> static int dell_lis3lv02d_i2c_bus_notify(struct notifier_block *nb,
>> unsigned long action, void *data)
>> {
>> struct device *dev = data;
>> struct i2c_client *client;
>> struct i2c_adapter *adap;
>>
>> switch (action) {
>> case BUS_NOTIFY_ADD_DEVICE:
>> adap = i2c_verify_adapter(dev);
>> if (!adap)
>> break;
>>
>> if (strstarts(adap->name, "SMBus I801 adapter"))
>> queue_work(system_long_wq, &dell_lis3lv02d_i2c_work);
>> break;
>> case BUS_NOTIFY_REMOVED_DEVICE:
>> client = i2c_verify_client(dev);
>> if (!client)
>> break;
>>
>> if (dell_lis3lv02d_i2c_dev == client) {
>> pr_debug("accelerometer i2c_client removed\n");
>> dell_lis3lv02d_i2c_dev = NULL;
>> }
>> break;
>> default:
>> break;
>> }
>>
>> return 0;
>> }
>>
>> // TODO: move this array into dell-smo8800.h header file
>> static const char *const acpi_smo8800_ids[] __initconst = {
>> "SMO8800",
>> "SMO8801",
>> "SMO8810",
>> "SMO8811",
>> "SMO8820",
>> "SMO8821",
>> "SMO8830",
>> "SMO8831",
>> };
>>
>> static acpi_status __init check_acpi_smo88xx_device(acpi_handle obj_handle,
>> u32 nesting_level,
>> void *context,
>> void **return_value)
>> {
>> struct acpi_device_info *info;
>> acpi_status status;
>> char *hid;
>> int i;
>>
>> status = acpi_get_object_info(obj_handle, &info);
>> if (ACPI_FAILURE(status))
>> return AE_OK;
>>
>> if (!(info->valid & ACPI_VALID_HID))
>> goto smo88xx_not_found;
>>
>> hid = info->hardware_id.string;
>> if (!hid)
>> goto smo88xx_not_found;
>>
>> i = match_string(acpi_smo8800_ids, ARRAY_SIZE(acpi_smo8800_ids), hid);
>> if (i < 0)
>> goto smo88xx_not_found;
>>
>> kfree(info);
>>
>> *return_value = NULL;
>> return AE_CTRL_TERMINATE;
>>
>> smo88xx_not_found:
>> kfree(info);
>> return AE_OK;
>> }
>>
>> static bool __init has_acpi_smo88xx_device(void)
>> {
>> void *err = ERR_PTR(-ENOENT);
>>
>> acpi_get_devices(NULL, check_acpi_smo88xx_device, NULL, &err);
>> return !IS_ERR(err);
>> }
>>
>> /*
>> * Accelerometer's I2C address is not specified in DMI nor ACPI,
>> * so it is needed to define mapping table based on DMI product names.
>> */
>> static const struct dmi_system_id dell_lis3lv02d_devices[] __initconst = {
>> /*
>> * Dell platform team told us that these Latitude devices have
>> * ST microelectronics accelerometer at I2C address 0x29.
>> */
>> {
>> .matches = {
>> DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
>> DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E5250"),
>> },
>> .driver_data = (void *)0x29,
>> },
>> {
>> .matches = {
>> DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
>> DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E5450"),
>> },
>> .driver_data = (void *)0x29,
>> },
>> {
>> .matches = {
>> DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
>> DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E5550"),
>> },
>> .driver_data = (void *)0x29,
>> },
>> {
>> .matches = {
>> DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
>> DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6440"),
>> },
>> .driver_data = (void *)0x29,
>> },
>> {
>> .matches = {
>> DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
>> DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6440 ATG"),
>> },
>> .driver_data = (void *)0x29,
>> },
>> {
>> .matches = {
>> DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
>> DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6540"),
>> },
>> .driver_data = (void *)0x29,
>> },
>> /*
>> * Additional individual entries were added after verification.
>> */
>> {
>> .matches = {
>> DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
>> DMI_MATCH(DMI_PRODUCT_NAME, "Latitude 5480"),
>> },
>> .driver_data = (void *)0x29,
>> },
>> {
>> .matches = {
>> DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
>> DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3540"),
>> },
>> .driver_data = (void *)0x29,
>> },
>> {
>> .matches = {
>> DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
>> DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V131"),
>> },
>> .driver_data = (void *)0x1d,
>> },
>> {
>> .matches = {
>> DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
>> DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 5568"),
>> },
>> .driver_data = (void *)0x29,
>> },
>> {
>> .matches = {
>> DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
>> DMI_MATCH(DMI_PRODUCT_NAME, "XPS 15 7590"),
>> },
>> .driver_data = (void *)0x29,
>> },
>> { }
>> };
>> MODULE_DEVICE_TABLE(dmi, dell_lis3lv02d_devices);
>>
>> static struct notifier_block dell_lis3lv02d_i2c_nb = {
>> .notifier_call = dell_lis3lv02d_i2c_bus_notify,
>> };
>>
>> static int __init dell_lis3lv02d_init(void)
>> {
>> const struct dmi_system_id *lis3lv02d_dmi_id;
>> int err;
>>
>> if (!has_acpi_smo88xx_device())
>> return -ENODEV;
>>
>> lis3lv02d_dmi_id = dmi_first_match(dell_lis3lv02d_devices);
>> if (!lis3lv02d_dmi_id)
>> return -ENODEV;
>>
>> dell_lis3lv02d_i2c_addr = (uintptr_t)lis3lv02d_dmi_id->driver_data;
>>
>> err = bus_register_notifier(&i2c_bus_type, &dell_lis3lv02d_i2c_nb);
>> if (err)
>> return err;
>>
>> INIT_WORK(&dell_lis3lv02d_i2c_work, dell_lis3lv02d_instantiate_i2c_client);
>> queue_work(system_long_wq, &dell_lis3lv02d_i2c_work);
>>
>> return 0;
>> }
>>
>> static void __exit dell_lis3lv02d_exit(void)
>> {
>> bus_unregister_notifier(&i2c_bus_type, &dell_lis3lv02d_i2c_nb);
>> cancel_work_sync(&dell_lis3lv02d_i2c_work);
>> if (dell_lis3lv02d_i2c_dev)
>> i2c_unregister_device(dell_lis3lv02d_i2c_dev);
>> }
>>
>> module_init(dell_lis3lv02d_init);
>> module_exit(dell_lis3lv02d_exit);
>>
>> MODULE_LICENSE("GPL");
>>
>
next prev parent reply other threads:[~2024-06-23 14:10 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-21 12:24 [PATCH v3 0/6] i2c-i801 / dell-smo8800: Move instantiation of lis3lv02d i2c_client from i2c-i801 to dell-smo8800 Hans de Goede
2024-06-21 12:24 ` [PATCH v3 1/6] i2c: core: Setup i2c_adapter runtime-pm before calling device_add() Hans de Goede
2024-06-21 15:08 ` Andy Shevchenko
2024-06-21 12:24 ` [PATCH v3 2/6] i2c: i801: Use a different adapter-name for IDF adapters Hans de Goede
2024-06-21 15:13 ` Andy Shevchenko
2024-06-22 12:46 ` Pali Rohár
2024-06-22 13:56 ` Hans de Goede
2024-06-22 14:08 ` Pali Rohár
2024-06-22 14:14 ` Hans de Goede
2024-06-22 14:23 ` Pali Rohár
2024-06-22 14:29 ` Hans de Goede
2024-06-22 15:07 ` Pali Rohár
2024-06-23 13:58 ` Hans de Goede
2024-06-21 12:24 ` [PATCH v3 3/6] platform/x86: dell-smo8800: Move instantiation of lis3lv02d i2c_client from i2c-i801 to dell-smo8800 Hans de Goede
2024-06-21 15:24 ` Andy Shevchenko
2024-06-22 13:59 ` Hans de Goede
2024-06-22 13:16 ` Pali Rohár
2024-06-22 14:06 ` Hans de Goede
2024-06-22 14:20 ` Pali Rohár
2024-06-22 14:26 ` Hans de Goede
2024-06-22 15:12 ` Pali Rohár
2024-06-22 16:35 ` Pali Rohár
2024-06-23 13:56 ` Hans de Goede
2024-06-23 14:09 ` Hans de Goede [this message]
2024-06-22 22:36 ` Andy Shevchenko
2024-06-22 22:41 ` Pali Rohár
2024-06-22 16:26 ` Pali Rohár
2024-06-23 13:46 ` Hans de Goede
2024-06-22 16:43 ` Pali Rohár
2024-06-22 22:43 ` Andy Shevchenko
2024-06-22 22:50 ` Pali Rohár
2024-06-22 22:53 ` Andy Shevchenko
2024-06-23 14:00 ` Hans de Goede
2024-06-22 15:35 ` Pali Rohár
2024-06-23 13:45 ` Hans de Goede
2024-06-23 14:30 ` Pali Rohár
2024-06-21 12:24 ` [PATCH v3 4/6] platform/x86: dell-smo8800: Allow lis3lv02d i2c_client instantiation without IRQ Hans de Goede
2024-06-21 15:30 ` Andy Shevchenko
2024-06-22 13:20 ` Pali Rohár
2024-06-22 14:07 ` Hans de Goede
2024-06-22 15:14 ` Pali Rohár
2024-06-21 12:25 ` [PATCH v3 5/6] platform/x86: dell-smo8800: Add a couple more models to dell_lis3lv02d_devices[] Hans de Goede
2024-06-21 12:25 ` [PATCH v3 6/6] platform/x86: dell-smo8800: Add support for probing for the accelerometer i2c address Hans de Goede
2024-06-21 15:37 ` Andy Shevchenko
2024-06-22 13:32 ` Pali Rohár
2024-06-22 14:21 ` Hans de Goede
2024-06-22 14:50 ` Pali Rohár
2024-06-22 22:50 ` Andy Shevchenko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=38fefc37-0599-4dc3-84b4-3e4d0870474c@redhat.com \
--to=hdegoede@redhat.com \
--cc=Dell.Client.Kernel@dell.com \
--cc=andi.shyti@kernel.org \
--cc=andy@kernel.org \
--cc=eric.piel@tremplin-utc.net \
--cc=ilpo.jarvinen@linux.intel.com \
--cc=jdelvare@suse.com \
--cc=kai.heng.feng@canonical.com \
--cc=linux-i2c@vger.kernel.org \
--cc=mail@mariushoch.de \
--cc=pali@kernel.org \
--cc=platform-driver-x86@vger.kernel.org \
--cc=pmenzel@molgen.mpg.de \
--cc=wsa@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox