platform/x86: Move Mellanox platform hotplug driver to platform/mellanox

In preparation for making the hotplug driver build for different
architectures, move mlxcpld-hotplug.c to platform/mellanox and the
header to include/linux/platform_data as mlxreg.h to reflect the new
interface changes to come.

Replace references to CPLD with REG throughout the files, consistent
with the new name.

Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
Acked-by: Andy Shevchenko <andy.shevchenko@gmail.com>
[dvhart: update copyright, rewrite commit message]
Signed-off-by: Darren Hart (VMware) <dvhart@infradead.org>
This commit is contained in:
Vadim Pasternak 2018-01-17 18:21:53 +00:00 committed by Darren Hart (VMware)
parent d6fa7588fd
commit 1f976f6978
10 changed files with 170 additions and 146 deletions

View File

@ -8860,12 +8860,13 @@ W: http://www.mellanox.com
Q: http://patchwork.ozlabs.org/project/netdev/list/ Q: http://patchwork.ozlabs.org/project/netdev/list/
F: drivers/net/ethernet/mellanox/mlxfw/ F: drivers/net/ethernet/mellanox/mlxfw/
MELLANOX MLX CPLD HOTPLUG DRIVER MELLANOX HARDWARE PLATFORM SUPPORT
M: Andy Shevchenko <andy@infradead.org>
M: Darren Hart <dvhart@infradead.org>
M: Vadim Pasternak <vadimp@mellanox.com> M: Vadim Pasternak <vadimp@mellanox.com>
L: platform-driver-x86@vger.kernel.org L: platform-driver-x86@vger.kernel.org
S: Supported S: Supported
F: drivers/platform/x86/mlxcpld-hotplug.c F: drivers/platform/mellanox/
F: include/linux/platform_data/mlxcpld-hotplug.h
MELLANOX MLX4 core VPI driver MELLANOX MLX4 core VPI driver
M: Tariq Toukan <tariqt@mellanox.com> M: Tariq Toukan <tariqt@mellanox.com>

View File

@ -8,3 +8,5 @@ endif
source "drivers/platform/goldfish/Kconfig" source "drivers/platform/goldfish/Kconfig"
source "drivers/platform/chrome/Kconfig" source "drivers/platform/chrome/Kconfig"
source "drivers/platform/mellanox/Kconfig"

View File

@ -4,6 +4,7 @@
# #
obj-$(CONFIG_X86) += x86/ obj-$(CONFIG_X86) += x86/
obj-$(CONFIG_MELLANOX_PLATFORM) += mellanox/
obj-$(CONFIG_MIPS) += mips/ obj-$(CONFIG_MIPS) += mips/
obj-$(CONFIG_OLPC) += olpc/ obj-$(CONFIG_OLPC) += olpc/
obj-$(CONFIG_GOLDFISH) += goldfish/ obj-$(CONFIG_GOLDFISH) += goldfish/

View File

@ -0,0 +1,25 @@
# SPDX-License-Identifier: GPL-2.0
#
# Platform support for Mellanox hardware
#
menuconfig MELLANOX_PLATFORM
bool "Platform support for Mellanox hardware"
depends on X86 || COMPILE_TEST
---help---
Say Y here to get to see options for platform support for
Mellanox systems. This option alone does not add any kernel code.
If you say N, all options in this submenu will be skipped and disabled.
if MELLANOX_PLATFORM
config MLXREG_HOTPLUG
tristate "Mellanox platform hotplug driver support"
depends on HWMON
depends on I2C
---help---
This driver handles hot-plug events for the power suppliers, power
cables and fans on the wide range Mellanox IB and Ethernet systems.
endif # MELLANOX_PLATFORM

View File

@ -0,0 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
#
# Makefile for linux/drivers/platform/mellanox
# Mellanox Platform-Specific Drivers
#
obj-$(CONFIG_MLXREG_HOTPLUG) += mlxreg-hotplug.o

View File

