Example #1
0
acpi_status
pr_add_device(
	BM_HANDLE		device_handle,
	void			**context)
{
	acpi_status		status = AE_OK;
	PR_CONTEXT		*processor = NULL;
	BM_DEVICE		*device = NULL;
	acpi_buffer		buffer;
	acpi_object		acpi_object;
	static u32		processor_count = 0;


	FUNCTION_TRACE("pr_add_device");

	if (!context || *context) {
		return_ACPI_STATUS(AE_BAD_PARAMETER);
	}

	status = bm_get_device_info(device_handle, &device);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	processor = acpi_os_callocate(sizeof(PR_CONTEXT));
	if (!processor) {
		return AE_NO_MEMORY;
	}

	processor->device_handle = device->handle;
	processor->acpi_handle = device->acpi_handle;

	/*
	 * Processor Block:
	 * ----------------
	 */
	memset(&acpi_object, 0, sizeof(acpi_object));

	buffer.length = sizeof(acpi_object);
	buffer.pointer = &acpi_object;

	status = acpi_evaluate_object(processor->acpi_handle, NULL, NULL, &buffer);
	if (ACPI_FAILURE(status)) {
		goto end;
	}

	/*
	 * Processor ID:
	 * -------------
	 * TBD:  We need to synchronize the processor ID values in ACPI
	 *       with those of the APIC.  For example, an IBM T20 has a
	 *       proc_id value of '1', where the Linux value for the
	 *       first CPU on this system is '0'.  Since x86 CPUs are
	 *       mapped 1:1 we can simply use a zero-based counter.  Note
	 *       that this assumes that processor objects are enumerated
	 *       in the proper order.
	 */
	/* processor->uid = acpi_object.processor.proc_id; */
	processor->uid = processor_count++;

	processor->pblk.length = acpi_object.processor.pblk_length;
	processor->pblk.address = acpi_object.processor.pblk_address;

	status = pr_power_add_device(processor);
	if (ACPI_FAILURE(status)) {
		goto end;
	}

	status = pr_perf_add_device(processor);
	if (ACPI_FAILURE(status)) {
		goto end;
	}

	status = pr_osl_add_device(processor);
	if (ACPI_FAILURE(status)) {
		goto end;
	}

	*context = processor;

	pr_print(processor);

end:
	if (ACPI_FAILURE(status)) {
		acpi_os_free(processor);
	}

	return_ACPI_STATUS(status);
}
Example #2
0
acpi_status
ec_add_device(
	BM_HANDLE               device_handle,
	void                    **context)
{
	acpi_status             status = AE_OK;
	BM_DEVICE		*device = NULL;
	EC_CONTEXT              *ec = NULL;
	u8                      gpe_handler = FALSE;
	u8                      space_handler = FALSE;

	FUNCTION_TRACE("ec_add_device");

	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Adding EC device [%02x].\n", device_handle));

	if (!context || *context) {
		return_ACPI_STATUS(AE_BAD_PARAMETER);
	}

	/*
	 * Get information on this device.
	 */
	status = bm_get_device_info(device_handle, &device);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	/*
	 * Allocate a new EC_CONTEXT structure.
	 */
	ec = acpi_os_callocate(sizeof(EC_CONTEXT));
	if (!ec) {
		return_ACPI_STATUS(AE_NO_MEMORY);
	}

	ec->device_handle = device->handle;
	ec->acpi_handle = device->acpi_handle;

	/*
	 * Get the I/O port addresses for the command/status and data ports.
	 */
	status = ec_get_port_values(ec);
	if (ACPI_FAILURE(status)) {
		goto end;
	}

	/*
	 * See if we need to obtain the global lock for EC transactions.
	 */
	status = bm_evaluate_simple_integer(ec->acpi_handle, "_GLK",
		&ec->use_global_lock);
	if (status == AE_NOT_FOUND) {
		ec->use_global_lock = 0;
	}
	else if (ACPI_FAILURE(status)) {
		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "EC _GLK failed\n"));
		goto end;
	}

	/*
	 * Install a handler for servicing this EC's GPE.
	 */
	status = ec_install_gpe_handler(ec);
	if (ACPI_FAILURE(status)) {
		goto end;
	}
	else {
		gpe_handler = TRUE;
	}

	/*
	 * Install a handler for servicing this EC's address space.
	 */
	status = ec_install_space_handler(ec);
	if (ACPI_FAILURE(status)) {
		goto end;
	}
	else {
		space_handler = TRUE;
	}

	/*
	 * Create a semaphore to serialize EC transactions.
	 */
	status = acpi_os_create_semaphore(1,1, &(ec->mutex));
	if (ACPI_FAILURE(status)) {
		goto end;
	}

	/*
	 * Context now contains information specific to this EC.  Note
	 * that we'll get this pointer back on every ec_request() and
	 * ec_notify().
	 */
	*context = ec;

	ec_print(ec);

