2019-09-22 18:48:12

by Fabien DESSENNE

[permalink] [raw]
Subject: [PATCH] irqchip/stm32-exti: Use the hwspin_lock_timeout_in_atomic() API

Now that the hwspin_lock_timeout_in_atomic() API is available use it.

Signed-off-by: Fabien Dessenne <[email protected]>
---
drivers/irqchip/irq-stm32-exti.c | 65 +++++++++++++---------------------------
1 file changed, 20 insertions(+), 45 deletions(-)

diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c
index e00f2fa..7fc0d1f 100644
--- a/drivers/irqchip/irq-stm32-exti.c
+++ b/drivers/irqchip/irq-stm32-exti.c
@@ -25,7 +25,6 @@
#define IRQS_PER_BANK 32

#define HWSPNLCK_TIMEOUT 1000 /* usec */
-#define HWSPNLCK_RETRY_DELAY 100 /* usec */

struct stm32_exti_bank {
u32 imr_ofst;
@@ -277,55 +276,24 @@ static int stm32_exti_set_type(struct irq_data *d,
return 0;
}

-static int stm32_exti_hwspin_lock(struct stm32_exti_chip_data *chip_data)
-{
- int ret, timeout = 0;
-
- if (!chip_data->host_data->hwlock)
- return 0;
-
- /*
- * Use the x_raw API since we are under spin_lock protection.
- * Do not use the x_timeout API because we are under irq_disable
- * mode (see __setup_irq())
- */
- do {
- ret = hwspin_trylock_raw(chip_data->host_data->hwlock);
- if (!ret)
- return 0;
-
- udelay(HWSPNLCK_RETRY_DELAY);
- timeout += HWSPNLCK_RETRY_DELAY;
- } while (timeout < HWSPNLCK_TIMEOUT);
-
- if (ret == -EBUSY)
- ret = -ETIMEDOUT;
-
- if (ret)
- pr_err("%s can't get hwspinlock (%d)\n", __func__, ret);
-
- return ret;
-}
-
-static void stm32_exti_hwspin_unlock(struct stm32_exti_chip_data *chip_data)
-{
- if (chip_data->host_data->hwlock)
- hwspin_unlock_raw(chip_data->host_data->hwlock);
-}
-
static int stm32_irq_set_type(struct irq_data *d, unsigned int type)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
struct stm32_exti_chip_data *chip_data = gc->private;
const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank;
+ struct hwspinlock *hwlock = chip_data->host_data->hwlock;
u32 rtsr, ftsr;
int err;

irq_gc_lock(gc);

- err = stm32_exti_hwspin_lock(chip_data);
- if (err)
- goto unlock;
+ if (hwlock) {
+ err = hwspin_lock_timeout_in_atomic(hwlock, HWSPNLCK_TIMEOUT);
+ if (err) {
+ pr_err("%s can't get hwspinlock (%d)\n", __func__, err);
+ goto unlock;
+ }
+ }

rtsr = irq_reg_readl(gc, stm32_bank->rtsr_ofst);
ftsr = irq_reg_readl(gc, stm32_bank->ftsr_ofst);
@@ -338,7 +306,8 @@ static int stm32_irq_set_type(struct irq_data *d, unsigned int type)
irq_reg_writel(gc, ftsr, stm32_bank->ftsr_ofst);

unspinlock:
- stm32_exti_hwspin_unlock(chip_data);
+ if (hwlock)
+ hwspin_unlock_in_atomic(hwlock);
unlock:
irq_gc_unlock(gc);

@@ -504,15 +473,20 @@ static int stm32_exti_h_set_type(struct irq_data *d, unsigned int type)
{
struct stm32_exti_chip_data *chip_data = irq_data_get_irq_chip_data(d);
const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank;
+ struct hwspinlock *hwlock = chip_data->host_data->hwlock;
void __iomem *base = chip_data->host_data->base;
u32 rtsr, ftsr;
int err;

raw_spin_lock(&chip_data->rlock);

- err = stm32_exti_hwspin_lock(chip_data);
- if (err)
- goto unlock;
+ if (hwlock) {
+ err = hwspin_lock_timeout_in_atomic(hwlock, HWSPNLCK_TIMEOUT);
+ if (err) {
+ pr_err("%s can't get hwspinlock (%d)\n", __func__, err);
+ goto unlock;
+ }
+ }

rtsr = readl_relaxed(base + stm32_bank->rtsr_ofst);
ftsr = readl_relaxed(base + stm32_bank->ftsr_ofst);
@@ -525,7 +499,8 @@ static int stm32_exti_h_set_type(struct irq_data *d, unsigned int type)
writel_relaxed(ftsr, base + stm32_bank->ftsr_ofst);

unspinlock:
- stm32_exti_hwspin_unlock(chip_data);
+ if (hwlock)
+ hwspin_unlock_in_atomic(hwlock);
unlock:
raw_spin_unlock(&chip_data->rlock);

--
2.7.4


2019-12-03 10:31:34

by Fabien DESSENNE

[permalink] [raw]
Subject: Re: [PATCH] irqchip/stm32-exti: Use the hwspin_lock_timeout_in_atomic() API

Hi


It looks like this patch got lost. Can anyone have a look at it?

BR

Fabien


On 20/09/2019 5:00 PM, Fabien Dessenne wrote:
> Now that the hwspin_lock_timeout_in_atomic() API is available use it.
>
> Signed-off-by: Fabien Dessenne <[email protected]>
> ---
> drivers/irqchip/irq-stm32-exti.c | 65 +++++++++++++---------------------------
> 1 file changed, 20 insertions(+), 45 deletions(-)
>
> diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c
> index e00f2fa..7fc0d1f 100644
> --- a/drivers/irqchip/irq-stm32-exti.c
> +++ b/drivers/irqchip/irq-stm32-exti.c
> @@ -25,7 +25,6 @@
> #define IRQS_PER_BANK 32
>
> #define HWSPNLCK_TIMEOUT 1000 /* usec */
> -#define HWSPNLCK_RETRY_DELAY 100 /* usec */
>
> struct stm32_exti_bank {
> u32 imr_ofst;
> @@ -277,55 +276,24 @@ static int stm32_exti_set_type(struct irq_data *d,
> return 0;
> }
>
> -static int stm32_exti_hwspin_lock(struct stm32_exti_chip_data *chip_data)
> -{
> - int ret, timeout = 0;
> -
> - if (!chip_data->host_data->hwlock)
> - return 0;
> -
> - /*
> - * Use the x_raw API since we are under spin_lock protection.
> - * Do not use the x_timeout API because we are under irq_disable
> - * mode (see __setup_irq())
> - */
> - do {
> - ret = hwspin_trylock_raw(chip_data->host_data->hwlock);
> - if (!ret)
> - return 0;
> -
> - udelay(HWSPNLCK_RETRY_DELAY);
> - timeout += HWSPNLCK_RETRY_DELAY;
> - } while (timeout < HWSPNLCK_TIMEOUT);
> -
> - if (ret == -EBUSY)
> - ret = -ETIMEDOUT;
> -
> - if (ret)
> - pr_err("%s can't get hwspinlock (%d)\n", __func__, ret);
> -
> - return ret;
> -}
> -
> -static void stm32_exti_hwspin_unlock(struct stm32_exti_chip_data *chip_data)
> -{
> - if (chip_data->host_data->hwlock)
> - hwspin_unlock_raw(chip_data->host_data->hwlock);
> -}
> -
> static int stm32_irq_set_type(struct irq_data *d, unsigned int type)
> {
> struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
> struct stm32_exti_chip_data *chip_data = gc->private;
> const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank;
> + struct hwspinlock *hwlock = chip_data->host_data->hwlock;
> u32 rtsr, ftsr;
> int err;
>
> irq_gc_lock(gc);
>
> - err = stm32_exti_hwspin_lock(chip_data);
> - if (err)
> - goto unlock;
> + if (hwlock) {
> + err = hwspin_lock_timeout_in_atomic(hwlock, HWSPNLCK_TIMEOUT);
> + if (err) {
> + pr_err("%s can't get hwspinlock (%d)\n", __func__, err);
> + goto unlock;
> + }
> + }
>
> rtsr = irq_reg_readl(gc, stm32_bank->rtsr_ofst);
> ftsr = irq_reg_readl(gc, stm32_bank->ftsr_ofst);
> @@ -338,7 +306,8 @@ static int stm32_irq_set_type(struct irq_data *d, unsigned int type)
> irq_reg_writel(gc, ftsr, stm32_bank->ftsr_ofst);
>
> unspinlock:
> - stm32_exti_hwspin_unlock(chip_data);
> + if (hwlock)
> + hwspin_unlock_in_atomic(hwlock);
> unlock:
> irq_gc_unlock(gc);
>
> @@ -504,15 +473,20 @@ static int stm32_exti_h_set_type(struct irq_data *d, unsigned int type)
> {
> struct stm32_exti_chip_data *chip_data = irq_data_get_irq_chip_data(d);
> const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank;
> + struct hwspinlock *hwlock = chip_data->host_data->hwlock;
> void __iomem *base = chip_data->host_data->base;
> u32 rtsr, ftsr;
> int err;
>
> raw_spin_lock(&chip_data->rlock);
>
> - err = stm32_exti_hwspin_lock(chip_data);
> - if (err)
> - goto unlock;
> + if (hwlock) {
> + err = hwspin_lock_timeout_in_atomic(hwlock, HWSPNLCK_TIMEOUT);
> + if (err) {
> + pr_err("%s can't get hwspinlock (%d)\n", __func__, err);
> + goto unlock;
> + }
> + }
>
> rtsr = readl_relaxed(base + stm32_bank->rtsr_ofst);
> ftsr = readl_relaxed(base + stm32_bank->ftsr_ofst);
> @@ -525,7 +499,8 @@ static int stm32_exti_h_set_type(struct irq_data *d, unsigned int type)
> writel_relaxed(ftsr, base + stm32_bank->ftsr_ofst);
>
> unspinlock:
> - stm32_exti_hwspin_unlock(chip_data);
> + if (hwlock)
> + hwspin_unlock_in_atomic(hwlock);
> unlock:
> raw_spin_unlock(&chip_data->rlock);
>