| Stephen Rothwell | f85ff30 | 2007-05-01 16:40:36 +1000 | [diff] [blame] | 1 | #include <linux/string.h> | 
|  | 2 | #include <linux/kernel.h> | 
|  | 3 | #include <linux/of.h> | 
| Stephen Rothwell | f898f8d | 2007-05-01 16:49:51 +1000 | [diff] [blame] | 4 | #include <linux/of_device.h> | 
| Stephen Rothwell | f85ff30 | 2007-05-01 16:40:36 +1000 | [diff] [blame] | 5 | #include <linux/init.h> | 
|  | 6 | #include <linux/module.h> | 
|  | 7 | #include <linux/mod_devicetable.h> | 
|  | 8 | #include <linux/slab.h> | 
|  | 9 |  | 
|  | 10 | #include <asm/errno.h> | 
| Stephen Rothwell | f85ff30 | 2007-05-01 16:40:36 +1000 | [diff] [blame] | 11 |  | 
|  | 12 | /** | 
| Stephen Rothwell | f85ff30 | 2007-05-01 16:40:36 +1000 | [diff] [blame] | 13 | * of_match_device - Tell if an of_device structure has a matching | 
|  | 14 | * of_match structure | 
|  | 15 | * @ids: array of of device match structures to search in | 
|  | 16 | * @dev: the of device structure to match against | 
|  | 17 | * | 
|  | 18 | * Used by a driver to check whether an of_device present in the | 
|  | 19 | * system is in its list of supported devices. | 
|  | 20 | */ | 
|  | 21 | const struct of_device_id *of_match_device(const struct of_device_id *matches, | 
|  | 22 | const struct of_device *dev) | 
|  | 23 | { | 
|  | 24 | if (!dev->node) | 
|  | 25 | return NULL; | 
|  | 26 | return of_match_node(matches, dev->node); | 
|  | 27 | } | 
|  | 28 | EXPORT_SYMBOL(of_match_device); | 
|  | 29 |  | 
|  | 30 | struct of_device *of_dev_get(struct of_device *dev) | 
|  | 31 | { | 
|  | 32 | struct device *tmp; | 
|  | 33 |  | 
|  | 34 | if (!dev) | 
|  | 35 | return NULL; | 
|  | 36 | tmp = get_device(&dev->dev); | 
|  | 37 | if (tmp) | 
|  | 38 | return to_of_device(tmp); | 
|  | 39 | else | 
|  | 40 | return NULL; | 
|  | 41 | } | 
|  | 42 | EXPORT_SYMBOL(of_dev_get); | 
|  | 43 |  | 
|  | 44 | void of_dev_put(struct of_device *dev) | 
|  | 45 | { | 
|  | 46 | if (dev) | 
|  | 47 | put_device(&dev->dev); | 
|  | 48 | } | 
|  | 49 | EXPORT_SYMBOL(of_dev_put); | 
|  | 50 |  | 
|  | 51 | static ssize_t dev_show_devspec(struct device *dev, | 
|  | 52 | struct device_attribute *attr, char *buf) | 
|  | 53 | { | 
|  | 54 | struct of_device *ofdev; | 
|  | 55 |  | 
|  | 56 | ofdev = to_of_device(dev); | 
|  | 57 | return sprintf(buf, "%s", ofdev->node->full_name); | 
|  | 58 | } | 
|  | 59 |  | 
|  | 60 | static DEVICE_ATTR(devspec, S_IRUGO, dev_show_devspec, NULL); | 
|  | 61 |  | 
|  | 62 | /** | 
|  | 63 | * of_release_dev - free an of device structure when all users of it are finished. | 
|  | 64 | * @dev: device that's been disconnected | 
|  | 65 | * | 
|  | 66 | * Will be called only by the device core when all users of this of device are | 
|  | 67 | * done. | 
|  | 68 | */ | 
|  | 69 | void of_release_dev(struct device *dev) | 
|  | 70 | { | 
|  | 71 | struct of_device *ofdev; | 
|  | 72 |  | 
|  | 73 | ofdev = to_of_device(dev); | 
|  | 74 | of_node_put(ofdev->node); | 
|  | 75 | kfree(ofdev); | 
|  | 76 | } | 
|  | 77 | EXPORT_SYMBOL(of_release_dev); | 
|  | 78 |  | 
|  | 79 | int of_device_register(struct of_device *ofdev) | 
|  | 80 | { | 
|  | 81 | int rc; | 
|  | 82 |  | 
|  | 83 | BUG_ON(ofdev->node == NULL); | 
|  | 84 |  | 
|  | 85 | rc = device_register(&ofdev->dev); | 
|  | 86 | if (rc) | 
|  | 87 | return rc; | 
|  | 88 |  | 
|  | 89 | rc = device_create_file(&ofdev->dev, &dev_attr_devspec); | 
|  | 90 | if (rc) | 
|  | 91 | device_unregister(&ofdev->dev); | 
|  | 92 |  | 
|  | 93 | return rc; | 
|  | 94 | } | 
|  | 95 | EXPORT_SYMBOL(of_device_register); | 
|  | 96 |  | 
|  | 97 | void of_device_unregister(struct of_device *ofdev) | 
|  | 98 | { | 
|  | 99 | device_remove_file(&ofdev->dev, &dev_attr_devspec); | 
|  | 100 | device_unregister(&ofdev->dev); | 
|  | 101 | } | 
|  | 102 | EXPORT_SYMBOL(of_device_unregister); |