예제 #1
0
static int acpi_memory_device_add(struct acpi_device *device)
{
	int result;
	struct acpi_memory_device *mem_device = NULL;

	ACPI_FUNCTION_TRACE("acpi_memory_device_add");

	if (!device)
		return_VALUE(-EINVAL);

	mem_device = kmalloc(sizeof(struct acpi_memory_device), GFP_KERNEL);
	if (!mem_device)
		return_VALUE(-ENOMEM);
	memset(mem_device, 0, sizeof(struct acpi_memory_device));

	mem_device->handle = device->handle;
	sprintf(acpi_device_name(device), "%s", ACPI_MEMORY_DEVICE_NAME);
	sprintf(acpi_device_class(device), "%s", ACPI_MEMORY_DEVICE_CLASS);
	acpi_driver_data(device) = mem_device;

	/* Get the range from the _CRS */
	result = acpi_memory_get_device_resources(mem_device);
	if (result) {
		kfree(mem_device);
		return_VALUE(result);
	}

	/* Set the device state */
	mem_device->state = MEMORY_POWER_ON_STATE;

	printk(KERN_INFO "%s \n", acpi_device_name(device));

	return_VALUE(result);
}
예제 #2
0
파일: core.c 프로젝트: 274914765/C
static int __init pnpacpi_add_device(struct acpi_device *device)
{
    acpi_handle temp = NULL;
    acpi_status status;
    struct pnp_dev *dev;

    status = acpi_get_handle(device->handle, "_CRS", &temp);
    if (ACPI_FAILURE(status) || !ispnpidacpi(acpi_device_hid(device)) ||
        is_exclusive_device(device))
        return 0;

    dev = pnp_alloc_dev(&pnpacpi_protocol, num, acpi_device_hid(device));
    if (!dev)
        return -ENOMEM;

    dev->data = device->handle;
    /* .enabled means the device can decode the resources */
    dev->active = device->status.enabled;
    status = acpi_get_handle(device->handle, "_SRS", &temp);
    if (ACPI_SUCCESS(status))
        dev->capabilities |= PNP_CONFIGURABLE;
    dev->capabilities |= PNP_READ;
    if (device->flags.dynamic_status && (dev->capabilities & PNP_CONFIGURABLE))
        dev->capabilities |= PNP_WRITE;
    if (device->flags.removable)
        dev->capabilities |= PNP_REMOVABLE;
    status = acpi_get_handle(device->handle, "_DIS", &temp);
    if (ACPI_SUCCESS(status))
        dev->capabilities |= PNP_DISABLE;

    if (strlen(acpi_device_name(device)))
        strncpy(dev->name, acpi_device_name(device), sizeof(dev->name));
    else
        strncpy(dev->name, acpi_device_bid(device), sizeof(dev->name));

    if (dev->active)
        pnpacpi_parse_allocated_resource(dev);

    if (dev->capabilities & PNP_CONFIGURABLE)
        pnpacpi_parse_resource_option_data(dev);

    if (device->flags.compatible_ids) {
        struct acpi_compatible_id_list *cid_list = device->pnp.cid_list;
        int i;

        for (i = 0; i < cid_list->count; i++) {
            if (!ispnpidacpi(cid_list->id[i].value))
                continue;
            pnp_add_id(dev, cid_list->id[i].value);
        }
    }

    /* clear out the damaged flags */
    if (!dev->active)
        pnp_init_resources(dev);
    pnp_add_device(dev);
    num++;

    return AE_OK;
}
예제 #3
0
static int
acpi_container_add(struct acpi_device *device)
{
	struct acpi_container *container;

	ACPI_FUNCTION_TRACE("acpi_container_add");

	if (!device) {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "device is NULL\n"));
		return_VALUE(-EINVAL);
	}

	container = kmalloc(sizeof(struct acpi_container), GFP_KERNEL);
	if(!container)
		return_VALUE(-ENOMEM);
	
	memset(container, 0, sizeof(struct acpi_container));
	container->handle = device->handle;
	strcpy(acpi_device_name(device), ACPI_CONTAINER_DEVICE_NAME);
	strcpy(acpi_device_class(device), ACPI_CONTAINER_CLASS);
	acpi_driver_data(device) = container;

	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device <%s> bid <%s>\n",	\
		acpi_device_name(device), acpi_device_bid(device)));


	return_VALUE(0);
}
예제 #4
0
static int acpi_fujitsu_add(struct acpi_device *device)
{
	int result = 0;
	int state = 0;

	ACPI_FUNCTION_TRACE("acpi_fujitsu_add");

	if (!device)
		return -EINVAL;

	fujitsu->acpi_handle = device->handle;
	sprintf(acpi_device_name(device), "%s", ACPI_FUJITSU_DEVICE_NAME);
	sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS);
	acpi_driver_data(device) = fujitsu;

	result = acpi_bus_get_power(fujitsu->acpi_handle, &state);
	if (result) {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
				  "Error reading power state\n"));
		goto end;
	}

	printk(KERN_INFO PREFIX "%s [%s] (%s)\n",
	       acpi_device_name(device), acpi_device_bid(device),
	       !device->power.state ? "on" : "off");

      end:

	return result;
}
static int acpi_power_add(struct acpi_device *device)
{
	int result = 0, state;
	acpi_status status = AE_OK;
	struct acpi_power_resource *resource = NULL;
	union acpi_object acpi_object;
	struct acpi_buffer buffer = { sizeof(acpi_object), &acpi_object };


	if (!device)
		return -EINVAL;

	resource = kzalloc(sizeof(struct acpi_power_resource), GFP_KERNEL);
	if (!resource)
		return -ENOMEM;

	resource->device = device;
	mutex_init(&resource->resource_lock);
	mutex_init(&resource->devices_lock);
	strcpy(resource->name, device->pnp.bus_id);
	strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME);
	strcpy(acpi_device_class(device), ACPI_POWER_CLASS);
	device->driver_data = resource;

	/* Evalute the object to get the system level and resource order. */
	status = acpi_evaluate_object(device->handle, NULL, NULL, &buffer);
	if (ACPI_FAILURE(status)) {
		result = -ENODEV;
		goto end;
	}
	resource->system_level = acpi_object.power_resource.system_level;
	resource->order = acpi_object.power_resource.resource_order;

	result = acpi_power_get_state(device->handle, &state);
	if (result)
		goto end;

	switch (state) {
	case ACPI_POWER_RESOURCE_STATE_ON:
		device->power.state = ACPI_STATE_D0;
		break;
	case ACPI_POWER_RESOURCE_STATE_OFF:
		device->power.state = ACPI_STATE_D3;
		break;
	default:
		device->power.state = ACPI_STATE_UNKNOWN;
		break;
	}

	printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device),
	       acpi_device_bid(device), state ? "on" : "off");

      end:
	if (result)
		kfree(resource);

	return result;
}
예제 #6
0
static int
acpi_thermal_add (
	struct acpi_device 		*device)
{
	int			result = 0;
	acpi_status		status = AE_OK;
	struct acpi_thermal	*tz = NULL;

