Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.20-rc1 191 lines 5.8 kB view raw
1/* 2 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 3 * This program is free software; you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation; either version 2 of the License, or (at 6 * your option) any later version. 7 * 8 * This program is distributed in the hope that it will be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 * General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License along 14 * with this program; if not, write to the Free Software Foundation, Inc., 15 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 16 * 17 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 18 */ 19 20/* Purpose: Prevent PCMCIA cards from using motherboard resources. */ 21 22#include <linux/kernel.h> 23#include <linux/init.h> 24#include <linux/types.h> 25#include <linux/pci.h> 26#include <linux/ioport.h> 27#include <asm/io.h> 28 29#include <acpi/acpi_bus.h> 30#include <acpi/acpi_drivers.h> 31 32#define _COMPONENT ACPI_SYSTEM_COMPONENT 33ACPI_MODULE_NAME("acpi_motherboard") 34 35/* Dell use PNP0C01 instead of PNP0C02 */ 36#define ACPI_MB_HID1 "PNP0C01" 37#define ACPI_MB_HID2 "PNP0C02" 38/** 39 * Doesn't care about legacy IO ports, only IO ports beyond 0x1000 are reserved 40 * Doesn't care about the failure of 'request_region', since other may reserve 41 * the io ports as well 42 */ 43#define IS_RESERVED_ADDR(base, len) \ 44 (((len) > 0) && ((base) > 0) && ((base) + (len) < IO_SPACE_LIMIT) \ 45 && ((base) + (len) > PCIBIOS_MIN_IO)) 46/* 47 * Clearing the flag (IORESOURCE_BUSY) allows drivers to use 48 * the io ports if they really know they can use it, while 49 * still preventing hotplug PCI devices from using it. 50 */ 51 52/* 53 * When CONFIG_PNP is enabled, pnp/system.c binds to PNP0C01 54 * and PNP0C02, redundant with acpi_reserve_io_ranges(). 55 * But acpi_reserve_io_ranges() is necessary for !CONFIG_PNP. 56 */ 57static acpi_status acpi_reserve_io_ranges(struct acpi_resource *res, void *data) 58{ 59 struct resource *requested_res = NULL; 60 61 62 if (res->type == ACPI_RESOURCE_TYPE_IO) { 63 struct acpi_resource_io *io_res = &res->data.io; 64 65 if (io_res->minimum != io_res->maximum) 66 return AE_OK; 67 if (IS_RESERVED_ADDR 68 (io_res->minimum, io_res->address_length)) { 69 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 70 "Motherboard resources 0x%08x - 0x%08x\n", 71 io_res->minimum, 72 io_res->minimum + 73 io_res->address_length)); 74 requested_res = 75 request_region(io_res->minimum, 76 io_res->address_length, "motherboard"); 77 } 78 } else if (res->type == ACPI_RESOURCE_TYPE_FIXED_IO) { 79 struct acpi_resource_fixed_io *fixed_io_res = 80 &res->data.fixed_io; 81 82 if (IS_RESERVED_ADDR 83 (fixed_io_res->address, fixed_io_res->address_length)) { 84 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 85 "Motherboard resources 0x%08x - 0x%08x\n", 86 fixed_io_res->address, 87 fixed_io_res->address + 88 fixed_io_res->address_length)); 89 requested_res = 90 request_region(fixed_io_res->address, 91 fixed_io_res->address_length, 92 "motherboard"); 93 } 94 } else { 95 /* Memory mapped IO? */ 96 } 97 98 if (requested_res) 99 requested_res->flags &= ~IORESOURCE_BUSY; 100 return AE_OK; 101} 102 103static int acpi_motherboard_add(struct acpi_device *device) 104{ 105 if (!device) 106 return -EINVAL; 107 acpi_walk_resources(device->handle, METHOD_NAME__CRS, 108 acpi_reserve_io_ranges, NULL); 109 110 return 0; 111} 112 113static struct acpi_driver acpi_motherboard_driver1 = { 114 .name = "motherboard", 115 .class = "", 116 .ids = ACPI_MB_HID1, 117 .ops = { 118 .add = acpi_motherboard_add, 119 }, 120}; 121 122static struct acpi_driver acpi_motherboard_driver2 = { 123 .name = "motherboard", 124 .class = "", 125 .ids = ACPI_MB_HID2, 126 .ops = { 127 .add = acpi_motherboard_add, 128 }, 129}; 130 131static void __init acpi_request_region (struct acpi_generic_address *addr, 132 unsigned int length, char *desc) 133{ 134 if (!addr->address || !length) 135 return; 136 137 if (addr->address_space_id == ACPI_ADR_SPACE_SYSTEM_IO) 138 request_region(addr->address, length, desc); 139 else if (addr->address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) 140 request_mem_region(addr->address, length, desc); 141} 142 143static void __init acpi_reserve_resources(void) 144{ 145 acpi_request_region(&acpi_gbl_FADT->xpm1a_evt_blk, 146 acpi_gbl_FADT->pm1_evt_len, "ACPI PM1a_EVT_BLK"); 147 148 acpi_request_region(&acpi_gbl_FADT->xpm1b_evt_blk, 149 acpi_gbl_FADT->pm1_evt_len, "ACPI PM1b_EVT_BLK"); 150 151 acpi_request_region(&acpi_gbl_FADT->xpm1a_cnt_blk, 152 acpi_gbl_FADT->pm1_cnt_len, "ACPI PM1a_CNT_BLK"); 153 154 acpi_request_region(&acpi_gbl_FADT->xpm1b_cnt_blk, 155 acpi_gbl_FADT->pm1_cnt_len, "ACPI PM1b_CNT_BLK"); 156 157 if (acpi_gbl_FADT->pm_tm_len == 4) 158 acpi_request_region(&acpi_gbl_FADT->xpm_tmr_blk, 4, "ACPI PM_TMR"); 159 160 acpi_request_region(&acpi_gbl_FADT->xpm2_cnt_blk, 161 acpi_gbl_FADT->pm2_cnt_len, "ACPI PM2_CNT_BLK"); 162 163 /* Length of GPE blocks must be a non-negative multiple of 2 */ 164 165 if (!(acpi_gbl_FADT->gpe0_blk_len & 0x1)) 166 acpi_request_region(&acpi_gbl_FADT->xgpe0_blk, 167 acpi_gbl_FADT->gpe0_blk_len, "ACPI GPE0_BLK"); 168 169 if (!(acpi_gbl_FADT->gpe1_blk_len & 0x1)) 170 acpi_request_region(&acpi_gbl_FADT->xgpe1_blk, 171 acpi_gbl_FADT->gpe1_blk_len, "ACPI GPE1_BLK"); 172} 173 174static int __init acpi_motherboard_init(void) 175{ 176 acpi_bus_register_driver(&acpi_motherboard_driver1); 177 acpi_bus_register_driver(&acpi_motherboard_driver2); 178 /* 179 * Guarantee motherboard IO reservation first 180 * This module must run after scan.c 181 */ 182 if (!acpi_disabled) 183 acpi_reserve_resources(); 184 return 0; 185} 186 187/** 188 * Reserve motherboard resources after PCI claim BARs, 189 * but before PCI assign resources for uninitialized PCI devices 190 */ 191fs_initcall(acpi_motherboard_init);