@@ -267,6 +267,15 @@ dpll_xa_ref_dpll_find(struct xarray *xa_refs, const struct dpll_device *dpll)
return NULL;
}
+struct dpll_pin_ref *dpll_xa_ref_dpll_first(struct xarray *xa_refs)
+{
+ struct dpll_pin_ref *ref;
+ unsigned long i = 0;
+
+ ref = xa_find(xa_refs, &i, ULONG_MAX, XA_PRESENT);
+ WARN_ON(!ref);
+ return ref;
+}
/**
* dpll_device_alloc - allocate the memory for dpll device
@@ -610,6 +619,9 @@ __dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin,
{
int ret;
+ if (WARN_ON(!ops))
+ return -EINVAL;
+
if (rclk_device_name && !pin->rclk_dev_name) {
pin->rclk_dev_name = kstrdup(rclk_device_name, GFP_KERNEL);
if (!pin->rclk_dev_name)
@@ -99,6 +99,7 @@ struct dpll_pin_ref *
dpll_xa_ref_pin_find(struct xarray *xa_refs, const struct dpll_pin *pin);
struct dpll_pin_ref *
dpll_xa_ref_dpll_find(struct xarray *xa_refs, const struct dpll_device *dpll);
+struct dpll_pin_ref *dpll_xa_ref_dpll_first(struct xarray *xa_refs);
extern struct xarray dpll_device_xa;
extern struct xarray dpll_pin_xa;
extern struct mutex dpll_device_xa_lock;
@@ -134,18 +134,11 @@ dpll_msg_add_pin_on_dpll_state(struct sk_buff *msg, const struct dpll_pin *pin,
static int
dpll_msg_add_pin_direction(struct sk_buff *msg, const struct dpll_pin *pin,
+ struct dpll_pin_ref *ref,
struct netlink_ext_ack *extack)
{
enum dpll_pin_direction direction;
- struct dpll_pin_ref *ref;
- unsigned long i;
- xa_for_each((struct xarray *)&pin->dpll_refs, i, ref) {
- if (ref && ref->ops && ref->dpll)
- break;
- }
- if (!ref || !ref->ops || !ref->dpll)
- return -ENODEV;
if (!ref->ops->direction_get)
return -EOPNOTSUPP;
if (ref->ops->direction_get(pin, ref->dpll, &direction, extack))
@@ -158,19 +151,12 @@ dpll_msg_add_pin_direction(struct sk_buff *msg, const struct dpll_pin *pin,
static int
dpll_msg_add_pin_freq(struct sk_buff *msg, const struct dpll_pin *pin,
- struct netlink_ext_ack *extack, bool dump_any_freq)
+ struct dpll_pin_ref *ref, struct netlink_ext_ack *extack,
+ bool dump_any_freq)
{
enum dpll_pin_freq_supp fs;
- struct dpll_pin_ref *ref;
- unsigned long i;
u32 freq;
- xa_for_each((struct xarray *)&pin->dpll_refs, i, ref) {
- if (ref && ref->ops && ref->dpll)
- break;
- }
- if (!ref || !ref->ops || !ref->dpll)
- return -ENODEV;
if (!ref->ops->frequency_get)
return -EOPNOTSUPP;
if (ref->ops->frequency_get(pin, ref->dpll, &freq, extack))
@@ -325,10 +311,11 @@ dpll_cmd_pin_on_dpll_get(struct sk_buff *msg, struct dpll_pin *pin,
return -EMSGSIZE;
if (nla_put_u32(msg, DPLL_A_PIN_DPLL_CAPS, pin->prop.capabilities))
return -EMSGSIZE;
- ret = dpll_msg_add_pin_direction(msg, pin, extack);
+ ref = dpll_xa_ref_dpll_first(&pin->dpll_refs);
+ ret = dpll_msg_add_pin_direction(msg, pin, ref, extack);
if (ret)
return ret;
- ret = dpll_msg_add_pin_freq(msg, pin, extack, true);
+ ret = dpll_msg_add_pin_freq(msg, pin, ref, extack, true);
if (ret && ret != -EOPNOTSUPP)
return ret;
ref = dpll_xa_ref_dpll_find(&pin->dpll_refs, dpll);
@@ -355,6 +342,7 @@ static int
__dpll_cmd_pin_dump_one(struct sk_buff *msg, struct dpll_pin *pin,
struct netlink_ext_ack *extack, bool dump_dpll)
{
+ struct dpll_pin_ref *ref;
int ret;
if (nla_put_u32(msg, DPLL_A_PIN_IDX, pin->dev_driver_id))
@@ -363,10 +351,11 @@ __dpll_cmd_pin_dump_one(struct sk_buff *msg, struct dpll_pin *pin,
return -EMSGSIZE;
if (nla_put_u8(msg, DPLL_A_PIN_TYPE, pin->prop.type))
return -EMSGSIZE;
- ret = dpll_msg_add_pin_direction(msg, pin, extack);
+ ref = dpll_xa_ref_dpll_first(&pin->dpll_refs);
+ ret = dpll_msg_add_pin_direction(msg, pin, ref, extack);
if (ret)
return ret;
- ret = dpll_msg_add_pin_freq(msg, pin, extack, true);
+ ret = dpll_msg_add_pin_freq(msg, pin, ref, extack, true);
if (ret && ret != -EOPNOTSUPP)
return ret;
ret = dpll_msg_add_pins_on_pin(msg, pin, extack);
@@ -920,7 +909,8 @@ dpll_event_device_change(struct sk_buff *msg, struct dpll_device *dpll,
ret = dpll_msg_add_temp(msg, dpll, NULL);
break;
case DPLL_A_PIN_FREQUENCY:
- ret = dpll_msg_add_pin_freq(msg, pin, NULL, false);
+ ref = dpll_xa_ref_dpll_find(&pin->dpll_refs, dpll);
+ ret = dpll_msg_add_pin_freq(msg, pin, ref, NULL, false);
break;
case DPLL_A_PIN_PRIO:
ref = dpll_xa_ref_dpll_find(&pin->dpll_refs, dpll);