Example #1
0
void acpi_db_generate_gpe(char *gpe_arg, char *block_arg)
{
	u32 block_number = 0;
	u32 gpe_number;
	struct acpi_gpe_event_info *gpe_event_info;

	gpe_number = strtoul(gpe_arg, NULL, 0);

	/*
	 * If no block arg, or block arg == 0 or 1, use the FADT-defined
	 * GPE blocks.
	 */
	if (block_arg) {
		block_number = strtoul(block_arg, NULL, 0);
		if (block_number == 1) {
			block_number = 0;
		}
	}

	gpe_event_info =
	    acpi_ev_get_gpe_event_info(ACPI_TO_POINTER(block_number),
				       gpe_number);
	if (!gpe_event_info) {
		acpi_os_printf("Invalid GPE\n");
		return;
	}

	(void)acpi_ev_gpe_dispatch(NULL, gpe_event_info, gpe_number);
}
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);
}
Example #3
0
u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list)
{
	acpi_status status;
	struct acpi_gpe_block_info *gpe_block;
	struct acpi_namespace_node *gpe_device;
	struct acpi_gpe_register_info *gpe_register_info;
	struct acpi_gpe_event_info *gpe_event_info;
	u32 gpe_number;
	struct acpi_gpe_handler_info *gpe_handler_info;
	u32 int_status = ACPI_INTERRUPT_NOT_HANDLED;
	u8 enabled_status_byte;
	u32 status_reg;
	u32 enable_reg;
	acpi_cpu_flags flags;
	u32 i;
	u32 j;

	ACPI_FUNCTION_NAME(ev_gpe_detect);

	/* Check for the case where there are no GPEs */

	if (!gpe_xrupt_list) {
		return (int_status);
	}

	/*
	 * We need to obtain the GPE lock for both the data structs and registers
	 * Note: Not necessary to obtain the hardware lock, since the GPE
	 * registers are owned by the gpe_lock.
	 */
	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);

	/* Examine all GPE blocks attached to this interrupt level */

	gpe_block = gpe_xrupt_list->gpe_block_list_head;
	while (gpe_block) {
		gpe_device = gpe_block->node;

		/*
		 * Read all of the 8-bit GPE status and enable registers in this GPE
		 * block, saving all of them. Find all currently active GP events.
		 */
		for (i = 0; i < gpe_block->register_count; i++) {

			/* Get the next status/enable pair */

			gpe_register_info = &gpe_block->register_info[i];

			/*
			 * Optimization: If there are no GPEs enabled within this
			 * register, we can safely ignore the entire register.
			 */
			if (!(gpe_register_info->enable_for_run |
			      gpe_register_info->enable_for_wake)) {
				ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
						  "Ignore disabled registers for GPE %02X-%02X: "
						  "RunEnable=%02X, WakeEnable=%02X\n",
						  gpe_register_info->
						  base_gpe_number,
						  gpe_register_info->
						  base_gpe_number +
						  (ACPI_GPE_REGISTER_WIDTH - 1),
						  gpe_register_info->
						  enable_for_run,
						  gpe_register_info->
						  enable_for_wake));
				continue;
			}

			/* Read the Status Register */

			status =
			    acpi_hw_read(&status_reg,
					 &gpe_register_info->status_address);
			if (ACPI_FAILURE(status)) {
				goto unlock_and_exit;
			}

			/* Read the Enable Register */

			status =
			    acpi_hw_read(&enable_reg,
					 &gpe_register_info->enable_address);
			if (ACPI_FAILURE(status)) {
				goto unlock_and_exit;
			}

			ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
					  "Read registers for GPE %02X-%02X: Status=%02X, Enable=%02X, "
					  "RunEnable=%02X, WakeEnable=%02X\n",
					  gpe_register_info->base_gpe_number,
					  gpe_register_info->base_gpe_number +
					  (ACPI_GPE_REGISTER_WIDTH - 1),
					  status_reg, enable_reg,
					  gpe_register_info->enable_for_run,
					  gpe_register_info->enable_for_wake));

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

			enabled_status_byte = (u8)(status_reg & enable_reg);
			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; j < ACPI_GPE_REGISTER_WIDTH; j++) {

				/* Examine one GPE bit */

				gpe_event_info =
				    &gpe_block->
				    event_info[((acpi_size) i *
						ACPI_GPE_REGISTER_WIDTH) + j];
				gpe_number =
				    j + gpe_register_info->base_gpe_number;

				if (enabled_status_byte & (1 << j)) {

					/* Invoke global event handler if present */

					acpi_gpe_count++;
					if (acpi_gbl_global_event_handler) {
						acpi_gbl_global_event_handler
						    (ACPI_EVENT_TYPE_GPE,
						     gpe_device, gpe_number,
						     acpi_gbl_global_event_handler_context);
					}

					/* Found an active GPE */

					if (ACPI_GPE_DISPATCH_TYPE
					    (gpe_event_info->flags) ==
					    ACPI_GPE_DISPATCH_RAW_HANDLER) {

						/* Dispatch the event to a raw handler */

						gpe_handler_info =
						    gpe_event_info->dispatch.
						    handler;

						/*
						 * There is no protection around the namespace node
						 * and the GPE handler to ensure a safe destruction
						 * because:
						 * 1. The namespace node is expected to always
						 *    exist after loading a table.
						 * 2. The GPE handler is expected to be flushed by
						 *    acpi_os_wait_events_complete() before the
						 *    destruction.
						 */
						acpi_os_release_lock
						    (acpi_gbl_gpe_lock, flags);
						int_status |=
						    gpe_handler_info->
						    address(gpe_device,
							    gpe_number,
							    gpe_handler_info->
							    context);
						flags =
						    acpi_os_acquire_lock
						    (acpi_gbl_gpe_lock);
					} else {
						/*
						 * Dispatch the event to a standard handler or
						 * method.
						 */
						int_status |=
						    acpi_ev_gpe_dispatch
						    (gpe_device, gpe_event_info,
						     gpe_number);
					}
				}
			}
		}

		gpe_block = gpe_block->next;
	}

