From: "Pali Rohár" <pali@kernel.org>
To: Hans de Goede <hdegoede@redhat.com>
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: Sat, 22 Jun 2024 18:35:18 +0200 [thread overview]
Message-ID: <20240622163518.rfm2wa2kzucy7in4@pali> (raw)
In-Reply-To: <20240622151250.zvli73oxqmbsd3n4@pali>
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.
#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-22 16:35 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 [this message]
2024-06-23 13:56 ` Hans de Goede
2024-06-23 14:09 ` Hans de Goede
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=20240622163518.rfm2wa2kzucy7in4@pali \
--to=pali@kernel.org \
--cc=Dell.Client.Kernel@dell.com \
--cc=andi.shyti@kernel.org \
--cc=andy@kernel.org \
--cc=eric.piel@tremplin-utc.net \
--cc=hdegoede@redhat.com \
--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=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