mirror of
				https://github.com/Ysurac/openmptcprouter.git
				synced 2025-03-09 15:40:20 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			126 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			126 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 96705a2b5ad643d209f242c805abbdb270cee57b Mon Sep 17 00:00:00 2001
 | |
| From: Dave Stevenson <dave.stevenson@raspberrypi.org>
 | |
| Date: Tue, 29 Jan 2019 15:56:10 +0000
 | |
| Subject: [PATCH 330/432] media:bcm2835-unicam: Power on subdev on
 | |
|  open/release, not streaming
 | |
| 
 | |
| The driver was powering on the source subdevice as part of STREAMON,
 | |
| and powering it off in STREAMOFF. This isn't so great if there is a
 | |
| significant amount of setup required for your device.
 | |
| 
 | |
| Copy the approach taken in the Atmel ISC driver where s_power(1) is called
 | |
| on first file handle open, and s_power(0) is called on the last release.
 | |
| 
 | |
| See https://www.raspberrypi.org/forums/viewtopic.php?f=43&t=232437
 | |
| 
 | |
| Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
 | |
| ---
 | |
|  .../media/platform/bcm2835/bcm2835-unicam.c   | 68 +++++++++++++++----
 | |
|  1 file changed, 54 insertions(+), 14 deletions(-)
 | |
| 
 | |
| diff --git a/drivers/media/platform/bcm2835/bcm2835-unicam.c b/drivers/media/platform/bcm2835/bcm2835-unicam.c
 | |
| index 545e729c7f0f..176c2d3d7ee7 100644
 | |
| --- a/drivers/media/platform/bcm2835/bcm2835-unicam.c
 | |
| +++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c
 | |
| @@ -1237,11 +1237,6 @@ static int unicam_start_streaming(struct vb2_queue *vq, unsigned int count)
 | |
|  		unicam_err(dev, "Failed to enable CSI clock: %d\n", ret);
 | |
|  		goto err_pm_put;
 | |
|  	}
 | |
| -	ret = v4l2_subdev_call(dev->sensor, core, s_power, 1);
 | |
| -	if (ret < 0 && ret != -ENOIOCTLCMD) {
 | |
| -		unicam_err(dev, "power on failed in subdev\n");
 | |
| -		goto err_clock_unprepare;
 | |
| -	}
 | |
|  	dev->streaming = 1;
 | |
|  
 | |
|  	unicam_start_rx(dev, addr);
 | |
| @@ -1256,8 +1251,6 @@ static int unicam_start_streaming(struct vb2_queue *vq, unsigned int count)
 | |
|  
 | |
|  err_disable_unicam:
 | |
|  	unicam_disable(dev);
 | |
| -	v4l2_subdev_call(dev->sensor, core, s_power, 0);
 | |
| -err_clock_unprepare:
 | |
|  	clk_disable_unprepare(dev->clock);
 | |
|  err_pm_put:
 | |
|  	unicam_runtime_put(dev);
 | |
| @@ -1306,11 +1299,6 @@ static void unicam_stop_streaming(struct vb2_queue *vq)
 | |
|  	dev->next_frm = NULL;
 | |
|  	spin_unlock_irqrestore(&dev->dma_queue_lock, flags);
 | |
|  
 | |
| -	if (v4l2_subdev_has_op(dev->sensor, core, s_power)) {
 | |
| -		if (v4l2_subdev_call(dev->sensor, core, s_power, 0) < 0)
 | |
| -			unicam_err(dev, "power off failed in subdev\n");
 | |
| -	}
 | |
| -
 | |
|  	clk_disable_unprepare(dev->clock);
 | |
|  	unicam_runtime_put(dev);
 | |
|  }
 | |
| @@ -1543,11 +1531,63 @@ static const struct vb2_ops unicam_video_qops = {
 | |
|  	.stop_streaming		= unicam_stop_streaming,
 | |
|  };
 | |
|  
 | |
| +/*
 | |
| + * unicam_open : This function is based on the v4l2_fh_open helper function.
 | |
| + * It has been augmented to handle sensor subdevice power management,
 | |
| + */
 | |
| +static int unicam_open(struct file *file)
 | |
| +{
 | |
| +	struct unicam_device *dev = video_drvdata(file);
 | |
| +	int ret;
 | |
| +
 | |
| +	mutex_lock(&dev->lock);
 | |
| +
 | |
| +	ret = v4l2_fh_open(file);
 | |
| +	if (ret) {
 | |
| +		unicam_err(dev, "v4l2_fh_open failed\n");
 | |
| +		goto unlock;
 | |
| +	}
 | |
| +
 | |
| +	if (!v4l2_fh_is_singular_file(file))
 | |
| +		goto unlock;
 | |
| +
 | |
| +	ret = v4l2_subdev_call(dev->sensor, core, s_power, 1);
 | |
| +	if (ret < 0 && ret != -ENOIOCTLCMD) {
 | |
| +		v4l2_fh_release(file);
 | |
| +		goto unlock;
 | |
| +	}
 | |
| +
 | |
| +unlock:
 | |
| +	mutex_unlock(&dev->lock);
 | |
| +	return ret;
 | |
| +}
 | |
| +
 | |
| +static int unicam_release(struct file *file)
 | |
| +{
 | |
| +	struct unicam_device *dev = video_drvdata(file);
 | |
| +	struct v4l2_subdev *sd = dev->sensor;
 | |
| +	bool fh_singular;
 | |
| +	int ret;
 | |
| +
 | |
| +	mutex_lock(&dev->lock);
 | |
| +
 | |
| +	fh_singular = v4l2_fh_is_singular_file(file);
 | |
| +
 | |
| +	ret = _vb2_fop_release(file, NULL);
 | |
| +
 | |
| +	if (fh_singular)
 | |
| +		v4l2_subdev_call(sd, core, s_power, 0);
 | |
| +
 | |
| +	mutex_unlock(&dev->lock);
 | |
| +
 | |
| +	return ret;
 | |
| +}
 | |
| +
 | |
|  /* unicam capture driver file operations */
 | |
|  static const struct v4l2_file_operations unicam_fops = {
 | |
|  	.owner		= THIS_MODULE,
 | |
| -	.open           = v4l2_fh_open,
 | |
| -	.release        = vb2_fop_release,
 | |
| +	.open           = unicam_open,
 | |
| +	.release        = unicam_release,
 | |
|  	.read		= vb2_fop_read,
 | |
|  	.poll		= vb2_fop_poll,
 | |
|  	.unlocked_ioctl	= video_ioctl2,
 | |
| -- 
 | |
| 2.19.1
 | |
| 
 |