Beispiel #1
0
/**
 * ide_acpi_set_state - set the channel power state
 * @hwif: target IDE interface
 * @on: state, on/off
 *
 * This function executes the _PS0/_PS3 ACPI method to set the power state.
 * ACPI spec requires _PS0 when IDE power on and _PS3 when power off
 */
void ide_acpi_set_state(ide_hwif_t *hwif, int on)
{
	int unit;

	if (ide_noacpi || ide_noacpi_psx)
		return;

	DEBPRINT("ENTER:\n");

	if (!hwif->acpidata) {
		DEBPRINT("no ACPI data for %s\n", hwif->name);
		return;
	}
	/* channel first and then drives for power on and verse versa for power off */
	if (on)
		acpi_bus_set_power(hwif->acpidata->obj_handle, ACPI_STATE_D0);
	for (unit = 0; unit < MAX_DRIVES; ++unit) {
		ide_drive_t *drive = &hwif->drives[unit];

		if (!drive->acpidata->obj_handle)
			drive->acpidata->obj_handle = ide_acpi_drive_get_handle(drive);

		if (drive->acpidata->obj_handle && drive->present) {
			acpi_bus_set_power(drive->acpidata->obj_handle,
				on? ACPI_STATE_D0: ACPI_STATE_D3);
		}
	}
	if (!on)
		acpi_bus_set_power(hwif->acpidata->obj_handle, ACPI_STATE_D3);
}
Beispiel #2
0
/**
 * usb_acpi_set_power_state - control usb port's power via acpi power
 * resource
 * @hdev: USB device belonging to the usb hub
 * @index: port index based zero
 * @enable: power state expected to be set
 *
 * Notice to use usb_acpi_power_manageable() to check whether the usb port
 * has acpi power resource before invoking this function.
 *
 * Returns 0 on success, else negative errno.
 */
int usb_acpi_set_power_state(struct usb_device *hdev, int index, bool enable)
{
	acpi_handle port_handle;
	unsigned char state;
	int port1 = index + 1;
	int error = -EINVAL;

	port_handle = (acpi_handle)usb_get_hub_port_acpi_handle(hdev,
		port1);
	if (!port_handle)
		return error;

	if (enable)
		state = ACPI_STATE_D0;
	else
		state = ACPI_STATE_D3_COLD;

	error = acpi_bus_set_power(port_handle, state);
	if (!error)
		dev_dbg(&hdev->dev, "The power of hub port %d was set to %d\n",
			port1, enable);
	else
		dev_dbg(&hdev->dev, "The power of hub port failed to be set\n");

	return error;
}
Beispiel #3
0
static ssize_t
acpi_fan_write_state(struct file *file, const char __user * buffer,
		     size_t count, loff_t * ppos)
{
	int result = 0;
	struct seq_file *m = file->private_data;
	struct acpi_device *device = m->private;
	char state_string[3] = { '\0' };

	if (count > sizeof(state_string) - 1)
		return -EINVAL;

	if (copy_from_user(state_string, buffer, count))
		return -EFAULT;

	state_string[count] = '\0';
	if ((state_string[0] < '0') || (state_string[0] > '3'))
		return -EINVAL;
	if (state_string[1] == '\n')
		state_string[1] = '\0';
	if (state_string[1] != '\0')
		return -EINVAL;

	result = acpi_bus_set_power(device->handle,
				    simple_strtoul(state_string, NULL, 0));
	if (result)
		return result;

	return count;
}
Beispiel #4
0
/**
 * usb_acpi_set_power_state - control usb port's power via acpi power
 * resource
 * @hdev: USB device belonging to the usb hub
 * @index: port index based zero
 * @enable: power state expected to be set
 *
 * Notice to use usb_acpi_power_manageable() to check whether the usb port
 * has acpi power resource before invoking this function.
 *
 * Returns 0 on success, else negative errno.
 */
