@@ -19,7 +19,7 @@
static int get_engine_number(struct meson_dev *mc)
{
- return atomic_inc_return(&mc->flow) % MAXFLOW;
+ return atomic_inc_return(&mc->flow) % mc->flow_cnt;
}
static bool meson_cipher_need_fallback(struct skcipher_request *areq)
@@ -26,8 +26,8 @@ static irqreturn_t meson_irq_handler(int irq, void *data)
int flow;
u32 p;
- for (flow = 0; flow < MAXFLOW; flow++) {
- if (mc->irqs[flow] == irq) {
+ for (flow = 0; flow < mc->flow_cnt; flow++) {
+ if (mc->chanlist[flow].irq == irq) {
p = readl(mc->base + ((0x04 + flow) << 2));
if (p) {
writel_relaxed(0xF, mc->base + ((0x4 + flow) << 2));
@@ -103,7 +103,7 @@ static int meson_debugfs_show(struct seq_file *seq, void *v)
struct meson_dev *mc = seq->private;
int i;
- for (i = 0; i < MAXFLOW; i++)
+ for (i = 0; i < mc->flow_cnt; i++)
seq_printf(seq, "Channel %d: nreq %lu\n", i, mc->chanlist[i].stat_req);
for (i = 0; i < ARRAY_SIZE(mc_algs); i++) {
@@ -138,14 +138,32 @@ static void meson_free_chanlist(struct meson_dev *mc, int i)
*/
static int meson_allocate_chanlist(struct meson_dev *mc)
{
+ struct platform_device *pdev = to_platform_device(mc->dev);
int i, err;
- mc->chanlist = devm_kcalloc(mc->dev, MAXFLOW,
+ mc->flow_cnt = platform_irq_count(pdev);
+ if (mc->flow_cnt <= 0) {
+ dev_err(mc->dev, "No IRQs defined\n");
+ return -ENODEV;
+ }
+
+ mc->chanlist = devm_kcalloc(mc->dev, mc->flow_cnt,
sizeof(struct meson_flow), GFP_KERNEL);
if (!mc->chanlist)
return -ENOMEM;
- for (i = 0; i < MAXFLOW; i++) {
+ for (i = 0; i < mc->flow_cnt; i++) {
+ mc->chanlist[i].irq = platform_get_irq(pdev, i);
+ if (mc->chanlist[i].irq < 0)
+ return mc->chanlist[i].irq;
+
+ err = devm_request_irq(mc->dev, mc->chanlist[i].irq,
+ meson_irq_handler, 0, "aml-crypto", mc);
+ if (err < 0) {
+ dev_err(mc->dev, "Cannot request IRQ for flow %d\n", i);
+ return err;
+ }
+
init_completion(&mc->chanlist[i].complete);
mc->chanlist[i].engine = crypto_engine_alloc_init(mc->dev, true);
@@ -215,7 +233,7 @@ static void meson_unregister_algs(struct meson_dev *mc)
static int meson_crypto_probe(struct platform_device *pdev)
{
struct meson_dev *mc;
- int err, i;
+ int err;
mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
if (!mc)
@@ -237,19 +255,6 @@ static int meson_crypto_probe(struct platform_device *pdev)
return err;
}
- for (i = 0; i < MAXFLOW; i++) {
- mc->irqs[i] = platform_get_irq(pdev, i);
- if (mc->irqs[i] < 0)
- return mc->irqs[i];
-
- err = devm_request_irq(&pdev->dev, mc->irqs[i], meson_irq_handler, 0,
- "gxl-crypto", mc);
- if (err < 0) {
- dev_err(mc->dev, "Cannot request IRQ for flow %d\n", i);
- return err;
- }
- }
-
err = clk_prepare_enable(mc->busclk);
if (err != 0) {
dev_err(&pdev->dev, "Cannot prepare_enable busclk\n");
@@ -273,7 +278,7 @@ static int meson_crypto_probe(struct platform_device *pdev)
error_alg:
meson_unregister_algs(mc);
error_flow:
- meson_free_chanlist(mc, MAXFLOW - 1);
+ meson_free_chanlist(mc, mc->flow_cnt - 1);
clk_disable_unprepare(mc->busclk);
return err;
}
@@ -288,7 +293,7 @@ static int meson_crypto_remove(struct platform_device *pdev)
meson_unregister_algs(mc);
- meson_free_chanlist(mc, MAXFLOW - 1);
+ meson_free_chanlist(mc, mc->flow_cnt - 1);
clk_disable_unprepare(mc->busclk);
return 0;
@@ -22,8 +22,6 @@
#define MESON_OPMODE_ECB 0
#define MESON_OPMODE_CBC 1
-#define MAXFLOW 2
-
#define MAXDESC 64
#define DESC_LAST BIT(18)
@@ -62,6 +60,7 @@ struct meson_desc {
* @keylen: keylen for this flow operation
* @complete: completion for the current task on this flow
* @status: set to 1 by interrupt if task is done
+ * @irq: IRQ number for amlogic-crypto
* @t_phy: Physical address of task
* @tl: pointer to the current ce_task for this flow
* @stat_req: number of request done by this flow
@@ -70,6 +69,7 @@ struct meson_flow {
struct crypto_engine *engine;
struct completion complete;
int status;
+ int irq;
unsigned int keylen;
dma_addr_t t_phy;
struct meson_desc *tl;
@@ -85,7 +85,7 @@ struct meson_flow {
* @dev: the platform device
* @chanlist: array of all flow
* @flow: flow to use in next request
- * @irqs: IRQ numbers for amlogic-crypto
+ * @flow_cnt: flow count for amlogic-crypto
* @dbgfs_dir: Debugfs dentry for statistic directory
* @dbgfs_stats: Debugfs dentry for statistic counters
*/
@@ -95,7 +95,7 @@ struct meson_dev {
struct device *dev;
struct meson_flow *chanlist;
atomic_t flow;
- int irqs[MAXFLOW];
+ int flow_cnt;
#ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
struct dentry *dbgfs_dir;
#endif