ACPI: Use correct IRQ when uninstalling ACPI interrupt handler
[cascardo/linux.git] / drivers / acpi / osl.c
index 3b8963f..2a25919 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  *
  */
@@ -47,6 +43,7 @@
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
+#include <asm-generic/io-64-nonatomic-lo-hi.h>
 
 #include "internal.h"
 
@@ -83,6 +80,8 @@ static void *acpi_irq_context;
 static struct workqueue_struct *kacpid_wq;
 static struct workqueue_struct *kacpi_notify_wq;
 static struct workqueue_struct *kacpi_hotplug_wq;
+static bool acpi_os_initialized;
+unsigned int acpi_sci_irq = INVALID_ACPI_IRQ;
 
 /*
  * This list of permanent mappings is for memory that may be accessed from
@@ -858,17 +857,19 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler,
                acpi_irq_handler = NULL;
                return AE_NOT_ACQUIRED;
        }
+       acpi_sci_irq = irq;
 
        return AE_OK;
 }
 
-acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler)
+acpi_status acpi_os_remove_interrupt_handler(u32 gsi, acpi_osd_handler handler)
 {
-       if (irq != acpi_gbl_FADT.sci_interrupt)
+       if (gsi != acpi_gbl_FADT.sci_interrupt || !acpi_sci_irq_valid())
                return AE_BAD_PARAMETER;
 
-       free_irq(irq, acpi_irq);
+       free_irq(acpi_sci_irq, acpi_irq);
        acpi_irq_handler = NULL;
+       acpi_sci_irq = INVALID_ACPI_IRQ;
 
        return AE_OK;
 }
@@ -947,21 +948,6 @@ acpi_status acpi_os_write_port(acpi_io_address port, u32 value, u32 width)
 
 EXPORT_SYMBOL(acpi_os_write_port);
 
-#ifdef readq
-static inline u64 read64(const volatile void __iomem *addr)
-{
-       return readq(addr);
-}
-#else
-static inline u64 read64(const volatile void __iomem *addr)
-{
-       u64 l, h;
-       l = readl(addr);
-       h = readl(addr+4);
-       return l | (h << 32);
-}
-#endif
-
 acpi_status
 acpi_os_read_memory(acpi_physical_address phys_addr, u64 *value, u32 width)
 {
@@ -994,7 +980,7 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u64 *value, u32 width)
                *(u32 *) value = readl(virt_addr);
                break;
        case 64:
-               *(u64 *) value = read64(virt_addr);
+               *(u64 *) value = readq(virt_addr);
                break;
        default:
                BUG();
@@ -1008,19 +994,6 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u64 *value, u32 width)
        return AE_OK;
 }
 
-#ifdef writeq
-static inline void write64(u64 val, volatile void __iomem *addr)
-{
-       writeq(val, addr);
-}
-#else
-static inline void write64(u64 val, volatile void __iomem *addr)
-{
-       writel(val, addr);
-       writel(val>>32, addr+4);
-}
-#endif
-
 acpi_status
 acpi_os_write_memory(acpi_physical_address phys_addr, u64 value, u32 width)
 {
@@ -1049,7 +1022,7 @@ acpi_os_write_memory(acpi_physical_address phys_addr, u64 value, u32 width)
                writel(value, virt_addr);
                break;
        case 64:
-               write64(value, virt_addr);
+               writeq(value, virt_addr);
                break;
        default:
                BUG();
@@ -1316,6 +1289,9 @@ acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout)
        long jiffies;
        int ret = 0;
 
+       if (!acpi_os_initialized)
+               return AE_OK;
+
        if (!sem || (units < 1))
                return AE_BAD_PARAMETER;
 
@@ -1355,6 +1331,9 @@ acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units)
 {
        struct semaphore *sem = (struct semaphore *)handle;
 
+       if (!acpi_os_initialized)
+               return AE_OK;
+
        if (!sem || (units < 1))
                return AE_BAD_PARAMETER;
 
@@ -1863,6 +1842,7 @@ acpi_status __init acpi_os_initialize(void)
                rv = acpi_os_map_generic_address(&acpi_gbl_FADT.reset_register);
                pr_debug(PREFIX "%s: map reset_reg status %d\n", __func__, rv);
        }
+       acpi_os_initialized = true;
 
        return AE_OK;
 }