aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/core.c')
-rw-r--r--drivers/base/core.c85
1 files changed, 69 insertions, 16 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 82c865452c70..a31ea193fba0 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -117,6 +117,56 @@ static const struct sysfs_ops dev_sysfs_ops = {
117 .store = dev_attr_store, 117 .store = dev_attr_store,
118}; 118};
119 119
120#define to_ext_attr(x) container_of(x, struct dev_ext_attribute, attr)
121
122ssize_t device_store_ulong(struct device *dev,
123 struct device_attribute *attr,
124 const char *buf, size_t size)
125{
126 struct dev_ext_attribute *ea = to_ext_attr(attr);
127 char *end;
128 unsigned long new = simple_strtoul(buf, &end, 0);
129 if (end == buf)
130 return -EINVAL;
131 *(unsigned long *)(ea->var) = new;
132 /* Always return full write size even if we didn't consume all */
133 return size;
134}
135EXPORT_SYMBOL_GPL(device_store_ulong);
136
137ssize_t device_show_ulong(struct device *dev,
138 struct device_attribute *attr,
139 char *buf)
140{
141 struct dev_ext_attribute *ea = to_ext_attr(attr);
142 return snprintf(buf, PAGE_SIZE, "%lx\n", *(unsigned long *)(ea->var));
143}
144EXPORT_SYMBOL_GPL(device_show_ulong);
145
146ssize_t device_store_int(struct device *dev,
147 struct device_attribute *attr,
148 const char *buf, size_t size)
149{
150 struct dev_ext_attribute *ea = to_ext_attr(attr);
151 char *end;
152 long new = simple_strtol(buf, &end, 0);
153 if (end == buf || new > INT_MAX || new < INT_MIN)
154 return -EINVAL;
155 *(int *)(ea->var) = new;
156 /* Always return full write size even if we didn't consume all */
157 return size;
158}
159EXPORT_SYMBOL_GPL(device_store_int);
160
161ssize_t device_show_int(struct device *dev,
162 struct device_attribute *attr,
163 char *buf)
164{
165 struct dev_ext_attribute *ea = to_ext_attr(attr);
166
167 return snprintf(buf, PAGE_SIZE, "%d\n", *(int *)(ea->var));
168}
169EXPORT_SYMBOL_GPL(device_show_int);
120 170
121/** 171/**
122 * device_release - free device structure. 172 * device_release - free device structure.
@@ -463,7 +513,7 @@ static ssize_t show_dev(struct device *dev, struct device_attribute *attr,
463static struct device_attribute devt_attr = 513static struct device_attribute devt_attr =
464 __ATTR(dev, S_IRUGO, show_dev, NULL); 514 __ATTR(dev, S_IRUGO, show_dev, NULL);
465 515
466/* kset to create /sys/devices/ */ 516/* /sys/devices/ */
467struct kset *devices_kset; 517struct kset *devices_kset;
468 518
469/** 519/**
@@ -710,6 +760,10 @@ static struct kobject *get_device_parent(struct device *dev,
710 return k; 760 return k;
711 } 761 }
712 762
763 /* subsystems can specify a default root directory for their devices */
764 if (!parent && dev->bus && dev->bus->dev_root)
765 return &dev->bus->dev_root->kobj;
766
713 if (parent) 767 if (parent)
714 return &parent->kobj; 768 return &parent->kobj;
715 return NULL; 769 return NULL;
@@ -730,14 +784,6 @@ static void cleanup_device_parent(struct device *dev)
730 cleanup_glue_dir(dev, dev->kobj.parent); 784 cleanup_glue_dir(dev, dev->kobj.parent);
731} 785}
732 786
733static void setup_parent(struct device *dev, struct device *parent)
734{
735 struct kobject *kobj;
736 kobj = get_device_parent(dev, parent);
737 if (kobj)
738 dev->kobj.parent = kobj;
739}
740
741static int device_add_class_symlinks(struct device *dev) 787static int device_add_class_symlinks(struct device *dev)
742{ 788{
743 int error; 789 int error;
@@ -890,6 +936,7 @@ int device_private_init(struct device *dev)
890int device_add(struct device *dev) 936int device_add(struct device *dev)
891{ 937{
892 struct device *parent = NULL; 938 struct device *parent = NULL;
939 struct kobject *kobj;
893 struct class_interface *class_intf; 940 struct class_interface *class_intf;
894 int error = -EINVAL; 941 int error = -EINVAL;
895 942
@@ -913,6 +960,10 @@ int device_add(struct device *dev)
913 dev->init_name = NULL; 960 dev->init_name = NULL;
914 } 961 }
915 962
963 /* subsystems can specify simple device enumeration */
964 if (!dev_name(dev) && dev->bus && dev->bus->dev_name)
965 dev_set_name(dev, "%s%u", dev->bus->dev_name, dev->id);
966
916 if (!dev_name(dev)) { 967 if (!dev_name(dev)) {
917 error = -EINVAL; 968 error = -EINVAL;
918 goto name_error; 969 goto name_error;
@@ -921,7 +972,9 @@ int device_add(struct device *dev)
921 pr_debug("device: '%s': %s\n", dev_name(dev), __func__); 972 pr_debug("device: '%s': %s\n", dev_name(dev), __func__);
922 973
923 parent = get_device(dev->parent); 974 parent = get_device(dev->parent);
924 setup_parent(dev, parent); 975 kobj = get_device_parent(dev, parent);
976 if (kobj)
977 dev->kobj.parent = kobj;
925 978
926 /* use parent numa_node */ 979 /* use parent numa_node */
927 if (parent) 980 if (parent)
@@ -981,17 +1034,17 @@ int device_add(struct device *dev)
981 &parent->p->klist_children); 1034 &parent->p->klist_children);
982 1035
983 if (dev->class) { 1036 if (dev->class) {
984 mutex_lock(&dev->class->p->class_mutex); 1037 mutex_lock(&dev->class->p->mutex);
985 /* tie the class to the device */ 1038 /* tie the class to the device */
986 klist_add_tail(&dev->knode_class, 1039 klist_add_tail(&dev->knode_class,
987 &dev->class->p->klist_devices); 1040 &dev->class->p->klist_devices);
988 1041
989 /* notify any interfaces that the device is here */ 1042 /* notify any interfaces that the device is here */
990 list_for_each_entry(class_intf, 1043 list_for_each_entry(class_intf,
991 &dev->class->p->class_interfaces, node) 1044 &dev->class->p->interfaces, node)
992 if (class_intf->add_dev) 1045 if (class_intf->add_dev)
993 class_intf->add_dev(dev, class_intf); 1046 class_intf->add_dev(dev, class_intf);
994 mutex_unlock(&dev->class->p->class_mutex); 1047 mutex_unlock(&dev->class->p->mutex);
995 } 1048 }
996done: 1049done:
997 put_device(dev); 1050 put_device(dev);
@@ -1106,15 +1159,15 @@ void device_del(struct device *dev)
1106 if (dev->class) { 1159 if (dev->class) {
1107 device_remove_class_symlinks(dev); 1160 device_remove_class_symlinks(dev);
1108 1161
1109 mutex_lock(&dev->class->p->class_mutex); 1162 mutex_lock(&dev->class->p->mutex);
1110 /* notify any interfaces that the device is now gone */ 1163 /* notify any interfaces that the device is now gone */
1111 list_for_each_entry(class_intf, 1164 list_for_each_entry(class_intf,
1112 &dev->class->p->class_interfaces, node) 1165 &dev->class->p->interfaces, node)
1113 if (class_intf->remove_dev) 1166 if (class_intf->remove_dev)
1114 class_intf->remove_dev(dev, class_intf); 1167 class_intf->remove_dev(dev, class_intf);
1115 /* remove the device from the class list */ 1168 /* remove the device from the class list */
1116 klist_del(&dev->knode_class); 1169 klist_del(&dev->knode_class);
1117 mutex_unlock(&dev->class->p->class_mutex); 1170 mutex_unlock(&dev->class->p->mutex);
1118 } 1171 }
1119 device_remove_file(dev, &uevent_attr); 1172 device_remove_file(dev, &uevent_attr);
1120 device_remove_attrs(dev); 1173 device_remove_attrs(dev);