From 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Tue, 22 Oct 2024 10:36:11 +0000 Subject: [PATCH] 修改4g拨号为QMI,需要在系统里后台执行quectel-CM --- kernel/drivers/media/v4l2-core/v4l2-device.c | 93 +++++++++++++++------------------------------- 1 files changed, 31 insertions(+), 62 deletions(-) diff --git a/kernel/drivers/media/v4l2-core/v4l2-device.c b/kernel/drivers/media/v4l2-core/v4l2-device.c index 3940e55..de42872 100644 --- a/kernel/drivers/media/v4l2-core/v4l2-device.c +++ b/kernel/drivers/media/v4l2-core/v4l2-device.c @@ -1,31 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* V4L2 device support. Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl> - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <linux/types.h> #include <linux/ioctl.h> #include <linux/module.h> -#include <linux/i2c.h> #include <linux/slab.h> -#if defined(CONFIG_SPI) -#include <linux/spi/spi.h> -#endif #include <linux/videodev2.h> #include <media/v4l2-device.h> #include <media/v4l2-ctrls.h> @@ -114,37 +98,10 @@ /* Unregister subdevs */ list_for_each_entry_safe(sd, next, &v4l2_dev->subdevs, list) { v4l2_device_unregister_subdev(sd); -#if IS_ENABLED(CONFIG_I2C) - if (sd->flags & V4L2_SUBDEV_FL_IS_I2C) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - - /* - * We need to unregister the i2c client - * explicitly. We cannot rely on - * i2c_del_adapter to always unregister - * clients for us, since if the i2c bus is a - * platform bus, then it is never deleted. - * - * Device tree or ACPI based devices must not - * be unregistered as they have not been - * registered by us, and would not be - * re-created by just probing the V4L2 driver. - */ - if (client && - !client->dev.of_node && !client->dev.fwnode) - i2c_unregister_device(client); - continue; - } -#endif -#if defined(CONFIG_SPI) - if (sd->flags & V4L2_SUBDEV_FL_IS_SPI) { - struct spi_device *spi = v4l2_get_subdevdata(sd); - - if (spi && !spi->dev.of_node && !spi->dev.fwnode) - spi_unregister_device(spi); - continue; - } -#endif + if (sd->flags & V4L2_SUBDEV_FL_IS_I2C) + v4l2_i2c_subdev_unregister(sd); + else if (sd->flags & V4L2_SUBDEV_FL_IS_SPI) + v4l2_spi_subdev_unregister(sd); } /* Mark as unregistered, thus preventing duplicate unregistrations */ v4l2_dev->name[0] = '\0'; @@ -154,9 +111,6 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, struct v4l2_subdev *sd) { -#if defined(CONFIG_MEDIA_CONTROLLER) - struct media_entity *entity = &sd->entity; -#endif int err; /* Check for valid input */ @@ -178,14 +132,15 @@ sd->v4l2_dev = v4l2_dev; /* This just returns 0 if either of the two args is NULL */ - err = v4l2_ctrl_add_handler(v4l2_dev->ctrl_handler, sd->ctrl_handler, NULL); + err = v4l2_ctrl_add_handler(v4l2_dev->ctrl_handler, sd->ctrl_handler, + NULL, true); if (err) goto error_module; #if defined(CONFIG_MEDIA_CONTROLLER) /* Register the entity. */ if (v4l2_dev->mdev) { - err = media_device_register_entity(v4l2_dev->mdev, entity); + err = media_device_register_entity(v4l2_dev->mdev, &sd->entity); if (err < 0) goto error_module; } @@ -205,7 +160,7 @@ error_unregister: #if defined(CONFIG_MEDIA_CONTROLLER) - media_device_unregister_entity(entity); + media_device_unregister_entity(&sd->entity); #endif error_module: if (!sd->owner_v4l2_dev) @@ -215,14 +170,24 @@ } EXPORT_SYMBOL_GPL(v4l2_device_register_subdev); +static void v4l2_subdev_release(struct v4l2_subdev *sd) +{ + struct module *owner = !sd->owner_v4l2_dev ? sd->owner : NULL; + + if (sd->internal_ops && sd->internal_ops->release) + sd->internal_ops->release(sd); + sd->devnode = NULL; + module_put(owner); +} + static void v4l2_device_release_subdev_node(struct video_device *vdev) { - struct v4l2_subdev *sd = video_get_drvdata(vdev); - sd->devnode = NULL; + v4l2_subdev_release(video_get_drvdata(vdev)); kfree(vdev); } -int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev) +int __v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev, + bool read_only) { struct video_device *vdev; struct v4l2_subdev *sd; @@ -245,11 +210,14 @@ } video_set_drvdata(vdev, sd); - strlcpy(vdev->name, sd->name, sizeof(vdev->name)); + strscpy(vdev->name, sd->name, sizeof(vdev->name)); + vdev->dev_parent = sd->dev; vdev->v4l2_dev = v4l2_dev; vdev->fops = &v4l2_subdev_fops; vdev->release = v4l2_device_release_subdev_node; vdev->ctrl_handler = sd->ctrl_handler; + if (read_only) + set_bit(V4L2_FL_SUBDEV_RO_DEVNODE, &vdev->flags); err = __video_register_device(vdev, VFL_TYPE_SUBDEV, -1, 1, sd->owner); if (err < 0) { @@ -287,7 +255,7 @@ return err; } -EXPORT_SYMBOL_GPL(v4l2_device_register_subdev_nodes); +EXPORT_SYMBOL_GPL(__v4l2_device_register_subdev_nodes); void v4l2_device_unregister_subdev(struct v4l2_subdev *sd) { @@ -316,8 +284,9 @@ media_device_unregister_entity(&sd->entity); } #endif - video_unregister_device(sd->devnode); - if (!sd->owner_v4l2_dev) - module_put(sd->owner); + if (sd->devnode) + video_unregister_device(sd->devnode); + else + v4l2_subdev_release(sd); } EXPORT_SYMBOL_GPL(v4l2_device_unregister_subdev); -- Gitblit v1.6.2