Skip to content

Commit 87f54c1

Browse files
Merge patch series "can: m_can: set init flag earlier in probe"
This series fixes problems in the m_can_pci driver found on the Intel Elkhart Lake processor. Link: https://patch.msgid.link/e247f331cb72829fcbdfda74f31a59cbad1a6006.1728288535.git.matthias.schiffer@ew.tq-group.com Signed-off-by: Marc Kleine-Budde <[email protected]>
2 parents 954a2b4 + 743375f commit 87f54c1

File tree

3 files changed

+28
-10
lines changed

3 files changed

+28
-10
lines changed

drivers/net/can/m_can/m_can.c

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,20 +1220,32 @@ static void m_can_coalescing_update(struct m_can_classdev *cdev, u32 ir)
12201220
static int m_can_interrupt_handler(struct m_can_classdev *cdev)
12211221
{
12221222
struct net_device *dev = cdev->net;
1223-
u32 ir;
1223+
u32 ir = 0, ir_read;
12241224
int ret;
12251225

12261226
if (pm_runtime_suspended(cdev->dev))
12271227
return IRQ_NONE;
12281228

1229-
ir = m_can_read(cdev, M_CAN_IR);
1229+
/* The m_can controller signals its interrupt status as a level, but
1230+
* depending in the integration the CPU may interpret the signal as
1231+
* edge-triggered (for example with m_can_pci). For these
1232+
* edge-triggered integrations, we must observe that IR is 0 at least
1233+
* once to be sure that the next interrupt will generate an edge.
1234+
*/
1235+
while ((ir_read = m_can_read(cdev, M_CAN_IR)) != 0) {
1236+
ir |= ir_read;
1237+
1238+
/* ACK all irqs */
1239+
m_can_write(cdev, M_CAN_IR, ir);
1240+
1241+
if (!cdev->irq_edge_triggered)
1242+
break;
1243+
}
1244+
12301245
m_can_coalescing_update(cdev, ir);
12311246
if (!ir)
12321247
return IRQ_NONE;
12331248

1234-
/* ACK all irqs */
1235-
m_can_write(cdev, M_CAN_IR, ir);
1236-
12371249
if (cdev->ops->clear_interrupts)
12381250
cdev->ops->clear_interrupts(cdev);
12391251

@@ -1695,6 +1707,14 @@ static int m_can_dev_setup(struct m_can_classdev *cdev)
16951707
return -EINVAL;
16961708
}
16971709

1710+
/* Write the INIT bit, in case no hardware reset has happened before
1711+
* the probe (for example, it was observed that the Intel Elkhart Lake
1712+
* SoCs do not properly reset the CAN controllers on reboot)
1713+
*/
1714+
err = m_can_cccr_update_bits(cdev, CCCR_INIT, CCCR_INIT);
1715+
if (err)
1716+
return err;
1717+
16981718
if (!cdev->is_peripheral)
16991719
netif_napi_add(dev, &cdev->napi, m_can_poll);
17001720

@@ -1746,11 +1766,7 @@ static int m_can_dev_setup(struct m_can_classdev *cdev)
17461766
return -EINVAL;
17471767
}
17481768

1749-
/* Forcing standby mode should be redundant, as the chip should be in
1750-
* standby after a reset. Write the INIT bit anyways, should the chip
1751-
* be configured by previous stage.
1752-
*/
1753-
return m_can_cccr_update_bits(cdev, CCCR_INIT, CCCR_INIT);
1769+
return 0;
17541770
}
17551771

17561772
static void m_can_stop(struct net_device *dev)

drivers/net/can/m_can/m_can.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ struct m_can_classdev {
9999
int pm_clock_support;
100100
int pm_wake_source;
101101
int is_peripheral;
102+
bool irq_edge_triggered;
102103

103104
// Cached M_CAN_IE register content
104105
u32 active_interrupts;

drivers/net/can/m_can/m_can_pci.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ static int m_can_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
127127
mcan_class->pm_clock_support = 1;
128128
mcan_class->pm_wake_source = 0;
129129
mcan_class->can.clock.freq = id->driver_data;
130+
mcan_class->irq_edge_triggered = true;
130131
mcan_class->ops = &m_can_pci_ops;
131132

132133
pci_set_drvdata(pci, mcan_class);

0 commit comments

Comments
 (0)