int usb_acpi_set_power_state(struct usb_device *hdev, int index, bool enable)
{
	struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
	struct usb_port *port_dev;
	acpi_handle port_handle;
	unsigned char state;
	int port1 = index + 1;
	int error = -EINVAL;

	if (!hub)
		return -ENODEV;
	port_dev = hub->ports[port1 - 1];

	port_handle = (acpi_handle) usb_get_hub_port_acpi_handle(hdev, port1);
	if (!port_handle)
		return error;

	if (enable)
		state = ACPI_STATE_D0;
	else
		state = ACPI_STATE_D3_COLD;

	error = acpi_bus_set_power(port_handle, state);
	if (!error)
		dev_dbg(&port_dev->dev, "acpi: power was set to %d\n", enable);
	else
		dev_dbg(&port_dev->dev, "acpi: power failed to be set\n");

	return error;
}
Beispiel #5
0
static int
acpi_fan_write_state (
	struct file		*file,
	const char		*buffer,
	unsigned long		count,
	void			*data)
{
	int			result = 0;
	struct acpi_fan		*fan = (struct acpi_fan *) data;
	char			state_string[12] = {'\0'};

	ACPI_FUNCTION_TRACE("acpi_fan_write_state");

	if (!fan || (count > sizeof(state_string) - 1))
		return_VALUE(-EINVAL);
	
	if (copy_from_user(state_string, buffer, count))
		return_VALUE(-EFAULT);
	
	state_string[count] = '\0';
	
	result = acpi_bus_set_power(fan->handle, 
		simple_strtoul(state_string, NULL, 0));
	if (result)
		return_VALUE(result);

	return_VALUE(count);
}
static int acpi_fan_suspend(struct device *dev)
{
	if (!dev)
		return -EINVAL;

	acpi_bus_set_power(to_acpi_device(dev)->handle, ACPI_STATE_D0);

	return AE_OK;
}
Beispiel #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;
}
Beispiel #8
0
static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state)
{
	if (!device)
		return -EINVAL;

	acpi_bus_set_power(device->handle, ACPI_STATE_D0);

	return AE_OK;
}
Beispiel #9
0
static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state)
{
	int power_state;

	power_state = acpi_pm_device_sleep_state(&dev->dev, NULL);
	if (power_state < 0)
		power_state = (state.event == PM_EVENT_ON) ?
				ACPI_STATE_D0 : ACPI_STATE_D3;

	return acpi_bus_set_power((acpi_handle) dev->data, power_state);
}
Beispiel #10
0
static int
fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
{
	struct acpi_device *device = cdev->devdata;
	int result;

	if (!device || (state != 0 && state != 1))
		return -EINVAL;

	result = acpi_bus_set_power(device->handle,
				state ? ACPI_STATE_D0 : ACPI_STATE_D3);

	return result;
}
Beispiel #11
0
static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
{
	acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev);
	static int state_conv[] = {
		[0] = 0,
		[1] = 1,
		[2] = 2,
		[3] = 3,
		[4] = 3
	};
	int acpi_state = state_conv[(int __force) state];

	if (!handle)
		return -ENODEV;
	return acpi_bus_set_power(handle, acpi_state);
}
Beispiel #12
0
static int pnpacpi_disable_resources(struct pnp_dev *dev)
{
	acpi_handle handle = dev->data;
	int ret;

	dev_dbg(&dev->dev, "disable resources\n");

	/* acpi_unregister_gsi(pnp_irq(dev, 0)); */
	ret = 0;
	if (acpi_bus_power_manageable(handle)) {
		ret = acpi_bus_set_power(handle, ACPI_STATE_D3);
		if (ret)
			return ret;
	}
	if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DIS", NULL, NULL)))
		ret = -ENODEV;
	return ret;
}
Beispiel #13
0
static int acpi_fan_resume(struct acpi_device *device)
{
	int result = 0;
	int power_state = 0;

	if (!device)
		return -EINVAL;

	result = acpi_bus_get_power(device->handle, &power_state);
	if (result) {
		printk(KERN_ERR PREFIX
				  "Error reading fan power state\n");
		return result;
	}

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

	return result;
}
Beispiel #14
0
static void gsl_ts_power(struct i2c_client *client, bool turnoff)
{
	struct gsl_ts_data *data = i2c_get_clientdata(client);
#ifdef CONFIG_ACPI
	int error;
#endif

	if (data) {
		if (data->gpio) {
			gpiod_set_value_cansleep(data->gpio, turnoff ? 0 : 1);
#ifdef CONFIG_ACPI
		} else {
			error = acpi_bus_set_power(ACPI_HANDLE(&client->dev), turnoff ? ACPI_STATE_D3 : ACPI_STATE_D0);
			if (error) {
				dev_warn(&client->dev, "%s: error changing power state: %d\n", __func__, error);
			}
#endif
		}
		usleep_range(20000, 50000);
	}
}
Beispiel #15
0
Datei: fan.c Projekt: 274914765/C
static int acpi_fan_resume(struct acpi_device *device)
{
    int result = 0;
    int power_state = 0;

    if (!device)
        return -EINVAL;

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

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

    return result;
}
Beispiel #16
0
static int pnpacpi_set_resources(struct pnp_dev *dev)
{
	acpi_handle handle = dev->data;
	struct acpi_buffer buffer;
	int ret;

	pnp_dbg(&dev->dev, "set resources\n");
	ret = pnpacpi_build_resource_template(dev, &buffer);
	if (ret)
		return ret;
	ret = pnpacpi_encode_resources(dev, &buffer);
	if (ret) {
		kfree(buffer.pointer);
		return ret;
	}
	if (ACPI_FAILURE(acpi_set_current_resources(handle, &buffer)))
		ret = -EINVAL;
	else if (acpi_bus_power_manageable(handle))
		ret = acpi_bus_set_power(handle, ACPI_STATE_D0);
	kfree(buffer.pointer);
	return ret;
}
static int __maybe_unused gsl_ts_suspend(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct gsl_ts_data *ts = i2c_get_clientdata(client);

	dev_warn(&client->dev, "%s: suspending device\n", __func__);

	disable_irq(client->irq);

	gsl_ts_reset_chip(client);
	usleep_range(10000, 20000);

	/* Do we need to do this ourselves? */
	acpi_bus_set_power(ACPI_HANDLE(&client->dev), ACPI_STATE_D3);

	if (device_may_wakeup(dev)) {
		ts->wake_irq_enabled = (enable_irq_wake(client->irq) == 0);
	}

	ts->state = GSL_TS_SHUTDOWN;

	return 0;
}
static int __maybe_unused gsl_ts_resume(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct gsl_ts_data *ts = i2c_get_clientdata(client);

	dev_warn(&client->dev, "%s: resuming device\n", __func__);

	if (device_may_wakeup(dev) && ts->wake_irq_enabled) {
		disable_irq_wake(client->irq);
	}

	/* Do we need to do this ourselves? */
	acpi_bus_set_power(ACPI_HANDLE(&client->dev), ACPI_STATE_D0);
	usleep_range(20000, 50000);

	gsl_ts_reset_chip(client);
	gsl_ts_startup_chip(client);

	enable_irq(client->irq);

	ts->state = GSL_TS_GREEN;

	return 0;
}
Beispiel #19
0
static int
acpi_thermal_active (
	struct acpi_thermal	*tz)
{
	int			result = 0;
	struct acpi_thermal_active *active = NULL;
	int                     i = 0;
	int			j = 0;
	unsigned long		maxtemp = 0;

