diff options
Diffstat (limited to 'drivers/platform/mellanox/nvsw-sn2201.c')
| -rw-r--r-- | drivers/platform/mellanox/nvsw-sn2201.c | 135 |
1 files changed, 122 insertions, 13 deletions
diff --git a/drivers/platform/mellanox/nvsw-sn2201.c b/drivers/platform/mellanox/nvsw-sn2201.c index 7b9c107c17ce..51504113c17e 100644 --- a/drivers/platform/mellanox/nvsw-sn2201.c +++ b/drivers/platform/mellanox/nvsw-sn2201.c @@ -6,6 +6,7 @@ */ #include <linux/device.h> +#include <linux/dmi.h> #include <linux/i2c.h> #include <linux/interrupt.h> #include <linux/irq.h> @@ -84,6 +85,10 @@ #define NVSW_SN2201_MAIN_MUX_CH5_NR (NVSW_SN2201_MAIN_MUX_CH0_NR + 5) #define NVSW_SN2201_MAIN_MUX_CH6_NR (NVSW_SN2201_MAIN_MUX_CH0_NR + 6) #define NVSW_SN2201_MAIN_MUX_CH7_NR (NVSW_SN2201_MAIN_MUX_CH0_NR + 7) +#define NVSW_SN2201_2ND_MUX_CH0_NR (NVSW_SN2201_MAIN_MUX_CH7_NR + 1) +#define NVSW_SN2201_2ND_MUX_CH1_NR (NVSW_SN2201_MAIN_MUX_CH7_NR + 2) +#define NVSW_SN2201_2ND_MUX_CH2_NR (NVSW_SN2201_MAIN_MUX_CH7_NR + 3) +#define NVSW_SN2201_2ND_MUX_CH3_NR (NVSW_SN2201_MAIN_MUX_CH7_NR + 4) #define NVSW_SN2201_CPLD_NR NVSW_SN2201_MAIN_MUX_CH0_NR #define NVSW_SN2201_NR_NONE -1 @@ -100,6 +105,9 @@ | NVSW_SN2201_CPLD_AGGR_PSU_MASK_DEF \ | NVSW_SN2201_CPLD_AGGR_PWR_MASK_DEF \ | NVSW_SN2201_CPLD_AGGR_FAN_MASK_DEF) +#define NVSW_SN2201_CPLD_AGGR_BUSBAR_MASK_DEF \ + (NVSW_SN2201_CPLD_AGGR_ASIC_MASK_DEF \ + | NVSW_SN2201_CPLD_AGGR_FAN_MASK_DEF) #define NVSW_SN2201_CPLD_ASIC_MASK GENMASK(3, 1) #define NVSW_SN2201_CPLD_PSU_MASK GENMASK(1, 0) @@ -128,6 +136,7 @@ * @cpld_devs: I2C devices for cpld; * @cpld_devs_num: number of I2C devices for cpld; * @main_mux_deferred_nr: I2C adapter number must be exist prior creating devices execution; + * @ext_pwr_source: true if system powered by external power supply; false - by internal; */ struct nvsw_sn2201 { struct device *dev; @@ -148,6 +157,7 @@ struct nvsw_sn2201 { struct mlxreg_hotplug_device *cpld_devs; int cpld_devs_num; int main_mux_deferred_nr; + bool ext_pwr_source; }; static bool nvsw_sn2201_writeable_reg(struct device *dev, unsigned int reg) @@ -425,28 +435,28 @@ static struct mlxreg_core_data nvsw_sn2201_fan_items_data[] = { .reg = NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET, .mask = BIT(0), .hpdev.brdinfo = &nvsw_sn2201_fan_devices[0], - .hpdev.nr = NVSW_SN2201_NR_NONE, + .hpdev.nr = NVSW_SN2201_2ND_MUX_CH0_NR, }, { .label = "fan2", .reg = NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET, .mask = BIT(1), .hpdev.brdinfo = &nvsw_sn2201_fan_devices[1], - .hpdev.nr = NVSW_SN2201_NR_NONE, + .hpdev.nr = NVSW_SN2201_2ND_MUX_CH1_NR, }, { .label = "fan3", .reg = NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET, .mask = BIT(2), .hpdev.brdinfo = &nvsw_sn2201_fan_devices[2], - .hpdev.nr = NVSW_SN2201_NR_NONE, + .hpdev.nr = NVSW_SN2201_2ND_MUX_CH2_NR, }, { .label = "fan4", .reg = NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET, .mask = BIT(3), .hpdev.brdinfo = &nvsw_sn2201_fan_devices[3], - .hpdev.nr = NVSW_SN2201_NR_NONE, + .hpdev.nr = NVSW_SN2201_2ND_MUX_CH3_NR, }, }; @@ -513,11 +523,40 @@ static struct mlxreg_core_item nvsw_sn2201_items[] = { static struct mlxreg_core_hotplug_platform_data nvsw_sn2201_hotplug = { .items = nvsw_sn2201_items, - .counter = ARRAY_SIZE(nvsw_sn2201_items), + .count = ARRAY_SIZE(nvsw_sn2201_items), .cell = NVSW_SN2201_SYS_INT_STATUS_OFFSET, .mask = NVSW_SN2201_CPLD_AGGR_MASK_DEF, }; +static struct mlxreg_core_item nvsw_sn2201_busbar_items[] = { + { + .data = nvsw_sn2201_fan_items_data, + .aggr_mask = NVSW_SN2201_CPLD_AGGR_FAN_MASK_DEF, + .reg = NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET, + .mask = NVSW_SN2201_CPLD_FAN_MASK, + .count = ARRAY_SIZE(nvsw_sn2201_fan_items_data), + .inversed = 1, + .health = false, + }, + { + .data = nvsw_sn2201_sys_items_data, + .aggr_mask = NVSW_SN2201_CPLD_AGGR_ASIC_MASK_DEF, + .reg = NVSW_SN2201_ASIC_STATUS_OFFSET, + .mask = NVSW_SN2201_CPLD_ASIC_MASK, + .count = ARRAY_SIZE(nvsw_sn2201_sys_items_data), + .inversed = 1, + .health = false, + }, +}; + +static +struct mlxreg_core_hotplug_platform_data nvsw_sn2201_busbar_hotplug = { + .items = nvsw_sn2201_busbar_items, + .count = ARRAY_SIZE(nvsw_sn2201_busbar_items), + .cell = NVSW_SN2201_SYS_INT_STATUS_OFFSET, + .mask = NVSW_SN2201_CPLD_AGGR_BUSBAR_MASK_DEF, +}; + /* SN2201 static devices. */ static struct i2c_board_info nvsw_sn2201_static_devices[] = { { @@ -553,6 +592,9 @@ static struct i2c_board_info nvsw_sn2201_static_devices[] = { { I2C_BOARD_INFO("pmbus", 0x40), }, + { + I2C_BOARD_INFO("lm5066i", 0x15), + }, }; /* SN2201 default static board info. */ @@ -603,6 +645,58 @@ static struct mlxreg_hotplug_device nvsw_sn2201_static_brdinfo[] = { }, }; +/* SN2201 default busbar static board info. */ +static struct mlxreg_hotplug_device nvsw_sn2201_busbar_static_brdinfo[] = { + { + .brdinfo = &nvsw_sn2201_static_devices[0], + .nr = NVSW_SN2201_MAIN_NR, + }, + { + .brdinfo = &nvsw_sn2201_static_devices[1], + .nr = NVSW_SN2201_MAIN_MUX_CH0_NR, + }, + { + .brdinfo = &nvsw_sn2201_static_devices[2], + .nr = NVSW_SN2201_MAIN_MUX_CH0_NR, + }, + { + .brdinfo = &nvsw_sn2201_static_devices[3], + .nr = NVSW_SN2201_MAIN_MUX_CH0_NR, + }, + { + .brdinfo = &nvsw_sn2201_static_devices[4], + .nr = NVSW_SN2201_MAIN_MUX_CH3_NR, + }, + { + .brdinfo = &nvsw_sn2201_static_devices[5], + .nr = NVSW_SN2201_MAIN_MUX_CH5_NR, + }, + { + .brdinfo = &nvsw_sn2201_static_devices[6], + .nr = NVSW_SN2201_MAIN_MUX_CH5_NR, + }, + { + .brdinfo = &nvsw_sn2201_static_devices[7], + .nr = NVSW_SN2201_MAIN_MUX_CH5_NR, + }, + { + .brdinfo = &nvsw_sn2201_static_devices[8], + .nr = NVSW_SN2201_MAIN_MUX_CH6_NR, + }, + { + .brdinfo = &nvsw_sn2201_static_devices[9], + .nr = NVSW_SN2201_MAIN_MUX_CH6_NR, + }, + { + .brdinfo = &nvsw_sn2201_static_devices[10], + .nr = NVSW_SN2201_MAIN_MUX_CH7_NR, + }, + { + .brdinfo = &nvsw_sn2201_static_devices[11], + .nr = NVSW_SN2201_MAIN_MUX_CH1_NR, + }, +}; + /* LED default data. */ static struct mlxreg_core_data nvsw_sn2201_led_data[] = { { @@ -977,7 +1071,10 @@ static int nvsw_sn2201_config_init(struct nvsw_sn2201 *nvsw_sn2201, void *regmap nvsw_sn2201->io_data = &nvsw_sn2201_regs_io; nvsw_sn2201->led_data = &nvsw_sn2201_led; nvsw_sn2201->wd_data = &nvsw_sn2201_wd; - nvsw_sn2201->hotplug_data = &nvsw_sn2201_hotplug; + if (nvsw_sn2201->ext_pwr_source) + nvsw_sn2201->hotplug_data = &nvsw_sn2201_busbar_hotplug; + else + nvsw_sn2201->hotplug_data = &nvsw_sn2201_hotplug; /* Register IO access driver. */ if (nvsw_sn2201->io_data) { @@ -1084,7 +1181,7 @@ static int nvsw_sn2201_i2c_completion_notify(void *handle, int id) if (!nvsw_sn2201->main_mux_devs->adapter) { err = -ENODEV; dev_err(nvsw_sn2201->dev, "Failed to get adapter for bus %d\n", - nvsw_sn2201->cpld_devs->nr); + nvsw_sn2201->main_mux_devs->nr); goto i2c_get_adapter_main_fail; } @@ -1194,26 +1291,40 @@ static int nvsw_sn2201_config_pre_init(struct nvsw_sn2201 *nvsw_sn2201) static int nvsw_sn2201_probe(struct platform_device *pdev) { struct nvsw_sn2201 *nvsw_sn2201; + const char *sku; + int ret; nvsw_sn2201 = devm_kzalloc(&pdev->dev, sizeof(*nvsw_sn2201), GFP_KERNEL); if (!nvsw_sn2201) return -ENOMEM; + /* Validate system powering type - only HI168 SKU supports external power. */ + sku = dmi_get_system_info(DMI_PRODUCT_SKU); + if (sku && !strcmp(sku, "HI168")) + nvsw_sn2201->ext_pwr_source = true; + nvsw_sn2201->dev = &pdev->dev; platform_set_drvdata(pdev, nvsw_sn2201); - platform_device_add_resources(pdev, nvsw_sn2201_lpc_io_resources, + ret = platform_device_add_resources(pdev, nvsw_sn2201_lpc_io_resources, ARRAY_SIZE(nvsw_sn2201_lpc_io_resources)); + if (ret) + return ret; nvsw_sn2201->main_mux_deferred_nr = NVSW_SN2201_MAIN_MUX_DEFER_NR; nvsw_sn2201->main_mux_devs = nvsw_sn2201_main_mux_brdinfo; nvsw_sn2201->cpld_devs = nvsw_sn2201_cpld_brdinfo; - nvsw_sn2201->sn2201_devs = nvsw_sn2201_static_brdinfo; - nvsw_sn2201->sn2201_devs_num = ARRAY_SIZE(nvsw_sn2201_static_brdinfo); + if (nvsw_sn2201->ext_pwr_source) { + nvsw_sn2201->sn2201_devs = nvsw_sn2201_busbar_static_brdinfo; + nvsw_sn2201->sn2201_devs_num = ARRAY_SIZE(nvsw_sn2201_busbar_static_brdinfo); + } else { + nvsw_sn2201->sn2201_devs = nvsw_sn2201_static_brdinfo; + nvsw_sn2201->sn2201_devs_num = ARRAY_SIZE(nvsw_sn2201_static_brdinfo); + } return nvsw_sn2201_config_pre_init(nvsw_sn2201); } -static int nvsw_sn2201_remove(struct platform_device *pdev) +static void nvsw_sn2201_remove(struct platform_device *pdev) { struct nvsw_sn2201 *nvsw_sn2201 = platform_get_drvdata(pdev); @@ -1235,8 +1346,6 @@ static int nvsw_sn2201_remove(struct platform_device *pdev) /* Unregister I2C controller. */ if (nvsw_sn2201->pdev_i2c) platform_device_unregister(nvsw_sn2201->pdev_i2c); - - return 0; } static const struct acpi_device_id nvsw_sn2201_acpi_ids[] = { |
