On 2/13/21 7:59 AM, Hans de Goede wrote: > Hi, > > On 2/13/21 4:27 PM, Guenter Roeck wrote: >> On 2/13/21 7:03 AM, Hans de Goede wrote: >> [ ... ] >>> >>> I think something like this should work: >>> >>> static int devm_delayed_work_autocancel(struct device *dev, struct delayed_work *w, >>> void (*worker)(struct work_struct *work)) { >>> INIT_DELAYED_WORK(w, worker); >>> return devm_add_action(dev, (void (*action)(void *))cancel_delayed_work_sync, w); >>> } >>> >>> I'm not sure about the cast, that may need something like this instead: >>> >>> typedef void (*devm_action_func)(void *); >>> >>> static int devm_delayed_work_autocancel(struct device *dev, struct delayed_work *w, >>> void (*worker)(struct work_struct *work)) { >>> INIT_DELAYED_WORK(w, worker); >>> return devm_add_action(dev, (devm_action_func)cancel_delayed_work_sync, w); >> >> Unfortunately, you can not type cast function pointers in C. It is against the C ABI. >> I am sure it is done in a few places in the kernel anyway, but those are wrong. > > I see, bummer. > >> This is the reason why many calls to devm_add_action() point to functions such as >> >> static void visconti_clk_disable_unprepare(void *data) >> { >> clk_disable_unprepare(data); >> } >> >> which could otherwise be handled using typecasts. > > Hmm, wouldn't something like this be a candidate for adding a: > > devm_clk_prepare_enable() helper? > > This seems better then having the driver(s) make + error check separate > clk_prepare_enable() + devm_add_action_or_reset() calls ? > I don't really want to go there anymore. The maintainer rejected it several times. Guenter