@@ -13,6 +13,7 @@
static DEFINE_MUTEX(pse_list_mutex);
static LIST_HEAD(pse_controller_list);
+static DEFINE_IDA(pse_ida);
/**
* struct pse_control - a PSE control
@@ -440,18 +441,22 @@ int pse_controller_register(struct pse_controller_dev *pcdev)
mutex_init(&pcdev->lock);
INIT_LIST_HEAD(&pcdev->pse_control_head);
+ ret = ida_alloc_max(&pse_ida, INT_MAX, GFP_KERNEL);
+ if (ret < 0)
+ return ret;
+ pcdev->id = ret;
if (!pcdev->nr_lines)
pcdev->nr_lines = 1;
ret = of_load_pse_pis(pcdev);
if (ret)
- return ret;
+ goto free_pse_ida;
if (pcdev->ops->setup_pi_matrix) {
ret = pcdev->ops->setup_pi_matrix(pcdev);
if (ret)
- return ret;
+ goto free_pse_ida;
}
/* Each regulator name len is pcdev dev name + 7 char +
@@ -468,15 +473,17 @@ int pse_controller_register(struct pse_controller_dev *pcdev)
continue;
reg_name = devm_kzalloc(pcdev->dev, reg_name_len, GFP_KERNEL);
- if (!reg_name)
- return -ENOMEM;
+ if (!reg_name) {
+ ret = -ENOMEM;
+ goto free_pse_ida;
+ }
snprintf(reg_name, reg_name_len, "pse-%s_pi%d",
dev_name(pcdev->dev), i);
ret = devm_pse_pi_regulator_register(pcdev, reg_name, i);
if (ret)
- return ret;
+ goto free_pse_ida;
}
mutex_lock(&pse_list_mutex);
@@ -484,6 +491,10 @@ int pse_controller_register(struct pse_controller_dev *pcdev)
mutex_unlock(&pse_list_mutex);
return 0;
+
+free_pse_ida:
+ ida_free(&pse_ida, pcdev->id);
+ return ret;
}
EXPORT_SYMBOL_GPL(pse_controller_register);
@@ -494,6 +505,7 @@ EXPORT_SYMBOL_GPL(pse_controller_register);
void pse_controller_unregister(struct pse_controller_dev *pcdev)
{
pse_release_pis(pcdev);
+ ida_free(&pse_ida, pcdev->id);
mutex_lock(&pse_list_mutex);
list_del(&pcdev->list);
mutex_unlock(&pse_list_mutex);
@@ -750,6 +762,7 @@ static int _pse_ethtool_get_status(struct pse_controller_dev *pcdev,
return -EOPNOTSUPP;
}
+ status->pse_id = pcdev->id;
return ops->ethtool_get_status(pcdev, id, extack, status);
}
@@ -31,6 +31,7 @@ struct pse_control_config {
/**
* struct pse_control_status - PSE control/channel status.
*
+ * @pse_id: index number of the PSE. Set by PSE core.
* @podl_admin_state: operational state of the PoDL PSE
* functions. IEEE 802.3-2018 30.15.1.1.2 aPoDLPSEAdminState
* @podl_pw_status: power detection status of the PoDL PSE.
@@ -52,6 +53,7 @@ struct pse_control_config {
* ranges
*/
struct pse_control_status {
+ u32 pse_id;
enum ethtool_podl_pse_admin_state podl_admin_state;
enum ethtool_podl_pse_pw_d_status podl_pw_status;
enum ethtool_c33_pse_admin_state c33_admin_state;
@@ -150,6 +152,7 @@ struct pse_pi {
* @types: types of the PSE controller
* @pi: table of PSE PIs described in this controller device
* @no_of_pse_pi: flag set if the pse_pis devicetree node is not used
+ * @id: Index of the PSE
*/
struct pse_controller_dev {
const struct pse_controller_ops *ops;
@@ -163,6 +166,7 @@ struct pse_controller_dev {
enum ethtool_pse_types types;
struct pse_pi *pi;
bool no_of_pse_pi;
+ int id;
};
#if IS_ENABLED(CONFIG_PSE_CONTROLLER)