	ACPI_FUNCTION_TRACE("acpi_thermal_active");

	if (!tz)
		return_VALUE(-EINVAL);

	for (i=0; i<ACPI_THERMAL_MAX_ACTIVE; i++) {

		active = &(tz->trips.active[i]);
		if (!active || !active->flags.valid)
			break;

		/*
		 * Above Threshold?
		 * ----------------
		 * If not already enabled, turn ON all cooling devices
		 * associated with this active threshold.
		 */
		if (tz->temperature >= active->temperature) {
			if (active->temperature > maxtemp)
				tz->state.active_index = i, maxtemp = active->temperature;
			if (!active->flags.enabled) {
				for (j = 0; j < active->devices.count; j++) {
					result = acpi_bus_set_power(active->devices.handles[j], ACPI_STATE_D0);
					if (result) {
						ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Unable to turn cooling device [%p] 'on'\n", active->devices.handles[j]));
						continue;
					}
					active->flags.enabled = 1;
					ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cooling device [%p] now 'on'\n", active->devices.handles[j]));
				}
			}
		}
		/*
		 * Below Threshold?
		 * ----------------
		 * Turn OFF all cooling devices associated with this
		 * threshold.
		 */
		else if (active->flags.enabled) {
			for (j = 0; j < active->devices.count; j++) {
				result = acpi_bus_set_power(active->devices.handles[j], ACPI_STATE_D3);
				if (result) {
					ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Unable to turn cooling device [%p] 'off'\n", active->devices.handles[j]));
					continue;
				}
				active->flags.enabled = 0;
				ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cooling device [%p] now 'off'\n", active->devices.handles[j]));
			}
		}
	}

