.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0+ |
---|
1 | 2 | /* Renesas R-Car CAN FD device driver |
---|
2 | 3 | * |
---|
3 | 4 | * Copyright (C) 2015 Renesas Electronics Corp. |
---|
4 | | - * |
---|
5 | | - * This program is free software; you can redistribute it and/or modify it |
---|
6 | | - * under the terms of the GNU General Public License as published by the |
---|
7 | | - * Free Software Foundation; either version 2 of the License, or (at your |
---|
8 | | - * option) any later version. |
---|
9 | 5 | */ |
---|
10 | 6 | |
---|
11 | 7 | /* The R-Car CAN FD controller can operate in either one of the below two modes |
---|
.. | .. |
---|
1079 | 1075 | struct rcar_canfd_global *gpriv = dev_id; |
---|
1080 | 1076 | struct net_device *ndev; |
---|
1081 | 1077 | struct rcar_canfd_channel *priv; |
---|
1082 | | - u32 sts, gerfl; |
---|
| 1078 | + u32 sts, cc, gerfl; |
---|
1083 | 1079 | u32 ch, ridx; |
---|
1084 | 1080 | |
---|
1085 | 1081 | /* Global error interrupts still indicate a condition specific |
---|
.. | .. |
---|
1097 | 1093 | |
---|
1098 | 1094 | /* Handle Rx interrupts */ |
---|
1099 | 1095 | sts = rcar_canfd_read(priv->base, RCANFD_RFSTS(ridx)); |
---|
1100 | | - if (likely(sts & RCANFD_RFSTS_RFIF)) { |
---|
| 1096 | + cc = rcar_canfd_read(priv->base, RCANFD_RFCC(ridx)); |
---|
| 1097 | + if (likely(sts & RCANFD_RFSTS_RFIF && |
---|
| 1098 | + cc & RCANFD_RFCC_RFIE)) { |
---|
1101 | 1099 | if (napi_schedule_prep(&priv->napi)) { |
---|
1102 | 1100 | /* Disable Rx FIFO interrupts */ |
---|
1103 | 1101 | rcar_canfd_clear_bit(priv->base, |
---|
.. | .. |
---|
1602 | 1600 | |
---|
1603 | 1601 | netif_napi_add(ndev, &priv->napi, rcar_canfd_rx_poll, |
---|
1604 | 1602 | RCANFD_NAPI_WEIGHT); |
---|
| 1603 | + spin_lock_init(&priv->tx_lock); |
---|
| 1604 | + devm_can_led_init(ndev); |
---|
| 1605 | + gpriv->ch[priv->channel] = priv; |
---|
1605 | 1606 | err = register_candev(ndev); |
---|
1606 | 1607 | if (err) { |
---|
1607 | 1608 | dev_err(&pdev->dev, |
---|
1608 | 1609 | "register_candev() failed, error %d\n", err); |
---|
1609 | 1610 | goto fail_candev; |
---|
1610 | 1611 | } |
---|
1611 | | - spin_lock_init(&priv->tx_lock); |
---|
1612 | | - devm_can_led_init(ndev); |
---|
1613 | | - gpriv->ch[priv->channel] = priv; |
---|
1614 | 1612 | dev_info(&pdev->dev, "device registered (channel %u)\n", priv->channel); |
---|
1615 | 1613 | return 0; |
---|
1616 | 1614 | |
---|
.. | .. |
---|
1634 | 1632 | |
---|
1635 | 1633 | static int rcar_canfd_probe(struct platform_device *pdev) |
---|
1636 | 1634 | { |
---|
1637 | | - struct resource *mem; |
---|
1638 | 1635 | void __iomem *addr; |
---|
1639 | 1636 | u32 sts, ch, fcan_freq; |
---|
1640 | 1637 | struct rcar_canfd_global *gpriv; |
---|
.. | .. |
---|
1656 | 1653 | |
---|
1657 | 1654 | ch_irq = platform_get_irq(pdev, 0); |
---|
1658 | 1655 | if (ch_irq < 0) { |
---|
1659 | | - dev_err(&pdev->dev, "no Channel IRQ resource\n"); |
---|
1660 | 1656 | err = ch_irq; |
---|
1661 | 1657 | goto fail_dev; |
---|
1662 | 1658 | } |
---|
1663 | 1659 | |
---|
1664 | 1660 | g_irq = platform_get_irq(pdev, 1); |
---|
1665 | 1661 | if (g_irq < 0) { |
---|
1666 | | - dev_err(&pdev->dev, "no Global IRQ resource\n"); |
---|
1667 | 1662 | err = g_irq; |
---|
1668 | 1663 | goto fail_dev; |
---|
1669 | 1664 | } |
---|
.. | .. |
---|
1710 | 1705 | /* CANFD clock is further divided by (1/2) within the IP */ |
---|
1711 | 1706 | fcan_freq /= 2; |
---|
1712 | 1707 | |
---|
1713 | | - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
---|
1714 | | - addr = devm_ioremap_resource(&pdev->dev, mem); |
---|
| 1708 | + addr = devm_platform_ioremap_resource(pdev, 0); |
---|
1715 | 1709 | if (IS_ERR(addr)) { |
---|
1716 | 1710 | err = PTR_ERR(addr); |
---|
1717 | 1711 | goto fail_dev; |
---|