linux/drivers/platform/mips/acpi_init.c
<<
>>
Prefs
   1#include <linux/io.h>
   2#include <linux/init.h>
   3#include <linux/ioport.h>
   4#include <linux/export.h>
   5
   6#define SBX00_ACPI_IO_BASE 0x800
   7#define SBX00_ACPI_IO_SIZE 0x100
   8
   9#define ACPI_PM_EVT_BLK         (SBX00_ACPI_IO_BASE + 0x00) /* 4 bytes */
  10#define ACPI_PM_CNT_BLK         (SBX00_ACPI_IO_BASE + 0x04) /* 2 bytes */
  11#define ACPI_PMA_CNT_BLK        (SBX00_ACPI_IO_BASE + 0x0F) /* 1 byte */
  12#define ACPI_PM_TMR_BLK         (SBX00_ACPI_IO_BASE + 0x18) /* 4 bytes */
  13#define ACPI_GPE0_BLK           (SBX00_ACPI_IO_BASE + 0x10) /* 8 bytes */
  14#define ACPI_END                (SBX00_ACPI_IO_BASE + 0x80)
  15
  16#define PM_INDEX        0xCD6
  17#define PM_DATA         0xCD7
  18#define PM2_INDEX       0xCD0
  19#define PM2_DATA        0xCD1
  20
  21/*
  22 * SCI interrupt need acpi space, allocate here
  23 */
  24
  25static int __init register_acpi_resource(void)
  26{
  27        request_region(SBX00_ACPI_IO_BASE, SBX00_ACPI_IO_SIZE, "acpi");
  28        return 0;
  29}
  30
  31static void pmio_write_index(u16 index, u8 reg, u8 value)
  32{
  33        outb(reg, index);
  34        outb(value, index + 1);
  35}
  36
  37static u8 pmio_read_index(u16 index, u8 reg)
  38{
  39        outb(reg, index);
  40        return inb(index + 1);
  41}
  42
  43void pm_iowrite(u8 reg, u8 value)
  44{
  45        pmio_write_index(PM_INDEX, reg, value);
  46}
  47EXPORT_SYMBOL(pm_iowrite);
  48
  49u8 pm_ioread(u8 reg)
  50{
  51        return pmio_read_index(PM_INDEX, reg);
  52}
  53EXPORT_SYMBOL(pm_ioread);
  54
  55void pm2_iowrite(u8 reg, u8 value)
  56{
  57        pmio_write_index(PM2_INDEX, reg, value);
  58}
  59EXPORT_SYMBOL(pm2_iowrite);
  60
  61u8 pm2_ioread(u8 reg)
  62{
  63        return pmio_read_index(PM2_INDEX, reg);
  64}
  65EXPORT_SYMBOL(pm2_ioread);
  66
  67static void acpi_hw_clear_status(void)
  68{
  69        u16 value;
  70
  71        /* PMStatus: Clear WakeStatus/PwrBtnStatus */
  72        value = inw(ACPI_PM_EVT_BLK);
  73        value |= (1 << 8 | 1 << 15);
  74        outw(value, ACPI_PM_EVT_BLK);
  75
  76        /* GPEStatus: Clear all generated events */
  77        outl(inl(ACPI_GPE0_BLK), ACPI_GPE0_BLK);
  78}
  79
  80void acpi_registers_setup(void)
  81{
  82        u32 value;
  83
  84        /* PM Status Base */
  85        pm_iowrite(0x20, ACPI_PM_EVT_BLK & 0xff);
  86        pm_iowrite(0x21, ACPI_PM_EVT_BLK >> 8);
  87
  88        /* PM Control Base */
  89        pm_iowrite(0x22, ACPI_PM_CNT_BLK & 0xff);
  90        pm_iowrite(0x23, ACPI_PM_CNT_BLK >> 8);
  91
  92        /* GPM Base */
  93        pm_iowrite(0x28, ACPI_GPE0_BLK & 0xff);
  94        pm_iowrite(0x29, ACPI_GPE0_BLK >> 8);
  95
  96        /* ACPI End */
  97        pm_iowrite(0x2e, ACPI_END & 0xff);
  98        pm_iowrite(0x2f, ACPI_END >> 8);
  99
 100        /* IO Decode: When AcpiDecodeEnable set, South-Bridge uses the contents
 101         * of the PM registers at index 0x20~0x2B to decode ACPI I/O address. */
 102        pm_iowrite(0x0e, 1 << 3);
 103
 104        /* SCI_EN set */
 105        outw(1, ACPI_PM_CNT_BLK);
 106
 107        /* Enable to generate SCI */
 108        pm_iowrite(0x10, pm_ioread(0x10) | 1);
 109
 110        /* GPM3/GPM9 enable */
 111        value = inl(ACPI_GPE0_BLK + 4);
 112        outl(value | (1 << 14) | (1 << 22), ACPI_GPE0_BLK + 4);
 113
 114        /* Set GPM9 as input */
 115        pm_iowrite(0x8d, pm_ioread(0x8d) & (~(1 << 1)));
 116
 117        /* Set GPM9 as non-output */
 118        pm_iowrite(0x94, pm_ioread(0x94) | (1 << 3));
 119
 120        /* GPM3 config ACPI trigger SCIOUT */
 121        pm_iowrite(0x33, pm_ioread(0x33) & (~(3 << 4)));
 122
 123        /* GPM9 config ACPI trigger SCIOUT */
 124        pm_iowrite(0x3d, pm_ioread(0x3d) & (~(3 << 2)));
 125
 126        /* GPM3 config falling edge trigger */
 127        pm_iowrite(0x37, pm_ioread(0x37) & (~(1 << 6)));
 128
 129        /* No wait for STPGNT# in ACPI Sx state */
 130        pm_iowrite(0x7c, pm_ioread(0x7c) | (1 << 6));
 131
 132        /* Set GPM3 pull-down enable */
 133        value = pm2_ioread(0xf6);
 134        value |= ((1 << 7) | (1 << 3));
 135        pm2_iowrite(0xf6, value);
 136
 137        /* Set GPM9 pull-down enable */
 138        value = pm2_ioread(0xf8);
 139        value |= ((1 << 5) | (1 << 1));
 140        pm2_iowrite(0xf8, value);
 141}
 142
 143int __init sbx00_acpi_init(void)
 144{
 145        register_acpi_resource();
 146        acpi_registers_setup();
 147        acpi_hw_clear_status();
 148
 149        return 0;
 150}
 151