unlock_and_exit:

	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
	return (int_status);
}
Example #4
0
u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
{
    acpi_status status;
    struct acpi_gpe_block_info *gpe_block;
    struct acpi_gpe_register_info *gpe_register_info;
    u32 int_status = ACPI_INTERRUPT_NOT_HANDLED;
    u8 enabled_status_byte;
    u32 status_reg;
    u32 enable_reg;
    acpi_cpu_flags flags;
    u32 i;
    u32 j;

    ACPI_FUNCTION_NAME(ev_gpe_detect);

    /* Check for the case where there are no GPEs */

    if (!gpe_xrupt_list) {
        return (int_status);
    }

    /*
     * We need to obtain the GPE lock for both the data structs and registers
     * Note: Not necessary to obtain the hardware lock, since the GPE
     * registers are owned by the gpe_lock.
     */
    flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);

    /* Examine all GPE blocks attached to this interrupt level */

    gpe_block = gpe_xrupt_list->gpe_block_list_head;
    while (gpe_block) {
        /*
         * Read all of the 8-bit GPE status and enable registers in this GPE
         * block, saving all of them. Find all currently active GP events.
         */
        for (i = 0; i < gpe_block->register_count; i++) {

            /* Get the next status/enable pair */

            gpe_register_info = &gpe_block->register_info[i];

            /* Read the Status Register */

            status =
                acpi_hw_read(&status_reg,
                             &gpe_register_info->status_address);
            if (ACPI_FAILURE(status)) {
                goto unlock_and_exit;
            }

            /* Read the Enable Register */

            status =
                acpi_hw_read(&enable_reg,
                             &gpe_register_info->enable_address);
            if (ACPI_FAILURE(status)) {
                goto unlock_and_exit;
            }

            ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
                              "Read GPE Register at GPE%X: Status=%02X, Enable=%02X\n",
                              gpe_register_info->base_gpe_number,
                              status_reg, enable_reg));

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

            enabled_status_byte = (u8) (status_reg & enable_reg);
            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; j < ACPI_GPE_REGISTER_WIDTH; j++) {

                /* Examine one GPE bit */

                if (enabled_status_byte & (1 << j)) {
                    /*
                     * Found an active GPE. Dispatch the event to a handler
                     * or method.
                     */
                    int_status |=
                        acpi_ev_gpe_dispatch(&gpe_block->
                                             event_info[((acpi_size) i * ACPI_GPE_REGISTER_WIDTH) + j], j + gpe_register_info->base_gpe_number);
                }
            }
        }

        gpe_block = gpe_block->next;
    }

