diff --git a/drivers/dpll/dpll_core.c b/drivers/dpll/dpll_core.c index 0b5f499cfc4d5..f56a283ea35de 100644 --- a/drivers/dpll/dpll_core.c +++ b/drivers/dpll/dpll_core.c @@ -190,6 +190,7 @@ void dpll_init_pin(struct dpll_pin **pin, enum dpll_pin_type type, (*pin)->type = type; (*pin)->priv = priv; (*pin)->id = id; + refcount_set(&((*pin)->ref_count), 0); if (name) snprintf((*pin)->name, PIN_NAME_LENGTH, "%s", name); else @@ -241,7 +242,7 @@ int dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin) mutex_lock(&dpll->lock); ret = pin_register(&dpll->pins, pin); if (!ret) { - pin->ref_count++; + refcount_inc(&pin->ref_count); change_pin_count(dpll, pin, true); xa_set_mark(&dpll->pins, dpll->id, DPLL_REGISTERED); } @@ -287,9 +288,7 @@ int dpll_pin_deregister(struct dpll_device *dpll, struct dpll_pin *pin) mutex_unlock(&dpll->lock); if (!ret) { - mutex_lock(&pin->lock); - pin->ref_count--; - mutex_unlock(&pin->lock); + refcount_dec(&pin->ref_count); dpll_notify_pin_deregister(dpll->id, pin->id); } @@ -311,7 +310,7 @@ void dpll_pin_free(struct dpll_device *dpll, struct dpll_pin *pin) if (!pin_found) return; - if (pin->ref_count) + if (refcount_read(&pin->ref_count) != 0) return; xa_destroy(&pin->muxed_pins); @@ -333,7 +332,7 @@ void dpll_muxed_pin_free(struct dpll_pin *parent_pin, struct dpll_pin *pin) if (!pin_found) return; - if (pin->ref_count) + if (refcount_read(&pin->ref_count) != 0) return; xa_destroy(&pin->muxed_pins); @@ -348,9 +347,7 @@ int dpll_muxed_pin_register(struct dpll_pin *parent_pin, struct dpll_pin *pin) ret = pin_register(&parent_pin->muxed_pins, pin); if (!ret) { - mutex_lock(&pin->lock); - pin->ref_count++; - mutex_unlock(&pin->lock); + refcount_inc(&pin->ref_count); dpll_notify_muxed_pin_register(parent_pin, pin->id); } @@ -370,9 +367,7 @@ int dpll_muxed_pin_deregister(struct dpll_pin *parent_pin, struct dpll_pin *pin) mutex_unlock(&parent_pin->lock); if (!ret) { - mutex_lock(&pin->lock); - pin->ref_count--; - mutex_unlock(&pin->lock); + refcount_dec(&pin->ref_count); dpll_notify_muxed_pin_deregister(parent_pin, pin->id); } diff --git a/drivers/dpll/dpll_core.h b/drivers/dpll/dpll_core.h index 7ff64df735d93..7db9b23b4a084 100644 --- a/drivers/dpll/dpll_core.h +++ b/drivers/dpll/dpll_core.h @@ -36,7 +36,7 @@ struct dpll_pin { int id; enum dpll_pin_type type; - int ref_count; + refcount_t ref_count; struct dpll_pin_ops *ops; struct mutex lock; void *priv; diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c index 5c43da0b4d7dd..6b081d19cf0f3 100644 --- a/drivers/dpll/dpll_netlink.c +++ b/drivers/dpll/dpll_netlink.c @@ -133,8 +133,8 @@ static int __dpll_cmd_dump_sources(struct dpll_device *dpll, } ret = 0; } - if (pin->ops->get_prio) { - prio = pin->ops->get_prio(pin, dpll); + if (dpll->ops->get_prio) { + prio = dpll->ops->get_prio(dpll, pin); if (nla_put_u32(msg, DPLLA_SOURCE_PIN_PRIO, prio)) { nla_nest_cancel(msg, src_attr); ret = -EMSGSIZE; @@ -393,10 +393,10 @@ static int dpll_genl_cmd_set_source_prio(struct sk_buff *skb, struct genl_info * mutex_lock(&dpll->lock); pin = dpll_pin_get_by_id(dpll, src_id); - if (!pin || !pin->ops || !pin->ops->set_prio) + if (!dpll->ops || !dpll->ops->set_prio) ret = -EOPNOTSUPP; else - ret = pin->ops->set_prio(pin, dpll, prio); + ret = dpll->ops->set_prio(dpll, pin, prio); mutex_unlock(&dpll->lock); if (!ret) diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h index b2802309462e5..d62c4318aa8ff 100644 --- a/drivers/net/ethernet/intel/ice/ice.h +++ b/drivers/net/ethernet/intel/ice/ice.h @@ -610,7 +610,8 @@ struct ice_pf { #define ICE_VF_AGG_NODE_ID_START 65 #define ICE_MAX_VF_AGG_NODES 32 struct ice_agg_node vf_agg_node[ICE_MAX_VF_AGG_NODES]; - struct ice_synce synce; + struct ice_dpll dpll_synce; + struct ice_dpll dpll_ptp; }; struct ice_netdev_priv { diff --git a/drivers/net/ethernet/intel/ice/ice_synce.c b/drivers/net/ethernet/intel/ice/ice_synce.c index 39c1a1be222d7..5e2b184339551 100644 --- a/drivers/net/ethernet/intel/ice/ice_synce.c +++ b/drivers/net/ethernet/intel/ice/ice_synce.c @@ -361,13 +361,13 @@ static int ice_synce_get_src_select_supported(struct dpll_device *dpll, int mode /** * ice_synce_get_source_prio * @dpll: registered dpll pointer - * @id: source index + * @pin: dpll pin object * * dpll subsystem callback. * Get source priority value. * Return: source priority value */ -static int ice_synce_get_source_prio(struct dpll_pin *pin, struct dpll_device *dpll) +static int ice_synce_get_source_prio(struct dpll_device *dpll, struct dpll_pin *pin) { struct ice_pf *pf = dpll_priv(dpll); u8 idx = (u8)pin_id(pin); @@ -389,7 +389,7 @@ static int ice_synce_get_source_prio(struct dpll_pin *pin, struct dpll_device *d /** * ice_synce_set_source_prio * @dpll: registered dpll pointer - * @id: source index + * @pin: dpll pin object * @prio: expected priority value * * dpll subsystem callback. @@ -398,8 +398,8 @@ static int ice_synce_get_source_prio(struct dpll_pin *pin, struct dpll_device *d * * 0 - success * * negative - failure */ -static int ice_synce_set_source_prio(struct dpll_pin *pin, - struct dpll_device *dpll, int prio) +static int ice_synce_set_source_prio(struct dpll_device *dpll, + struct dpll_pin *pin, int prio) { struct ice_pf *pf = dpll_priv(dpll); u8 idx, priov = (u8)prio; @@ -431,25 +431,25 @@ static int ice_synce_set_source_prio(struct dpll_pin *pin, return ret; } -static struct dpll_pin_ops ice_synce_source_ops = { - .get_type = ice_synce_get_source_type, - .set_type = ice_synce_set_source_type, - .is_type_supported = ice_synce_get_source_supported, - .get_prio = ice_synce_get_source_prio, - .set_prio = ice_synce_set_source_prio, +static struct dpll_pin_ops ice_dpll_source_ops = { + .get_type = ice_dpll_get_source_type, + .set_type = ice_dpll_set_source_type, + .is_type_supported = ice_dpll_get_source_supported, }; -static struct dpll_pin_ops ice_synce_output_ops = { - .get_type = ice_synce_get_output_type, - .set_type = ice_synce_set_output_type, - .is_type_supported = ice_synce_get_output_supported, +static struct dpll_pin_ops ice_dpll_output_ops = { + .get_type = ice_dpll_get_output_type, + .set_type = ice_dpll_set_output_type, + .is_type_supported = ice_dpll_get_output_supported, }; -static struct dpll_device_ops ice_synce_dpll_ops = { - .get_status = ice_synce_get_status, - .get_lock_status = ice_synce_get_lock_status, - .get_source_select_mode = ice_synce_get_source_select_mode, - .get_source_select_mode_supported = ice_synce_get_src_select_supported, +static struct dpll_device_ops ice_dpll_ops = { + .get_status = ice_dpll_get_status, + .get_lock_status = ice_dpll_get_lock_status, + .get_source_select_mode = ice_dpll_get_source_select_mode, + .get_source_select_mode_supported = ice_dpll_get_src_select_supported, + .get_prio = ice_dpll_get_source_prio, + .set_prio = ice_dpll_set_source_prio, }; /** @@ -653,9 +653,9 @@ static void ice_synce_release_pins(struct dpll_device *dpll, * * 0 - success * * negative - error */ -static int ice_synce_register_pins(struct ice_pf *pf, struct dpll_device *dpll, - struct ice_synce_pin *pins, int count, - bool inputs) +static int ice_dpll_register_pins(struct ice_pf *pf, struct dpll_device *dpll, + struct ice_synce_pin *pins, int count, + bool inputs) { struct dpll_pin_ops *ops; enum dpll_pin_type type; @@ -672,17 +672,19 @@ static int ice_synce_register_pins(struct ice_pf *pf, struct dpll_device *dpll, for (i = 0; i < count; i++) { dpll_init_pin(&pins->pin, type, ops, pf, NULL, i); - dpll_pin_register(dpll, pins->pin); + ret = dpll_pin_register(dpll, pins->pin); if (ret) { ice_synce_release_pins(dpll, pins, i + 1); } + + dev_err(ice_pf_to_dev(pf), "abc\n"); } return 0; } /** - * ice_synce_init_info + * ice_dpll_init_info * @pf: Board private structure * * Acquire (from HW) and set basic dpll information (on pf->synce struct). @@ -691,41 +693,32 @@ static int ice_synce_register_pins(struct ice_pf *pf, struct dpll_device *dpll, * * 0 - success * * negative - AQ error */ -static int ice_synce_init_info(struct ice_pf *pf) +static int ice_dpll_init_info(struct ice_pf *pf, int dpll_idx) { struct ice_aqc_get_cgu_abilities abilities; - struct ice_synce *se = &pf->synce; + struct ice_dpll *se = &pf->dpll; struct ice_hw *hw = &pf->hw; int ret, alloc_size; - ret = ice_aq_get_cgu_abilities(hw, &abilities); - if (ret) { - dev_err(ice_pf_to_dev(pf), - "err:%d %s failed to read cgu abilities\n", - ret, ice_aq_str(hw->adminq.sq_last_status)); - return ret; - } - se->dpll_idx = abilities.synce_dpll_idx; - se->num_inputs = abilities.num_inputs; alloc_size = sizeof(*se->inputs) * se->num_inputs; se->inputs = kmalloc(alloc_size, GFP_KERNEL); if (!se->inputs) return -ENOMEM; - ret = ice_synce_init_pins(hw, true, se->num_inputs, se->inputs, - se->dpll_idx); + ret = ice_dpll_init_pins(hw, true, se->num_inputs, se->inputs, + dpll_idx); if (ret) goto release_info; - se->num_outputs = abilities.num_outputs; + alloc_size = sizeof(*se->outputs) * se->num_outputs; se->outputs = kmalloc(alloc_size, GFP_KERNEL); if (!se->outputs) goto release_info; - ret = ice_synce_init_pins(hw, false, se->num_outputs, se->outputs, - se->dpll_idx); + ret = ice_dpll_init_pins(hw, false, se->num_outputs, se->outputs, + dpll_idx); if (ret) goto release_info; - dev_info(ice_pf_to_dev(pf), "SyncE dpll init: inputs:%u, outputs:%u\n", - abilities.num_inputs, abilities.num_outputs); + dev_info(ice_pf_to_dev(pf), "Dpll%d init: inputs:%u, outputs:%u\n", + dpll_idx, se->num_inputs, se->num_outputs); return 0; @@ -734,6 +727,37 @@ static int ice_synce_init_info(struct ice_pf *pf) return ret; } +static int ice_dpll_init(struct ice_pf *pf) +{ + struct ice_aqc_get_cgu_abilities abilities; + struct ice_dpll *se = &pf->dpll_synce; + struct ice_dpll *ptp = &pf->dpll_ptp; + int ret, alloc_size; + + ret = ice_aq_get_cgu_abilities(hw, &abilities); + if (ret) { + dev_err(ice_pf_to_dev(pf), + "err: %d %s failed to read cgu abilities\n", + ret, ice_aq_str(hw->adminq.sq_last_status)); + return ret; + } + + se->dpll_idx = abilities.synce_dpll_idx; + se->num_inputs = abilities.num_inputs; + se->num_outputs = abilities.num_outputs; + + ptp->dpll = abilities.ptp_dpll_idx; + ptp->num_inputs = abilities.num_inputs; + se->num_outputs = abilities.num_outputs; + + ret = ice_dpll_init_info(pf, se->dpll_idx); + if (ret) { + dev_err(ice_pf_to_dev(pf), + "err: %d failed to initialize pins of dpll%d\n", + ret, se->dpll_idx); + } + return 0; +} /** * ice_synce_init_dpll * @pf: Board private structure @@ -744,22 +768,36 @@ static int ice_synce_init_info(struct ice_pf *pf) * * 0 - success * * -ENOMEM - allocation fails */ -static int ice_synce_init_dpll(struct ice_pf *pf) +static int ice_dpll_alloc_dplls(struct ice_pf *pf) { struct device *dev = ice_pf_to_dev(pf); - struct ice_synce *se = &pf->synce; + struct ice_dpll *se = &pf->dpll_synce; + struct ice_dpll *ptp = &pf->dpll_ptp; + char name[DPLL_NAME_LENGTH]; snprintf(name, DPLL_NAME_LENGTH, "%s-SyncE-%s", dev_driver_string(dev), dev_name(dev)); - se->dpll = dpll_device_alloc(&ice_synce_dpll_ops, name, pf); + se->dpll = dpll_device_alloc(&ice_dpll_ops, name, pf); if (!se->dpll) { dev_err(ice_pf_to_dev(pf), "dpll_device_alloc failed\n"); return -ENOMEM; } + dpll_device_register(se->dpll); + snprintf(name, DPLL_NAME_LENGTH, "%s-PTP-%s", + dev_driver_string(dev), dev(name)); + + ptp->dpll = dpll_device_alloc(&ice_dpll_ops, name, pf); + if(!ptp->dpll) { + dev_err(ice_pf_to_dev(pf), "dpll_device_alloc failed \n"); + return -ENOMEM; + } + + dpll_device_register(ptp->dpll); + return 0; } @@ -773,7 +811,7 @@ static int ice_synce_init_dpll(struct ice_pf *pf) * * 0 - success * * negative - AQ failure */ -static int ice_synce_update_dpll_state(struct ice_pf *pf, +static int ice_dpll_update_state(struct ice_pf *pf, enum ice_cgu_state last_state) { struct ice_synce *se = &pf->synce; @@ -838,7 +876,7 @@ static void ice_synce_periodic_work(struct kthread_work *work) * * 0 - success * * negative - create worker failure */ -static int ice_synce_init_dpll_worker(struct ice_pf *pf) +static int ice_dpll_init_synce_worker(struct ice_pf *pf) { struct ice_synce *se = &pf->synce; struct kthread_worker *kworker; @@ -867,42 +905,42 @@ static int ice_synce_init_dpll_worker(struct ice_pf *pf) * * 0 - success * * negative - init failure */ -int ice_synce_init(struct ice_pf *pf) +int ice_dpll_init(struct ice_pf *pf) { int err; - mutex_init(&pf->synce.lock); - mutex_lock(&pf->synce.lock); + mutex_init(&pf->dpll_synce.lock); + mutex_lock(&pf->dpll_synce.lock); - err = ice_synce_init_info(pf); + err = ice_dpll_init_info(pf); if (err) goto unlock; - err = ice_synce_init_dpll_worker(pf); + err = ice_dpll_init_dpll_worker(pf); if (err) goto free_info; - err = ice_synce_init_dpll(pf); + err = ice_dpll_init_dpll(pf); if (err) goto free_info; - err = ice_synce_register_pins(pf, pf->synce.dpll, pf->synce.inputs, - pf->synce.num_inputs, true); + err = ice_dpll_register_pins(pf, pf->synce.dpll, pf->synce.inputs, + pf->synce.num_inputs, true); if (err) goto free_info; - err = ice_synce_register_pins(pf, pf->synce.dpll, pf->synce.outputs, - pf->synce.num_outputs, false); - if (err) { - ice_synce_release_pins(pf->synce.dpll, pf->synce.inputs, - pf->synce.num_inputs); + err = ice_dpll_register_pins(pf, pf->synce.dpll, pf->synce.outputs, + pf->synce.num_outputs, false); + if (err) + ice_dpll_release_pins(pf->synce.dpll, pf->synce.inputs, + pf->synce.num_inputs); goto free_info; } dev_dbg(ice_pf_to_dev(pf), "SyncE init successful\n"); - mutex_unlock(&pf->synce.lock); + mutex_unlock(&pf->dpll_synce.lock); return err; free_info: ice_synce_release_info(pf); unlock: - mutex_unlock(&pf->synce.lock); + mutex_unlock(&pf->dpll_synce.lock); return err; } diff --git a/drivers/net/ethernet/intel/ice/ice_synce.h b/drivers/net/ethernet/intel/ice/ice_synce.h index 514e218540cba..33110b7bf3f7f 100644 --- a/drivers/net/ethernet/intel/ice/ice_synce.h +++ b/drivers/net/ethernet/intel/ice/ice_synce.h @@ -42,7 +42,7 @@ struct ice_synce_pin { * @lock: locks access to configuration of a dpll * @work: periodic work */ -struct ice_synce { +struct ice_dpll { struct dpll_device *dpll; int dpll_idx; u8 current_source; diff --git a/include/linux/dpll.h b/include/linux/dpll.h index 133999be7f066..1e54f56450a0c 100644 --- a/include/linux/dpll.h +++ b/include/linux/dpll.h @@ -22,6 +22,8 @@ struct dpll_device_ops { int (*get_source_supported)(struct dpll_device *dpll, int sma, int type); int (*get_output_type)(struct dpll_device *dpll, int sma); int (*get_output_supported)(struct dpll_device, int sma, int type); + int (*get_prio)(struct dpll_device *dpll, struct dpll_pin *pin); + int (*set_prio)(struct dpll_device *dpll, struct dpll_pin *pin, int prio); }; struct dpll_pin_ops { @@ -30,8 +32,6 @@ struct dpll_pin_ops { int (*set_type)(struct dpll_pin *pin, int type); int (*set_source)(struct dpll_pin *pin, struct dpll_device *dpll, int id); int (*set_flags)(struct dpll_pin *pin, struct dpll_device *dpll, int flags); - int (*get_prio)(struct dpll_pin *pin, struct dpll_device *dpll); - int (*set_prio)(struct dpll_pin *pin, struct dpll_device *dpll, int prio); }; enum dpll_pin_type {