staging: nvec: cleanup childs on remove
authorMarc Dietrich <marvin24@gmx.de>
Mon, 29 Apr 2013 21:14:52 +0000 (23:14 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 14 May 2013 11:07:50 +0000 (07:07 -0400)
Disable device functions and unregister notifier if available. The
serio device must not be "kzallocated". Otherwise serio_unregister_port
will fail because the device is already freed.

Signed-off-by: Marc Dietrich <marvin24@gmx.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/nvec/nvec.c
drivers/staging/nvec/nvec_kbd.c
drivers/staging/nvec/nvec_power.c
drivers/staging/nvec/nvec_ps2.c

index 51a123e..0e34679 100644 (file)
@@ -829,7 +829,7 @@ static int tegra_nvec_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
-       i2c_clk = clk_get(&pdev->dev, "div-clk");
+       i2c_clk = devm_clk_get(&pdev->dev, "div-clk");
        if (IS_ERR(i2c_clk)) {
                dev_err(nvec->dev, "failed to get controller clock\n");
                return -ENODEV;
@@ -916,8 +916,11 @@ static int tegra_nvec_remove(struct platform_device *pdev)
 
        nvec_toggle_global_events(nvec, false);
        mfd_remove_devices(nvec->dev);
+       nvec_unregister_notifier(nvec, &nvec->nvec_status_notifier);
        cancel_work_sync(&nvec->rx_work);
        cancel_work_sync(&nvec->tx_work);
+       /* FIXME: needs check wether nvec is responsible for power off */
+       pm_power_off = NULL;
 
        return 0;
 }
index fdbe0f3..a0ec52a 100644 (file)
@@ -169,8 +169,15 @@ fail:
 
 static int nvec_kbd_remove(struct platform_device *pdev)
 {
+       struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent);
+       char disable_kbd[] = { NVEC_KBD, DISABLE_KBD },
+            uncnfg_wake_key_reporting[] = { NVEC_KBD, CNFG_WAKE_KEY_REPORTING,
+                                               false };
+       nvec_write_async(nvec, uncnfg_wake_key_reporting, 3);
+       nvec_write_async(nvec, disable_kbd, 2);
+       nvec_unregister_notifier(nvec, &keys_dev.notifier);
+
        input_unregister_device(keys_dev.input);
-       input_free_device(keys_dev.input);
 
        return 0;
 }
index 296f7b9..aacfcd6 100644 (file)
@@ -414,6 +414,7 @@ static int nvec_power_remove(struct platform_device *pdev)
        struct nvec_power *power = platform_get_drvdata(pdev);
 
        cancel_delayed_work_sync(&power->poller);
+       nvec_unregister_notifier(power->nvec, &power->notifier);
        switch (pdev->id) {
        case AC:
                power_supply_unregister(&nvec_psy);
index abb03f0..06dbb02 100644 (file)
@@ -106,7 +106,7 @@ static int nvec_mouse_probe(struct platform_device *pdev)
        struct serio *ser_dev;
        char mouse_reset[] = { NVEC_PS2, SEND_COMMAND, PSMOUSE_RST, 3 };
 
-       ser_dev = devm_kzalloc(&pdev->dev, sizeof(struct serio), GFP_KERNEL);
+       ser_dev = kzalloc(sizeof(struct serio), GFP_KERNEL);
        if (ser_dev == NULL)
                return -ENOMEM;
 
@@ -133,6 +133,11 @@ static int nvec_mouse_probe(struct platform_device *pdev)
 
 static int nvec_mouse_remove(struct platform_device *pdev)
 {
+       struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent);
+
+       ps2_sendcommand(ps2_dev.ser_dev, DISABLE_MOUSE);
+       ps2_stopstreaming(ps2_dev.ser_dev);
+       nvec_unregister_notifier(nvec, &ps2_dev.notifier);
        serio_unregister_port(ps2_dev.ser_dev);
 
        return 0;