unlock_and_exit:

    acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
    return (int_status);
}
Example #5
0
u32
acpi_ev_gpe_detect (
	struct acpi_gpe_xrupt_info      *gpe_xrupt_list)
{
	u32                             int_status = ACPI_INTERRUPT_NOT_HANDLED;
	u8                              enabled_status_byte;
	struct acpi_gpe_register_info   *gpe_register_info;
	u32                             status_reg;
	u32                             enable_reg;
	acpi_status                     status;
	struct acpi_gpe_block_info      *gpe_block;
	acpi_native_uint                i;
	acpi_native_uint                j;


	ACPI_FUNCTION_NAME ("ev_gpe_detect");

	/* Check for the case where there are no GPEs */

	if (!gpe_xrupt_list) {
		return (int_status);
	}

	/* Examine all GPE blocks attached to this interrupt level */

	acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_ISR);
	gpe_block = gpe_xrupt_list->gpe_block_list_head;
	while (gpe_block) {
		/*
		 * Read all of the 8-bit GPE status and enable registers
		 * in this GPE block, saving all of them.
		 * Find all currently active GP events.
		 */
		for (i = 0; i < gpe_block->register_count; i++) {
			/* Get the next status/enable pair */

			gpe_register_info = &gpe_block->register_info[i];

			/* Read the Status Register */

			status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &status_reg,
					 &gpe_register_info->status_address);
			if (ACPI_FAILURE (status)) {
				goto unlock_and_exit;
			}

			/* Read the Enable Register */

			status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &enable_reg,
					 &gpe_register_info->enable_address);
			if (ACPI_FAILURE (status)) {
				goto unlock_and_exit;
			}

			ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
				"GPE pair: Status %8.8X%8.8X = %02X, Enable %8.8X%8.8X = %02X\n",
				ACPI_FORMAT_UINT64 (
					gpe_register_info->status_address.address),
					status_reg,
				ACPI_FORMAT_UINT64 (
					gpe_register_info->enable_address.address),
					enable_reg));

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

			enabled_status_byte = (u8) (status_reg & enable_reg);
			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; j < ACPI_GPE_REGISTER_WIDTH; j++) {
				/* Examine one GPE bit */

				if (enabled_status_byte & acpi_gbl_decode_to8bit[j]) {
					/*
					 * Found an active GPE. Dispatch the event to a handler
					 * or method.
					 */
					int_status |= acpi_ev_gpe_dispatch (
							  &gpe_block->event_info[(i * ACPI_GPE_REGISTER_WIDTH) + j],
							  (u32) j + gpe_register_info->base_gpe_number);
				}
			}
		}

		gpe_block = gpe_block->next;
	}

unlock_and_exit:

	acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_ISR);
	return (int_status);
}
Example #6
0
u32
acpi_ev_gpe_detect (
	struct acpi_gpe_xrupt_info      *gpe_xrupt_list)
{
	u32                             int_status = ACPI_INTERRUPT_NOT_HANDLED;
	u8                              enabled_status_byte;
	u8                              bit_mask;
	struct acpi_gpe_register_info   *gpe_register_info;
	u32                             in_value;
	acpi_status                     status;
	struct acpi_gpe_block_info      *gpe_block;
	u32                             gpe_number;
	u32                             i;
	u32                             j;


	ACPI_FUNCTION_NAME ("ev_gpe_detect");


