drivers/net/can/spi/hi311x.c
Source file repositories/reference/linux-study-clean/drivers/net/can/spi/hi311x.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/can/spi/hi311x.c- Extension
.c- Size
- 26240 bytes
- Lines
- 1045
- 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/can/core.hlinux/can/dev.hlinux/clk.hlinux/completion.hlinux/delay.hlinux/device.hlinux/ethtool.hlinux/freezer.hlinux/interrupt.hlinux/io.hlinux/kernel.hlinux/mod_devicetable.hlinux/module.hlinux/netdevice.hlinux/platform_device.hlinux/property.hlinux/regulator/consumer.hlinux/slab.hlinux/spi/spi.hlinux/uaccess.h
Detected Declarations
struct hi3110_privenum hi3110_modelfunction hi3110_cleanfunction hi3110_spi_transfunction hi3110_cmdfunction hi3110_readfunction hi3110_writefunction hi3110_hw_tx_framefunction hi3110_hw_txfunction hi3110_hw_rx_framefunction hi3110_hw_rxfunction hi3110_hw_sleepfunction hi3110_hard_start_xmitfunction hi3110_do_set_modefunction hi3110_get_berr_counterfunction hi3110_set_normal_modefunction hi3110_do_set_bittimingfunction hi3110_setupfunction hi3110_hw_resetfunction hi3110_hw_probefunction hi3110_power_enablefunction hi3110_stopfunction hi3110_tx_work_handlerfunction hi3110_restart_work_handlerfunction hi3110_can_istfunction hi3110_openfunction hi3110_can_probefunction hi3110_can_removefunction hi3110_can_suspendfunction hi3110_can_resume
Annotated Snippet
static const struct net_device_ops hi3110_netdev_ops = {
.ndo_open = hi3110_open,
.ndo_stop = hi3110_stop,
.ndo_start_xmit = hi3110_hard_start_xmit,
};
static const struct ethtool_ops hi3110_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};
static const struct of_device_id hi3110_of_match[] = {
{
.compatible = "holt,hi3110",
.data = (void *)CAN_HI3110_HI3110,
},
{ }
};
MODULE_DEVICE_TABLE(of, hi3110_of_match);
static const struct spi_device_id hi3110_id_table[] = {
{
.name = "hi3110",
.driver_data = (kernel_ulong_t)CAN_HI3110_HI3110,
},
{ }
};
MODULE_DEVICE_TABLE(spi, hi3110_id_table);
static int hi3110_can_probe(struct spi_device *spi)
{
struct device *dev = &spi->dev;
struct net_device *net;
struct hi3110_priv *priv;
struct clk *clk;
u32 freq;
int ret;
clk = devm_clk_get_optional(&spi->dev, NULL);
if (IS_ERR(clk))
return dev_err_probe(dev, PTR_ERR(clk), "no CAN clock source defined\n");
if (clk) {
freq = clk_get_rate(clk);
} else {
ret = device_property_read_u32(dev, "clock-frequency", &freq);
if (ret)
return dev_err_probe(dev, ret, "Failed to get clock-frequency!\n");
}
/* Sanity check */
if (freq > 40000000)
return -ERANGE;
/* Allocate can/net device */
net = alloc_candev(sizeof(struct hi3110_priv), HI3110_TX_ECHO_SKB_MAX);
if (!net)
return -ENOMEM;
ret = clk_prepare_enable(clk);
if (ret)
goto out_free;
net->netdev_ops = &hi3110_netdev_ops;
net->ethtool_ops = &hi3110_ethtool_ops;
net->flags |= IFF_ECHO;
priv = netdev_priv(net);
priv->can.bittiming_const = &hi3110_bittiming_const;
priv->can.do_set_mode = hi3110_do_set_mode;
priv->can.do_get_berr_counter = hi3110_get_berr_counter;
priv->can.clock.freq = freq / 2;
priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES |
CAN_CTRLMODE_LOOPBACK |
CAN_CTRLMODE_LISTENONLY |
CAN_CTRLMODE_BERR_REPORTING;
priv->model = (enum hi3110_model)(uintptr_t)spi_get_device_match_data(spi);
priv->net = net;
priv->clk = clk;
spi_set_drvdata(spi, priv);
/* Configure the SPI bus */
spi->bits_per_word = 8;
ret = spi_setup(spi);
if (ret)
goto out_clk;
priv->power = devm_regulator_get_optional(&spi->dev, "vdd");
priv->transceiver = devm_regulator_get_optional(&spi->dev, "xceiver");
Annotation
- Immediate include surface: `linux/can/core.h`, `linux/can/dev.h`, `linux/clk.h`, `linux/completion.h`, `linux/delay.h`, `linux/device.h`, `linux/ethtool.h`, `linux/freezer.h`.
- Detected declarations: `struct hi3110_priv`, `enum hi3110_model`, `function hi3110_clean`, `function hi3110_spi_trans`, `function hi3110_cmd`, `function hi3110_read`, `function hi3110_write`, `function hi3110_hw_tx_frame`, `function hi3110_hw_tx`, `function hi3110_hw_rx_frame`.
- 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.