diff options
author | Paul Mundt <lethal@linux-sh.org> | 2011-01-13 01:06:28 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2011-01-13 01:06:28 -0500 |
commit | f43dc23d5ea91fca257be02138a255f02d98e806 (patch) | |
tree | b29722f6e965316e90ac97abf79923ced250dc21 /fs/char_dev.c | |
parent | f8e53553f452dcbf67cb89c8cba63a1cd6eb4cc0 (diff) | |
parent | 4162cf64973df51fc885825bc9ca4d055891c49f (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6 into common/serial-rework
Conflicts:
arch/sh/kernel/cpu/sh2/setup-sh7619.c
arch/sh/kernel/cpu/sh2a/setup-mxg.c
arch/sh/kernel/cpu/sh2a/setup-sh7201.c
arch/sh/kernel/cpu/sh2a/setup-sh7203.c
arch/sh/kernel/cpu/sh2a/setup-sh7206.c
arch/sh/kernel/cpu/sh3/setup-sh7705.c
arch/sh/kernel/cpu/sh3/setup-sh770x.c
arch/sh/kernel/cpu/sh3/setup-sh7710.c
arch/sh/kernel/cpu/sh3/setup-sh7720.c
arch/sh/kernel/cpu/sh4/setup-sh4-202.c
arch/sh/kernel/cpu/sh4/setup-sh7750.c
arch/sh/kernel/cpu/sh4/setup-sh7760.c
arch/sh/kernel/cpu/sh4a/setup-sh7343.c
arch/sh/kernel/cpu/sh4a/setup-sh7366.c
arch/sh/kernel/cpu/sh4a/setup-sh7722.c
arch/sh/kernel/cpu/sh4a/setup-sh7723.c
arch/sh/kernel/cpu/sh4a/setup-sh7724.c
arch/sh/kernel/cpu/sh4a/setup-sh7763.c
arch/sh/kernel/cpu/sh4a/setup-sh7770.c
arch/sh/kernel/cpu/sh4a/setup-sh7780.c
arch/sh/kernel/cpu/sh4a/setup-sh7785.c
arch/sh/kernel/cpu/sh4a/setup-sh7786.c
arch/sh/kernel/cpu/sh4a/setup-shx3.c
arch/sh/kernel/cpu/sh5/setup-sh5.c
drivers/serial/sh-sci.c
drivers/serial/sh-sci.h
include/linux/serial_sci.h
Diffstat (limited to 'fs/char_dev.c')
-rw-r--r-- | fs/char_dev.c | 50 |
1 files changed, 32 insertions, 18 deletions
diff --git a/fs/char_dev.c b/fs/char_dev.c index b7c9d5187a75..e5b9df993b93 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/major.h> | 13 | #include <linux/major.h> |
14 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/smp_lock.h> | ||
17 | #include <linux/seq_file.h> | 16 | #include <linux/seq_file.h> |
18 | 17 | ||
19 | #include <linux/kobject.h> | 18 | #include <linux/kobject.h> |
@@ -21,6 +20,7 @@ | |||
21 | #include <linux/cdev.h> | 20 | #include <linux/cdev.h> |
22 | #include <linux/mutex.h> | 21 | #include <linux/mutex.h> |
23 | #include <linux/backing-dev.h> | 22 | #include <linux/backing-dev.h> |
23 | #include <linux/tty.h> | ||
24 | 24 | ||
25 | #include "internal.h" | 25 | #include "internal.h" |
26 | 26 | ||
@@ -32,6 +32,7 @@ | |||
32 | * - no readahead or I/O queue unplugging required | 32 | * - no readahead or I/O queue unplugging required |
33 | */ | 33 | */ |
34 | struct backing_dev_info directly_mappable_cdev_bdi = { | 34 | struct backing_dev_info directly_mappable_cdev_bdi = { |
35 | .name = "char", | ||
35 | .capabilities = ( | 36 | .capabilities = ( |
36 | #ifdef CONFIG_MMU | 37 | #ifdef CONFIG_MMU |
37 | /* permit private copies of the data to be taken */ | 38 | /* permit private copies of the data to be taken */ |
@@ -39,7 +40,9 @@ struct backing_dev_info directly_mappable_cdev_bdi = { | |||
39 | #endif | 40 | #endif |
40 | /* permit direct mmap, for read, write or exec */ | 41 | /* permit direct mmap, for read, write or exec */ |
41 | BDI_CAP_MAP_DIRECT | | 42 | BDI_CAP_MAP_DIRECT | |
42 | BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP), | 43 | BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP | |
44 | /* no writeback happens */ | ||
45 | BDI_CAP_NO_ACCT_AND_WRITEBACK), | ||
43 | }; | 46 | }; |
44 | 47 | ||
45 | static struct kobj_map *cdev_map; | 48 | static struct kobj_map *cdev_map; |
@@ -238,8 +241,10 @@ int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, | |||
238 | } | 241 | } |
239 | 242 | ||
240 | /** | 243 | /** |
241 | * register_chrdev() - Register a major number for character devices. | 244 | * __register_chrdev() - create and register a cdev occupying a range of minors |
242 | * @major: major device number or 0 for dynamic allocation | 245 | * @major: major device number or 0 for dynamic allocation |
246 | * @baseminor: first of the requested range of minor numbers | ||
247 | * @count: the number of minor numbers required | ||
243 | * @name: name of this range of devices | 248 | * @name: name of this range of devices |
244 | * @fops: file operations associated with this devices | 249 | * @fops: file operations associated with this devices |
245 | * | 250 | * |
@@ -255,19 +260,16 @@ int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, | |||
255 | * /dev. It only helps to keep track of the different owners of devices. If | 260 | * /dev. It only helps to keep track of the different owners of devices. If |
256 | * your module name has only one type of devices it's ok to use e.g. the name | 261 | * your module name has only one type of devices it's ok to use e.g. the name |
257 | * of the module here. | 262 | * of the module here. |
258 | * | ||
259 | * This function registers a range of 256 minor numbers. The first minor number | ||
260 | * is 0. | ||
261 | */ | 263 | */ |
262 | int register_chrdev(unsigned int major, const char *name, | 264 | int __register_chrdev(unsigned int major, unsigned int baseminor, |
263 | const struct file_operations *fops) | 265 | unsigned int count, const char *name, |
266 | const struct file_operations *fops) | ||
264 | { | 267 | { |
265 | struct char_device_struct *cd; | 268 | struct char_device_struct *cd; |
266 | struct cdev *cdev; | 269 | struct cdev *cdev; |
267 | char *s; | ||
268 | int err = -ENOMEM; | 270 | int err = -ENOMEM; |
269 | 271 | ||
270 | cd = __register_chrdev_region(major, 0, 256, name); | 272 | cd = __register_chrdev_region(major, baseminor, count, name); |
271 | if (IS_ERR(cd)) | 273 | if (IS_ERR(cd)) |
272 | return PTR_ERR(cd); | 274 | return PTR_ERR(cd); |
273 | 275 | ||
@@ -278,10 +280,8 @@ int register_chrdev(unsigned int major, const char *name, | |||
278 | cdev->owner = fops->owner; | 280 | cdev->owner = fops->owner; |
279 | cdev->ops = fops; | 281 | cdev->ops = fops; |
280 | kobject_set_name(&cdev->kobj, "%s", name); | 282 | kobject_set_name(&cdev->kobj, "%s", name); |
281 | for (s = strchr(kobject_name(&cdev->kobj),'/'); s; s = strchr(s, '/')) | ||
282 | *s = '!'; | ||
283 | 283 | ||
284 | err = cdev_add(cdev, MKDEV(cd->major, 0), 256); | 284 | err = cdev_add(cdev, MKDEV(cd->major, baseminor), count); |
285 | if (err) | 285 | if (err) |
286 | goto out; | 286 | goto out; |
287 | 287 | ||
@@ -291,7 +291,7 @@ int register_chrdev(unsigned int major, const char *name, | |||
291 | out: | 291 | out: |
292 | kobject_put(&cdev->kobj); | 292 | kobject_put(&cdev->kobj); |
293 | out2: | 293 | out2: |
294 | kfree(__unregister_chrdev_region(cd->major, 0, 256)); | 294 | kfree(__unregister_chrdev_region(cd->major, baseminor, count)); |
295 | return err; | 295 | return err; |
296 | } | 296 | } |
297 | 297 | ||
@@ -317,10 +317,23 @@ void unregister_chrdev_region(dev_t from, unsigned count) | |||
317 | } | 317 | } |
318 | } | 318 | } |
319 | 319 | ||
320 | void unregister_chrdev(unsigned int major, const char *name) | 320 | /** |
321 | * __unregister_chrdev - unregister and destroy a cdev | ||
322 | * @major: major device number | ||
323 | * @baseminor: first of the range of minor numbers | ||
324 | * @count: the number of minor numbers this cdev is occupying | ||
325 | * @name: name of this range of devices | ||
326 | * | ||
327 | * Unregister and destroy the cdev occupying the region described by | ||
328 | * @major, @baseminor and @count. This function undoes what | ||
329 | * __register_chrdev() did. | ||
330 | */ | ||
331 | void __unregister_chrdev(unsigned int major, unsigned int baseminor, | ||
332 | unsigned int count, const char *name) | ||
321 | { | 333 | { |
322 | struct char_device_struct *cd; | 334 | struct char_device_struct *cd; |
323 | cd = __unregister_chrdev_region(major, 0, 256); | 335 | |
336 | cd = __unregister_chrdev_region(major, baseminor, count); | ||
324 | if (cd && cd->cdev) | 337 | if (cd && cd->cdev) |
325 | cdev_del(cd->cdev); | 338 | cdev_del(cd->cdev); |
326 | kfree(cd); | 339 | kfree(cd); |
@@ -443,6 +456,7 @@ static void cdev_purge(struct cdev *cdev) | |||
443 | */ | 456 | */ |
444 | const struct file_operations def_chr_fops = { | 457 | const struct file_operations def_chr_fops = { |
445 | .open = chrdev_open, | 458 | .open = chrdev_open, |
459 | .llseek = noop_llseek, | ||
446 | }; | 460 | }; |
447 | 461 | ||
448 | static struct kobject *exact_match(dev_t dev, int *part, void *data) | 462 | static struct kobject *exact_match(dev_t dev, int *part, void *data) |
@@ -569,6 +583,6 @@ EXPORT_SYMBOL(cdev_alloc); | |||
569 | EXPORT_SYMBOL(cdev_del); | 583 | EXPORT_SYMBOL(cdev_del); |
570 | EXPORT_SYMBOL(cdev_add); | 584 | EXPORT_SYMBOL(cdev_add); |
571 | EXPORT_SYMBOL(cdev_index); | 585 | EXPORT_SYMBOL(cdev_index); |
572 | EXPORT_SYMBOL(register_chrdev); | 586 | EXPORT_SYMBOL(__register_chrdev); |
573 | EXPORT_SYMBOL(unregister_chrdev); | 587 | EXPORT_SYMBOL(__unregister_chrdev); |
574 | EXPORT_SYMBOL(directly_mappable_cdev_bdi); | 588 | EXPORT_SYMBOL(directly_mappable_cdev_bdi); |