On Tue, 2020-08-25 at 21:30 +0300, Abel Vesa wrote:
[...]
> >     if (assert)
> >             pm_runtime_get_sync();
> >     spin_lock_irqsave();
> >     /* ... */
> >     spin_unlock_irqrestore();
> >     if (assert && asserted_before)
> >             pm_runtime_put();
> > 
> 
> On a second thought this doesn't work because, for the first assertion,
> the runtime put will never be called, if the asserted_before does not count
> the current assertion.

I'm not sure I follow. The first assert will increment device usage
0 -> 1, all others asserts will just temporarily increment and decrement
1 -> 2 -> 1. Isn't this just missing one
        if (!assert && !asserted_after)
                pm_runtime_put()
to do the last deassert 1 -> 0 transition?

> If it counts the current assertion, then every assertion
> will end with runtime put. None of these options work here.
>
> How about the following:
>
>       if (assert && !test_and_set_bit(1, &drvdata->rst_hws[id].asserted))     
>               pm_runtime_get_sync(rcdev->dev);                                
>                                                                         
>       spin_lock_irqsave(&drvdata->lock, flags);                               
>                                                                         
>       reg = readl(reg_addr);                                                  
>       if (assert)                                                             
>               writel(reg & ~(mask << shift), reg_addr);                       
>       else                                                                    
>               writel(reg | (mask << shift), reg_addr);                        
>                                                                         
>       spin_unlock_irqrestore(&drvdata->lock, flags);                          
>                                                                         
>       if (!assert && test_and_clear_bit(1, &drvdata->rst_hws[id].asserted))   
>               pm_runtime_put(rcdev->dev);                                     
>                                                                         
> This would only call the get_sync/put once for each reset bit.

Yes, that should work. I think it is a much better idea, no more looping
through the entire reset control array.

regards
Philipp

Reply via email to