2015-04-27 23:02 GMT+09:00 Nicolae, Anda-maria <[email protected]>:
> However after looking at the code I got different question. You are
> reading here and in few other places the RT9455_REG_IRQ1. Isn't the
> register auto-cleared?
>
> No, RT9455_REG_IRQ1 is not cleared after reading. Let me give you an example. 
> Suppose the battery is missing, so BATAB bit is set. This bit remains set 
> until the battery is reconnected to the charger, independent of the number of 
> i2c_reads over RT9455_REG_IRQ1. Unfortunately, no interrupt is triggered when 
> the battery is reconnected (and BATAB bit is cleared).

OK, I got it.

>
> (...)
>
>>> +
>>> +#if IS_ENABLED(CONFIG_USB_PHY)
>>> +       info->usb_phy = usb_get_phy(USB_PHY_TYPE_USB2);
>>> +       if (IS_ERR_OR_NULL(info->usb_phy)) {
>>> +               dev_err(dev, "Failed to get USB transceiver\n");
>>> +       } else {
>>> +               info->nb.notifier_call = rt9455_usb_event;
>>> +               ret = usb_register_notifier(info->usb_phy, &info->nb);
>>> +               if (ret) {
>>> +                       dev_err(dev, "Failed to register USB notifier\n");
>>> +                       usb_put_phy(info->usb_phy);
>>> +               }
>>> +       }
>>> +#endif
>>> +
>>> +       INIT_DELAYED_WORK(&info->pwr_rdy_work, 
>>> rt9455_pwr_rdy_work_callback);
>>> +       INIT_DELAYED_WORK(&info->max_charging_time_work,
>>> +                         rt9455_max_charging_time_work_callback);
>>> +       INIT_DELAYED_WORK(&info->batt_presence_work,
>>> +                         rt9455_batt_presence_work_callback);
>>
>> Maybe any of these could be made as DEFERRABLE_WORK? Just thinking out 
>> loud...
>>
>> I cannot use DEFERRABLE_WORK instead of DELAYED_WORK. DEFERRABLE_WORK runs 
>> in interrupt context, while DELAYED_WORK runs in process context. All 
>> handlers for DELAYED_WORK from the driver perform read/write operations via 
>> I2C, which may sleep. This is the reason why DELAYED_WORK is used.
>
> AFAIK, the context is the same. The only difference is the type of
> timer used for scheduling the work. In case of deferrable timer it
> won't wake up a sleeping CPU. Which means that it may be executed some
> unspecified time in the future. This has energy conserving benefits
> but may not be appropriate for your case because you could want to
> poll the battery status in exact intervals.
>
> Just to understand correctly, you mean that if I use DEFERRABLE_WORK, I will 
> not get kernel panic with message "scheduling while atomic"? This is what 
> happens if I use timers and I thought that I would get the same result with 
> DEFERRABLE_WORK. Actually, the timers are not critical and status of the 
> charger may be checked some fraction of a second later.

You shouldn't get that panic. Deferrable work is used in few other
similar places. As you can check in the include/linux/workqueue.h file
the timers are used in both cases. The INIT_DELAYED_WORK already uses
a flag for timers - TIMER_IRQSAFE. However for deferrable work it uses
additional flag - deferrable timer.

Unfortunately the difference may not be a "fraction of a second
later". Actually the difference may be as much as 1 second later for
the fully non-tickless system. If system is truly idle, the deferrable
timers (and work) may not fire for long time. So this must be
considered.

Best regards,
Krzysztof
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to