	ACPI_FUNCTION_TRACE("acpi_thermal_add");

	if (!device)
		return_VALUE(-EINVAL);

	tz = kmalloc(sizeof(struct acpi_thermal), GFP_KERNEL);
	if (!tz)
		return_VALUE(-ENOMEM);
	memset(tz, 0, sizeof(struct acpi_thermal));

	tz->handle = device->handle;
	sprintf(tz->name, "%s", device->pnp.bus_id);
	sprintf(acpi_device_name(device), "%s", ACPI_THERMAL_DEVICE_NAME);
	sprintf(acpi_device_class(device), "%s", ACPI_THERMAL_CLASS);
	acpi_driver_data(device) = tz;

	result = acpi_thermal_get_info(tz);
	if (result)
		goto end;

	result = acpi_thermal_add_fs(device);
	if (result)
		return_VALUE(result);

	init_timer(&tz->timer);

	acpi_thermal_check(tz);

	status = acpi_install_notify_handler(tz->handle,
		ACPI_DEVICE_NOTIFY, acpi_thermal_notify, tz);
	if (ACPI_FAILURE(status)) {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
			"Error installing notify handler\n"));
		result = -ENODEV;
		goto end;
	}

	printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n",
		acpi_device_name(device), acpi_device_bid(device),
		KELVIN_TO_CELSIUS(tz->temperature));

end:
	if (result) {
		acpi_thermal_remove_fs(device);
		kfree(tz);
	}

	return_VALUE(result);
}
예제 #7
0
static int acpi_fan_add(struct acpi_device *device)
{
	int result = 0;
	int state = 0;
	struct thermal_cooling_device *cdev;

	if (!device)
		return -EINVAL;

	strcpy(acpi_device_name(device), "Fan");
	strcpy(acpi_device_class(device), ACPI_FAN_CLASS);

	result = acpi_bus_get_power(device->handle, &state);
	if (result) {
		printk(KERN_ERR PREFIX "Reading power state\n");
		goto end;
	}

	device->flags.force_power_state = 1;
	acpi_bus_set_power(device->handle, state);
	device->flags.force_power_state = 0;

	cdev = thermal_cooling_device_register("Fan", device,
						&fan_cooling_ops);
	if (IS_ERR(cdev)) {
		result = PTR_ERR(cdev);
		goto end;
	}

	dev_dbg(&device->dev, "registered as cooling_device%d\n", cdev->id);

	device->driver_data = cdev;
	result = sysfs_create_link(&device->dev.kobj,
				   &cdev->device.kobj,
				   "thermal_cooling");
	if (result)
		dev_err(&device->dev, "Failed to create sysfs link "
			"'thermal_cooling'\n");

	result = sysfs_create_link(&cdev->device.kobj,
				   &device->dev.kobj,
				   "device");
	if (result)
		dev_err(&device->dev, "Failed to create sysfs link "
			"'device'\n");

	result = acpi_fan_add_fs(device);
	if (result)
		goto end;

	printk(KERN_INFO PREFIX "%s [%s] (%s)\n",
	       acpi_device_name(device), acpi_device_bid(device),
	       !device->power.state ? "on" : "off");

      end:
	return result;
}
예제 #8
0
int
acpi_ac_add (
	struct acpi_device	*device)
{
	int			result = 0;
	acpi_status		status = AE_OK;
	struct acpi_ac		*ac = NULL;

	ACPI_FUNCTION_TRACE("acpi_ac_add");

	if (!device)
		return_VALUE(-EINVAL);

	ac = kmalloc(sizeof(struct acpi_ac), GFP_KERNEL);
	if (!ac)
		return_VALUE(-ENOMEM);
	memset(ac, 0, sizeof(struct acpi_ac));