	return_VALUE(0);
}
static int gsl_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	struct gsl_ts_data *ts;
	const struct firmware *fw;
	unsigned long irqflags;
	int error;

	dev_warn(&client->dev, "%s: got a device named %s at address 0x%x, IRQ %d, flags 0x%x\n", __func__, client->name, client->addr, client->irq, client->flags);

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		dev_err(&client->dev, "%s: i2c check functionality error\n", __func__);
		return -ENXIO;
	}

	if (client->irq <= 0) {
		dev_err(&client->dev, "%s: missing IRQ configuration\n", __func__);
		return -ENODEV;
	}

	ts = devm_kzalloc(&client->dev, sizeof(struct gsl_ts_data), GFP_KERNEL);
	if (!ts) {
		return -ENOMEM;
	}

	ts->client = client;
	i2c_set_clientdata(client, ts);

#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
	/* Set up ACPI device descriptor GPIO name mappings.
		* This is a fallback, it will only be used if the system does not
		* provide a corresponding _DSD entry.
		*/
	error = acpi_dev_add_driver_gpios(ACPI_COMPANION(&client->dev), gsl_ts_acpi_gpios);
	if (error < 0) {
		dev_warn(&client->dev, "%s: failed to register GPIO names, continuing anyway\n", __func__);
	}
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
	ts->gpio = devm_gpiod_get(&client->dev, GSL_PWR_GPIO);
#else
	ts->gpio = devm_gpiod_get(&client->dev, GSL_PWR_GPIO, GPIOD_OUT_LOW);
#endif
	if (IS_ERR(ts->gpio)) {
		dev_err(&client->dev, "%s: error obtaining power pin GPIO resource\n", __func__);
		error = PTR_ERR(ts->gpio);
		goto release_gpios;
	}
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
	error = gpiod_direction_output(ts->gpio, 0);
	if (error < 0) {
		dev_err(&client->dev, "%s: error setting GPIO pin direction\n", __func__);
		goto release_gpios;
	}
