tps65086-restart.c 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2021 Emil Renner Berthing
  4. */
  5. #include <linux/mfd/tps65086.h>
  6. #include <linux/mod_devicetable.h>
  7. #include <linux/module.h>
  8. #include <linux/platform_device.h>
  9. #include <linux/reboot.h>
  10. struct tps65086_restart {
  11. struct notifier_block handler;
  12. struct device *dev;
  13. };
  14. static int tps65086_restart_notify(struct notifier_block *this,
  15. unsigned long mode, void *cmd)
  16. {
  17. struct tps65086_restart *tps65086_restart =
  18. container_of(this, struct tps65086_restart, handler);
  19. struct tps65086 *tps65086 = dev_get_drvdata(tps65086_restart->dev->parent);
  20. int ret;
  21. ret = regmap_write(tps65086->regmap, TPS65086_FORCESHUTDN, 1);
  22. if (ret) {
  23. dev_err(tps65086_restart->dev, "%s: error writing to tps65086 pmic: %d\n",
  24. __func__, ret);
  25. return NOTIFY_DONE;
  26. }
  27. /* give it a little time */
  28. mdelay(200);
  29. WARN_ON(1);
  30. return NOTIFY_DONE;
  31. }
  32. static int tps65086_restart_probe(struct platform_device *pdev)
  33. {
  34. struct tps65086_restart *tps65086_restart;
  35. int ret;
  36. tps65086_restart = devm_kzalloc(&pdev->dev, sizeof(*tps65086_restart), GFP_KERNEL);
  37. if (!tps65086_restart)
  38. return -ENOMEM;
  39. platform_set_drvdata(pdev, tps65086_restart);
  40. tps65086_restart->handler.notifier_call = tps65086_restart_notify;
  41. tps65086_restart->handler.priority = 192;
  42. tps65086_restart->dev = &pdev->dev;
  43. ret = register_restart_handler(&tps65086_restart->handler);
  44. if (ret) {
  45. dev_err(&pdev->dev, "%s: cannot register restart handler: %d\n",
  46. __func__, ret);
  47. return -ENODEV;
  48. }
  49. return 0;
  50. }
  51. static int tps65086_restart_remove(struct platform_device *pdev)
  52. {
  53. struct tps65086_restart *tps65086_restart = platform_get_drvdata(pdev);
  54. int ret;
  55. ret = unregister_restart_handler(&tps65086_restart->handler);
  56. if (ret) {
  57. dev_err(&pdev->dev, "%s: cannot unregister restart handler: %d\n",
  58. __func__, ret);
  59. return -ENODEV;
  60. }
  61. return 0;
  62. }
  63. static const struct platform_device_id tps65086_restart_id_table[] = {
  64. { "tps65086-reset", },
  65. { /* sentinel */ }
  66. };
  67. MODULE_DEVICE_TABLE(platform, tps65086_restart_id_table);
  68. static struct platform_driver tps65086_restart_driver = {
  69. .driver = {
  70. .name = "tps65086-restart",
  71. },
  72. .probe = tps65086_restart_probe,
  73. .remove = tps65086_restart_remove,
  74. .id_table = tps65086_restart_id_table,
  75. };
  76. module_platform_driver(tps65086_restart_driver);
  77. MODULE_AUTHOR("Emil Renner Berthing <[email protected]>");
  78. MODULE_DESCRIPTION("TPS65086 restart driver");
  79. MODULE_LICENSE("GPL v2");