Re: [PATCH v3 3/4] Crypto: rockchip/crypto - add crypto driver for rk3288

2015-11-15 Thread Zain


On 2015年11月15日 06:41, Heiko Stuebner wrote:
> Hi Zain,
>
> Am Freitag, 13. November 2015, 14:44:43 schrieb Zain:
>> On 2015年11月12日 20:32, Heiko Stuebner wrote:
>>> Hi Zain,
>>>
>>> I was able to sucessfully test your crypto-driver, but have found some
>>> improvements below that should probably get looked at:
>>>
>>> Am Mittwoch, 11. November 2015, 14:35:58 schrieb Zain Wang:
 Crypto driver support:
  ecb(aes) cbc(aes) ecb(des) cbc(des) ecb(des3_ede) cbc(des3_ede)
 You can alloc tags above in your case.

 And other algorithms and platforms will be added later on.

 Signed-off-by: Zain Wang 
 ---
>>> [...]
>>>
 diff --git a/drivers/crypto/rockchip/rk3288_crypto.c 
 b/drivers/crypto/rockchip/rk3288_crypto.c
 new file mode 100644
 index 000..bb36baa
 --- /dev/null
 +++ b/drivers/crypto/rockchip/rk3288_crypto.c
 @@ -0,0 +1,392 @@
