Even yet more V4L2 patches for 5.18

-----BEGIN PGP SIGNATURE-----
 
 iJMEABEIADsWIQRTrFil9ZSGNsBKG/gUHfpUoeyN6gUCYiHBnh0cc2FrYXJpLmFp
 bHVzQGxpbnV4LmludGVsLmNvbQAKCRAUHfpUoeyN6jvwAQCXadtz1Ak1oRm+nWih
 dO6rM2yonXUgZHyCwT3DRhdUHwD/Xs51RkSsrISWAuSqClDe0MSfREQ+TQKGtU6+
 zQkHU1Q=
 =4R9H
 -----END PGP SIGNATURE-----

Merge tag 'for-5.18-2.6-signed' of git://linuxtv.org/sailus/media_tree into media_stage

Even yet more V4L2 patches for 5.18

* tag 'for-5.18-2.6-signed' of git://linuxtv.org/sailus/media_tree:
  media: i2c: Fix pixel array positions in ov8865
  media: adv7183: Convert to GPIO descriptors
  media: m5mols: Convert to use GPIO descriptors
  media: noon010p30: Convert to use GPIO descriptors
  media: mt9m111: Drop unused include
  media: adv7511: Drop unused include
  media: i2c: isl7998x: Add driver for Intersil ISL7998x
  media: dt-bindings: Add Intersil ISL79987 DT bindings
  media: media-entity: Clarify media_entity_cleanup() usage
  media: i2c: imx274: Drop surplus includes
  media: i2c: ccs: Drop unused include
  v4l: fwnode: Remove now-redundant loop from v4l2_fwnode_parse_reference()
  v4l: fwnode: Drop redunant -ENODATA check in property reference parsing
  media: media-entity: Simplify media_pipeline_start()
  media: media-entity: Add media_pad_is_streaming() helper function
  media: Add a driver for the og01a1b camera sensor
  media: i2c: ov5648: Fix lockdep error
  media: ov5640: Fix set format, v4l2_mbus_pixelcode not updated

Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
This commit is contained in:
Mauro Carvalho Chehab 2022-03-07 16:43:02 +01:00
commit 12fdba564a
28 changed files with 3063 additions and 173 deletions

View File

@ -0,0 +1,113 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/media/i2c/isil,isl79987.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Intersil ISL79987 Analog to MIPI CSI-2 decoder
maintainers:
- Michael Tretter <m.tretter@pengutronix.de>
- Marek Vasut <marex@denx.de>
description:
The Intersil ISL79987 is an analog to MIPI CSI-2 decoder which is capable of
receiving up to four analog stream and multiplexing them into up to four MIPI
CSI-2 virtual channels, using one MIPI clock lane and 1/2 data lanes.
properties:
compatible:
enum:
- isil,isl79987
reg:
maxItems: 1
reset-gpios:
maxItems: 1
description:
A GPIO spec for the RSTB pin (active high)
powerdown-gpios:
maxItems: 1
description:
A GPIO spec for the Power Down pin (active high)
ports:
$ref: /schemas/graph.yaml#/properties/ports
properties:
port@0:
$ref: /schemas/graph.yaml#/$defs/port-base
unevaluatedProperties: false
description: Output port
properties:
endpoint:
$ref: /schemas/media/video-interfaces.yaml#
unevaluatedProperties: false
properties:
data-lanes:
minItems: 1
maxItems: 2
required:
- data-lanes
patternProperties:
"^port@[1-4]$":
$ref: /schemas/graph.yaml#/properties/port
description: Input ports
required:
- port@0
additionalProperties: false
required:
- compatible
- reg
- ports
examples:
- |
#include <dt-bindings/gpio/gpio.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
isl7998x_mipi@44 {
compatible = "isil,isl79987";
reg = <0x44>;
powerdown-gpios = <&gpio3 27 GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpio3 28 GPIO_ACTIVE_HIGH>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
isl79987_out: endpoint {
remote-endpoint = <&mipi_csi2_in>;
data-lanes = <1 2>;
};
};
port@1 {
reg = <1>;
endpoint {
remote-endpoint = <&camera_0>;
};
};
port@2 {
reg = <2>;
endpoint {
remote-endpoint = <&camera_1>;
};
};
};
};
};

View File

@ -10006,6 +10006,14 @@ L: linux-iio@vger.kernel.org
F: Documentation/devicetree/bindings/counter/interrupt-counter.yaml
F: drivers/counter/interrupt-cnt.c
INTERSIL ISL7998X VIDEO DECODER DRIVER
M: Michael Tretter <m.tretter@pengutronix.de>
R: Pengutronix Kernel Team <kernel@pengutronix.de>
L: linux-media@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/media/i2c/isil,isl79987.yaml
F: drivers/media/i2c/isl7998x.c
INVENSENSE ICM-426xx IMU DRIVER
M: Jean-Baptiste Maneyrol <jmaneyrol@invensense.com>
L: linux-iio@vger.kernel.org
@ -14185,6 +14193,12 @@ M: Harald Welte <laforge@gnumonks.org>
S: Maintained
F: drivers/char/pcmcia/cm4040_cs.*
OMNIVISION OG01A1B SENSOR DRIVER
M: Shawn Tu <shawnx.tu@intel.com>
L: linux-media@vger.kernel.org
S: Maintained
F: drivers/media/i2c/og01a1b.c
OMNIVISION OV02A10 SENSOR DRIVER
M: Dongchun Zhu <dongchun.zhu@mediatek.com>
L: linux-media@vger.kernel.org

View File

@ -325,6 +325,16 @@ config VIDEO_BT866
To compile this driver as a module, choose M here: the
module will be called bt866.
config VIDEO_ISL7998X
tristate "Intersil ISL7998x video decoder"
depends on VIDEO_V4L2 && I2C
depends on OF_GPIO
select MEDIA_CONTROLLER
select VIDEO_V4L2_SUBDEV_API
help
Support for Intersil ISL7998x analog to MIPI-CSI2 or
BT.656 decoder.
config VIDEO_KS0127
tristate "KS0127 video decoder"
depends on VIDEO_V4L2 && I2C
@ -912,6 +922,19 @@ config VIDEO_IMX412
To compile this driver as a module, choose M here: the
module will be called imx412.
config VIDEO_OG01A1B
tristate "OmniVision OG01A1B sensor support"
depends on I2C && VIDEO_V4L2
select MEDIA_CONTROLLER
select VIDEO_V4L2_SUBDEV_API
select V4L2_FWNODE
help
This is a Video4Linux2 sensor driver for the OmniVision
OG01A1B camera.
To compile this driver as a module, choose M here: the
module will be called og01a1b.
config VIDEO_OV02A10
tristate "OmniVision OV02A10 sensor support"
depends on VIDEO_V4L2 && I2C

View File

@ -64,6 +64,7 @@ obj-$(CONFIG_VIDEO_VP27SMPX) += vp27smpx.o
obj-$(CONFIG_VIDEO_SONY_BTF_MPX) += sony-btf-mpx.o
obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o
obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
obj-$(CONFIG_VIDEO_OG01A1B) += og01a1b.o
obj-$(CONFIG_VIDEO_OV02A10) += ov02a10.o
obj-$(CONFIG_VIDEO_OV08D10) += ov08d10.o
obj-$(CONFIG_VIDEO_OV2640) += ov2640.o
@ -133,6 +134,7 @@ obj-$(CONFIG_VIDEO_IMX334) += imx334.o
obj-$(CONFIG_VIDEO_IMX335) += imx335.o
obj-$(CONFIG_VIDEO_IMX355) += imx355.o
obj-$(CONFIG_VIDEO_IMX412) += imx412.o
obj-$(CONFIG_VIDEO_ISL7998X) += isl7998x.o
obj-$(CONFIG_VIDEO_MAX9286) += max9286.o
obj-$(CONFIG_VIDEO_MAX9271_LIB) += max9271.o
obj-$(CONFIG_VIDEO_RDACM20) += rdacm20.o

View File

