|
@@ -47,6 +47,11 @@
|
|
|
/* LPC bus IO offsets */
|
|
|
#define MLXPLAT_CPLD_LPC_I2C_BASE_ADRR 0x2000
|
|
|
#define MLXPLAT_CPLD_LPC_REG_BASE_ADRR 0x2500
|
|
|
+#define MLXPLAT_CPLD_LPC_REG_LED1_OFFSET 0x20
|
|
|
+#define MLXPLAT_CPLD_LPC_REG_LED2_OFFSET 0x21
|
|
|
+#define MLXPLAT_CPLD_LPC_REG_LED3_OFFSET 0x22
|
|
|
+#define MLXPLAT_CPLD_LPC_REG_LED4_OFFSET 0x23
|
|
|
+#define MLXPLAT_CPLD_LPC_REG_LED5_OFFSET 0x24
|
|
|
#define MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET 0x3a
|
|
|
#define MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET 0x3b
|
|
|
#define MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET 0x40
|
|
@@ -84,6 +89,8 @@
|
|
|
#define MLXPLAT_CPLD_PWR_MASK GENMASK(1, 0)
|
|
|
#define MLXPLAT_CPLD_FAN_MASK GENMASK(3, 0)
|
|
|
#define MLXPLAT_CPLD_FAN_NG_MASK GENMASK(5, 0)
|
|
|
+#define MLXPLAT_CPLD_LED_LO_NIBBLE_MASK GENMASK(7, 4)
|
|
|
+#define MLXPLAT_CPLD_LED_HI_NIBBLE_MASK GENMASK(3, 0)
|
|
|
|
|
|
/* Default I2C parent bus number */
|
|
|
#define MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR 1
|
|
@@ -114,11 +121,13 @@
|
|
|
* @pdev_i2c - i2c controller platform device
|
|
|
* @pdev_mux - array of mux platform devices
|
|
|
* @pdev_hotplug - hotplug platform devices
|
|
|
+ * @pdev_led - led platform devices
|
|
|
*/
|
|
|
struct mlxplat_priv {
|
|
|
struct platform_device *pdev_i2c;
|
|
|
struct platform_device *pdev_mux[MLXPLAT_CPLD_LPC_MUX_DEVS];
|
|
|
struct platform_device *pdev_hotplug;
|
|
|
+ struct platform_device *pdev_led;
|
|
|
};
|
|
|
|
|
|
/* Regions for LPC I2C controller and LPC base register space */
|
|
@@ -592,9 +601,227 @@ struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_default_ng_data = {
|
|
|
.mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
|
|
|
};
|
|
|
|
|
|
+/* Platform led default data */
|
|
|
+static struct mlxreg_core_data mlxplat_mlxcpld_default_led_data[] = {
|
|
|
+ {
|
|
|
+ .label = "status:green",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "status:red",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "psu:green",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "psu:red",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "fan1:green",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "fan1:red",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "fan2:green",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "fan2:red",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "fan3:green",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "fan3:red",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "fan4:green",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "fan4:red",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+};
|
|
|
+
|
|
|
+static struct mlxreg_core_platform_data mlxplat_default_led_data = {
|
|
|
+ .data = mlxplat_mlxcpld_default_led_data,
|
|
|
+ .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_led_data),
|
|
|
+};
|
|
|
+
|
|
|
+/* Platform led MSN21xx system family data */
|
|
|
+static struct mlxreg_core_data mlxplat_mlxcpld_msn21xx_led_data[] = {
|
|
|
+ {
|
|
|
+ .label = "status:green",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "status:red",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "fan:green",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "fan:red",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "psu1:green",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "psu1:red",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "psu2:green",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "psu2:red",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "uid:blue",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED5_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+};
|
|
|
+
|
|
|
+static struct mlxreg_core_platform_data mlxplat_msn21xx_led_data = {
|
|
|
+ .data = mlxplat_mlxcpld_msn21xx_led_data,
|
|
|
+ .counter = ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_led_data),
|
|
|
+};
|
|
|
+
|
|
|
+/* Platform led for default data for 200GbE systems */
|
|
|
+static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_led_data[] = {
|
|
|
+ {
|
|
|
+ .label = "status:green",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "status:orange",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "psu:green",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "psu:orange",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "fan1:green",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "fan1:orange",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "fan2:green",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "fan2:orange",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "fan3:green",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "fan3:orange",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "fan4:green",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "fan4:orange",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "fan5:green",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "fan5:orange",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "fan6:green",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .label = "fan6:orange",
|
|
|
+ .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
|
|
|
+ .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
|
|
|
+ },
|
|
|
+};
|
|
|
+
|
|
|
+static struct mlxreg_core_platform_data mlxplat_default_ng_led_data = {
|
|
|
+ .data = mlxplat_mlxcpld_default_ng_led_data,
|
|
|
+ .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_led_data),
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
static bool mlxplat_mlxcpld_writeable_reg(struct device *dev, unsigned int reg)
|
|
|
{
|
|
|
switch (reg) {
|
|
|
+ case MLXPLAT_CPLD_LPC_REG_LED1_OFFSET:
|
|
|
+ case MLXPLAT_CPLD_LPC_REG_LED2_OFFSET:
|
|
|
+ case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET:
|
|
|
+ case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET:
|
|
|
+ case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
|
|
|
case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET:
|
|
|
case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET:
|
|
|
case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
|
|
@@ -611,6 +838,11 @@ static bool mlxplat_mlxcpld_writeable_reg(struct device *dev, unsigned int reg)
|
|
|
static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg)
|
|
|
{
|
|
|
switch (reg) {
|
|
|
+ case MLXPLAT_CPLD_LPC_REG_LED1_OFFSET:
|
|
|
+ case MLXPLAT_CPLD_LPC_REG_LED2_OFFSET:
|
|
|
+ case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET:
|
|
|
+ case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET:
|
|
|
+ case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
|
|
|
case MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET:
|
|
|
case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET:
|
|
|
case MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET:
|
|
@@ -632,6 +864,11 @@ static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg)
|
|
|
static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg)
|
|
|
{
|
|
|
switch (reg) {
|
|
|
+ case MLXPLAT_CPLD_LPC_REG_LED1_OFFSET:
|
|
|
+ case MLXPLAT_CPLD_LPC_REG_LED2_OFFSET:
|
|
|
+ case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET:
|
|
|
+ case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET:
|
|
|
+ case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
|
|
|
case MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET:
|
|
|
case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET:
|
|
|
case MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET:
|
|
@@ -692,6 +929,7 @@ static struct resource mlxplat_mlxcpld_resources[] = {
|
|
|
|
|
|
static struct platform_device *mlxplat_dev;
|
|
|
static struct mlxreg_core_hotplug_platform_data *mlxplat_hotplug;
|
|
|
+static struct mlxreg_core_platform_data *mlxplat_led;
|
|
|
|
|
|
static int __init mlxplat_dmi_default_matched(const struct dmi_system_id *dmi)
|
|
|
{
|
|
@@ -705,6 +943,7 @@ static int __init mlxplat_dmi_default_matched(const struct dmi_system_id *dmi)
|
|
|
mlxplat_hotplug = &mlxplat_mlxcpld_default_data;
|
|
|
mlxplat_hotplug->deferred_nr =
|
|
|
mlxplat_default_channels[i - 1][MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
|
|
|
+ mlxplat_led = &mlxplat_default_led_data;
|
|
|
|
|
|
return 1;
|
|
|
};
|
|
@@ -721,6 +960,7 @@ static int __init mlxplat_dmi_msn21xx_matched(const struct dmi_system_id *dmi)
|
|
|
mlxplat_hotplug = &mlxplat_mlxcpld_msn21xx_data;
|
|
|
mlxplat_hotplug->deferred_nr =
|
|
|
mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
|
|
|
+ mlxplat_led = &mlxplat_msn21xx_led_data;
|
|
|
|
|
|
return 1;
|
|
|
};
|
|
@@ -737,6 +977,7 @@ static int __init mlxplat_dmi_msn274x_matched(const struct dmi_system_id *dmi)
|
|
|
mlxplat_hotplug = &mlxplat_mlxcpld_msn274x_data;
|
|
|
mlxplat_hotplug->deferred_nr =
|
|
|
mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
|
|
|
+ mlxplat_led = &mlxplat_default_led_data;
|
|
|
|
|
|
return 1;
|
|
|
};
|
|
@@ -753,6 +994,7 @@ static int __init mlxplat_dmi_msn201x_matched(const struct dmi_system_id *dmi)
|
|
|
mlxplat_hotplug = &mlxplat_mlxcpld_msn201x_data;
|
|
|
mlxplat_hotplug->deferred_nr =
|
|
|
mlxplat_default_channels[i - 1][MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
|
|
|
+ mlxplat_led = &mlxplat_default_ng_led_data;
|
|
|
|
|
|
return 1;
|
|
|
};
|
|
@@ -769,6 +1011,7 @@ static int __init mlxplat_dmi_qmb7xx_matched(const struct dmi_system_id *dmi)
|
|
|
mlxplat_hotplug = &mlxplat_mlxcpld_default_ng_data;
|
|
|
mlxplat_hotplug->deferred_nr =
|
|
|
mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
|
|
|
+ mlxplat_led = &mlxplat_msn21xx_led_data;
|
|
|
|
|
|
return 1;
|
|
|
};
|
|
@@ -990,14 +1233,27 @@ static int __init mlxplat_init(void)
|
|
|
goto fail_platform_mux_register;
|
|
|
}
|
|
|
|
|
|
+ /* Add LED driver. */
|
|
|
+ mlxplat_led->regmap = mlxplat_hotplug->regmap;
|
|
|
+ priv->pdev_led = platform_device_register_resndata(
|
|
|
+ &mlxplat_dev->dev, "leds-mlxreg",
|
|
|
+ PLATFORM_DEVID_NONE, NULL, 0,
|
|
|
+ mlxplat_led, sizeof(*mlxplat_led));
|
|
|
+ if (IS_ERR(priv->pdev_led)) {
|
|
|
+ err = PTR_ERR(priv->pdev_led);
|
|
|
+ goto fail_platform_hotplug_register;
|
|
|
+ }
|
|
|
+
|
|
|
/* Sync registers with hardware. */
|
|
|
regcache_mark_dirty(mlxplat_hotplug->regmap);
|
|
|
err = regcache_sync(mlxplat_hotplug->regmap);
|
|
|
if (err)
|
|
|
- goto fail_platform_hotplug_register;
|
|
|
+ goto fail_platform_led_register;
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
+fail_platform_led_register:
|
|
|
+ platform_device_unregister(priv->pdev_led);
|
|
|
fail_platform_hotplug_register:
|
|
|
platform_device_unregister(priv->pdev_hotplug);
|
|
|
fail_platform_mux_register:
|
|
@@ -1016,6 +1272,7 @@ static void __exit mlxplat_exit(void)
|
|
|
struct mlxplat_priv *priv = platform_get_drvdata(mlxplat_dev);
|
|
|
int i;
|
|
|
|
|
|
+ platform_device_unregister(priv->pdev_led);
|
|
|
platform_device_unregister(priv->pdev_hotplug);
|
|
|
|
|
|
for (i = ARRAY_SIZE(mlxplat_mux_data) - 1; i >= 0 ; i--)
|