16 #include <linux/types.h>
17 #include <linux/kernel.h>
18 #include <linux/string.h>
19 #include <linux/slab.h>
25 static void quirk_awe32_add_ports(
struct pnp_dev *
dev,
33 dev_err(&dev->
dev,
"couldn't add ioport region to option set "
34 "%d\n", pnp_option_set(option));
41 list_add(&new_option->
list, &option->
list);
43 dev_info(&dev->
dev,
"added ioport region %#llx-%#llx to set %d\n",
44 (
unsigned long long) new_option->
u.
port.min,
45 (
unsigned long long) new_option->
u.
port.max,
46 pnp_option_set(option));
49 static void quirk_awe32_resources(
struct pnp_dev *dev)
52 unsigned int set = ~0;
59 if (pnp_option_is_dependent(option) &&
60 pnp_option_set(option) !=
set) {
61 set = pnp_option_set(option);
62 quirk_awe32_add_ports(dev, option, 0x800);
63 quirk_awe32_add_ports(dev, option, 0x400);
68 static void quirk_cmi8330_resources(
struct pnp_dev *dev)
75 if (!pnp_option_is_dependent(option))
85 "option set %d to 5, 7, 10\n",
86 pnp_option_set(option));
93 "DMA channel mask in option set %d "
94 "from %#02x to 0x0A (1, 3)\n",
95 pnp_option_set(option), dma->
map);
102 static void quirk_sb16audio_resources(
struct pnp_dev *dev)
105 unsigned int prev_option_flags = ~0,
n = 0;
114 if (prev_option_flags != option->
flags) {
115 prev_option_flags = option->
flags;
119 if (pnp_option_is_dependent(option) &&
122 port = &option->
u.
port;
123 if (
n == 3 && port->
min == port->
max) {
126 "range from %#llx-%#llx to "
128 (
unsigned long long) port->
min,
129 (
unsigned long long) port->
min,
130 (
unsigned long long) port->
min,
131 (
unsigned long long) port->
max);
145 if (pnp_option_is_dependent(option))
149 dev_err(&dev->
dev,
"no dependent option sets\n");
155 if (pnp_option_is_dependent(option) &&
156 pnp_option_set(option) ==
set) {
160 dev_err(&dev->
dev,
"couldn't clone dependent "
167 if (!first_new_option)
168 first_new_option = new_option;
170 list_add(&new_option->
list, &tail->
list);
175 return first_new_option;
179 static void quirk_add_irq_optional_dependent_sets(
struct pnp_dev *dev)
182 unsigned int num_sets,
i,
set;
186 for (i = 0; i < num_sets; i++) {
187 new_option = pnp_clone_dependent_set(dev, i);
191 set = pnp_option_set(new_option);
192 while (new_option && pnp_option_set(new_option) ==
set) {
194 irq = &new_option->
u.
irq;
202 dev_info(&dev->
dev,
"added dependent option set %d (same as "
203 "set %d except IRQ optional)\n",
set, i);
207 static void quirk_ad1815_mpu_resources(
struct pnp_dev *dev)
211 unsigned int independent_irqs = 0;
215 !pnp_option_is_dependent(option)) {
217 irq = &option->
u.
irq;
221 if (independent_irqs != 1)
225 dev_info(&dev->
dev,
"made independent IRQ optional\n");
228 #include <linux/pci.h>
230 static void quirk_system_pci_resources(
struct pnp_dev *dev)
259 if (res->
start == 0 && res->
end == 0)
262 pnp_start = res->
start;
269 if (pnp_end < pci_start || pnp_start > pci_end)
279 if (pnp_start <= pci_start &&
289 "disabling %pR because it overlaps "
290 "%s BAR %d %pR\n", res,
291 pci_name(pdev), i, &pdev->
resource[i]);
302 static void quirk_amd_mmconfig_area(
struct pnp_dev *dev)
307 struct resource mmconfig_res, *mmconfig;
320 "%pR covers only part of AMD MMCONFIG area %pR; adding more reservations\n",
323 start = mmconfig->
start;
324 end = res->
start - 1;
327 if (mmconfig->
end > res->
end) {
328 start = res->
end + 1;
344 {
"CTL0021", quirk_awe32_resources},
345 {
"CTL0022", quirk_awe32_resources},
346 {
"CTL0023", quirk_awe32_resources},
348 {
"@X@0001", quirk_cmi8330_resources},
350 {
"CTL0001", quirk_sb16audio_resources},
351 {
"CTL0031", quirk_sb16audio_resources},
352 {
"CTL0041", quirk_sb16audio_resources},
353 {
"CTL0042", quirk_sb16audio_resources},
354 {
"CTL0043", quirk_sb16audio_resources},
355 {
"CTL0044", quirk_sb16audio_resources},
356 {
"CTL0045", quirk_sb16audio_resources},
358 {
"ADS7151", quirk_ad1815_mpu_resources},
359 {
"ADS7181", quirk_add_irq_optional_dependent_sets},
360 {
"AZT0002", quirk_add_irq_optional_dependent_sets},
362 {
"PNP0c01", quirk_system_pci_resources},
363 {
"PNP0c02", quirk_system_pci_resources},
365 {
"PNP0c01", quirk_amd_mmconfig_area},
374 for (f = pnp_fixups; *f->
id; f++) {