xref: /openbmc/linux/drivers/s390/block/scm_drv.c (revision 0d456bad)
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 notify(struct scm_device *scmdev)
17 {
18 	pr_info("%lu: 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 }
23 
24 static int scm_probe(struct scm_device *scmdev)
25 {
26 	struct scm_blk_dev *bdev;
27 	int ret;
28 
29 	SCM_LOG(2, "probe");
30 	SCM_LOG_STATE(2, scmdev);
31 
32 	if (scmdev->attrs.oper_state != OP_STATE_GOOD)
33 		return -EINVAL;
34 
35 	bdev = kzalloc(sizeof(*bdev), GFP_KERNEL);
36 	if (!bdev)
37 		return -ENOMEM;
38 
39 	dev_set_drvdata(&scmdev->dev, bdev);
40 	ret = scm_blk_dev_setup(bdev, scmdev);
41 	if (ret) {
42 		dev_set_drvdata(&scmdev->dev, NULL);
43 		kfree(bdev);
44 		goto out;
45 	}
46 
47 out:
48 	return ret;
49 }
50 
51 static int scm_remove(struct scm_device *scmdev)
52 {
53 	struct scm_blk_dev *bdev = dev_get_drvdata(&scmdev->dev);
54 
55 	scm_blk_dev_cleanup(bdev);
56 	dev_set_drvdata(&scmdev->dev, NULL);
57 	kfree(bdev);
58 
59 	return 0;
60 }
61 
62 static struct scm_driver scm_drv = {
63 	.drv = {
64 		.name = "scm_block",
65 		.owner = THIS_MODULE,
66 	},
67 	.notify = notify,
68 	.probe = scm_probe,
69 	.remove = scm_remove,
70 	.handler = scm_blk_irq,
71 };
72 
73 int __init scm_drv_init(void)
74 {
75 	return scm_driver_register(&scm_drv);
76 }
77 
78 void scm_drv_cleanup(void)
79 {
80 	scm_driver_unregister(&scm_drv);
81 }
82