#endif

	if (ACPI_COMPANION(&client->dev)) {
		/* Wake the device up with a power on reset */
		error = acpi_bus_set_power(ACPI_HANDLE(&client->dev), ACPI_STATE_D3);
		if (error == 0) {
			error = acpi_bus_set_power(ACPI_HANDLE(&client->dev), ACPI_STATE_D0);
		}
		if (error) {
			dev_err(&client->dev, "%s: failed to wake up device through ACPI: %d, continuting anyway\n", __func__, error);
		}
	}

	error = request_firmware(&fw, GSL_FW_NAME, &ts->client->dev);
	if (error < 0) {
		dev_err(&client->dev, "%s: failed to load firmware: %d\n", __func__, error);
		goto release_gpios;
	}

	error = gsl_ts_init(ts, fw);
	if (error < 0) {
		dev_err(&client->dev, "%s: failed to initialize: %d\n", __func__, error);
		goto release_fw;
	}

	ts->input = devm_input_allocate_device(&client->dev);
	if (!ts->input) {
		dev_err(&client->dev, "%s: failed to allocate input device\n", __func__);
		error = -ENOMEM;
		goto release_fw;
	}

	ts->input->name = "Silead GSLx680 Touchscreen";
	ts->input->id.bustype = BUS_I2C;
	ts->input->phys = "input/ts";

	input_set_capability(ts->input, EV_ABS, ABS_X);
	input_set_capability(ts->input, EV_ABS, ABS_Y);

	input_set_abs_params(ts->input, ABS_MT_POSITION_X, 0, ts->x_max, ts->jitter, ts->deadzone);
	input_set_abs_params(ts->input, ABS_MT_POSITION_Y, 0, ts->y_max, ts->jitter, ts->deadzone);

	input_mt_init_slots(ts->input, ts->multi_touches, INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED | INPUT_MT_TRACK);

	input_set_drvdata(ts->input, ts);

	error = input_register_device(ts->input);
	if (error) {
		dev_err(&client->dev, "%s: unable to register input device: %d\n", __func__, error);
		goto release_fw;
	}

	/*
	 * Systems using device tree should set up interrupt via DTS,
	 * the rest will use the default falling edge interrupts.
	 */
	irqflags = client->dev.of_node ? 0 : IRQF_TRIGGER_FALLING;

	/* Set up interrupt handler - do we still need to account for shared interrupts? */
	error = devm_request_threaded_irq(
		&client->dev,
		client->irq,
		NULL,
		gsl_ts_irq,
		irqflags | IRQF_ONESHOT,
		client->name,
		ts
	);
	if (error) {
		dev_err(&client->dev, "%s: failed to register interrupt\n", __func__);
		goto release_fw;
	}

	/* Execute the controller startup sequence */
	error = gsl_ts_reset_chip(client);
	if (error < 0) {
		dev_err(&client->dev, "%s: chip reset failed\n", __func__);
		goto release_fw;
	}
	error = gsl_ts_write_fw(ts, fw);
	if (error < 0) {
		dev_err(&client->dev, "%s: firmware transfer failed\n", __func__);
		goto release_fw;
	}
	error = gsl_ts_startup_chip(client);
	if (error < 0) {
		dev_err(&client->dev, "%s: chip startup failed\n", __func__);
		goto release_fw;
	}

	/*
	 * Systems using device tree should set up wakeup via DTS,
	 * the rest will configure device as wakeup source by default.
	 */
	if (!client->dev.of_node) {
		device_init_wakeup(&client->dev, true);
	}

	ts->state = GSL_TS_GREEN;

release_fw:
	if (fw) {
		release_firmware(fw);
	}

release_gpios:
	if (error < 0) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
		acpi_dev_remove_driver_gpios(ACPI_COMPANION(&client->dev));
