Skip to content

Commit b61aebb

Browse files
committed
jesd204: jesd204-core: Support for dynamic dt changes
This adds support for loading dt overlays including a jesd204-devices. The requirement for this to work is that the base devicetree doesn't define any jesd204-devices. Also overlay removal are currently not supported. Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
1 parent bc4a82e commit b61aebb

File tree

1 file changed

+87
-1
lines changed

1 file changed

+87
-1
lines changed

drivers/jesd204/jesd204-core.c

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ static unsigned int jesd204_device_count;
3030
static unsigned int jesd204_topologies_count;
3131

3232
static unsigned int jesd204_con_id_counter;
33+
static bool jesd204_dyn_dt_change;
3334

3435
static void jesd204_dev_unregister(struct jesd204_dev *jdev);
3536

@@ -934,11 +935,14 @@ static struct jesd204_dev *jesd204_dev_register(struct device *dev,
934935
}
935936

936937
jdev = jesd204_dev_find_by_of_node(dev->of_node);
937-
if (!jdev) {
938+
if (!jdev && !jesd204_dyn_dt_change) {
938939
dev_err(dev, "Device has no configuration node\n");
939940
return ERR_PTR(-ENODEV);
940941
}
941942

943+
if (!jdev)
944+
return ERR_PTR(-EPROBE_DEFER);
945+
942946
ret = jesd204_dev_init_links_data(dev, jdev, init);
943947
if (ret)
944948
return ERR_PTR(ret);
@@ -1068,6 +1072,83 @@ struct jesd204_dev *devm_jesd204_dev_register(struct device *dev,
10681072
}
10691073
EXPORT_SYMBOL_GPL(devm_jesd204_dev_register);
10701074

1075+
1076+
static int jesd204_overlay_has_device(struct device_node *node)
1077+
{
1078+
struct device_node *dn;
1079+
int i = 0;
1080+
1081+
for (dn = of_find_node_with_property(node, "jesd204-device"); dn;
1082+
dn = of_find_node_with_property(dn, "jesd204-device"))
1083+
i++;
1084+
1085+
return i;
1086+
}
1087+
1088+
/**
1089+
* of_jesd204_notify - reconfig notifier for dynamic DT changes
1090+
* @nb: notifier block
1091+
* @action: notifier action
1092+
* @arg: reconfig data
1093+
*
1094+
*/
1095+
static int of_jesd204_notify(struct notifier_block *nb,
1096+
unsigned long action, void *arg)
1097+
{
1098+
struct of_overlay_notify_data *nd = arg;
1099+
int devs, ret = 0;
1100+
1101+
switch (action) {
1102+
case OF_OVERLAY_PRE_APPLY:
1103+
pr_debug("%s OF_OVERLAY_PRE_APPLY\n", __func__);
1104+
1105+
devs = jesd204_overlay_has_device(nd->overlay);
1106+
if (!devs)
1107+
return NOTIFY_OK;
1108+
1109+
if (jesd204_device_count || jesd204_topologies_count) {
1110+
pr_err("%s Failed: base devicetree must not have any jesd204-devices",
1111+
__func__);
1112+
return notifier_from_errno(-EOPNOTSUPP);
1113+
}
1114+
1115+
jesd204_dyn_dt_change = true;
1116+
1117+
return NOTIFY_OK;
1118+
case OF_OVERLAY_POST_APPLY:
1119+
pr_debug("%s OF_OVERLAY_POST_APPLY\n", __func__);
1120+
1121+
if (jesd204_dyn_dt_change) {
1122+
ret = jesd204_of_create_devices();
1123+
1124+
pr_info("found %u devices and %u topologies\n",
1125+
jesd204_device_count, jesd204_topologies_count);
1126+
1127+
jesd204_dyn_dt_change = false;
1128+
if (!ret)
1129+
driver_deferred_probe_trigger();
1130+
1131+
return notifier_from_errno(ret);
1132+
}
1133+
1134+
return NOTIFY_OK;
1135+
case OF_OVERLAY_PRE_REMOVE:
1136+
pr_debug("%s OF_OVERLAY_PRE_REMOVE\n", __func__);
1137+
1138+
if (jesd204_device_count)
1139+
return notifier_from_errno(-EOPNOTSUPP);
1140+
1141+
return NOTIFY_OK;
1142+
default:
1143+
pr_debug("%s Not implemented action: %ld\n", __func__, action);
1144+
return NOTIFY_OK;
1145+
}
1146+
}
1147+
1148+
static struct notifier_block jesd204_of_nb = {
1149+
.notifier_call = of_jesd204_notify,
1150+
};
1151+
10711152
static int __init jesd204_init(void)
10721153
{
10731154
int ret;
@@ -1084,6 +1165,10 @@ static int __init jesd204_init(void)
10841165
if (ret < 0)
10851166
goto error_unreg_devices;
10861167

1168+
ret = of_overlay_notifier_register(&jesd204_of_nb);
1169+
if (ret)
1170+
return ret;
1171+
10871172
pr_info("found %u devices and %u topologies\n",
10881173
jesd204_device_count, jesd204_topologies_count);
10891174

@@ -1099,6 +1184,7 @@ static void __exit jesd204_exit(void)
10991184
{
11001185
jesd204_of_unregister_devices();
11011186
bus_unregister(&jesd204_bus_type);
1187+
of_overlay_notifier_unregister(&jesd204_of_nb);
11021188
}
11031189

11041190
subsys_initcall(jesd204_init);

0 commit comments

Comments
 (0)