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