Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 61303736 authored by Andrew Lunn's avatar Andrew Lunn Committed by David S. Miller
Browse files

net: dsa: mv88e6xxx: Add mv88e6390 watchdog interrupt support



Implement the ops needed to support the watchdog for the MV88E6390
family.

Signed-off-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent fcd25166
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -3419,6 +3419,7 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
	.stats_get_stats = mv88e6390_stats_get_stats,
	.g1_set_cpu_port = mv88e6390_g1_set_cpu_port,
	.g1_set_egress_port = mv88e6390_g1_set_egress_port,
	.watchdog_ops = &mv88e6390_watchdog_ops,
	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
	.reset = mv88e6352_g1_reset,
};
@@ -3446,6 +3447,7 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
	.stats_get_stats = mv88e6390_stats_get_stats,
	.g1_set_cpu_port = mv88e6390_g1_set_cpu_port,
	.g1_set_egress_port = mv88e6390_g1_set_egress_port,
	.watchdog_ops = &mv88e6390_watchdog_ops,
	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
	.reset = mv88e6352_g1_reset,
};
@@ -3473,6 +3475,7 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
	.stats_get_stats = mv88e6390_stats_get_stats,
	.g1_set_cpu_port = mv88e6390_g1_set_cpu_port,
	.g1_set_egress_port = mv88e6390_g1_set_egress_port,
	.watchdog_ops = &mv88e6390_watchdog_ops,
	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
	.reset = mv88e6352_g1_reset,
};
@@ -3530,6 +3533,7 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
	.stats_get_stats = mv88e6390_stats_get_stats,
	.g1_set_cpu_port = mv88e6390_g1_set_cpu_port,
	.g1_set_egress_port = mv88e6390_g1_set_egress_port,
	.watchdog_ops = &mv88e6390_watchdog_ops,
	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
	.reset = mv88e6352_g1_reset,
};
@@ -3694,6 +3698,7 @@ static const struct mv88e6xxx_ops mv88e6141_ops = {
	.stats_get_stats = mv88e6390_stats_get_stats,
	.g1_set_cpu_port = mv88e6390_g1_set_cpu_port,
	.g1_set_egress_port = mv88e6390_g1_set_egress_port,
	.watchdog_ops = &mv88e6390_watchdog_ops,
	.mgmt_rsvd2cpu =  mv88e6390_g1_mgmt_rsvd2cpu,
	.reset = mv88e6352_g1_reset,
};
@@ -3722,6 +3727,7 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
	.stats_get_stats = mv88e6390_stats_get_stats,
	.g1_set_cpu_port = mv88e6390_g1_set_cpu_port,
	.g1_set_egress_port = mv88e6390_g1_set_egress_port,
	.watchdog_ops = &mv88e6390_watchdog_ops,
	.mgmt_rsvd2cpu =  mv88e6390_g1_mgmt_rsvd2cpu,
	.reset = mv88e6352_g1_reset,
};
@@ -3752,6 +3758,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
	.stats_get_stats = mv88e6390_stats_get_stats,
	.g1_set_cpu_port = mv88e6390_g1_set_cpu_port,
	.g1_set_egress_port = mv88e6390_g1_set_egress_port,
	.watchdog_ops = &mv88e6390_watchdog_ops,
	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
	.reset = mv88e6352_g1_reset,
};
@@ -3781,6 +3788,7 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
	.stats_get_stats = mv88e6390_stats_get_stats,
	.g1_set_cpu_port = mv88e6390_g1_set_cpu_port,
	.g1_set_egress_port = mv88e6390_g1_set_egress_port,
	.watchdog_ops = &mv88e6390_watchdog_ops,
	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
	.reset = mv88e6352_g1_reset,
};
@@ -3808,6 +3816,7 @@ static const struct mv88e6xxx_ops mv88e6391_ops = {
	.stats_get_stats = mv88e6390_stats_get_stats,
	.g1_set_cpu_port = mv88e6390_g1_set_cpu_port,
	.g1_set_egress_port = mv88e6390_g1_set_egress_port,
	.watchdog_ops = &mv88e6390_watchdog_ops,
	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
	.reset = mv88e6352_g1_reset,
};
+48 −0
Original line number Diff line number Diff line
@@ -686,6 +686,54 @@ const struct mv88e6xxx_irq_ops mv88e6097_watchdog_ops = {
	.irq_free = mv88e6097_watchdog_free,
};

static int mv88e6390_watchdog_setup(struct mv88e6xxx_chip *chip)
{
	return mv88e6xxx_g2_update(chip, GLOBAL2_WDOG_CONTROL,
				   GLOBAL2_WDOG_INT_ENABLE |
				   GLOBAL2_WDOG_CUT_THROUGH |
				   GLOBAL2_WDOG_QUEUE_CONTROLLER |
				   GLOBAL2_WDOG_EGRESS |
				   GLOBAL2_WDOG_FORCE_IRQ);
}