@ -7,7 +7,7 @@
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/module.h>
@ -28,8 +28,8 @@ struct adv7183 {
v4l2_std_id std; /* Current set standard */
u32 input;
u32 output;
unsigned reset_pin;
unsigned oe_pin;
struct gpio_desc *reset_pin;
struct gpio_desc *oe_pin;
struct v4l2_mbus_framefmt fmt;
};
@ -465,9 +465,9 @@ static int adv7183_s_stream(struct v4l2_subdev *sd, int enable)
struct adv7183 *decoder = to_adv7183(sd);
if (enable)
gpio_set_value(decoder->oe_pin, 0);
gpiod_set_value(decoder->oe_pin, 1);
else
gpio_set_value(decoder->oe_pin, 1);
gpiod_set_value(decoder->oe_pin, 0);
udelay(1);
return 0;
}
@ -531,7 +531,6 @@ static int adv7183_probe(struct i2c_client *client,
struct v4l2_subdev_format fmt = {
.which = V4L2_SUBDEV_FORMAT_ACTIVE,
};
const unsigned *pin_array;
/* Check if the adapter supports the needed features */
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@ -540,29 +539,28 @@ static int adv7183_probe(struct i2c_client *client,
v4l_info(client, "chip found @ 0x%02x (%s)\n",
client->addr << 1, client->adapter->name);
pin_array = client->dev.platform_data;
if (pin_array == NULL)
return -EINVAL;
decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
if (decoder == NULL)
return -ENOMEM;
decoder->reset_pin = pin_array[0];
decoder->oe_pin = pin_array[1];
if (devm_gpio_request_one(&client->dev, decoder->reset_pin,
GPIOF_OUT_INIT_LOW, "ADV7183 Reset")) {
v4l_err(client, "failed to request GPIO %d\n", decoder->reset_pin);
return -EBUSY;
}
if (devm_gpio_request_one(&client->dev, decoder->oe_pin,
GPIOF_OUT_INIT_HIGH,
"ADV7183 Output Enable")) {
v4l_err(client, "failed to request GPIO %d\n", decoder->oe_pin);
return -EBUSY;
}
/*
* Requesting high will assert reset, the line should be
* flagged as active low in descriptor table or machine description.
*/
decoder->reset_pin = devm_gpiod_get(&client->dev, "reset",
GPIOD_OUT_HIGH);
if (IS_ERR(decoder->reset_pin))
return PTR_ERR(decoder->reset_pin);
gpiod_set_consumer_name(decoder->reset_pin, "ADV7183 Reset");
/*
* Requesting low will start with output disabled, the line should be
* flagged as active low in descriptor table or machine description.
*/
decoder->oe_pin = devm_gpiod_get(&client->dev, "oe",
GPIOD_OUT_LOW);
if (IS_ERR(decoder->oe_pin))
return PTR_ERR(decoder->oe_pin);
gpiod_set_consumer_name(decoder->reset_pin, "ADV7183 Output Enable");
sd = &decoder->sd;
v4l2_i2c_subdev_init(sd, client, &adv7183_ops);
@ -594,7 +592,8 @@ static int adv7183_probe(struct i2c_client *client,
/* reset chip */
/* reset pulse width at least 5ms */
mdelay(10);
gpio_set_value(decoder->reset_pin, 1);
/* De-assert reset line (descriptor tagged active low) */
gpiod_set_value(decoder->reset_pin, 0);
/* wait 5ms before any further i2c writes are performed */
mdelay(5);

View File

@ -17,7 +17,6 @@
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/videodev2.h>
#include <linux/gpio.h>
#include <linux/workqueue.h>
#include <linux/hdmi.h>
#include <linux/v4l2-dv-timings.h>

View File

@ -17,7 +17,6 @@
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/firmware.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>

View File

@ -11,13 +11,11 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_gpio.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>

1628
drivers/media/i2c/isl7998x.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -13,6 +13,7 @@
#define M5MOLS_H
#include <linux/sizes.h>
#include <linux/gpio/consumer.h>
#include <media/v4l2-subdev.h>
#include "m5mols_reg.h"
@ -224,6 +225,7 @@ struct m5mols_info {
struct v4l2_ctrl *jpeg_quality;
int (*set_power)(struct device *dev, int on);
struct gpio_desc *reset;
struct mutex lock;

View File

@ -15,7 +15,6 @@
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/regulator/consumer.h>
#include <linux/videodev2.h>
#include <media/v4l2-ctrls.h>

View File

@ -14,7 +14,7 @@
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/regulator/consumer.h>
#include <linux/videodev2.h>
#include <linux/module.h>
@ -752,7 +752,6 @@ static int m5mols_sensor_power(struct m5mols_info *info, bool enable)
{
struct v4l2_subdev *sd = &info->sd;
struct i2c_client *client = v4l2_get_subdevdata(sd);
const struct m5mols_platform_data *pdata = info->pdata;
int ret;
if (info->power == enable)
@ -772,7 +771,7 @@ static int m5mols_sensor_power(struct m5mols_info *info, bool enable)
return ret;
}
gpio_set_value(pdata->gpio_reset, !pdata->reset_polarity);
gpiod_set_value(info->reset, 0);
info->power = 1;
return ret;
@ -785,7 +784,7 @@ static int m5mols_sensor_power(struct m5mols_info *info, bool enable)
if (info->set_power)
info->set_power(&client->dev, 0);
gpio_set_value(pdata->gpio_reset, pdata->reset_polarity);
gpiod_set_value(info->reset, 1);
info->isp_ready = 0;
info->power = 0;
@ -944,7 +943,6 @@ static int m5mols_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
const struct m5mols_platform_data *pdata = client->dev.platform_data;
unsigned long gpio_flags;
struct m5mols_info *info;
struct v4l2_subdev *sd;
int ret;
@ -954,11 +952,6 @@ static int m5mols_probe(struct i2c_client *client,
return -EINVAL;
}
if (!gpio_is_valid(pdata->gpio_reset)) {
dev_err(&client->dev, "No valid RESET GPIO specified\n");
return -EINVAL;
}
if (!client->irq) {
dev_err(&client->dev, "Interrupt not assigned\n");
return -EINVAL;
@ -968,18 +961,16 @@ static int m5mols_probe(struct i2c_client *client,
if (!info)
return -ENOMEM;
/* This asserts reset, descriptor shall have polarity specified */
info->reset = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(info->reset))
return PTR_ERR(info->reset);
/* Notice: the "N" in M5MOLS_NRST implies active low */
gpiod_set_consumer_name(info->reset, "M5MOLS_NRST");
info->pdata = pdata;
info->set_power = pdata->set_power;
gpio_flags = pdata->reset_polarity
? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
ret = devm_gpio_request_one(&client->dev, pdata->gpio_reset, gpio_flags,
"M5MOLS_NRST");
if (ret) {
dev_err(&client->dev, "Failed to request gpio: %d\n", ret);
return ret;
}
ret = devm_regulator_bulk_get(&client->dev, ARRAY_SIZE(supplies),
supplies);
if (ret) {

View File

@ -9,7 +9,6 @@
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/log2.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/regulator/consumer.h>
#include <linux/v4l2-mediabus.h>

View File

@ -10,7 +10,7 @@
*/
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/regulator/consumer.h>
@ -130,8 +130,8 @@ struct noon010_info {
struct media_pad pad;
struct v4l2_ctrl_handler hdl;
struct regulator_bulk_data supply[NOON010_NUM_SUPPLIES];
u32 gpio_nreset;
u32 gpio_nstby;
struct gpio_desc *reset;
struct gpio_desc *stby;
/* Protects the struct members below */
struct mutex lock;
@ -393,29 +393,33 @@ static int power_enable(struct noon010_info *info)
return 0;
}
if (gpio_is_valid(info->gpio_nstby))
gpio_set_value(info->gpio_nstby, 0);
/* Assert standby: line should be flagged active low in descriptor */
if (info->stby)
gpiod_set_value(info->stby, 1);
if (gpio_is_valid(info->gpio_nreset))
gpio_set_value(info->gpio_nreset, 0);
/* Assert reset: line should be flagged active low in descriptor */
if (info->reset)
gpiod_set_value(info->reset, 1);
ret = regulator_bulk_enable(NOON010_NUM_SUPPLIES, info->supply);
if (ret)
return ret;
if (gpio_is_valid(info->gpio_nreset)) {
/* De-assert reset and standby */
if (info->reset) {
msleep(50);
gpio_set_value(info->gpio_nreset, 1);
gpiod_set_value(info->reset, 0);
}
if (gpio_is_valid(info->gpio_nstby)) {
if (info->stby) {
udelay(1000);
gpio_set_value(info->gpio_nstby, 1);
gpiod_set_value(info->stby, 0);
}
if (gpio_is_valid(info->gpio_nreset)) {
/* Cycle reset: assert and deassert */
if (info->reset) {
udelay(1000);
gpio_set_value(info->gpio_nreset, 0);
gpiod_set_value(info->reset, 1);
msleep(100);
gpio_set_value(info->gpio_nreset, 1);
gpiod_set_value(info->reset, 0);
msleep(20);
}
info->power = 1;
@ -438,11 +442,12 @@ static int power_disable(struct noon010_info *info)
if (ret)
return ret;
if (gpio_is_valid(info->gpio_nstby))
gpio_set_value(info->gpio_nstby, 0);
/* Assert standby and reset */
if (info->stby)
gpiod_set_value(info->stby, 1);
if (gpio_is_valid(info->gpio_nreset))
gpio_set_value(info->gpio_nreset, 0);
if (info->reset)
gpiod_set_value(info->reset, 1);
info->power = 0;
@ -741,34 +746,24 @@ static int noon010_probe(struct i2c_client *client,
goto np_err;
info->i2c_reg_page = -1;
info->gpio_nreset = -EINVAL;
info->gpio_nstby = -EINVAL;
info->curr_fmt = &noon010_formats[0];
info->curr_win = &noon010_sizes[0];
if (gpio_is_valid(pdata->gpio_nreset)) {
ret = devm_gpio_request_one(&client->dev, pdata->gpio_nreset,
GPIOF_OUT_INIT_LOW,
"NOON010PC30 NRST");
if (ret) {
dev_err(&client->dev, "GPIO request error: %d\n", ret);
goto np_err;
}
info->gpio_nreset = pdata->gpio_nreset;
gpio_export(info->gpio_nreset, 0);
/* Request reset asserted so we get put into reset */
info->reset = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(info->reset)) {
ret = PTR_ERR(info->reset);
goto np_err;
}
gpiod_set_consumer_name(info->reset, "NOON010PC30 NRST");
if (gpio_is_valid(pdata->gpio_nstby)) {
ret = devm_gpio_request_one(&client->dev, pdata->gpio_nstby,
GPIOF_OUT_INIT_LOW,
"NOON010PC30 NSTBY");
if (ret) {
dev_err(&client->dev, "GPIO request error: %d\n", ret);
goto np_err;
}
info->gpio_nstby = pdata->gpio_nstby;
gpio_export(info->gpio_nstby, 0);
/* Request standby asserted so we get put into standby */
info->stby = devm_gpiod_get(&client->dev, "standby", GPIOD_OUT_HIGH);
if (IS_ERR(info->stby)) {
ret = PTR_ERR(info->stby);
goto np_err;
}
gpiod_set_consumer_name(info->reset, "NOON010PC30 STBY");
for (i = 0; i < NOON010_NUM_SUPPLIES; i++)
info->supply[i].supply = noon010_supply_name[i];

1128
drivers/media/i2c/og01a1b.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -2293,7 +2293,6 @@ static int ov5640_set_fmt(struct v4l2_subdev *sd,
struct ov5640_dev *sensor = to_ov5640_dev(sd);
const struct ov5640_mode_info *new_mode;
struct v4l2_mbus_framefmt *mbus_fmt = &format->format;
struct v4l2_mbus_framefmt *fmt;
int ret;
if (format->pad != 0)
@ -2311,12 +2310,10 @@ static int ov5640_set_fmt(struct v4l2_subdev *sd,
if (ret)
goto out;
if (format->which == V4L2_SUBDEV_FORMAT_TRY)
fmt = v4l2_subdev_get_try_format(sd, sd_state, 0);
else
fmt = &sensor->fmt;
*fmt = *mbus_fmt;
if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
*v4l2_subdev_get_try_format(sd, sd_state, 0) = *mbus_fmt;
goto out;
}
if (new_mode != sensor->current_mode) {
sensor->current_mode = new_mode;
@ -2325,6 +2322,9 @@ static int ov5640_set_fmt(struct v4l2_subdev *sd,
if (mbus_fmt->code != sensor->fmt.code)
sensor->pending_fmt_change = true;
/* update format even if code is unchanged, resolution might change */
sensor->fmt = *mbus_fmt;
__v4l2_ctrl_s_ctrl_int64(sensor->ctrls.pixel_rate,
ov5640_calc_pixel_rate(sensor));
out:

View File

@ -1778,8 +1778,14 @@ static int ov5648_state_configure(struct ov5648_sensor *sensor,
static int ov5648_state_init(struct ov5648_sensor *sensor)
{
return ov5648_state_configure(sensor, &ov5648_modes[0],
ov5648_mbus_codes[0]);
int ret;
mutex_lock(&sensor->mutex);
ret = ov5648_state_configure(sensor, &ov5648_modes[0],
ov5648_mbus_codes[0]);
mutex_unlock(&sensor->mutex);
return ret;
}
/* Sensor Base */

View File

@ -457,8 +457,8 @@
#define OV8865_NATIVE_WIDTH 3296
#define OV8865_NATIVE_HEIGHT 2528
#define OV8865_ACTIVE_START_TOP 32
#define OV8865_ACTIVE_START_LEFT 80
#define OV8865_ACTIVE_START_LEFT 16
#define OV8865_ACTIVE_START_TOP 40
#define OV8865_ACTIVE_WIDTH 3264
#define OV8865_ACTIVE_HEIGHT 2448

View File

@ -396,20 +396,21 @@ __must_check int __media_pipeline_start(struct media_entity *entity,
struct media_link *link;
int ret;
if (!pipe->streaming_count++) {
ret = media_graph_walk_init(&pipe->graph, mdev);
if (ret)
goto error_graph_walk_start;
if (pipe->streaming_count) {
pipe->streaming_count++;
return 0;
}
ret = media_graph_walk_init(&pipe->graph, mdev);
if (ret)
return ret;
media_graph_walk_start(&pipe->graph, entity);
while ((entity = media_graph_walk_next(graph))) {
DECLARE_BITMAP(active, MEDIA_ENTITY_MAX_PADS);
DECLARE_BITMAP(has_no_links, MEDIA_ENTITY_MAX_PADS);
entity->stream_count++;
if (entity->pipe && entity->pipe != pipe) {
pr_err("Pipe active for %s. Can't start for %s\n",
entity->name,
@ -418,12 +419,12 @@ __must_check int __media_pipeline_start(struct media_entity *entity,
goto error;
}
entity->pipe = pipe;
/* Already streaming --- no need to check. */
if (entity->stream_count > 1)
if (entity->pipe)
continue;
entity->pipe = pipe;
if (!entity->ops || !entity->ops->link_validate)
continue;
@ -479,6 +480,8 @@ __must_check int __media_pipeline_start(struct media_entity *entity,
}
}
pipe->streaming_count++;
return 0;
error:
@ -489,24 +492,17 @@ error:
media_graph_walk_start(graph, entity_err);
while ((entity_err = media_graph_walk_next(graph))) {
/* Sanity check for negative stream_count */
if (!WARN_ON_ONCE(entity_err->stream_count <= 0)) {
entity_err->stream_count--;
if (entity_err->stream_count == 0)
entity_err->pipe = NULL;
}
entity_err->pipe = NULL;
/*
* We haven't increased stream_count further than this
* so we quit here.
* We haven't started entities further than this so we quit
* here.
*/
if (entity_err == entity)
break;
}
error_graph_walk_start:
if (!--pipe->streaming_count)
media_graph_walk_cleanup(graph);
media_graph_walk_cleanup(graph);
return ret;
}
@ -537,19 +533,15 @@ void __media_pipeline_stop(struct media_entity *entity)
if (WARN_ON(!pipe))
return;
if (--pipe->streaming_count)
return;
media_graph_walk_start(graph, entity);
while ((entity = media_graph_walk_next(graph))) {
/* Sanity check for negative stream_count */
if (!WARN_ON_ONCE(entity->stream_count <= 0)) {
entity->stream_count--;
if (entity->stream_count == 0)
entity->pipe = NULL;
}
}
while ((entity = media_graph_walk_next(graph)))
entity->pipe = NULL;
if (!--pipe->streaming_count)
media_graph_walk_cleanup(graph);
media_graph_walk_cleanup(graph);
}
EXPORT_SYMBOL_GPL(__media_pipeline_stop);
@ -834,7 +826,8 @@ int __media_entity_setup_link(struct media_link *link, u32 flags)
sink = link->sink->entity;
if (!(link->flags & MEDIA_LNK_FL_DYNAMIC) &&
(source->stream_count || sink->stream_count))
(media_entity_is_streaming(source) ||
media_entity_is_streaming(sink)))
return -EBUSY;
mdev = source->graph_obj.mdev;

View File

@ -10,7 +10,10 @@
#include <media/drv-intf/exynos-fimc.h>
#include "common.h"
/* Called with the media graph mutex held or entity->stream_count > 0. */
/*
* Called with the media graph mutex held or media_entity_is_streaming(entity)
* true.
*/
struct v4l2_subdev *fimc_find_remote_sensor(struct media_entity *entity)
{
struct media_pad *pad = &entity->pads[0];

View File

@ -226,7 +226,7 @@ static int fimc_isp_subdev_set_fmt(struct v4l2_subdev *sd,
}
}
} else {
if (sd->entity.stream_count == 0) {
if (!media_entity_is_streaming(&sd->entity)) {
if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
struct v4l2_subdev_format format = *fmt;

View File

@ -1073,7 +1073,7 @@ static int fimc_lite_subdev_set_fmt(struct v4l2_subdev *sd,
mutex_lock(&fimc->lock);
if ((atomic_read(&fimc->out_path) == FIMC_IO_ISP &&
sd->entity.stream_count > 0) ||
media_entity_is_streaming(&sd->entity)) ||
(atomic_read(&fimc->out_path) == FIMC_IO_DMA &&
vb2_is_busy(&fimc->vb_queue))) {
mutex_unlock(&fimc->lock);
@ -1197,8 +1197,8 @@ static int fimc_lite_subdev_s_stream(struct v4l2_subdev *sd, int on)
* Find sensor subdev linked to FIMC-LITE directly or through
* MIPI-CSIS. This is required for configuration where FIMC-LITE
* is used as a subdev only and feeds data internally to FIMC-IS.
* The pipeline links are protected through entity.stream_count
* so there is no need to take the media graph mutex here.
* The pipeline links are protected through entity.pipe so there is no
* need to take the media graph mutex here.
*/
fimc->sensor = fimc_find_remote_sensor(&sd->entity);

View File

@ -793,7 +793,7 @@ static int rvin_csi2_link_notify(struct media_link *link, u32 flags,
* running streams.
*/
media_device_for_each_entity(entity, &group->mdev)
if (entity->stream_count)
if (media_entity_is_streaming(entity))
return -EBUSY;
/* Find the master VIN that controls the routes. */

View File

@ -894,25 +894,8 @@ static int v4l2_fwnode_reference_parse(struct device *dev,
int ret;
for (index = 0;
!(ret = fwnode_property_get_reference_args(dev_fwnode(dev),
prop, NULL, 0,
index, &args));
index++)
fwnode_handle_put(args.fwnode);
if (!index)
return -ENOENT;
/*
* Note that right now both -ENODATA and -ENOENT may signal
* out-of-bounds access. Return the error in cases other than that.
*/
if (ret != -ENOENT && ret != -ENODATA)
return ret;
for (index = 0;
!fwnode_property_get_reference_args(dev_fwnode(dev), prop, NULL,
0, index, &args);
!(ret = fwnode_property_get_reference_args(dev_fwnode(dev), prop,
NULL, 0, index, &args));
index++) {
struct v4l2_async_subdev *asd;
@ -928,7 +911,12 @@ static int v4l2_fwnode_reference_parse(struct device *dev,
}
}
return 0;
/* -ENOENT here means successful parsing */
if (ret != -ENOENT)
return ret;
/* Return -ENOENT if no references were found */
return index ? 0 : -ENOENT;
}
/*

View File

@ -14,15 +14,11 @@
/**
* struct m5mols_platform_data - platform data for M-5MOLS driver
* @gpio_reset: GPIO driving the reset pin of M-5MOLS
* @reset_polarity: active state for gpio_reset pin, 0 or 1
* @set_power: an additional callback to the board setup code
* to be called after enabling and before disabling
* the sensor's supply regulators
*/
struct m5mols_platform_data {
int gpio_reset;
u8 reset_polarity;
int (*set_power)(struct device *dev, int on);
};

View File

@ -12,14 +12,10 @@
/**
* struct noon010pc30_platform_data - platform data
* @clk_rate: the clock frequency in Hz
* @gpio_nreset: GPIO driving nRESET pin
* @gpio_nstby: GPIO driving nSTBY pin
*/
struct noon010pc30_platform_data {
unsigned long clk_rate;
int gpio_nreset;
int gpio_nstby;
};
#endif /* NOON010PC30_H */

View File

@ -268,7 +268,6 @@ enum media_entity_type {
* @pads: Pads array with the size defined by @num_pads.
* @links: List of data links.
* @ops: Entity operations.
* @stream_count: Stream count for the entity.
* @use_count: Use count for the entity.
* @pipe: Pipeline this entity belongs to.
* @info: Union with devnode information. Kept just for backward
@ -283,10 +282,9 @@ enum media_entity_type {
*
* .. note::
*
* @stream_count and @use_count reference counts must never be
* negative, but are signed integers on purpose: a simple ``WARN_ON(<0)``
* check can be used to detect reference count bugs that would make them
* negative.
* The @use_count reference count must never be negative, but is a signed
* integer on purpose: a simple ``WARN_ON(<0)`` check can be used to detect
* reference count bugs that would make it negative.
*/
struct media_entity {
struct media_gobj graph_obj; /* must be first field in struct */
@ -305,7 +303,6 @@ struct media_entity {
const struct media_entity_operations *ops;
int stream_count;
int use_count;
struct media_pipeline *pipe;
@ -657,6 +654,10 @@ int media_entity_pads_init(struct media_entity *entity, u16 num_pads,
*
* This function must be called during the cleanup phase after unregistering
* the entity (currently, it does nothing).
*
* Calling media_entity_cleanup() on a media_entity whose memory has been
* zeroed but that has not been initialized with media_entity_pad_init() is
* valid and is a no-op.
*/
#if IS_ENABLED(CONFIG_MEDIA_CONTROLLER)
static inline void media_entity_cleanup(struct media_entity *entity) {}
@ -858,6 +859,18 @@ struct media_link *media_entity_find_link(struct media_pad *source,
*/
struct media_pad *media_entity_remote_pad(const struct media_pad *pad);
/**
* media_entity_is_streaming - Test if an entity is part of a streaming pipeline
* @entity: The entity
*
* Return: True if the entity is part of a pipeline started with the
* media_pipeline_start() function, false otherwise.
*/
static inline bool media_entity_is_streaming(const struct media_entity *entity)
{
return entity->pipe;
}
/**
* media_entity_get_fwnode_pad - Get pad number from fwnode
*

View File

@ -219,6 +219,12 @@ enum v4l2_colorfx {
*/
#define V4L2_CID_USER_ALLEGRO_BASE (V4L2_CID_USER_BASE + 0x1170)
/*
* The base for the isl7998x driver controls.
* We reserve 16 controls for this driver.
*/
#define V4L2_CID_USER_ISL7998X_BASE (V4L2_CID_USER_BASE + 0x1180)
/* MPEG-class control IDs */
/* The MPEG controls are applicable to all codec controls
* and the 'MPEG' part of the define is historical */