Commit 8ce2dddb authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

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: default avatarJakub Kicinski <kuba@kernel.org>
parents 746d684e 0970836c
Loading
Loading
Loading
Loading
+25 −26
Original line number Diff line number Diff line
@@ -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);
}
+4 −0
Original line number Diff line number Diff line
@@ -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);
+6 −0
Original line number Diff line number Diff line
@@ -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;
}