@ -1,7 +1,6 @@
/* /*
* drivers/platform/x86/mlxcpld-hotplug.c * Copyright (c) 2016-2018 Mellanox Technologies. All rights reserved.
* Copyright (c) 2016 Mellanox Technologies. All rights reserved. * Copyright (c) 2016-2018 Vadim Pasternak <vadimp@mellanox.com>
* Copyright (c) 2016 Vadim Pasternak <vadimp@mellanox.com>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
@ -40,39 +39,39 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_data/mlxcpld-hotplug.h> #include <linux/platform_data/mlxreg.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
/* Offset of event and mask registers from status register */ /* Offset of event and mask registers from status register */
#define MLXCPLD_HOTPLUG_EVENT_OFF 1 #define MLXREG_HOTPLUG_EVENT_OFF 1
#define MLXCPLD_HOTPLUG_MASK_OFF 2 #define MLXREG_HOTPLUG_MASK_OFF 2
#define MLXCPLD_HOTPLUG_AGGR_MASK_OFF 1 #define MLXREG_HOTPLUG_AGGR_MASK_OFF 1
#define MLXCPLD_HOTPLUG_ATTRS_NUM 8 #define MLXREG_HOTPLUG_ATTRS_NUM 8
/** /**
* enum mlxcpld_hotplug_attr_type - sysfs attributes for hotplug events: * enum mlxreg_hotplug_attr_type - sysfs attributes for hotplug events:
* @MLXCPLD_HOTPLUG_ATTR_TYPE_PSU: power supply unit attribute; * @MLXREG_HOTPLUG_ATTR_TYPE_PSU: power supply unit attribute;
* @MLXCPLD_HOTPLUG_ATTR_TYPE_PWR: power cable attribute; * @MLXREG_HOTPLUG_ATTR_TYPE_PWR: power cable attribute;
* @MLXCPLD_HOTPLUG_ATTR_TYPE_FAN: FAN drawer attribute; * @MLXREG_HOTPLUG_ATTR_TYPE_FAN: FAN drawer attribute;
*/ */
enum mlxcpld_hotplug_attr_type { enum mlxreg_hotplug_attr_type {
MLXCPLD_HOTPLUG_ATTR_TYPE_PSU, MLXREG_HOTPLUG_ATTR_TYPE_PSU,
MLXCPLD_HOTPLUG_ATTR_TYPE_PWR, MLXREG_HOTPLUG_ATTR_TYPE_PWR,
MLXCPLD_HOTPLUG_ATTR_TYPE_FAN, MLXREG_HOTPLUG_ATTR_TYPE_FAN,
}; };
/** /**
* struct mlxcpld_hotplug_priv_data - platform private data: * struct mlxreg_hotplug_priv_data - platform private data:
* @irq: platform interrupt number; * @irq: platform interrupt number;
* @pdev: platform device; * @pdev: platform device;
* @plat: platform data; * @plat: platform data;
* @hwmon: hwmon device; * @hwmon: hwmon device;
* @mlxcpld_hotplug_attr: sysfs attributes array; * @mlxreg_hotplug_attr: sysfs attributes array;
* @mlxcpld_hotplug_dev_attr: sysfs sensor device attribute array; * @mlxreg_hotplug_dev_attr: sysfs sensor device attribute array;
* @group: sysfs attribute group; * @group: sysfs attribute group;
* @groups: list of sysfs attribute group for hwmon registration; * @groups: list of sysfs attribute group for hwmon registration;
* @dwork: delayed work template; * @dwork: delayed work template;
@ -82,14 +81,14 @@ enum mlxcpld_hotplug_attr_type {
* @pwr_cache: last value of power register status; * @pwr_cache: last value of power register status;
* @fan_cache: last value of FAN register status; * @fan_cache: last value of FAN register status;
*/ */
struct mlxcpld_hotplug_priv_data { struct mlxreg_hotplug_priv_data {
int irq; int irq;
struct platform_device *pdev; struct platform_device *pdev;
struct mlxcpld_hotplug_platform_data *plat; struct mlxreg_hotplug_platform_data *plat;
struct device *hwmon; struct device *hwmon;
struct attribute *mlxcpld_hotplug_attr[MLXCPLD_HOTPLUG_ATTRS_NUM + 1]; struct attribute *mlxreg_hotplug_attr[MLXREG_HOTPLUG_ATTRS_NUM + 1];
struct sensor_device_attribute_2 struct sensor_device_attribute_2
mlxcpld_hotplug_dev_attr[MLXCPLD_HOTPLUG_ATTRS_NUM]; mlxreg_hotplug_dev_attr[MLXREG_HOTPLUG_ATTRS_NUM];
struct attribute_group group; struct attribute_group group;
const struct attribute_group *groups[2]; const struct attribute_group *groups[2];
struct delayed_work dwork; struct delayed_work dwork;
@ -100,29 +99,29 @@ struct mlxcpld_hotplug_priv_data {
u8 fan_cache; u8 fan_cache;
}; };
static ssize_t mlxcpld_hotplug_attr_show(struct device *dev, static ssize_t mlxreg_hotplug_attr_show(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
char *buf) char *buf)
{ {
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
struct mlxcpld_hotplug_priv_data *priv = platform_get_drvdata(pdev); struct mlxreg_hotplug_priv_data *priv = platform_get_drvdata(pdev);
int index = to_sensor_dev_attr_2(attr)->index; int index = to_sensor_dev_attr_2(attr)->index;
int nr = to_sensor_dev_attr_2(attr)->nr; int nr = to_sensor_dev_attr_2(attr)->nr;
u8 reg_val = 0; u8 reg_val = 0;
switch (nr) { switch (nr) {
case MLXCPLD_HOTPLUG_ATTR_TYPE_PSU: case MLXREG_HOTPLUG_ATTR_TYPE_PSU:
/* Bit = 0 : PSU is present. */ /* Bit = 0 : PSU is present. */
reg_val = !!!(inb(priv->plat->psu_reg_offset) & BIT(index)); reg_val = !!!(inb(priv->plat->psu_reg_offset) & BIT(index));
break; break;
case MLXCPLD_HOTPLUG_ATTR_TYPE_PWR: case MLXREG_HOTPLUG_ATTR_TYPE_PWR:
/* Bit = 1 : power cable is attached. */ /* Bit = 1 : power cable is attached. */
reg_val = !!(inb(priv->plat->pwr_reg_offset) & BIT(index % reg_val = !!(inb(priv->plat->pwr_reg_offset) & BIT(index %
priv->plat->pwr_count)); priv->plat->pwr_count));
break; break;
case MLXCPLD_HOTPLUG_ATTR_TYPE_FAN: case MLXREG_HOTPLUG_ATTR_TYPE_FAN:
/* Bit = 0 : FAN is present. */ /* Bit = 0 : FAN is present. */
reg_val = !!!(inb(priv->plat->fan_reg_offset) & BIT(index % reg_val = !!!(inb(priv->plat->fan_reg_offset) & BIT(index %
priv->plat->fan_count)); priv->plat->fan_count));
@ -132,9 +131,9 @@ static ssize_t mlxcpld_hotplug_attr_show(struct device *dev,
return sprintf(buf, "%u\n", reg_val); return sprintf(buf, "%u\n", reg_val);
} }
#define PRIV_ATTR(i) priv->mlxcpld_hotplug_attr[i] #define PRIV_ATTR(i) priv->mlxreg_hotplug_attr[i]
#define PRIV_DEV_ATTR(i) priv->mlxcpld_hotplug_dev_attr[i] #define PRIV_DEV_ATTR(i) priv->mlxreg_hotplug_dev_attr[i]
static int mlxcpld_hotplug_attr_init(struct mlxcpld_hotplug_priv_data *priv) static int mlxreg_hotplug_attr_init(struct mlxreg_hotplug_priv_data *priv)
{ {
int num_attrs = priv->plat->psu_count + priv->plat->pwr_count + int num_attrs = priv->plat->psu_count + priv->plat->pwr_count +
priv->plat->fan_count; priv->plat->fan_count;
@ -152,17 +151,17 @@ static int mlxcpld_hotplug_attr_init(struct mlxcpld_hotplug_priv_data *priv)
if (i < priv->plat->psu_count) { if (i < priv->plat->psu_count) {
PRIV_ATTR(i)->name = devm_kasprintf(&priv->pdev->dev, PRIV_ATTR(i)->name = devm_kasprintf(&priv->pdev->dev,
GFP_KERNEL, "psu%u", i + 1); GFP_KERNEL, "psu%u", i + 1);
PRIV_DEV_ATTR(i).nr = MLXCPLD_HOTPLUG_ATTR_TYPE_PSU; PRIV_DEV_ATTR(i).nr = MLXREG_HOTPLUG_ATTR_TYPE_PSU;
} else if (i < priv->plat->psu_count + priv->plat->pwr_count) { } else if (i < priv->plat->psu_count + priv->plat->pwr_count) {
PRIV_ATTR(i)->name = devm_kasprintf(&priv->pdev->dev, PRIV_ATTR(i)->name = devm_kasprintf(&priv->pdev->dev,
GFP_KERNEL, "pwr%u", i % GFP_KERNEL, "pwr%u", i %
priv->plat->pwr_count + 1); priv->plat->pwr_count + 1);
PRIV_DEV_ATTR(i).nr = MLXCPLD_HOTPLUG_ATTR_TYPE_PWR; PRIV_DEV_ATTR(i).nr = MLXREG_HOTPLUG_ATTR_TYPE_PWR;
} else { } else {
PRIV_ATTR(i)->name = devm_kasprintf(&priv->pdev->dev, PRIV_ATTR(i)->name = devm_kasprintf(&priv->pdev->dev,
GFP_KERNEL, "fan%u", i % GFP_KERNEL, "fan%u", i %
priv->plat->fan_count + 1); priv->plat->fan_count + 1);
PRIV_DEV_ATTR(i).nr = MLXCPLD_HOTPLUG_ATTR_TYPE_FAN; PRIV_DEV_ATTR(i).nr = MLXREG_HOTPLUG_ATTR_TYPE_FAN;
} }
if (!PRIV_ATTR(i)->name) { if (!PRIV_ATTR(i)->name) {
@ -173,20 +172,20 @@ static int mlxcpld_hotplug_attr_init(struct mlxcpld_hotplug_priv_data *priv)
PRIV_DEV_ATTR(i).dev_attr.attr.name = PRIV_ATTR(i)->name; PRIV_DEV_ATTR(i).dev_attr.attr.name = PRIV_ATTR(i)->name;
PRIV_DEV_ATTR(i).dev_attr.attr.mode = S_IRUGO; PRIV_DEV_ATTR(i).dev_attr.attr.mode = S_IRUGO;
PRIV_DEV_ATTR(i).dev_attr.show = mlxcpld_hotplug_attr_show; PRIV_DEV_ATTR(i).dev_attr.show = mlxreg_hotplug_attr_show;
PRIV_DEV_ATTR(i).index = i; PRIV_DEV_ATTR(i).index = i;
sysfs_attr_init(&PRIV_DEV_ATTR(i).dev_attr.attr); sysfs_attr_init(&PRIV_DEV_ATTR(i).dev_attr.attr);
} }
priv->group.attrs = priv->mlxcpld_hotplug_attr; priv->group.attrs = priv->mlxreg_hotplug_attr;
priv->groups[0] = &priv->group; priv->groups[0] = &priv->group;
priv->groups[1] = NULL; priv->groups[1] = NULL;
return 0; return 0;
} }
static int mlxcpld_hotplug_device_create(struct device *dev, static int mlxreg_hotplug_device_create(struct device *dev,
struct mlxcpld_hotplug_device *item) struct mlxreg_hotplug_device *item)
{ {
item->adapter = i2c_get_adapter(item->bus); item->adapter = i2c_get_adapter(item->bus);
if (!item->adapter) { if (!item->adapter) {
@ -207,7 +206,7 @@ static int mlxcpld_hotplug_device_create(struct device *dev,
return 0; return 0;
} }
static void mlxcpld_hotplug_device_destroy(struct mlxcpld_hotplug_device *item) static void mlxreg_hotplug_device_destroy(struct mlxreg_hotplug_device *item)
{ {
if (item->client) { if (item->client) {
i2c_unregister_device(item->client); i2c_unregister_device(item->client);
@ -221,15 +220,15 @@ static void mlxcpld_hotplug_device_destroy(struct mlxcpld_hotplug_device *item)
} }
static inline void static inline void
mlxcpld_hotplug_work_helper(struct device *dev, mlxreg_hotplug_work_helper(struct device *dev,
struct mlxcpld_hotplug_device *item, u8 is_inverse, struct mlxreg_hotplug_device *item, u8 is_inverse,
u16 offset, u8 mask, u8 *cache) u16 offset, u8 mask, u8 *cache)
{ {
u8 val, asserted; u8 val, asserted;
int bit; int bit;
/* Mask event. */ /* Mask event. */
outb(0, offset + MLXCPLD_HOTPLUG_MASK_OFF); outb(0, offset + MLXREG_HOTPLUG_MASK_OFF);
/* Read status. */ /* Read status. */
val = inb(offset) & mask; val = inb(offset) & mask;
asserted = *cache ^ val; asserted = *cache ^ val;
@ -251,25 +250,25 @@ mlxcpld_hotplug_work_helper(struct device *dev,
for_each_set_bit(bit, (unsigned long *)&asserted, 8) { for_each_set_bit(bit, (unsigned long *)&asserted, 8) {
if (val & BIT(bit)) { if (val & BIT(bit)) {
if (is_inverse) if (is_inverse)
mlxcpld_hotplug_device_destroy(item + bit); mlxreg_hotplug_device_destroy(item + bit);
else else
mlxcpld_hotplug_device_create(dev, item + bit); mlxreg_hotplug_device_create(dev, item + bit);
} else { } else {
if (is_inverse) if (is_inverse)
mlxcpld_hotplug_device_create(dev, item + bit); mlxreg_hotplug_device_create(dev, item + bit);
else else
mlxcpld_hotplug_device_destroy(item + bit); mlxreg_hotplug_device_destroy(item + bit);
} }
} }
/* Acknowledge event. */ /* Acknowledge event. */
outb(0, offset + MLXCPLD_HOTPLUG_EVENT_OFF); outb(0, offset + MLXREG_HOTPLUG_EVENT_OFF);
/* Unmask event. */ /* Unmask event. */
outb(mask, offset + MLXCPLD_HOTPLUG_MASK_OFF); outb(mask, offset + MLXREG_HOTPLUG_MASK_OFF);
} }
/* /*
* mlxcpld_hotplug_work_handler - performs traversing of CPLD interrupt * mlxreg_hotplug_work_handler - performs traversing of CPLD interrupt
* registers according to the below hierarchy schema: * registers according to the below hierarchy schema:
* *
* Aggregation registers (status/mask) * Aggregation registers (status/mask)
@ -289,15 +288,15 @@ mlxcpld_hotplug_work_helper(struct device *dev,
* In case some system changed are detected: FAN in/out, PSU in/out, power * In case some system changed are detected: FAN in/out, PSU in/out, power
* cable attached/detached, relevant device is created or destroyed. * cable attached/detached, relevant device is created or destroyed.
*/ */
static void mlxcpld_hotplug_work_handler(struct work_struct *work) static void mlxreg_hotplug_work_handler(struct work_struct *work)
{ {
struct mlxcpld_hotplug_priv_data *priv = container_of(work, struct mlxreg_hotplug_priv_data *priv = container_of(work,
struct mlxcpld_hotplug_priv_data, dwork.work); struct mlxreg_hotplug_priv_data, dwork.work);
u8 val, aggr_asserted; u8 val, aggr_asserted;
unsigned long flags; unsigned long flags;
/* Mask aggregation event. */ /* Mask aggregation event. */
outb(0, priv->plat->top_aggr_offset + MLXCPLD_HOTPLUG_AGGR_MASK_OFF); outb(0, priv->plat->top_aggr_offset + MLXREG_HOTPLUG_AGGR_MASK_OFF);
/* Read aggregation status. */ /* Read aggregation status. */
val = inb(priv->plat->top_aggr_offset) & priv->plat->top_aggr_mask; val = inb(priv->plat->top_aggr_offset) & priv->plat->top_aggr_mask;
aggr_asserted = priv->aggr_cache ^ val; aggr_asserted = priv->aggr_cache ^ val;
@ -305,21 +304,21 @@ static void mlxcpld_hotplug_work_handler(struct work_struct *work)
/* Handle PSU configuration changes. */ /* Handle PSU configuration changes. */
if (aggr_asserted & priv->plat->top_aggr_psu_mask) if (aggr_asserted & priv->plat->top_aggr_psu_mask)
mlxcpld_hotplug_work_helper(&priv->pdev->dev, priv->plat->psu, mlxreg_hotplug_work_helper(&priv->pdev->dev, priv->plat->psu,
1, priv->plat->psu_reg_offset, 1, priv->plat->psu_reg_offset,
priv->plat->psu_mask, priv->plat->psu_mask,
&priv->psu_cache); &priv->psu_cache);
/* Handle power cable configuration changes. */ /* Handle power cable configuration changes. */
if (aggr_asserted & priv->plat->top_aggr_pwr_mask) if (aggr_asserted & priv->plat->top_aggr_pwr_mask)
mlxcpld_hotplug_work_helper(&priv->pdev->dev, priv->plat->pwr, mlxreg_hotplug_work_helper(&priv->pdev->dev, priv->plat->pwr,
0, priv->plat->pwr_reg_offset, 0, priv->plat->pwr_reg_offset,
priv->plat->pwr_mask, priv->plat->pwr_mask,
&priv->pwr_cache); &priv->pwr_cache);
/* Handle FAN configuration changes. */ /* Handle FAN configuration changes. */
if (aggr_asserted & priv->plat->top_aggr_fan_mask) if (aggr_asserted & priv->plat->top_aggr_fan_mask)
mlxcpld_hotplug_work_helper(&priv->pdev->dev, priv->plat->fan, mlxreg_hotplug_work_helper(&priv->pdev->dev, priv->plat->fan,
1, priv->plat->fan_reg_offset, 1, priv->plat->fan_reg_offset,
priv->plat->fan_mask, priv->plat->fan_mask,
&priv->fan_cache); &priv->fan_cache);
@ -329,7 +328,7 @@ static void mlxcpld_hotplug_work_handler(struct work_struct *work)
/* /*
* It is possible, that some signals have been inserted, while * It is possible, that some signals have been inserted, while
* interrupt has been masked by mlxcpld_hotplug_work_handler. * interrupt has been masked by mlxreg_hotplug_work_handler.
* In this case such signals will be missed. In order to handle * In this case such signals will be missed. In order to handle
* these signals delayed work is canceled and work task * these signals delayed work is canceled and work task
* re-scheduled for immediate execution. It allows to handle * re-scheduled for immediate execution. It allows to handle
@ -347,42 +346,42 @@ static void mlxcpld_hotplug_work_handler(struct work_struct *work)
/* Unmask aggregation event (no need acknowledge). */ /* Unmask aggregation event (no need acknowledge). */
outb(priv->plat->top_aggr_mask, priv->plat->top_aggr_offset + outb(priv->plat->top_aggr_mask, priv->plat->top_aggr_offset +
MLXCPLD_HOTPLUG_AGGR_MASK_OFF); MLXREG_HOTPLUG_AGGR_MASK_OFF);
} }
static void mlxcpld_hotplug_set_irq(struct mlxcpld_hotplug_priv_data *priv) static void mlxreg_hotplug_set_irq(struct mlxreg_hotplug_priv_data *priv)
{ {
/* Clear psu presense event. */ /* Clear psu presense event. */
outb(0, priv->plat->psu_reg_offset + MLXCPLD_HOTPLUG_EVENT_OFF); outb(0, priv->plat->psu_reg_offset + MLXREG_HOTPLUG_EVENT_OFF);
/* Set psu initial status as mask and unmask psu event. */ /* Set psu initial status as mask and unmask psu event. */
priv->psu_cache = priv->plat->psu_mask; priv->psu_cache = priv->plat->psu_mask;
outb(priv->plat->psu_mask, priv->plat->psu_reg_offset + outb(priv->plat->psu_mask, priv->plat->psu_reg_offset +
MLXCPLD_HOTPLUG_MASK_OFF); MLXREG_HOTPLUG_MASK_OFF);
/* Clear power cable event. */ /* Clear power cable event. */
outb(0, priv->plat->pwr_reg_offset + MLXCPLD_HOTPLUG_EVENT_OFF); outb(0, priv->plat->pwr_reg_offset + MLXREG_HOTPLUG_EVENT_OFF);
/* Keep power initial status as zero and unmask power event. */ /* Keep power initial status as zero and unmask power event. */
outb(priv->plat->pwr_mask, priv->plat->pwr_reg_offset + outb(priv->plat->pwr_mask, priv->plat->pwr_reg_offset +
MLXCPLD_HOTPLUG_MASK_OFF); MLXREG_HOTPLUG_MASK_OFF);
/* Clear fan presense event. */ /* Clear fan presense event. */
outb(0, priv->plat->fan_reg_offset + MLXCPLD_HOTPLUG_EVENT_OFF); outb(0, priv->plat->fan_reg_offset + MLXREG_HOTPLUG_EVENT_OFF);
/* Set fan initial status as mask and unmask fan event. */ /* Set fan initial status as mask and unmask fan event. */
priv->fan_cache = priv->plat->fan_mask; priv->fan_cache = priv->plat->fan_mask;
outb(priv->plat->fan_mask, priv->plat->fan_reg_offset + outb(priv->plat->fan_mask, priv->plat->fan_reg_offset +
MLXCPLD_HOTPLUG_MASK_OFF); MLXREG_HOTPLUG_MASK_OFF);
/* Keep aggregation initial status as zero and unmask events. */ /* Keep aggregation initial status as zero and unmask events. */
outb(priv->plat->top_aggr_mask, priv->plat->top_aggr_offset + outb(priv->plat->top_aggr_mask, priv->plat->top_aggr_offset +
MLXCPLD_HOTPLUG_AGGR_MASK_OFF); MLXREG_HOTPLUG_AGGR_MASK_OFF);
/* Invoke work handler for initializing hot plug devices setting. */ /* Invoke work handler for initializing hot plug devices setting. */
mlxcpld_hotplug_work_handler(&priv->dwork.work); mlxreg_hotplug_work_handler(&priv->dwork.work);
enable_irq(priv->irq); enable_irq(priv->irq);
} }
static void mlxcpld_hotplug_unset_irq(struct mlxcpld_hotplug_priv_data *priv) static void mlxreg_hotplug_unset_irq(struct mlxreg_hotplug_priv_data *priv)
{ {
int i; int i;
@ -390,38 +389,38 @@ static void mlxcpld_hotplug_unset_irq(struct mlxcpld_hotplug_priv_data *priv)
cancel_delayed_work_sync(&priv->dwork); cancel_delayed_work_sync(&priv->dwork);
/* Mask aggregation event. */ /* Mask aggregation event. */
outb(0, priv->plat->top_aggr_offset + MLXCPLD_HOTPLUG_AGGR_MASK_OFF); outb(0, priv->plat->top_aggr_offset + MLXREG_HOTPLUG_AGGR_MASK_OFF);
/* Mask psu presense event. */ /* Mask psu presense event. */
outb(0, priv->plat->psu_reg_offset + MLXCPLD_HOTPLUG_MASK_OFF); outb(0, priv->plat->psu_reg_offset + MLXREG_HOTPLUG_MASK_OFF);
/* Clear psu presense event. */ /* Clear psu presense event. */
outb(0, priv->plat->psu_reg_offset + MLXCPLD_HOTPLUG_EVENT_OFF); outb(0, priv->plat->psu_reg_offset + MLXREG_HOTPLUG_EVENT_OFF);
/* Mask power cable event. */ /* Mask power cable event. */
outb(0, priv->plat->pwr_reg_offset + MLXCPLD_HOTPLUG_MASK_OFF); outb(0, priv->plat->pwr_reg_offset + MLXREG_HOTPLUG_MASK_OFF);
/* Clear power cable event. */ /* Clear power cable event. */
outb(0, priv->plat->pwr_reg_offset + MLXCPLD_HOTPLUG_EVENT_OFF); outb(0, priv->plat->pwr_reg_offset + MLXREG_HOTPLUG_EVENT_OFF);
/* Mask fan presense event. */ /* Mask fan presense event. */
outb(0, priv->plat->fan_reg_offset + MLXCPLD_HOTPLUG_MASK_OFF); outb(0, priv->plat->fan_reg_offset + MLXREG_HOTPLUG_MASK_OFF);
/* Clear fan presense event. */ /* Clear fan presense event. */
outb(0, priv->plat->fan_reg_offset + MLXCPLD_HOTPLUG_EVENT_OFF); outb(0, priv->plat->fan_reg_offset + MLXREG_HOTPLUG_EVENT_OFF);
/* Remove all the attached devices. */ /* Remove all the attached devices. */
for (i = 0; i < priv->plat->psu_count; i++) for (i = 0; i < priv->plat->psu_count; i++)
mlxcpld_hotplug_device_destroy(priv->plat->psu + i); mlxreg_hotplug_device_destroy(priv->plat->psu + i);
for (i = 0; i < priv->plat->pwr_count; i++) for (i = 0; i < priv->plat->pwr_count; i++)
mlxcpld_hotplug_device_destroy(priv->plat->pwr + i); mlxreg_hotplug_device_destroy(priv->plat->pwr + i);
for (i = 0; i < priv->plat->fan_count; i++) for (i = 0; i < priv->plat->fan_count; i++)
mlxcpld_hotplug_device_destroy(priv->plat->fan + i); mlxreg_hotplug_device_destroy(priv->plat->fan + i);
} }
static irqreturn_t mlxcpld_hotplug_irq_handler(int irq, void *dev) static irqreturn_t mlxreg_hotplug_irq_handler(int irq, void *dev)
{ {
struct mlxcpld_hotplug_priv_data *priv = struct mlxreg_hotplug_priv_data *priv =
(struct mlxcpld_hotplug_priv_data *)dev; (struct mlxreg_hotplug_priv_data *)dev;
/* Schedule work task for immediate execution.*/ /* Schedule work task for immediate execution.*/
schedule_delayed_work(&priv->dwork, 0); schedule_delayed_work(&priv->dwork, 0);
@ -429,10 +428,10 @@ static irqreturn_t mlxcpld_hotplug_irq_handler(int irq, void *dev)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static int mlxcpld_hotplug_probe(struct platform_device *pdev) static int mlxreg_hotplug_probe(struct platform_device *pdev)
{ {
struct mlxcpld_hotplug_platform_data *pdata; struct mlxreg_hotplug_platform_data *pdata;
struct mlxcpld_hotplug_priv_data *priv; struct mlxreg_hotplug_priv_data *priv;
int err; int err;
pdata = dev_get_platdata(&pdev->dev); pdata = dev_get_platdata(&pdev->dev);
@ -456,7 +455,7 @@ static int mlxcpld_hotplug_probe(struct platform_device *pdev)
} }
err = devm_request_irq(&pdev->dev, priv->irq, err = devm_request_irq(&pdev->dev, priv->irq,
mlxcpld_hotplug_irq_handler, 0, pdev->name, mlxreg_hotplug_irq_handler, 0, pdev->name,
priv); priv);
if (err) { if (err) {
dev_err(&pdev->dev, "Failed to request irq: %d\n", err); dev_err(&pdev->dev, "Failed to request irq: %d\n", err);
@ -464,17 +463,17 @@ static int mlxcpld_hotplug_probe(struct platform_device *pdev)
} }
disable_irq(priv->irq); disable_irq(priv->irq);
INIT_DELAYED_WORK(&priv->dwork, mlxcpld_hotplug_work_handler); INIT_DELAYED_WORK(&priv->dwork, mlxreg_hotplug_work_handler);
spin_lock_init(&priv->lock); spin_lock_init(&priv->lock);
err = mlxcpld_hotplug_attr_init(priv); err = mlxreg_hotplug_attr_init(priv);
if (err) { if (err) {
dev_err(&pdev->dev, "Failed to allocate attributes: %d\n", err); dev_err(&pdev->dev, "Failed to allocate attributes: %d\n", err);
return err; return err;
} }
priv->hwmon = devm_hwmon_device_register_with_groups(&pdev->dev, priv->hwmon = devm_hwmon_device_register_with_groups(&pdev->dev,
"mlxcpld_hotplug", priv, priv->groups); "mlxreg_hotplug", priv, priv->groups);
if (IS_ERR(priv->hwmon)) { if (IS_ERR(priv->hwmon)) {
dev_err(&pdev->dev, "Failed to register hwmon device %ld\n", dev_err(&pdev->dev, "Failed to register hwmon device %ld\n",
PTR_ERR(priv->hwmon)); PTR_ERR(priv->hwmon));
@ -484,32 +483,32 @@ static int mlxcpld_hotplug_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, priv); platform_set_drvdata(pdev, priv);
/* Perform initial interrupts setup. */ /* Perform initial interrupts setup. */
mlxcpld_hotplug_set_irq(priv); mlxreg_hotplug_set_irq(priv);
return 0; return 0;
} }
static int mlxcpld_hotplug_remove(struct platform_device *pdev) static int mlxreg_hotplug_remove(struct platform_device *pdev)
{ {
struct mlxcpld_hotplug_priv_data *priv = platform_get_drvdata(pdev); struct mlxreg_hotplug_priv_data *priv = platform_get_drvdata(pdev);
/* Clean interrupts setup. */ /* Clean interrupts setup. */
mlxcpld_hotplug_unset_irq(priv); mlxreg_hotplug_unset_irq(priv);
return 0; return 0;
} }
static struct platform_driver mlxcpld_hotplug_driver = { static struct platform_driver mlxreg_hotplug_driver = {
.driver = { .driver = {
.name = "mlxcpld-hotplug", .name = "mlxreg-hotplug",
}, },
.probe = mlxcpld_hotplug_probe, .probe = mlxreg_hotplug_probe,
.remove = mlxcpld_hotplug_remove, .remove = mlxreg_hotplug_remove,
}; };
module_platform_driver(mlxcpld_hotplug_driver); module_platform_driver(mlxreg_hotplug_driver);
MODULE_AUTHOR("Vadim Pasternak <vadimp@mellanox.com>"); MODULE_AUTHOR("Vadim Pasternak <vadimp@mellanox.com>");
MODULE_DESCRIPTION("Mellanox CPLD hotplug platform driver"); MODULE_DESCRIPTION("Mellanox regmap hotplug platform driver");
MODULE_LICENSE("Dual BSD/GPL"); MODULE_LICENSE("Dual BSD/GPL");
MODULE_ALIAS("platform:mlxcpld-hotplug"); MODULE_ALIAS("platform:mlxreg-hotplug");

View File

@ -1169,14 +1169,6 @@ config MLX_PLATFORM
If you have a Mellanox system, say Y or M here. If you have a Mellanox system, say Y or M here.
config MLX_CPLD_PLATFORM
tristate "Mellanox platform hotplug driver support"
select HWMON
select I2C
---help---
This driver handles hot-plug events for the power suppliers, power
cables and fans on the wide range Mellanox IB and Ethernet systems.
config INTEL_TURBO_MAX_3 config INTEL_TURBO_MAX_3
bool "Intel Turbo Boost Max Technology 3.0 enumeration driver" bool "Intel Turbo Boost Max Technology 3.0 enumeration driver"
depends on X86_64 && SCHED_MC_PRIO depends on X86_64 && SCHED_MC_PRIO

View File

@ -88,6 +88,5 @@ obj-$(CONFIG_INTEL_TELEMETRY) += intel_telemetry_core.o \
obj-$(CONFIG_INTEL_PMC_CORE) += intel_pmc_core.o obj-$(CONFIG_INTEL_PMC_CORE) += intel_pmc_core.o
obj-$(CONFIG_PMC_ATOM) += pmc_atom.o obj-$(CONFIG_PMC_ATOM) += pmc_atom.o
obj-$(CONFIG_MLX_PLATFORM) += mlx-platform.o obj-$(CONFIG_MLX_PLATFORM) += mlx-platform.o
obj-$(CONFIG_MLX_CPLD_PLATFORM) += mlxcpld-hotplug.o
obj-$(CONFIG_INTEL_TURBO_MAX_3) += intel_turbo_max_3.o obj-$(CONFIG_INTEL_TURBO_MAX_3) += intel_turbo_max_3.o
obj-$(CONFIG_INTEL_CHTDC_TI_PWRBTN) += intel_chtdc_ti_pwrbtn.o obj-$(CONFIG_INTEL_CHTDC_TI_PWRBTN) += intel_chtdc_ti_pwrbtn.o

View File

@ -38,7 +38,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/platform_data/i2c-mux-reg.h> #include <linux/platform_data/i2c-mux-reg.h>
#include <linux/platform_data/mlxcpld-hotplug.h> #include <linux/platform_data/mlxreg.h>
#define MLX_PLAT_DEVICE_NAME "mlxplat" #define MLX_PLAT_DEVICE_NAME "mlxplat"
@ -138,7 +138,7 @@ static struct i2c_mux_reg_platform_data mlxplat_mux_data[] = {
}; };
/* Platform hotplug devices */ /* Platform hotplug devices */
static struct mlxcpld_hotplug_device mlxplat_mlxcpld_psu[] = { static struct mlxreg_hotplug_device mlxplat_mlxcpld_psu[] = {
{ {
.brdinfo = { I2C_BOARD_INFO("24c02", 0x51) }, .brdinfo = { I2C_BOARD_INFO("24c02", 0x51) },
.bus = 10, .bus = 10,
@ -149,7 +149,7 @@ static struct mlxcpld_hotplug_device mlxplat_mlxcpld_psu[] = {
}, },
}; };
static struct mlxcpld_hotplug_device mlxplat_mlxcpld_pwr[] = { static struct mlxreg_hotplug_device mlxplat_mlxcpld_pwr[] = {
{ {
.brdinfo = { I2C_BOARD_INFO("dps460", 0x59) }, .brdinfo = { I2C_BOARD_INFO("dps460", 0x59) },
.bus = 10, .bus = 10,
@ -160,7 +160,7 @@ static struct mlxcpld_hotplug_device mlxplat_mlxcpld_pwr[] = {
}, },
}; };
static struct mlxcpld_hotplug_device mlxplat_mlxcpld_fan[] = { static struct mlxreg_hotplug_device mlxplat_mlxcpld_fan[] = {
{ {
.brdinfo = { I2C_BOARD_INFO("24c32", 0x50) }, .brdinfo = { I2C_BOARD_INFO("24c32", 0x50) },
.bus = 11, .bus = 11,
@ -181,7 +181,7 @@ static struct mlxcpld_hotplug_device mlxplat_mlxcpld_fan[] = {
/* Platform hotplug default data */ /* Platform hotplug default data */
static static
struct mlxcpld_hotplug_platform_data mlxplat_mlxcpld_default_data = { struct mlxreg_hotplug_platform_data mlxplat_mlxcpld_default_data = {
.top_aggr_offset = MLXPLAT_CPLD_LPC_REG_AGGR_ADRR, .top_aggr_offset = MLXPLAT_CPLD_LPC_REG_AGGR_ADRR,
.top_aggr_mask = MLXPLAT_CPLD_AGGR_MASK_DEF, .top_aggr_mask = MLXPLAT_CPLD_AGGR_MASK_DEF,
.top_aggr_psu_mask = MLXPLAT_CPLD_AGGR_PSU_MASK_DEF, .top_aggr_psu_mask = MLXPLAT_CPLD_AGGR_PSU_MASK_DEF,
@ -203,7 +203,7 @@ struct mlxcpld_hotplug_platform_data mlxplat_mlxcpld_default_data = {
/* Platform hotplug MSN21xx system family data */ /* Platform hotplug MSN21xx system family data */
static static
struct mlxcpld_hotplug_platform_data mlxplat_mlxcpld_msn21xx_data = { struct mlxreg_hotplug_platform_data mlxplat_mlxcpld_msn21xx_data = {
.top_aggr_offset = MLXPLAT_CPLD_LPC_REG_AGGR_ADRR, .top_aggr_offset = MLXPLAT_CPLD_LPC_REG_AGGR_ADRR,
.top_aggr_mask = MLXPLAT_CPLD_AGGR_MASK_MSN21XX, .top_aggr_mask = MLXPLAT_CPLD_AGGR_MASK_MSN21XX,
.top_aggr_pwr_mask = MLXPLAT_CPLD_AGGR_MASK_MSN21XX, .top_aggr_pwr_mask = MLXPLAT_CPLD_AGGR_MASK_MSN21XX,
@ -213,11 +213,11 @@ struct mlxcpld_hotplug_platform_data mlxplat_mlxcpld_msn21xx_data = {
}; };
static struct resource mlxplat_mlxcpld_resources[] = { static struct resource mlxplat_mlxcpld_resources[] = {
[0] = DEFINE_RES_IRQ_NAMED(17, "mlxcpld-hotplug"), [0] = DEFINE_RES_IRQ_NAMED(17, "mlxreg-hotplug"),
}; };
static struct platform_device *mlxplat_dev; static struct platform_device *mlxplat_dev;
static struct mlxcpld_hotplug_platform_data *mlxplat_hotplug; static struct mlxreg_hotplug_platform_data *mlxplat_hotplug;
static int __init mlxplat_dmi_default_matched(const struct dmi_system_id *dmi) static int __init mlxplat_dmi_default_matched(const struct dmi_system_id *dmi)
{ {
@ -329,7 +329,7 @@ static int __init mlxplat_init(void)
} }
priv->pdev_hotplug = platform_device_register_resndata( priv->pdev_hotplug = platform_device_register_resndata(
&mlxplat_dev->dev, "mlxcpld-hotplug", &mlxplat_dev->dev, "mlxreg-hotplug",
PLATFORM_DEVID_NONE, PLATFORM_DEVID_NONE,
mlxplat_mlxcpld_resources, mlxplat_mlxcpld_resources,
ARRAY_SIZE(mlxplat_mlxcpld_resources), ARRAY_SIZE(mlxplat_mlxcpld_resources),

View File

@ -1,7 +1,6 @@
/* /*
* include/linux/platform_data/mlxcpld-hotplug.h * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
* Copyright (c) 2016 Mellanox Technologies. All rights reserved. * Copyright (c) 2017 Vadim Pasternak <vadimp@mellanox.com>
* Copyright (c) 2016 Vadim Pasternak <vadimp@mellanox.com>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
@ -32,11 +31,11 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef __LINUX_PLATFORM_DATA_MLXCPLD_HOTPLUG_H #ifndef __LINUX_PLATFORM_DATA_MLXREG_H
#define __LINUX_PLATFORM_DATA_MLXCPLD_HOTPLUG_H #define __LINUX_PLATFORM_DATA_MLXREG_H
/** /**
* struct mlxcpld_hotplug_device - I2C device data: * struct mlxreg_hotplug_device - I2C device data:
* @adapter: I2C device adapter; * @adapter: I2C device adapter;
* @client: I2C device client; * @client: I2C device client;
* @brdinfo: device board information; * @brdinfo: device board information;
@ -45,7 +44,7 @@
* Structure represents I2C hotplug device static data (board topology) and * Structure represents I2C hotplug device static data (board topology) and
* dynamic data (related kernel objects handles). * dynamic data (related kernel objects handles).
*/ */
struct mlxcpld_hotplug_device { struct mlxreg_hotplug_device {
struct i2c_adapter *adapter; struct i2c_adapter *adapter;
struct i2c_client *client; struct i2c_client *client;
struct i2c_board_info brdinfo; struct i2c_board_info brdinfo;
@ -53,7 +52,7 @@ struct mlxcpld_hotplug_device {
}; };
/** /**
* struct mlxcpld_hotplug_platform_data - device platform data: * struct mlxreg_hotplug_platform_data - device platform data:
* @top_aggr_offset: offset of top aggregation interrupt register; * @top_aggr_offset: offset of top aggregation interrupt register;
* @top_aggr_mask: top aggregation interrupt common mask; * @top_aggr_mask: top aggregation interrupt common mask;
* @top_aggr_psu_mask: top aggregation interrupt PSU mask; * @top_aggr_psu_mask: top aggregation interrupt PSU mask;
@ -76,24 +75,24 @@ struct mlxcpld_hotplug_device {
* like FAN, PSU, power cable insertion and removing. This data provides the * like FAN, PSU, power cable insertion and removing. This data provides the
* number of hot-pluggable devices and hardware description for event handling. * number of hot-pluggable devices and hardware description for event handling.
*/ */
struct mlxcpld_hotplug_platform_data { struct mlxreg_hotplug_platform_data {
u16 top_aggr_offset; u16 top_aggr_offset;
u8 top_aggr_mask; u8 top_aggr_mask;
u8 top_aggr_psu_mask; u8 top_aggr_psu_mask;
u16 psu_reg_offset; u16 psu_reg_offset;
u8 psu_mask; u8 psu_mask;
u8 psu_count; u8 psu_count;
struct mlxcpld_hotplug_device *psu; struct mlxreg_hotplug_device *psu;
u8 top_aggr_pwr_mask; u8 top_aggr_pwr_mask;
u16 pwr_reg_offset; u16 pwr_reg_offset;
u8 pwr_mask; u8 pwr_mask;
u8 pwr_count; u8 pwr_count;
struct mlxcpld_hotplug_device *pwr; struct mlxreg_hotplug_device *pwr;
u8 top_aggr_fan_mask; u8 top_aggr_fan_mask;
u16 fan_reg_offset; u16 fan_reg_offset;
u8 fan_mask; u8 fan_mask;
u8 fan_count; u8 fan_count;
struct mlxcpld_hotplug_device *fan; struct mlxreg_hotplug_device *fan;
}; };
#endif /* __LINUX_PLATFORM_DATA_MLXCPLD_HOTPLUG_H */ #endif /* __LINUX_PLATFORM_DATA_MLXREG_H */