Re: [PATCH 1/2] input: misc: add twl4030-pwrbutton driver
From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Date: 2009-02-28 22:23:27
Also in:
lkml
Hi Felipe, On Fri, Feb 27, 2009 at 09:28:02PM +0200, Felipe Balbi wrote:
From: Felipe Balbi <redacted> This is part of the twl4030 multifunction device driver. With this driver we add support for reporting KEY_POWER events via the input layer.
...
+
+ err = twl4030_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &value,
+ STS_HW_CONDITIONS);
+ if (!err) {
+ input_report_key(powerbutton_dev, KEY_POWER,
+ value & PWR_PWRON_IRQ);input_sync() here please.
+ } else {
+ dev_err(dbg_dev, "twl4030: i2c error %d while reading TWL4030"
+ " PM_MASTER STS_HW_CONDITIONS register\n", err);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int __devinit twl4030_pwrbutton_probe(struct platform_device *pdev)
+{
+ int err = 0;
+ int irq = platform_get_irq(pdev, 0);
+
+ dbg_dev = &pdev->dev;
+
+ /* PWRBTN == PWRON */
+ err = request_irq(irq, powerbutton_irq,
+ IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+ "twl4030-pwrbutton", NULL);Requesting IRQ before allocating input device seems unsafe. If IRQ arrives right now we'll go boom.
+ if (err < 0) {
+ dev_dbg(&pdev->dev, "Can't get IRQ for pwrbutton: %d\n", err);
+ goto out;
+ }
+
+ powerbutton_dev = input_allocate_device();
+ if (!powerbutton_dev) {
+ dev_dbg(&pdev->dev, "Can't allocate power button\n");
+ err = -ENOMEM;
+ goto free_irq_and_out;
+ }
+
+ powerbutton_dev->evbit[0] = BIT_MASK(EV_KEY);
+ powerbutton_dev->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER);
+ powerbutton_dev->name = "triton2-pwrbutton";powerbutton_dev->dev.parent = &pdev->dev; Any chance we could set up phys as well? BUS_I2C seems to be in order as well.
+
+ err = input_register_device(powerbutton_dev);
+ if (err) {
+ dev_dbg(&pdev->dev, "Can't register power button: %d\n", err);
+ goto free_input_dev;
+ }
+
+ dev_info(&pdev->dev, "triton2 power button driver initialized\n");
+
+ return 0;
+
+
+free_input_dev:
+ input_free_device(powerbutton_dev);
+free_irq_and_out:
+ free_irq(TWL4030_PWRIRQ_PWRBTN, NULL);
+out:
+ return err;
+}
+
+static int __devexit twl4030_pwrbutton_remove(struct platform_device *pdev)
+{
+ int irq = platform_get_irq(pdev, 0);
+
+ free_irq(irq, NULL);
+ input_unregister_device(powerbutton_dev);
+ input_free_device(powerbutton_dev);Do not call free after unregistering, unregister will drop last reference and will cause device structure be freed. -- Dmitry