	ac->handle = device->handle;
	sprintf(acpi_device_name(device), "%s", ACPI_AC_DEVICE_NAME);
	sprintf(acpi_device_class(device), "%s", ACPI_AC_CLASS);
	acpi_driver_data(device) = ac;

	result = acpi_ac_get_state(ac);
	if (result)
		goto end;

	result = acpi_ac_add_fs(device);
	if (result)
		goto end;

	status = acpi_install_notify_handler(ac->handle,
		ACPI_DEVICE_NOTIFY, acpi_ac_notify, ac);
	if (ACPI_FAILURE(status)) {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
			"Error installing notify handler\n"));
		result = -ENODEV;
		goto end;
	}

	printk(KERN_INFO PREFIX "%s [%s] (%s)\n", 
		acpi_device_name(device), acpi_device_bid(device), 
		ac->state?"on-line":"off-line");

end:
	if (result) {
		acpi_ac_remove_fs(device);
		kfree(ac);
	}

	return_VALUE(result);
}
예제 #9
0
파일: ac.c 프로젝트: CenturyGlorion/linux
static int acpi_ac_probe(struct platform_device *pdev)
{
	int result = 0;
	struct acpi_ac *ac = NULL;
	struct acpi_device *adev;

	if (!pdev)
		return -EINVAL;

	adev = ACPI_COMPANION(&pdev->dev);
	if (!adev)
		return -ENODEV;

	ac = kzalloc(sizeof(struct acpi_ac), GFP_KERNEL);
	if (!ac)
		return -ENOMEM;

	strcpy(acpi_device_name(adev), ACPI_AC_DEVICE_NAME);
	strcpy(acpi_device_class(adev), ACPI_AC_CLASS);
	ac->pdev = pdev;
	platform_set_drvdata(pdev, ac);

	result = acpi_ac_get_state(ac);
	if (result)
		goto end;

	ac->charger.name = acpi_device_bid(adev);
	ac->charger.type = POWER_SUPPLY_TYPE_MAINS;
	ac->charger.properties = ac_props;
	ac->charger.num_properties = ARRAY_SIZE(ac_props);
	ac->charger.get_property = get_ac_property;
	result = power_supply_register(&pdev->dev, &ac->charger);
	if (result)
		goto end;

	result = acpi_install_notify_handler(ACPI_HANDLE(&pdev->dev),
			ACPI_ALL_NOTIFY, acpi_ac_notify_handler, ac);
	if (result) {
		power_supply_unregister(&ac->charger);
		goto end;
	}
	printk(KERN_INFO PREFIX "%s [%s] (%s)\n",
	       acpi_device_name(adev), acpi_device_bid(adev),
	       ac->state ? "on-line" : "off-line");

end:
	if (result)
		kfree(ac);

	dmi_check_system(ac_dmi_table);
	return result;
}
예제 #10
0
static int
acpi_button_read_info (
	char			*page,
	char			**start,
	off_t			off,
	int 			count,
	int 			*eof,
	void			*data)
{
	struct acpi_button	*button = (struct acpi_button *) data;
	char			*p = page;
	int			len = 0;

	ACPI_FUNCTION_TRACE("acpi_button_read_info");

	if (!button || !button->device || (off != 0))
		goto end;

	p += sprintf(p, "type:                    %s\n", 
		acpi_device_name(button->device));

end:
	len = (p - page);
	if (len <= off+count) *eof = 1;
	*start = page + off;
	len -= off;
	if (len>count) len = count;
	if (len<0) len = 0;

	return_VALUE(len);
}
예제 #11
0
파일: button.c 프로젝트: daveyoung/linux
static int acpi_button_add(struct acpi_device *device)
{
	struct acpi_button *button;
	struct input_dev *input;
	const char *hid = acpi_device_hid(device);
	char *name, *class;
	int error;

	if (!strcmp(hid, ACPI_BUTTON_HID_LID) && dmi_check_system(lid_blacklst))
		return -ENODEV;

	button = kzalloc(sizeof(struct acpi_button), GFP_KERNEL);
	if (!button)
		return -ENOMEM;

	device->driver_data = button;

	button->input = input = input_allocate_device();
	if (!input) {
		error = -ENOMEM;
		goto err_free_button;
	}

	name = acpi_device_name(device);
	class = acpi_device_class(device);

	if (!strcmp(hid, ACPI_BUTTON_HID_POWER) ||
	    !strcmp(hid, ACPI_BUTTON_HID_POWERF)) {
		button->type = ACPI_BUTTON_TYPE_POWER;
		strcpy(name, ACPI_BUTTON_DEVICE_NAME_POWER);
		sprintf(class, "%s/%s",
			ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_POWER);
	} else if (!strcmp(hid, ACPI_BUTTON_HID_SLEEP) ||
예제 #12
0
static int acpi_processor_start(struct acpi_device *device)
{
	int result = 0;
	acpi_status status = AE_OK;
	struct acpi_processor *pr;

	ACPI_FUNCTION_TRACE("acpi_processor_start");

	pr = acpi_driver_data(device);

	result = acpi_processor_get_info(pr);
	if (result) {
		/* Processor is physically not present */
		return_VALUE(0);
	}

	BUG_ON((pr->id >= NR_CPUS) || (pr->id < 0));

	/*
	 * Buggy BIOS check
	 * ACPI id of processors can be reported wrongly by the BIOS.
	 * Don't trust it blindly
	 */
	if (processor_device_array[pr->id] != NULL &&
	    processor_device_array[pr->id] != (void *)device) {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "BIOS reporting wrong ACPI id"
			"for the processor\n"));
		return_VALUE(-ENODEV);
	}
	processor_device_array[pr->id] = (void *)device;

	processors[pr->id] = pr;

	result = acpi_processor_add_fs(device);
	if (result)
		goto end;

	status = acpi_install_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY,
					     acpi_processor_notify, pr);
	if (ACPI_FAILURE(status)) {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
				  "Error installing device notify handler\n"));
	}

	acpi_processor_power_init(pr, device);

	if (pr->flags.throttling) {
		printk(KERN_INFO PREFIX "%s [%s] (supports",
		       acpi_device_name(device), acpi_device_bid(device));
		printk(" %d throttling states", pr->throttling.state_count);
		printk(")\n");
	}

      end:

	return_VALUE(result);
}
예제 #13
0
파일: acpi_pad.c 프로젝트: 1800alex/linux
static void acpi_pad_handle_notify(acpi_handle handle)
{
	int num_cpus;
	uint32_t idle_cpus;
	struct acpi_buffer param = {
		.length = 4,
		.pointer = (void *)&idle_cpus,
	};

	mutex_lock(&isolated_cpus_lock);
	num_cpus = acpi_pad_pur(handle);
	if (num_cpus < 0) {
		mutex_unlock(&isolated_cpus_lock);
		return;
	}
	acpi_pad_idle_cpus(num_cpus);
	idle_cpus = acpi_pad_idle_cpus_num();
	acpi_evaluate_ost(handle, ACPI_PROCESSOR_AGGREGATOR_NOTIFY, 0, &param);
	mutex_unlock(&isolated_cpus_lock);
}

