99#include <linux/mutex.h>
1010#include <linux/module.h>
1111#include <linux/mod_devicetable.h>
12+ #include <linux/platform_data/mlxreg.h>
1213#include <linux/slab.h>
1314
1415#include "cmd.h"
5152#define MLXSW_I2C_TIMEOUT_MSECS 5000
5253#define MLXSW_I2C_MAX_DATA_SIZE 256
5354
55+ /* Driver can be initialized by kernel platform driver or from the user
56+ * space. In the first case IRQ line number is passed through the platform
57+ * data, otherwise default IRQ line is to be used. Default IRQ is relevant
58+ * only for specific I2C slave address, allowing 3.4 MHz I2C path to the chip
59+ * (special hardware feature for I2C acceleration).
60+ */
61+ #define MLXSW_I2C_DEFAULT_IRQ 17
62+ #define MLXSW_FAST_I2C_SLAVE 0x37
63+
5464/**
5565 * struct mlxsw_i2c - device private data:
5666 * @cmd: command attributes;
6373 * @core: switch core pointer;
6474 * @bus_info: bus info block;
6575 * @block_size: maximum block size allowed to pass to under layer;
76+ * @pdata: device platform data;
77+ * @irq_work: interrupts work item;
78+ * @irq: IRQ line number;
6679 */
6780struct mlxsw_i2c {
6881 struct {
@@ -76,6 +89,9 @@ struct mlxsw_i2c {
7689 struct mlxsw_core * core ;
7790 struct mlxsw_bus_info bus_info ;
7891 u16 block_size ;
92+ struct mlxreg_core_hotplug_platform_data * pdata ;
93+ struct work_struct irq_work ;
94+ int irq ;
7995};
8096
8197#define MLXSW_I2C_READ_MSG (_client , _addr_buf , _buf , _len ) { \
@@ -546,6 +562,67 @@ static void mlxsw_i2c_fini(void *bus_priv)
546562 mlxsw_i2c -> core = NULL ;
547563}
548564
565+ static void mlxsw_i2c_work_handler (struct work_struct * work )
566+ {
567+ struct mlxsw_i2c * mlxsw_i2c ;
568+
569+ mlxsw_i2c = container_of (work , struct mlxsw_i2c , irq_work );
570+ mlxsw_core_irq_event_handlers_call (mlxsw_i2c -> core );
571+ }
572+
573+ static irqreturn_t mlxsw_i2c_irq_handler (int irq , void * dev )
574+ {
575+ struct mlxsw_i2c * mlxsw_i2c = dev ;
576+
577+ mlxsw_core_schedule_work (& mlxsw_i2c -> irq_work );
578+
579+ /* Interrupt handler shares IRQ line with 'main' interrupt handler.
580+ * Return here IRQ_NONE, while main handler will return IRQ_HANDLED.
581+ */
582+ return IRQ_NONE ;
583+ }
584+
585+ static int mlxsw_i2c_irq_init (struct mlxsw_i2c * mlxsw_i2c , u8 addr )
586+ {
587+ int err ;
588+
589+ /* Initialize interrupt handler if system hotplug driver is reachable,
590+ * otherwise interrupt line is not enabled and interrupts will not be
591+ * raised to CPU. Also request_irq() call will be not valid.
592+ */
593+ if (!IS_REACHABLE (CONFIG_MLXREG_HOTPLUG ))
594+ return 0 ;
595+
596+ /* Set default interrupt line. */
597+ if (mlxsw_i2c -> pdata && mlxsw_i2c -> pdata -> irq )
598+ mlxsw_i2c -> irq = mlxsw_i2c -> pdata -> irq ;
599+ else if (addr == MLXSW_FAST_I2C_SLAVE )
600+ mlxsw_i2c -> irq = MLXSW_I2C_DEFAULT_IRQ ;
601+
602+ if (!mlxsw_i2c -> irq )
603+ return 0 ;
604+
605+ INIT_WORK (& mlxsw_i2c -> irq_work , mlxsw_i2c_work_handler );
606+ err = request_irq (mlxsw_i2c -> irq , mlxsw_i2c_irq_handler ,
607+ IRQF_TRIGGER_FALLING | IRQF_SHARED , "mlxsw-i2c" ,
608+ mlxsw_i2c );
609+ if (err ) {
610+ dev_err (mlxsw_i2c -> bus_info .dev , "Failed to request irq: %d\n" ,
611+ err );
612+ return err ;
613+ }
614+
615+ return 0 ;
616+ }
617+
618+ static void mlxsw_i2c_irq_fini (struct mlxsw_i2c * mlxsw_i2c )
619+ {
620+ if (!IS_REACHABLE (CONFIG_MLXREG_HOTPLUG ) || !mlxsw_i2c -> irq )
621+ return ;
622+ cancel_work_sync (& mlxsw_i2c -> irq_work );
623+ free_irq (mlxsw_i2c -> irq , mlxsw_i2c );
624+ }
625+
549626static const struct mlxsw_bus mlxsw_i2c_bus = {
550627 .kind = "i2c" ,
551628 .init = mlxsw_i2c_init ,
@@ -638,17 +715,24 @@ static int mlxsw_i2c_probe(struct i2c_client *client,
638715 mlxsw_i2c -> bus_info .dev = & client -> dev ;
639716 mlxsw_i2c -> bus_info .low_frequency = true;
640717 mlxsw_i2c -> dev = & client -> dev ;
718+ mlxsw_i2c -> pdata = client -> dev .platform_data ;
719+
720+ err = mlxsw_i2c_irq_init (mlxsw_i2c , client -> addr );
721+ if (err )
722+ goto errout ;
641723
642724 err = mlxsw_core_bus_device_register (& mlxsw_i2c -> bus_info ,
643725 & mlxsw_i2c_bus , mlxsw_i2c , false,
644726 NULL , NULL );
645727 if (err ) {
646728 dev_err (& client -> dev , "Fail to register core bus\n" );
647- return err ;
729+ goto err_bus_device_register ;
648730 }
649731
650732 return 0 ;
651733
734+ err_bus_device_register :
735+ mlxsw_i2c_irq_fini (mlxsw_i2c );
652736errout :
653737 mutex_destroy (& mlxsw_i2c -> cmd .lock );
654738 i2c_set_clientdata (client , NULL );
@@ -661,6 +745,7 @@ static int mlxsw_i2c_remove(struct i2c_client *client)
661745 struct mlxsw_i2c * mlxsw_i2c = i2c_get_clientdata (client );
662746
663747 mlxsw_core_bus_device_unregister (mlxsw_i2c -> core , false);
748+ mlxsw_i2c_irq_fini (mlxsw_i2c );
664749 mutex_destroy (& mlxsw_i2c -> cmd .lock );
665750
666751 return 0 ;
0 commit comments