mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-09-30 08:30:50 +09:00
syscon: update syscon_node_to_regmap to use the DM functions
+ Update the function syscon_node_to_regmap() to force bound on syscon uclass and directly use the list of device from DM. + Remove the static list syscon_list. This patch avoid issue (crash) when syscon_node_to_regmap() is called before and after reallocation (list content is invalid). Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
This commit is contained in:
parent
74473ed0cf
commit
de5bab9c59
@ -146,52 +146,31 @@ U_BOOT_DRIVER(generic_syscon) = {
|
|||||||
* The syscon node can be bound to another driver, but still works
|
* The syscon node can be bound to another driver, but still works
|
||||||
* as a syscon provider.
|
* as a syscon provider.
|
||||||
*/
|
*/
|
||||||
static LIST_HEAD(syscon_list);
|
struct regmap *syscon_node_to_regmap(ofnode node)
|
||||||
|
|
||||||
struct syscon {
|
|
||||||
ofnode node;
|
|
||||||
struct regmap *regmap;
|
|
||||||
struct list_head list;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct syscon *of_syscon_register(ofnode node)
|
|
||||||
{
|
{
|
||||||
struct syscon *syscon;
|
struct udevice *dev, *parent;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (!uclass_get_device_by_ofnode(UCLASS_SYSCON, node, &dev))
|
||||||
|
return syscon_get_regmap(dev);
|
||||||
|
|
||||||
if (!ofnode_device_is_compatible(node, "syscon"))
|
if (!ofnode_device_is_compatible(node, "syscon"))
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
syscon = malloc(sizeof(*syscon));
|
/* bound to driver with same ofnode or to root if not found */
|
||||||
if (!syscon)
|
if (device_find_global_by_ofnode(node, &parent))
|
||||||
return ERR_PTR(-ENOMEM);
|
parent = dm_root();
|
||||||
|
|
||||||
ret = regmap_init_mem(node, &syscon->regmap);
|
/* force bound to syscon class */
|
||||||
if (ret) {
|
ret = device_bind_driver_to_node(parent, "syscon",
|
||||||
free(syscon);
|
ofnode_get_name(node),
|
||||||
|
node, &dev);
|
||||||
|
if (ret)
|
||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
}
|
|
||||||
|
|
||||||
list_add_tail(&syscon->list, &syscon_list);
|
ret = device_probe(dev);
|
||||||
|
if (ret)
|
||||||
|
return ERR_PTR(ret);
|
||||||
|
|
||||||
return syscon;
|
return syscon_get_regmap(dev);
|
||||||
}
|
|
||||||
|
|
||||||
struct regmap *syscon_node_to_regmap(ofnode node)
|
|
||||||
{
|
|
||||||
struct syscon *entry, *syscon = NULL;
|
|
||||||
|
|
||||||
list_for_each_entry(entry, &syscon_list, list)
|
|
||||||
if (ofnode_equal(entry->node, node)) {
|
|
||||||
syscon = entry;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!syscon)
|
|
||||||
syscon = of_syscon_register(node);
|
|
||||||
|
|
||||||
if (IS_ERR(syscon))
|
|
||||||
return ERR_CAST(syscon);
|
|
||||||
|
|
||||||
return syscon->regmap;
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user