clk: Drop the rate range on clk_put()
[linux-2.6-microblaze.git] / arch / x86 / kernel / resource.c
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/dmi.h>
3 #include <linux/ioport.h>
4 #include <asm/e820/api.h>
5
6 static void resource_clip(struct resource *res, resource_size_t start,
7                           resource_size_t end)
8 {
9         resource_size_t low = 0, high = 0;
10
11         if (res->end < start || res->start > end)
12                 return;         /* no conflict */
13
14         if (res->start < start)
15                 low = start - res->start;
16
17         if (res->end > end)
18                 high = res->end - end;
19
20         /* Keep the area above or below the conflict, whichever is larger */
21         if (low > high)
22                 res->end = start - 1;
23         else
24                 res->start = end + 1;
25 }
26
27 /*
28  * Some BIOS-es contain a bug where they add addresses which map to
29  * system RAM in the PCI host bridge window returned by the ACPI _CRS
30  * method, see commit 4dc2287c1805 ("x86: avoid E820 regions when
31  * allocating address space"). To avoid this Linux by default excludes
32  * E820 reservations when allocating addresses since 2010.
33  * In 2019 some systems have shown-up with E820 reservations which cover
34  * the entire _CRS returned PCI host bridge window, causing all attempts
35  * to assign memory to PCI BARs to fail if Linux uses E820 reservations.
36  *
37  * Ideally Linux would fully stop using E820 reservations, but then
38  * the old systems this was added for will regress.
39  * Instead keep the old behavior for old systems, while ignoring the
40  * E820 reservations for any systems from now on.
41  */
42 static void remove_e820_regions(struct resource *avail)
43 {
44         int i, year = dmi_get_bios_year();
45         struct e820_entry *entry;
46
47         if (year >= 2018)
48                 return;
49
50         pr_info_once("PCI: Removing E820 reservations from host bridge windows\n");
51
52         for (i = 0; i < e820_table->nr_entries; i++) {
53                 entry = &e820_table->entries[i];
54
55                 resource_clip(avail, entry->addr,
56                               entry->addr + entry->size - 1);
57         }
58 }
59
60 void arch_remove_reservations(struct resource *avail)
61 {
62         /*
63          * Trim out BIOS area (high 2MB) and E820 regions. We do not remove
64          * the low 1MB unconditionally, as this area is needed for some ISA
65          * cards requiring a memory range, e.g. the i82365 PCMCIA controller.
66          */
67         if (avail->flags & IORESOURCE_MEM) {
68                 resource_clip(avail, BIOS_ROM_BASE, BIOS_ROM_END);
69
70                 remove_e820_regions(avail);
71         }
72 }