@@ -30,6 +30,7 @@ static unsigned int jesd204_device_count;
3030static unsigned int jesd204_topologies_count ;
3131
3232static unsigned int jesd204_con_id_counter ;
33+ static bool jesd204_dyn_dt_change ;
3334
3435static 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}
10691073EXPORT_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+
10711152static 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
11041190subsys_initcall (jesd204_init );
0 commit comments