Skip to content

Commit 2ab4e70

Browse files
vadimp-nvidiakuba-moo
authored andcommitted
mlxsw: core: Add registration APIs for system event handler
The purpose of system event handler is to handle system interrupts. Such interrupts are raised to CPU from system programmable logic devices, upon specific system wide changes, like line card activation and deactivation. The purpose is to create an alternative to trap mechanism, which delivers these events to driver over PCI bus, but not available for the driver working over I2C bus. Mechanism is system dependent and applicable only for the systems equipped with programmable devices with custom logic. Add APIs for event handler registration and un-registration and API which should be invoked from the registered callbacks when system interrupt is raised to CPU. Signed-off-by: Vadim Pasternak <vadimp@nvidia.com> Reviewed-by: Jiri Pirko <jiri@nvidia.com> Signed-off-by: Ido Schimmel <idosch@nvidia.com> Signed-off-by: Petr Machata <petrm@nvidia.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 4be4779 commit 2ab4e70

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed

drivers/net/ethernet/mellanox/mlxsw/core.c

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ struct mlxsw_core {
7070
struct workqueue_struct *emad_wq;
7171
struct list_head rx_listener_list;
7272
struct list_head event_listener_list;
73+
struct list_head irq_event_handler_list;
74+
struct mutex irq_event_handler_lock; /* Locks access to handlers list */
7375
struct {
7476
atomic64_t tid;
7577
struct list_head trans_list;
@@ -2090,6 +2092,18 @@ static void mlxsw_core_health_fini(struct mlxsw_core *mlxsw_core)
20902092
devlink_health_reporter_destroy(mlxsw_core->health.fw_fatal);
20912093
}
20922094

2095+
static void mlxsw_core_irq_event_handler_init(struct mlxsw_core *mlxsw_core)
2096+
{
2097+
INIT_LIST_HEAD(&mlxsw_core->irq_event_handler_list);
2098+
mutex_init(&mlxsw_core->irq_event_handler_lock);
2099+
}
2100+
2101+
static void mlxsw_core_irq_event_handler_fini(struct mlxsw_core *mlxsw_core)
2102+
{
2103+
mutex_destroy(&mlxsw_core->irq_event_handler_lock);
2104+
WARN_ON(!list_empty(&mlxsw_core->irq_event_handler_list));
2105+
}
2106+
20932107
static int
20942108
__mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
20952109
const struct mlxsw_bus *mlxsw_bus,
@@ -2125,6 +2139,7 @@ __mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
21252139
mlxsw_core->bus = mlxsw_bus;
21262140
mlxsw_core->bus_priv = bus_priv;
21272141
mlxsw_core->bus_info = mlxsw_bus_info;
2142+
mlxsw_core_irq_event_handler_init(mlxsw_core);
21282143

21292144
err = mlxsw_bus->init(bus_priv, mlxsw_core, mlxsw_driver->profile,
21302145
&mlxsw_core->res);
@@ -2233,6 +2248,7 @@ __mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
22332248
err_register_resources:
22342249
mlxsw_bus->fini(bus_priv);
22352250
err_bus_init:
2251+
mlxsw_core_irq_event_handler_fini(mlxsw_core);
22362252
if (!reload) {
22372253
devl_unlock(devlink);
22382254
devlink_free(devlink);
@@ -2302,6 +2318,7 @@ void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core,
23022318
if (!reload)
23032319
devl_resources_unregister(devlink);
23042320
mlxsw_core->bus->fini(mlxsw_core->bus_priv);
2321+
mlxsw_core_irq_event_handler_fini(mlxsw_core);
23052322
if (!reload) {
23062323
devl_unlock(devlink);
23072324
devlink_free(devlink);
@@ -2772,6 +2789,57 @@ int mlxsw_reg_trans_bulk_wait(struct list_head *bulk_list)
27722789
}
27732790
EXPORT_SYMBOL(mlxsw_reg_trans_bulk_wait);
27742791

2792+
struct mlxsw_core_irq_event_handler_item {
2793+
struct list_head list;
2794+
void (*cb)(struct mlxsw_core *mlxsw_core);
2795+
};
2796+
2797+
int mlxsw_core_irq_event_handler_register(struct mlxsw_core *mlxsw_core,
2798+
mlxsw_irq_event_cb_t cb)
2799+
{
2800+
struct mlxsw_core_irq_event_handler_item *item;
2801+
2802+
item = kzalloc(sizeof(*item), GFP_KERNEL);
2803+
if (!item)
2804+
return -ENOMEM;
2805+
item->cb = cb;
2806+
mutex_lock(&mlxsw_core->irq_event_handler_lock);
2807+
list_add_tail(&item->list, &mlxsw_core->irq_event_handler_list);
2808+
mutex_unlock(&mlxsw_core->irq_event_handler_lock);
2809+
return 0;
2810+
}
2811+
EXPORT_SYMBOL(mlxsw_core_irq_event_handler_register);
2812+
2813+
void mlxsw_core_irq_event_handler_unregister(struct mlxsw_core *mlxsw_core,
2814+
mlxsw_irq_event_cb_t cb)
2815+
{
2816+
struct mlxsw_core_irq_event_handler_item *item, *tmp;
2817+
2818+
mutex_lock(&mlxsw_core->irq_event_handler_lock);
2819+
list_for_each_entry_safe(item, tmp,
2820+
&mlxsw_core->irq_event_handler_list, list) {
2821+
if (item->cb == cb) {
2822+
list_del(&item->list);
2823+
kfree(item);
2824+
}
2825+
}
2826+
mutex_unlock(&mlxsw_core->irq_event_handler_lock);
2827+
}
2828+
EXPORT_SYMBOL(mlxsw_core_irq_event_handler_unregister);
2829+
2830+
void mlxsw_core_irq_event_handlers_call(struct mlxsw_core *mlxsw_core)
2831+
{
2832+
struct mlxsw_core_irq_event_handler_item *item;
2833+
2834+
mutex_lock(&mlxsw_core->irq_event_handler_lock);
2835+
list_for_each_entry(item, &mlxsw_core->irq_event_handler_list, list) {
2836+
if (item->cb)
2837+
item->cb(mlxsw_core);
2838+
}
2839+
mutex_unlock(&mlxsw_core->irq_event_handler_lock);
2840+
}
2841+
EXPORT_SYMBOL(mlxsw_core_irq_event_handlers_call);
2842+
27752843
static int mlxsw_core_reg_access_cmd(struct mlxsw_core *mlxsw_core,
27762844
const struct mlxsw_reg_info *reg,
27772845
char *payload,

drivers/net/ethernet/mellanox/mlxsw/core.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,14 @@ int mlxsw_reg_trans_write(struct mlxsw_core *mlxsw_core,
215215
mlxsw_reg_trans_cb_t *cb, unsigned long cb_priv);
216216
int mlxsw_reg_trans_bulk_wait(struct list_head *bulk_list);
217217

218+
typedef void mlxsw_irq_event_cb_t(struct mlxsw_core *mlxsw_core);
219+
220+
int mlxsw_core_irq_event_handler_register(struct mlxsw_core *mlxsw_core,
221+
mlxsw_irq_event_cb_t cb);
222+
void mlxsw_core_irq_event_handler_unregister(struct mlxsw_core *mlxsw_core,
223+
mlxsw_irq_event_cb_t cb);
224+
void mlxsw_core_irq_event_handlers_call(struct mlxsw_core *mlxsw_core);
225+
218226
int mlxsw_reg_query(struct mlxsw_core *mlxsw_core,
219227
const struct mlxsw_reg_info *reg, char *payload);
220228
int mlxsw_reg_write(struct mlxsw_core *mlxsw_core,

0 commit comments

Comments
 (0)