#endif

		return error;
	}
	return 0;
}
Beispiel #21
0
static int gsl_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	struct gsl_ts_data *ts;
	const struct firmware *fw = NULL;
	unsigned long irqflags;
	int error;
	bool acpipower;

	dev_warn(&client->dev, "%s: got a device named %s at address 0x%x, IRQ %d, flags 0x%x\n", __func__, client->name, client->addr, client->irq, client->flags);

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		dev_err(&client->dev, "%s: i2c check functionality error\n", __func__);
		error = -ENXIO;
		goto release;
	}

	if (client->irq <= 0) {
		dev_err(&client->dev, "%s: missing IRQ configuration\n", __func__);
		error = -ENODEV;
		goto release;
	}
	
	ts = devm_kzalloc(&client->dev, sizeof(struct gsl_ts_data), GFP_KERNEL);
	if (!ts) {
		error = -ENOMEM;
		goto release;
	}
	
	ts->client = client;
	i2c_set_clientdata(client, ts);
	
	if (gsl_fw_name != NULL) {
		strncpy(ts->fw_name, gsl_fw_name, sizeof(ts->fw_name));
	} else {
		strncpy(ts->fw_name, GSL_FW_NAME_DEFAULT, sizeof(ts->fw_name));
	}
	error = request_firmware(&fw, ts->fw_name, &ts->client->dev);
	if (error < 0) {
		dev_err(&client->dev, "%s: failed to load firmware: %d\n", __func__, error);
		goto release;
	}

	error = gsl_ts_init(ts, fw);
	if (error < 0) {
		dev_err(&client->dev, "%s: failed to initialize: %d\n", __func__, error);
		goto release;
	}

	ts->input = devm_input_allocate_device(&client->dev);
	if (!ts->input) {
		dev_err(&client->dev, "%s: failed to allocate input device\n", __func__);
		error = -ENOMEM;
		goto release;
	}

	ts->input->name = "Silead GSLx680 Touchscreen";
	ts->input->id.bustype = BUS_I2C;
	ts->input->phys = "input/ts";

	input_set_capability(ts->input, EV_ABS, ABS_X);
	input_set_capability(ts->input, EV_ABS, ABS_Y);

	input_set_abs_params(ts->input, ABS_MT_POSITION_X, 0, ts->x_max, ts->jitter, ts->deadzone);
	input_set_abs_params(ts->input, ABS_MT_POSITION_Y, 0, ts->y_max, ts->jitter, ts->deadzone);

	input_mt_init_slots(ts->input, ts->multi_touches, INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED | INPUT_MT_TRACK);

	input_set_drvdata(ts->input, ts);

	error = input_register_device(ts->input);
	if (error) {
		dev_err(&client->dev, "%s: unable to register input device: %d\n", __func__, error);
		goto release;
	}

	/* Try to use ACPI power methods first */
	acpipower = false;
#ifdef CONFIG_ACPI
	if (ACPI_COMPANION(&client->dev)) {
		/* Wake the device up with a power on reset */
		if (acpi_bus_set_power(ACPI_HANDLE(&client->dev), ACPI_STATE_D3)) {
			dev_warn(&client->dev, "%s: failed to wake up device through ACPI: %d, using GPIO controls instead\n", __func__, error);
		} else {
			acpipower = true;
		}
	}
#endif
	/* Not available, use GPIO settings from DSDT/DT instead */
	if (!acpipower) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
		ts->gpio = devm_gpiod_get_index(&client->dev, GSL_PWR_GPIO, 0);
#else
		ts->gpio = devm_gpiod_get_index(&client->dev, GSL_PWR_GPIO, 0, GPIOD_OUT_LOW);
#endif
		if (IS_ERR(ts->gpio)) {
			dev_err(&client->dev, "%s: error obtaining power pin GPIO resource\n", __func__);
			error = PTR_ERR(ts->gpio);
			goto release;
		}
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
		error = gpiod_direction_output(ts->gpio, 0);
		if (error < 0) {
			dev_err(&client->dev, "%s: error setting GPIO pin direction\n", __func__);
			goto release;
		}
#endif
	} else {
		ts->gpio = NULL;
	}

	/* Enable power */
	gsl_ts_power(client, false);

	/* Execute the controller startup sequence */
	error = gsl_ts_reset_chip(client);
	if (error < 0) {
		dev_err(&client->dev, "%s: chip reset failed\n", __func__);
		goto release;
	}
	error = gsl_ts_write_fw(ts, fw);
	if (error < 0) {
		dev_err(&client->dev, "%s: firmware transfer failed\n", __func__);
		goto release;
	}
	error = gsl_ts_startup_chip(client);
	if (error < 0) {
		dev_err(&client->dev, "%s: chip startup failed\n", __func__);
		goto release;
	}

	/*
	 * Systems using device tree should set up interrupt via DTS,
	 * the rest will use the default falling edge interrupts.
	 */
	irqflags = client->dev.of_node ? 0 : IRQF_TRIGGER_FALLING;

	/* Set up interrupt handler - do we still need to account for shared interrupts? */
	error = devm_request_threaded_irq(
		&client->dev,
		client->irq,
		NULL,
		gsl_ts_irq,
		irqflags | IRQF_ONESHOT,
		client->name,
		ts
	);
	if (error) {
		dev_err(&client->dev, "%s: failed to register interrupt\n", __func__);
		goto release;
	}

	/*
	 * Systems using device tree should set up wakeup via DTS,
	 * the rest will configure device as wakeup source by default.
	 */
	if (!client->dev.of_node) {
		device_init_wakeup(&client->dev, true);
	}

	ts->state = GSL_TS_GREEN;

