Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

media: v4l: async: Also match secondary fwnode endpoints

For camera sensor devices the firmware information of which comes from
non-DT (or some ACPI variants), the kernel makes the information visible
to the drivers in a form similar to DT. This takes place through device's
secondary fwnodes, in which case also the secondary fwnode needs to be
heterogenously (endpoint vs. device) matched.

Fixes: 1f391df44607 ("media: v4l2-async: Use endpoints in __v4l2_async_nf_add_fwnode_remote()")
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>

authored by

Sakari Ailus and committed by
Mauro Carvalho Chehab
46347e3e e670f5d6

+21 -14
+21 -14
drivers/media/v4l2-core/v4l2-async.c
··· 66 66 #endif 67 67 } 68 68 69 - static bool match_fwnode(struct v4l2_async_notifier *notifier, 70 - struct v4l2_subdev *sd, struct v4l2_async_subdev *asd) 69 + static bool 70 + match_fwnode_one(struct v4l2_async_notifier *notifier, 71 + struct v4l2_subdev *sd, struct fwnode_handle *sd_fwnode, 72 + struct v4l2_async_subdev *asd) 71 73 { 72 74 struct fwnode_handle *other_fwnode; 73 75 struct fwnode_handle *dev_fwnode; ··· 82 80 * fwnode or a device fwnode. Start with the simple case of direct 83 81 * fwnode matching. 84 82 */ 85 - if (sd->fwnode == asd->match.fwnode) 86 - return true; 87 - 88 - /* 89 - * Check the same situation for any possible secondary assigned to the 90 - * subdev's fwnode 91 - */ 92 - if (!IS_ERR_OR_NULL(sd->fwnode->secondary) && 93 - sd->fwnode->secondary == asd->match.fwnode) 83 + if (sd_fwnode == asd->match.fwnode) 94 84 return true; 95 85 96 86 /* ··· 93 99 * ACPI. This won't make a difference, as drivers should not try to 94 100 * match unconnected endpoints. 95 101 */ 96 - sd_fwnode_is_ep = fwnode_graph_is_endpoint(sd->fwnode); 102 + sd_fwnode_is_ep = fwnode_graph_is_endpoint(sd_fwnode); 97 103 asd_fwnode_is_ep = fwnode_graph_is_endpoint(asd->match.fwnode); 98 104 99 105 if (sd_fwnode_is_ep == asd_fwnode_is_ep) ··· 104 110 * parent of the endpoint fwnode, and compare it with the other fwnode. 105 111 */ 106 112 if (sd_fwnode_is_ep) { 107 - dev_fwnode = fwnode_graph_get_port_parent(sd->fwnode); 113 + dev_fwnode = fwnode_graph_get_port_parent(sd_fwnode); 108 114 other_fwnode = asd->match.fwnode; 109 115 } else { 110 116 dev_fwnode = fwnode_graph_get_port_parent(asd->match.fwnode); 111 - other_fwnode = sd->fwnode; 117 + other_fwnode = sd_fwnode; 112 118 } 113 119 114 120 fwnode_handle_put(dev_fwnode); ··· 135 141 } 136 142 137 143 return true; 144 + } 145 + 146 + static bool match_fwnode(struct v4l2_async_notifier *notifier, 147 + struct v4l2_subdev *sd, struct v4l2_async_subdev *asd) 148 + { 149 + if (match_fwnode_one(notifier, sd, sd->fwnode, asd)) 150 + return true; 151 + 152 + /* Also check the secondary fwnode. */ 153 + if (IS_ERR_OR_NULL(sd->fwnode->secondary)) 154 + return false; 155 + 156 + return match_fwnode_one(notifier, sd, sd->fwnode->secondary, asd); 138 157 } 139 158 140 159 static LIST_HEAD(subdev_list);