Re: [RFC PATCH v3 9/9] ipu3-cio2: Add functionality allowing software_node connections to sensors on platforms designed for Windows

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

 



On 24/10/2020 16:14, Sakari Ailus wrote:
> Hi Daniel,
>
> Thanks for the update.
Thanks for the comments as always
>> +// SPDX-License-Identifier: GPL-2.0
>> +// Author: Dan Scally <djrscally@xxxxxxxxx>
> /* Author: ... */
>
> But not the SPDX tag.
Weird - okedokey
>> +#include <linux/acpi.h>
>> +#include <linux/device.h>
>> +#include <linux/fwnode.h>
>> +#include <linux/i2c.h>
>> +#include <linux/kernel.h>
>> +#include <linux/module.h>
>> +#include <linux/pci.h>
>> +#include <linux/property.h>
>> +#include <media/v4l2-subdev.h>
>> +
>> +#include "cio2-bridge.h"
>> +
>> +/*
>> + * Extend this array with ACPI Hardware ID's of devices known to be
>> + * working
>> + */
>> +static const char * const supported_devices[] = {
>> +	"INT33BE",
>> +	"OVTI2680",
>> +};
>> +
>> +static struct software_node cio2_hid_node = { CIO2_HID };
>> +
>> +static struct cio2_bridge bridge;
>> +
>> +static const char * const port_names[] = {
>> +	"port0", "port1", "port2", "port3"
>> +};
>> +
>> +static const struct property_entry remote_endpoints[] = {
> How about another dimension, for local and remote? Or make it a struct with
> local and remote fields. Perhaps a struct would be better?
>
> This could also be nicer to initialise in a function.
Sure; a struct probably would be cleaner I agree. I shall make that change
>> +static int create_fwnode_properties(struct sensor *sensor,
>> +				    struct sensor_bios_data *ssdb)
>> +{
>> +	struct property_entry *cio2_properties = sensor->cio2_properties;
>> +	struct property_entry *dev_properties = sensor->dev_properties;
>> +	struct property_entry *ep_properties = sensor->ep_properties;
>> +	int i;
>> +
>> +	/* device fwnode properties */
>> +	memset(dev_properties, 0, sizeof(struct property_entry) * 3);
> I'd put them all to the struct itself. Then the compiler will be able to
> check array indices.
Makes sense; I think I was just trying to save line length in the rest
of that function by that.
>> +
>> +	dev_properties[0] = PROPERTY_ENTRY_U32("clock-frequency",
>> +					       ssdb->mclkspeed);
>> +	dev_properties[1] = PROPERTY_ENTRY_U8("rotation", ssdb->degree);
>> +
>> +	/* endpoint fwnode properties */
>> +	memset(ep_properties, 0, sizeof(struct property_entry) * 4);
>> +
>> +	sensor->data_lanes = kmalloc_array(ssdb->lanes, sizeof(u32),
>> +					   GFP_KERNEL);
>> +
>> +	if (!sensor->data_lanes)
>> +		return -ENOMEM;
>> +
>> +	for (i = 0; i < ssdb->lanes; i++)
>> +		sensor->data_lanes[i] = i + 1;
>> +
>> +	ep_properties[0] = PROPERTY_ENTRY_U32("bus-type", 5);
>> +	ep_properties[1] = PROPERTY_ENTRY_U32_ARRAY_LEN("data-lanes",
>> +							sensor->data_lanes,
>> +							ssdb->lanes);
>> +	ep_properties[2] = remote_endpoints[(bridge.n_sensors * 2) + ENDPOINT_SENSOR];
>> +
>> +	/* cio2 endpoint props */
>> +	memset(cio2_properties, 0, sizeof(struct property_entry) * 3);
>> +
>> +	cio2_properties[0] = PROPERTY_ENTRY_U32_ARRAY_LEN("data-lanes",
>> +							  sensor->data_lanes,
>> +							  ssdb->lanes);
>> +	cio2_properties[1] = remote_endpoints[(bridge.n_sensors * 2) + ENDPOINT_CIO2];
>> +
>> +	return 0;
>> +}
>> +
>> +static int create_connection_swnodes(struct sensor *sensor,
>> +				     struct sensor_bios_data *ssdb)
>> +{
>> +	struct software_node *nodes = sensor->swnodes;
>> +
>> +	memset(nodes, 0, sizeof(struct software_node) * 6);
> Could you make the index an enum, and add an item to the end used to tell
> the number of entries. It could be called e.g. NR_OF_SENSOR_SWNODES.
Ooh I like that, it's neat; thanks - will do.
>> +int cio2_bridge_build(struct pci_dev *cio2)
>> +{
>> +	struct fwnode_handle *fwnode;
>> +	int ret;
>> +
>> +	pci_dev_get(cio2);
> Could you check that this isn't used by more than one user? The current
> implementation assumes that. I'm not sure if there could be more instances
> of CIO2 but if there were, that'd be an issue currently.

I can check; can't think of anything better than just failing out if it
turns out to be in use already though - any ideas or is that appropriate?

>> +struct sensor {
> How about calling this e.g. cio2_sensor? sensor is rather generic.
Yup, will probably prefix all such generically named vars with cio2_*
and functions with cio2_bridge_*().
>> +	char name[ACPI_ID_LEN];
>> +	struct device *dev;
>> +	struct acpi_device *adev;
>> +	struct software_node swnodes[6];
>> +	struct property_entry dev_properties[3];
>> +	struct property_entry ep_properties[4];
>> +	struct property_entry cio2_properties[3];
>> +	u32 *data_lanes;
> The maximum is four so you could as well make this static.
Ack
>> +};
>> +
>> +struct cio2_bridge {
>> +	int n_sensors;
> Do you need negative values? %u, too, if not.
I do not, I will switch to using unsigned.
>> diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
>> index f68ef0f6b..827457110 100644
>> --- a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
>> +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
>> @@ -1715,9 +1715,27 @@ static void cio2_queues_exit(struct cio2_device *cio2)
>>  static int cio2_pci_probe(struct pci_dev *pci_dev,
>>  			  const struct pci_device_id *id)
>>  {
>> +	struct fwnode_handle *endpoint;
>>  	struct cio2_device *cio2;
>>  	int r;
>>  
>> +	/*
>> +	 * 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.
>> +	 *
>> +	 * This may EPROBE_DEFER if supported devices are found defined in ACPI
>> +	 * but not yet ready for use (either not attached to the i2c bus yet,
>> +	 * or not done probing themselves).
>> +	 */
>> +
>> +	endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(&pci_dev->dev), NULL);
>> +	if (!endpoint) {
>> +		r = cio2_bridge_build(pci_dev);
>> +		if (r)
>> +			return r;
>> +	}
> } else {
> 	fwnode_handle_put(endpoint);
> }
Ah, of course, thank you.



[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