@@ -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+
425476static 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
439503static void isys_unregister_subdevices (struct ipu_isys * isys )
@@ -793,6 +857,7 @@ static int isys_register_devices(struct ipu_isys *isys)
793857static 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