struct netlink_ext_ack *extack)
{
const struct dpll_device_ops *ops = dpll_device_ops(dpll);
+ DECLARE_BITMAP(modes, DPLL_MODE_MAX + 1) = { 0 };
enum dpll_mode mode;
int ret;
- /* No mode change is supported now, so the only supported mode is the
- * one obtained by mode_get().
- */
+ if (ops->supported_modes_get) {
+ ret = ops->supported_modes_get(dpll, dpll_priv(dpll), modes,
+ extack);
+ if (ret)
+ return ret;
+ } else {
+ /* If the supported modes are not reported by the driver, the
+ * only supported mode is the one obtained by mode_get().
+ */
+ ret = ops->mode_get(dpll, dpll_priv(dpll), &mode, extack);
+ if (ret)
+ return ret;
- ret = ops->mode_get(dpll, dpll_priv(dpll), &mode, extack);
- if (ret)
- return ret;
- if (nla_put_u32(msg, DPLL_A_MODE_SUPPORTED, mode))
- return -EMSGSIZE;
+ __set_bit(mode, modes);
+ }
+
+ for_each_set_bit(mode, modes, DPLL_MODE_MAX + 1)
+ if (nla_put_u32(msg, DPLL_A_MODE_SUPPORTED, mode))
+ return -EMSGSIZE;
return 0;
}
struct dpll_device_ops {
int (*mode_get)(const struct dpll_device *dpll, void *dpll_priv,
enum dpll_mode *mode, struct netlink_ext_ack *extack);
+ int (*supported_modes_get)(const struct dpll_device *dpll,
+ void *dpll_priv, unsigned long *modes,
+ struct netlink_ext_ack *extack);
int (*lock_status_get)(const struct dpll_device *dpll, void *dpll_priv,
enum dpll_lock_status *status,
enum dpll_lock_status_error *status_error,