static void acpi_pad_notify(acpi_handle handle, u32 event,
	void *data)
{
	struct acpi_device *device = data;

	switch (event) {
	case ACPI_PROCESSOR_AGGREGATOR_NOTIFY:
		acpi_pad_handle_notify(handle);
		acpi_bus_generate_netlink_event(device->pnp.device_class,
			dev_name(&device->dev), event, 0);
		break;
	default:
		pr_warn("Unsupported event [0x%x]\n", event);
		break;
	}
}

static int acpi_pad_add(struct acpi_device *device)
{
	acpi_status status;

	strcpy(acpi_device_name(device), ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME);
	strcpy(acpi_device_class(device), ACPI_PROCESSOR_AGGREGATOR_CLASS);

	if (acpi_pad_add_sysfs(device))
		return -ENODEV;

	status = acpi_install_notify_handler(device->handle,
		ACPI_DEVICE_NOTIFY, acpi_pad_notify, device);
	if (ACPI_FAILURE(status)) {
		acpi_pad_remove_sysfs(device);
		return -ENODEV;
	}

	return 0;
}
예제 #14
0
파일: fan.c 프로젝트: sarnobat/knoppix
int
acpi_fan_add (
	struct acpi_device	*device)
{
	int			result = 0;
	struct acpi_fan		*fan = NULL;
	int			state = 0;

	ACPI_FUNCTION_TRACE("acpi_fan_add");

	if (!device)
		return_VALUE(-EINVAL);

	fan = kmalloc(sizeof(struct acpi_fan), GFP_KERNEL);
	if (!fan)
		return_VALUE(-ENOMEM);
	memset(fan, 0, sizeof(struct acpi_fan));

	fan->handle = device->handle;
	sprintf(acpi_device_name(device), "%s", ACPI_FAN_DEVICE_NAME);
	sprintf(acpi_device_class(device), "%s", ACPI_FAN_CLASS);
	acpi_driver_data(device) = fan;

	result = acpi_bus_get_power(fan->handle, &state);
	if (result) {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
			"Error reading power state\n"));
		goto end;
	}

	result = acpi_fan_add_fs(device);
	if (result)
		goto end;

	printk(KERN_INFO PREFIX "%s [%s] (%s)\n",
		acpi_device_name(device), acpi_device_bid(device),
		!device->power.state?"on":"off");

