drivers/net/can/rockchip/rockchip_canfd-core.c

Source file repositories/reference/linux-study-clean/drivers/net/can/rockchip/rockchip_canfd-core.c

File Facts

System
Linux kernel
Corpus path
drivers/net/can/rockchip/rockchip_canfd-core.c
Extension
.c
Size
27079 bytes
Lines
963
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.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct net_device_ops rkcanfd_netdev_ops = {
	.ndo_open = rkcanfd_open,
	.ndo_stop = rkcanfd_stop,
	.ndo_start_xmit = rkcanfd_start_xmit,
};

static int __maybe_unused rkcanfd_runtime_suspend(struct device *dev)
{
	struct rkcanfd_priv *priv = dev_get_drvdata(dev);

	clk_bulk_disable_unprepare(priv->clks_num, priv->clks);

	return 0;
}

static int __maybe_unused rkcanfd_runtime_resume(struct device *dev)
{
	struct rkcanfd_priv *priv = dev_get_drvdata(dev);

	return clk_bulk_prepare_enable(priv->clks_num, priv->clks);
}

static void rkcanfd_register_done(const struct rkcanfd_priv *priv)
{
	u32 dev_id;

	dev_id = rkcanfd_read(priv, RKCANFD_REG_RTL_VERSION);

	netdev_info(priv->ndev,
		    "Rockchip-CANFD %s rev%lu.%lu (errata 0x%04x) found\n",
		    rkcanfd_get_model_str(priv),
		    FIELD_GET(RKCANFD_REG_RTL_VERSION_MAJOR, dev_id),
		    FIELD_GET(RKCANFD_REG_RTL_VERSION_MINOR, dev_id),
		    priv->devtype_data.quirks);

	if (priv->devtype_data.quirks & RKCANFD_QUIRK_RK3568_ERRATUM_5 &&
	    priv->can.clock.freq < RKCANFD_ERRATUM_5_SYSCLOCK_HZ_MIN)
		netdev_info(priv->ndev,
			    "Erratum 5: CAN clock frequency (%luMHz) lower than known good (%luMHz), expect degraded performance\n",
			    priv->can.clock.freq / MEGA,
			    RKCANFD_ERRATUM_5_SYSCLOCK_HZ_MIN / MEGA);
}

static int rkcanfd_register(struct rkcanfd_priv *priv)
{
	struct net_device *ndev = priv->ndev;
	int err;

	pm_runtime_enable(ndev->dev.parent);

	err = pm_runtime_resume_and_get(ndev->dev.parent);
	if (err)
		goto out_pm_runtime_disable;

	rkcanfd_ethtool_init(priv);

	err = register_candev(ndev);
	if (err)
		goto out_pm_runtime_put_sync;

	rkcanfd_register_done(priv);

	pm_runtime_put(ndev->dev.parent);

	return 0;

out_pm_runtime_put_sync:
	pm_runtime_put_sync(ndev->dev.parent);
out_pm_runtime_disable:
	pm_runtime_disable(ndev->dev.parent);

	return err;
}

static inline void rkcanfd_unregister(struct rkcanfd_priv *priv)
{
	struct net_device *ndev	= priv->ndev;

	unregister_candev(ndev);
	pm_runtime_disable(ndev->dev.parent);
}

static const struct of_device_id rkcanfd_of_match[] = {
	{
		.compatible = "rockchip,rk3568v2-canfd",
		.data = &rkcanfd_devtype_data_rk3568v2,
	}, {
		.compatible = "rockchip,rk3568v3-canfd",
		.data = &rkcanfd_devtype_data_rk3568v3,
	}, {

Annotation

Implementation Notes