+static irqreturn_t pb_isr(int irq, void *dev_id) +{ + int ret; + int state; + + ret = intel_soc_pmic_readb(DC_TI_SIRQ_REG); + if (ret < 0) { + pr_err("[%s] power button SIRQ REG read fail %d\n", + pb_input->name, ret); + return IRQ_NONE; + } + + state = ret & SIRQ_PWRBTN_REL; + + if (force_trigger && state) { + /* If we lost the press interrupt when short pressing + * power button to wake up board from S3, simulate one. + */ + input_event(pb_input, EV_KEY, KEY_POWER, 1); + input_sync(pb_input); + input_event(pb_input, EV_KEY, KEY_POWER, 0); + input_sync(pb_input); + } else { + input_event(pb_input, EV_KEY, KEY_POWER, !state); + input_sync(pb_input); + pr_info("[%s] power button %s\n", pb_input->name, + state ? "released" : "pressed"); + } + + if (force_trigger) + force_trigger = 0; + + return IRQ_HANDLED; +} + +static int pb_probe(struct platform_device *pdev) +{ + int ret; + + pwrbtn_irq = platform_get_irq(pdev, 0); + if (pwrbtn_irq < 0) { + dev_err(&pdev->dev, + "get irq fail: irq1:%d\n", pwrbtn_irq); + return -EINVAL; + } + pb_input = input_allocate_device(); + if (!pb_input) { + dev_err(&pdev->dev, "failed to allocate input device\n"); + return -ENOMEM; + } + pb_input->name = pdev->name; + pb_input->phys = "power-button/input0"; + pb_input->id.bustype = BUS_HOST; + pb_input->dev.parent = &pdev->dev; + input_set_capability(pb_input, EV_KEY, KEY_POWER); + ret = input_register_device(pb_input); + if (ret) { + dev_err(&pdev->dev, + "failed to register input device:%d\n", ret); + input_free_device(pb_input); + return ret; + } + + ret = request_threaded_irq(pwrbtn_irq, NULL, pb_isr, + IRQF_NO_SUSPEND, DRIVER_NAME, pdev); + if (ret) { + dev_err(&pdev->dev, + "[request irq fail0]irq:%d err:%d\n", pwrbtn_irq, ret); + input_unregister_device(pb_input); + return ret; + } + + return 0; +} |