X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=drivers%2Fcore%2Fuclass.c;h=9766aeabd192f69206f5fec8bb8274979aa14edb;hb=9450ab2ba8d720bd9f73bccc0af2e2b5a2c2aaf1;hp=f5e406792209686a897c7395dc80d616f082036f;hpb=8d3a25685e4aac7070365a2b3c53c2c81b27930f;p=platform%2Fkernel%2Fu-boot.git diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c index f5e4067..9766aea 100644 --- a/drivers/core/uclass.c +++ b/drivers/core/uclass.c @@ -1,10 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 2013 Google, Inc * * (C) Copyright 2012 * Pavel Herrmann - * - * SPDX-License-Identifier: GPL-2.0+ */ #include @@ -158,6 +157,41 @@ const char *uclass_get_name(enum uclass_id id) return uc->uc_drv->name; } +enum uclass_id uclass_get_by_name(const char *name) +{ + int i; + + for (i = 0; i < UCLASS_COUNT; i++) { + struct uclass_driver *uc_drv = lists_uclass_lookup(i); + + if (uc_drv && !strcmp(uc_drv->name, name)) + return i; + } + + return UCLASS_INVALID; +} + +int dev_get_uclass_index(struct udevice *dev, struct uclass **ucp) +{ + struct udevice *iter; + struct uclass *uc = dev->uclass; + int i = 0; + + if (list_empty(&uc->dev_head)) + return -ENODEV; + + uclass_foreach_dev(iter, uc) { + if (iter == dev) { + if (ucp) + *ucp = uc; + return i; + } + i++; + } + + return -ENODEV; +} + int uclass_find_device(enum uclass_id id, int index, struct udevice **devp) { struct uclass *uc; @@ -171,7 +205,7 @@ int uclass_find_device(enum uclass_id id, int index, struct udevice **devp) if (list_empty(&uc->dev_head)) return -ENODEV; - list_for_each_entry(dev, &uc->dev_head, uclass_node) { + uclass_foreach_dev(dev, uc) { if (!index--) { *devp = dev; return 0; @@ -225,7 +259,7 @@ int uclass_find_device_by_name(enum uclass_id id, const char *name, if (ret) return ret; - list_for_each_entry(dev, &uc->dev_head, uclass_node) { + uclass_foreach_dev(dev, uc) { if (!strncmp(dev->name, name, strlen(name))) { *devp = dev; return 0; @@ -250,7 +284,7 @@ int uclass_find_device_by_seq(enum uclass_id id, int seq_or_req_seq, if (ret) return ret; - list_for_each_entry(dev, &uc->dev_head, uclass_node) { + uclass_foreach_dev(dev, uc) { debug(" - %d %d '%s'\n", dev->req_seq, dev->seq, dev->name); if ((find_req_seq ? dev->req_seq : dev->seq) == seq_or_req_seq) { @@ -278,7 +312,7 @@ int uclass_find_device_by_of_offset(enum uclass_id id, int node, if (ret) return ret; - list_for_each_entry(dev, &uc->dev_head, uclass_node) { + uclass_foreach_dev(dev, uc) { if (dev_of_offset(dev) == node) { *devp = dev; return 0; @@ -295,6 +329,7 @@ int uclass_find_device_by_ofnode(enum uclass_id id, ofnode node, struct udevice *dev; int ret; + log(LOGC_DM, LOGL_DEBUG, "Looking for %s\n", ofnode_get_name(node)); *devp = NULL; if (!ofnode_valid(node)) return -ENODEV; @@ -302,21 +337,25 @@ int uclass_find_device_by_ofnode(enum uclass_id id, ofnode node, if (ret) return ret; - list_for_each_entry(dev, &uc->dev_head, uclass_node) { + uclass_foreach_dev(dev, uc) { + log(LOGC_DM, LOGL_DEBUG_CONTENT, " - checking %s\n", + dev->name); if (ofnode_equal(dev_ofnode(dev), node)) { *devp = dev; - return 0; + goto done; } } + ret = -ENODEV; - return -ENODEV; +done: + log(LOGC_DM, LOGL_DEBUG, " - result for %s: %s (ret=%d)\n", + ofnode_get_name(node), *devp ? (*devp)->name : "(none)", ret); + return ret; } #if CONFIG_IS_ENABLED(OF_CONTROL) -static int uclass_find_device_by_phandle(enum uclass_id id, - struct udevice *parent, - const char *name, - struct udevice **devp) +int uclass_find_device_by_phandle(enum uclass_id id, struct udevice *parent, + const char *name, struct udevice **devp) { struct udevice *dev; struct uclass *uc; @@ -331,7 +370,7 @@ static int uclass_find_device_by_phandle(enum uclass_id id, if (ret) return ret; - list_for_each_entry(dev, &uc->dev_head, uclass_node) { + uclass_foreach_dev(dev, uc) { uint phandle; phandle = dev_read_phandle(dev); @@ -358,7 +397,7 @@ int uclass_get_device_by_driver(enum uclass_id id, if (ret) return ret; - list_for_each_entry(dev, &uc->dev_head, uclass_node) { + uclass_foreach_dev(dev, uc) { if (dev->driver == find_drv) return uclass_get_device_tail(dev, 0, devp); } @@ -436,13 +475,42 @@ int uclass_get_device_by_ofnode(enum uclass_id id, ofnode node, struct udevice *dev; int ret; + log(LOGC_DM, LOGL_DEBUG, "Looking for %s\n", ofnode_get_name(node)); *devp = NULL; ret = uclass_find_device_by_ofnode(id, node, &dev); + log(LOGC_DM, LOGL_DEBUG, " - result for %s: %s (ret=%d)\n", + ofnode_get_name(node), dev ? dev->name : "(none)", ret); return uclass_get_device_tail(dev, ret, devp); } #if CONFIG_IS_ENABLED(OF_CONTROL) +int uclass_get_device_by_phandle_id(enum uclass_id id, uint phandle_id, + struct udevice **devp) +{ + struct udevice *dev; + struct uclass *uc; + int ret; + + *devp = NULL; + ret = uclass_get(id, &uc); + if (ret) + return ret; + + uclass_foreach_dev(dev, uc) { + uint phandle; + + phandle = dev_read_phandle(dev); + + if (phandle == phandle_id) { + *devp = dev; + return uclass_get_device_tail(dev, ret, devp); + } + } + + return -ENODEV; +} + int uclass_get_device_by_phandle(enum uclass_id id, struct udevice *parent, const char *name, struct udevice **devp) { @@ -492,6 +560,19 @@ int uclass_next_device(struct udevice **devp) return uclass_get_device_tail(dev, ret, devp); } +int uclass_next_device_err(struct udevice **devp) +{ + int ret; + + ret = uclass_next_device(devp); + if (ret) + return ret; + else if (!*devp) + return -ENODEV; + + return 0; +} + int uclass_first_device_check(enum uclass_id id, struct udevice **devp) { int ret; @@ -617,8 +698,19 @@ int uclass_pre_probe_device(struct udevice *dev) int uclass_post_probe_device(struct udevice *dev) { - struct uclass_driver *uc_drv = dev->uclass->uc_drv; + struct uclass_driver *uc_drv; + int ret; + if (dev->parent) { + uc_drv = dev->parent->uclass->uc_drv; + if (uc_drv->child_post_probe) { + ret = uc_drv->child_post_probe(dev); + if (ret) + return ret; + } + } + + uc_drv = dev->uclass->uc_drv; if (uc_drv->post_probe) return uc_drv->post_probe(dev);