diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-07 18:41:01 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-07 18:41:01 -0500 |
| commit | b424e8d3b438e841cd1700f6433a100a5d611e4a (patch) | |
| tree | 545638d0b925de4c7f740286760767cca86cb91e /kernel | |
| parent | 7c7758f99d39d529a64d4f60d22129bbf2f16d74 (diff) | |
| parent | f6dc1e5e3d4b523e1616b43beddb04e4fb1d376a (diff) | |
Merge branch 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6
* 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6: (98 commits)
PCI PM: Put PM callbacks in the order of execution
PCI PM: Run default PM callbacks for all devices using new framework
PCI PM: Register power state of devices during initialization
PCI PM: Call pci_fixup_device from legacy routines
PCI PM: Rearrange code in pci-driver.c
PCI PM: Avoid touching devices behind bridges in unknown state
PCI PM: Move pci_has_legacy_pm_support
PCI PM: Power-manage devices without drivers during suspend-resume
PCI PM: Add suspend counterpart of pci_reenable_device
PCI PM: Fix poweroff and restore callbacks
PCI: Use msleep instead of cpu_relax during ASPM link retraining
PCI: PCIe portdrv: Add kerneldoc comments to remining core funtions
PCI: PCIe portdrv: Rearrange code so that related things are together
PCI: PCIe portdrv: Fix suspend and resume of PCI Express port services
PCI: PCIe portdrv: Add kerneldoc comments to some core functions
x86/PCI: Do not use interrupt links for devices using MSI-X
net: sfc: Use pci_clear_master() to disable bus mastering
PCI: Add pci_clear_master() as opposite of pci_set_master()
PCI hotplug: remove redundant test in cpq hotplug
PCI: pciehp: cleanup register and field definitions
...
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/resource.c | 61 |
1 files changed, 58 insertions, 3 deletions
diff --git a/kernel/resource.c b/kernel/resource.c index e633106b12f6..ca6a1536b205 100644 --- a/kernel/resource.c +++ b/kernel/resource.c | |||
| @@ -623,7 +623,7 @@ resource_size_t resource_alignment(struct resource *res) | |||
| 623 | */ | 623 | */ |
| 624 | struct resource * __request_region(struct resource *parent, | 624 | struct resource * __request_region(struct resource *parent, |
| 625 | resource_size_t start, resource_size_t n, | 625 | resource_size_t start, resource_size_t n, |
| 626 | const char *name) | 626 | const char *name, int flags) |
| 627 | { | 627 | { |
| 628 | struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); | 628 | struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); |
| 629 | 629 | ||
| @@ -634,6 +634,7 @@ struct resource * __request_region(struct resource *parent, | |||
| 634 | res->start = start; | 634 | res->start = start; |
| 635 | res->end = start + n - 1; | 635 | res->end = start + n - 1; |
| 636 | res->flags = IORESOURCE_BUSY; | 636 | res->flags = IORESOURCE_BUSY; |
| 637 | res->flags |= flags; | ||
| 637 | 638 | ||
| 638 | write_lock(&resource_lock); | 639 | write_lock(&resource_lock); |
| 639 | 640 | ||
| @@ -679,7 +680,7 @@ int __check_region(struct resource *parent, resource_size_t start, | |||
| 679 | { | 680 | { |
| 680 | struct resource * res; | 681 | struct resource * res; |
| 681 | 682 | ||
| 682 | res = __request_region(parent, start, n, "check-region"); | 683 | res = __request_region(parent, start, n, "check-region", 0); |
| 683 | if (!res) | 684 | if (!res) |
| 684 | return -EBUSY; | 685 | return -EBUSY; |
| 685 | 686 | ||
| @@ -776,7 +777,7 @@ struct resource * __devm_request_region(struct device *dev, | |||
| 776 | dr->start = start; | 777 | dr->start = start; |
| 777 | dr->n = n; | 778 | dr->n = n; |
| 778 | 779 | ||
| 779 | res = __request_region(parent, start, n, name); | 780 | res = __request_region(parent, start, n, name, 0); |
| 780 | if (res) | 781 | if (res) |
| 781 | devres_add(dev, dr); | 782 | devres_add(dev, dr); |
| 782 | else | 783 | else |
| @@ -876,3 +877,57 @@ int iomem_map_sanity_check(resource_size_t addr, unsigned long size) | |||
| 876 | 877 | ||
| 877 | return err; | 878 | return err; |
| 878 | } | 879 | } |
| 880 | |||
| 881 | #ifdef CONFIG_STRICT_DEVMEM | ||
| 882 | static int strict_iomem_checks = 1; | ||
| 883 | #else | ||
| 884 | static int strict_iomem_checks; | ||
| 885 | #endif | ||
| 886 | |||
| 887 | /* | ||
| 888 | * check if an address is reserved in the iomem resource tree | ||
| 889 | * returns 1 if reserved, 0 if not reserved. | ||
| 890 | */ | ||
| 891 | int iomem_is_exclusive(u64 addr) | ||
| 892 | { | ||
| 893 | struct resource *p = &iomem_resource; | ||
| 894 | int err = 0; | ||
| 895 | loff_t l; | ||
| 896 | int size = PAGE_SIZE; | ||
| 897 | |||
| 898 | if (!strict_iomem_checks) | ||
| 899 | return 0; | ||
| 900 | |||
| 901 | addr = addr & PAGE_MASK; | ||
| 902 | |||
| 903 | read_lock(&resource_lock); | ||
| 904 | for (p = p->child; p ; p = r_next(NULL, p, &l)) { | ||
| 905 | /* | ||
| 906 | * We can probably skip the resources without | ||
| 907 | * IORESOURCE_IO attribute? | ||
| 908 | */ | ||
| 909 | if (p->start >= addr + size) | ||
| 910 | break; | ||
| 911 | if (p->end < addr) | ||
| 912 | continue; | ||
| 913 | if (p->flags & IORESOURCE_BUSY && | ||
| 914 | p->flags & IORESOURCE_EXCLUSIVE) { | ||
| 915 | err = 1; | ||
| 916 | break; | ||
| 917 | } | ||
| 918 | } | ||
| 919 | read_unlock(&resource_lock); | ||
| 920 | |||
| 921 | return err; | ||
| 922 | } | ||
| 923 | |||
| 924 | static int __init strict_iomem(char *str) | ||
| 925 | { | ||
| 926 | if (strstr(str, "relaxed")) | ||
| 927 | strict_iomem_checks = 0; | ||
| 928 | if (strstr(str, "strict")) | ||
| 929 | strict_iomem_checks = 1; | ||
| 930 | return 1; | ||
| 931 | } | ||
| 932 | |||
| 933 | __setup("iomem=", strict_iomem); | ||