	/* Examine all GPE blocks attached to this interrupt level */

	acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_ISR);
	gpe_block = gpe_xrupt_list->gpe_block_list_head;
	while (gpe_block) {
		/*
		 * Read all of the 8-bit GPE status and enable registers
		 * in this GPE block, saving all of them.
		 * Find all currently active GP events.
		 */
		for (i = 0; i < gpe_block->register_count; i++) {
			/* Get the next status/enable pair */

			gpe_register_info = &gpe_block->register_info[i];

			/* Read the Status Register */

			status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &in_value,
					 &gpe_register_info->status_address);
			gpe_register_info->status = (u8) in_value;
			if (ACPI_FAILURE (status)) {
				goto unlock_and_exit;
			}

			/* Read the Enable Register */

			status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &in_value,
					 &gpe_register_info->enable_address);
			gpe_register_info->enable = (u8) in_value;
			if (ACPI_FAILURE (status)) {
				goto unlock_and_exit;
			}

			ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
				"GPE pair: Status %8.8X%8.8X = %02X, Enable %8.8X%8.8X = %02X\n",
				ACPI_HIDWORD (gpe_register_info->status_address.address),
				ACPI_LODWORD (gpe_register_info->status_address.address),
				gpe_register_info->status,
				ACPI_HIDWORD (gpe_register_info->enable_address.address),
				ACPI_LODWORD (gpe_register_info->enable_address.address),
				gpe_register_info->enable));

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

			enabled_status_byte = (u8) (gpe_register_info->status &
					   gpe_register_info->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 < ACPI_GPE_REGISTER_WIDTH; 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.
					 */
					gpe_number = (i * ACPI_GPE_REGISTER_WIDTH) + j;

					int_status |= acpi_ev_gpe_dispatch (
							  &gpe_block->event_info[gpe_number],
							  gpe_number + gpe_block->register_info[gpe_number].base_gpe_number);
				}
			}
		}

		gpe_block = gpe_block->next;
	}

unlock_and_exit:

	acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_ISR);
	return (int_status);
}
Example #7
0
u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
{
	acpi_status status;
	struct acpi_gpe_block_info *gpe_block;
	struct acpi_gpe_register_info *gpe_register_info;
	u32 int_status = ACPI_INTERRUPT_NOT_HANDLED;
	u8 enabled_status_byte;
	u32 status_reg;
	u32 enable_reg;
	acpi_cpu_flags flags;
	u32 i;
	u32 j;

	ACPI_FUNCTION_NAME(ev_gpe_detect);

	

	if (!gpe_xrupt_list) {
		return (int_status);
	}

	
	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);

	

	gpe_block = gpe_xrupt_list->gpe_block_list_head;
	while (gpe_block) {
		
		for (i = 0; i < gpe_block->register_count; i++) {

			

			gpe_register_info = &gpe_block->register_info[i];

			

			status =
			    acpi_hw_read(&status_reg,
					 &gpe_register_info->status_address);
			if (ACPI_FAILURE(status)) {
				goto unlock_and_exit;
			}

			

			status =
			    acpi_hw_read(&enable_reg,
					 &gpe_register_info->enable_address);
			if (ACPI_FAILURE(status)) {
				goto unlock_and_exit;
			}

			ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
					  "Read GPE Register at GPE%X: Status=%02X, Enable=%02X\n",
					  gpe_register_info->base_gpe_number,
					  status_reg, enable_reg));

			

			enabled_status_byte = (u8) (status_reg & enable_reg);
			if (!enabled_status_byte) {

				

				continue;
			}

			

			for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {

				

				if (enabled_status_byte & (1 << j)) {
					
					int_status |=
					    acpi_ev_gpe_dispatch(&gpe_block->
						event_info[((acpi_size) i * ACPI_GPE_REGISTER_WIDTH) + j], j + gpe_register_info->base_gpe_number);
				}
			}
		}

		gpe_block = gpe_block->next;
	}

      unlock_and_exit:

	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
	return (int_status);
}