> [...]
>
> static void rk_crypto_action(void *data)
> {
>   struct rk_crypto_info *crypto_info = data;
>
>   reset_control_assert(crypto_info->rst);
> }
>
 +static int rk_crypto_probe(struct platform_device *pdev)
 +{
 +  struct resource *res;
 +  struct device *dev = &pdev->dev;
 +  struct rk_crypto_info *crypto_info;
 +  int err = 0;
 +
 +  crypto_info = devm_kzalloc(&pdev->dev,
 + sizeof(*crypto_info), GFP_KERNEL);
 +  if (!crypto_info) {
 +  err = -ENOMEM;
 +  goto err_crypto;
 +  }
 +
 +  crypto_info->rst = devm_reset_control_get(dev, "crypto-rst");
 +  if (IS_ERR(crypto_info->rst)) {
 +  err = PTR_ERR(crypto_info->rst);
 +  goto err_crypto;
 +  }
 +
 +  reset_control_assert(crypto_info->rst);
 +  usleep_range(10, 20);
 +  reset_control_deassert(crypto_info->rst);
>   err = devm_add_action(dev, rk_crypto_action, crypto_info);
>   if (err) {
>   reset_control_assert(crypto_info->rst);
>   return err;
>   }
>
> from here onwards the devm_action will always be executed when either
> _probe fails, or after remove finishes, so no need to assert the reset
> manually.
I have known this function,
rk_crypto_action will be executed next to either failed _probe, or
_remove automatically.
It also make sure reset_control_assert can be executed after tasklet_kill.

OK! Done!
>
 +
 +  spin_lock_init(&crypto_info->lock);
 +
 +  res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 +  crypto_info->reg = devm_ioremap_resource(&pdev->dev, res);
 +  if (IS_ERR(crypto_info->reg)) {
 +  err = PTR_ERR(crypto_info->reg);
 +  goto err_ioremap;
 +  }
 +
 +  crypto_info->aclk = devm_clk_get(&pdev->dev, "aclk");
 +  if (IS_ERR(crypto_info->aclk)) {
 +  err = PTR_ERR(crypto_info->aclk);
 +  goto err_ioremap;
 +  }
 +
 +  crypto_info->hclk = devm_clk_get(&pdev->dev, "hclk");
 +  if (IS_ERR(crypto_info->hclk)) {
 +  err = PTR_ERR(crypto_info->hclk);
 +  goto err_ioremap;
 +  }
 +
 +  crypto_info->sclk = devm_clk_get(&pdev->dev, "sclk");
 +  if (IS_ERR(crypto_info->sclk)) {
 +  err = PTR_ERR(crypto_info->sclk);
 +  goto err_ioremap;
 +  }
 +
 +  crypto_info->dmaclk = devm_clk_get(&pdev->dev, "apb_pclk");
 +  if (IS_ERR(crypto_info->dmaclk)) {
 +  err = PTR_ERR(crypto_info->dmaclk);
 +  goto err_ioremap;
 +  }
 +
 +  crypto_info->irq = platform_get_irq(pdev, 0);
 +  if (crypto_info->irq < 0) {
 +  dev_warn(crypto_info->dev,
 +   "control Interrupt is not available.\n");
 +  err = crypto_info->irq;
 +  goto err_ioremap;
 +  }
 +
 +  err = devm_request_irq(&pdev->dev, crypto_info->irq, crypto_irq_handle,
 + IRQF_SHARED, "rk-crypto", pdev);
>>> you are freeing the irq manually below and in _remove too. As it stands
>>> with putting the ip block in reset again on remove this should either loose
>>> the devm_ or you could add a devm_action that handles the reset assert
>>> like in [0] - registering the devm_action above where the reset is done.
>>> That way you could really use dev_request_irq and loose the free_irq
>>> calls here and in remove.
>>>
>>> [0] https://lkml.org/lkml/2015/11/8/159
>> I made a mistake here. I did not remove free_irq when using
>> devm_request_irq.
>>
>> As I do not konw enough about devm_action and reset-assert , can I
>> remove free_irq
>> simply like drivers/i2c/buses/i2c-sun6i-p2wi.c used devm_request_irq and
>> reset_assert?
> I did insert suitable code on how that could look a bit above :-)
Thanks, done!
>
>>> [...]
>>>
 +static int rk_crypto_remove(struct platform_device *pdev)
 +{
 +  struct rk_crypto_info *crypto_tmp = platform_get_drvdata(pdev);
 +
 +  rk_crypto_unregister();
 +  

Re: [PATCH v3 3/4] Crypto: rockchip/crypto - add crypto driver for rk3288

2015-11-14 Thread Heiko Stuebner
Hi Zain,

Am Freitag, 13. November 2015, 14:44:43 schrieb Zain:
> 
> On 2015年11月12日 20:32, Heiko Stuebner wrote:
> > Hi Zain,
> >
> > I was able to sucessfully test your crypto-driver, but have found some
> > improvements below that should probably get looked at:
> >
> > Am Mittwoch, 11. November 2015, 14:35:58 schrieb Zain Wang:
> >> Crypto driver support:
> >>  ecb(aes) cbc(aes) ecb(des) cbc(des) ecb(des3_ede) cbc(des3_ede)
> >> You can alloc tags above in your case.
> >>
> >> And other algorithms and platforms will be added later on.
> >>
> >> Signed-off-by: Zain Wang 
> >> ---
> > [...]
> >
> >> diff --git a/drivers/crypto/rockchip/rk3288_crypto.c 
> >> b/drivers/crypto/rockchip/rk3288_crypto.c
> >> new file mode 100644
> >> index 000..bb36baa
> >> --- /dev/null
> >> +++ b/drivers/crypto/rockchip/rk3288_crypto.c
> >> @@ -0,0 +1,392 @@

[...]

static void rk_crypto_action(void *data)
{
struct rk_crypto_info *crypto_info = data;

reset_control_assert(crypto_info->rst);
}

> >> +static int rk_crypto_probe(struct platform_device *pdev)
> >> +{
> >> +  struct resource *res;
> >> +  struct device *dev = &pdev->dev;
> >> +  struct rk_crypto_info *crypto_info;
> >> +  int err = 0;
> >> +
> >> +  crypto_info = devm_kzalloc(&pdev->dev,
> >> + sizeof(*crypto_info), GFP_KERNEL);
> >> +  if (!crypto_info) {
> >> +  err = -ENOMEM;
> >> +  goto err_crypto;
> >> +  }
> >> +
> >> +  crypto_info->rst = devm_reset_control_get(dev, "crypto-rst");
> >> +  if (IS_ERR(crypto_info->rst)) {
> >> +  err = PTR_ERR(crypto_info->rst);
> >> +  goto err_crypto;
> >> +  }
> >> +
> >> +  reset_control_assert(crypto_info->rst);
> >> +  usleep_range(10, 20);
> >> +  reset_control_deassert(crypto_info->rst);

err = devm_add_action(dev, rk_crypto_action, crypto_info);
if (err) {
reset_control_assert(crypto_info->rst);
return err;
}

from here onwards the devm_action will always be executed when either
_probe fails, or after remove finishes, so no need to assert the reset
manually.

> >> +
> >> +  spin_lock_init(&crypto_info->lock);
> >> +
> >> +  res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> >> +  crypto_info->reg = devm_ioremap_resource(&pdev->dev, res);
> >> +  if (IS_ERR(crypto_info->reg)) {
> >> +  err = PTR_ERR(crypto_info->reg);
> >> +  goto err_ioremap;
> >> +  }
> >> +
> >> +  crypto_info->aclk = devm_clk_get(&pdev->dev, "aclk");
> >> +  if (IS_ERR(crypto_info->aclk)) {
> >> +  err = PTR_ERR(crypto_info->aclk);
> >> +  goto err_ioremap;
> >> +  }
> >> +
> >> +  crypto_info->hclk = devm_clk_get(&pdev->dev, "hclk");
> >> +  if (IS_ERR(crypto_info->hclk)) {
> >> +  err = PTR_ERR(crypto_info->hclk);
> >> +  goto err_ioremap;
> >> +  }
> >> +
> >> +  crypto_info->sclk = devm_clk_get(&pdev->dev, "sclk");
> >> +  if (IS_ERR(crypto_info->sclk)) {
> >> +  err = PTR_ERR(crypto_info->sclk);
> >> +  goto err_ioremap;
> >> +  }
> >> +
> >> +  crypto_info->dmaclk = devm_clk_get(&pdev->dev, "apb_pclk");
> >> +  if (IS_ERR(crypto_info->dmaclk)) {
> >> +  err = PTR_ERR(crypto_info->dmaclk);
> >> +  goto err_ioremap;
> >> +  }
> >> +
> >> +  crypto_info->irq = platform_get_irq(pdev, 0);
> >> +  if (crypto_info->irq < 0) {
> >> +  dev_warn(crypto_info->dev,
> >> +   "control Interrupt is not available.\n");
> >> +  err = crypto_info->irq;
> >> +  goto err_ioremap;
> >> +  }
> >> +
> >> +  err = devm_request_irq(&pdev->dev, crypto_info->irq, crypto_irq_handle,
> >> + IRQF_SHARED, "rk-crypto", pdev);
> > you are freeing the irq manually below and in _remove too. As it stands
> > with putting the ip block in reset again on remove this should either loose
> > the devm_ or you could add a devm_action that handles the reset assert
> > like in [0] - registering the devm_action above where the reset is done.
> > That way you could really use dev_request_irq and loose the free_irq
> > calls here and in remove.
> >
> > [0] https://lkml.org/lkml/2015/11/8/159
> I made a mistake here. I did not remove free_irq when using
> devm_request_irq.
> 
> As I do not konw enough about devm_action and reset-assert , can I
> remove free_irq
> simply like drivers/i2c/buses/i2c-sun6i-p2wi.c used devm_request_irq and
> reset_assert?

I did insert suitable code on how that could look a bit above :-)

> >
> > [...]
> >
> >> +static int rk_crypto_remove(struct platform_device *pdev)
> >> +{
> >> +  struct rk_crypto_info *crypto_tmp = platform_get_drvdata(pdev);
> >> +
> >> +  rk_crypto_unregister();
> >> +  reset_control_assert(crypto_tmp->rst);
> > mainly my comment from above applies, but in any case the reset-assert
> > should definitly happen _after_ the tasklet is killed and the irq freed,
> > to make sure nothing will want to access device-registers anymore.
> >
> > [devm works sequen

Re: [PATCH v3 3/4] Crypto: rockchip/crypto - add crypto driver for rk3288

2015-11-12 Thread Zain


On 2015年11月12日 20:32, Heiko Stuebner wrote:
> Hi Zain,
>
> I was able to sucessfully test your crypto-driver, but have found some
> improvements below that should probably get looked at:
>
> Am Mittwoch, 11. November 2015, 14:35:58 schrieb Zain Wang:
>> Crypto driver support:
>>  ecb(aes) cbc(aes) ecb(des) cbc(des) ecb(des3_ede) cbc(des3_ede)
>> You can alloc tags above in your case.
>>
>> And other algorithms and platforms will be added later on.
>>
>> Signed-off-by: Zain Wang 
>> ---
> [...]
>
>> diff --git a/drivers/crypto/rockchip/rk3288_crypto.c 
>> b/drivers/crypto/rockchip/rk3288_crypto.c
>> new file mode 100644
>> index 000..bb36baa
>> --- /dev/null
>> +++ b/drivers/crypto/rockchip/rk3288_crypto.c
>> @@ -0,0 +1,392 @@
> [...]
>
>> +static irqreturn_t crypto_irq_handle(int irq, void *dev_id)
> that function should probably also get a "rk_" prefix?
OK! good idea.
I will add it to next version.
>> +{
>> +struct rk_crypto_info *dev  = platform_get_drvdata(dev_id);
>> +u32 interrupt_status;
>> +int err = 0;
>> +
>> +spin_lock(&dev->lock);
>> +
>> +if (irq == dev->irq) {
> I'm not sure I understand that line. Interrupt handlers are only
> called for the interrupt they are registered for, which would be dev->irq
> in any case, so that should always be true and therefore be unnecessary?
You are right, it is unnecessary.
 It will be remove in next version.
>
>> +interrupt_status = CRYPTO_READ(dev, RK_CRYPTO_INTSTS);
>> +CRYPTO_WRITE(dev, RK_CRYPTO_INTSTS, interrupt_status);
>> +if (interrupt_status & 0x0a) {
>> +dev_warn(dev->dev, "DMA Error\n");
>> +err = -EFAULT;
>> +} else if (interrupt_status & 0x05) {
>> +err = dev->update(dev);
>> +}
>> +
>> +if (err)
>> +dev->complete(dev, err);
>> +}
>> +spin_unlock(&dev->lock);
>> +return IRQ_HANDLED;
>> +}
> [...]
>
>> +static int rk_crypto_probe(struct platform_device *pdev)
>> +{
>> +struct resource *res;
>> +struct device *dev = &pdev->dev;
>> +struct rk_crypto_info *crypto_info;
>> +int err = 0;
>> +
>> +crypto_info = devm_kzalloc(&pdev->dev,
>> +   sizeof(*crypto_info), GFP_KERNEL);
>> +if (!crypto_info) {
>> +err = -ENOMEM;
>> +goto err_crypto;
>> +}
>> +
>> +crypto_info->rst = devm_reset_control_get(dev, "crypto-rst");
>> +if (IS_ERR(crypto_info->rst)) {
>> +err = PTR_ERR(crypto_info->rst);
>> +goto err_crypto;
>> +}
>> +
>> +reset_control_assert(crypto_info->rst);
>> +usleep_range(10, 20);
>> +reset_control_deassert(crypto_info->rst);
>> +
>> +spin_lock_init(&crypto_info->lock);
>> +
>> +res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> +crypto_info->reg = devm_ioremap_resource(&pdev->dev, res);
>> +if (IS_ERR(crypto_info->reg)) {
>> +err = PTR_ERR(crypto_info->reg);
>> +goto err_ioremap;
>> +}
>> +
>> +crypto_info->aclk = devm_clk_get(&pdev->dev, "aclk");
>> +if (IS_ERR(crypto_info->aclk)) {
>> +err = PTR_ERR(crypto_info->aclk);
>> +goto err_ioremap;
>> +}
>> +
>> +crypto_info->hclk = devm_clk_get(&pdev->dev, "hclk");
>> +if (IS_ERR(crypto_info->hclk)) {
>> +err = PTR_ERR(crypto_info->hclk);
>> +goto err_ioremap;
>> +}
>> +
>> +crypto_info->sclk = devm_clk_get(&pdev->dev, "sclk");
>> +if (IS_ERR(crypto_info->sclk)) {
>> +err = PTR_ERR(crypto_info->sclk);
>> +goto err_ioremap;
>> +}
>> +
>> +crypto_info->dmaclk = devm_clk_get(&pdev->dev, "apb_pclk");
>> +if (IS_ERR(crypto_info->dmaclk)) {
>> +err = PTR_ERR(crypto_info->dmaclk);
>> +goto err_ioremap;
>> +}
>> +
>> +crypto_info->irq = platform_get_irq(pdev, 0);
>> +if (crypto_info->irq < 0) {
>> +dev_warn(crypto_info->dev,
>> + "control Interrupt is not available.\n");
>> +err = crypto_info->irq;
>> +goto err_ioremap;
>> +}
>> +
>> +err = devm_request_irq(&pdev->dev, crypto_info->irq, crypto_irq_handle,
>> +   IRQF_SHARED, "rk-crypto", pdev);
> you are freeing the irq manually below and in _remove too. As it stands
> with putting the ip block in reset again on remove this should either loose
> the devm_ or you could add a devm_action that handles the reset assert
> like in [0] - registering the devm_action above where the reset is done.
> That way you could really use dev_request_irq and loose the free_irq
> calls here and in remove.
>
> [0] https://lkml.org/lkml/2015/11/8/159
I made a mistake here. I did not remove free_irq when using
devm_request_irq.

As I do not konw enough about devm_action and reset-assert , can I
remove free_irq
simply like drivers/i2c/buses/i2c-sun6i-p2wi.c used devm_request_irq and

Re: [PATCH v3 3/4] Crypto: rockchip/crypto - add crypto driver for rk3288

2015-11-12 Thread Heiko Stuebner
Hi Zain,

I was able to sucessfully test your crypto-driver, but have found some
improvements below that should probably get looked at:

Am Mittwoch, 11. November 2015, 14:35:58 schrieb Zain Wang:
> Crypto driver support:
>  ecb(aes) cbc(aes) ecb(des) cbc(des) ecb(des3_ede) cbc(des3_ede)
> You can alloc tags above in your case.
> 
> And other algorithms and platforms will be added later on.
> 
> Signed-off-by: Zain Wang 
> ---

[...]

> diff --git a/drivers/crypto/rockchip/rk3288_crypto.c 
> b/drivers/crypto/rockchip/rk3288_crypto.c
> new file mode 100644
> index 000..bb36baa
> --- /dev/null
> +++ b/drivers/crypto/rockchip/rk3288_crypto.c
> @@ -0,0 +1,392 @@

[...]

> +static irqreturn_t crypto_irq_handle(int irq, void *dev_id)

that function should probably also get a "rk_" prefix?

> +{
> + struct rk_crypto_info *dev  = platform_get_drvdata(dev_id);
> + u32 interrupt_status;
> + int err = 0;
> +
> + spin_lock(&dev->lock);
> +
> + if (irq == dev->irq) {

I'm not sure I understand that line. Interrupt handlers are only
called for the interrupt they are registered for, which would be dev->irq
in any case, so that should always be true and therefore be unnecessary?


> + interrupt_status = CRYPTO_READ(dev, RK_CRYPTO_INTSTS);
> + CRYPTO_WRITE(dev, RK_CRYPTO_INTSTS, interrupt_status);
> + if (interrupt_status & 0x0a) {
> + dev_warn(dev->dev, "DMA Error\n");
> + err = -EFAULT;
> + } else if (interrupt_status & 0x05) {
> + err = dev->update(dev);
> + }
> +
> + if (err)
> + dev->complete(dev, err);
> + }
> + spin_unlock(&dev->lock);
> + return IRQ_HANDLED;
> +}

[...]

> +static int rk_crypto_probe(struct platform_device *pdev)
> +{
> + struct resource *res;
> + struct device *dev = &pdev->dev;
> + struct rk_crypto_info *crypto_info;
> + int err = 0;
> +
> + crypto_info = devm_kzalloc(&pdev->dev,
> +sizeof(*crypto_info), GFP_KERNEL);
> + if (!crypto_info) {
> + err = -ENOMEM;
> + goto err_crypto;
> + }
> +
> + crypto_info->rst = devm_reset_control_get(dev, "crypto-rst");
> + if (IS_ERR(crypto_info->rst)) {
> + err = PTR_ERR(crypto_info->rst);
> + goto err_crypto;
> + }
> +
> + reset_control_assert(crypto_info->rst);
> + usleep_range(10, 20);
> + reset_control_deassert(crypto_info->rst);
> +
> + spin_lock_init(&crypto_info->lock);
> +
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + crypto_info->reg = devm_ioremap_resource(&pdev->dev, res);
> + if (IS_ERR(crypto_info->reg)) {
> + err = PTR_ERR(crypto_info->reg);
> + goto err_ioremap;
> + }
> +
> + crypto_info->aclk = devm_clk_get(&pdev->dev, "aclk");
> + if (IS_ERR(crypto_info->aclk)) {
> + err = PTR_ERR(crypto_info->aclk);
> + goto err_ioremap;
> + }
> +
> + crypto_info->hclk = devm_clk_get(&pdev->dev, "hclk");
> + if (IS_ERR(crypto_info->hclk)) {
> + err = PTR_ERR(crypto_info->hclk);
> + goto err_ioremap;
> + }
> +
> + crypto_info->sclk = devm_clk_get(&pdev->dev, "sclk");
> + if (IS_ERR(crypto_info->sclk)) {
> + err = PTR_ERR(crypto_info->sclk);
> + goto err_ioremap;
> + }
> +
> + crypto_info->dmaclk = devm_clk_get(&pdev->dev, "apb_pclk");
> + if (IS_ERR(crypto_info->dmaclk)) {
> + err = PTR_ERR(crypto_info->dmaclk);
> + goto err_ioremap;
> + }
> +
> + crypto_info->irq = platform_get_irq(pdev, 0);
> + if (crypto_info->irq < 0) {
> + dev_warn(crypto_info->dev,
> +  "control Interrupt is not available.\n");
> + err = crypto_info->irq;
> + goto err_ioremap;
> + }
> +
> + err = devm_request_irq(&pdev->dev, crypto_info->irq, crypto_irq_handle,
> +IRQF_SHARED, "rk-crypto", pdev);

you are freeing the irq manually below and in _remove too. As it stands
with putting the ip block in reset again on remove this should either loose
the devm_ or you could add a devm_action that handles the reset assert
like in [0] - registering the devm_action above where the reset is done.
That way you could really use dev_request_irq and loose the free_irq
calls here and in remove.

[0] https://lkml.org/lkml/2015/11/8/159

[...]

> +static int rk_crypto_remove(struct platform_device *pdev)
> +{
> + struct rk_crypto_info *crypto_tmp = platform_get_drvdata(pdev);
> +
> + rk_crypto_unregister();
> + reset_control_assert(crypto_tmp->rst);

mainly my comment from above applies, but in any case the reset-assert
should definitly happen _after_ the tasklet is killed and the irq freed,
to make sure nothing will want to access device-registers anymore.

[devm works sequentia