Example #1
0
/**
 * acpi_add_pm_notifier - Register PM notify handler for given ACPI device.
 * @adev: ACPI device to add the notify handler for.
 * @dev: Device to generate a wakeup event for while handling the notification.
 * @work_func: Work function to execute when handling the notification.
 *
 * NOTE: @adev need not be a run-wake or wakeup device to be a valid source of
 * PM wakeup events.  For example, wakeup events may be generated for bridges
 * if one of the devices below the bridge is signaling wakeup, even if the
 * bridge itself doesn't have a wakeup GPE associated with it.
 */
acpi_status acpi_add_pm_notifier(struct acpi_device *adev, struct device *dev,
				 void (*work_func)(struct work_struct *work))
{
	acpi_status status = AE_ALREADY_EXISTS;

	if (!dev && !work_func)
		return AE_BAD_PARAMETER;

	mutex_lock(&acpi_pm_notifier_lock);

	if (adev->wakeup.flags.notifier_present)
		goto out;

	adev->wakeup.ws = wakeup_source_register(dev_name(&adev->dev));
	adev->wakeup.context.dev = dev;
	if (work_func)
		INIT_WORK(&adev->wakeup.context.work, work_func);

	status = acpi_install_notify_handler(adev->handle, ACPI_SYSTEM_NOTIFY,
					     acpi_pm_notify_handler, NULL);
	if (ACPI_FAILURE(status))
		goto out;

	adev->wakeup.flags.notifier_present = true;

 out:
	mutex_unlock(&acpi_pm_notifier_lock);
	return status;
}
int __init pm_autosleep_init(void)
{
	autosleep_ws = wakeup_source_register("autosleep");
	if (!autosleep_ws)
		return -ENOMEM;

	autosleep_wq = alloc_ordered_workqueue("autosleep", 0);
	if (autosleep_wq)
		return 0;

	wakeup_source_unregister(autosleep_ws);
	return -ENOMEM;
}
Example #3
0
int __init pm_autosleep_init(void)
{
	int ret;

	ret = sysfs_create_group(power_kobj, &attr_group);
	if (ret) {
		pr_err("pm_autosleep_init: sysfs_create_group failed\n");
	}

	autosleep_ws = wakeup_source_register("autosleep");
	if (!autosleep_ws)
		return -ENOMEM;

	autosleep_wq = alloc_ordered_workqueue("autosleep", 0);
	if (autosleep_wq)
		return 0;

	wakeup_source_unregister(autosleep_ws);
	return -ENOMEM;
}
//[---]Debug for active wakelock before entering suspend
int __init pm_autosleep_init(void)
{
	//[+++]Debug for active wakelock before entering suspend
    int ret;
    pmsp_dev.name = "PowerManagerServicePrinter";
    pmsp_dev.index = 0;
    INIT_WORK(&pms_printer, pms_printer_func);
    ret = switch_dev_register(&pmsp_dev);
    if (ret < 0)
        printk("%s:fail to register switch power_manager_printer \n",__func__);
    else
        printk("%s:success to register pmsp switch \n",__func__);
	//[---]Debug for active wakelock before entering suspend
	autosleep_ws = wakeup_source_register("autosleep");
	if (!autosleep_ws)
		return -ENOMEM;

	autosleep_wq = alloc_ordered_workqueue("autosleep", 0);
	if (autosleep_wq)
		return 0;

	wakeup_source_unregister(autosleep_ws);
	return -ENOMEM;
}
static int bcm2079x_probe(struct i2c_client *client,
                          const struct i2c_device_id *id)
{
    int ret = 0;
    struct bcm2079x_dev *bcm2079x_dev;

#ifdef USE_PLATFORM_DATA
    struct bcm2079x_i2c_platform_data *platform_data;
    platform_data = client->dev.platform_data;
#else
    struct device_node *np = client->dev.of_node;
#endif
    dev_info(&client->dev, "%s, probing bcm2079x driver flags = %x\n",
             __func__, client->flags);
    if (platform_data == NULL) {
        dev_err(&client->dev, "nfc probe fail\n");
        return -ENODEV;
    }

    if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
        dev_err(&client->dev, "need I2C_FUNC_I2C\n");
        ret = -EIO;
        goto err_exit;
    }

    ret = gpio_request(platform_data->irq_gpio, "nfc_int");
    if (ret)
        return -ENODEV;
    ret = gpio_request(platform_data->en_gpio, "nfc_en");
    if (ret)
        goto err_en;
    ret = gpio_request(platform_data->wake_gpio, "nfc_wake");
    if (ret)
        goto err_firm;

    gpio_set_value(platform_data->en_gpio, 0);
    gpio_set_value(platform_data->wake_gpio, 1);

    bcm2079x_dev = devm_kzalloc(&client->dev,
                                sizeof(*bcm2079x_dev), GFP_KERNEL);
    if (bcm2079x_dev == NULL) {
        dev_err(&client->dev,
                "failed to allocate memory for module data\n");
        ret = -ENOMEM;
        goto err_exit;
    }

#ifdef USE_PLATFORM_DATA
    bcm2079x_dev->wake_gpio = platform_data->wake_gpio;
    bcm2079x_dev->en_gpio = platform_data->en_gpio;
    bcm2079x_dev->irq_gpio = gpio_to_irq(platform_data->irq_gpio);
    platform_data->init(platform_data);

