11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pnpacpi -- PnP ACPI driver 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (c) 2004 Matthieu Castet <castet.matthieu@free.fr> 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (c) 2004 Li Shaohua <shaohua.li@intel.com> 640ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas * Copyright (C) 2008 Hewlett-Packard Development Company, L.P. 740ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas * Bjorn Helgaas <bjorn.helgaas@hp.com> 850eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore * 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is free software; you can redistribute it and/or modify it 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * under the terms of the GNU General Public License as published by the 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Free Software Foundation; either version 2, or (at your option) any 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * later version. 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is distributed in the hope that it will be useful, but 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * WITHOUT ANY WARRANTY; without even the implied warranty of 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * General Public License for more details. 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * You should have received a copy of the GNU General Public License 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * along with this program; if not, write to the Free Software 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h> 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/acpi.h> 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/pci.h> 2602d83b5da3efa3c278ce87db2637f3dd6837166dBjorn Helgaas#include <linux/pnp.h> 275a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 2802d83b5da3efa3c278ce87db2637f3dd6837166dBjorn Helgaas#include "../base.h" 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "pnpacpi.h" 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_IA64 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define valid_IRQ(i) (1) 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define valid_IRQ(i) (((i) != 0) && ((i) != 2)) 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Allocated Resources 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 40cd7ec927d9cd3d2001cbbdce872bd73f6e49c986Bjorn Helgaasstatic int irq_flags(int triggering, int polarity, int shareable) 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 42cd7ec927d9cd3d2001cbbdce872bd73f6e49c986Bjorn Helgaas int flags; 43cd7ec927d9cd3d2001cbbdce872bd73f6e49c986Bjorn Helgaas 4450eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore if (triggering == ACPI_LEVEL_SENSITIVE) { 451c6e7d0aeecac38e66b1bb63e3eff07b2a1c2f2cBjorn Helgaas if (polarity == ACPI_ACTIVE_LOW) 46cd7ec927d9cd3d2001cbbdce872bd73f6e49c986Bjorn Helgaas flags = IORESOURCE_IRQ_LOWLEVEL; 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 48cd7ec927d9cd3d2001cbbdce872bd73f6e49c986Bjorn Helgaas flags = IORESOURCE_IRQ_HIGHLEVEL; 499dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas } else { 501c6e7d0aeecac38e66b1bb63e3eff07b2a1c2f2cBjorn Helgaas if (polarity == ACPI_ACTIVE_LOW) 51cd7ec927d9cd3d2001cbbdce872bd73f6e49c986Bjorn Helgaas flags = IORESOURCE_IRQ_LOWEDGE; 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 53cd7ec927d9cd3d2001cbbdce872bd73f6e49c986Bjorn Helgaas flags = IORESOURCE_IRQ_HIGHEDGE; 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 55cd7ec927d9cd3d2001cbbdce872bd73f6e49c986Bjorn Helgaas 56a993273beae8022390e48fe9205480565ad470abBjorn Helgaas if (shareable == ACPI_SHARED) 57cd7ec927d9cd3d2001cbbdce872bd73f6e49c986Bjorn Helgaas flags |= IORESOURCE_IRQ_SHAREABLE; 58cd7ec927d9cd3d2001cbbdce872bd73f6e49c986Bjorn Helgaas 59cd7ec927d9cd3d2001cbbdce872bd73f6e49c986Bjorn Helgaas return flags; 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 62e9fe9e188118a0a34c6200d9b10ea6247f53592dBjorn Helgaasstatic void decode_irq_flags(struct pnp_dev *dev, int flags, int *triggering, 63a993273beae8022390e48fe9205480565ad470abBjorn Helgaas int *polarity, int *shareable) 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 65e9fe9e188118a0a34c6200d9b10ea6247f53592dBjorn Helgaas switch (flags & (IORESOURCE_IRQ_LOWLEVEL | IORESOURCE_IRQ_HIGHLEVEL | 66e9fe9e188118a0a34c6200d9b10ea6247f53592dBjorn Helgaas IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE)) { 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IORESOURCE_IRQ_LOWLEVEL: 6850eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore *triggering = ACPI_LEVEL_SENSITIVE; 6950eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore *polarity = ACPI_ACTIVE_LOW; 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 711c6e7d0aeecac38e66b1bb63e3eff07b2a1c2f2cBjorn Helgaas case IORESOURCE_IRQ_HIGHLEVEL: 7250eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore *triggering = ACPI_LEVEL_SENSITIVE; 7350eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore *polarity = ACPI_ACTIVE_HIGH; 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IORESOURCE_IRQ_LOWEDGE: 7650eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore *triggering = ACPI_EDGE_SENSITIVE; 7750eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore *polarity = ACPI_ACTIVE_LOW; 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IORESOURCE_IRQ_HIGHEDGE: 8050eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore *triggering = ACPI_EDGE_SENSITIVE; 8150eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore *polarity = ACPI_ACTIVE_HIGH; 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 83e9fe9e188118a0a34c6200d9b10ea6247f53592dBjorn Helgaas default: 84e9fe9e188118a0a34c6200d9b10ea6247f53592dBjorn Helgaas dev_err(&dev->dev, "can't encode invalid IRQ mode %#x\n", 85e9fe9e188118a0a34c6200d9b10ea6247f53592dBjorn Helgaas flags); 86e9fe9e188118a0a34c6200d9b10ea6247f53592dBjorn Helgaas *triggering = ACPI_EDGE_SENSITIVE; 87e9fe9e188118a0a34c6200d9b10ea6247f53592dBjorn Helgaas *polarity = ACPI_ACTIVE_HIGH; 88e9fe9e188118a0a34c6200d9b10ea6247f53592dBjorn Helgaas break; 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 90a993273beae8022390e48fe9205480565ad470abBjorn Helgaas 91a993273beae8022390e48fe9205480565ad470abBjorn Helgaas if (flags & IORESOURCE_IRQ_SHAREABLE) 92a993273beae8022390e48fe9205480565ad470abBjorn Helgaas *shareable = ACPI_SHARED; 93a993273beae8022390e48fe9205480565ad470abBjorn Helgaas else 94a993273beae8022390e48fe9205480565ad470abBjorn Helgaas *shareable = ACPI_EXCLUSIVE; 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 974ab55d8d4f7b910c4c60e0f8ff70d0dfdd484f02Bjorn Helgaasstatic void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev, 9807d4e9af109221ab731c5aaf832e89776c64b013Bjorn Helgaas u32 gsi, int triggering, 9907d4e9af109221ab731c5aaf832e89776c64b013Bjorn Helgaas int polarity, int shareable) 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 101dbddd0383c59d588f8db5e773b062756e39117ecBjorn Helgaas int irq, flags; 10261fd47e0c84764f49b4e52bfd8170fac52636f00Shaohua Li int p, t; 103dbed12da5bb06b15c63930e9282b45daea566d7bBjorn Helgaas 1045acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas if (!valid_IRQ(gsi)) { 1055acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas pnp_add_irq_resource(dev, gsi, IORESOURCE_DISABLED); 106dbed12da5bb06b15c63930e9282b45daea566d7bBjorn Helgaas return; 1075acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas } 108dbed12da5bb06b15c63930e9282b45daea566d7bBjorn Helgaas 10961fd47e0c84764f49b4e52bfd8170fac52636f00Shaohua Li /* 11061fd47e0c84764f49b4e52bfd8170fac52636f00Shaohua Li * in IO-APIC mode, use overrided attribute. Two reasons: 11161fd47e0c84764f49b4e52bfd8170fac52636f00Shaohua Li * 1. BIOS bug in DSDT 11261fd47e0c84764f49b4e52bfd8170fac52636f00Shaohua Li * 2. BIOS uses IO-APIC mode Interrupt Source Override 11361fd47e0c84764f49b4e52bfd8170fac52636f00Shaohua Li */ 11461fd47e0c84764f49b4e52bfd8170fac52636f00Shaohua Li if (!acpi_get_override_irq(gsi, &t, &p)) { 11561fd47e0c84764f49b4e52bfd8170fac52636f00Shaohua Li t = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE; 11661fd47e0c84764f49b4e52bfd8170fac52636f00Shaohua Li p = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH; 11761fd47e0c84764f49b4e52bfd8170fac52636f00Shaohua Li 11861fd47e0c84764f49b4e52bfd8170fac52636f00Shaohua Li if (triggering != t || polarity != p) { 119af11cb2d521f9d7e10c565bafe8f2358772baa65Bjorn Helgaas dev_warn(&dev->dev, "IRQ %d override to %s, %s\n", 12061fd47e0c84764f49b4e52bfd8170fac52636f00Shaohua Li gsi, t ? "edge":"level", p ? "low":"high"); 12161fd47e0c84764f49b4e52bfd8170fac52636f00Shaohua Li triggering = t; 12261fd47e0c84764f49b4e52bfd8170fac52636f00Shaohua Li polarity = p; 12361fd47e0c84764f49b4e52bfd8170fac52636f00Shaohua Li } 12461fd47e0c84764f49b4e52bfd8170fac52636f00Shaohua Li } 12561fd47e0c84764f49b4e52bfd8170fac52636f00Shaohua Li 126dbddd0383c59d588f8db5e773b062756e39117ecBjorn Helgaas flags = irq_flags(triggering, polarity, shareable); 127a2f809b08ae4dddc1015c7dcd8659e5729e45b3eYinghai Lu irq = acpi_register_gsi(&dev->dev, gsi, triggering, polarity); 128dbddd0383c59d588f8db5e773b062756e39117ecBjorn Helgaas if (irq >= 0) 129dbddd0383c59d588f8db5e773b062756e39117ecBjorn Helgaas pcibios_penalize_isa_irq(irq, 1); 130dbddd0383c59d588f8db5e773b062756e39117ecBjorn Helgaas else 131dbddd0383c59d588f8db5e773b062756e39117ecBjorn Helgaas flags |= IORESOURCE_DISABLED; 132dbed12da5bb06b15c63930e9282b45daea566d7bBjorn Helgaas 133dbddd0383c59d588f8db5e773b062756e39117ecBjorn Helgaas pnp_add_irq_resource(dev, irq, flags); 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 136958a1fdd3904b009c926cb840be48ce3c5f2389eBjorn Helgaasstatic int dma_flags(struct pnp_dev *dev, int type, int bus_master, 137958a1fdd3904b009c926cb840be48ce3c5f2389eBjorn Helgaas int transfer) 138362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher{ 139362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher int flags = 0; 140362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher 141362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher if (bus_master) 142362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher flags |= IORESOURCE_DMA_MASTER; 143362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher switch (type) { 144362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher case ACPI_COMPATIBILITY: 145362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher flags |= IORESOURCE_DMA_COMPATIBLE; 146362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher break; 147362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher case ACPI_TYPE_A: 148362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher flags |= IORESOURCE_DMA_TYPEA; 149362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher break; 150362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher case ACPI_TYPE_B: 151362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher flags |= IORESOURCE_DMA_TYPEB; 152362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher break; 153362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher case ACPI_TYPE_F: 154362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher flags |= IORESOURCE_DMA_TYPEF; 155362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher break; 156362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher default: 157362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher /* Set a default value ? */ 158362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher flags |= IORESOURCE_DMA_COMPATIBLE; 159958a1fdd3904b009c926cb840be48ce3c5f2389eBjorn Helgaas dev_err(&dev->dev, "invalid DMA type %d\n", type); 160362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher } 161362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher switch (transfer) { 162362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher case ACPI_TRANSFER_8: 163362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher flags |= IORESOURCE_DMA_8BIT; 164362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher break; 165362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher case ACPI_TRANSFER_8_16: 166362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher flags |= IORESOURCE_DMA_8AND16BIT; 167362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher break; 168362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher case ACPI_TRANSFER_16: 169362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher flags |= IORESOURCE_DMA_16BIT; 170362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher break; 171362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher default: 172362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher /* Set a default value ? */ 173362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher flags |= IORESOURCE_DMA_8AND16BIT; 174958a1fdd3904b009c926cb840be48ce3c5f2389eBjorn Helgaas dev_err(&dev->dev, "invalid DMA transfer type %d\n", transfer); 175362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher } 176362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher 177362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher return flags; 178362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher} 179362ea087db9d99bb0cf79479544dfafa9e18c300Michael Karcher 180cc8c2e308194f0997c718c7c735550ff06754d20Bjorn Helgaasstatic void pnpacpi_parse_allocated_ioresource(struct pnp_dev *dev, u64 start, 181fa35b49260b615d634bfa1f767aa315fa323c2e9Bjorn Helgaas u64 len, int io_decode, 182fa35b49260b615d634bfa1f767aa315fa323c2e9Bjorn Helgaas int window) 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 184cc8c2e308194f0997c718c7c735550ff06754d20Bjorn Helgaas int flags = 0; 185cc8c2e308194f0997c718c7c735550ff06754d20Bjorn Helgaas u64 end = start + len - 1; 18607d4e9af109221ab731c5aaf832e89776c64b013Bjorn Helgaas 187cc8c2e308194f0997c718c7c735550ff06754d20Bjorn Helgaas if (io_decode == ACPI_DECODE_16) 18808c9f262f268f7948be13bf3a5bda1d635c649b4Bjorn Helgaas flags |= IORESOURCE_IO_16BIT_ADDR; 189cc8c2e308194f0997c718c7c735550ff06754d20Bjorn Helgaas if (len == 0 || end >= 0x10003) 190cc8c2e308194f0997c718c7c735550ff06754d20Bjorn Helgaas flags |= IORESOURCE_DISABLED; 191fa35b49260b615d634bfa1f767aa315fa323c2e9Bjorn Helgaas if (window) 192fa35b49260b615d634bfa1f767aa315fa323c2e9Bjorn Helgaas flags |= IORESOURCE_WINDOW; 193cc8c2e308194f0997c718c7c735550ff06754d20Bjorn Helgaas 194cc8c2e308194f0997c718c7c735550ff06754d20Bjorn Helgaas pnp_add_io_resource(dev, start, end, flags); 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19740ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas/* 19840ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas * Device CSRs that do not appear in PCI config space should be described 19940ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas * via ACPI. This would normally be done with Address Space Descriptors 20040ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas * marked as "consumer-only," but old versions of Windows and Linux ignore 20140ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas * the producer/consumer flag, so HP invented a vendor-defined resource to 20240ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas * describe the location and size of CSR space. 20340ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas */ 20440ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaasstatic struct acpi_vendor_uuid hp_ccsr_uuid = { 20540ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas .subtype = 2, 20640ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas .data = { 0xf9, 0xad, 0xe9, 0x69, 0x4f, 0x92, 0x5f, 0xab, 0xf6, 0x4a, 20740ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas 0x24, 0xd2, 0x01, 0x37, 0x0e, 0xad }, 20840ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas}; 20940ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas 21040ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaasstatic int vendor_resource_matches(struct pnp_dev *dev, 21140ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas struct acpi_resource_vendor_typed *vendor, 21240ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas struct acpi_vendor_uuid *match, 21340ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas int expected_len) 21440ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas{ 21540ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas int uuid_len = sizeof(vendor->uuid); 21640ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas u8 uuid_subtype = vendor->uuid_subtype; 21740ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas u8 *uuid = vendor->uuid; 21840ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas int actual_len; 21940ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas 22040ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas /* byte_length includes uuid_subtype and uuid */ 22140ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas actual_len = vendor->byte_length - uuid_len - 1; 22240ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas 22340ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas if (uuid_subtype == match->subtype && 22440ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas uuid_len == sizeof(match->data) && 22540ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas memcmp(uuid, match->data, uuid_len) == 0) { 22640ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas if (expected_len && expected_len != actual_len) { 22740ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas dev_err(&dev->dev, "wrong vendor descriptor size; " 22840ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas "expected %d, found %d bytes\n", 22940ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas expected_len, actual_len); 23040ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas return 0; 23140ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas } 23240ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas 23340ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas return 1; 23440ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas } 23540ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas 23640ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas return 0; 23740ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas} 23840ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas 23940ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaasstatic void pnpacpi_parse_allocated_vendor(struct pnp_dev *dev, 24040ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas struct acpi_resource_vendor_typed *vendor) 24140ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas{ 24240ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas if (vendor_resource_matches(dev, vendor, &hp_ccsr_uuid, 16)) { 24340ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas u64 start, length; 24440ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas 24540ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas memcpy(&start, vendor->byte_data, sizeof(start)); 24640ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas memcpy(&length, vendor->byte_data + 8, sizeof(length)); 24740ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas 24840ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas pnp_add_mem_resource(dev, start, start + length - 1, 0); 24940ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas } 25040ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas} 25140ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas 2524ab55d8d4f7b910c4c60e0f8ff70d0dfdd484f02Bjorn Helgaasstatic void pnpacpi_parse_allocated_memresource(struct pnp_dev *dev, 253d6180f36617953990bf90d4c1ff85b77e9995cd1Bjorn Helgaas u64 start, u64 len, 254fa35b49260b615d634bfa1f767aa315fa323c2e9Bjorn Helgaas int write_protect, int window) 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 256d6180f36617953990bf90d4c1ff85b77e9995cd1Bjorn Helgaas int flags = 0; 257d6180f36617953990bf90d4c1ff85b77e9995cd1Bjorn Helgaas u64 end = start + len - 1; 258d6180f36617953990bf90d4c1ff85b77e9995cd1Bjorn Helgaas 259d6180f36617953990bf90d4c1ff85b77e9995cd1Bjorn Helgaas if (len == 0) 260d6180f36617953990bf90d4c1ff85b77e9995cd1Bjorn Helgaas flags |= IORESOURCE_DISABLED; 261d6180f36617953990bf90d4c1ff85b77e9995cd1Bjorn Helgaas if (write_protect == ACPI_READ_WRITE_MEMORY) 262d6180f36617953990bf90d4c1ff85b77e9995cd1Bjorn Helgaas flags |= IORESOURCE_MEM_WRITEABLE; 263fa35b49260b615d634bfa1f767aa315fa323c2e9Bjorn Helgaas if (window) 264fa35b49260b615d634bfa1f767aa315fa323c2e9Bjorn Helgaas flags |= IORESOURCE_WINDOW; 265d6180f36617953990bf90d4c1ff85b77e9995cd1Bjorn Helgaas 266d6180f36617953990bf90d4c1ff85b77e9995cd1Bjorn Helgaas pnp_add_mem_resource(dev, start, end, flags); 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2697e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaasstatic void pnpacpi_parse_allocated_busresource(struct pnp_dev *dev, 2707e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas u64 start, u64 len) 2717e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas{ 2727e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas u64 end = start + len - 1; 2737e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas 2747e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas pnp_add_bus_resource(dev, start, end); 2757e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas} 2767e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas 2774ab55d8d4f7b910c4c60e0f8ff70d0dfdd484f02Bjorn Helgaasstatic void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev, 27807d4e9af109221ab731c5aaf832e89776c64b013Bjorn Helgaas struct acpi_resource *res) 2791acfb7f2b0d460ee86bdb25ad0679070ec8a5f0dBjorn Helgaas{ 2801acfb7f2b0d460ee86bdb25ad0679070ec8a5f0dBjorn Helgaas struct acpi_resource_address64 addr, *p = &addr; 2811acfb7f2b0d460ee86bdb25ad0679070ec8a5f0dBjorn Helgaas acpi_status status; 282fa35b49260b615d634bfa1f767aa315fa323c2e9Bjorn Helgaas int window; 2833162b6f0c5e1fcad372d64194fb3cb968941b428Bjorn Helgaas u64 len; 2841acfb7f2b0d460ee86bdb25ad0679070ec8a5f0dBjorn Helgaas 2851acfb7f2b0d460ee86bdb25ad0679070ec8a5f0dBjorn Helgaas status = acpi_resource_to_address64(res, p); 2861acfb7f2b0d460ee86bdb25ad0679070ec8a5f0dBjorn Helgaas if (!ACPI_SUCCESS(status)) { 287af11cb2d521f9d7e10c565bafe8f2358772baa65Bjorn Helgaas dev_warn(&dev->dev, "failed to convert resource type %d\n", 2889dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas res->type); 2891acfb7f2b0d460ee86bdb25ad0679070ec8a5f0dBjorn Helgaas return; 2901acfb7f2b0d460ee86bdb25ad0679070ec8a5f0dBjorn Helgaas } 2911acfb7f2b0d460ee86bdb25ad0679070ec8a5f0dBjorn Helgaas 292f238b414a74a13c3d62e31a08e81b585d750df74Bjorn Helgaas /* Windows apparently computes length rather than using _LEN */ 293f238b414a74a13c3d62e31a08e81b585d750df74Bjorn Helgaas len = p->maximum - p->minimum + 1; 294fa35b49260b615d634bfa1f767aa315fa323c2e9Bjorn Helgaas window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0; 2952b8de5f50e4a302b83ebcd5b0120621336d50bd6Matthieu CASTET 2961acfb7f2b0d460ee86bdb25ad0679070ec8a5f0dBjorn Helgaas if (p->resource_type == ACPI_MEMORY_RANGE) 2973162b6f0c5e1fcad372d64194fb3cb968941b428Bjorn Helgaas pnpacpi_parse_allocated_memresource(dev, p->minimum, len, 298fa35b49260b615d634bfa1f767aa315fa323c2e9Bjorn Helgaas p->info.mem.write_protect, window); 2991acfb7f2b0d460ee86bdb25ad0679070ec8a5f0dBjorn Helgaas else if (p->resource_type == ACPI_IO_RANGE) 3003162b6f0c5e1fcad372d64194fb3cb968941b428Bjorn Helgaas pnpacpi_parse_allocated_ioresource(dev, p->minimum, len, 30107d4e9af109221ab731c5aaf832e89776c64b013Bjorn Helgaas p->granularity == 0xfff ? ACPI_DECODE_10 : 302fa35b49260b615d634bfa1f767aa315fa323c2e9Bjorn Helgaas ACPI_DECODE_16, window); 3037e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas else if (p->resource_type == ACPI_BUS_NUMBER_RANGE) 3043162b6f0c5e1fcad372d64194fb3cb968941b428Bjorn Helgaas pnpacpi_parse_allocated_busresource(dev, p->minimum, len); 3051acfb7f2b0d460ee86bdb25ad0679070ec8a5f0dBjorn Helgaas} 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3078cb24c8fd70ea8431744de1ca0ca34ab45fbbdaaBjorn Helgaasstatic void pnpacpi_parse_allocated_ext_address_space(struct pnp_dev *dev, 3088cb24c8fd70ea8431744de1ca0ca34ab45fbbdaaBjorn Helgaas struct acpi_resource *res) 3098cb24c8fd70ea8431744de1ca0ca34ab45fbbdaaBjorn Helgaas{ 3108cb24c8fd70ea8431744de1ca0ca34ab45fbbdaaBjorn Helgaas struct acpi_resource_extended_address64 *p = &res->data.ext_address64; 311fa35b49260b615d634bfa1f767aa315fa323c2e9Bjorn Helgaas int window; 3123162b6f0c5e1fcad372d64194fb3cb968941b428Bjorn Helgaas u64 len; 3138cb24c8fd70ea8431744de1ca0ca34ab45fbbdaaBjorn Helgaas 314f238b414a74a13c3d62e31a08e81b585d750df74Bjorn Helgaas /* Windows apparently computes length rather than using _LEN */ 315f238b414a74a13c3d62e31a08e81b585d750df74Bjorn Helgaas len = p->maximum - p->minimum + 1; 316fa35b49260b615d634bfa1f767aa315fa323c2e9Bjorn Helgaas window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0; 3178cb24c8fd70ea8431744de1ca0ca34ab45fbbdaaBjorn Helgaas 3188cb24c8fd70ea8431744de1ca0ca34ab45fbbdaaBjorn Helgaas if (p->resource_type == ACPI_MEMORY_RANGE) 3193162b6f0c5e1fcad372d64194fb3cb968941b428Bjorn Helgaas pnpacpi_parse_allocated_memresource(dev, p->minimum, len, 320fa35b49260b615d634bfa1f767aa315fa323c2e9Bjorn Helgaas p->info.mem.write_protect, window); 3218cb24c8fd70ea8431744de1ca0ca34ab45fbbdaaBjorn Helgaas else if (p->resource_type == ACPI_IO_RANGE) 3223162b6f0c5e1fcad372d64194fb3cb968941b428Bjorn Helgaas pnpacpi_parse_allocated_ioresource(dev, p->minimum, len, 3238cb24c8fd70ea8431744de1ca0ca34ab45fbbdaaBjorn Helgaas p->granularity == 0xfff ? ACPI_DECODE_10 : 324fa35b49260b615d634bfa1f767aa315fa323c2e9Bjorn Helgaas ACPI_DECODE_16, window); 3257e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas else if (p->resource_type == ACPI_BUS_NUMBER_RANGE) 3263162b6f0c5e1fcad372d64194fb3cb968941b428Bjorn Helgaas pnpacpi_parse_allocated_busresource(dev, p->minimum, len); 3278cb24c8fd70ea8431744de1ca0ca34ab45fbbdaaBjorn Helgaas} 3288cb24c8fd70ea8431744de1ca0ca34ab45fbbdaaBjorn Helgaas 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, 3309dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas void *data) 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3324ab55d8d4f7b910c4c60e0f8ff70d0dfdd484f02Bjorn Helgaas struct pnp_dev *dev = data; 3339570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas struct acpi_resource_irq *irq; 3349570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas struct acpi_resource_dma *dma; 3359570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas struct acpi_resource_io *io; 3369570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas struct acpi_resource_fixed_io *fixed_io; 33740ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas struct acpi_resource_vendor_typed *vendor_typed; 3389570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas struct acpi_resource_memory24 *memory24; 3399570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas struct acpi_resource_memory32 *memory32; 3409570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas struct acpi_resource_fixed_memory32 *fixed_memory32; 3419570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas struct acpi_resource_extended_irq *extended_irq; 342dc16f5f2ede8cc2acf8ac22857a7fecf3a4296c2Bjorn Helgaas int i, flags; 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 344eca008c8134df15262a0362623edb59902628c95Len Brown switch (res->type) { 34550eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore case ACPI_RESOURCE_TYPE_IRQ: 346dbed12da5bb06b15c63930e9282b45daea566d7bBjorn Helgaas /* 347dbed12da5bb06b15c63930e9282b45daea566d7bBjorn Helgaas * Per spec, only one interrupt per descriptor is allowed in 348dbed12da5bb06b15c63930e9282b45daea566d7bBjorn Helgaas * _CRS, but some firmware violates this, so parse them all. 349dbed12da5bb06b15c63930e9282b45daea566d7bBjorn Helgaas */ 3509570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas irq = &res->data.irq; 3515acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas if (irq->interrupt_count == 0) 3525acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED); 3535acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas else { 3545acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas for (i = 0; i < irq->interrupt_count; i++) { 3555acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas pnpacpi_parse_allocated_irqresource(dev, 3565acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas irq->interrupts[i], 3575acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas irq->triggering, 3585acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas irq->polarity, 3595acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas irq->sharable); 3605acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas } 3615acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas 3625acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas /* 3635acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas * The IRQ encoder puts a single interrupt in each 3645acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas * descriptor, so if a _CRS descriptor has more than 3655acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas * one interrupt, we won't be able to re-encode it. 3665acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas */ 3675acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas if (pnp_can_write(dev) && irq->interrupt_count > 1) { 3685acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas dev_warn(&dev->dev, "multiple interrupts in " 3695acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas "_CRS descriptor; configuration can't " 3705acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas "be changed\n"); 3715acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas dev->capabilities &= ~PNP_WRITE; 3725acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas } 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 37650eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore case ACPI_RESOURCE_TYPE_DMA: 3779570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas dma = &res->data.dma; 3785acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas if (dma->channel_count > 0 && dma->channels[0] != (u8) -1) 379958a1fdd3904b009c926cb840be48ce3c5f2389eBjorn Helgaas flags = dma_flags(dev, dma->type, dma->bus_master, 380dc16f5f2ede8cc2acf8ac22857a7fecf3a4296c2Bjorn Helgaas dma->transfer); 3815acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas else 3825acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas flags = IORESOURCE_DISABLED; 3835acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas pnp_add_dma_resource(dev, dma->channels[0], flags); 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3850af5853bccd263161df80c259d61fc71211c5ac3Len Brown 38650eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore case ACPI_RESOURCE_TYPE_IO: 3879570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas io = &res->data.io; 3884ab55d8d4f7b910c4c60e0f8ff70d0dfdd484f02Bjorn Helgaas pnpacpi_parse_allocated_ioresource(dev, 3899570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas io->minimum, 3909570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas io->address_length, 391fa35b49260b615d634bfa1f767aa315fa323c2e9Bjorn Helgaas io->io_decode, 0); 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3930af5853bccd263161df80c259d61fc71211c5ac3Len Brown 3940af5853bccd263161df80c259d61fc71211c5ac3Len Brown case ACPI_RESOURCE_TYPE_START_DEPENDENT: 3950af5853bccd263161df80c259d61fc71211c5ac3Len Brown case ACPI_RESOURCE_TYPE_END_DEPENDENT: 3960af5853bccd263161df80c259d61fc71211c5ac3Len Brown break; 3970af5853bccd263161df80c259d61fc71211c5ac3Len Brown 39850eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore case ACPI_RESOURCE_TYPE_FIXED_IO: 3999570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas fixed_io = &res->data.fixed_io; 4004ab55d8d4f7b910c4c60e0f8ff70d0dfdd484f02Bjorn Helgaas pnpacpi_parse_allocated_ioresource(dev, 4019570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas fixed_io->address, 4029570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas fixed_io->address_length, 403fa35b49260b615d634bfa1f767aa315fa323c2e9Bjorn Helgaas ACPI_DECODE_10, 0); 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4050af5853bccd263161df80c259d61fc71211c5ac3Len Brown 4060af5853bccd263161df80c259d61fc71211c5ac3Len Brown case ACPI_RESOURCE_TYPE_VENDOR: 40740ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas vendor_typed = &res->data.vendor_typed; 40840ab4f4c1d843362eb26d83425317e91fbd98b17Bjorn Helgaas pnpacpi_parse_allocated_vendor(dev, vendor_typed); 4090af5853bccd263161df80c259d61fc71211c5ac3Len Brown break; 4100af5853bccd263161df80c259d61fc71211c5ac3Len Brown 4110af5853bccd263161df80c259d61fc71211c5ac3Len Brown case ACPI_RESOURCE_TYPE_END_TAG: 4120af5853bccd263161df80c259d61fc71211c5ac3Len Brown break; 4130af5853bccd263161df80c259d61fc71211c5ac3Len Brown 41450eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore case ACPI_RESOURCE_TYPE_MEMORY24: 4159570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas memory24 = &res->data.memory24; 4164ab55d8d4f7b910c4c60e0f8ff70d0dfdd484f02Bjorn Helgaas pnpacpi_parse_allocated_memresource(dev, 4179570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas memory24->minimum, 4189570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas memory24->address_length, 419fa35b49260b615d634bfa1f767aa315fa323c2e9Bjorn Helgaas memory24->write_protect, 0); 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 42150eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore case ACPI_RESOURCE_TYPE_MEMORY32: 4229570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas memory32 = &res->data.memory32; 4234ab55d8d4f7b910c4c60e0f8ff70d0dfdd484f02Bjorn Helgaas pnpacpi_parse_allocated_memresource(dev, 4249570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas memory32->minimum, 4259570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas memory32->address_length, 426fa35b49260b615d634bfa1f767aa315fa323c2e9Bjorn Helgaas memory32->write_protect, 0); 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 42850eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: 4299570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas fixed_memory32 = &res->data.fixed_memory32; 4304ab55d8d4f7b910c4c60e0f8ff70d0dfdd484f02Bjorn Helgaas pnpacpi_parse_allocated_memresource(dev, 4319570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas fixed_memory32->address, 4329570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas fixed_memory32->address_length, 433fa35b49260b615d634bfa1f767aa315fa323c2e9Bjorn Helgaas fixed_memory32->write_protect, 0); 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 43550eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore case ACPI_RESOURCE_TYPE_ADDRESS16: 43650eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore case ACPI_RESOURCE_TYPE_ADDRESS32: 43750eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore case ACPI_RESOURCE_TYPE_ADDRESS64: 4384ab55d8d4f7b910c4c60e0f8ff70d0dfdd484f02Bjorn Helgaas pnpacpi_parse_allocated_address_space(dev, res); 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4400af5853bccd263161df80c259d61fc71211c5ac3Len Brown 4410af5853bccd263161df80c259d61fc71211c5ac3Len Brown case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: 4428cb24c8fd70ea8431744de1ca0ca34ab45fbbdaaBjorn Helgaas pnpacpi_parse_allocated_ext_address_space(dev, res); 4430af5853bccd263161df80c259d61fc71211c5ac3Len Brown break; 4440af5853bccd263161df80c259d61fc71211c5ac3Len Brown 4450af5853bccd263161df80c259d61fc71211c5ac3Len Brown case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 4469570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas extended_irq = &res->data.extended_irq; 4472b8de5f50e4a302b83ebcd5b0120621336d50bd6Matthieu CASTET 4485acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas if (extended_irq->interrupt_count == 0) 4495acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED); 4505acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas else { 4515acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas for (i = 0; i < extended_irq->interrupt_count; i++) { 4525acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas pnpacpi_parse_allocated_irqresource(dev, 4535acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas extended_irq->interrupts[i], 4545acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas extended_irq->triggering, 4555acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas extended_irq->polarity, 4565acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas extended_irq->sharable); 4575acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas } 4585acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas 4595acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas /* 4605acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas * The IRQ encoder puts a single interrupt in each 4615acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas * descriptor, so if a _CRS descriptor has more than 4625acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas * one interrupt, we won't be able to re-encode it. 4635acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas */ 4645acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas if (pnp_can_write(dev) && 4655acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas extended_irq->interrupt_count > 1) { 4665acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas dev_warn(&dev->dev, "multiple interrupts in " 4675acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas "_CRS descriptor; configuration can't " 4685acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas "be changed\n"); 4695acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas dev->capabilities &= ~PNP_WRITE; 4705acf91415799025410cc0d13101340d352f34c89Bjorn Helgaas } 4710af5853bccd263161df80c259d61fc71211c5ac3Len Brown } 4720af5853bccd263161df80c259d61fc71211c5ac3Len Brown break; 4730af5853bccd263161df80c259d61fc71211c5ac3Len Brown 4740af5853bccd263161df80c259d61fc71211c5ac3Len Brown case ACPI_RESOURCE_TYPE_GENERIC_REGISTER: 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4760af5853bccd263161df80c259d61fc71211c5ac3Len Brown 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 478af11cb2d521f9d7e10c565bafe8f2358772baa65Bjorn Helgaas dev_warn(&dev->dev, "unknown resource type %d in _CRS\n", 479af11cb2d521f9d7e10c565bafe8f2358772baa65Bjorn Helgaas res->type); 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return AE_ERROR; 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4821c6e7d0aeecac38e66b1bb63e3eff07b2a1c2f2cBjorn Helgaas 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return AE_OK; 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 486d152cf5d0c3325979e71ee53b425fdd51a1a285aBjorn Helgaasint pnpacpi_parse_allocated_resource(struct pnp_dev *dev) 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 488c4da6940a7a41c72781ff2d62ebd4b99f3749f14Bjorn Helgaas struct acpi_device *acpi_dev = dev->data; 489c4da6940a7a41c72781ff2d62ebd4b99f3749f14Bjorn Helgaas acpi_handle handle = acpi_dev->handle; 490d152cf5d0c3325979e71ee53b425fdd51a1a285aBjorn Helgaas acpi_status status; 4914ab55d8d4f7b910c4c60e0f8ff70d0dfdd484f02Bjorn Helgaas 4922f53432c2aedbe79020e44525eb069d9138a01ddBjorn Helgaas pnp_dbg(&dev->dev, "parse allocated resources\n"); 49372dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas 494f44900020926b2cb06b87f0f52643d6285514fc3Bjorn Helgaas pnp_init_resources(dev); 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 496d152cf5d0c3325979e71ee53b425fdd51a1a285aBjorn Helgaas status = acpi_walk_resources(handle, METHOD_NAME__CRS, 497d152cf5d0c3325979e71ee53b425fdd51a1a285aBjorn Helgaas pnpacpi_allocated_resource, dev); 498d152cf5d0c3325979e71ee53b425fdd51a1a285aBjorn Helgaas 499d152cf5d0c3325979e71ee53b425fdd51a1a285aBjorn Helgaas if (ACPI_FAILURE(status)) { 500d152cf5d0c3325979e71ee53b425fdd51a1a285aBjorn Helgaas if (status != AE_NOT_FOUND) 501d152cf5d0c3325979e71ee53b425fdd51a1a285aBjorn Helgaas dev_err(&dev->dev, "can't evaluate _CRS: %d", status); 502d152cf5d0c3325979e71ee53b425fdd51a1a285aBjorn Helgaas return -EPERM; 503d152cf5d0c3325979e71ee53b425fdd51a1a285aBjorn Helgaas } 504d152cf5d0c3325979e71ee53b425fdd51a1a285aBjorn Helgaas return 0; 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 507c1caf06ccfd3a4efd4b489f89bcdabd2362f31d0Bjorn Helgaasstatic __init void pnpacpi_parse_dma_option(struct pnp_dev *dev, 5081f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas unsigned int option_flags, 5092bb9a6b32f98873adf89a0de04c898681a2c5b8eThomas Renninger struct acpi_resource_dma *p) 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 51218fd470a48396c8795ba7256c5973e92ffa25cb3Witold Szczeponik unsigned char map = 0, flags; 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5149dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas for (i = 0; i < p->channel_count; i++) 515c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas map |= 1 << p->channels[i]; 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 51718fd470a48396c8795ba7256c5973e92ffa25cb3Witold Szczeponik flags = dma_flags(dev, p->type, p->bus_master, p->transfer); 5181f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas pnp_register_dma_resource(dev, option_flags, map, flags); 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 521c1caf06ccfd3a4efd4b489f89bcdabd2362f31d0Bjorn Helgaasstatic __init void pnpacpi_parse_irq_option(struct pnp_dev *dev, 5221f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas unsigned int option_flags, 5232bb9a6b32f98873adf89a0de04c898681a2c5b8eThomas Renninger struct acpi_resource_irq *p) 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 526c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas pnp_irq_mask_t map; 52718fd470a48396c8795ba7256c5973e92ffa25cb3Witold Szczeponik unsigned char flags; 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 529c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas bitmap_zero(map.bits, PNP_IRQ_NR); 5309dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas for (i = 0; i < p->interrupt_count; i++) 5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p->interrupts[i]) 532c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas __set_bit(p->interrupts[i], map.bits); 5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 53418fd470a48396c8795ba7256c5973e92ffa25cb3Witold Szczeponik flags = irq_flags(p->triggering, p->polarity, p->sharable); 5351f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas pnp_register_irq_resource(dev, option_flags, &map, flags); 5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 538c1caf06ccfd3a4efd4b489f89bcdabd2362f31d0Bjorn Helgaasstatic __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev, 5391f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas unsigned int option_flags, 5402bb9a6b32f98873adf89a0de04c898681a2c5b8eThomas Renninger struct acpi_resource_extended_irq *p) 5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 543c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas pnp_irq_mask_t map; 54418fd470a48396c8795ba7256c5973e92ffa25cb3Witold Szczeponik unsigned char flags; 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 546c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas bitmap_zero(map.bits, PNP_IRQ_NR); 547fe2cf598e6942abd8fb70fee230d74b1a1eae0d1Bjorn Helgaas for (i = 0; i < p->interrupt_count; i++) { 548fe2cf598e6942abd8fb70fee230d74b1a1eae0d1Bjorn Helgaas if (p->interrupts[i]) { 549fe2cf598e6942abd8fb70fee230d74b1a1eae0d1Bjorn Helgaas if (p->interrupts[i] < PNP_IRQ_NR) 550fe2cf598e6942abd8fb70fee230d74b1a1eae0d1Bjorn Helgaas __set_bit(p->interrupts[i], map.bits); 551fe2cf598e6942abd8fb70fee230d74b1a1eae0d1Bjorn Helgaas else 552fe2cf598e6942abd8fb70fee230d74b1a1eae0d1Bjorn Helgaas dev_err(&dev->dev, "ignoring IRQ %d option " 553fe2cf598e6942abd8fb70fee230d74b1a1eae0d1Bjorn Helgaas "(too large for %d entry bitmap)\n", 554fe2cf598e6942abd8fb70fee230d74b1a1eae0d1Bjorn Helgaas p->interrupts[i], PNP_IRQ_NR); 555fe2cf598e6942abd8fb70fee230d74b1a1eae0d1Bjorn Helgaas } 556fe2cf598e6942abd8fb70fee230d74b1a1eae0d1Bjorn Helgaas } 5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 55818fd470a48396c8795ba7256c5973e92ffa25cb3Witold Szczeponik flags = irq_flags(p->triggering, p->polarity, p->sharable); 5591f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas pnp_register_irq_resource(dev, option_flags, &map, flags); 5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 562c1caf06ccfd3a4efd4b489f89bcdabd2362f31d0Bjorn Helgaasstatic __init void pnpacpi_parse_port_option(struct pnp_dev *dev, 5631f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas unsigned int option_flags, 5642bb9a6b32f98873adf89a0de04c898681a2c5b8eThomas Renninger struct acpi_resource_io *io) 5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 566c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas unsigned char flags = 0; 5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 568c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas if (io->io_decode == ACPI_DECODE_16) 56918fd470a48396c8795ba7256c5973e92ffa25cb3Witold Szczeponik flags = IORESOURCE_IO_16BIT_ADDR; 5701f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas pnp_register_port_resource(dev, option_flags, io->minimum, io->maximum, 571c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas io->alignment, io->address_length, flags); 5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 574c1caf06ccfd3a4efd4b489f89bcdabd2362f31d0Bjorn Helgaasstatic __init void pnpacpi_parse_fixed_port_option(struct pnp_dev *dev, 5751f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas unsigned int option_flags, 5762bb9a6b32f98873adf89a0de04c898681a2c5b8eThomas Renninger struct acpi_resource_fixed_io *io) 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5781f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas pnp_register_port_resource(dev, option_flags, io->address, io->address, 57918fd470a48396c8795ba7256c5973e92ffa25cb3Witold Szczeponik 0, io->address_length, IORESOURCE_IO_FIXED); 5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 582c1caf06ccfd3a4efd4b489f89bcdabd2362f31d0Bjorn Helgaasstatic __init void pnpacpi_parse_mem24_option(struct pnp_dev *dev, 5831f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas unsigned int option_flags, 5842bb9a6b32f98873adf89a0de04c898681a2c5b8eThomas Renninger struct acpi_resource_memory24 *p) 5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 586c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas unsigned char flags = 0; 5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 588c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas if (p->write_protect == ACPI_READ_WRITE_MEMORY) 58918fd470a48396c8795ba7256c5973e92ffa25cb3Witold Szczeponik flags = IORESOURCE_MEM_WRITEABLE; 5901f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas pnp_register_mem_resource(dev, option_flags, p->minimum, p->maximum, 591c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas p->alignment, p->address_length, flags); 5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 594c1caf06ccfd3a4efd4b489f89bcdabd2362f31d0Bjorn Helgaasstatic __init void pnpacpi_parse_mem32_option(struct pnp_dev *dev, 5951f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas unsigned int option_flags, 5962bb9a6b32f98873adf89a0de04c898681a2c5b8eThomas Renninger struct acpi_resource_memory32 *p) 5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 598c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas unsigned char flags = 0; 5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 600c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas if (p->write_protect == ACPI_READ_WRITE_MEMORY) 60118fd470a48396c8795ba7256c5973e92ffa25cb3Witold Szczeponik flags = IORESOURCE_MEM_WRITEABLE; 6021f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas pnp_register_mem_resource(dev, option_flags, p->minimum, p->maximum, 603c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas p->alignment, p->address_length, flags); 6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 606c1caf06ccfd3a4efd4b489f89bcdabd2362f31d0Bjorn Helgaasstatic __init void pnpacpi_parse_fixed_mem32_option(struct pnp_dev *dev, 6071f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas unsigned int option_flags, 6082bb9a6b32f98873adf89a0de04c898681a2c5b8eThomas Renninger struct acpi_resource_fixed_memory32 *p) 6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 610c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas unsigned char flags = 0; 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 612c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas if (p->write_protect == ACPI_READ_WRITE_MEMORY) 61318fd470a48396c8795ba7256c5973e92ffa25cb3Witold Szczeponik flags = IORESOURCE_MEM_WRITEABLE; 6141f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas pnp_register_mem_resource(dev, option_flags, p->address, p->address, 615c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas 0, p->address_length, flags); 6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 618c1caf06ccfd3a4efd4b489f89bcdabd2362f31d0Bjorn Helgaasstatic __init void pnpacpi_parse_address_option(struct pnp_dev *dev, 6191f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas unsigned int option_flags, 6202bb9a6b32f98873adf89a0de04c898681a2c5b8eThomas Renninger struct acpi_resource *r) 6216f957eaf79356a32e838f5f262ee9a60544b1d5bBjorn Helgaas{ 6226f957eaf79356a32e838f5f262ee9a60544b1d5bBjorn Helgaas struct acpi_resource_address64 addr, *p = &addr; 6236f957eaf79356a32e838f5f262ee9a60544b1d5bBjorn Helgaas acpi_status status; 624c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas unsigned char flags = 0; 6256f957eaf79356a32e838f5f262ee9a60544b1d5bBjorn Helgaas 6266f957eaf79356a32e838f5f262ee9a60544b1d5bBjorn Helgaas status = acpi_resource_to_address64(r, p); 627958a1fdd3904b009c926cb840be48ce3c5f2389eBjorn Helgaas if (ACPI_FAILURE(status)) { 628958a1fdd3904b009c926cb840be48ce3c5f2389eBjorn Helgaas dev_warn(&dev->dev, "can't convert resource type %d\n", 6299dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas r->type); 6306f957eaf79356a32e838f5f262ee9a60544b1d5bBjorn Helgaas return; 6316f957eaf79356a32e838f5f262ee9a60544b1d5bBjorn Helgaas } 6326f957eaf79356a32e838f5f262ee9a60544b1d5bBjorn Helgaas 6336f957eaf79356a32e838f5f262ee9a60544b1d5bBjorn Helgaas if (p->resource_type == ACPI_MEMORY_RANGE) { 634c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas if (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY) 63518fd470a48396c8795ba7256c5973e92ffa25cb3Witold Szczeponik flags = IORESOURCE_MEM_WRITEABLE; 6361f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas pnp_register_mem_resource(dev, option_flags, p->minimum, 6371f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas p->minimum, 0, p->address_length, 6381f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas flags); 639c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas } else if (p->resource_type == ACPI_IO_RANGE) 6401f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas pnp_register_port_resource(dev, option_flags, p->minimum, 6411f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas p->minimum, 0, p->address_length, 64218fd470a48396c8795ba7256c5973e92ffa25cb3Witold Szczeponik IORESOURCE_IO_FIXED); 6436f957eaf79356a32e838f5f262ee9a60544b1d5bBjorn Helgaas} 6446f957eaf79356a32e838f5f262ee9a60544b1d5bBjorn Helgaas 6458cb24c8fd70ea8431744de1ca0ca34ab45fbbdaaBjorn Helgaasstatic __init void pnpacpi_parse_ext_address_option(struct pnp_dev *dev, 6468cb24c8fd70ea8431744de1ca0ca34ab45fbbdaaBjorn Helgaas unsigned int option_flags, 6478cb24c8fd70ea8431744de1ca0ca34ab45fbbdaaBjorn Helgaas struct acpi_resource *r) 6488cb24c8fd70ea8431744de1ca0ca34ab45fbbdaaBjorn Helgaas{ 6498cb24c8fd70ea8431744de1ca0ca34ab45fbbdaaBjorn Helgaas struct acpi_resource_extended_address64 *p = &r->data.ext_address64; 6508cb24c8fd70ea8431744de1ca0ca34ab45fbbdaaBjorn Helgaas unsigned char flags = 0; 6518cb24c8fd70ea8431744de1ca0ca34ab45fbbdaaBjorn Helgaas 6528cb24c8fd70ea8431744de1ca0ca34ab45fbbdaaBjorn Helgaas if (p->resource_type == ACPI_MEMORY_RANGE) { 6538cb24c8fd70ea8431744de1ca0ca34ab45fbbdaaBjorn Helgaas if (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY) 65418fd470a48396c8795ba7256c5973e92ffa25cb3Witold Szczeponik flags = IORESOURCE_MEM_WRITEABLE; 6558cb24c8fd70ea8431744de1ca0ca34ab45fbbdaaBjorn Helgaas pnp_register_mem_resource(dev, option_flags, p->minimum, 6568cb24c8fd70ea8431744de1ca0ca34ab45fbbdaaBjorn Helgaas p->minimum, 0, p->address_length, 6578cb24c8fd70ea8431744de1ca0ca34ab45fbbdaaBjorn Helgaas flags); 6588cb24c8fd70ea8431744de1ca0ca34ab45fbbdaaBjorn Helgaas } else if (p->resource_type == ACPI_IO_RANGE) 6598cb24c8fd70ea8431744de1ca0ca34ab45fbbdaaBjorn Helgaas pnp_register_port_resource(dev, option_flags, p->minimum, 6608cb24c8fd70ea8431744de1ca0ca34ab45fbbdaaBjorn Helgaas p->minimum, 0, p->address_length, 66118fd470a48396c8795ba7256c5973e92ffa25cb3Witold Szczeponik IORESOURCE_IO_FIXED); 6628cb24c8fd70ea8431744de1ca0ca34ab45fbbdaaBjorn Helgaas} 6638cb24c8fd70ea8431744de1ca0ca34ab45fbbdaaBjorn Helgaas 6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct acpipnp_parse_option_s { 6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pnp_dev *dev; 6661f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas unsigned int option_flags; 6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6692bb9a6b32f98873adf89a0de04c898681a2c5b8eThomas Renningerstatic __init acpi_status pnpacpi_option_resource(struct acpi_resource *res, 6702bb9a6b32f98873adf89a0de04c898681a2c5b8eThomas Renninger void *data) 6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 672e2a1a6f1cfaf6ee770a8700e5df8a3708dae503bBjorn Helgaas int priority; 6734721a4cc8864f0eb92958c3e0479e7994e8b0072Bjorn Helgaas struct acpipnp_parse_option_s *parse_data = data; 6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pnp_dev *dev = parse_data->dev; 6751f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas unsigned int option_flags = parse_data->option_flags; 6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 677eca008c8134df15262a0362623edb59902628c95Len Brown switch (res->type) { 6789dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas case ACPI_RESOURCE_TYPE_IRQ: 6791f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas pnpacpi_parse_irq_option(dev, option_flags, &res->data.irq); 6809dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas break; 6810af5853bccd263161df80c259d61fc71211c5ac3Len Brown 6829dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas case ACPI_RESOURCE_TYPE_DMA: 6831f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas pnpacpi_parse_dma_option(dev, option_flags, &res->data.dma); 6849dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas break; 6850af5853bccd263161df80c259d61fc71211c5ac3Len Brown 6869dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas case ACPI_RESOURCE_TYPE_START_DEPENDENT: 6879dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas switch (res->data.start_dpf.compatibility_priority) { 6889dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas case ACPI_GOOD_CONFIGURATION: 6899dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas priority = PNP_RES_PRIORITY_PREFERRED; 6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6910af5853bccd263161df80c259d61fc71211c5ac3Len Brown 6929dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas case ACPI_ACCEPTABLE_CONFIGURATION: 6939dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas priority = PNP_RES_PRIORITY_ACCEPTABLE; 694b008b8d7092053fc1f036cfc54dc11740cc424edMatthieu CASTET break; 6950af5853bccd263161df80c259d61fc71211c5ac3Len Brown 6969dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas case ACPI_SUB_OPTIMAL_CONFIGURATION: 6979dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas priority = PNP_RES_PRIORITY_FUNCTIONAL; 6980af5853bccd263161df80c259d61fc71211c5ac3Len Brown break; 6999dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas default: 7009dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas priority = PNP_RES_PRIORITY_INVALID; 7010af5853bccd263161df80c259d61fc71211c5ac3Len Brown break; 7029dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas } 7031f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas parse_data->option_flags = pnp_new_dependent_set(dev, priority); 7049dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas break; 7050af5853bccd263161df80c259d61fc71211c5ac3Len Brown 7069dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas case ACPI_RESOURCE_TYPE_END_DEPENDENT: 7071f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas parse_data->option_flags = 0; 7089dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas break; 7090af5853bccd263161df80c259d61fc71211c5ac3Len Brown 7109dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas case ACPI_RESOURCE_TYPE_IO: 7111f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas pnpacpi_parse_port_option(dev, option_flags, &res->data.io); 7129dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas break; 7130af5853bccd263161df80c259d61fc71211c5ac3Len Brown 7149dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas case ACPI_RESOURCE_TYPE_FIXED_IO: 7151f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas pnpacpi_parse_fixed_port_option(dev, option_flags, 716c1caf06ccfd3a4efd4b489f89bcdabd2362f31d0Bjorn Helgaas &res->data.fixed_io); 7179dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas break; 7180af5853bccd263161df80c259d61fc71211c5ac3Len Brown 7199dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas case ACPI_RESOURCE_TYPE_VENDOR: 7209dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas case ACPI_RESOURCE_TYPE_END_TAG: 7219dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas break; 7220af5853bccd263161df80c259d61fc71211c5ac3Len Brown 7239dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas case ACPI_RESOURCE_TYPE_MEMORY24: 7241f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas pnpacpi_parse_mem24_option(dev, option_flags, 7251f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas &res->data.memory24); 7269dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas break; 7270af5853bccd263161df80c259d61fc71211c5ac3Len Brown 7289dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas case ACPI_RESOURCE_TYPE_MEMORY32: 7291f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas pnpacpi_parse_mem32_option(dev, option_flags, 7301f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas &res->data.memory32); 7319dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas break; 7320af5853bccd263161df80c259d61fc71211c5ac3Len Brown 7339dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: 7341f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas pnpacpi_parse_fixed_mem32_option(dev, option_flags, 7359dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas &res->data.fixed_memory32); 7369dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas break; 7370af5853bccd263161df80c259d61fc71211c5ac3Len Brown 7389dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas case ACPI_RESOURCE_TYPE_ADDRESS16: 7399dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas case ACPI_RESOURCE_TYPE_ADDRESS32: 7409dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas case ACPI_RESOURCE_TYPE_ADDRESS64: 7411f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas pnpacpi_parse_address_option(dev, option_flags, res); 7429dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas break; 7430af5853bccd263161df80c259d61fc71211c5ac3Len Brown 7449dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: 7458cb24c8fd70ea8431744de1ca0ca34ab45fbbdaaBjorn Helgaas pnpacpi_parse_ext_address_option(dev, option_flags, res); 7469dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas break; 7479dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas 7489dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 7491f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas pnpacpi_parse_ext_irq_option(dev, option_flags, 750c1caf06ccfd3a4efd4b489f89bcdabd2362f31d0Bjorn Helgaas &res->data.extended_irq); 7519dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas break; 7529dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas 7539dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas case ACPI_RESOURCE_TYPE_GENERIC_REGISTER: 7549dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas break; 7559dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas 7569dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas default: 757af11cb2d521f9d7e10c565bafe8f2358772baa65Bjorn Helgaas dev_warn(&dev->dev, "unknown resource type %d in _PRS\n", 758af11cb2d521f9d7e10c565bafe8f2358772baa65Bjorn Helgaas res->type); 7599dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas return AE_ERROR; 7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7611c6e7d0aeecac38e66b1bb63e3eff07b2a1c2f2cBjorn Helgaas 7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return AE_OK; 7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 765d152cf5d0c3325979e71ee53b425fdd51a1a285aBjorn Helgaasint __init pnpacpi_parse_resource_option_data(struct pnp_dev *dev) 7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 767c4da6940a7a41c72781ff2d62ebd4b99f3749f14Bjorn Helgaas struct acpi_device *acpi_dev = dev->data; 768c4da6940a7a41c72781ff2d62ebd4b99f3749f14Bjorn Helgaas acpi_handle handle = acpi_dev->handle; 7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acpi_status status; 7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct acpipnp_parse_option_s parse_data; 7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7722f53432c2aedbe79020e44525eb069d9138a01ddBjorn Helgaas pnp_dbg(&dev->dev, "parse resource options\n"); 77372dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas 7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds parse_data.dev = dev; 7751f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas parse_data.option_flags = 0; 7761f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas 77750eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore status = acpi_walk_resources(handle, METHOD_NAME__PRS, 7789dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas pnpacpi_option_resource, &parse_data); 7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 780d152cf5d0c3325979e71ee53b425fdd51a1a285aBjorn Helgaas if (ACPI_FAILURE(status)) { 781d152cf5d0c3325979e71ee53b425fdd51a1a285aBjorn Helgaas if (status != AE_NOT_FOUND) 782d152cf5d0c3325979e71ee53b425fdd51a1a285aBjorn Helgaas dev_err(&dev->dev, "can't evaluate _PRS: %d", status); 783d152cf5d0c3325979e71ee53b425fdd51a1a285aBjorn Helgaas return -EPERM; 784d152cf5d0c3325979e71ee53b425fdd51a1a285aBjorn Helgaas } 785d152cf5d0c3325979e71ee53b425fdd51a1a285aBjorn Helgaas return 0; 7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 788b5f2490b6e3317059e87ba40d4f659d1c30afc1fBjorn Helgaasstatic int pnpacpi_supported_resource(struct acpi_resource *res) 7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 790eca008c8134df15262a0362623edb59902628c95Len Brown switch (res->type) { 79150eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore case ACPI_RESOURCE_TYPE_IRQ: 79250eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore case ACPI_RESOURCE_TYPE_DMA: 79350eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore case ACPI_RESOURCE_TYPE_IO: 79450eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore case ACPI_RESOURCE_TYPE_FIXED_IO: 79550eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore case ACPI_RESOURCE_TYPE_MEMORY24: 79650eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore case ACPI_RESOURCE_TYPE_MEMORY32: 79750eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: 79850eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore case ACPI_RESOURCE_TYPE_ADDRESS16: 79950eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore case ACPI_RESOURCE_TYPE_ADDRESS32: 80050eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore case ACPI_RESOURCE_TYPE_ADDRESS64: 8018cb24c8fd70ea8431744de1ca0ca34ab45fbbdaaBjorn Helgaas case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: 8020af5853bccd263161df80c259d61fc71211c5ac3Len Brown case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 803b5f2490b6e3317059e87ba40d4f659d1c30afc1fBjorn Helgaas return 1; 8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 805b5f2490b6e3317059e87ba40d4f659d1c30afc1fBjorn Helgaas return 0; 806b5f2490b6e3317059e87ba40d4f659d1c30afc1fBjorn Helgaas} 807b5f2490b6e3317059e87ba40d4f659d1c30afc1fBjorn Helgaas 808b5f2490b6e3317059e87ba40d4f659d1c30afc1fBjorn Helgaas/* 809b5f2490b6e3317059e87ba40d4f659d1c30afc1fBjorn Helgaas * Set resource 810b5f2490b6e3317059e87ba40d4f659d1c30afc1fBjorn Helgaas */ 811b5f2490b6e3317059e87ba40d4f659d1c30afc1fBjorn Helgaasstatic acpi_status pnpacpi_count_resources(struct acpi_resource *res, 8129dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas void *data) 813b5f2490b6e3317059e87ba40d4f659d1c30afc1fBjorn Helgaas{ 8144721a4cc8864f0eb92958c3e0479e7994e8b0072Bjorn Helgaas int *res_cnt = data; 815b5f2490b6e3317059e87ba40d4f659d1c30afc1fBjorn Helgaas 816b5f2490b6e3317059e87ba40d4f659d1c30afc1fBjorn Helgaas if (pnpacpi_supported_resource(res)) 817b5f2490b6e3317059e87ba40d4f659d1c30afc1fBjorn Helgaas (*res_cnt)++; 8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return AE_OK; 8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8211c6e7d0aeecac38e66b1bb63e3eff07b2a1c2f2cBjorn Helgaasstatic acpi_status pnpacpi_type_resources(struct acpi_resource *res, void *data) 8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8234721a4cc8864f0eb92958c3e0479e7994e8b0072Bjorn Helgaas struct acpi_resource **resource = data; 824b5f2490b6e3317059e87ba40d4f659d1c30afc1fBjorn Helgaas 825b5f2490b6e3317059e87ba40d4f659d1c30afc1fBjorn Helgaas if (pnpacpi_supported_resource(res)) { 826eca008c8134df15262a0362623edb59902628c95Len Brown (*resource)->type = res->type; 827b5f2490b6e3317059e87ba40d4f659d1c30afc1fBjorn Helgaas (*resource)->length = sizeof(struct acpi_resource); 82836d872a370d3d10e5a7faa9dcacce744260fb13bBjorn Helgaas if (res->type == ACPI_RESOURCE_TYPE_IRQ) 82936d872a370d3d10e5a7faa9dcacce744260fb13bBjorn Helgaas (*resource)->data.irq.descriptor_length = 83036d872a370d3d10e5a7faa9dcacce744260fb13bBjorn Helgaas res->data.irq.descriptor_length; 8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (*resource)++; 8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return AE_OK; 8351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 837cdef6254e17e98f1071ce1bfc8f2a87997c855d0Bjorn Helgaasint pnpacpi_build_resource_template(struct pnp_dev *dev, 8389dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas struct acpi_buffer *buffer) 8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 840c4da6940a7a41c72781ff2d62ebd4b99f3749f14Bjorn Helgaas struct acpi_device *acpi_dev = dev->data; 841c4da6940a7a41c72781ff2d62ebd4b99f3749f14Bjorn Helgaas acpi_handle handle = acpi_dev->handle; 8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct acpi_resource *resource; 8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int res_cnt = 0; 8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acpi_status status; 8451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 84650eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore status = acpi_walk_resources(handle, METHOD_NAME__CRS, 8479dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas pnpacpi_count_resources, &res_cnt); 8481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ACPI_FAILURE(status)) { 849d152cf5d0c3325979e71ee53b425fdd51a1a285aBjorn Helgaas dev_err(&dev->dev, "can't evaluate _CRS: %d\n", status); 8501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!res_cnt) 8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buffer->length = sizeof(struct acpi_resource) * (res_cnt + 1) + 1; 855cd86128088554d64fea1679191509f00e6353c5bRobert P. J. Day buffer->pointer = kzalloc(buffer->length - 1, GFP_KERNEL); 8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!buffer->pointer) 8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 85872dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas 8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds resource = (struct acpi_resource *)buffer->pointer; 86050eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore status = acpi_walk_resources(handle, METHOD_NAME__CRS, 8619dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas pnpacpi_type_resources, &resource); 8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ACPI_FAILURE(status)) { 8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(buffer->pointer); 864d152cf5d0c3325979e71ee53b425fdd51a1a285aBjorn Helgaas dev_err(&dev->dev, "can't evaluate _CRS: %d\n", status); 8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* resource will pointer the end resource now */ 86850eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore resource->type = ACPI_RESOURCE_TYPE_END_TAG; 8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 87372dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaasstatic void pnpacpi_encode_irq(struct pnp_dev *dev, 87472dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas struct acpi_resource *resource, 8759dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas struct resource *p) 8761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8779570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas struct acpi_resource_irq *irq = &resource->data.irq; 878a993273beae8022390e48fe9205480565ad470abBjorn Helgaas int triggering, polarity, shareable; 8791c6e7d0aeecac38e66b1bb63e3eff07b2a1c2f2cBjorn Helgaas 880aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas if (!pnp_resource_enabled(p)) { 881aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas irq->interrupt_count = 0; 8822f53432c2aedbe79020e44525eb069d9138a01ddBjorn Helgaas pnp_dbg(&dev->dev, " encode irq (%s)\n", 883aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas p ? "disabled" : "missing"); 884aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas return; 885aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas } 886aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas 887a993273beae8022390e48fe9205480565ad470abBjorn Helgaas decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable); 8889570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas irq->triggering = triggering; 8899570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas irq->polarity = polarity; 890a993273beae8022390e48fe9205480565ad470abBjorn Helgaas irq->sharable = shareable; 8919570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas irq->interrupt_count = 1; 8929570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas irq->interrupts[0] = p->start; 89372dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas 8942f53432c2aedbe79020e44525eb069d9138a01ddBjorn Helgaas pnp_dbg(&dev->dev, " encode irq %d %s %s %s (%d-byte descriptor)\n", 89536d872a370d3d10e5a7faa9dcacce744260fb13bBjorn Helgaas (int) p->start, 89672dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge", 89772dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas polarity == ACPI_ACTIVE_LOW ? "low" : "high", 89836d872a370d3d10e5a7faa9dcacce744260fb13bBjorn Helgaas irq->sharable == ACPI_SHARED ? "shared" : "exclusive", 89936d872a370d3d10e5a7faa9dcacce744260fb13bBjorn Helgaas irq->descriptor_length); 9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 90272dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaasstatic void pnpacpi_encode_ext_irq(struct pnp_dev *dev, 90372dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas struct acpi_resource *resource, 9049dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas struct resource *p) 9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9069570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq; 907a993273beae8022390e48fe9205480565ad470abBjorn Helgaas int triggering, polarity, shareable; 9081c6e7d0aeecac38e66b1bb63e3eff07b2a1c2f2cBjorn Helgaas 909aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas if (!pnp_resource_enabled(p)) { 910aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas extended_irq->interrupt_count = 0; 9112f53432c2aedbe79020e44525eb069d9138a01ddBjorn Helgaas pnp_dbg(&dev->dev, " encode extended irq (%s)\n", 912aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas p ? "disabled" : "missing"); 913aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas return; 914aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas } 915aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas 916a993273beae8022390e48fe9205480565ad470abBjorn Helgaas decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable); 9179570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas extended_irq->producer_consumer = ACPI_CONSUMER; 9189570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas extended_irq->triggering = triggering; 9199570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas extended_irq->polarity = polarity; 920a993273beae8022390e48fe9205480565ad470abBjorn Helgaas extended_irq->sharable = shareable; 9219570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas extended_irq->interrupt_count = 1; 9229570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas extended_irq->interrupts[0] = p->start; 92372dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas 9242f53432c2aedbe79020e44525eb069d9138a01ddBjorn Helgaas pnp_dbg(&dev->dev, " encode irq %d %s %s %s\n", (int) p->start, 92572dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge", 92672dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas polarity == ACPI_ACTIVE_LOW ? "low" : "high", 92772dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas extended_irq->sharable == ACPI_SHARED ? "shared" : "exclusive"); 9281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 93072dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaasstatic void pnpacpi_encode_dma(struct pnp_dev *dev, 93172dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas struct acpi_resource *resource, 9329dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas struct resource *p) 9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9349570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas struct acpi_resource_dma *dma = &resource->data.dma; 9359570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas 936aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas if (!pnp_resource_enabled(p)) { 937aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas dma->channel_count = 0; 9382f53432c2aedbe79020e44525eb069d9138a01ddBjorn Helgaas pnp_dbg(&dev->dev, " encode dma (%s)\n", 939aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas p ? "disabled" : "missing"); 940aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas return; 941aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas } 942aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas 9431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */ 944ccc4c7bbd6a2d47bf5899c2c8cf2e0d176a4dc0fVojtech Pavlik switch (p->flags & IORESOURCE_DMA_SPEED_MASK) { 9459dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas case IORESOURCE_DMA_TYPEA: 9469570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas dma->type = ACPI_TYPE_A; 9479dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas break; 9489dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas case IORESOURCE_DMA_TYPEB: 9499570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas dma->type = ACPI_TYPE_B; 9509dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas break; 9519dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas case IORESOURCE_DMA_TYPEF: 9529570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas dma->type = ACPI_TYPE_F; 9539dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas break; 9549dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas default: 9559570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas dma->type = ACPI_COMPATIBILITY; 956ccc4c7bbd6a2d47bf5899c2c8cf2e0d176a4dc0fVojtech Pavlik } 957ccc4c7bbd6a2d47bf5899c2c8cf2e0d176a4dc0fVojtech Pavlik 958ccc4c7bbd6a2d47bf5899c2c8cf2e0d176a4dc0fVojtech Pavlik switch (p->flags & IORESOURCE_DMA_TYPE_MASK) { 9599dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas case IORESOURCE_DMA_8BIT: 9609570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas dma->transfer = ACPI_TRANSFER_8; 9619dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas break; 9629dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas case IORESOURCE_DMA_8AND16BIT: 9639570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas dma->transfer = ACPI_TRANSFER_8_16; 9649dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas break; 9659dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas default: 9669570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas dma->transfer = ACPI_TRANSFER_16; 967ccc4c7bbd6a2d47bf5899c2c8cf2e0d176a4dc0fVojtech Pavlik } 968ccc4c7bbd6a2d47bf5899c2c8cf2e0d176a4dc0fVojtech Pavlik 9699570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas dma->bus_master = !!(p->flags & IORESOURCE_DMA_MASTER); 9709570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas dma->channel_count = 1; 9719570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas dma->channels[0] = p->start; 97272dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas 9732f53432c2aedbe79020e44525eb069d9138a01ddBjorn Helgaas pnp_dbg(&dev->dev, " encode dma %d " 97472dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas "type %#x transfer %#x master %d\n", 97572dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas (int) p->start, dma->type, dma->transfer, dma->bus_master); 9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 97872dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaasstatic void pnpacpi_encode_io(struct pnp_dev *dev, 97972dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas struct acpi_resource *resource, 9809dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas struct resource *p) 9811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9829570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas struct acpi_resource_io *io = &resource->data.io; 9839570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas 984aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas if (pnp_resource_enabled(p)) { 985aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas /* Note: pnp_assign_port copies pnp_port->flags into p->flags */ 98608c9f262f268f7948be13bf3a5bda1d635c649b4Bjorn Helgaas io->io_decode = (p->flags & IORESOURCE_IO_16BIT_ADDR) ? 987aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas ACPI_DECODE_16 : ACPI_DECODE_10; 988aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas io->minimum = p->start; 989aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas io->maximum = p->end; 990aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas io->alignment = 0; /* Correct? */ 99128f65c11f2ffb3957259dece647a24f8ad2e241bJoe Perches io->address_length = resource_size(p); 992aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas } else { 993aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas io->minimum = 0; 994aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas io->address_length = 0; 995aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas } 99672dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas 9972f53432c2aedbe79020e44525eb069d9138a01ddBjorn Helgaas pnp_dbg(&dev->dev, " encode io %#x-%#x decode %#x\n", io->minimum, 998aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas io->minimum + io->address_length - 1, io->io_decode); 9991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 100172dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaasstatic void pnpacpi_encode_fixed_io(struct pnp_dev *dev, 100272dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas struct acpi_resource *resource, 10039dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas struct resource *p) 10041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10059570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas struct acpi_resource_fixed_io *fixed_io = &resource->data.fixed_io; 10069570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas 1007aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas if (pnp_resource_enabled(p)) { 1008aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas fixed_io->address = p->start; 100928f65c11f2ffb3957259dece647a24f8ad2e241bJoe Perches fixed_io->address_length = resource_size(p); 1010aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas } else { 1011aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas fixed_io->address = 0; 1012aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas fixed_io->address_length = 0; 1013aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas } 101472dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas 10152f53432c2aedbe79020e44525eb069d9138a01ddBjorn Helgaas pnp_dbg(&dev->dev, " encode fixed_io %#x-%#x\n", fixed_io->address, 1016aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas fixed_io->address + fixed_io->address_length - 1); 10171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 101972dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaasstatic void pnpacpi_encode_mem24(struct pnp_dev *dev, 102072dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas struct acpi_resource *resource, 10219dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas struct resource *p) 10221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10239570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas struct acpi_resource_memory24 *memory24 = &resource->data.memory24; 10249570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas 1025aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas if (pnp_resource_enabled(p)) { 1026aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas /* Note: pnp_assign_mem copies pnp_mem->flags into p->flags */ 1027aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas memory24->write_protect = p->flags & IORESOURCE_MEM_WRITEABLE ? 1028aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; 1029aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas memory24->minimum = p->start; 1030aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas memory24->maximum = p->end; 1031aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas memory24->alignment = 0; 103228f65c11f2ffb3957259dece647a24f8ad2e241bJoe Perches memory24->address_length = resource_size(p); 1033aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas } else { 1034aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas memory24->minimum = 0; 1035aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas memory24->address_length = 0; 1036aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas } 1037aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas 10382f53432c2aedbe79020e44525eb069d9138a01ddBjorn Helgaas pnp_dbg(&dev->dev, " encode mem24 %#x-%#x write_protect %#x\n", 1039aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas memory24->minimum, 1040aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas memory24->minimum + memory24->address_length - 1, 104172dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas memory24->write_protect); 10421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 104472dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaasstatic void pnpacpi_encode_mem32(struct pnp_dev *dev, 104572dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas struct acpi_resource *resource, 10469dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas struct resource *p) 10471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10489570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas struct acpi_resource_memory32 *memory32 = &resource->data.memory32; 10499570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas 1050aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas if (pnp_resource_enabled(p)) { 1051aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas memory32->write_protect = p->flags & IORESOURCE_MEM_WRITEABLE ? 1052aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; 1053aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas memory32->minimum = p->start; 1054aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas memory32->maximum = p->end; 1055aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas memory32->alignment = 0; 105628f65c11f2ffb3957259dece647a24f8ad2e241bJoe Perches memory32->address_length = resource_size(p); 1057aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas } else { 1058aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas memory32->minimum = 0; 1059aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas memory32->alignment = 0; 1060aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas } 106172dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas 10622f53432c2aedbe79020e44525eb069d9138a01ddBjorn Helgaas pnp_dbg(&dev->dev, " encode mem32 %#x-%#x write_protect %#x\n", 1063aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas memory32->minimum, 1064aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas memory32->minimum + memory32->address_length - 1, 106572dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas memory32->write_protect); 10661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 106872dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaasstatic void pnpacpi_encode_fixed_mem32(struct pnp_dev *dev, 106972dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas struct acpi_resource *resource, 10709dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas struct resource *p) 10711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10729570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas struct acpi_resource_fixed_memory32 *fixed_memory32 = &resource->data.fixed_memory32; 10739570a20e9da282721afc6885dbeaa1b9c1e7ff4dBjorn Helgaas 1074aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas if (pnp_resource_enabled(p)) { 1075aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas fixed_memory32->write_protect = 1076aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas p->flags & IORESOURCE_MEM_WRITEABLE ? 1077aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; 1078aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas fixed_memory32->address = p->start; 107928f65c11f2ffb3957259dece647a24f8ad2e241bJoe Perches fixed_memory32->address_length = resource_size(p); 1080aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas } else { 1081aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas fixed_memory32->address = 0; 1082aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas fixed_memory32->address_length = 0; 1083aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas } 108472dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas 10852f53432c2aedbe79020e44525eb069d9138a01ddBjorn Helgaas pnp_dbg(&dev->dev, " encode fixed_mem32 %#x-%#x write_protect %#x\n", 1086aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas fixed_memory32->address, 1087aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas fixed_memory32->address + fixed_memory32->address_length - 1, 108872dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas fixed_memory32->write_protect); 10891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10914ab55d8d4f7b910c4c60e0f8ff70d0dfdd484f02Bjorn Helgaasint pnpacpi_encode_resources(struct pnp_dev *dev, struct acpi_buffer *buffer) 10921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i = 0; 10941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* pnpacpi_build_resource_template allocates extra mem */ 10959dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas int res_cnt = (buffer->length - 1) / sizeof(struct acpi_resource) - 1; 10964721a4cc8864f0eb92958c3e0479e7994e8b0072Bjorn Helgaas struct acpi_resource *resource = buffer->pointer; 10971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int port = 0, irq = 0, dma = 0, mem = 0; 10981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10992f53432c2aedbe79020e44525eb069d9138a01ddBjorn Helgaas pnp_dbg(&dev->dev, "encode %d resources\n", res_cnt); 11001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (i < res_cnt) { 11019dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas switch (resource->type) { 110250eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore case ACPI_RESOURCE_TYPE_IRQ: 110372dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas pnpacpi_encode_irq(dev, resource, 11047e2cf31f1c97ac14b6d9dc5f1ce9e1e01aef9c18Bjorn Helgaas pnp_get_resource(dev, IORESOURCE_IRQ, irq)); 11051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds irq++; 11061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 110850eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore case ACPI_RESOURCE_TYPE_DMA: 110972dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas pnpacpi_encode_dma(dev, resource, 11107e2cf31f1c97ac14b6d9dc5f1ce9e1e01aef9c18Bjorn Helgaas pnp_get_resource(dev, IORESOURCE_DMA, dma)); 11111c6e7d0aeecac38e66b1bb63e3eff07b2a1c2f2cBjorn Helgaas dma++; 11121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 111350eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore case ACPI_RESOURCE_TYPE_IO: 111472dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas pnpacpi_encode_io(dev, resource, 11157e2cf31f1c97ac14b6d9dc5f1ce9e1e01aef9c18Bjorn Helgaas pnp_get_resource(dev, IORESOURCE_IO, port)); 11161c6e7d0aeecac38e66b1bb63e3eff07b2a1c2f2cBjorn Helgaas port++; 11171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 111850eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore case ACPI_RESOURCE_TYPE_FIXED_IO: 111972dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas pnpacpi_encode_fixed_io(dev, resource, 11207e2cf31f1c97ac14b6d9dc5f1ce9e1e01aef9c18Bjorn Helgaas pnp_get_resource(dev, IORESOURCE_IO, port)); 11211c6e7d0aeecac38e66b1bb63e3eff07b2a1c2f2cBjorn Helgaas port++; 11221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 112350eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore case ACPI_RESOURCE_TYPE_MEMORY24: 112472dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas pnpacpi_encode_mem24(dev, resource, 11257e2cf31f1c97ac14b6d9dc5f1ce9e1e01aef9c18Bjorn Helgaas pnp_get_resource(dev, IORESOURCE_MEM, mem)); 11261c6e7d0aeecac38e66b1bb63e3eff07b2a1c2f2cBjorn Helgaas mem++; 11271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 112850eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore case ACPI_RESOURCE_TYPE_MEMORY32: 112972dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas pnpacpi_encode_mem32(dev, resource, 11307e2cf31f1c97ac14b6d9dc5f1ce9e1e01aef9c18Bjorn Helgaas pnp_get_resource(dev, IORESOURCE_MEM, mem)); 11311c6e7d0aeecac38e66b1bb63e3eff07b2a1c2f2cBjorn Helgaas mem++; 11321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 113350eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: 113472dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas pnpacpi_encode_fixed_mem32(dev, resource, 11357e2cf31f1c97ac14b6d9dc5f1ce9e1e01aef9c18Bjorn Helgaas pnp_get_resource(dev, IORESOURCE_MEM, mem)); 11361c6e7d0aeecac38e66b1bb63e3eff07b2a1c2f2cBjorn Helgaas mem++; 11371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11380af5853bccd263161df80c259d61fc71211c5ac3Len Brown case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 113972dcc883d8e5b59105e75ee5265442e458740575Bjorn Helgaas pnpacpi_encode_ext_irq(dev, resource, 11407e2cf31f1c97ac14b6d9dc5f1ce9e1e01aef9c18Bjorn Helgaas pnp_get_resource(dev, IORESOURCE_IRQ, irq)); 11410af5853bccd263161df80c259d61fc71211c5ac3Len Brown irq++; 11420af5853bccd263161df80c259d61fc71211c5ac3Len Brown break; 11430af5853bccd263161df80c259d61fc71211c5ac3Len Brown case ACPI_RESOURCE_TYPE_START_DEPENDENT: 11440af5853bccd263161df80c259d61fc71211c5ac3Len Brown case ACPI_RESOURCE_TYPE_END_DEPENDENT: 11450af5853bccd263161df80c259d61fc71211c5ac3Len Brown case ACPI_RESOURCE_TYPE_VENDOR: 11460af5853bccd263161df80c259d61fc71211c5ac3Len Brown case ACPI_RESOURCE_TYPE_END_TAG: 11470af5853bccd263161df80c259d61fc71211c5ac3Len Brown case ACPI_RESOURCE_TYPE_ADDRESS16: 11480af5853bccd263161df80c259d61fc71211c5ac3Len Brown case ACPI_RESOURCE_TYPE_ADDRESS32: 11490af5853bccd263161df80c259d61fc71211c5ac3Len Brown case ACPI_RESOURCE_TYPE_ADDRESS64: 11500af5853bccd263161df80c259d61fc71211c5ac3Len Brown case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: 11510af5853bccd263161df80c259d61fc71211c5ac3Len Brown case ACPI_RESOURCE_TYPE_GENERIC_REGISTER: 11529dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas default: /* other type */ 1153af11cb2d521f9d7e10c565bafe8f2358772baa65Bjorn Helgaas dev_warn(&dev->dev, "can't encode unknown resource " 1154af11cb2d521f9d7e10c565bafe8f2358772baa65Bjorn Helgaas "type %d\n", resource->type); 11551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 11561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11571c6e7d0aeecac38e66b1bb63e3eff07b2a1c2f2cBjorn Helgaas resource++; 11581c6e7d0aeecac38e66b1bb63e3eff07b2a1c2f2cBjorn Helgaas i++; 11591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 11611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1162