Re: [PATCH v9 2/2] Add support for OV5647 sensor.
From: Vladimir Zapolskiy
Date: Wed Feb 22 2017 - 06:43:27 EST
On 02/22/2017 12:51 PM, Ramiro Oliveira wrote:
> Hi Zakari,
>
> On 2/21/2017 8:36 PM, Vladimir Zapolskiy wrote:
>> Hi Ramiro,
>>
>> On 02/21/2017 06:42 PM, Ramiro Oliveira wrote:
>>> Hi Vladimir,
>>>
>>> Thank you for your feedback
>>>
>>> On 2/21/2017 3:54 PM, Vladimir Zapolskiy wrote:
>>>> Hi Ramiro,
>>>>
>>>> please find some review comments below.
>>>>
>>>> On 02/17/2017 03:14 PM, Ramiro Oliveira wrote:
>>>>> The OV5647 sensor from Omnivision supports up to 2592x1944 @ 15 fps, RAW 8
>>>>> and RAW 10 output formats, and MIPI CSI-2 interface.
>>>>>
>>>>> The driver adds support for 640x480 RAW 8.
>>>>>
>>>>> Signed-off-by: Ramiro Oliveira <roliveir@xxxxxxxxxxxx>
>>>>> ---
>>>>
>>>> [snip]
>>>>
>>>>> +
>>>>> +struct ov5647 {
>>>>> + struct v4l2_subdev sd;
>>>>> + struct media_pad pad;
>>>>> + struct mutex lock;
>>>>> + struct v4l2_mbus_framefmt format;
>>>>> + unsigned int width;
>>>>> + unsigned int height;
>>>>> + int power_count;
>>>>> + struct clk *xclk;
>>>>> + /* External clock frequency currently supported is 30MHz */
>>>>> + u32 xclk_freq;
>>>>
>>>> See a comment about 25MHz vs 30MHz below.
>>>>
>>>> Also I assume you can remove 'xclk_freq' from the struct fields,
>>>> it can be replaced by a local variable.
>>>>
>>>
>>> I'll do that.
>>>
>>>>> +};
>>>>
>>>> [snip]
>>>>
>>>>> +
>>>>> +static int ov5647_read(struct v4l2_subdev *sd, u16 reg, u8 *val)
>>>>> +{
>>>>> + int ret;
>>>>> + unsigned char data_w[2] = { reg >> 8, reg & 0xff };
>>>>> + struct i2c_client *client = v4l2_get_subdevdata(sd);
>>>>> +
>>>>> + ret = i2c_master_send(client, data_w, 2);
>>>>> + if (ret < 0) {
>>>>> + dev_dbg(&client->dev, "%s: i2c read error, reg: %x\n",
>>>>
>>>> s/i2c read error/i2c write error/
>>>>
>>>
>>> I'm not sure I understand what you mean.
>>
>> That's a sed expression for string substitution. Here you do i2c_master_send()
>> but dev_dbg() comment says "i2c read error". It's a simple copy-paste typo to fix.
>>
>
> Ohh... now I see. I'll change it.
>
>>>>> + __func__, reg);
>>>>> + return ret;
>>>>> + }
>>>>> +
>>
>> [snip]
>>
>>>>> +
>>>>> +static int sensor_power(struct v4l2_subdev *sd, int on)
>>
>> On the caller's side (functions ov5647_open() and ov5647_close()) the second
>> argument of the function is of 'bool' type, however .s_power callback from
>> struct v4l2_subdev_core_ops (see include/media/v4l2-subdev.h) defines it as
>> 'int'.
>>
>> It's just a nitpicking, please feel free to ignore the comment above or
>> please consider to change the arguments on callers' side to integers.
>>
>> Also you may consider to add 'ov5647_' prefix to the function name to
>> distinguish it from a potentially added in future sensor_power() function,
>> the original name sounds too generic.
>>
>
> OK. I'll add the prefix and change the variable type from int to bool.
>
Just to eliminate any potential misunderstanding, if you consider to reuse
the current sensor_power() function, please change variables from bool to int
on a caller's side, the signature of the function shall not be changed to
match .s_power type.
>>>>> +{
>>>>> + int ret;
>>>>> + struct ov5647 *ov5647 = to_state(sd);
>>>>> + struct i2c_client *client = v4l2_get_subdevdata(sd);
>>>>> +
>>>>> + ret = 0;
>>>>> + mutex_lock(&ov5647->lock);
>>>>> +
>>>>> + if (on && !ov5647->power_count) {
>>>>> + dev_dbg(&client->dev, "OV5647 power on\n");
>>>>> +
>>>>> + clk_set_rate(ov5647->xclk, ov5647->xclk_freq);
>>>>
>>>> Now clk_set_rate() is redundant, please remove it.
>>>>
>>>> If once it is needed again, please move it to the .probe function, so
>>>> it is called only once in the runtime.
>>>>
>>>
>>> Ok. I'll remove it for now.
>>>
>>>>> +
>>>>> + ret = clk_prepare_enable(ov5647->xclk);
>>>>
>>>> I wonder would it be possible to unload the driver or to unbind the device
>>>> and leave the clock unintentionally enabled? If yes, then this is a bug.
>>>>
>>>
>>> You're saying that if the driver was unloaded and the clock was left enabled
>>> when the driver was loaded again this line would cause an error?
>>
>> Not exactly, here I saw a potential resource leak, namely a potentially left
>> prepared/enabled clock.
>>
>>>
>>> Should I disable the clock when the driver is removed?
>>>
>>
>> The driver (and framework) shall guarantee that when it is detached from
>> device(s) (e.g. by unloading "ov5647" kernel module or unbinding ov5647 device),
>> all acquired resources are released.
>>
>> But in this particular case most probably I've been overly alert, I believe
>> that V4L2 framework correcly handles device power states, so please ignore my
>> comment.
>>
>> To add something valuable to the review, could you please confirm that
>> ov5647_subdev_internal_ops data is in use by the driver?
>>
>> E.g. shouldn't it be registered by
>>
>> sd->internal_ops = &ov5647_subdev_internal_ops;
>>
>> before calling v4l2_async_register_subdev(sd) ?
>>
>
> You're right, it's not being registered. I think I'll remove them since they
> aren't being used.
>
--
With best wishes,
Vladimir