diff options
author | Len Brown <len.brown@intel.com> | 2005-12-06 17:31:30 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2005-12-06 17:31:30 -0500 |
commit | 3d5271f9883cba7b54762bc4fe027d4172f06db7 (patch) | |
tree | ab8a881a14478598a0c8bda0d26c62cdccfffd6d /drivers/char/hpet.c | |
parent | 378b2556f4e09fa6f87ff0cb5c4395ff28257d02 (diff) | |
parent | 9115a6c787596e687df03010d97fccc5e0762506 (diff) |
Pull release into acpica branch
Diffstat (limited to 'drivers/char/hpet.c')
-rw-r--r-- | drivers/char/hpet.c | 169 |
1 files changed, 113 insertions, 56 deletions
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index a5c3f9c0c909..5172d4e1236c 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c | |||
@@ -49,7 +49,9 @@ | |||
49 | #define HPET_USER_FREQ (64) | 49 | #define HPET_USER_FREQ (64) |
50 | #define HPET_DRIFT (500) | 50 | #define HPET_DRIFT (500) |
51 | 51 | ||
52 | static u32 hpet_ntimer, hpet_nhpet, hpet_max_freq = HPET_USER_FREQ; | 52 | #define HPET_RANGE_SIZE 1024 /* from HPET spec */ |
53 | |||
54 | static u32 hpet_nhpet, hpet_max_freq = HPET_USER_FREQ; | ||
53 | 55 | ||
54 | /* A lock for concurrent access by app and isr hpet activity. */ | 56 | /* A lock for concurrent access by app and isr hpet activity. */ |
55 | static DEFINE_SPINLOCK(hpet_lock); | 57 | static DEFINE_SPINLOCK(hpet_lock); |
@@ -78,7 +80,7 @@ struct hpets { | |||
78 | struct hpet __iomem *hp_hpet; | 80 | struct hpet __iomem *hp_hpet; |
79 | unsigned long hp_hpet_phys; | 81 | unsigned long hp_hpet_phys; |
80 | struct time_interpolator *hp_interpolator; | 82 | struct time_interpolator *hp_interpolator; |
81 | unsigned long hp_period; | 83 | unsigned long long hp_tick_freq; |
82 | unsigned long hp_delta; | 84 | unsigned long hp_delta; |
83 | unsigned int hp_ntimer; | 85 | unsigned int hp_ntimer; |
84 | unsigned int hp_which; | 86 | unsigned int hp_which; |
@@ -90,6 +92,7 @@ static struct hpets *hpets; | |||
90 | #define HPET_OPEN 0x0001 | 92 | #define HPET_OPEN 0x0001 |
91 | #define HPET_IE 0x0002 /* interrupt enabled */ | 93 | #define HPET_IE 0x0002 /* interrupt enabled */ |
92 | #define HPET_PERIODIC 0x0004 | 94 | #define HPET_PERIODIC 0x0004 |
95 | #define HPET_SHARED_IRQ 0x0008 | ||
93 | 96 | ||
94 | #if BITS_PER_LONG == 64 | 97 | #if BITS_PER_LONG == 64 |
95 | #define write_counter(V, MC) writeq(V, MC) | 98 | #define write_counter(V, MC) writeq(V, MC) |
@@ -120,6 +123,11 @@ static irqreturn_t hpet_interrupt(int irq, void *data, struct pt_regs *regs) | |||
120 | unsigned long isr; | 123 | unsigned long isr; |
121 | 124 | ||
122 | devp = data; | 125 | devp = data; |
126 | isr = 1 << (devp - devp->hd_hpets->hp_dev); | ||
127 | |||
128 | if ((devp->hd_flags & HPET_SHARED_IRQ) && | ||
129 | !(isr & readl(&devp->hd_hpet->hpet_isr))) | ||
130 | return IRQ_NONE; | ||
123 | 131 | ||
124 | spin_lock(&hpet_lock); | 132 | spin_lock(&hpet_lock); |
125 | devp->hd_irqdata++; | 133 | devp->hd_irqdata++; |
@@ -137,8 +145,8 @@ static irqreturn_t hpet_interrupt(int irq, void *data, struct pt_regs *regs) | |||
137 | &devp->hd_timer->hpet_compare); | 145 | &devp->hd_timer->hpet_compare); |
138 | } | 146 | } |
139 | 147 | ||
140 | isr = (1 << (devp - devp->hd_hpets->hp_dev)); | 148 | if (devp->hd_flags & HPET_SHARED_IRQ) |
141 | writeq(isr, &devp->hd_hpet->hpet_isr); | 149 | writel(isr, &devp->hd_hpet->hpet_isr); |
142 | spin_unlock(&hpet_lock); | 150 | spin_unlock(&hpet_lock); |
143 | 151 | ||
144 | spin_lock(&hpet_task_lock); | 152 | spin_lock(&hpet_task_lock); |
@@ -273,11 +281,11 @@ static int hpet_mmap(struct file *file, struct vm_area_struct *vma) | |||
273 | 281 | ||
274 | vma->vm_flags |= VM_IO; | 282 | vma->vm_flags |= VM_IO; |
275 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | 283 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
276 | addr = __pa(addr); | ||
277 | 284 | ||
278 | if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT, | 285 | if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT, |
279 | PAGE_SIZE, vma->vm_page_prot)) { | 286 | PAGE_SIZE, vma->vm_page_prot)) { |
280 | printk(KERN_ERR "remap_pfn_range failed in hpet.c\n"); | 287 | printk(KERN_ERR "%s: io_remap_pfn_range failed\n", |
288 | __FUNCTION__); | ||
281 | return -EAGAIN; | 289 | return -EAGAIN; |
282 | } | 290 | } |
283 | 291 | ||
@@ -365,7 +373,9 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp) | |||
365 | hpet = devp->hd_hpet; | 373 | hpet = devp->hd_hpet; |
366 | hpetp = devp->hd_hpets; | 374 | hpetp = devp->hd_hpets; |
367 | 375 | ||
368 | v = readq(&timer->hpet_config); | 376 | if (!devp->hd_ireqfreq) |
377 | return -EIO; | ||
378 | |||
369 | spin_lock_irq(&hpet_lock); | 379 | spin_lock_irq(&hpet_lock); |
370 | 380 | ||
371 | if (devp->hd_flags & HPET_IE) { | 381 | if (devp->hd_flags & HPET_IE) { |
@@ -374,16 +384,21 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp) | |||
374 | } | 384 | } |
375 | 385 | ||
376 | devp->hd_flags |= HPET_IE; | 386 | devp->hd_flags |= HPET_IE; |
387 | |||
388 | if (readl(&timer->hpet_config) & Tn_INT_TYPE_CNF_MASK) | ||
389 | devp->hd_flags |= HPET_SHARED_IRQ; | ||
377 | spin_unlock_irq(&hpet_lock); | 390 | spin_unlock_irq(&hpet_lock); |
378 | 391 | ||
379 | t = readq(&timer->hpet_config); | ||
380 | irq = devp->hd_hdwirq; | 392 | irq = devp->hd_hdwirq; |
381 | 393 | ||
382 | if (irq) { | 394 | if (irq) { |
383 | sprintf(devp->hd_name, "hpet%d", (int)(devp - hpetp->hp_dev)); | 395 | unsigned long irq_flags; |
384 | 396 | ||
385 | if (request_irq | 397 | sprintf(devp->hd_name, "hpet%d", (int)(devp - hpetp->hp_dev)); |
386 | (irq, hpet_interrupt, SA_INTERRUPT, devp->hd_name, (void *)devp)) { | 398 | irq_flags = devp->hd_flags & HPET_SHARED_IRQ |
399 | ? SA_SHIRQ : SA_INTERRUPT; | ||
400 | if (request_irq(irq, hpet_interrupt, irq_flags, | ||
401 | devp->hd_name, (void *)devp)) { | ||
387 | printk(KERN_ERR "hpet: IRQ %d is not free\n", irq); | 402 | printk(KERN_ERR "hpet: IRQ %d is not free\n", irq); |
388 | irq = 0; | 403 | irq = 0; |
389 | } | 404 | } |
@@ -417,20 +432,24 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp) | |||
417 | write_counter(t + m + hpetp->hp_delta, &timer->hpet_compare); | 432 | write_counter(t + m + hpetp->hp_delta, &timer->hpet_compare); |
418 | } | 433 | } |
419 | 434 | ||
420 | isr = (1 << (devp - hpets->hp_dev)); | 435 | if (devp->hd_flags & HPET_SHARED_IRQ) { |
421 | writeq(isr, &hpet->hpet_isr); | 436 | isr = 1 << (devp - devp->hd_hpets->hp_dev); |
437 | writel(isr, &hpet->hpet_isr); | ||
438 | } | ||
422 | writeq(g, &timer->hpet_config); | 439 | writeq(g, &timer->hpet_config); |
423 | local_irq_restore(flags); | 440 | local_irq_restore(flags); |
424 | 441 | ||
425 | return 0; | 442 | return 0; |
426 | } | 443 | } |
427 | 444 | ||
428 | static inline unsigned long hpet_time_div(unsigned long dis) | 445 | /* converts Hz to number of timer ticks */ |
446 | static inline unsigned long hpet_time_div(struct hpets *hpets, | ||
447 | unsigned long dis) | ||
429 | { | 448 | { |
430 | unsigned long long m = 1000000000000000ULL; | 449 | unsigned long long m; |
431 | 450 | ||
451 | m = hpets->hp_tick_freq + (dis >> 1); | ||
432 | do_div(m, dis); | 452 | do_div(m, dis); |
433 | |||
434 | return (unsigned long)m; | 453 | return (unsigned long)m; |
435 | } | 454 | } |
436 | 455 | ||
@@ -478,14 +497,21 @@ hpet_ioctl_common(struct hpet_dev *devp, int cmd, unsigned long arg, int kernel) | |||
478 | { | 497 | { |
479 | struct hpet_info info; | 498 | struct hpet_info info; |
480 | 499 | ||
481 | info.hi_ireqfreq = hpet_time_div(hpetp->hp_period * | 500 | if (devp->hd_ireqfreq) |
482 | devp->hd_ireqfreq); | 501 | info.hi_ireqfreq = |
502 | hpet_time_div(hpetp, devp->hd_ireqfreq); | ||
503 | else | ||
504 | info.hi_ireqfreq = 0; | ||
483 | info.hi_flags = | 505 | info.hi_flags = |
484 | readq(&timer->hpet_config) & Tn_PER_INT_CAP_MASK; | 506 | readq(&timer->hpet_config) & Tn_PER_INT_CAP_MASK; |
485 | info.hi_hpet = devp->hd_hpets->hp_which; | 507 | info.hi_hpet = hpetp->hp_which; |
486 | info.hi_timer = devp - devp->hd_hpets->hp_dev; | 508 | info.hi_timer = devp - hpetp->hp_dev; |
487 | if (copy_to_user((void __user *)arg, &info, sizeof(info))) | 509 | if (kernel) |
488 | err = -EFAULT; | 510 | memcpy((void *)arg, &info, sizeof(info)); |
511 | else | ||
512 | if (copy_to_user((void __user *)arg, &info, | ||
513 | sizeof(info))) | ||
514 | err = -EFAULT; | ||
489 | break; | 515 | break; |
490 | } | 516 | } |
491 | case HPET_EPI: | 517 | case HPET_EPI: |
@@ -517,12 +543,12 @@ hpet_ioctl_common(struct hpet_dev *devp, int cmd, unsigned long arg, int kernel) | |||
517 | break; | 543 | break; |
518 | } | 544 | } |
519 | 545 | ||
520 | if (arg & (arg - 1)) { | 546 | if (!arg) { |
521 | err = -EINVAL; | 547 | err = -EINVAL; |
522 | break; | 548 | break; |
523 | } | 549 | } |
524 | 550 | ||
525 | devp->hd_ireqfreq = hpet_time_div(hpetp->hp_period * arg); | 551 | devp->hd_ireqfreq = hpet_time_div(hpetp, arg); |
526 | } | 552 | } |
527 | 553 | ||
528 | return err; | 554 | return err; |
@@ -540,6 +566,17 @@ static struct file_operations hpet_fops = { | |||
540 | .mmap = hpet_mmap, | 566 | .mmap = hpet_mmap, |
541 | }; | 567 | }; |
542 | 568 | ||
569 | static int hpet_is_known(struct hpet_data *hdp) | ||
570 | { | ||
571 | struct hpets *hpetp; | ||
572 | |||
573 | for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next) | ||
574 | if (hpetp->hp_hpet_phys == hdp->hd_phys_address) | ||
575 | return 1; | ||
576 | |||
577 | return 0; | ||
578 | } | ||
579 | |||
543 | EXPORT_SYMBOL(hpet_alloc); | 580 | EXPORT_SYMBOL(hpet_alloc); |
544 | EXPORT_SYMBOL(hpet_register); | 581 | EXPORT_SYMBOL(hpet_register); |
545 | EXPORT_SYMBOL(hpet_unregister); | 582 | EXPORT_SYMBOL(hpet_unregister); |
@@ -564,6 +601,8 @@ int hpet_register(struct hpet_task *tp, int periodic) | |||
564 | return -EINVAL; | 601 | return -EINVAL; |
565 | } | 602 | } |
566 | 603 | ||
604 | tp->ht_opaque = NULL; | ||
605 | |||
567 | spin_lock_irq(&hpet_task_lock); | 606 | spin_lock_irq(&hpet_task_lock); |
568 | spin_lock(&hpet_lock); | 607 | spin_lock(&hpet_lock); |
569 | 608 | ||
@@ -703,15 +742,14 @@ static void hpet_register_interpolator(struct hpets *hpetp) | |||
703 | #ifdef CONFIG_TIME_INTERPOLATION | 742 | #ifdef CONFIG_TIME_INTERPOLATION |
704 | struct time_interpolator *ti; | 743 | struct time_interpolator *ti; |
705 | 744 | ||
706 | ti = kmalloc(sizeof(*ti), GFP_KERNEL); | 745 | ti = kzalloc(sizeof(*ti), GFP_KERNEL); |
707 | if (!ti) | 746 | if (!ti) |
708 | return; | 747 | return; |
709 | 748 | ||
710 | memset(ti, 0, sizeof(*ti)); | ||
711 | ti->source = TIME_SOURCE_MMIO64; | 749 | ti->source = TIME_SOURCE_MMIO64; |
712 | ti->shift = 10; | 750 | ti->shift = 10; |
713 | ti->addr = &hpetp->hp_hpet->hpet_mc; | 751 | ti->addr = &hpetp->hp_hpet->hpet_mc; |
714 | ti->frequency = hpet_time_div(hpets->hp_period); | 752 | ti->frequency = hpetp->hp_tick_freq; |
715 | ti->drift = HPET_DRIFT; | 753 | ti->drift = HPET_DRIFT; |
716 | ti->mask = -1; | 754 | ti->mask = -1; |
717 | 755 | ||
@@ -744,11 +782,11 @@ static unsigned long hpet_calibrate(struct hpets *hpetp) | |||
744 | if (!timer) | 782 | if (!timer) |
745 | return 0; | 783 | return 0; |
746 | 784 | ||
747 | hpet = hpets->hp_hpet; | 785 | hpet = hpetp->hp_hpet; |
748 | t = read_counter(&timer->hpet_compare); | 786 | t = read_counter(&timer->hpet_compare); |
749 | 787 | ||
750 | i = 0; | 788 | i = 0; |
751 | count = hpet_time_div(hpetp->hp_period * TICK_CALIBRATE); | 789 | count = hpet_time_div(hpetp, TICK_CALIBRATE); |
752 | 790 | ||
753 | local_irq_save(flags); | 791 | local_irq_save(flags); |
754 | 792 | ||
@@ -772,28 +810,29 @@ int hpet_alloc(struct hpet_data *hdp) | |||
772 | struct hpets *hpetp; | 810 | struct hpets *hpetp; |
773 | size_t siz; | 811 | size_t siz; |
774 | struct hpet __iomem *hpet; | 812 | struct hpet __iomem *hpet; |
775 | static struct hpets *last = (struct hpets *)0; | 813 | static struct hpets *last = NULL; |
776 | unsigned long ns; | 814 | unsigned long period; |
815 | unsigned long long temp; | ||
777 | 816 | ||
778 | /* | 817 | /* |
779 | * hpet_alloc can be called by platform dependent code. | 818 | * hpet_alloc can be called by platform dependent code. |
780 | * if platform dependent code has allocated the hpet | 819 | * If platform dependent code has allocated the hpet that |
781 | * ACPI also reports hpet, then we catch it here. | 820 | * ACPI has also reported, then we catch it here. |
782 | */ | 821 | */ |
783 | for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next) | 822 | if (hpet_is_known(hdp)) { |
784 | if (hpetp->hp_hpet == hdp->hd_address) | 823 | printk(KERN_DEBUG "%s: duplicate HPET ignored\n", |
785 | return 0; | 824 | __FUNCTION__); |
825 | return 0; | ||
826 | } | ||
786 | 827 | ||
787 | siz = sizeof(struct hpets) + ((hdp->hd_nirqs - 1) * | 828 | siz = sizeof(struct hpets) + ((hdp->hd_nirqs - 1) * |
788 | sizeof(struct hpet_dev)); | 829 | sizeof(struct hpet_dev)); |
789 | 830 | ||
790 | hpetp = kmalloc(siz, GFP_KERNEL); | 831 | hpetp = kzalloc(siz, GFP_KERNEL); |
791 | 832 | ||
792 | if (!hpetp) | 833 | if (!hpetp) |
793 | return -ENOMEM; | 834 | return -ENOMEM; |
794 | 835 | ||
795 | memset(hpetp, 0, siz); | ||
796 | |||
797 | hpetp->hp_which = hpet_nhpet++; | 836 | hpetp->hp_which = hpet_nhpet++; |
798 | hpetp->hp_hpet = hdp->hd_address; | 837 | hpetp->hp_hpet = hdp->hd_address; |
799 | hpetp->hp_hpet_phys = hdp->hd_phys_address; | 838 | hpetp->hp_hpet_phys = hdp->hd_phys_address; |
@@ -823,21 +862,23 @@ int hpet_alloc(struct hpet_data *hdp) | |||
823 | 862 | ||
824 | last = hpetp; | 863 | last = hpetp; |
825 | 864 | ||
826 | hpetp->hp_period = (cap & HPET_COUNTER_CLK_PERIOD_MASK) >> | 865 | period = (cap & HPET_COUNTER_CLK_PERIOD_MASK) >> |
827 | HPET_COUNTER_CLK_PERIOD_SHIFT; | 866 | HPET_COUNTER_CLK_PERIOD_SHIFT; /* fs, 10^-15 */ |
867 | temp = 1000000000000000uLL; /* 10^15 femtoseconds per second */ | ||
868 | temp += period >> 1; /* round */ | ||
869 | do_div(temp, period); | ||
870 | hpetp->hp_tick_freq = temp; /* ticks per second */ | ||
828 | 871 | ||
829 | printk(KERN_INFO "hpet%d: at MMIO 0x%lx, IRQ%s", | 872 | printk(KERN_INFO "hpet%d: at MMIO 0x%lx (virtual 0x%p), IRQ%s", |
830 | hpetp->hp_which, hdp->hd_phys_address, | 873 | hpetp->hp_which, hdp->hd_phys_address, hdp->hd_address, |
831 | hpetp->hp_ntimer > 1 ? "s" : ""); | 874 | hpetp->hp_ntimer > 1 ? "s" : ""); |
832 | for (i = 0; i < hpetp->hp_ntimer; i++) | 875 | for (i = 0; i < hpetp->hp_ntimer; i++) |
833 | printk("%s %d", i > 0 ? "," : "", hdp->hd_irq[i]); | 876 | printk("%s %d", i > 0 ? "," : "", hdp->hd_irq[i]); |
834 | printk("\n"); | 877 | printk("\n"); |
835 | 878 | ||
836 | ns = hpetp->hp_period; /* femptoseconds, 10^-15 */ | 879 | printk(KERN_INFO "hpet%u: %u %d-bit timers, %Lu Hz\n", |
837 | ns /= 1000000; /* convert to nanoseconds, 10^-9 */ | 880 | hpetp->hp_which, hpetp->hp_ntimer, |
838 | printk(KERN_INFO "hpet%d: %ldns tick, %d %d-bit timers\n", | 881 | cap & HPET_COUNTER_SIZE_MASK ? 64 : 32, hpetp->hp_tick_freq); |
839 | hpetp->hp_which, ns, hpetp->hp_ntimer, | ||
840 | cap & HPET_COUNTER_SIZE_MASK ? 64 : 32); | ||
841 | 882 | ||
842 | mcfg = readq(&hpet->hpet_config); | 883 | mcfg = readq(&hpet->hpet_config); |
843 | if ((mcfg & HPET_ENABLE_CNF_MASK) == 0) { | 884 | if ((mcfg & HPET_ENABLE_CNF_MASK) == 0) { |
@@ -846,13 +887,10 @@ int hpet_alloc(struct hpet_data *hdp) | |||
846 | writeq(mcfg, &hpet->hpet_config); | 887 | writeq(mcfg, &hpet->hpet_config); |
847 | } | 888 | } |
848 | 889 | ||
849 | for (i = 0, devp = hpetp->hp_dev; i < hpetp->hp_ntimer; | 890 | for (i = 0, devp = hpetp->hp_dev; i < hpetp->hp_ntimer; i++, devp++) { |
850 | i++, hpet_ntimer++, devp++) { | ||
851 | unsigned long v; | ||
852 | struct hpet_timer __iomem *timer; | 891 | struct hpet_timer __iomem *timer; |
853 | 892 | ||
854 | timer = &hpet->hpet_timers[devp - hpetp->hp_dev]; | 893 | timer = &hpet->hpet_timers[devp - hpetp->hp_dev]; |
855 | v = readq(&timer->hpet_config); | ||
856 | 894 | ||
857 | devp->hd_hpets = hpetp; | 895 | devp->hd_hpets = hpetp; |
858 | devp->hd_hpet = hpet; | 896 | devp->hd_hpet = hpet; |
@@ -881,7 +919,6 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) | |||
881 | struct hpet_data *hdp; | 919 | struct hpet_data *hdp; |
882 | acpi_status status; | 920 | acpi_status status; |
883 | struct acpi_resource_address64 addr; | 921 | struct acpi_resource_address64 addr; |
884 | struct hpets *hpetp; | ||
885 | 922 | ||
886 | hdp = data; | 923 | hdp = data; |
887 | 924 | ||
@@ -894,9 +931,29 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) | |||
894 | hdp->hd_phys_address = addr.min_address_range; | 931 | hdp->hd_phys_address = addr.min_address_range; |
895 | hdp->hd_address = ioremap(addr.min_address_range, size); | 932 | hdp->hd_address = ioremap(addr.min_address_range, size); |
896 | 933 | ||
897 | for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next) | 934 | if (hpet_is_known(hdp)) { |
898 | if (hpetp->hp_hpet == hdp->hd_address) | 935 | printk(KERN_DEBUG "%s: 0x%lx is busy\n", |
899 | return -EBUSY; | 936 | __FUNCTION__, hdp->hd_phys_address); |
937 | iounmap(hdp->hd_address); | ||
938 | return -EBUSY; | ||
939 | } | ||
940 | } else if (res->type == ACPI_RSTYPE_FIXED_MEM32) { | ||
941 | struct acpi_resource_fixed_mem32 *fixmem32; | ||
942 | |||
943 | fixmem32 = &res->data.fixed_memory32; | ||
944 | if (!fixmem32) | ||
945 | return -EINVAL; | ||
946 | |||
947 | hdp->hd_phys_address = fixmem32->range_base_address; | ||
948 | hdp->hd_address = ioremap(fixmem32->range_base_address, | ||
949 | HPET_RANGE_SIZE); | ||
950 | |||
951 | if (hpet_is_known(hdp)) { | ||
952 | printk(KERN_DEBUG "%s: 0x%lx is busy\n", | ||
953 | __FUNCTION__, hdp->hd_phys_address); | ||
954 | iounmap(hdp->hd_address); | ||
955 | return -EBUSY; | ||
956 | } | ||
900 | } else if (res->type == ACPI_RSTYPE_EXT_IRQ) { | 957 | } else if (res->type == ACPI_RSTYPE_EXT_IRQ) { |
901 | struct acpi_resource_ext_irq *irqp; | 958 | struct acpi_resource_ext_irq *irqp; |
902 | int i; | 959 | int i; |