aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/resource.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/resource.c')
-rw-r--r--kernel/resource.c63
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,
618EXPORT_SYMBOL(__release_region); 618EXPORT_SYMBOL(__release_region);
619 619
620/* 620/*
621 * Managed region resource
622 */
623struct region_devres {
624 struct resource *parent;
625 resource_size_t start;
626 resource_size_t n;
627};
628
629static 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
636static 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
644struct 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}
668EXPORT_SYMBOL(__devm_request_region);
669
670void __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}
679EXPORT_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