end:
	if (result)
		kfree(fan);

	return_VALUE(result);
}
예제 #15
0
static int __cpuinit acpi_processor_start(struct acpi_device *device)
{
	int result = 0;
	acpi_status status = AE_OK;
	struct acpi_processor *pr;


	pr = acpi_driver_data(device);

	result = acpi_processor_get_info(pr);
	if (result) {
		/* Processor is physically not present */
		return 0;
	}

	BUG_ON((pr->id >= NR_CPUS) || (pr->id < 0));

	/*
	 * Buggy BIOS check
	 * ACPI id of processors can be reported wrongly by the BIOS.
	 * Don't trust it blindly
	 */
	if (processor_device_array[pr->id] != NULL &&
	    processor_device_array[pr->id] != device) {
		printk(KERN_WARNING "BIOS reported wrong ACPI id"
			"for the processor\n");
		return -ENODEV;
	}
	processor_device_array[pr->id] = device;

	processors[pr->id] = pr;

	result = acpi_processor_add_fs(device);
	if (result)
		goto end;

	status = acpi_install_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY,
					     acpi_processor_notify, pr);

	/* _PDC call should be done before doing anything else (if reqd.). */
	arch_acpi_processor_init_pdc(pr);
	acpi_processor_set_pdc(pr);

	acpi_processor_power_init(pr, device);

	if (pr->flags.throttling) {
		printk(KERN_INFO PREFIX "%s [%s] (supports",
		       acpi_device_name(device), acpi_device_bid(device));
		printk(" %d throttling states", pr->throttling.state_count);
		printk(")\n");
	}

      end:

	return result;
}
예제 #16
0
파일: thermal.c 프로젝트: 119-org/lamobo-d1
static int acpi_thermal_add(struct acpi_device *device)
{
	int result = 0;
	struct acpi_thermal *tz = NULL;


	if (!device)
		return -EINVAL;

	tz = kzalloc(sizeof(struct acpi_thermal), GFP_KERNEL);
	if (!tz)
		return -ENOMEM;

	tz->device = device;
	strcpy(tz->name, device->pnp.bus_id);
	strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME);
	strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS);
	device->driver_data = tz;
	mutex_init(&tz->lock);


	result = acpi_thermal_get_info(tz);
	if (result)
		goto free_memory;

	acpi_thermal_guess_offset(tz);

	result = acpi_thermal_register_thermal_zone(tz);
	if (result)
		goto free_memory;

	printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n",
	       acpi_device_name(device), acpi_device_bid(device),
	       KELVIN_TO_CELSIUS(tz->temperature));
	goto end;

free_memory:
	kfree(tz);
end:
	return result;
}
예제 #17
0
파일: battery.c 프로젝트: wxlong/Test
static int
acpi_battery_add (
	struct acpi_device	*device)
{
	int			result = 0;
	acpi_status		status = 0;
	struct acpi_battery	*battery = NULL;

	ACPI_FUNCTION_TRACE("acpi_battery_add");
	
	if (!device)
		return_VALUE(-EINVAL);

	battery = kmalloc(sizeof(struct acpi_battery), GFP_KERNEL);
	if (!battery)
		return_VALUE(-ENOMEM);
	memset(battery, 0, sizeof(struct acpi_battery));

	battery->handle = device->handle;
	strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
	strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
	acpi_driver_data(device) = battery;

	result = acpi_battery_check(battery);
	if (result)
		goto end;

	result = acpi_battery_add_fs(device);
	if (result)
		goto end;

	status = acpi_install_notify_handler(battery->handle,
		ACPI_DEVICE_NOTIFY, acpi_battery_notify, battery);
	if (ACPI_FAILURE(status)) {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
			"Error installing notify handler\n"));
		result = -ENODEV;
		goto end;
	}

	printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
		ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
		device->status.battery_present?"present":"absent");
		
