diff options
Diffstat (limited to 'kernel/resource.c')
-rw-r--r-- | kernel/resource.c | 63 |
1 files changed, 62 insertions, 1 deletions
diff --git a/kernel/resource.c b/kernel/resource.c index 7b9a497419d9..bdb55a33f969 100644 --- a/kernel/resource.c +++ b/kernel/resource.c | |||
@@ -8,7 +8,6 @@ | |||
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/sched.h> | ||
12 | #include <linux/errno.h> | 11 | #include <linux/errno.h> |
13 | #include <linux/ioport.h> | 12 | #include <linux/ioport.h> |
14 | #include <linux/init.h> | 13 | #include <linux/init.h> |
@@ -17,6 +16,7 @@ | |||
17 | #include <linux/fs.h> | 16 | #include <linux/fs.h> |
18 | #include <linux/proc_fs.h> | 17 | #include <linux/proc_fs.h> |
19 | #include <linux/seq_file.h> | 18 | #include <linux/seq_file.h> |
19 | #include <linux/device.h> | ||
20 | #include <asm/io.h> | 20 | #include <asm/io.h> |
21 | 21 | ||
22 | 22 | ||
@@ -618,6 +618,67 @@ void __release_region(struct resource *parent, resource_size_t start, | |||
618 | EXPORT_SYMBOL(__release_region); | 618 | EXPORT_SYMBOL(__release_region); |
619 | 619 | ||
620 | /* | 620 | /* |
621 | * Managed region resource | ||
622 | */ | ||
623 | struct region_devres { | ||
624 | struct resource *parent; | ||
625 | resource_size_t start; | ||
626 | resource_size_t n; | ||
627 | }; | ||
628 | |||
629 | static void devm_region_release(struct device *dev, void *res) | ||
630 | { | ||
631 | struct region_devres *this = res; | ||
632 | |||
633 | __release_region(this->parent, this->start, this->n); | ||
634 | } | ||
635 | |||
636 | static int devm_region_match(struct device *dev, void *res, void *match_data) | ||
637 | { | ||
638 | struct region_devres *this = res, *match = match_data; | ||
639 | |||
640 | return this->parent == match->parent && | ||
641 | this->start == match->start && this->n == match->n; | ||
642 | } | ||
643 | |||
644 | struct resource * __devm_request_region(struct device *dev, | ||
645 | struct resource *parent, resource_size_t start, | ||
646 | resource_size_t n, const char *name) | ||
647 | { | ||
648 | struct region_devres *dr = NULL; | ||
649 | struct resource *res; | ||
650 | |||
651 | dr = devres_alloc(devm_region_release, sizeof(struct region_devres), | ||
652 | GFP_KERNEL); | ||
653 | if (!dr) | ||
654 | return NULL; | ||
655 | |||
656 | dr->parent = parent; | ||
657 | dr->start = start; | ||
658 | dr->n = n; | ||
659 | |||
660 | res = __request_region(parent, start, n, name); | ||
661 | if (res) | ||
662 | devres_add(dev, dr); | ||
663 | else | ||
664 | devres_free(dr); | ||
665 | |||
666 | return res; | ||
667 | } | ||
668 | EXPORT_SYMBOL(__devm_request_region); | ||
669 | |||
670 | void __devm_release_region(struct device *dev, struct resource *parent, | ||
671 | resource_size_t start, resource_size_t n) | ||
672 | { | ||
673 | struct region_devres match_data = { parent, start, n }; | ||
674 | |||
675 | __release_region(parent, start, n); | ||
676 | WARN_ON(devres_destroy(dev, devm_region_release, devm_region_match, | ||
677 | &match_data)); | ||
678 | } | ||
679 | EXPORT_SYMBOL(__devm_release_region); | ||
680 | |||
681 | /* | ||
621 | * Called from init/main.c to reserve IO ports. | 682 | * Called from init/main.c to reserve IO ports. |
622 | */ | 683 | */ |
623 | #define MAXRESERVE 4 | 684 | #define MAXRESERVE 4 |