diff options
Diffstat (limited to 'drivers/acpi/osl.c')
-rw-r--r-- | drivers/acpi/osl.c | 124 |
1 files changed, 38 insertions, 86 deletions
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 412a1e04a922..ba14fb93c929 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -77,6 +77,9 @@ EXPORT_SYMBOL(acpi_in_debugger); | |||
77 | extern char line_buf[80]; | 77 | extern char line_buf[80]; |
78 | #endif /*ENABLE_DEBUGGER */ | 78 | #endif /*ENABLE_DEBUGGER */ |
79 | 79 | ||
80 | static int (*__acpi_os_prepare_sleep)(u8 sleep_state, u32 pm1a_ctrl, | ||
81 | u32 pm1b_ctrl); | ||
82 | |||
80 | static acpi_osd_handler acpi_irq_handler; | 83 | static acpi_osd_handler acpi_irq_handler; |
81 | static void *acpi_irq_context; | 84 | static void *acpi_irq_context; |
82 | static struct workqueue_struct *kacpid_wq; | 85 | static struct workqueue_struct *kacpid_wq; |
@@ -347,7 +350,7 @@ static void acpi_unmap(acpi_physical_address pg_off, void __iomem *vaddr) | |||
347 | unsigned long pfn; | 350 | unsigned long pfn; |
348 | 351 | ||
349 | pfn = pg_off >> PAGE_SHIFT; | 352 | pfn = pg_off >> PAGE_SHIFT; |
350 | if (page_is_ram(pfn)) | 353 | if (should_use_kmap(pfn)) |
351 | kunmap(pfn_to_page(pfn)); | 354 | kunmap(pfn_to_page(pfn)); |
352 | else | 355 | else |
353 | iounmap(vaddr); | 356 | iounmap(vaddr); |
@@ -554,6 +557,15 @@ acpi_os_table_override(struct acpi_table_header * existing_table, | |||
554 | return AE_OK; | 557 | return AE_OK; |
555 | } | 558 | } |
556 | 559 | ||
560 | acpi_status | ||
561 | acpi_os_physical_table_override(struct acpi_table_header *existing_table, | ||
562 | acpi_physical_address * new_address, | ||
563 | u32 *new_table_length) | ||
564 | { | ||
565 | return AE_SUPPORT; | ||
566 | } | ||
567 | |||
568 | |||
557 | static irqreturn_t acpi_irq(int irq, void *dev_id) | 569 | static irqreturn_t acpi_irq(int irq, void *dev_id) |
558 | { | 570 | { |
559 | u32 handled; | 571 | u32 handled; |
@@ -595,7 +607,8 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler, | |||
595 | 607 | ||
596 | acpi_irq_handler = handler; | 608 | acpi_irq_handler = handler; |
597 | acpi_irq_context = context; | 609 | acpi_irq_context = context; |
598 | if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) { | 610 | if (request_threaded_irq(irq, NULL, acpi_irq, IRQF_SHARED, "acpi", |
611 | acpi_irq)) { | ||
599 | printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq); | 612 | printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq); |
600 | acpi_irq_handler = NULL; | 613 | acpi_irq_handler = NULL; |
601 | return AE_NOT_ACQUIRED; | 614 | return AE_NOT_ACQUIRED; |
@@ -699,49 +712,6 @@ acpi_status acpi_os_write_port(acpi_io_address port, u32 value, u32 width) | |||
699 | 712 | ||
700 | EXPORT_SYMBOL(acpi_os_write_port); | 713 | EXPORT_SYMBOL(acpi_os_write_port); |
701 | 714 | ||
702 | acpi_status | ||
703 | acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width) | ||
704 | { | ||
705 | void __iomem *virt_addr; | ||
706 | unsigned int size = width / 8; | ||
707 | bool unmap = false; | ||
708 | u32 dummy; | ||
709 | |||
710 | rcu_read_lock(); | ||
711 | virt_addr = acpi_map_vaddr_lookup(phys_addr, size); | ||
712 | if (!virt_addr) { | ||
713 | rcu_read_unlock(); | ||
714 | virt_addr = acpi_os_ioremap(phys_addr, size); | ||
715 | if (!virt_addr) | ||
716 | return AE_BAD_ADDRESS; | ||
717 | unmap = true; | ||
718 | } | ||
719 | |||
720 | if (!value) | ||
721 | value = &dummy; | ||
722 | |||
723 | switch (width) { | ||
724 | case 8: | ||
725 | *(u8 *) value = readb(virt_addr); | ||
726 | break; | ||
727 | case 16: | ||
728 | *(u16 *) value = readw(virt_addr); | ||
729 | break; | ||
730 | case 32: | ||
731 | *(u32 *) value = readl(virt_addr); | ||
732 | break; | ||
733 | default: | ||
734 | BUG(); | ||
735 | } | ||
736 | |||
737 | if (unmap) | ||
738 | iounmap(virt_addr); | ||
739 | else | ||
740 | rcu_read_unlock(); | ||
741 | |||
742 | return AE_OK; | ||
743 | } | ||
744 | |||
745 | #ifdef readq | 715 | #ifdef readq |
746 | static inline u64 read64(const volatile void __iomem *addr) | 716 | static inline u64 read64(const volatile void __iomem *addr) |
747 | { | 717 | { |
@@ -758,7 +728,7 @@ static inline u64 read64(const volatile void __iomem *addr) | |||
758 | #endif | 728 | #endif |
759 | 729 | ||
760 | acpi_status | 730 | acpi_status |
761 | acpi_os_read_memory64(acpi_physical_address phys_addr, u64 *value, u32 width) | 731 | acpi_os_read_memory(acpi_physical_address phys_addr, u64 *value, u32 width) |
762 | { | 732 | { |
763 | void __iomem *virt_addr; | 733 | void __iomem *virt_addr; |
764 | unsigned int size = width / 8; | 734 | unsigned int size = width / 8; |
@@ -803,45 +773,6 @@ acpi_os_read_memory64(acpi_physical_address phys_addr, u64 *value, u32 width) | |||
803 | return AE_OK; | 773 | return AE_OK; |
804 | } | 774 | } |
805 | 775 | ||
806 | acpi_status | ||
807 | acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width) | ||
808 | { | ||
809 | void __iomem *virt_addr; | ||
810 | unsigned int size = width / 8; | ||
811 | bool unmap = false; | ||
812 | |||
813 | rcu_read_lock(); | ||
814 | virt_addr = acpi_map_vaddr_lookup(phys_addr, size); | ||
815 | if (!virt_addr) { | ||
816 | rcu_read_unlock(); | ||
817 | virt_addr = acpi_os_ioremap(phys_addr, size); | ||
818 | if (!virt_addr) | ||
819 | return AE_BAD_ADDRESS; | ||
820 | unmap = true; | ||
821 | } | ||
822 | |||
823 | switch (width) { | ||
824 | case 8: | ||
825 | writeb(value, virt_addr); | ||
826 | break; | ||
827 | case 16: | ||
828 | writew(value, virt_addr); | ||
829 | break; | ||
830 | case 32: | ||
831 | writel(value, virt_addr); | ||
832 | break; | ||
833 | default: | ||
834 | BUG(); | ||
835 | } | ||
836 | |||
837 | if (unmap) | ||
838 | iounmap(virt_addr); | ||
839 | else | ||
840 | rcu_read_unlock(); | ||
841 | |||
842 | return AE_OK; | ||
843 | } | ||
844 | |||
845 | #ifdef writeq | 776 | #ifdef writeq |
846 | static inline void write64(u64 val, volatile void __iomem *addr) | 777 | static inline void write64(u64 val, volatile void __iomem *addr) |
847 | { | 778 | { |
@@ -856,7 +787,7 @@ static inline void write64(u64 val, volatile void __iomem *addr) | |||
856 | #endif | 787 | #endif |
857 | 788 | ||
858 | acpi_status | 789 | acpi_status |
859 | acpi_os_write_memory64(acpi_physical_address phys_addr, u64 value, u32 width) | 790 | acpi_os_write_memory(acpi_physical_address phys_addr, u64 value, u32 width) |
860 | { | 791 | { |
861 | void __iomem *virt_addr; | 792 | void __iomem *virt_addr; |
862 | unsigned int size = width / 8; | 793 | unsigned int size = width / 8; |
@@ -1641,3 +1572,24 @@ acpi_status acpi_os_terminate(void) | |||
1641 | 1572 | ||
1642 | return AE_OK; | 1573 | return AE_OK; |
1643 | } | 1574 | } |
1575 | |||
1576 | acpi_status acpi_os_prepare_sleep(u8 sleep_state, u32 pm1a_control, | ||
1577 | u32 pm1b_control) | ||
1578 | { | ||
1579 | int rc = 0; | ||
1580 | if (__acpi_os_prepare_sleep) | ||
1581 | rc = __acpi_os_prepare_sleep(sleep_state, | ||
1582 | pm1a_control, pm1b_control); | ||
1583 | if (rc < 0) | ||
1584 | return AE_ERROR; | ||
1585 | else if (rc > 0) | ||
1586 | return AE_CTRL_SKIP; | ||
1587 | |||
1588 | return AE_OK; | ||
1589 | } | ||
1590 | |||
1591 | void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state, | ||
1592 | u32 pm1a_ctrl, u32 pm1b_ctrl)) | ||
1593 | { | ||
1594 | __acpi_os_prepare_sleep = func; | ||
1595 | } | ||