end:
	if (result) {
		acpi_battery_remove_fs(device);
		kfree(battery);
	}

	return_VALUE(result);
}
예제 #18
0
static int acpi_container_add(struct acpi_device *device)
{
	struct acpi_container *container;

	if (!device) {
		printk(KERN_ERR PREFIX "device is NULL\n");
		return -EINVAL;
	}

	container = kzalloc(sizeof(struct acpi_container), GFP_KERNEL);
	if (!container)
		return -ENOMEM;

	container->handle = device->handle;
	strcpy(acpi_device_name(device), ACPI_CONTAINER_DEVICE_NAME);
	strcpy(acpi_device_class(device), ACPI_CONTAINER_CLASS);
	device->driver_data = container;

	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device <%s> bid <%s>\n",
			  acpi_device_name(device), acpi_device_bid(device)));

	return 0;
}
예제 #19
0
static int acpi_battery_add(struct acpi_device *device)
{
	int result = 0;
	acpi_status status = 0;
	struct acpi_battery *battery = NULL;


	if (!device)
		return -EINVAL;

	battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL);
	if (!battery)
		return -ENOMEM;

	battery->device = device;
	strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
	strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
	acpi_driver_data(device) = battery;

	result = acpi_battery_check(battery);
	if (result)
		goto end;

	result = acpi_battery_add_fs(device);
	if (result)
		goto end;

	status = acpi_install_notify_handler(device->handle,
					     ACPI_ALL_NOTIFY,
					     acpi_battery_notify, battery);
	if (ACPI_FAILURE(status)) {
		result = -ENODEV;
		goto end;
	}

	printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
	       ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
	       device->status.battery_present ? "present" : "absent");

      end:
	if (result) {
		acpi_battery_remove_fs(device);
		kfree(battery);
	}

	return result;
}
예제 #20
0
static int xo15_sci_add(struct acpi_device *device)
{
	unsigned long long tmp;
	acpi_status status;
	int r;

	if (!device)
		return -EINVAL;

	strcpy(acpi_device_name(device), XO15_SCI_DEVICE_NAME);
	strcpy(acpi_device_class(device), XO15_SCI_CLASS);

	/* Get GPE bit assignment (EC events). */
	status = acpi_evaluate_integer(device->handle, "_GPE", NULL, &tmp);
	if (ACPI_FAILURE(status))
		return -EINVAL;

	xo15_sci_gpe = tmp;
	status = acpi_install_gpe_handler(NULL, xo15_sci_gpe,
					  ACPI_GPE_EDGE_TRIGGERED,
					  xo15_sci_gpe_handler, device);
	if (ACPI_FAILURE(status))
		return -ENODEV;

	dev_info(&device->dev, "Initialized, GPE = 0x%lx\n", xo15_sci_gpe);

	r = sysfs_create_file(&device->dev.kobj, &lid_wake_on_close_attr.attr);
	if (r)
		goto err_sysfs;

	/* Flush queue, and enable all SCI events */
	process_sci_queue();
	olpc_ec_mask_write(EC_SCI_SRC_ALL);

	acpi_enable_gpe(NULL, xo15_sci_gpe);

	/* Enable wake-on-EC */
	if (device->wakeup.flags.valid)
		device_init_wakeup(&device->dev, true);

	return 0;

err_sysfs:
	acpi_remove_gpe_handler(NULL, xo15_sci_gpe, xo15_sci_gpe_handler);
	cancel_work_sync(&sci_work);
	return r;
}
예제 #21
0
static int acpi_power_meter_add(struct acpi_device *device)
{
	int res;
	struct acpi_power_meter_resource *resource;

	if (!device)
		return -EINVAL;

	resource = kzalloc(sizeof(struct acpi_power_meter_resource),
			   GFP_KERNEL);
	if (!resource)
		return -ENOMEM;

	resource->sensors_valid = 0;
	resource->acpi_dev = device;
	mutex_init(&resource->lock);
	strcpy(acpi_device_name(device), ACPI_POWER_METER_DEVICE_NAME);
	strcpy(acpi_device_class(device), ACPI_POWER_METER_CLASS);
	device->driver_data = resource;

	free_capabilities(resource);
	res = read_capabilities(resource);
	if (res)
		goto exit_free;

	resource->trip[0] = resource->trip[1] = -1;

	res = setup_attrs(resource);
	if (res)
		goto exit_free;

	resource->hwmon_dev = hwmon_device_register(&device->dev);
	if (IS_ERR(resource->hwmon_dev)) {
		res = PTR_ERR(resource->hwmon_dev);
		goto exit_remove;
	}

	res = 0;
	goto exit;

exit_remove:
	remove_attrs(resource);
exit_free:
	kfree(resource);
exit:
	return res;
}
예제 #22
0
static int acpi_processor_add(struct acpi_device *device)
{
	struct acpi_processor *pr = NULL;


	if (!device)
		return -EINVAL;

	pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
	if (!pr)
		return -ENOMEM;

	pr->handle = device->handle;
	strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME);
	strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS);
	acpi_driver_data(device) = pr;

	return 0;
}
예제 #23
0
static int acpi_processor_add(struct acpi_device *device)
{
	struct acpi_processor *pr = NULL;

	ACPI_FUNCTION_TRACE("acpi_processor_add");

	if (!device)
		return_VALUE(-EINVAL);

	pr = kmalloc(sizeof(struct acpi_processor), GFP_KERNEL);
	if (!pr)
		return_VALUE(-ENOMEM);
	memset(pr, 0, sizeof(struct acpi_processor));

	pr->handle = device->handle;
	strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME);
	strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS);
	acpi_driver_data(device) = pr;

	return_VALUE(0);
}
예제 #24
0
static int __cpuinit xen_acpi_processor_add(struct acpi_device *device)
{
	int ret;
	struct acpi_processor *pr;

	if (!device)
		return -EINVAL;

	pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
	if (!pr)
		return -ENOMEM;

	pr->handle = device->handle;
	strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME);
	strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS);
	device->driver_data = pr;

	ret = xen_acpi_processor_enable(device);
	if (ret)
		pr_err(PREFIX "Error when enabling Xen processor\n");

	return ret;
}
예제 #25
0
static void gpio_regulator_fill_ssdt_generator(struct device *dev)
{
	struct drivers_generic_gpio_regulator_config *config = dev->chip_info;
	const char *scope = acpi_device_scope(dev);
	const char *path = acpi_device_path(dev);
	struct acpi_dp *dsd;

	if (!dev->enabled || !scope || !path || !config->gpio.pin_count)
		return;

	/* Device */
	acpigen_write_scope(scope);
	acpigen_write_device(acpi_device_name(dev));

	/* _HID is set to PRP0001 */
	acpigen_write_name_string("_HID", ACPI_DT_NAMESPACE_HID);

	/* Resources - _CRS */
	acpigen_write_name("_CRS");
	acpigen_write_resourcetemplate_header();
	acpi_device_write_gpio(&config->gpio);
	acpigen_write_resourcetemplate_footer();

	/* DSD */
	dsd = acpi_dp_new_table("_DSD");
	acpi_dp_add_string(dsd, "compatible", "regulator-fixed");
	acpi_dp_add_string(dsd, "regulator-name", config->name);
	acpi_dp_add_gpio(dsd, "gpio-gpios", path, 0, 0, config->gpio.polarity);
	if (config->enabled_on_boot)
		acpi_dp_add_string(dsd, "regulator-boot-on", "on");
	if (config->gpio.polarity == ACPI_GPIO_ACTIVE_HIGH)
		acpi_dp_add_string(dsd, "enable-active-high", "on");
	acpi_dp_write(dsd);

	acpigen_pop_len(); /* Device */
	acpigen_pop_len(); /* Scope */
}
static int acpi_processor_add(struct acpi_device *device)
{
	struct acpi_processor *pr = NULL;


	if (!device)
		return -EINVAL;

	pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
	if (!pr)
		return -ENOMEM;

	if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) {
		kfree(pr);
		return -ENOMEM;
	}

	pr->handle = device->handle;
	strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME);
	strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS);
	device->driver_data = pr;

	return 0;
}
static int acpi_processor_add(struct acpi_device *device,
					const struct acpi_device_id *id)
{
	struct acpi_processor *pr;
	struct device *dev;
	int result = 0;

	pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
	if (!pr)
		return -ENOMEM;

	if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) {
		result = -ENOMEM;
		goto err_free_pr;
	}

	pr->handle = device->handle;
	strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME);
	strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS);
	device->driver_data = pr;

	result = acpi_processor_get_info(device);
	if (result) /* Processor is not physically present or unavailable */
		return 0;