#else
    /*
     * Obtain the GPIO.
     */
    bcm2079x_dev->wake_gpio =
        of_get_named_gpio(np, "wake-gpios", 0);
    if (gpio_is_valid(bcm2079x_dev->wake_gpio)) {
        ret = devm_gpio_request_one(&client->dev,
                                    bcm2079x_dev->wake_gpio,
                                    GPIOF_OUT_INIT_LOW,
                                    "bcm2079x_wake");
        if (ret) {
            dev_err(&client->dev, "Can not request wake-gpio %d\n",
                    bcm2079x_dev->wake_gpio);
            goto err_exit;
        }
    } else {
        dev_err(&client->dev, "Can not find wake-gpio %d\n",
                bcm2079x_dev->wake_gpio);
        ret = bcm2079x_dev->wake_gpio;
        goto err_exit;

    }

    bcm2079x_dev->en_gpio =
        of_get_named_gpio(np, "en-gpios", 0);
    if (gpio_is_valid(bcm2079x_dev->en_gpio)) {
        ret = devm_gpio_request_one(&client->dev, bcm2079x_dev->en_gpio,
                                    GPIOF_OUT_INIT_LOW,
                                    "bcm2079x_en");
        if (ret) {
            dev_err(&client->dev, "Can not request en-gpio %d\n",
                    bcm2079x_dev->en_gpio);
            goto err_exit;
        }
    } else {
        dev_err(&client->dev, "Can not find en-gpio %d\n",
                bcm2079x_dev->en_gpio);
        ret = bcm2079x_dev->en_gpio;
        goto err_exit;

    }


    /*
     * Obtain the interrupt pin.
     */
    bcm2079x_dev->irq_gpio = irq_of_parse_and_map(np, 0);
    if (!bcm2079x_dev->irq_gpio) {
        dev_err(&client->dev, "can not get irq\n");
        goto err_exit;
    }

    dev_info(&client->dev,
             "bcm2079x_probe gpio en %d, wake %d, irq %d\n",
             bcm2079x_dev->en_gpio,
             bcm2079x_dev->wake_gpio,
             bcm2079x_dev->irq_gpio);
#endif


    bcm2079x_dev->client = client;

    /* init mutex and queues */
    init_waitqueue_head(&bcm2079x_dev->read_wq);
    mutex_init(&bcm2079x_dev->read_mutex);
    spin_lock_init(&bcm2079x_dev->irq_enabled_lock);

    bcm2079x_dev->bcm2079x_device.minor = MISC_DYNAMIC_MINOR;
    bcm2079x_dev->bcm2079x_device.name = "bcm2079x";
    bcm2079x_dev->bcm2079x_device.fops = &bcm2079x_dev_fops;

    ret = misc_register(&bcm2079x_dev->bcm2079x_device);
    if (ret) {
        dev_err(&client->dev, "misc_register failed %d\n", ret);
        goto err_misc_register;
    }

    DBG(dev_info(&client->dev, "requesting GPIO: %d / IRQ: %d\n",
                 platform_data->irq_gpio, bcm2079x_dev->irq_gpio));

    bcm2079x_dev->host_wake_ws = wakeup_source_register(
                                     "bcm2079x-ws");
    if (bcm2079x_dev->host_wake_ws == NULL) {
        dev_err(&client->dev,
                "failed to register host-wake wakeup source\n");
        goto err_misc_register;
    }

    setup_timer(&bcm2079x_dev->wake_timer,
                wake_timer_callback, (int)bcm2079x_dev);

    /* request irq.  the irq is set whenever the chip has data available
     * for reading.  it is cleared when all data has been read.
     */
    DBG(dev_info(&client->dev, "requesting IRQ %d\n", client->irq));

    ret = request_irq(client->irq,
                      bcm2079x_dev_irq_handler,
                      INTERRUPT_TRIGGER_TYPE,
                      client->name, bcm2079x_dev);
    if (ret) {
        dev_err(&client->dev, "request_irq %d failed %d\n",
                bcm2079x_dev->irq_gpio, ret);
        goto err_request_irq_failed;
    }

    ret = irq_set_irq_wake(bcm2079x_dev->irq_gpio, 1);
    if (ret) {
        dev_err(&client->dev, "irq_set_irq_wake %d failed %d\n",
                bcm2079x_dev->irq_gpio, ret);
        goto err_request_irq_failed;
    }

    disable_irq_nosync(client->irq);
    bcm2079x_dev->irq_enabled = FALSE;

    bcm2079x_dev->original_address = client->addr;

#ifdef CONFIG_HAS_WAKELOCK
    wake_lock_init(&nfc_soft_wake_lock, WAKE_LOCK_SUSPEND, "NFCSOFTWAKE");
    wake_lock_init(&nfc_pin_wake_lock, WAKE_LOCK_SUSPEND, "NFCPINWAKE");
#endif
    i2c_set_clientdata(client, bcm2079x_dev);

    DBG(dev_info(&client->dev,
                 "%s, probing bcm2079x driver = 0x%x\n",
                 __func__, client->addr));

    DBG(dev_info(&client->dev,
                 "%s, probing bcm2079x driver exited successfully\n",
                 __func__));

    return 0;

err_request_irq_failed:
    misc_deregister(&bcm2079x_dev->bcm2079x_device);
err_misc_register:
    mutex_destroy(&bcm2079x_dev->read_mutex);
    kfree(bcm2079x_dev);
err_exit:
    gpio_free(platform_data->wake_gpio);
err_firm:
    gpio_free(platform_data->en_gpio);
err_en:
    gpio_free(platform_data->irq_gpio);
    return ret;
}