18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Device driver for s390 storage class memory. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright IBM Corp. 2012 68c2ecf20Sopenharmony_ci * Author(s): Sebastian Ott <sebott@linux.vnet.ibm.com> 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#define KMSG_COMPONENT "scm_block" 108c2ecf20Sopenharmony_ci#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#include <linux/module.h> 138c2ecf20Sopenharmony_ci#include <linux/slab.h> 148c2ecf20Sopenharmony_ci#include <asm/eadm.h> 158c2ecf20Sopenharmony_ci#include "scm_blk.h" 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_cistatic void scm_notify(struct scm_device *scmdev, enum scm_event event) 188c2ecf20Sopenharmony_ci{ 198c2ecf20Sopenharmony_ci struct scm_blk_dev *bdev = dev_get_drvdata(&scmdev->dev); 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci switch (event) { 228c2ecf20Sopenharmony_ci case SCM_CHANGE: 238c2ecf20Sopenharmony_ci pr_info("%lx: The capabilities of the SCM increment changed\n", 248c2ecf20Sopenharmony_ci (unsigned long) scmdev->address); 258c2ecf20Sopenharmony_ci SCM_LOG(2, "State changed"); 268c2ecf20Sopenharmony_ci SCM_LOG_STATE(2, scmdev); 278c2ecf20Sopenharmony_ci break; 288c2ecf20Sopenharmony_ci case SCM_AVAIL: 298c2ecf20Sopenharmony_ci SCM_LOG(2, "Increment available"); 308c2ecf20Sopenharmony_ci SCM_LOG_STATE(2, scmdev); 318c2ecf20Sopenharmony_ci scm_blk_set_available(bdev); 328c2ecf20Sopenharmony_ci break; 338c2ecf20Sopenharmony_ci } 348c2ecf20Sopenharmony_ci} 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_cistatic int scm_probe(struct scm_device *scmdev) 378c2ecf20Sopenharmony_ci{ 388c2ecf20Sopenharmony_ci struct scm_blk_dev *bdev; 398c2ecf20Sopenharmony_ci int ret; 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci SCM_LOG(2, "probe"); 428c2ecf20Sopenharmony_ci SCM_LOG_STATE(2, scmdev); 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci if (scmdev->attrs.oper_state != OP_STATE_GOOD) 458c2ecf20Sopenharmony_ci return -EINVAL; 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci bdev = kzalloc(sizeof(*bdev), GFP_KERNEL); 488c2ecf20Sopenharmony_ci if (!bdev) 498c2ecf20Sopenharmony_ci return -ENOMEM; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci dev_set_drvdata(&scmdev->dev, bdev); 528c2ecf20Sopenharmony_ci ret = scm_blk_dev_setup(bdev, scmdev); 538c2ecf20Sopenharmony_ci if (ret) { 548c2ecf20Sopenharmony_ci dev_set_drvdata(&scmdev->dev, NULL); 558c2ecf20Sopenharmony_ci kfree(bdev); 568c2ecf20Sopenharmony_ci goto out; 578c2ecf20Sopenharmony_ci } 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ciout: 608c2ecf20Sopenharmony_ci return ret; 618c2ecf20Sopenharmony_ci} 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_cistatic int scm_remove(struct scm_device *scmdev) 648c2ecf20Sopenharmony_ci{ 658c2ecf20Sopenharmony_ci struct scm_blk_dev *bdev = dev_get_drvdata(&scmdev->dev); 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci scm_blk_dev_cleanup(bdev); 688c2ecf20Sopenharmony_ci dev_set_drvdata(&scmdev->dev, NULL); 698c2ecf20Sopenharmony_ci kfree(bdev); 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci return 0; 728c2ecf20Sopenharmony_ci} 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_cistatic struct scm_driver scm_drv = { 758c2ecf20Sopenharmony_ci .drv = { 768c2ecf20Sopenharmony_ci .name = "scm_block", 778c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 788c2ecf20Sopenharmony_ci }, 798c2ecf20Sopenharmony_ci .notify = scm_notify, 808c2ecf20Sopenharmony_ci .probe = scm_probe, 818c2ecf20Sopenharmony_ci .remove = scm_remove, 828c2ecf20Sopenharmony_ci .handler = scm_blk_irq, 838c2ecf20Sopenharmony_ci}; 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ciint __init scm_drv_init(void) 868c2ecf20Sopenharmony_ci{ 878c2ecf20Sopenharmony_ci return scm_driver_register(&scm_drv); 888c2ecf20Sopenharmony_ci} 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_civoid scm_drv_cleanup(void) 918c2ecf20Sopenharmony_ci{ 928c2ecf20Sopenharmony_ci scm_driver_unregister(&scm_drv); 938c2ecf20Sopenharmony_ci} 94