#ifdef CONFIG_SMP
	if (pr->id >= setup_max_cpus && pr->id != 0)
		return 0;
#endif

	BUG_ON(pr->id >= nr_cpu_ids);

	/*
	 * Buggy BIOS check.
	 * ACPI id of processors can be reported wrongly by the BIOS.
	 * Don't trust it blindly
	 */
	if (per_cpu(processor_device_array, pr->id) != NULL &&
	    per_cpu(processor_device_array, pr->id) != device) {
		dev_warn(&device->dev,
			"BIOS reported wrong ACPI id %d for the processor\n",
			pr->id);
		/* Give up, but do not abort the namespace scan. */
		goto err;
	}
	/*
	 * processor_device_array is not cleared on errors to allow buggy BIOS
	 * checks.
	 */
	per_cpu(processor_device_array, pr->id) = device;
	per_cpu(processors, pr->id) = pr;

	dev = get_cpu_device(pr->id);
	if (!dev) {
		result = -ENODEV;
		goto err;
	}

	result = acpi_bind_one(dev, pr->handle);
	if (result)
		goto err;

	pr->dev = dev;
	dev->offline = pr->flags.need_hotplug_init;

	/* Trigger the processor driver's .probe() if present. */
	if (device_attach(dev) >= 0)
		return 1;

	dev_err(dev, "Processor driver could not be attached\n");
	acpi_unbind_one(dev);

 err:
	free_cpumask_var(pr->throttling.shared_cpu_map);
	device->driver_data = NULL;
	per_cpu(processors, pr->id) = NULL;
 err_free_pr:
	kfree(pr);
	return result;
}
예제 #28
0
static int __cpuinit acpi_processor_add(struct acpi_device *device)
{
	struct acpi_processor *pr = NULL;
	int result = 0;
	struct sys_device *sysdev;

	pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
	if (!pr)
		return -ENOMEM;

	if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) {
		kfree(pr);
		return -ENOMEM;
	}

	pr->handle = device->handle;
	strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME);
	strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS);
	device->driver_data = pr;

	result = acpi_processor_get_info(device);
	if (result) {
		/* Processor is physically not present */
		return 0;
	}

	BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));

	/*
	 * Buggy BIOS check
	 * ACPI id of processors can be reported wrongly by the BIOS.
	 * Don't trust it blindly
	 */
	if (per_cpu(processor_device_array, pr->id) != NULL &&
	    per_cpu(processor_device_array, pr->id) != device) {
		printk(KERN_WARNING "BIOS reported wrong ACPI id "
			"for the processor\n");
		result = -ENODEV;
		goto err_free_cpumask;
	}
	per_cpu(processor_device_array, pr->id) = device;

	per_cpu(processors, pr->id) = pr;

	result = acpi_processor_add_fs(device);
	if (result)
		goto err_free_cpumask;

	sysdev = get_cpu_sysdev(pr->id);
	if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) {
		result = -EFAULT;
		goto err_remove_fs;
	}

	/* _PDC call should be done before doing anything else (if reqd.). */
	arch_acpi_processor_init_pdc(pr);
	acpi_processor_set_pdc(pr);
	arch_acpi_processor_cleanup_pdc(pr);

#ifdef CONFIG_CPU_FREQ
	acpi_processor_ppc_has_changed(pr);
#endif
	acpi_processor_get_throttling_info(pr);
	acpi_processor_get_limit_info(pr);


	acpi_processor_power_init(pr, device);

	pr->cdev = thermal_cooling_device_register("Processor", device,
						&processor_cooling_ops);
	if (IS_ERR(pr->cdev)) {
		result = PTR_ERR(pr->cdev);
		goto err_power_exit;
	}

	dev_info(&device->dev, "registered as cooling_device%d\n",
		 pr->cdev->id);

	result = sysfs_create_link(&device->dev.kobj,
				   &pr->cdev->device.kobj,
				   "thermal_cooling");
	if (result) {
		printk(KERN_ERR PREFIX "Create sysfs link\n");
		goto err_thermal_unregister;
	}
	result = sysfs_create_link(&pr->cdev->device.kobj,
				   &device->dev.kobj,
				   "device");
	if (result) {
		printk(KERN_ERR PREFIX "Create sysfs link\n");
		goto err_remove_sysfs;
	}

	return 0;

err_remove_sysfs:
	sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
err_thermal_unregister:
	thermal_cooling_device_unregister(pr->cdev);
err_power_exit:
	acpi_processor_power_exit(pr, device);
err_remove_fs:
	acpi_processor_remove_fs(device);
