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