Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / s390 / block / scm_drv.c
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
8 #define KMSG_COMPONENT "scm_block"
9 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
10
11 #include <linux/module.h>
12 #include <linux/slab.h>
13 #include <asm/eadm.h>
14 #include "scm_blk.h"
15
16 static void scm_notify(struct scm_device *scmdev, enum scm_event event)
17 {
18         struct scm_blk_dev *bdev = dev_get_drvdata(&scmdev->dev);
19
20         switch (event) {
21         case SCM_CHANGE:
22                 pr_info("%lx: The capabilities of the SCM increment changed\n",
23                         (unsigned long) scmdev->address);
24                 SCM_LOG(2, "State changed");
25                 SCM_LOG_STATE(2, scmdev);
26                 break;
27         case SCM_AVAIL:
28                 SCM_LOG(2, "Increment available");
29                 SCM_LOG_STATE(2, scmdev);
30                 scm_blk_set_available(bdev);
31                 break;
32         }
33 }
34
35 static int scm_probe(struct scm_device *scmdev)
36 {
37         struct scm_blk_dev *bdev;
38         int ret;
39
40         SCM_LOG(2, "probe");
41         SCM_LOG_STATE(2, scmdev);
42
43         if (scmdev->attrs.oper_state != OP_STATE_GOOD)
44                 return -EINVAL;
45
46         bdev = kzalloc(sizeof(*bdev), GFP_KERNEL);
47         if (!bdev)
48                 return -ENOMEM;
49
50         dev_set_drvdata(&scmdev->dev, bdev);
51         ret = scm_blk_dev_setup(bdev, scmdev);
52         if (ret) {
53                 dev_set_drvdata(&scmdev->dev, NULL);
54                 kfree(bdev);
55                 goto out;
56         }
57
58 out:
59         return ret;
60 }
61
62 static int scm_remove(struct scm_device *scmdev)
63 {
64         struct scm_blk_dev *bdev = dev_get_drvdata(&scmdev->dev);
65
66         scm_blk_dev_cleanup(bdev);
67         dev_set_drvdata(&scmdev->dev, NULL);
68         kfree(bdev);
69
70         return 0;
71 }
72
73 static struct scm_driver scm_drv = {
74         .drv = {
75                 .name = "scm_block",
76                 .owner = THIS_MODULE,
77         },
78         .notify = scm_notify,
79         .probe = scm_probe,
80         .remove = scm_remove,
81         .handler = scm_blk_irq,
82 };
83
84 int __init scm_drv_init(void)
85 {
86         return scm_driver_register(&scm_drv);
87 }
88
89 void scm_drv_cleanup(void)
90 {
91         scm_driver_unregister(&scm_drv);
92 }