示例#1
0
u32
acpi_ev_gpe_detect (void)
{
	u32                     int_status = INTERRUPT_NOT_HANDLED;
	u32                     i;
	u32                     j;
	u8                      enabled_status_byte;
	u8                      bit_mask;


	PROC_NAME ("Ev_gpe_detect");


	/*
	 * Read all of the 8-bit GPE status and enable registers
	 * in both of the register blocks, saving all of it.
	 * Find all currently active GP events.
	 */
	for (i = 0; i < acpi_gbl_gpe_register_count; i++) {
		acpi_os_read_port (acpi_gbl_gpe_registers[i].status_addr,
				&acpi_gbl_gpe_registers[i].status, 8);

		acpi_os_read_port (acpi_gbl_gpe_registers[i].enable_addr,
				&acpi_gbl_gpe_registers[i].enable, 8);

		ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
			"GPE block at %X - Enable %08X Status %08X\n",
			acpi_gbl_gpe_registers[i].enable_addr,
			acpi_gbl_gpe_registers[i].status,
			acpi_gbl_gpe_registers[i].enable));

		/* First check if there is anything active at all in this register */

		enabled_status_byte = (u8) (acpi_gbl_gpe_registers[i].status &
				   acpi_gbl_gpe_registers[i].enable);

		if (!enabled_status_byte) {
			/* No active GPEs in this register, move on */

			continue;
		}

		/* Now look at the individual GPEs in this byte register */

		for (j = 0, bit_mask = 1; j < 8; j++, bit_mask <<= 1) {
			/* Examine one GPE bit */

			if (enabled_status_byte & bit_mask) {
				/*
				 * Found an active GPE.  Dispatch the event to a handler
				 * or method.
				 */
				int_status |= acpi_ev_gpe_dispatch (
						  acpi_gbl_gpe_registers[i].gpe_base + j);
			}
		}
	}

	return (int_status);
}
示例#2
0
void
acpi_hw_get_gpe_status (
	u32                     gpe_number,
	acpi_event_status       *event_status)
{
	u32                     in_byte = 0;
	u32                     register_index = 0;
	u32                     bit_mask = 0;


	FUNCTION_ENTRY ();


	if (!event_status) {
		return;
	}

	(*event_status) = 0;

	/*
	 * Translate GPE number to index into global registers array.
	 */
	register_index = acpi_gbl_gpe_valid[gpe_number];

	/*
	 * Figure out the bit offset for this GPE within the target register.
	 */
	bit_mask = acpi_gbl_decode_to8bit [MOD_8 (gpe_number)];

	/*
	 * Enabled?:
	 */
	in_byte = 0;
	acpi_os_read_port (acpi_gbl_gpe_registers[register_index].enable_addr, &in_byte, 8);
	if (bit_mask & in_byte) {
		(*event_status) |= ACPI_EVENT_FLAG_ENABLED;
	}

	/*
	 * Enabled for wake?:
	 */
	if (bit_mask & acpi_gbl_gpe_registers[register_index].wake_enable) {
		(*event_status) |= ACPI_EVENT_FLAG_WAKE_ENABLED;
	}

	/*
	 * Set?
	 */
	in_byte = 0;
	acpi_os_read_port (acpi_gbl_gpe_registers[register_index].status_addr, &in_byte, 8);
	if (bit_mask & in_byte) {
		(*event_status) |= ACPI_EVENT_FLAG_SET;
	}
}
示例#3
0
static u32 cpu_freq_read_io(struct acpi_pct_register *reg)
{
	u32 val;

	acpi_os_read_port(reg->address, &val, reg->bit_width);
	return val;
}
示例#4
0
void
acpi_hw_enable_gpe (
	u32                     gpe_number)
{
	u32                     in_byte;
	u32                     register_index;
	u32                     bit_mask;


	FUNCTION_ENTRY ();


	/*
	 * Translate GPE number to index into global registers array.
	 */
	register_index = acpi_gbl_gpe_valid[gpe_number];

	/*
	 * Figure out the bit offset for this GPE within the target register.
	 */
	bit_mask = acpi_gbl_decode_to8bit [MOD_8 (gpe_number)];

	/*
	 * Read the current value of the register, set the appropriate bit
	 * to enable the GPE, and write out the new register.
	 */
	in_byte = 0;
	acpi_os_read_port (acpi_gbl_gpe_registers[register_index].enable_addr, &in_byte, 8);
	acpi_os_write_port (acpi_gbl_gpe_registers[register_index].enable_addr,
			   (in_byte | bit_mask), 8);
}
示例#5
0
acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width)
{
    acpi_status status;
    u32 one_byte;
    u32 i;

    /* Truncate address to 16 bits if requested */

    if (acpi_gbl_truncate_io_addresses) {
        address &= ACPI_UINT16_MAX;
    }

    /* Validate the entire request and perform the I/O */

    status = acpi_hw_validate_io_request(address, width);
    if (ACPI_SUCCESS(status)) {
        status = acpi_os_read_port(address, value, width);
        return (status);
    }

    if (status != AE_AML_ILLEGAL_ADDRESS) {
        return (status);
    }

    /*
     * There has been a protection violation within the request. Fall
     * back to byte granularity port I/O and ignore the failing bytes.
     * This provides Windows compatibility.
     */
    for (i = 0, *value = 0; i < width; i += 8) {

        /* Validate and read one byte */

        if (acpi_hw_validate_io_request(address, 8) == AE_OK) {
            status = acpi_os_read_port(address, &one_byte, 8);
            if (ACPI_FAILURE(status)) {
                return (status);
            }

            *value |= (one_byte << i);
        }

        address++;
    }

    return (AE_OK);
}
示例#6
0
static void do_drv_read(struct drv_cmd *cmd)
{
    u32 h;

    switch (cmd->type) {
    case SYSTEM_INTEL_MSR_CAPABLE:
        rdmsr(cmd->addr.msr.reg, cmd->val, h);
        break;
    case SYSTEM_IO_CAPABLE:
        acpi_os_read_port((acpi_io_address)cmd->addr.io.port,
            &cmd->val, (u32)cmd->addr.io.bit_width);
        break;
    default:
        break;
    }
}
示例#7
0
acpi_status
acpi_ex_system_io_space_handler (
	u32                             function,
	acpi_physical_address           address,
	u32                             bit_width,
	acpi_integer                    *value,
	void                            *handler_context,
	void                            *region_context)
{
	acpi_status                     status = AE_OK;
	u32                             value32;


	ACPI_FUNCTION_TRACE ("ex_system_io_space_handler");


	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
			"system_iO %d (%d width) Address=%8.8X%8.8X\n", function, bit_width,
			ACPI_FORMAT_UINT64 (address)));

	/* Decode the function parameter */

	switch (function) {
	case ACPI_READ:

		status = acpi_os_read_port ((acpi_io_address) address,
				 &value32, bit_width);
		*value = value32;
		break;

	case ACPI_WRITE:

		status = acpi_os_write_port ((acpi_io_address) address,
				 (u32) *value, bit_width);
		break;

	default:
		status = AE_BAD_PARAMETER;
		break;
	}

	return_ACPI_STATUS (status);
}
acpi_status
acpi_ex_system_io_space_handler (
	u32                     function,
	ACPI_PHYSICAL_ADDRESS   address,
	u32                     bit_width,
	u32                     *value,
	void                    *handler_context,
	void                    *region_context)
{
	acpi_status             status = AE_OK;


	FUNCTION_TRACE ("Ex_system_io_space_handler");


	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
		"System_iO %d (%d width) Address=%8.8X%8.8X\n", function, bit_width,
		HIDWORD (address), LODWORD (address)));

	/* Decode the function parameter */

	switch (function) {

	case ACPI_READ_ADR_SPACE:

		*value = 0;
		status = acpi_os_read_port ((ACPI_IO_ADDRESS) address, value, bit_width);
		break;


	case ACPI_WRITE_ADR_SPACE:

		status = acpi_os_write_port ((ACPI_IO_ADDRESS) address, *value, bit_width);
		break;


	default:
		status = AE_BAD_PARAMETER;
		break;
	}

	return_ACPI_STATUS (status);
}
示例#9
0
void
acpi_hw_disable_non_wakeup_gpes (
	void)
{
	u32                     i;

	FUNCTION_ENTRY ();

	for (i = 0; i < acpi_gbl_gpe_register_count; i++) {
		/*
		 * Read the enabled status of all GPEs. We
		 * will be using it to restore all the GPEs later.
		 */
		acpi_os_read_port (acpi_gbl_gpe_registers[i].enable_addr,
				&acpi_gbl_gpe_registers[i].enable, 8);

		/*
		 * Disable all GPEs but wakeup GPEs.
		 */
		acpi_os_write_port(acpi_gbl_gpe_registers[i].enable_addr,
				acpi_gbl_gpe_registers[i].wake_enable, 8);
	}
}
示例#10
0
void
ec_gpe_handler (
	void                    *context)
{
	acpi_status             status = AE_OK;
	EC_CONTEXT              *ec = (EC_CONTEXT*)context;
	EC_STATUS               ec_status = 0;

	FUNCTION_TRACE("ec_gpe_handler");

	if (!ec) {
		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid (NULL) context.\n"));
		return_VOID;
	}

	/* TBD: synchronize w/ transaction (ectransx). */

	/*
	 * EC_SCI?
	 * -------
	 * Check the EC_SCI bit to see if this is an EC_SCI event.  If not (e.g.
	 * OBF/IBE) just return, as we already poll to detect these events.
	 */
	acpi_os_read_port(ec->status_port, &ec_status, 8);
	if (!(ec_status & EC_FLAG_SCI)) {
		return_VOID;
	}

	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "EC_SCI event detected on ec [%02x] - running query.\n", ec->device_handle));

	/*
	 * Run Query:
	 * ----------
	 * Query the EC to find out which _Qxx method we need to evaluate.
	 * Note that successful completion of the query causes the EC_SCI
	 * bit to be cleared (and thus clearing the interrupt source).
	 */
	status = ec_io_write(ec, ec->command_port, EC_COMMAND_QUERY,
		EC_EVENT_OUTPUT_BUFFER_FULL);
	if (ACPI_FAILURE(status)) {
		ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Unable to send 'query command' to EC.\n"));
		return_VOID;
	}

	status = ec_io_read(ec, ec->data_port, &(ec->query_data),
		EC_EVENT_NONE);
	if (ACPI_FAILURE(status)) {
		ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Error reading query data.\n"));
		return_VOID;
	}

	/* TBD: un-synchronize w/ transaction (ectransx). */

	/*
	 * Spurious EC_SCI?
	 * ----------------
	 */
	if (!ec->query_data) {
		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Spurious EC SCI detected.\n"));
		return_VOID;
	}

	/*
	 * Defer _Qxx Execution:
	 * ---------------------
	 * Can't evaluate this method now 'cause we're at interrupt-level.
	 */
	status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE,
		ec_query_handler, ec);
	if (ACPI_FAILURE(status)) {
		ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Unable to defer _Qxx method evaluation.\n"));
		return_VOID;
	}

	return_VOID;
}