diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-18 19:59:52 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-18 19:59:52 -0400 |
commit | 60fbf2bda140f27b0e9ab5b6d17342c9a5f9eacf (patch) | |
tree | 5ab62db9c538de54d8176439b0adebfff2758d31 | |
parent | 8cb652bb10e788270b6b8b6df20fba62b479feb2 (diff) | |
parent | 94f8cc0eea03648e5cc5de1a4e7dc464de92cc74 (diff) |
Merge tag 'driver-core-3.15-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core
Pull driver core fixes from Greg KH:
"Here are some driver core fixes for 3.15-rc2. Also in here are some
documentation updates, as well as an API removal that had to wait for
after -rc1 due to the cleanups coming into you from multiple developer
trees (this one and the PPC tree.)
All have been in linux next successfully"
* tag 'driver-core-3.15-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core:
drivers/base/dd.c incorrect pr_debug() parameters
Documentation: Update stable address in Chinese and Japanese translations
topology: Fix compilation warning when not in SMP
Chinese: add translation of io_ordering.txt
stable_kernel_rules: spelling/word usage
sysfs, driver-core: remove unused {sysfs|device}_schedule_callback_owner()
kernfs: protect lazy kernfs_iattrs allocation with mutex
fs: Don't return 0 from get_anon_bdev
-rw-r--r-- | Documentation/ja_JP/HOWTO | 2 | ||||
-rw-r--r-- | Documentation/ja_JP/stable_kernel_rules.txt | 6 | ||||
-rw-r--r-- | Documentation/stable_kernel_rules.txt | 2 | ||||
-rw-r--r-- | Documentation/zh_CN/HOWTO | 2 | ||||
-rw-r--r-- | Documentation/zh_CN/io_ordering.txt | 67 | ||||
-rw-r--r-- | Documentation/zh_CN/stable_kernel_rules.txt | 2 | ||||
-rw-r--r-- | drivers/base/core.c | 33 | ||||
-rw-r--r-- | drivers/base/dd.c | 4 | ||||
-rw-r--r-- | drivers/base/topology.c | 3 | ||||
-rw-r--r-- | fs/kernfs/inode.c | 14 | ||||
-rw-r--r-- | fs/super.c | 5 | ||||
-rw-r--r-- | fs/sysfs/file.c | 92 | ||||
-rw-r--r-- | include/linux/device.h | 11 | ||||
-rw-r--r-- | include/linux/sysfs.h | 9 |
14 files changed, 92 insertions, 160 deletions
diff --git a/Documentation/ja_JP/HOWTO b/Documentation/ja_JP/HOWTO index 0091a8215ac1..b61885c35ce1 100644 --- a/Documentation/ja_JP/HOWTO +++ b/Documentation/ja_JP/HOWTO | |||
@@ -315,7 +315,7 @@ Andrew Morton が Linux-kernel メーリングリストにカーネルリリー | |||
315 | もし、3.x.y カーネルが存在しない場合には、番号が一番大きい 3.x が | 315 | もし、3.x.y カーネルが存在しない場合には、番号が一番大きい 3.x が |
316 | 最新の安定版カーネルです。 | 316 | 最新の安定版カーネルです。 |
317 | 317 | ||
318 | 3.x.y は "stable" チーム <stable@kernel.org> でメンテされており、必 | 318 | 3.x.y は "stable" チーム <stable@vger.kernel.org> でメンテされており、必 |
319 | 要に応じてリリースされます。通常のリリース期間は 2週間毎ですが、差し迫っ | 319 | 要に応じてリリースされます。通常のリリース期間は 2週間毎ですが、差し迫っ |
320 | た問題がなければもう少し長くなることもあります。セキュリティ関連の問題 | 320 | た問題がなければもう少し長くなることもあります。セキュリティ関連の問題 |
321 | の場合はこれに対してだいたいの場合、すぐにリリースがされます。 | 321 | の場合はこれに対してだいたいの場合、すぐにリリースがされます。 |
diff --git a/Documentation/ja_JP/stable_kernel_rules.txt b/Documentation/ja_JP/stable_kernel_rules.txt index 14265837c4ce..9dbda9b5d21e 100644 --- a/Documentation/ja_JP/stable_kernel_rules.txt +++ b/Documentation/ja_JP/stable_kernel_rules.txt | |||
@@ -50,16 +50,16 @@ linux-2.6.29/Documentation/stable_kernel_rules.txt | |||
50 | 50 | ||
51 | -stable ツリーにパッチを送付する手続き- | 51 | -stable ツリーにパッチを送付する手続き- |
52 | 52 | ||
53 | - 上記の規則に従っているかを確認した後に、stable@kernel.org にパッチ | 53 | - 上記の規則に従っているかを確認した後に、stable@vger.kernel.org にパッチ |
54 | を送る。 | 54 | を送る。 |
55 | - 送信者はパッチがキューに受け付けられた際には ACK を、却下された場合 | 55 | - 送信者はパッチがキューに受け付けられた際には ACK を、却下された場合 |
56 | には NAK を受け取る。この反応は開発者たちのスケジュールによって、数 | 56 | には NAK を受け取る。この反応は開発者たちのスケジュールによって、数 |
57 | 日かかる場合がある。 | 57 | 日かかる場合がある。 |
58 | - もし受け取られたら、パッチは他の開発者たちと関連するサブシステムの | 58 | - もし受け取られたら、パッチは他の開発者たちと関連するサブシステムの |
59 | メンテナーによるレビューのために -stable キューに追加される。 | 59 | メンテナーによるレビューのために -stable キューに追加される。 |
60 | - パッチに stable@kernel.org のアドレスが付加されているときには、それ | 60 | - パッチに stable@vger.kernel.org のアドレスが付加されているときには、それ |
61 | が Linus のツリーに入る時に自動的に stable チームに email される。 | 61 | が Linus のツリーに入る時に自動的に stable チームに email される。 |
62 | - セキュリティパッチはこのエイリアス (stable@kernel.org) に送られるべ | 62 | - セキュリティパッチはこのエイリアス (stable@vger.kernel.org) に送られるべ |
63 | きではなく、代わりに security@kernel.org のアドレスに送られる。 | 63 | きではなく、代わりに security@kernel.org のアドレスに送られる。 |
64 | 64 | ||
65 | レビューサイクル- | 65 | レビューサイクル- |
diff --git a/Documentation/stable_kernel_rules.txt b/Documentation/stable_kernel_rules.txt index b0714d8f678a..cbc2f03056bd 100644 --- a/Documentation/stable_kernel_rules.txt +++ b/Documentation/stable_kernel_rules.txt | |||
@@ -39,7 +39,7 @@ Procedure for submitting patches to the -stable tree: | |||
39 | the stable tree without anything else needing to be done by the author | 39 | the stable tree without anything else needing to be done by the author |
40 | or subsystem maintainer. | 40 | or subsystem maintainer. |
41 | - If the patch requires other patches as prerequisites which can be | 41 | - If the patch requires other patches as prerequisites which can be |
42 | cherry-picked than this can be specified in the following format in | 42 | cherry-picked, then this can be specified in the following format in |
43 | the sign-off area: | 43 | the sign-off area: |
44 | 44 | ||
45 | Cc: <stable@vger.kernel.org> # 3.3.x: a1f84a3: sched: Check for idle | 45 | Cc: <stable@vger.kernel.org> # 3.3.x: a1f84a3: sched: Check for idle |
diff --git a/Documentation/zh_CN/HOWTO b/Documentation/zh_CN/HOWTO index 6c914aa87e71..54ea24ff63c7 100644 --- a/Documentation/zh_CN/HOWTO +++ b/Documentation/zh_CN/HOWTO | |||
@@ -237,7 +237,7 @@ kernel.org网站的pub/linux/kernel/v2.6/目录下找到它。它的开发遵循 | |||
237 | 如果没有2.6.x.y版本内核存在,那么最新的2.6.x版本内核就相当于是当前的稳定 | 237 | 如果没有2.6.x.y版本内核存在,那么最新的2.6.x版本内核就相当于是当前的稳定 |
238 | 版内核。 | 238 | 版内核。 |
239 | 239 | ||
240 | 2.6.x.y版本由“稳定版”小组(邮件地址<stable@kernel.org>)维护,一般隔周发 | 240 | 2.6.x.y版本由“稳定版”小组(邮件地址<stable@vger.kernel.org>)维护,一般隔周发 |
241 | 布新版本。 | 241 | 布新版本。 |
242 | 242 | ||
243 | 内核源码中的Documentation/stable_kernel_rules.txt文件具体描述了可被稳定 | 243 | 内核源码中的Documentation/stable_kernel_rules.txt文件具体描述了可被稳定 |
diff --git a/Documentation/zh_CN/io_ordering.txt b/Documentation/zh_CN/io_ordering.txt new file mode 100644 index 000000000000..e592daf4e014 --- /dev/null +++ b/Documentation/zh_CN/io_ordering.txt | |||
@@ -0,0 +1,67 @@ | |||
1 | Chinese translated version of Documentation/io_orderings.txt | ||
2 | |||
3 | If you have any comment or update to the content, please contact the | ||
4 | original document maintainer directly. However, if you have a problem | ||
5 | communicating in English you can also ask the Chinese maintainer for | ||
6 | help. Contact the Chinese maintainer if this translation is outdated | ||
7 | or if there is a problem with the translation. | ||
8 | |||
9 | Chinese maintainer: Lin Yongting <linyongting@gmail.com> | ||
10 | --------------------------------------------------------------------- | ||
11 | Documentation/io_ordering.txt 的中文翻译 | ||
12 | |||
13 | 如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文 | ||
14 | 交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻 | ||
15 | 译存在问题,请联系中文版维护者。 | ||
16 | |||
17 | 中文版维护者: 林永听 Lin Yongting <linyongting@gmail.com> | ||
18 | 中文版翻译者: 林永听 Lin Yongting <linyongting@gmail.com> | ||
19 | 中文版校译者: 林永听 Lin Yongting <linyongting@gmail.com> | ||
20 | |||
21 | |||
22 | 以下为正文 | ||
23 | --------------------------------------------------------------------- | ||
24 | |||
25 | 在某些平台上,所谓的内存映射I/O是弱顺序。在这些平台上,驱动开发者有责任 | ||
26 | 保证I/O内存映射地址的写操作按程序图意的顺序达到设备。通常读取一个“安全” | ||
27 | 设备寄存器或桥寄存器,触发IO芯片清刷未处理的写操作到达设备后才处理读操作, | ||
28 | 而达到保证目的。驱动程序通常在spinlock保护的临界区退出之前使用这种技术。 | ||
29 | 这也可以保证后面的写操作只在前面的写操作之后到达设备(这非常类似于内存 | ||
30 | 屏障操作,mb(),不过仅适用于I/O)。 | ||
31 | |||
32 | 假设一个设备驱动程的具体例子: | ||
33 | |||
34 | ... | ||
35 | CPU A: spin_lock_irqsave(&dev_lock, flags) | ||
36 | CPU A: val = readl(my_status); | ||
37 | CPU A: ... | ||
38 | CPU A: writel(newval, ring_ptr); | ||
39 | CPU A: spin_unlock_irqrestore(&dev_lock, flags) | ||
40 | ... | ||
41 | CPU B: spin_lock_irqsave(&dev_lock, flags) | ||
42 | CPU B: val = readl(my_status); | ||
43 | CPU B: ... | ||
44 | CPU B: writel(newval2, ring_ptr); | ||
45 | CPU B: spin_unlock_irqrestore(&dev_lock, flags) | ||
46 | ... | ||
47 | |||
48 | 上述例子中,设备可能会先接收到newval2的值,然后接收到newval的值,问题就 | ||
49 | 发生了。不过很容易通过下面方法来修复: | ||
50 | |||
51 | ... | ||
52 | CPU A: spin_lock_irqsave(&dev_lock, flags) | ||
53 | CPU A: val = readl(my_status); | ||
54 | CPU A: ... | ||
55 | CPU A: writel(newval, ring_ptr); | ||
56 | CPU A: (void)readl(safe_register); /* 配置寄存器?*/ | ||
57 | CPU A: spin_unlock_irqrestore(&dev_lock, flags) | ||
58 | ... | ||
59 | CPU B: spin_lock_irqsave(&dev_lock, flags) | ||
60 | CPU B: val = readl(my_status); | ||
61 | CPU B: ... | ||
62 | CPU B: writel(newval2, ring_ptr); | ||
63 | CPU B: (void)readl(safe_register); /* 配置寄存器?*/ | ||
64 | CPU B: spin_unlock_irqrestore(&dev_lock, flags) | ||
65 | |||
66 | 在解决方案中,读取safe_register寄存器,触发IO芯片清刷未处理的写操作, | ||
67 | 再处理后面的读操作,防止引发数据不一致问题。 | ||
diff --git a/Documentation/zh_CN/stable_kernel_rules.txt b/Documentation/zh_CN/stable_kernel_rules.txt index b5b9b0ab02fd..26ea5ed7cd9c 100644 --- a/Documentation/zh_CN/stable_kernel_rules.txt +++ b/Documentation/zh_CN/stable_kernel_rules.txt | |||
@@ -42,7 +42,7 @@ Documentation/stable_kernel_rules.txt 的中文翻译 | |||
42 | 42 | ||
43 | 向稳定版代码树提交补丁的过程: | 43 | 向稳定版代码树提交补丁的过程: |
44 | 44 | ||
45 | - 在确认了补丁符合以上的规则后,将补丁发送到stable@kernel.org。 | 45 | - 在确认了补丁符合以上的规则后,将补丁发送到stable@vger.kernel.org。 |
46 | - 如果补丁被接受到队列里,发送者会收到一个ACK回复,如果没有被接受,收 | 46 | - 如果补丁被接受到队列里,发送者会收到一个ACK回复,如果没有被接受,收 |
47 | 到的是NAK回复。回复需要几天的时间,这取决于开发者的时间安排。 | 47 | 到的是NAK回复。回复需要几天的时间,这取决于开发者的时间安排。 |
48 | - 被接受的补丁会被加到稳定版本队列里,等待其他开发者的审查。 | 48 | - 被接受的补丁会被加到稳定版本队列里,等待其他开发者的审查。 |
diff --git a/drivers/base/core.c b/drivers/base/core.c index 0dd65281cc65..20da3ad1696b 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -614,39 +614,6 @@ void device_remove_bin_file(struct device *dev, | |||
614 | } | 614 | } |
615 | EXPORT_SYMBOL_GPL(device_remove_bin_file); | 615 | EXPORT_SYMBOL_GPL(device_remove_bin_file); |
616 | 616 | ||
617 | /** | ||
618 | * device_schedule_callback_owner - helper to schedule a callback for a device | ||
619 | * @dev: device. | ||
620 | * @func: callback function to invoke later. | ||
621 | * @owner: module owning the callback routine | ||
622 | * | ||
623 | * Attribute methods must not unregister themselves or their parent device | ||
624 | * (which would amount to the same thing). Attempts to do so will deadlock, | ||
625 | * since unregistration is mutually exclusive with driver callbacks. | ||
626 | * | ||
627 | * Instead methods can call this routine, which will attempt to allocate | ||
628 | * and schedule a workqueue request to call back @func with @dev as its | ||
629 | * argument in the workqueue's process context. @dev will be pinned until | ||
630 | * @func returns. | ||
631 | * | ||
632 | * This routine is usually called via the inline device_schedule_callback(), | ||
633 | * which automatically sets @owner to THIS_MODULE. | ||
634 | * | ||
635 | * Returns 0 if the request was submitted, -ENOMEM if storage could not | ||
636 | * be allocated, -ENODEV if a reference to @owner isn't available. | ||
637 | * | ||
638 | * NOTE: This routine won't work if CONFIG_SYSFS isn't set! It uses an | ||
639 | * underlying sysfs routine (since it is intended for use by attribute | ||
640 | * methods), and if sysfs isn't available you'll get nothing but -ENOSYS. | ||
641 | */ | ||
642 | int device_schedule_callback_owner(struct device *dev, | ||
643 | void (*func)(struct device *), struct module *owner) | ||
644 | { | ||
645 | return sysfs_schedule_callback(&dev->kobj, | ||
646 | (void (*)(void *)) func, dev, owner); | ||
647 | } | ||
648 | EXPORT_SYMBOL_GPL(device_schedule_callback_owner); | ||
649 | |||
650 | static void klist_children_get(struct klist_node *n) | 617 | static void klist_children_get(struct klist_node *n) |
651 | { | 618 | { |
652 | struct device_private *p = to_device_private_parent(n); | 619 | struct device_private *p = to_device_private_parent(n); |
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 06051767393f..8986b9f22781 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c | |||
@@ -187,8 +187,8 @@ static void driver_bound(struct device *dev) | |||
187 | return; | 187 | return; |
188 | } | 188 | } |
189 | 189 | ||
190 | pr_debug("driver: '%s': %s: bound to device '%s'\n", dev_name(dev), | 190 | pr_debug("driver: '%s': %s: bound to device '%s'\n", dev->driver->name, |
191 | __func__, dev->driver->name); | 191 | __func__, dev_name(dev)); |
192 | 192 | ||
193 | klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices); | 193 | klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices); |
194 | 194 | ||
diff --git a/drivers/base/topology.c b/drivers/base/topology.c index bbcbd3c43926..be7c1fb7c0c9 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c | |||
@@ -39,8 +39,7 @@ | |||
39 | static ssize_t show_##name(struct device *dev, \ | 39 | static ssize_t show_##name(struct device *dev, \ |
40 | struct device_attribute *attr, char *buf) \ | 40 | struct device_attribute *attr, char *buf) \ |
41 | { \ | 41 | { \ |
42 | unsigned int cpu = dev->id; \ | 42 | return sprintf(buf, "%d\n", topology_##name(dev->id)); \ |
43 | return sprintf(buf, "%d\n", topology_##name(cpu)); \ | ||
44 | } | 43 | } |
45 | 44 | ||
46 | #if defined(topology_thread_cpumask) || defined(topology_core_cpumask) || \ | 45 | #if defined(topology_thread_cpumask) || defined(topology_core_cpumask) || \ |
diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c index abb0f1f53d93..985217626e66 100644 --- a/fs/kernfs/inode.c +++ b/fs/kernfs/inode.c | |||
@@ -48,14 +48,18 @@ void __init kernfs_inode_init(void) | |||
48 | 48 | ||
49 | static struct kernfs_iattrs *kernfs_iattrs(struct kernfs_node *kn) | 49 | static struct kernfs_iattrs *kernfs_iattrs(struct kernfs_node *kn) |
50 | { | 50 | { |
51 | static DEFINE_MUTEX(iattr_mutex); | ||
52 | struct kernfs_iattrs *ret; | ||
51 | struct iattr *iattrs; | 53 | struct iattr *iattrs; |
52 | 54 | ||
55 | mutex_lock(&iattr_mutex); | ||
56 | |||
53 | if (kn->iattr) | 57 | if (kn->iattr) |
54 | return kn->iattr; | 58 | goto out_unlock; |
55 | 59 | ||
56 | kn->iattr = kzalloc(sizeof(struct kernfs_iattrs), GFP_KERNEL); | 60 | kn->iattr = kzalloc(sizeof(struct kernfs_iattrs), GFP_KERNEL); |
57 | if (!kn->iattr) | 61 | if (!kn->iattr) |
58 | return NULL; | 62 | goto out_unlock; |
59 | iattrs = &kn->iattr->ia_iattr; | 63 | iattrs = &kn->iattr->ia_iattr; |
60 | 64 | ||
61 | /* assign default attributes */ | 65 | /* assign default attributes */ |
@@ -65,8 +69,10 @@ static struct kernfs_iattrs *kernfs_iattrs(struct kernfs_node *kn) | |||
65 | iattrs->ia_atime = iattrs->ia_mtime = iattrs->ia_ctime = CURRENT_TIME; | 69 | iattrs->ia_atime = iattrs->ia_mtime = iattrs->ia_ctime = CURRENT_TIME; |
66 | 70 | ||
67 | simple_xattrs_init(&kn->iattr->xattrs); | 71 | simple_xattrs_init(&kn->iattr->xattrs); |
68 | 72 | out_unlock: | |
69 | return kn->iattr; | 73 | ret = kn->iattr; |
74 | mutex_unlock(&iattr_mutex); | ||
75 | return ret; | ||
70 | } | 76 | } |
71 | 77 | ||
72 | static int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr) | 78 | static int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr) |
diff --git a/fs/super.c b/fs/super.c index e9dc3c3fe159..48377f7463c0 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -800,7 +800,10 @@ void emergency_remount(void) | |||
800 | 800 | ||
801 | static DEFINE_IDA(unnamed_dev_ida); | 801 | static DEFINE_IDA(unnamed_dev_ida); |
802 | static DEFINE_SPINLOCK(unnamed_dev_lock);/* protects the above */ | 802 | static DEFINE_SPINLOCK(unnamed_dev_lock);/* protects the above */ |
803 | static int unnamed_dev_start = 0; /* don't bother trying below it */ | 803 | /* Many userspace utilities consider an FSID of 0 invalid. |
804 | * Always return at least 1 from get_anon_bdev. | ||
805 | */ | ||
806 | static int unnamed_dev_start = 1; | ||
804 | 807 | ||
805 | int get_anon_bdev(dev_t *p) | 808 | int get_anon_bdev(dev_t *p) |
806 | { | 809 | { |
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 1b8b91b67fdb..28cc1acd5439 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
@@ -453,95 +453,3 @@ void sysfs_remove_bin_file(struct kobject *kobj, | |||
453 | kernfs_remove_by_name(kobj->sd, attr->attr.name); | 453 | kernfs_remove_by_name(kobj->sd, attr->attr.name); |
454 | } | 454 | } |
455 | EXPORT_SYMBOL_GPL(sysfs_remove_bin_file); | 455 | EXPORT_SYMBOL_GPL(sysfs_remove_bin_file); |
456 | |||
457 | struct sysfs_schedule_callback_struct { | ||
458 | struct list_head workq_list; | ||
459 | struct kobject *kobj; | ||
460 | void (*func)(void *); | ||
461 | void *data; | ||
462 | struct module *owner; | ||
463 | struct work_struct work; | ||
464 | }; | ||
465 | |||
466 | static struct workqueue_struct *sysfs_workqueue; | ||
467 | static DEFINE_MUTEX(sysfs_workq_mutex); | ||
468 | static LIST_HEAD(sysfs_workq); | ||
469 | static void sysfs_schedule_callback_work(struct work_struct *work) | ||
470 | { | ||
471 | struct sysfs_schedule_callback_struct *ss = container_of(work, | ||
472 | struct sysfs_schedule_callback_struct, work); | ||
473 | |||
474 | (ss->func)(ss->data); | ||
475 | kobject_put(ss->kobj); | ||
476 | module_put(ss->owner); | ||
477 | mutex_lock(&sysfs_workq_mutex); | ||
478 | list_del(&ss->workq_list); | ||
479 | mutex_unlock(&sysfs_workq_mutex); | ||
480 | kfree(ss); | ||
481 | } | ||
482 | |||
483 | /** | ||
484 | * sysfs_schedule_callback - helper to schedule a callback for a kobject | ||
485 | * @kobj: object we're acting for. | ||
486 | * @func: callback function to invoke later. | ||
487 | * @data: argument to pass to @func. | ||
488 | * @owner: module owning the callback code | ||
489 | * | ||
490 | * sysfs attribute methods must not unregister themselves or their parent | ||
491 | * kobject (which would amount to the same thing). Attempts to do so will | ||
492 | * deadlock, since unregistration is mutually exclusive with driver | ||
493 | * callbacks. | ||
494 | * | ||
495 | * Instead methods can call this routine, which will attempt to allocate | ||
496 | * and schedule a workqueue request to call back @func with @data as its | ||
497 | * argument in the workqueue's process context. @kobj will be pinned | ||
498 | * until @func returns. | ||
499 | * | ||
500 | * Returns 0 if the request was submitted, -ENOMEM if storage could not | ||
501 | * be allocated, -ENODEV if a reference to @owner isn't available, | ||
502 | * -EAGAIN if a callback has already been scheduled for @kobj. | ||
503 | */ | ||
504 | int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *), | ||
505 | void *data, struct module *owner) | ||
506 | { | ||
507 | struct sysfs_schedule_callback_struct *ss, *tmp; | ||
508 | |||
509 | if (!try_module_get(owner)) | ||
510 | return -ENODEV; | ||
511 | |||
512 | mutex_lock(&sysfs_workq_mutex); | ||
513 | list_for_each_entry_safe(ss, tmp, &sysfs_workq, workq_list) | ||
514 | if (ss->kobj == kobj) { | ||
515 | module_put(owner); | ||
516 | mutex_unlock(&sysfs_workq_mutex); | ||
517 | return -EAGAIN; | ||
518 | } | ||
519 | mutex_unlock(&sysfs_workq_mutex); | ||
520 | |||
521 | if (sysfs_workqueue == NULL) { | ||
522 | sysfs_workqueue = create_singlethread_workqueue("sysfsd"); | ||
523 | if (sysfs_workqueue == NULL) { | ||
524 | module_put(owner); | ||
525 | return -ENOMEM; | ||
526 | } | ||
527 | } | ||
528 | |||
529 | ss = kmalloc(sizeof(*ss), GFP_KERNEL); | ||
530 | if (!ss) { | ||
531 | module_put(owner); | ||
532 | return -ENOMEM; | ||
533 | } | ||
534 | kobject_get(kobj); | ||
535 | ss->kobj = kobj; | ||
536 | ss->func = func; | ||
537 | ss->data = data; | ||
538 | ss->owner = owner; | ||
539 | INIT_WORK(&ss->work, sysfs_schedule_callback_work); | ||
540 | INIT_LIST_HEAD(&ss->workq_list); | ||
541 | mutex_lock(&sysfs_workq_mutex); | ||
542 | list_add_tail(&ss->workq_list, &sysfs_workq); | ||
543 | mutex_unlock(&sysfs_workq_mutex); | ||
544 | queue_work(sysfs_workqueue, &ss->work); | ||
545 | return 0; | ||
546 | } | ||
547 | EXPORT_SYMBOL_GPL(sysfs_schedule_callback); | ||
diff --git a/include/linux/device.h b/include/linux/device.h index 233bbbeb768d..d1d1c055b48e 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -566,12 +566,6 @@ extern int __must_check device_create_bin_file(struct device *dev, | |||
566 | const struct bin_attribute *attr); | 566 | const struct bin_attribute *attr); |
567 | extern void device_remove_bin_file(struct device *dev, | 567 | extern void device_remove_bin_file(struct device *dev, |
568 | const struct bin_attribute *attr); | 568 | const struct bin_attribute *attr); |
569 | extern int device_schedule_callback_owner(struct device *dev, | ||
570 | void (*func)(struct device *dev), struct module *owner); | ||
571 | |||
572 | /* This is a macro to avoid include problems with THIS_MODULE */ | ||
573 | #define device_schedule_callback(dev, func) \ | ||
574 | device_schedule_callback_owner(dev, func, THIS_MODULE) | ||
575 | 569 | ||
576 | /* device resource management */ | 570 | /* device resource management */ |
577 | typedef void (*dr_release_t)(struct device *dev, void *res); | 571 | typedef void (*dr_release_t)(struct device *dev, void *res); |
@@ -932,10 +926,7 @@ extern int device_online(struct device *dev); | |||
932 | extern struct device *__root_device_register(const char *name, | 926 | extern struct device *__root_device_register(const char *name, |
933 | struct module *owner); | 927 | struct module *owner); |
934 | 928 | ||
935 | /* | 929 | /* This is a macro to avoid include problems with THIS_MODULE */ |
936 | * This is a macro to avoid include problems with THIS_MODULE, | ||
937 | * just as per what is done for device_schedule_callback() above. | ||
938 | */ | ||
939 | #define root_device_register(name) \ | 930 | #define root_device_register(name) \ |
940 | __root_device_register(name, THIS_MODULE) | 931 | __root_device_register(name, THIS_MODULE) |
941 | 932 | ||
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 084354b0e814..5ffaa3443712 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h | |||
@@ -179,9 +179,6 @@ struct sysfs_ops { | |||
179 | 179 | ||
180 | #ifdef CONFIG_SYSFS | 180 | #ifdef CONFIG_SYSFS |
181 | 181 | ||
182 | int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *), | ||
183 | void *data, struct module *owner); | ||
184 | |||
185 | int __must_check sysfs_create_dir_ns(struct kobject *kobj, const void *ns); | 182 | int __must_check sysfs_create_dir_ns(struct kobject *kobj, const void *ns); |
186 | void sysfs_remove_dir(struct kobject *kobj); | 183 | void sysfs_remove_dir(struct kobject *kobj); |
187 | int __must_check sysfs_rename_dir_ns(struct kobject *kobj, const char *new_name, | 184 | int __must_check sysfs_rename_dir_ns(struct kobject *kobj, const char *new_name, |
@@ -255,12 +252,6 @@ static inline void sysfs_enable_ns(struct kernfs_node *kn) | |||
255 | 252 | ||
256 | #else /* CONFIG_SYSFS */ | 253 | #else /* CONFIG_SYSFS */ |
257 | 254 | ||
258 | static inline int sysfs_schedule_callback(struct kobject *kobj, | ||
259 | void (*func)(void *), void *data, struct module *owner) | ||
260 | { | ||
261 | return -ENOSYS; | ||
262 | } | ||
263 | |||
264 | static inline int sysfs_create_dir_ns(struct kobject *kobj, const void *ns) | 255 | static inline int sysfs_create_dir_ns(struct kobject *kobj, const void *ns) |
265 | { | 256 | { |
266 | return 0; | 257 | return 0; |