end:
	if (ACPI_FAILURE(status)) {

		if (gpe_handler) {
			ec_remove_gpe_handler(ec);
		}

		if (space_handler) {
			ec_remove_space_handler(ec);
		}

		if (ec->mutex) {
			acpi_os_delete_semaphore(ec->mutex);
		}

		acpi_os_free(ec);
	}

	return_ACPI_STATUS(status);
}
Example #3
0
acpi_status
tz_add_device (
	BM_HANDLE               device_handle,
	void                    **context)
{
	acpi_status             status = AE_OK;
	TZ_CONTEXT              *tz = NULL;
	BM_DEVICE		*device = NULL;
	acpi_handle             tmp_handle = NULL;
	static u32		zone_count = 0;

	FUNCTION_TRACE("tz_add_device");

	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Adding thermal zone [%02x].\n", device_handle));

	if (!context || *context) {
		ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Invalid context for device [%02x].\n", device_handle));
		return_ACPI_STATUS(AE_BAD_PARAMETER);
	}

	/*
	 * Get information on this device.
	 */
	status = bm_get_device_info(device_handle, &device);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	/*
	 * Allocate a new Thermal Zone device.
	 */
	tz = acpi_os_callocate(sizeof(TZ_CONTEXT));
	if (!tz) {
		return_ACPI_STATUS(AE_NO_MEMORY);
	}

	tz->device_handle = device->handle;
	tz->acpi_handle = device->acpi_handle;

	/* TBD: How to manage 'uid' when zones are Pn_p? */
	sprintf(tz->uid, "%d", zone_count++);

	/*
	 * Temperature:
	 * ------------
	 * Make sure we can read the zone's current temperature (_TMP).
	 * If we can't, there's no use in doing any policy (abort).
	 */
	status = tz_get_temperature(tz);
	if (ACPI_FAILURE(status))
		goto end;

	/*
	 * Polling Frequency:
	 * ------------------
	 * If _TZP doesn't exist use the OS default polling frequency.
	 */
	status = bm_evaluate_simple_integer(tz->acpi_handle, "_TZP", &(tz->policy.polling_freq));
	if (ACPI_FAILURE(status)) {
		tz->policy.polling_freq = TZP;
	}
	status = AE_OK;

	/*
	 * Cooling Preference:
	 * -------------------
	 * Default to ACTIVE (noisy) cooling until policy decides otherwise.
	 * Note that _SCP is optional.
	 */
	tz_set_cooling_preference(tz, TZ_COOLING_MODE_ACTIVE);

	/*
	 * Start Policy:
	 * -------------
	 * Thermal policy is included in the kernel (this driver) because
	 * of the critical role it plays in avoiding nuclear meltdown. =O
	 */
	status = tz_policy_add_device(tz);
	if (ACPI_FAILURE(status))
		goto end;

	status = tz_osl_add_device(tz);
	if (ACPI_FAILURE(status))
		goto end;

	*context = tz;

	tz_print(tz);

end:
	if (ACPI_FAILURE(status))
		acpi_os_free(tz);

	return_ACPI_STATUS(status);
}
Example #4
0
acpi_status
bn_add_device(
	BM_HANDLE		device_handle,
	void			**context)
{
	acpi_status		status = AE_OK;
	BM_DEVICE		*device = NULL;
	BN_CONTEXT		*button = NULL;

	FUNCTION_TRACE("bn_add_device");

	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Adding button device [%02x].\n", device_handle));

	if (!context || *context) {
		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid context.\n"));
		return_ACPI_STATUS(AE_BAD_PARAMETER);
	}

	/*
	 * Get information on this device.
	 */
	status = bm_get_device_info( device_handle, &device );
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	/*
	 * Allocate a new BN_CONTEXT structure.
	 */
	button = acpi_os_callocate(sizeof(BN_CONTEXT));
	if (!button) {
		return_ACPI_STATUS(AE_NO_MEMORY);
	}

	button->device_handle = device->handle;
	button->acpi_handle = device->acpi_handle;

	/*
	 * Power Button?
	 * -------------
	 * Either fixed-feature or generic (namespace) types.
	 */
	if (strncmp(device->id.hid, BN_HID_POWER_BUTTON,
		sizeof(BM_DEVICE_HID)) == 0) {

		if (device->id.type == BM_TYPE_FIXED_BUTTON) {

			button->type = BN_TYPE_POWER_BUTTON_FIXED;

			/* Register for fixed-feature events. */
			status = acpi_install_fixed_event_handler(
				ACPI_EVENT_POWER_BUTTON, bn_notify_fixed,
				(void*)button);
		}
		else {
			button->type = BN_TYPE_POWER_BUTTON;
		}

	}

	/*
	 * Sleep Button?
	 * -------------
	 * Either fixed-feature or generic (namespace) types.
	 */
	else if (strncmp( device->id.hid, BN_HID_SLEEP_BUTTON,
		sizeof(BM_DEVICE_HID)) == 0) {

		if (device->id.type == BM_TYPE_FIXED_BUTTON) {

			button->type = BN_TYPE_SLEEP_BUTTON_FIXED;

			/* Register for fixed-feature events. */
			status = acpi_install_fixed_event_handler(
				ACPI_EVENT_SLEEP_BUTTON, bn_notify_fixed,
				(void*)button);
		}
		else {
			button->type = BN_TYPE_SLEEP_BUTTON;
		}
	}

	/*
	 * LID Switch?
	 * -----------
	 */
	else if (strncmp( device->id.hid, BN_HID_LID_SWITCH,
		sizeof(BM_DEVICE_HID)) == 0) {
		button->type = BN_TYPE_LID_SWITCH;
	}

	status = bn_osl_add_device(button);
	if (ACPI_FAILURE(status)) {
		goto end;
	}

	*context = button;

	bn_print(button);

end:
	if (ACPI_FAILURE(status)) {
		acpi_os_free(button);
	}

	return_ACPI_STATUS(status);
}
Example #5
0
acpi_status
bm_pr_add_device (
	BM_HANDLE               device_handle,
	void                    **context)
{
	acpi_status             status = AE_OK;
	BM_POWER_RESOURCE	*pr = NULL;
	BM_DEVICE		*device = NULL;
	acpi_buffer		buffer;
	acpi_object		acpi_object;

	FUNCTION_TRACE("bm_pr_add_device");

	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Adding power resource [%02x].\n", device_handle));

	if (!context || *context) {
		return_ACPI_STATUS(AE_BAD_PARAMETER);
	}

	buffer.length = sizeof(acpi_object);
	buffer.pointer = &acpi_object;

	/*
	 * Get information on this device.
	 */
	status = bm_get_device_info(device_handle, &device);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	/*
	 * Allocate a new BM_POWER_RESOURCE structure.
	 */
	pr = acpi_os_callocate(sizeof(BM_POWER_RESOURCE));
	if (!pr) {
		return_ACPI_STATUS(AE_NO_MEMORY);
	}

	pr->device_handle = device->handle;
	pr->acpi_handle = device->acpi_handle;

	/*
	 * Get information on this power resource.
	 */
	status = acpi_evaluate_object(pr->acpi_handle, NULL, NULL, &buffer);
	if (ACPI_FAILURE(status)) {
		goto end;
	}

	pr->system_level = acpi_object.power_resource.system_level;
	pr->resource_order = acpi_object.power_resource.resource_order;
	pr->state = ACPI_STATE_UNKNOWN;
	pr->reference_count = 0;

	/*
	 * Get the power resource's current state (ON|OFF).
	 */
	status = bm_pr_get_state(pr);

end:
	if (ACPI_FAILURE(status)) {
		acpi_os_free(pr);
	}
	else {
		*context = pr;
		bm_pr_print(pr);
	}

	return_ACPI_STATUS(status);
}
Example #6
0
acpi_status
ac_add_device(
    BM_HANDLE		device_handle,
    void			**context)
{
    acpi_status 		status = AE_OK;
    BM_DEVICE		*device = NULL;
    AC_CONTEXT		*ac_adapter = NULL;
    acpi_device_info	info;

    FUNCTION_TRACE("ac_add_device");

    ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Adding ac_adapter device [%02x].\n", device_handle));

    if (!context || *context) {
        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid (NULL) context."));
        return_ACPI_STATUS(AE_BAD_PARAMETER);
    }

    /*
     * Get information on this device.
     */
    status = bm_get_device_info(device_handle, &device);
    if (ACPI_FAILURE(status)) {
        return_ACPI_STATUS(status);
    }

    /*
     * Allocate a new AC_CONTEXT structure.
     */
    ac_adapter = acpi_os_callocate(sizeof(AC_CONTEXT));
    if (!ac_adapter) {
        return_ACPI_STATUS(AE_NO_MEMORY);
    }

    ac_adapter->device_handle = device->handle;
    ac_adapter->acpi_handle = device->acpi_handle;

    /*
     * Get information on this object.
     */
    status = acpi_get_object_info(ac_adapter->acpi_handle, &info);
    if (ACPI_FAILURE(status)) {
        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unable to get object info for ac_adapter device."));
        goto end;
    }

    /*
     * _UID?
     * -----
     */
    if (info.valid & ACPI_VALID_UID) {
        strncpy(ac_adapter->uid, info.unique_id, sizeof(info.unique_id));
    }
    else {
        strncpy(ac_adapter->uid, "0", sizeof("0"));
    }

    /*
     * _STA?
     * -----
     */
    if (!(info.valid & ACPI_VALID_STA)) {
        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Must have valid _STA.\n"));
        status = AE_ERROR;
        goto end;
    }

    status = ac_osl_add_device(ac_adapter);
    if (ACPI_FAILURE(status)) {
        goto end;
    }

    *context = ac_adapter;

    ac_print(ac_adapter);

end:
    if (ACPI_FAILURE(status)) {
        acpi_os_free(ac_adapter);
    }

    return_ACPI_STATUS(status);
}