scm_drv.c 1.7 KB

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