aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto/omap-sham.c
diff options
context:
space:
mode:
authorMark A. Greer <mgreer@animalcreek.com>2012-12-21 12:04:06 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2013-01-05 05:43:57 -0500
commit03feec9cc67eaa21e9aa0d3aede0dfed0629f468 (patch)
treecb9bef43e15ad229829c3798e4d6417734632951 /drivers/crypto/omap-sham.c
parentdd49a69e8eb1423e4d434081a7785bc1b8b8948a (diff)
crypto: omap-sham - Add Device Tree Support
Add Device Tree suport to the omap-sham crypto driver. Currently, only support for OMAP2 and OMAP3 is being added but support for OMAP4 will be added in a subsequent patch. CC: Dmitry Kasatkin <dmitry.kasatkin@intel.com> Signed-off-by: Mark A. Greer <mgreer@animalcreek.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto/omap-sham.c')
-rw-r--r--drivers/crypto/omap-sham.c139
1 files changed, 106 insertions, 33 deletions
diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
index f6b270ed7d62..860cad866a36 100644
--- a/drivers/crypto/omap-sham.c
+++ b/drivers/crypto/omap-sham.c
@@ -30,6 +30,10 @@
30#include <linux/dmaengine.h> 30#include <linux/dmaengine.h>
31#include <linux/omap-dma.h> 31#include <linux/omap-dma.h>
32#include <linux/pm_runtime.h> 32#include <linux/pm_runtime.h>
33#include <linux/of.h>
34#include <linux/of_device.h>
35#include <linux/of_address.h>
36#include <linux/of_irq.h>
33#include <linux/delay.h> 37#include <linux/delay.h>
34#include <linux/crypto.h> 38#include <linux/crypto.h>
35#include <linux/cryptohash.h> 39#include <linux/cryptohash.h>
@@ -145,6 +149,7 @@ struct omap_sham_dev {
145 int irq; 149 int irq;
146 spinlock_t lock; 150 spinlock_t lock;
147 int err; 151 int err;
152 unsigned int dma;
148 struct dma_chan *dma_lch; 153 struct dma_chan *dma_lch;
149 struct tasklet_struct done_task; 154 struct tasklet_struct done_task;
150 155
@@ -1155,13 +1160,99 @@ static irqreturn_t omap_sham_irq(int irq, void *dev_id)
1155 return IRQ_HANDLED; 1160 return IRQ_HANDLED;
1156} 1161}
1157 1162
1163#ifdef CONFIG_OF
1164static const struct of_device_id omap_sham_of_match[] = {
1165 {
1166 .compatible = "ti,omap2-sham",
1167 },
1168 {},
1169};
1170MODULE_DEVICE_TABLE(of, omap_sham_of_match);
1171
1172static int omap_sham_get_res_of(struct omap_sham_dev *dd,
1173 struct device *dev, struct resource *res)
1174{
1175 struct device_node *node = dev->of_node;
1176 const struct of_device_id *match;
1177 int err = 0;
1178
1179 match = of_match_device(of_match_ptr(omap_sham_of_match), dev);
1180 if (!match) {
1181 dev_err(dev, "no compatible OF match\n");
1182 err = -EINVAL;
1183 goto err;
1184 }
1185
1186 err = of_address_to_resource(node, 0, res);
1187 if (err < 0) {
1188 dev_err(dev, "can't translate OF node address\n");
1189 err = -EINVAL;
1190 goto err;
1191 }
1192
1193 dd->irq = of_irq_to_resource(node, 0, NULL);
1194 if (!dd->irq) {
1195 dev_err(dev, "can't translate OF irq value\n");
1196 err = -EINVAL;
1197 goto err;
1198 }
1199
1200 dd->dma = -1; /* Dummy value that's unused */
1201
1202err:
1203 return err;
1204}
1205#else
1206static int omap_sham_get_res_dev(struct omap_sham_dev *dd,
1207 struct device *dev, struct resource *res)
1208{
1209 return -EINVAL;
1210}
1211#endif
1212
1213static int omap_sham_get_res_pdev(struct omap_sham_dev *dd,
1214 struct platform_device *pdev, struct resource *res)
1215{
1216 struct device *dev = &pdev->dev;
1217 struct resource *r;
1218 int err = 0;
1219
1220 /* Get the base address */
1221 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1222 if (!r) {
1223 dev_err(dev, "no MEM resource info\n");
1224 err = -ENODEV;
1225 goto err;
1226 }
1227 memcpy(res, r, sizeof(*res));
1228
1229 /* Get the IRQ */
1230 dd->irq = platform_get_irq(pdev, 0);
1231 if (dd->irq < 0) {
1232 dev_err(dev, "no IRQ resource info\n");
1233 err = dd->irq;
1234 goto err;
1235 }
1236
1237 /* Get the DMA */
1238 r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
1239 if (!r) {
1240 dev_err(dev, "no DMA resource info\n");
1241 err = -ENODEV;
1242 goto err;
1243 }
1244 dd->dma = r->start;
1245
1246err:
1247 return err;
1248}
1249
1158static int __devinit omap_sham_probe(struct platform_device *pdev) 1250static int __devinit omap_sham_probe(struct platform_device *pdev)
1159{ 1251{
1160 struct omap_sham_dev *dd; 1252 struct omap_sham_dev *dd;
1161 struct device *dev = &pdev->dev; 1253 struct device *dev = &pdev->dev;
1162 struct resource *res; 1254 struct resource res;
1163 dma_cap_mask_t mask; 1255 dma_cap_mask_t mask;
1164 unsigned dma_chan;
1165 int err, i, j; 1256 int err, i, j;
1166 1257
1167 dd = kzalloc(sizeof(struct omap_sham_dev), GFP_KERNEL); 1258 dd = kzalloc(sizeof(struct omap_sham_dev), GFP_KERNEL);
@@ -1178,33 +1269,18 @@ static int __devinit omap_sham_probe(struct platform_device *pdev)
1178 tasklet_init(&dd->done_task, omap_sham_done_task, (unsigned long)dd); 1269 tasklet_init(&dd->done_task, omap_sham_done_task, (unsigned long)dd);
1179 crypto_init_queue(&dd->queue, OMAP_SHAM_QUEUE_LENGTH); 1270 crypto_init_queue(&dd->queue, OMAP_SHAM_QUEUE_LENGTH);
1180 1271
1181 dd->irq = -1; 1272 err = (dev->of_node) ? omap_sham_get_res_of(dd, dev, &res) :
1182 1273 omap_sham_get_res_pdev(dd, pdev, &res);
1183 /* Get the base address */ 1274 if (err)
1184 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1185 if (!res) {
1186 dev_err(dev, "no MEM resource info\n");
1187 err = -ENODEV;
1188 goto res_err;
1189 }
1190 dd->phys_base = res->start;
1191
1192 /* Get the DMA */
1193 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
1194 if (!res) {
1195 dev_err(dev, "no DMA resource info\n");
1196 err = -ENODEV;
1197 goto res_err; 1275 goto res_err;
1198 }
1199 dma_chan = res->start;
1200 1276
1201 /* Get the IRQ */ 1277 dd->io_base = devm_request_and_ioremap(dev, &res);
1202 dd->irq = platform_get_irq(pdev, 0); 1278 if (!dd->io_base) {
1203 if (dd->irq < 0) { 1279 dev_err(dev, "can't ioremap\n");
1204 dev_err(dev, "no IRQ resource info\n"); 1280 err = -ENOMEM;
1205 err = dd->irq;
1206 goto res_err; 1281 goto res_err;
1207 } 1282 }
1283 dd->phys_base = res.start;
1208 1284
1209 err = request_irq(dd->irq, omap_sham_irq, 1285 err = request_irq(dd->irq, omap_sham_irq,
1210 IRQF_TRIGGER_LOW, dev_name(dev), dd); 1286 IRQF_TRIGGER_LOW, dev_name(dev), dd);
@@ -1216,10 +1292,10 @@ static int __devinit omap_sham_probe(struct platform_device *pdev)
1216 dma_cap_zero(mask); 1292 dma_cap_zero(mask);
1217 dma_cap_set(DMA_SLAVE, mask); 1293 dma_cap_set(DMA_SLAVE, mask);
1218 1294
1219 dd->dma_lch = dma_request_channel(mask, omap_dma_filter_fn, &dma_chan); 1295 dd->dma_lch = dma_request_channel(mask, omap_dma_filter_fn, &dd->dma);
1220 if (!dd->dma_lch) { 1296 if (!dd->dma_lch) {
1221 dev_err(dev, "unable to obtain RX DMA engine channel %u\n", 1297 dev_err(dev, "unable to obtain RX DMA engine channel %u\n",
1222 dma_chan); 1298 dd->dma);
1223 err = -ENXIO; 1299 err = -ENXIO;
1224 goto dma_err; 1300 goto dma_err;
1225 } 1301 }
@@ -1255,13 +1331,11 @@ static int __devinit omap_sham_probe(struct platform_device *pdev)
1255err_algs: 1331err_algs:
1256 for (j = 0; j < i; j++) 1332 for (j = 0; j < i; j++)
1257 crypto_unregister_ahash(&algs[j]); 1333 crypto_unregister_ahash(&algs[j]);
1258 iounmap(dd->io_base);
1259 pm_runtime_disable(dev); 1334 pm_runtime_disable(dev);
1260io_err: 1335io_err:
1261 dma_release_channel(dd->dma_lch); 1336 dma_release_channel(dd->dma_lch);
1262dma_err: 1337dma_err:
1263 if (dd->irq >= 0) 1338 free_irq(dd->irq, dd);
1264 free_irq(dd->irq, dd);
1265res_err: 1339res_err:
1266 kfree(dd); 1340 kfree(dd);
1267 dd = NULL; 1341 dd = NULL;
@@ -1285,11 +1359,9 @@ static int __devexit omap_sham_remove(struct platform_device *pdev)
1285 for (i = 0; i < ARRAY_SIZE(algs); i++) 1359 for (i = 0; i < ARRAY_SIZE(algs); i++)
1286 crypto_unregister_ahash(&algs[i]); 1360 crypto_unregister_ahash(&algs[i]);
1287 tasklet_kill(&dd->done_task); 1361 tasklet_kill(&dd->done_task);
1288 iounmap(dd->io_base);
1289 pm_runtime_disable(&pdev->dev); 1362 pm_runtime_disable(&pdev->dev);
1290 dma_release_channel(dd->dma_lch); 1363 dma_release_channel(dd->dma_lch);
1291 if (dd->irq >= 0) 1364 free_irq(dd->irq, dd);
1292 free_irq(dd->irq, dd);
1293 kfree(dd); 1365 kfree(dd);
1294 dd = NULL; 1366 dd = NULL;
1295 1367
@@ -1321,6 +1393,7 @@ static struct platform_driver omap_sham_driver = {
1321 .name = "omap-sham", 1393 .name = "omap-sham",
1322 .owner = THIS_MODULE, 1394 .owner = THIS_MODULE,
1323 .pm = &omap_sham_pm_ops, 1395 .pm = &omap_sham_pm_ops,
1396 .of_match_table = omap_sham_of_match,
1324 }, 1397 },
1325}; 1398};
1326 1399