err_free_cpumask:
	free_cpumask_var(pr->throttling.shared_cpu_map);

	return result;
}
예제 #29
0
static void i2c_tpm_fill_ssdt(struct device *dev)
{
	struct drivers_i2c_tpm_config *config = dev->chip_info;
	const char *scope = acpi_device_scope(dev);
	struct acpi_i2c i2c = {
		.address = dev->path.i2c.device,
		.mode_10bit = dev->path.i2c.mode_10bit,
		.speed = config->speed ? : I2C_SPEED_FAST,
		.resource = scope,
	};

	if (!dev->enabled || !scope)
		return;

	if (!config->hid) {
		printk(BIOS_ERR, "%s: ERROR: HID required\n", dev_path(dev));
		return;
	}

	/* Device */
	acpigen_write_scope(scope);
	acpigen_write_device(acpi_device_name(dev));
	acpigen_write_name_string("_HID", config->hid);
	acpigen_write_name_integer("_UID", config->uid);
	acpigen_write_name_string("_DDN", dev->chip_ops->name);
	acpigen_write_STA(ACPI_STATUS_DEVICE_ALL_ON);

	/* Resources */
	acpigen_write_name("_CRS");
	acpigen_write_resourcetemplate_header();
	acpi_device_write_i2c(&i2c);
	acpi_device_write_interrupt(&config->irq);
	acpigen_write_resourcetemplate_footer();

	acpigen_pop_len(); /* Device */
	acpigen_pop_len(); /* Scope */

	printk(BIOS_INFO, "%s: %s at %s\n", acpi_device_path(dev),
	       dev->chip_ops->name, dev_path(dev));
}

static const char *i2c_tpm_acpi_name(struct device *dev)
{
	return "TPMI";
}

static struct device_operations i2c_tpm_ops = {
	.read_resources		  = DEVICE_NOOP,
	.set_resources		  = DEVICE_NOOP,
	.enable_resources	  = DEVICE_NOOP,
	.acpi_name		  = &i2c_tpm_acpi_name,
	.acpi_fill_ssdt_generator = &i2c_tpm_fill_ssdt,
};

static void i2c_tpm_enable(struct device *dev)
{
	dev->ops = &i2c_tpm_ops;
}

struct chip_operations drivers_i2c_tpm_ops = {
	CHIP_NAME("I2C TPM")
	.enable_dev = &i2c_tpm_enable
};
예제 #30
0
static int __init pnpacpi_add_device(struct acpi_device *device)
{
	acpi_handle temp = NULL;
	acpi_status status;
	struct pnp_id *dev_id;
	struct pnp_dev *dev;

	if (!ispnpidacpi(acpi_device_hid(device)) ||
		is_exclusive_device(device))
		return 0;

	pnp_dbg("ACPI device : hid %s", acpi_device_hid(device));
	dev =  kcalloc(1, sizeof(struct pnp_dev), GFP_KERNEL);
	if (!dev) {
		pnp_err("Out of memory");
		return -ENOMEM;
	}
	dev->data = device->handle;
	/* .enabled means if the device can decode the resources */
	dev->active = device->status.enabled;
	status = acpi_get_handle(device->handle, "_SRS", &temp);
	if (ACPI_SUCCESS(status))
		dev->capabilities |= PNP_CONFIGURABLE;
	dev->capabilities |= PNP_READ;
	if (device->flags.dynamic_status)
		dev->capabilities |= PNP_WRITE;
	if (device->flags.removable)
		dev->capabilities |= PNP_REMOVABLE;
	status = acpi_get_handle(device->handle, "_DIS", &temp);
	if (ACPI_SUCCESS(status))
		dev->capabilities |= PNP_DISABLE;

	dev->protocol = &pnpacpi_protocol;

	if (strlen(acpi_device_name(device)))
		strncpy(dev->name, acpi_device_name(device), sizeof(dev->name));
	else
		strncpy(dev->name, acpi_device_bid(device), sizeof(dev->name));

	dev->number = num;
	
	/* set the initial values for the PnP device */
	dev_id = kcalloc(1, sizeof(struct pnp_id), GFP_KERNEL);
	if (!dev_id)
		goto err;
	pnpidacpi_to_pnpid(acpi_device_hid(device), dev_id->id);
	pnp_add_id(dev_id, dev);

	if(dev->active) {
		/* parse allocated resource */
		status = pnpacpi_parse_allocated_resource(device->handle, &dev->res);
		if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
			pnp_err("PnPACPI: METHOD_NAME__CRS failure for %s", dev_id->id);
			goto err1;
		}
	}

	if(dev->capabilities & PNP_CONFIGURABLE) {
		status = pnpacpi_parse_resource_option_data(device->handle, 
			dev);
		if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
			pnp_err("PnPACPI: METHOD_NAME__PRS failure for %s", dev_id->id);
			goto err1;
		}
	}
	
	/* parse compatible ids */
	if (device->flags.compatible_ids) {
		struct acpi_compatible_id_list *cid_list = device->pnp.cid_list;
		int i;

		for (i = 0; i < cid_list->count; i++) {
			if (!ispnpidacpi(cid_list->id[i].value))
				continue;
			dev_id = kcalloc(1, sizeof(struct pnp_id), GFP_KERNEL);
			if (!dev_id)
				continue;

			pnpidacpi_to_pnpid(cid_list->id[i].value, dev_id->id);
			pnp_add_id(dev_id, dev);
		}
	}

	/* clear out the damaged flags */
	if (!dev->active)
		pnp_init_resource_table(&dev->res);
	pnp_add_device(dev);
	num ++;

	return AE_OK;
err1:
	kfree(dev_id);
err:
	kfree(dev);
	return -EINVAL;
}