Skip to content

Commit c07e0c3

Browse files
author
Dmitry Perchanov
committed
isys: remove i2c subdevices on unloading module
Signed-off-by: Dmitry Perchanov <[email protected]>
1 parent c61e2c8 commit c07e0c3

File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed

drivers/media/pci/intel/ipu-isys.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,57 @@ static int isys_register_ext_subdev(struct ipu_isys *isys,
422422
return rval;
423423
}
424424

425+
static int isys_unregister_ext_subdev(struct ipu_isys *isys,
426+
struct ipu_isys_subdev_info *sd_info)
427+
{
428+
struct i2c_adapter *adapter;
429+
struct i2c_client *client;
430+
int rval;
431+
int bus;
432+
433+
bus = ipu_get_i2c_bus_id(sd_info->i2c.i2c_adapter_id,
434+
sd_info->i2c.i2c_adapter_bdf,
435+
sizeof(sd_info->i2c.i2c_adapter_bdf));
436+
if (bus < 0) {
437+
dev_err(&isys->adev->dev,
438+
"getting i2c bus id for adapter %d (bdf %s) failed",
439+
sd_info->i2c.i2c_adapter_id,
440+
sd_info->i2c.i2c_adapter_bdf);
441+
return -ENOENT;
442+
}
443+
dev_info(&isys->adev->dev,
444+
"got i2c bus id %d for adapter %d (bdf %s)", bus,
445+
sd_info->i2c.i2c_adapter_id,
446+
sd_info->i2c.i2c_adapter_bdf);
447+
adapter = i2c_get_adapter(bus);
448+
if (!adapter) {
449+
dev_warn(&isys->adev->dev, "can't find adapter\n");
450+
return -ENOENT;
451+
}
452+
453+
dev_info(&isys->adev->dev,
454+
"unregister i2c subdev for %s (address %2.2x, bus %d)",
455+
sd_info->i2c.board_info.type, sd_info->i2c.board_info.addr,
456+
bus);
457+
458+
client = isys_find_i2c_subdev(adapter, sd_info);
459+
if (!client) {
460+
dev_dbg(&isys->adev->dev, "Device not exists\n");
461+
rval = 0;
462+
goto skip_put_adapter;
463+
}
464+
465+
i2c_unregister_device(client);
466+
i2c_put_adapter(adapter);
467+
468+
return 0;
469+
470+
skip_put_adapter:
471+
i2c_put_adapter(adapter);
472+
473+
return rval;
474+
}
475+
425476
static void isys_register_ext_subdevs(struct ipu_isys *isys)
426477
{
427478
struct ipu_isys_subdev_pdata *spdata = isys->pdata->spdata;
@@ -434,6 +485,19 @@ static void isys_register_ext_subdevs(struct ipu_isys *isys)
434485
for (sd_info = spdata->subdevs; *sd_info; sd_info++)
435486
isys_register_ext_subdev(isys, *sd_info);
436487
}
488+
489+
static void isys_unregister_ext_subdevs(struct ipu_isys *isys)
490+
{
491+
struct ipu_isys_subdev_pdata *spdata = isys->pdata->spdata;
492+
struct ipu_isys_subdev_info **sd_info;
493+
494+
if (!spdata) {
495+
dev_info(&isys->adev->dev, "no subdevice info provided\n");
496+
return;
497+
}
498+
for (sd_info = spdata->subdevs; *sd_info; sd_info++)
499+
isys_unregister_ext_subdev(isys, *sd_info);
500+
}
437501
#endif
438502

439503
static void isys_unregister_subdevices(struct ipu_isys *isys)
@@ -793,6 +857,7 @@ static int isys_register_devices(struct ipu_isys *isys)
793857
static void isys_unregister_devices(struct ipu_isys *isys)
794858
{
795859
isys_unregister_subdevices(isys);
860+
isys_unregister_ext_subdevs(isys);
796861
v4l2_device_unregister(&isys->v4l2_dev);
797862
media_device_unregister(&isys->media_dev);
798863
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)

0 commit comments

Comments
 (0)