On 28/04/26 00:53, Shenwei Wang wrote:
[...]
>>> +
>>> +struct rpmsg_gpio_packet {
>>> + u8 type; /* Message type */
>>> + u8 cmd; /* Command code */
>>> + u8 port_idx;
>>> + u8 line;
>>> + u8 val1;
>>> + u8 val2;
>>> +};
>>
>> Could you please document the fields in these structs (and the below ones
>> too)?
>> From the code, it looks like while sending a message from Linux to Firmware;
>> val1
>> and val2 are used to describe the values to set. Whereas while receiving a
>> response, val1 represents a possible error code, and val2 represents the
>> actual
>> message of get type queries. If that is so, you might want to change the
>> variable
>> names to be more descriptive and also use a union.
>>
> The fields in the two structs are fairly self-explanatory. Do we really need
> the additional comments?
val1 and val2 sounded arbitrary, that's all. If we are moving away from
that, then there is no need :)
[...]
>
>>> + void *channel_devices[MAX_PORT_PER_CHANNEL];
>>
>> So this is technically a rpmsg endpoint (struct rpmsg_endpoint) without
>> naming it
>> "endpoint". Every rpmsg endpoint has a reference to its parent rpmsg channel
>> (struct rpmsg_device) which represents the same information here. So we
>> should
>> use the framework standard here.
>>
> Yes, agree to use "endpoint_devices".
I did not mean to say to just change the variable name from
"channel_devices" to "endpoint_devices". Infact you would not need to
have this field & struct anymore.
Pseudo-code:
1. Add a 'struct rpmsg_endpoint *ept' field to struct rpmsg_gpio_port
to maintain the ept to port idx map.
2. Call port->ept = rpmsg_create_ept(rpdev,
rpmsg_gpio_channel_callback,
port,
{rpdev.id.name,
RPMSG_ADDR_ANY,
RPMSG_ADDR_ANY})
from rpmsg_gpiochip_register().
3. Send msgs from local ept in rpmsg_gpio_send_message() by:
rpmsg_send(port->ept, msg, sizeof(*msg));
4. Get the port info in rpmsg_gpio_channel_callback() by:
struct rpmsg_gpio_port *port = priv;
Which also eliminates the need for struct rpdev_drvdata as you can just
do rpmsg_get_rproc_node_name(rpdev) from rpmsg_gpiochip_register().
>
>> This also allows for dynamic creation and deletion of ports too! (if/when the
>> firmware supports it)
>>
>> Which means at port init time, we should make a call to
>> rpmsg_create_ept() for each port tying the same callback
>> rpmsg_gpio_channel_callback(). And based on the 'u32 src', we could identify
>> the
>> appropriate gpio port in the callback.
>>
[...]
>>
>>> +
>>> + girq = &gc->irq;
>>> + gpio_irq_chip_set_chip(girq, &gpio_rpmsg_irq_chip);
>>> + girq->parent_handler = NULL;
>>> + girq->num_parents = 0;
>>> + girq->parents = NULL;
>>> + girq->chip->name = devm_kasprintf(&rpdev->dev, GFP_KERNEL, "%s-
>> gpio%d",
>>> + drvdata->rproc_name,
>>> + port->idx);
>>
>> We could just re-use gc->label here...
> We also want to include the remoteproc name (for example,
> remoteproc-cm33-gpio0), rather than just gpio0.
Isn't it also included in the gc->label field?
gc->label = devm_kasprintf(&rpdev->dev, GFP_KERNEL, "%s-gpio%d",
+ drvdata->rproc_name, port->idx);
[...]
>>> +}
>>> +
>>> +static int rpmsg_gpio_channel_probe(struct rpmsg_device *rpdev) {
>>> + struct device *dev = &rpdev->dev;
>>> + struct rpdev_drvdata *drvdata;
>>> + struct device_node *np;
>>> + int ret = -ENODEV;
>>> +
>>> + if (!dev->of_node) {
>>> + np = rpmsg_get_channel_ofnode(rpdev, rpdev->id.name);
>>> + if (np) {
>>> + dev->of_node = np;
>>> + set_primary_fwnode(dev, of_fwnode_handle(np));
>>> + }
>>> + return -EPROBE_DEFER;
>>
>> I know this was asked in the v10 version also. But I don't think the answer
>> is
>> sufficient. Should we not continue the intialization of drvdata etc if np !=
>> 0? Why
>> return a deferred probe, and let the kernel come back to it again to do the
>> same
>> stuff with extra latency?
>>
>> We could just do:
>> if (!np) return -EPROBE_DEFER;
>> else {everything_else};
>>
> After configuring dev->of_node, it would be better to restart the driver
> probe process.
> This ensures that all required resources, such as pinctrl, clocks, and power
> domains, are
> properly set up if they are specified in the device node, before the probe
> function is invoked.
Hmm that makes sense to me... Thanks!
Thanks,
Beleswar