crypto: nx - add NX-842 platform frontend driver
[linux-2.6-block.git] / drivers / crypto / nx / nx-842.c
1 /*
2  * Driver frontend for IBM Power 842 compression accelerator
3  *
4  * Copyright (C) 2015 Dan Streetman, IBM Corp
5  *
6  * Designer of the Power data compression engine:
7  *   Bulent Abali <abali@us.ibm.com>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  */
19
20 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
21
22 #include "nx-842.h"
23
24 #define MODULE_NAME "nx-compress"
25 MODULE_LICENSE("GPL");
26 MODULE_AUTHOR("Dan Streetman <ddstreet@ieee.org>");
27 MODULE_DESCRIPTION("842 H/W Compression driver for IBM Power processors");
28
29 /* Only one driver is expected, based on the HW platform */
30 static struct nx842_driver *nx842_driver;
31 static DEFINE_SPINLOCK(nx842_driver_lock); /* protects driver pointers */
32
33 void nx842_register_driver(struct nx842_driver *driver)
34 {
35         spin_lock(&nx842_driver_lock);
36
37         if (nx842_driver) {
38                 pr_err("can't register driver %s, already using driver %s\n",
39                        driver->owner->name, nx842_driver->owner->name);
40         } else {
41                 pr_info("registering driver %s\n", driver->owner->name);
42                 nx842_driver = driver;
43         }
44
45         spin_unlock(&nx842_driver_lock);
46 }
47 EXPORT_SYMBOL_GPL(nx842_register_driver);
48
49 void nx842_unregister_driver(struct nx842_driver *driver)
50 {
51         spin_lock(&nx842_driver_lock);
52
53         if (nx842_driver == driver) {
54                 pr_info("unregistering driver %s\n", driver->owner->name);
55                 nx842_driver = NULL;
56         } else if (nx842_driver) {
57                 pr_err("can't unregister driver %s, using driver %s\n",
58                        driver->owner->name, nx842_driver->owner->name);
59         } else {
60                 pr_err("can't unregister driver %s, no driver in use\n",
61                        driver->owner->name);
62         }
63
64         spin_unlock(&nx842_driver_lock);
65 }
66 EXPORT_SYMBOL_GPL(nx842_unregister_driver);
67
68 static struct nx842_driver *get_driver(void)
69 {
70         struct nx842_driver *driver = NULL;
71
72         spin_lock(&nx842_driver_lock);
73
74         driver = nx842_driver;
75
76         if (driver && !try_module_get(driver->owner))
77                 driver = NULL;
78
79         spin_unlock(&nx842_driver_lock);
80
81         return driver;
82 }
83
84 static void put_driver(struct nx842_driver *driver)
85 {
86         module_put(driver->owner);
87 }
88
89 int nx842_compress(const unsigned char *in, unsigned int in_len,
90                    unsigned char *out, unsigned int *out_len,
91                    void *wrkmem)
92 {
93         struct nx842_driver *driver = get_driver();
94         int ret;
95
96         if (!driver)
97                 return -ENODEV;
98
99         ret = driver->compress(in, in_len, out, out_len, wrkmem);
100
101         put_driver(driver);
102
103         return ret;
104 }
105 EXPORT_SYMBOL_GPL(nx842_compress);
106
107 int nx842_decompress(const unsigned char *in, unsigned int in_len,
108                      unsigned char *out, unsigned int *out_len,
109                      void *wrkmem)
110 {
111         struct nx842_driver *driver = get_driver();
112         int ret;
113
114         if (!driver)
115                 return -ENODEV;
116
117         ret = driver->decompress(in, in_len, out, out_len, wrkmem);
118
119         put_driver(driver);
120
121         return ret;
122 }
123 EXPORT_SYMBOL_GPL(nx842_decompress);
124
125 static __init int nx842_init(void)
126 {
127         pr_info("loading\n");
128
129         if (of_find_compatible_node(NULL, NULL, NX842_PSERIES_COMPAT_NAME))
130                 request_module_nowait(NX842_PSERIES_MODULE_NAME);
131         else
132                 pr_err("no nx842 driver found.\n");
133
134         pr_info("loaded\n");
135
136         return 0;
137 }
138 module_init(nx842_init);
139
140 static void __exit nx842_exit(void)
141 {
142         pr_info("NX842 unloaded\n");
143 }
144 module_exit(nx842_exit);