scm_drv.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Device driver for s390 storage class memory.
  4. *
  5. * Copyright IBM Corp. 2012
  6. * Author(s): Sebastian Ott <sebott@linux.vnet.ibm.com>
  7. */
  8. #define KMSG_COMPONENT "scm_block"
  9. #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
  10. #include <linux/module.h>
  11. #include <linux/slab.h>
  12. #include <asm/eadm.h>
  13. #include "scm_blk.h"
  14. static void scm_notify(struct scm_device *scmdev, enum scm_event event)
  15. {
  16. struct scm_blk_dev *bdev = dev_get_drvdata(&scmdev->dev);
  17. switch (event) {
  18. case SCM_CHANGE:
  19. pr_info("%lx: The capabilities of the SCM increment changed\n",
  20. (unsigned long) scmdev->address);
  21. SCM_LOG(2, "State changed");
  22. SCM_LOG_STATE(2, scmdev);
  23. break;
  24. case SCM_AVAIL:
  25. SCM_LOG(2, "Increment available");
  26. SCM_LOG_STATE(2, scmdev);
  27. scm_blk_set_available(bdev);
  28. break;
  29. }
  30. }
  31. static int scm_probe(struct scm_device *scmdev)
  32. {
  33. struct scm_blk_dev *bdev;
  34. int ret;
  35. SCM_LOG(2, "probe");
  36. SCM_LOG_STATE(2, scmdev);
  37. if (scmdev->attrs.oper_state != OP_STATE_GOOD)
  38. return -EINVAL;
  39. bdev = kzalloc(sizeof(*bdev), GFP_KERNEL);
  40. if (!bdev)
  41. return -ENOMEM;
  42. dev_set_drvdata(&scmdev->dev, bdev);
  43. ret = scm_blk_dev_setup(bdev, scmdev);
  44. if (ret) {
  45. dev_set_drvdata(&scmdev->dev, NULL);
  46. kfree(bdev);
  47. goto out;
  48. }
  49. out:
  50. return ret;
  51. }
  52. static int scm_remove(struct scm_device *scmdev)
  53. {
  54. struct scm_blk_dev *bdev = dev_get_drvdata(&scmdev->dev);
  55. scm_blk_dev_cleanup(bdev);
  56. dev_set_drvdata(&scmdev->dev, NULL);
  57. kfree(bdev);
  58. return 0;
  59. }
  60. static struct scm_driver scm_drv = {
  61. .drv = {
  62. .name = "scm_block",
  63. .owner = THIS_MODULE,
  64. },
  65. .notify = scm_notify,
  66. .probe = scm_probe,
  67. .remove = scm_remove,
  68. .handler = scm_blk_irq,
  69. };
  70. int __init scm_drv_init(void)
  71. {
  72. return scm_driver_register(&scm_drv);
  73. }
  74. void scm_drv_cleanup(void)
  75. {
  76. scm_driver_unregister(&scm_drv);
  77. }