| .. | .. |
|---|
| 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; |
|---|