mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-01 03:44:27 -04:00
Merge branch 'mlxsw-improvements'
Petr Machata says: ==================== mlxsw: Improvements This patchset contains assortments of improvements to the mlxsw driver. Please see individual patches for details. ==================== Link: https://patch.msgid.link/cover.1720447210.git.petrm@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
@@ -100,6 +100,12 @@ static const struct mlxsw_cooling_states default_cooling_states[] = {
|
||||
|
||||
struct mlxsw_thermal;
|
||||
|
||||
struct mlxsw_thermal_cooling_device {
|
||||
struct mlxsw_thermal *thermal;
|
||||
struct thermal_cooling_device *cdev;
|
||||
unsigned int idx;
|
||||
};
|
||||
|
||||
struct mlxsw_thermal_module {
|
||||
struct mlxsw_thermal *parent;
|
||||
struct thermal_zone_device *tzdev;
|
||||
@@ -123,7 +129,7 @@ struct mlxsw_thermal {
|
||||
const struct mlxsw_bus_info *bus_info;
|
||||
struct thermal_zone_device *tzdev;
|
||||
int polling_delay;
|
||||
struct thermal_cooling_device *cdevs[MLXSW_MFCR_PWMS_MAX];
|
||||
struct mlxsw_thermal_cooling_device cdevs[MLXSW_MFCR_PWMS_MAX];
|
||||
struct thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
|
||||
struct mlxsw_cooling_states cooling_states[MLXSW_THERMAL_NUM_TRIPS];
|
||||
struct mlxsw_thermal_area line_cards[];
|
||||
@@ -147,7 +153,7 @@ static int mlxsw_get_cooling_device_idx(struct mlxsw_thermal *thermal,
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MLXSW_MFCR_PWMS_MAX; i++)
|
||||
if (thermal->cdevs[i] == cdev)
|
||||
if (thermal->cdevs[i].cdev == cdev)
|
||||
return i;
|
||||
|
||||
/* Allow mlxsw thermal zone binding to an external cooling device */
|
||||
@@ -352,17 +358,14 @@ static int mlxsw_thermal_get_cur_state(struct thermal_cooling_device *cdev,
|
||||
unsigned long *p_state)
|
||||
|
||||
{
|
||||
struct mlxsw_thermal *thermal = cdev->devdata;
|
||||
struct mlxsw_thermal_cooling_device *mlxsw_cdev = cdev->devdata;
|
||||
struct mlxsw_thermal *thermal = mlxsw_cdev->thermal;
|
||||
struct device *dev = thermal->bus_info->dev;
|
||||
char mfsc_pl[MLXSW_REG_MFSC_LEN];
|
||||
int err, idx;
|
||||
u8 duty;
|
||||
int err;
|
||||
|
||||
idx = mlxsw_get_cooling_device_idx(thermal, cdev);
|
||||
if (idx < 0)
|
||||
return idx;
|
||||
|
||||
mlxsw_reg_mfsc_pack(mfsc_pl, idx, 0);
|
||||
mlxsw_reg_mfsc_pack(mfsc_pl, mlxsw_cdev->idx, 0);
|
||||
err = mlxsw_reg_query(thermal->core, MLXSW_REG(mfsc), mfsc_pl);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to query PWM duty\n");
|
||||
@@ -378,22 +381,19 @@ static int mlxsw_thermal_set_cur_state(struct thermal_cooling_device *cdev,
|
||||
unsigned long state)
|
||||
|
||||
{
|
||||
struct mlxsw_thermal *thermal = cdev->devdata;
|
||||
struct mlxsw_thermal_cooling_device *mlxsw_cdev = cdev->devdata;
|
||||
struct mlxsw_thermal *thermal = mlxsw_cdev->thermal;
|
||||
struct device *dev = thermal->bus_info->dev;
|
||||
char mfsc_pl[MLXSW_REG_MFSC_LEN];
|
||||
int idx;
|
||||
int err;
|
||||
|
||||
if (state > MLXSW_THERMAL_MAX_STATE)
|
||||
return -EINVAL;
|
||||
|
||||
idx = mlxsw_get_cooling_device_idx(thermal, cdev);
|
||||
if (idx < 0)
|
||||
return idx;
|
||||
|
||||
/* Normalize the state to the valid speed range. */
|
||||
state = max_t(unsigned long, MLXSW_THERMAL_MIN_STATE, state);
|
||||
mlxsw_reg_mfsc_pack(mfsc_pl, idx, mlxsw_state_to_duty(state));
|
||||
mlxsw_reg_mfsc_pack(mfsc_pl, mlxsw_cdev->idx,
|
||||
mlxsw_state_to_duty(state));
|
||||
err = mlxsw_reg_write(thermal->core, MLXSW_REG(mfsc), mfsc_pl);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to write PWM duty\n");
|
||||
@@ -753,17 +753,21 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
|
||||
}
|
||||
for (i = 0; i < MLXSW_MFCR_PWMS_MAX; i++) {
|
||||
if (pwm_active & BIT(i)) {
|
||||
struct mlxsw_thermal_cooling_device *mlxsw_cdev;
|
||||
struct thermal_cooling_device *cdev;
|
||||
|
||||
mlxsw_cdev = &thermal->cdevs[i];
|
||||
mlxsw_cdev->thermal = thermal;
|
||||
mlxsw_cdev->idx = i;
|
||||
cdev = thermal_cooling_device_register("mlxsw_fan",
|
||||
thermal,
|
||||
mlxsw_cdev,
|
||||
&mlxsw_cooling_ops);
|
||||
if (IS_ERR(cdev)) {
|
||||
err = PTR_ERR(cdev);
|
||||
dev_err(dev, "Failed to register cooling device\n");
|
||||
goto err_thermal_cooling_device_register;
|
||||
}
|
||||
thermal->cdevs[i] = cdev;
|
||||
mlxsw_cdev->cdev = cdev;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -824,8 +828,7 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
|
||||
err_thermal_zone_device_register:
|
||||
err_thermal_cooling_device_register:
|
||||
for (i = 0; i < MLXSW_MFCR_PWMS_MAX; i++)
|
||||
if (thermal->cdevs[i])
|
||||
thermal_cooling_device_unregister(thermal->cdevs[i]);
|
||||
thermal_cooling_device_unregister(thermal->cdevs[i].cdev);
|
||||
err_reg_write:
|
||||
err_reg_query:
|
||||
kfree(thermal);
|
||||
@@ -847,12 +850,8 @@ void mlxsw_thermal_fini(struct mlxsw_thermal *thermal)
|
||||
thermal->tzdev = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < MLXSW_MFCR_PWMS_MAX; i++) {
|
||||
if (thermal->cdevs[i]) {
|
||||
thermal_cooling_device_unregister(thermal->cdevs[i]);
|
||||
thermal->cdevs[i] = NULL;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < MLXSW_MFCR_PWMS_MAX; i++)
|
||||
thermal_cooling_device_unregister(thermal->cdevs[i].cdev);
|
||||
|
||||
kfree(thermal);
|
||||
}
|
||||
|
||||
@@ -218,6 +218,10 @@ __mlxsw_item_bit_array_offset(const struct mlxsw_item *item,
|
||||
}
|
||||
|
||||
max_index = (item->size.bytes << 3) / item->element_size - 1;
|
||||
if (WARN_ONCE(index > max_index,
|
||||
"name=%s,index=%u,max_index=%u\n", item->name, index,
|
||||
max_index))
|
||||
index = 0;
|
||||
be_index = max_index - index;
|
||||
offset = be_index * item->element_size >> 3;
|
||||
in_byte_index = index % (BITS_PER_BYTE / item->element_size);
|
||||
|
||||
@@ -1784,6 +1784,7 @@ static int mlxsw_pci_reset_at_pci_disable(struct mlxsw_pci *mlxsw_pci,
|
||||
{
|
||||
struct pci_dev *pdev = mlxsw_pci->pdev;
|
||||
char mrsr_pl[MLXSW_REG_MRSR_LEN];
|
||||
struct pci_dev *bridge;
|
||||
int err;
|
||||
|
||||
if (!pci_reset_sbr_supported) {
|
||||
@@ -1800,6 +1801,9 @@ static int mlxsw_pci_reset_at_pci_disable(struct mlxsw_pci *mlxsw_pci,
|
||||
sbr:
|
||||
device_lock_assert(&pdev->dev);
|
||||
|
||||
bridge = pci_upstream_bridge(pdev);
|
||||
if (bridge)
|
||||
pci_cfg_access_lock(bridge);
|
||||
pci_cfg_access_lock(pdev);
|
||||
pci_save_state(pdev);
|
||||
|
||||
@@ -1809,6 +1813,8 @@ static int mlxsw_pci_reset_at_pci_disable(struct mlxsw_pci *mlxsw_pci,
|
||||
|
||||
pci_restore_state(pdev);
|
||||
pci_cfg_access_unlock(pdev);
|
||||
if (bridge)
|
||||
pci_cfg_access_unlock(bridge);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user