release:
	if (fw) {
		release_firmware(fw);
	}

	if (error < 0) {
		return error;
	}
	return 0;
}
Beispiel #22
0
static int pnpacpi_resume(struct pnp_dev *dev)
{
    return acpi_bus_set_power((acpi_handle) dev->data, ACPI_STATE_D0);
}
Beispiel #23
0
NTSTATUS
Bus_PDO_Power (
    PPDO_DEVICE_DATA    PdoData,
    PIRP                Irp
)
{
    NTSTATUS            status;
    PIO_STACK_LOCATION  stack;
    POWER_STATE         powerState;
    POWER_STATE_TYPE    powerType;
    ULONG               error;

    stack = IoGetCurrentIrpStackLocation (Irp);
    powerType = stack->Parameters.Power.Type;
    powerState = stack->Parameters.Power.State;

    switch (stack->MinorFunction) {
    case IRP_MN_SET_POWER:

        DPRINT("\tSetting %s power state to %s\n",
               ((powerType == SystemPowerState) ?  "System" : "Device"),
               ((powerType == SystemPowerState) ? \
                DbgSystemPowerString(powerState.SystemState) : \
                DbgDevicePowerString(powerState.DeviceState)));

        switch (powerType) {
        case DevicePowerState:
            if (!PdoData->AcpiHandle || !acpi_bus_power_manageable(PdoData->AcpiHandle))
            {
                PoSetPowerState(PdoData->Common.Self, DevicePowerState, powerState);
                PdoData->Common.DevicePowerState = powerState.DeviceState;
                status = STATUS_SUCCESS;
                break;
            }

            switch (powerState.DeviceState)
            {
            case PowerDeviceD0:
                error = acpi_bus_set_power(PdoData->AcpiHandle, ACPI_STATE_D0);
                break;

            case PowerDeviceD1:
                error = acpi_bus_set_power(PdoData->AcpiHandle, ACPI_STATE_D1);
                break;

            case PowerDeviceD2:
                error = acpi_bus_set_power(PdoData->AcpiHandle, ACPI_STATE_D2);
                break;

            case PowerDeviceD3:
                error = acpi_bus_set_power(PdoData->AcpiHandle, ACPI_STATE_D3);
                break;

            default:
                error = 0;
                break;
            }

            if (ACPI_SUCCESS(error))
            {
                PoSetPowerState(PdoData->Common.Self, DevicePowerState, powerState);
                PdoData->Common.DevicePowerState = powerState.DeviceState;
                status = STATUS_SUCCESS;
            }
            else
                status = STATUS_UNSUCCESSFUL;
            break;

        case SystemPowerState:
            PdoData->Common.SystemPowerState = powerState.SystemState;
            status = STATUS_SUCCESS;
            break;

        default:
            status = STATUS_NOT_SUPPORTED;
            break;
        }
        break;

    case IRP_MN_QUERY_POWER:
        status = STATUS_SUCCESS;
        break;

    case IRP_MN_WAIT_WAKE:
    //
    // We cannot support wait-wake because we are root-enumerated
    // driver, and our parent, the PnP manager, doesn't support wait-wake.
    //
    case IRP_MN_POWER_SEQUENCE:
    default:
        status = STATUS_NOT_SUPPORTED;
        break;
    }

    if (status != STATUS_NOT_SUPPORTED) {

        Irp->IoStatus.Status = status;
    }

    PoStartNextPowerIrp(Irp);
    status = Irp->IoStatus.Status;
    IoCompleteRequest (Irp, IO_NO_INCREMENT);

    return status;
}