diff options
author | Sudeep Holla <sudeep.holla@arm.com> | 2014-09-30 09:48:24 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-11-07 14:45:00 -0500 |
commit | 3d52943b3a51497a777e6d7d840a38596a92cee9 (patch) | |
tree | eb75d73033dab562bcd01de19cfe99fbc5cdc632 | |
parent | d6ea8d01d1893e1299a4016d62fdda870b8cc215 (diff) |
drivers: base: add cpu_device_create to support per-cpu devices
This patch adds a new function to create per-cpu devices.
This helps in:
1. reusing the device infrastructure to create any cpu related
attributes and corresponding sysfs instead of creating and
dealing with raw kobjects directly
2. retaining the legacy path(/sys/devices/system/cpu/..) to support
existing sysfs ABI
3. avoiding to create links in the bus directory pointing to the
device as there would be per-cpu instance of these devices with
the same name since dev->bus is not populated to cpu_sysbus on
purpose
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
Tested-by: Stephen Boyd <sboyd@codeaurora.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: David Herrmann <dh.herrmann@gmail.com>
Cc: Kay Sievers <kay@vrfy.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/base/cpu.c | 54 | ||||
-rw-r--r-- | include/linux/cpu.h | 4 |
2 files changed, 58 insertions, 0 deletions
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 4d8a56406fbb..f829a4c71749 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c | |||
@@ -363,6 +363,60 @@ struct device *get_cpu_device(unsigned cpu) | |||
363 | } | 363 | } |
364 | EXPORT_SYMBOL_GPL(get_cpu_device); | 364 | EXPORT_SYMBOL_GPL(get_cpu_device); |
365 | 365 | ||
366 | static void device_create_release(struct device *dev) | ||
367 | { | ||
368 | kfree(dev); | ||
369 | } | ||
370 | |||
371 | static struct device * | ||
372 | __cpu_device_create(struct device *parent, void *drvdata, | ||
373 | const struct attribute_group **groups, | ||
374 | const char *fmt, va_list args) | ||
375 | { | ||
376 | struct device *dev = NULL; | ||
377 | int retval = -ENODEV; | ||
378 | |||
379 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
380 | if (!dev) { | ||
381 | retval = -ENOMEM; | ||
382 | goto error; | ||
383 | } | ||
384 | |||
385 | device_initialize(dev); | ||
386 | dev->parent = parent; | ||
387 | dev->groups = groups; | ||
388 | dev->release = device_create_release; | ||
389 | dev_set_drvdata(dev, drvdata); | ||
390 | |||
391 | retval = kobject_set_name_vargs(&dev->kobj, fmt, args); | ||
392 | if (retval) | ||
393 | goto error; | ||
394 | |||
395 | retval = device_add(dev); | ||
396 | if (retval) | ||
397 | goto error; | ||
398 | |||
399 | return dev; | ||
400 | |||
401 | error: | ||
402 | put_device(dev); | ||
403 | return ERR_PTR(retval); | ||
404 | } | ||
405 | |||
406 | struct device *cpu_device_create(struct device *parent, void *drvdata, | ||
407 | const struct attribute_group **groups, | ||
408 | const char *fmt, ...) | ||
409 | { | ||
410 | va_list vargs; | ||
411 | struct device *dev; | ||
412 | |||
413 | va_start(vargs, fmt); | ||
414 | dev = __cpu_device_create(parent, drvdata, groups, fmt, vargs); | ||
415 | va_end(vargs); | ||
416 | return dev; | ||
417 | } | ||
418 | EXPORT_SYMBOL_GPL(cpu_device_create); | ||
419 | |||
366 | #ifdef CONFIG_GENERIC_CPU_AUTOPROBE | 420 | #ifdef CONFIG_GENERIC_CPU_AUTOPROBE |
367 | static DEVICE_ATTR(modalias, 0444, print_cpu_modalias, NULL); | 421 | static DEVICE_ATTR(modalias, 0444, print_cpu_modalias, NULL); |
368 | #endif | 422 | #endif |
diff --git a/include/linux/cpu.h b/include/linux/cpu.h index b2d9a43012b2..4260e8594bd7 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | struct device; | 20 | struct device; |
21 | struct device_node; | 21 | struct device_node; |
22 | struct attribute_group; | ||
22 | 23 | ||
23 | struct cpu { | 24 | struct cpu { |
24 | int node_id; /* The node which contains the CPU */ | 25 | int node_id; /* The node which contains the CPU */ |
@@ -39,6 +40,9 @@ extern void cpu_remove_dev_attr(struct device_attribute *attr); | |||
39 | extern int cpu_add_dev_attr_group(struct attribute_group *attrs); | 40 | extern int cpu_add_dev_attr_group(struct attribute_group *attrs); |
40 | extern void cpu_remove_dev_attr_group(struct attribute_group *attrs); | 41 | extern void cpu_remove_dev_attr_group(struct attribute_group *attrs); |
41 | 42 | ||
43 | extern struct device *cpu_device_create(struct device *parent, void *drvdata, | ||
44 | const struct attribute_group **groups, | ||
45 | const char *fmt, ...); | ||
42 | #ifdef CONFIG_HOTPLUG_CPU | 46 | #ifdef CONFIG_HOTPLUG_CPU |
43 | extern void unregister_cpu(struct cpu *cpu); | 47 | extern void unregister_cpu(struct cpu *cpu); |
44 | extern ssize_t arch_cpu_probe(const char *, size_t); | 48 | extern ssize_t arch_cpu_probe(const char *, size_t); |