drivers/net/can/grcan.c
Source file repositories/reference/linux-study-clean/drivers/net/can/grcan.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/can/grcan.c- Extension
.c- Size
- 50197 bytes
- Lines
- 1735
- Domain
- Driver Families
- Bucket
- drivers/net
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/module.hlinux/interrupt.hlinux/netdevice.hlinux/delay.hlinux/ethtool.hlinux/io.hlinux/can/dev.hlinux/platform_device.hlinux/spinlock.hlinux/of.hlinux/of_irq.hlinux/dma-mapping.h
Detected Declarations
struct grcan_registersstruct grcan_dma_bufferstruct grcan_dmastruct grcan_device_configstruct grcan_privfunction grcan_read_regfunction grcan_write_regfunction grcan_read_regfunction grcan_write_regfunction grcan_clear_bitsfunction grcan_set_bitsfunction grcan_read_bitsfunction grcan_write_bitsfunction grcan_ring_addfunction grcan_ring_subfunction grcan_txspacefunction grcan_set_bittimingfunction grcan_get_berr_counterfunction grcan_resetfunction grcan_stop_hardwarefunction catch_up_echo_skbfunction grcan_lost_one_shot_framefunction grcan_errfunction grcan_interruptfunction ONGOINGfunction bitratefunction grcan_reset_timerfunction grcan_initiate_running_resetfunction grcan_free_dma_buffersfunction grcan_allocate_dma_buffersfunction grcan_startfunction grcan_set_modefunction grcan_openfunction grcan_closefunction grcan_transmit_catch_upfunction grcan_receivefunction grcan_pollfunction grcan_txbug_workaroundfunction grcan_start_xmitfunction grcan_sanitize_module_configfunction grcan_setup_netdevfunction grcan_probefunction grcan_remove
Annotated Snippet
static const struct net_device_ops grcan_netdev_ops = {
.ndo_open = grcan_open,
.ndo_stop = grcan_close,
.ndo_start_xmit = grcan_start_xmit,
};
static const struct ethtool_ops grcan_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};
static int grcan_setup_netdev(struct platform_device *ofdev,
void __iomem *base,
int irq, u32 ambafreq, bool txbug)
{
struct net_device *dev;
struct grcan_priv *priv;
struct grcan_registers __iomem *regs;
int err;
dev = alloc_candev(sizeof(struct grcan_priv), 0);
if (!dev)
return -ENOMEM;
dev->irq = irq;
dev->flags |= IFF_ECHO;
dev->netdev_ops = &grcan_netdev_ops;
dev->ethtool_ops = &grcan_ethtool_ops;
dev->sysfs_groups[0] = &sysfs_grcan_group;
priv = netdev_priv(dev);
memcpy(&priv->config, &grcan_module_config,
sizeof(struct grcan_device_config));
priv->dev = dev;
priv->ofdev_dev = &ofdev->dev;
priv->regs = base;
priv->can.bittiming_const = &grcan_bittiming_const;
priv->can.do_set_bittiming = grcan_set_bittiming;
priv->can.do_set_mode = grcan_set_mode;
priv->can.do_get_berr_counter = grcan_get_berr_counter;
priv->can.clock.freq = ambafreq;
priv->can.ctrlmode_supported =
CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_ONE_SHOT;
priv->need_txbug_workaround = txbug;
/* Discover if triple sampling is supported by hardware */
regs = priv->regs;
grcan_set_bits(®s->ctrl, GRCAN_CTRL_RESET);
grcan_set_bits(®s->conf, GRCAN_CONF_SAM);
if (grcan_read_bits(®s->conf, GRCAN_CONF_SAM)) {
priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES;
dev_dbg(&ofdev->dev, "Hardware supports triple-sampling\n");
}
spin_lock_init(&priv->lock);
if (priv->need_txbug_workaround) {
timer_setup(&priv->rr_timer, grcan_running_reset, 0);
timer_setup(&priv->hang_timer, grcan_initiate_running_reset, 0);
}
netif_napi_add_weight(dev, &priv->napi, grcan_poll, GRCAN_NAPI_WEIGHT);
SET_NETDEV_DEV(dev, &ofdev->dev);
dev_info(&ofdev->dev, "regs=0x%p, irq=%d, clock=%d\n",
priv->regs, dev->irq, priv->can.clock.freq);
err = register_candev(dev);
if (err)
goto exit_free_candev;
platform_set_drvdata(ofdev, dev);
/* Reset device to allow bit-timing to be set. No need to call
* grcan_reset at this stage. That is done in grcan_open.
*/
grcan_write_reg(®s->ctrl, GRCAN_CTRL_RESET);
return 0;
exit_free_candev:
free_candev(dev);
return err;
}
static int grcan_probe(struct platform_device *ofdev)
{
struct device_node *np = ofdev->dev.of_node;
struct device_node *sysid_parent;
u32 sysid, ambafreq;
int irq, err;
void __iomem *base;
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/module.h`, `linux/interrupt.h`, `linux/netdevice.h`, `linux/delay.h`, `linux/ethtool.h`, `linux/io.h`, `linux/can/dev.h`.
- Detected declarations: `struct grcan_registers`, `struct grcan_dma_buffer`, `struct grcan_dma`, `struct grcan_device_config`, `struct grcan_priv`, `function grcan_read_reg`, `function grcan_write_reg`, `function grcan_read_reg`, `function grcan_write_reg`, `function grcan_clear_bits`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: pattern implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.