.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * Socket CAN driver for Aeroflex Gaisler GRCAN and GRHCAN. |
---|
3 | 4 | * |
---|
.. | .. |
---|
17 | 18 | * |
---|
18 | 19 | * See "Documentation/admin-guide/kernel-parameters.rst" for information on the module |
---|
19 | 20 | * parameters. |
---|
20 | | - * |
---|
21 | | - * This program is free software; you can redistribute it and/or modify it |
---|
22 | | - * under the terms of the GNU General Public License as published by the |
---|
23 | | - * Free Software Foundation; either version 2 of the License, or (at your |
---|
24 | | - * option) any later version. |
---|
25 | 21 | * |
---|
26 | 22 | * Contributors: Andreas Larsson <andreas@gaisler.com> |
---|
27 | 23 | */ |
---|
.. | .. |
---|
245 | 241 | .rxsize = GRCAN_DEFAULT_BUFFER_SIZE, \ |
---|
246 | 242 | } |
---|
247 | 243 | |
---|
248 | | -#define GRCAN_TXBUG_SAFE_GRLIB_VERSION 0x4100 |
---|
| 244 | +#define GRCAN_TXBUG_SAFE_GRLIB_VERSION 4100 |
---|
249 | 245 | #define GRLIB_VERSION_MASK 0xffff |
---|
250 | 246 | |
---|
251 | 247 | /* GRCAN private data structure */ |
---|
252 | 248 | struct grcan_priv { |
---|
253 | 249 | struct can_priv can; /* must be the first member */ |
---|
254 | 250 | struct net_device *dev; |
---|
| 251 | + struct device *ofdev_dev; |
---|
255 | 252 | struct napi_struct napi; |
---|
256 | 253 | |
---|
257 | 254 | struct grcan_registers __iomem *regs; /* ioremap'ed registers */ |
---|
.. | .. |
---|
730 | 727 | txrx = "on rx "; |
---|
731 | 728 | stats->rx_errors++; |
---|
732 | 729 | } |
---|
733 | | - netdev_err(dev, "Fatal AHB buss error %s- halting device\n", |
---|
| 730 | + netdev_err(dev, "Fatal AHB bus error %s- halting device\n", |
---|
734 | 731 | txrx); |
---|
735 | 732 | |
---|
736 | 733 | spin_lock_irqsave(&priv->lock, flags); |
---|
.. | .. |
---|
928 | 925 | struct grcan_priv *priv = netdev_priv(dev); |
---|
929 | 926 | struct grcan_dma *dma = &priv->dma; |
---|
930 | 927 | |
---|
931 | | - dma_free_coherent(&dev->dev, dma->base_size, dma->base_buf, |
---|
| 928 | + dma_free_coherent(priv->ofdev_dev, dma->base_size, dma->base_buf, |
---|
932 | 929 | dma->base_handle); |
---|
933 | 930 | memset(dma, 0, sizeof(*dma)); |
---|
934 | 931 | } |
---|
.. | .. |
---|
953 | 950 | |
---|
954 | 951 | /* Extra GRCAN_BUFFER_ALIGNMENT to allow for alignment */ |
---|
955 | 952 | dma->base_size = lsize + ssize + GRCAN_BUFFER_ALIGNMENT; |
---|
956 | | - dma->base_buf = dma_alloc_coherent(&dev->dev, |
---|
| 953 | + dma->base_buf = dma_alloc_coherent(priv->ofdev_dev, |
---|
957 | 954 | dma->base_size, |
---|
958 | 955 | &dma->base_handle, |
---|
959 | 956 | GFP_KERNEL); |
---|
.. | .. |
---|
1117 | 1114 | |
---|
1118 | 1115 | priv->closing = true; |
---|
1119 | 1116 | if (priv->need_txbug_workaround) { |
---|
| 1117 | + spin_unlock_irqrestore(&priv->lock, flags); |
---|
1120 | 1118 | del_timer_sync(&priv->hang_timer); |
---|
1121 | 1119 | del_timer_sync(&priv->rr_timer); |
---|
| 1120 | + spin_lock_irqsave(&priv->lock, flags); |
---|
1122 | 1121 | } |
---|
1123 | 1122 | netif_stop_queue(dev); |
---|
1124 | 1123 | grcan_stop_hardware(dev); |
---|
.. | .. |
---|
1138 | 1137 | return 0; |
---|
1139 | 1138 | } |
---|
1140 | 1139 | |
---|
1141 | | -static int grcan_transmit_catch_up(struct net_device *dev, int budget) |
---|
| 1140 | +static void grcan_transmit_catch_up(struct net_device *dev) |
---|
1142 | 1141 | { |
---|
1143 | 1142 | struct grcan_priv *priv = netdev_priv(dev); |
---|
1144 | 1143 | unsigned long flags; |
---|
.. | .. |
---|
1146 | 1145 | |
---|
1147 | 1146 | spin_lock_irqsave(&priv->lock, flags); |
---|
1148 | 1147 | |
---|
1149 | | - work_done = catch_up_echo_skb(dev, budget, true); |
---|
| 1148 | + work_done = catch_up_echo_skb(dev, -1, true); |
---|
1150 | 1149 | if (work_done) { |
---|
1151 | 1150 | if (!priv->resetting && !priv->closing && |
---|
1152 | 1151 | !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)) |
---|
.. | .. |
---|
1160 | 1159 | } |
---|
1161 | 1160 | |
---|
1162 | 1161 | spin_unlock_irqrestore(&priv->lock, flags); |
---|
1163 | | - |
---|
1164 | | - return work_done; |
---|
1165 | 1162 | } |
---|
1166 | 1163 | |
---|
1167 | 1164 | static int grcan_receive(struct net_device *dev, int budget) |
---|
.. | .. |
---|
1243 | 1240 | struct net_device *dev = priv->dev; |
---|
1244 | 1241 | struct grcan_registers __iomem *regs = priv->regs; |
---|
1245 | 1242 | unsigned long flags; |
---|
1246 | | - int tx_work_done, rx_work_done; |
---|
1247 | | - int rx_budget = budget / 2; |
---|
1248 | | - int tx_budget = budget - rx_budget; |
---|
| 1243 | + int work_done; |
---|
1249 | 1244 | |
---|
1250 | | - /* Half of the budget for receiveing messages */ |
---|
1251 | | - rx_work_done = grcan_receive(dev, rx_budget); |
---|
| 1245 | + work_done = grcan_receive(dev, budget); |
---|
1252 | 1246 | |
---|
1253 | | - /* Half of the budget for transmitting messages as that can trigger echo |
---|
1254 | | - * frames being received |
---|
1255 | | - */ |
---|
1256 | | - tx_work_done = grcan_transmit_catch_up(dev, tx_budget); |
---|
| 1247 | + grcan_transmit_catch_up(dev); |
---|
1257 | 1248 | |
---|
1258 | | - if (rx_work_done < rx_budget && tx_work_done < tx_budget) { |
---|
| 1249 | + if (work_done < budget) { |
---|
1259 | 1250 | napi_complete(napi); |
---|
1260 | 1251 | |
---|
1261 | 1252 | /* Guarantee no interference with a running reset that otherwise |
---|
.. | .. |
---|
1272 | 1263 | spin_unlock_irqrestore(&priv->lock, flags); |
---|
1273 | 1264 | } |
---|
1274 | 1265 | |
---|
1275 | | - return rx_work_done + tx_work_done; |
---|
| 1266 | + return work_done; |
---|
1276 | 1267 | } |
---|
1277 | 1268 | |
---|
1278 | 1269 | /* Work tx bug by waiting while for the risky situation to clear. If that fails, |
---|
.. | .. |
---|
1604 | 1595 | memcpy(&priv->config, &grcan_module_config, |
---|
1605 | 1596 | sizeof(struct grcan_device_config)); |
---|
1606 | 1597 | priv->dev = dev; |
---|
| 1598 | + priv->ofdev_dev = &ofdev->dev; |
---|
1607 | 1599 | priv->regs = base; |
---|
1608 | 1600 | priv->can.bittiming_const = &grcan_bittiming_const; |
---|
1609 | 1601 | priv->can.do_set_bittiming = grcan_set_bittiming; |
---|
.. | .. |
---|
1656 | 1648 | static int grcan_probe(struct platform_device *ofdev) |
---|
1657 | 1649 | { |
---|
1658 | 1650 | struct device_node *np = ofdev->dev.of_node; |
---|
1659 | | - struct resource *res; |
---|
| 1651 | + struct device_node *sysid_parent; |
---|
1660 | 1652 | u32 sysid, ambafreq; |
---|
1661 | 1653 | int irq, err; |
---|
1662 | 1654 | void __iomem *base; |
---|
.. | .. |
---|
1665 | 1657 | /* Compare GRLIB version number with the first that does not |
---|
1666 | 1658 | * have the tx bug (see start_xmit) |
---|
1667 | 1659 | */ |
---|
1668 | | - err = of_property_read_u32(np, "systemid", &sysid); |
---|
1669 | | - if (!err && ((sysid & GRLIB_VERSION_MASK) |
---|
1670 | | - >= GRCAN_TXBUG_SAFE_GRLIB_VERSION)) |
---|
1671 | | - txbug = false; |
---|
| 1660 | + sysid_parent = of_find_node_by_path("/ambapp0"); |
---|
| 1661 | + if (sysid_parent) { |
---|
| 1662 | + err = of_property_read_u32(sysid_parent, "systemid", &sysid); |
---|
| 1663 | + if (!err && ((sysid & GRLIB_VERSION_MASK) >= |
---|
| 1664 | + GRCAN_TXBUG_SAFE_GRLIB_VERSION)) |
---|
| 1665 | + txbug = false; |
---|
| 1666 | + of_node_put(sysid_parent); |
---|
| 1667 | + } |
---|
1672 | 1668 | |
---|
1673 | 1669 | err = of_property_read_u32(np, "freq", &ambafreq); |
---|
1674 | 1670 | if (err) { |
---|
.. | .. |
---|
1676 | 1672 | goto exit_error; |
---|
1677 | 1673 | } |
---|
1678 | 1674 | |
---|
1679 | | - res = platform_get_resource(ofdev, IORESOURCE_MEM, 0); |
---|
1680 | | - base = devm_ioremap_resource(&ofdev->dev, res); |
---|
| 1675 | + base = devm_platform_ioremap_resource(ofdev, 0); |
---|
1681 | 1676 | if (IS_ERR(base)) { |
---|
1682 | 1677 | err = PTR_ERR(base); |
---|
1683 | 1678 | goto exit_error; |
---|