diff options
author | Olof Johansson <olof@lixom.net> | 2013-05-27 20:09:53 -0700 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2013-05-27 20:10:04 -0700 |
commit | 6f39ef575df368ed77fcaa2f1d0f28191c7414fc (patch) | |
tree | e64a261770acf65a32e498f5b8f1f8323e14fbb7 /drivers/crypto | |
parent | e4aa937ec75df0eea0bee03bffa3303ad36c986b (diff) | |
parent | 95e4bf98520c9a92cd1b87d12c89e8c60c5fe2ca (diff) |
Merge tag 'ux500-dma40-for-arm-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson into next/drivers
From Linus Walleij:
This is a set of patches from Lee Jones to start converting
the ux500 to fetch DMA channels from the device tree:
- Full DT support and channel mapping in the DMA40 driver
- Dropping of platform data for migrated devices on the DT
boot path.
* tag 'ux500-dma40-for-arm-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson: (36 commits)
ARM: ux500: Register Cryp and Hash platform drivers on Snowball
crypto: ux500/[cryp|hash] - Show successful start-up in the bootlog
ARM: ux500: Stop passing Cryp DMA channel config information though pdata
crypto: ux500/cryp - Set DMA configuration though dma_slave_config()
crypto: ux500/cryp - Prepare clock before enabling it
ARM: ux500: Stop passing Hash DMA channel config information though pdata
crypto: ux500/hash - Set DMA configuration though dma_slave_config()
crypto: ux500/hash - Prepare clock before enabling it
ARM: ux500: Remove unnecessary attributes from DMA channel request pdata
dmaengine: ste_dma40: Correct copy/paste error
ARM: ux500: Remove DMA address look-up table
dmaengine: ste_dma40: Remove redundant address fetching function
dmaengine: ste_dma40: Only use addresses passed as configuration information
ARM: ux500: Stop passing UART's platform data for Device Tree boots
dmaengine: ste_dma40: Don't configure runtime configurable setup during allocate
dmaengine: ste_dma40: Remove unnecessary call to d40_phy_cfg()
dmaengine: ste_dma40: Separate Logical Global Interrupt Mask (GIM) unmasking
ARM: ux500: Pass remnant platform data though to DMA40 driver
dmaengine: ste_dma40: Supply full Device Tree parsing support
dmaengine: ste_dma40: Allow driver to be probe()able when DT is enabled
...
Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'drivers/crypto')
-rw-r--r-- | drivers/crypto/ux500/cryp/cryp.h | 7 | ||||
-rw-r--r-- | drivers/crypto/ux500/cryp/cryp_core.c | 31 | ||||
-rw-r--r-- | drivers/crypto/ux500/hash/hash_alg.h | 5 | ||||
-rw-r--r-- | drivers/crypto/ux500/hash/hash_core.c | 24 |
4 files changed, 62 insertions, 5 deletions
diff --git a/drivers/crypto/ux500/cryp/cryp.h b/drivers/crypto/ux500/cryp/cryp.h index 14cfd05b777..d1d6606fe56 100644 --- a/drivers/crypto/ux500/cryp/cryp.h +++ b/drivers/crypto/ux500/cryp/cryp.h @@ -114,6 +114,9 @@ enum cryp_status_id { }; /* Cryp DMA interface */ +#define CRYP_DMA_TX_FIFO 0x08 +#define CRYP_DMA_RX_FIFO 0x10 + enum cryp_dma_req_type { CRYP_DMA_DISABLE_BOTH, CRYP_DMA_ENABLE_IN_DATA, @@ -217,7 +220,8 @@ struct cryp_dma { /** * struct cryp_device_data - structure for a cryp device. - * @base: Pointer to the hardware base address. + * @base: Pointer to virtual base address of the cryp device. + * @phybase: Pointer to physical memory location of the cryp device. * @dev: Pointer to the devices dev structure. * @clk: Pointer to the device's clock control. * @pwr_regulator: Pointer to the device's power control. @@ -232,6 +236,7 @@ struct cryp_dma { */ struct cryp_device_data { struct cryp_register __iomem *base; + phys_addr_t phybase; struct device *dev; struct clk *clk; struct regulator *pwr_regulator; diff --git a/drivers/crypto/ux500/cryp/cryp_core.c b/drivers/crypto/ux500/cryp/cryp_core.c index 32f480622b9..4f8b11af29a 100644 --- a/drivers/crypto/ux500/cryp/cryp_core.c +++ b/drivers/crypto/ux500/cryp/cryp_core.c @@ -475,6 +475,19 @@ static int cryp_get_device_data(struct cryp_ctx *ctx, static void cryp_dma_setup_channel(struct cryp_device_data *device_data, struct device *dev) { + struct dma_slave_config mem2cryp = { + .direction = DMA_MEM_TO_DEV, + .dst_addr = device_data->phybase + CRYP_DMA_TX_FIFO, + .dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES, + .dst_maxburst = 4, + }; + struct dma_slave_config cryp2mem = { + .direction = DMA_DEV_TO_MEM, + .src_addr = device_data->phybase + CRYP_DMA_RX_FIFO, + .src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES, + .src_maxburst = 4, + }; + dma_cap_zero(device_data->dma.mask); dma_cap_set(DMA_SLAVE, device_data->dma.mask); @@ -490,6 +503,9 @@ static void cryp_dma_setup_channel(struct cryp_device_data *device_data, stedma40_filter, device_data->dma.cfg_cryp2mem); + dmaengine_slave_config(device_data->dma.chan_mem2cryp, &mem2cryp); + dmaengine_slave_config(device_data->dma.chan_cryp2mem, &cryp2mem); + init_completion(&device_data->dma.cryp_dma_complete); } @@ -1431,6 +1447,7 @@ static int ux500_cryp_probe(struct platform_device *pdev) goto out_kfree; } + device_data->phybase = res->start; device_data->base = ioremap(res->start, resource_size(res)); if (!device_data->base) { dev_err(dev, "[%s]: ioremap failed!", __func__); @@ -1458,11 +1475,17 @@ static int ux500_cryp_probe(struct platform_device *pdev) goto out_regulator; } + ret = clk_prepare(device_data->clk); + if (ret) { + dev_err(dev, "[%s]: clk_prepare() failed!", __func__); + goto out_clk; + } + /* Enable device power (and clock) */ ret = cryp_enable_power(device_data->dev, device_data, false); if (ret) { dev_err(dev, "[%s]: cryp_enable_power() failed!", __func__); - goto out_clk; + goto out_clk_unprepare; } cryp_error = cryp_check(device_data); @@ -1518,11 +1541,16 @@ static int ux500_cryp_probe(struct platform_device *pdev) goto out_power; } + dev_info(dev, "successfully registered\n"); + return 0; out_power: cryp_disable_power(device_data->dev, device_data, false); +out_clk_unprepare: + clk_unprepare(device_data->clk); + out_clk: clk_put(device_data->clk); @@ -1593,6 +1621,7 @@ static int ux500_cryp_remove(struct platform_device *pdev) dev_err(&pdev->dev, "[%s]: cryp_disable_power() failed", __func__); + clk_unprepare(device_data->clk); clk_put(device_data->clk); regulator_put(device_data->pwr_regulator); diff --git a/drivers/crypto/ux500/hash/hash_alg.h b/drivers/crypto/ux500/hash/hash_alg.h index cd9351cb24d..be6eb54da40 100644 --- a/drivers/crypto/ux500/hash/hash_alg.h +++ b/drivers/crypto/ux500/hash/hash_alg.h @@ -11,6 +11,7 @@ #include <linux/bitops.h> #define HASH_BLOCK_SIZE 64 +#define HASH_DMA_FIFO 4 #define HASH_DMA_ALIGN_SIZE 4 #define HASH_DMA_PERFORMANCE_MIN_SIZE 1024 #define HASH_BYTES_PER_WORD 4 @@ -347,7 +348,8 @@ struct hash_req_ctx { /** * struct hash_device_data - structure for a hash device. - * @base: Pointer to the hardware base address. + * @base: Pointer to virtual base address of the hash device. + * @phybase: Pointer to physical memory location of the hash device. * @list_node: For inclusion in klist. * @dev: Pointer to the device dev structure. * @ctx_lock: Spinlock for current_ctx. @@ -361,6 +363,7 @@ struct hash_req_ctx { */ struct hash_device_data { struct hash_register __iomem *base; + phys_addr_t phybase; struct klist_node list_node; struct device *dev; struct spinlock ctx_lock; diff --git a/drivers/crypto/ux500/hash/hash_core.c b/drivers/crypto/ux500/hash/hash_core.c index cf550896753..9ca6fbb5e30 100644 --- a/drivers/crypto/ux500/hash/hash_core.c +++ b/drivers/crypto/ux500/hash/hash_core.c @@ -122,6 +122,13 @@ static void hash_dma_setup_channel(struct hash_device_data *device_data, struct device *dev) { struct hash_platform_data *platform_data = dev->platform_data; + struct dma_slave_config conf = { + .direction = DMA_MEM_TO_DEV, + .dst_addr = device_data->phybase + HASH_DMA_FIFO, + .dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES, + .dst_maxburst = 16, + }; + dma_cap_zero(device_data->dma.mask); dma_cap_set(DMA_SLAVE, device_data->dma.mask); @@ -131,6 +138,8 @@ static void hash_dma_setup_channel(struct hash_device_data *device_data, platform_data->dma_filter, device_data->dma.cfg_mem2hash); + dmaengine_slave_config(device_data->dma.chan_mem2hash, &conf); + init_completion(&device_data->dma.complete); } @@ -1699,6 +1708,7 @@ static int ux500_hash_probe(struct platform_device *pdev) goto out_kfree; } + device_data->phybase = res->start; device_data->base = ioremap(res->start, resource_size(res)); if (!device_data->base) { dev_err(dev, "[%s] ioremap() failed!", @@ -1726,11 +1736,17 @@ static int ux500_hash_probe(struct platform_device *pdev) goto out_regulator; } + ret = clk_prepare(device_data->clk); + if (ret) { + dev_err(dev, "[%s] clk_prepare() failed!", __func__); + goto out_clk; + } + /* Enable device power (and clock) */ ret = hash_enable_power(device_data, false); if (ret) { dev_err(dev, "[%s]: hash_enable_power() failed!", __func__); - goto out_clk; + goto out_clk_unprepare; } ret = hash_check_hw(device_data); @@ -1756,12 +1772,15 @@ static int ux500_hash_probe(struct platform_device *pdev) goto out_power; } - dev_info(dev, "[%s] successfully probed\n", __func__); + dev_info(dev, "successfully registered\n"); return 0; out_power: hash_disable_power(device_data, false); +out_clk_unprepare: + clk_unprepare(device_data->clk); + out_clk: clk_put(device_data->clk); @@ -1826,6 +1845,7 @@ static int ux500_hash_remove(struct platform_device *pdev) dev_err(dev, "[%s]: hash_disable_power() failed", __func__); + clk_unprepare(device_data->clk); clk_put(device_data->clk); regulator_put(device_data->regulator); |