static int mv88e6390_watchdog_action(struct mv88e6xxx_chip *chip, int irq)
{
	int err;
	u16 reg;

	mv88e6xxx_g2_write(chip, GLOBAL2_WDOG_CONTROL, GLOBAL2_WDOG_EVENT);
	err = mv88e6xxx_g2_read(chip, GLOBAL2_WDOG_CONTROL, &reg);

	dev_info(chip->dev, "Watchdog event: 0x%04x",
		 reg & GLOBAL2_WDOG_DATA_MASK);

	mv88e6xxx_g2_write(chip, GLOBAL2_WDOG_CONTROL, GLOBAL2_WDOG_HISTORY);
	err = mv88e6xxx_g2_read(chip, GLOBAL2_WDOG_CONTROL, &reg);

	dev_info(chip->dev, "Watchdog history: 0x%04x",
		 reg & GLOBAL2_WDOG_DATA_MASK);

	/* Trigger a software reset to try to recover the switch */
	if (chip->info->ops->reset)
		chip->info->ops->reset(chip);

	mv88e6390_watchdog_setup(chip);

	return IRQ_HANDLED;
}

static void mv88e6390_watchdog_free(struct mv88e6xxx_chip *chip)
{
	mv88e6xxx_g2_update(chip, GLOBAL2_WDOG_CONTROL,
			    GLOBAL2_WDOG_INT_ENABLE);
}

const struct mv88e6xxx_irq_ops mv88e6390_watchdog_ops = {
	.irq_action = mv88e6390_watchdog_action,
	.irq_setup = mv88e6390_watchdog_setup,
	.irq_free = mv88e6390_watchdog_free,
};

static irqreturn_t mv88e6xxx_g2_watchdog_thread_fn(int irq, void *dev_id)
{
	struct mv88e6xxx_chip *chip = dev_id;
+2 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ void mv88e6xxx_g2_irq_free(struct mv88e6xxx_chip *chip);
int mv88e6095_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip);

extern const struct mv88e6xxx_irq_ops mv88e6097_watchdog_ops;
extern const struct mv88e6xxx_irq_ops mv88e6390_watchdog_ops;

#else /* !CONFIG_NET_DSA_MV88E6XXX_GLOBAL2 */

@@ -128,6 +129,7 @@ static inline int mv88e6095_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip)
}

static const struct mv88e6xxx_irq_ops mv88e6097_watchdog_ops = {};
static const struct mv88e6xxx_irq_ops mv88e6390_watchdog_ops = {};

#endif /* CONFIG_NET_DSA_MV88E6XXX_GLOBAL2 */

+12 −0
Original line number Diff line number Diff line
@@ -424,6 +424,17 @@
#define GLOBAL2_WDOG_CONTROL_FORCE_IRQ		BIT(2)
#define GLOBAL2_WDOG_CONTROL_HISTORY		BIT(1)
#define GLOBAL2_WDOG_CONTROL_SWRESET		BIT(0)
#define GLOBAL2_WDOG_UPDATE			BIT(15)
#define GLOBAL2_WDOG_INT_SOURCE			(0x00 << 8)
#define GLOBAL2_WDOG_INT_STATUS			(0x10 << 8)
#define GLOBAL2_WDOG_INT_ENABLE			(0x11 << 8)
#define GLOBAL2_WDOG_EVENT			(0x12 << 8)
#define GLOBAL2_WDOG_HISTORY			(0x13 << 8)
#define GLOBAL2_WDOG_DATA_MASK			0xff
#define GLOBAL2_WDOG_CUT_THROUGH		BIT(3)
#define GLOBAL2_WDOG_QUEUE_CONTROLLER		BIT(2)
#define GLOBAL2_WDOG_EGRESS			BIT(1)
#define GLOBAL2_WDOG_FORCE_IRQ			BIT(0)
#define GLOBAL2_QOS_WEIGHT	0x1c
#define GLOBAL2_MISC		0x1d

@@ -675,6 +686,7 @@ enum mv88e6xxx_cap {
#define MV88E6XXX_FLAGS_FAMILY_6390	\
	(MV88E6XXX_FLAG_EEE |		\
	 MV88E6XXX_FLAG_GLOBAL2 |	\
	 MV88E6XXX_FLAG_G2_INT |        \
	 MV88E6XXX_FLAG_STU |		\
	 MV88E6XXX_FLAG_VTU |		\
	 MV88E6XXX_FLAGS_IRL |		\