Re: [PATCH v4 15/15] ipu3-cio2: Add cio2-bridge to ipu3-cio2 driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Andy

On 04/01/2021 12:09, Andy Shevchenko wrote:
> On Sun, Jan 03, 2021 at 11:12:35PM +0000, Daniel Scally wrote:
>> Currently on platforms designed for Windows, connections between CIO2 and
>> sensors are not properly defined in DSDT. This patch extends the ipu3-cio2
>> driver to compensate by building software_node connections, parsing the
>> connection properties from the sensor's SSDB buffer.
> Few nitpicks below (I consider it's good enough as is, though).
Thanks!
>> +static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
>> +				      struct cio2_bridge *bridge,
>> +				      struct pci_dev *cio2)
>> +{
>> +	struct fwnode_handle *fwnode;
>> +	struct cio2_sensor *sensor;
>> +	struct acpi_device *adev;
>> +	int ret;
>> +	for_each_acpi_dev_match(adev, cfg->hid, NULL, -1) {
> (1)
>
>> +		if (bridge->n_sensors >= CIO2_NUM_PORTS) {
>> +			dev_err(&cio2->dev, "Exceeded available CIO2 ports\n");
>> +			cio2_bridge_unregister_sensors(bridge);
>> +			ret = -EINVAL;
>> +			goto err_out;
>> +		}
>> +		if (!adev->status.enabled)
>> +			continue;
> A nit: this would be better to be at (1) location.


Yep, agreed

>
> Then possible to factor out the rest of the body of this loop as well.
>
> (Also can be considered as a hint for the future improvement)
Yeah I can look at this, there will probably be some future changes
anyway as we discover more details about the data in the SSDB buffer and
so on
> diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.h b/drivers/media/pci/intel/ipu3/cio2-bridge.h
> new file mode 100644
> index 000000000000..3ec4ed44aced
> --- /dev/null
> +++ b/drivers/media/pci/intel/ipu3/cio2-bridge.h
> @@ -0,0 +1,125 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/* Author: Dan Scally <djrscally@xxxxxxxxx> */
> +#ifndef __CIO2_BRIDGE_H
> +#define __CIO2_BRIDGE_H
> +
> +#include <linux/property.h>
> +#include <linux/types.h>
> +
> +#include "ipu3-cio2.h"
> +
> +#define CIO2_HID				"INT343E"
> +#define CIO2_MAX_LANES				4
> +#define MAX_NUM_LINK_FREQS			3
> +
> +#define CIO2_SENSOR_CONFIG(_HID, _NR, ...)	\
> +	{					\
> +		.hid = _HID,			\
> +		.nr_link_freqs = _NR,		\
> +		.link_freqs = { __VA_ARGS__ }	\
> +	}
> Perhaps also good to declare it as a compound literal.
>
> (Means to add (struct ...) to the initializer.
>
Yep ok
>> +#define NODE_SENSOR(_HID, _PROPS)		\
>> +	((const struct software_node) {		\
>> +		.name = _HID,			\
>> +		.properties = _PROPS,		\
>> +	})
>> +
>> +#define NODE_PORT(_PORT, _SENSOR_NODE)		\
>> +	((const struct software_node) {		\
>> +		.name = _PORT,			\
>> +		.parent = _SENSOR_NODE,		\
>> +	})
>> +
>> +#define NODE_ENDPOINT(_EP, _PORT, _PROPS)	\
>> +	((const struct software_node) {		\
>> +		.name = _EP,			\
>> +		.parent = _PORT,		\
>> +		.properties = _PROPS,		\
>> +	})
> In all three I didn't get why you need outer parentheses. Without them it will
> be well defined compound literal and should work as is.
The code works fine, but checkpatch complains that macros with complex
values should be enclosed in parentheses. I guess now that I'm more
familiar with the code I'd call that a false-positive though, as nowhere
else in the kernel that I've seen encloses them the same way.
>>  static int cio2_pci_probe(struct pci_dev *pci_dev,
>>  			  const struct pci_device_id *id)
>>  {
>> +	struct fwnode_handle *fwnode = dev_fwnode(&pci_dev->dev);
>>  	struct cio2_device *cio2;
>>  	int r;
>>  
>> @@ -1715,6 +1732,22 @@ static int cio2_pci_probe(struct pci_dev *pci_dev,
>>  		return -ENOMEM;
>>  	cio2->pci_dev = pci_dev;
>>  
>> +	/*
>> +	 * On some platforms no connections to sensors are defined in firmware,
>> +	 * if the device has no endpoints then we can try to build those as
>> +	 * software_nodes parsed from SSDB.
>> +	 */
>> +	if (!cio2_check_fwnode_graph(fwnode)) {
> A nit:
> I prefer form of
>
> 	r = cio2_check_fwnode_graph(fwnode);
> 	if (!r) { // alternatively if (r == 0), depends on maintainer's taste
This is fine by me; I can switch to that
>
>> +		if (fwnode && !IS_ERR_OR_NULL(fwnode->secondary)) {
>> +			dev_err(&pci_dev->dev, "fwnode graph has no endpoints connected\n");
>> +			return -EINVAL;
>> +		}
>> +
>> +		r = cio2_bridge_init(pci_dev);
>> +		if (r)
>> +			return r;
>> +	}
>> +
>>  	r = pcim_enable_device(pci_dev);
>>  	if (r) {
>>  		dev_err(&pci_dev->dev, "failed to enable device (%d)\n", r);
>> diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.h b/drivers/media/pci/intel/ipu3/ipu3-cio2.h
>> index 62187ab5ae43..dc3e343a37fb 100644
>> --- a/drivers/media/pci/intel/ipu3/ipu3-cio2.h
>> +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.h
>> @@ -455,4 +455,10 @@ static inline struct cio2_queue *vb2q_to_cio2_queue(struct vb2_queue *vq)
>>  	return container_of(vq, struct cio2_queue, vbq);
>>  }
>>  
>> +#if IS_ENABLED(CONFIG_CIO2_BRIDGE)
>> +int cio2_bridge_init(struct pci_dev *cio2);
>> +#else
>> +int cio2_bridge_init(struct pci_dev *cio2) { return 0; }
> static inline?

Ah, yes - thanks. Hadn't read about inline until now




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux