Commit 6a02f5eb authored by David S. Miller's avatar David S. Miller

Merge branch 'mlxsw-i2c'

Jiri Pirko says:

====================
mlxsw: Introduce support for I2C bus

Vadim says:

This patchset adds I2C access support for SwitchX, SwitchX2, SwitchIB,
SwitchIB2 and Spectrum silicones.

It contains:
 - Small changes in mlxsw core code, needed for I2C bus support;
 - I2C driver, which obtains I2C input/output mailboxes setting and
   provides command interface implementation.
 - Minimal driver, which works on top of I2C driver and allows running
   of mlxsw command interface over I2C bus;

Use case:
On system, which does not have PCI to ASIC (BMC), hwmon functionality
(sensors, pwm, tacho) will be available through I2C.

Usage (manual probing):
echo mlxsw_minimal 0x48 > /sys/bus/i2c/devices/i2c-2/new_device

Sysfs interface:
/sys/bus/i2c/devices/2-0048/hwmon/hwmon5/pwm1
/sys/bus/i2c/devices/2-0048/hwmon/hwmon5/temp1_input
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents d01eb808 d556e929
......@@ -29,6 +29,16 @@ config MLXSW_PCI
To compile this driver as a module, choose M here: the
module will be called mlxsw_pci.
config MLXSW_I2C
tristate "I2C bus implementation for Mellanox Technologies Switch ASICs"
depends on I2C && MLXSW_CORE
default m
---help---
This is I2C bus implementation for Mellanox Technologies Switch ASICs.
To compile this driver as a module, choose M here: the
module will be called mlxsw_i2c.
config MLXSW_SWITCHIB
tristate "Mellanox Technologies SwitchIB and SwitchIB-2 support"
depends on MLXSW_CORE && NET_SWITCHDEV
......@@ -69,3 +79,14 @@ config MLXSW_SPECTRUM_DCB
---help---
Say Y here if you want to use Data Center Bridging (DCB) in the
driver.
config MLXSW_MINIMAL
tristate "Mellanox Technologies minimal I2C support"
depends on MLXSW_CORE && MLXSW_I2C
default m
---help---
This driver supports I2C access for Mellanox Technologies Switch
ASICs.
To compile this driver as a module, choose M here: the
module will be called mlxsw_minimal.
......@@ -3,6 +3,8 @@ mlxsw_core-objs := core.o
mlxsw_core-$(CONFIG_MLXSW_CORE_HWMON) += core_hwmon.o
obj-$(CONFIG_MLXSW_PCI) += mlxsw_pci.o
mlxsw_pci-objs := pci.o
obj-$(CONFIG_MLXSW_I2C) += mlxsw_i2c.o
mlxsw_i2c-objs := i2c.o
obj-$(CONFIG_MLXSW_SWITCHIB) += mlxsw_switchib.o
mlxsw_switchib-objs := switchib.o
obj-$(CONFIG_MLXSW_SWITCHX2) += mlxsw_switchx2.o
......@@ -12,3 +14,5 @@ mlxsw_spectrum-objs := spectrum.o spectrum_buffers.o \
spectrum_switchdev.o spectrum_router.o \
spectrum_kvdl.o
mlxsw_spectrum-$(CONFIG_MLXSW_SPECTRUM_DCB) += spectrum_dcb.o
obj-$(CONFIG_MLXSW_MINIMAL) += mlxsw_minimal.o
mlxsw_minimal-objs := minimal.o
......@@ -598,6 +598,9 @@ static int mlxsw_emad_init(struct mlxsw_core *mlxsw_core)
u64 tid;
int err;
if (!(mlxsw_core->bus->features & MLXSW_BUS_F_TXRX))
return 0;
/* Set the upper 32 bits of the transaction ID field to a random
* number. This allows us to discard EMADs addressed to other
* devices.
......@@ -634,6 +637,9 @@ static void mlxsw_emad_fini(struct mlxsw_core *mlxsw_core)
{
char hpkt_pl[MLXSW_REG_HPKT_LEN];
if (!(mlxsw_core->bus->features & MLXSW_BUS_F_TXRX))
return;
mlxsw_core->emad.use_emad = false;
mlxsw_reg_hpkt_pack(hpkt_pl, MLXSW_REG_HPKT_ACTION_DISCARD,
MLXSW_TRAP_ID_ETHEMAD);
......@@ -1156,9 +1162,11 @@ int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
if (err)
goto err_hwmon_init;
if (mlxsw_driver->init) {
err = mlxsw_driver->init(mlxsw_core, mlxsw_bus_info);
if (err)
goto err_driver_init;
}
err = mlxsw_core_debugfs_init(mlxsw_core);
if (err)
......@@ -1167,6 +1175,7 @@ int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
return 0;
err_debugfs_init:
if (mlxsw_core->driver->fini)
mlxsw_core->driver->fini(mlxsw_core);
err_driver_init:
err_hwmon_init:
......@@ -1193,6 +1202,7 @@ void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core)
struct devlink *devlink = priv_to_devlink(mlxsw_core);
mlxsw_core_debugfs_fini(mlxsw_core);
if (mlxsw_core->driver->fini)
mlxsw_core->driver->fini(mlxsw_core);
devlink_unregister(devlink);
mlxsw_emad_fini(mlxsw_core);
......
......@@ -268,6 +268,8 @@ u64 mlxsw_core_res_get(struct mlxsw_core *mlxsw_core,
#define MLXSW_CORE_RES_GET(res, short_res_id) \
mlxsw_core_res_get(res, MLXSW_RES_ID_##short_res_id)
#define MLXSW_BUS_F_TXRX BIT(0)
struct mlxsw_bus {
const char *kind;
int (*init)(void *bus_priv, struct mlxsw_core *mlxsw_core,
......@@ -283,6 +285,7 @@ struct mlxsw_bus {
char *in_mbox, size_t in_mbox_size,
char *out_mbox, size_t out_mbox_size,
u8 *p_status);
u8 features;
};
struct mlxsw_bus_info {
......
This diff is collapsed.
/*
* drivers/net/ethernet/mellanox/mlxsw/i2c.h
* Copyright (c) 2016 Mellanox Technologies. All rights reserved.
* Copyright (c) 2016 Vadim Pasternak <vadimp@mellanox.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _MLXSW_I2C_H
#define _MLXSW_I2C_H
#include <linux/i2c.h>
#if IS_ENABLED(CONFIG_MLXSW_I2C)
int mlxsw_i2c_driver_register(struct i2c_driver *i2c_driver);
void mlxsw_i2c_driver_unregister(struct i2c_driver *i2c_driver);
#else
static inline int
mlxsw_i2c_driver_register(struct i2c_driver *i2c_driver)
{
return -ENODEV;
}
static inline void
mlxsw_i2c_driver_unregister(struct i2c_driver *i2c_driver)
{
}
#endif
#endif
/*
* drivers/net/ethernet/mellanox/mlxsw/minimal.c
* Copyright (c) 2016 Mellanox Technologies. All rights reserved.
* Copyright (c) 2016 Vadim Pasternak <vadimp@mellanox.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/types.h>
#include "core.h"
#include "i2c.h"
static const char mlxsw_minimal_driver_name[] = "mlxsw_minimal";
static const struct mlxsw_config_profile mlxsw_minimal_config_profile;
static struct mlxsw_driver mlxsw_minimal_driver = {
.kind = mlxsw_minimal_driver_name,
.priv_size = 1,
.profile = &mlxsw_minimal_config_profile,
};
static const struct i2c_device_id mlxsw_minimal_i2c_id[] = {
{ "mlxsw_minimal", 0},
{ },
};
static struct i2c_driver mlxsw_minimal_i2c_driver = {
.driver.name = "mlxsw_minimal",
.class = I2C_CLASS_HWMON,
.id_table = mlxsw_minimal_i2c_id,
};
static int __init mlxsw_minimal_module_init(void)
{
int err;
err = mlxsw_core_driver_register(&mlxsw_minimal_driver);
if (err)
return err;
err = mlxsw_i2c_driver_register(&mlxsw_minimal_i2c_driver);
if (err)
goto err_i2c_driver_register;
return 0;
err_i2c_driver_register:
mlxsw_core_driver_unregister(&mlxsw_minimal_driver);
return err;
}
static void __exit mlxsw_minimal_module_exit(void)
{
mlxsw_i2c_driver_unregister(&mlxsw_minimal_i2c_driver);
mlxsw_core_driver_unregister(&mlxsw_minimal_driver);
}
module_init(mlxsw_minimal_module_init);
module_exit(mlxsw_minimal_module_exit);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Vadim Pasternak <vadimp@mellanox.com>");
MODULE_DESCRIPTION("Mellanox minimal driver");
MODULE_DEVICE_TABLE(i2c, mlxsw_minimal_i2c_id);
......@@ -1755,6 +1755,7 @@ static const struct mlxsw_bus mlxsw_pci_bus = {
.skb_transmit_busy = mlxsw_pci_skb_transmit_busy,
.skb_transmit = mlxsw_pci_skb_transmit,
.cmd_exec = mlxsw_pci_cmd_exec,
.features = MLXSW_BUS_F_TXRX,
};
static int mlxsw_pci_sw_reset(struct mlxsw_pci *mlxsw_pci,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment