@ -37,6 +37,65 @@ struct udevice *dm_root(void)
return gd - > dm_root ;
}
# if defined(CONFIG_NEEDS_MANUAL_RELOC)
void fix_drivers ( void )
{
struct driver * drv =
ll_entry_start ( struct driver , driver ) ;
const int n_ents = ll_entry_count ( struct driver , driver ) ;
struct driver * entry ;
for ( entry = drv ; entry ! = drv + n_ents ; entry + + ) {
if ( entry - > of_match )
entry - > of_match = ( const struct udevice_id * )
( ( u32 ) entry - > of_match + gd - > reloc_off ) ;
if ( entry - > bind )
entry - > bind + = gd - > reloc_off ;
if ( entry - > probe )
entry - > probe + = gd - > reloc_off ;
if ( entry - > remove )
entry - > remove + = gd - > reloc_off ;
if ( entry - > unbind )
entry - > unbind + = gd - > reloc_off ;
if ( entry - > ofdata_to_platdata )
entry - > ofdata_to_platdata + = gd - > reloc_off ;
if ( entry - > child_pre_probe )
entry - > child_pre_probe + = gd - > reloc_off ;
if ( entry - > child_post_remove )
entry - > child_post_remove + = gd - > reloc_off ;
/* OPS are fixed in every uclass post_probe function */
if ( entry - > ops )
entry - > ops + = gd - > reloc_off ;
}
}
void fix_uclass ( void )
{
struct uclass_driver * uclass =
ll_entry_start ( struct uclass_driver , uclass ) ;
const int n_ents = ll_entry_count ( struct uclass_driver , uclass ) ;
struct uclass_driver * entry ;
for ( entry = uclass ; entry ! = uclass + n_ents ; entry + + ) {
if ( entry - > post_bind )
entry - > post_bind + = gd - > reloc_off ;
if ( entry - > pre_unbind )
entry - > pre_unbind + = gd - > reloc_off ;
if ( entry - > post_probe )
entry - > post_probe + = gd - > reloc_off ;
if ( entry - > pre_remove )
entry - > pre_remove + = gd - > reloc_off ;
if ( entry - > init )
entry - > init + = gd - > reloc_off ;
if ( entry - > destroy )
entry - > destroy + = gd - > reloc_off ;
/* FIXME maybe also need to fix these ops */
if ( entry - > ops )
entry - > ops + = gd - > reloc_off ;
}
}
# endif
int dm_init ( void )
{
int ret ;
@ -47,6 +106,11 @@ int dm_init(void)
}
INIT_LIST_HEAD ( & DM_UCLASS_ROOT_NON_CONST ) ;
# if defined(CONFIG_NEEDS_MANUAL_RELOC)
fix_drivers ( ) ;
fix_uclass ( ) ;
# endif
ret = device_bind_by_name ( NULL , false , & root_info , & DM_ROOT_NON_CONST ) ;
if ( ret )
return ret ;