xref: /linux/drivers/ntb/hw/mscc/ntb_hw_switchtec.c (revision 33dea5aae0320345af26ae9aba0894a930e0d4ec)
1 /*
2  * Microsemi Switchtec(tm) PCIe Management Driver
3  * Copyright (c) 2017, Microsemi Corporation
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms and conditions of the GNU General Public License,
7  * version 2, as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  */
15 
16 #include <linux/switchtec.h>
17 #include <linux/module.h>
18 
19 MODULE_DESCRIPTION("Microsemi Switchtec(tm) NTB Driver");
20 MODULE_VERSION("0.1");
21 MODULE_LICENSE("GPL");
22 MODULE_AUTHOR("Microsemi Corporation");
23 
24 struct switchtec_ntb {
25 	struct switchtec_dev *stdev;
26 };
27 
28 static int switchtec_ntb_add(struct device *dev,
29 			     struct class_interface *class_intf)
30 {
31 	struct switchtec_dev *stdev = to_stdev(dev);
32 	struct switchtec_ntb *sndev;
33 
34 	stdev->sndev = NULL;
35 
36 	if (stdev->pdev->class != MICROSEMI_NTB_CLASSCODE)
37 		return -ENODEV;
38 
39 	sndev = kzalloc_node(sizeof(*sndev), GFP_KERNEL, dev_to_node(dev));
40 	if (!sndev)
41 		return -ENOMEM;
42 
43 	sndev->stdev = stdev;
44 
45 	stdev->sndev = sndev;
46 	dev_info(dev, "NTB device registered");
47 
48 	return 0;
49 }
50 
51 void switchtec_ntb_remove(struct device *dev,
52 			  struct class_interface *class_intf)
53 {
54 	struct switchtec_dev *stdev = to_stdev(dev);
55 	struct switchtec_ntb *sndev = stdev->sndev;
56 
57 	if (!sndev)
58 		return;
59 
60 	stdev->sndev = NULL;
61 	kfree(sndev);
62 	dev_info(dev, "ntb device unregistered");
63 }
64 
65 static struct class_interface switchtec_interface  = {
66 	.add_dev = switchtec_ntb_add,
67 	.remove_dev = switchtec_ntb_remove,
68 };
69 
70 static int __init switchtec_ntb_init(void)
71 {
72 	switchtec_interface.class = switchtec_class;
73 	return class_interface_register(&switchtec_interface);
74 }
75 module_init(switchtec_ntb_init);
76 
77 static void __exit switchtec_ntb_exit(void)
78 {
79 	class_interface_unregister(&switchtec_interface);
80 }
81 module_exit(switchtec_ntb_exit);
82