drivers/net/can/cc770/cc770_platform.c

Source file repositories/reference/linux-study-clean/drivers/net/can/cc770/cc770_platform.c

File Facts

System
Linux kernel
Corpus path
drivers/net/can/cc770/cc770_platform.c
Extension
.c
Size
6597 bytes
Lines
254
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source 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

if (cdv > 0 && cdv < 16) {
			u32 slew;

			priv->cpu_interface |= CPUIF_CEN;
			priv->clkout |= (cdv - 1) & CLKOUT_CD_MASK;

			if (of_property_read_u32(np, "bosch,slew-rate", &slew)) {
				/* Determine default slew rate */
				slew = (CLKOUT_SL_MASK >>
					CLKOUT_SL_SHIFT) -
					((cdv * clkext - 1) / 8000000);
				if (slew > (CLKOUT_SL_MASK >> CLKOUT_SL_SHIFT))
					slew = 0;
			}
			priv->clkout |= (slew << CLKOUT_SL_SHIFT) &
				CLKOUT_SL_MASK;
		} else {
			dev_dbg(&pdev->dev, "invalid clock-out-frequency\n");
		}
	}

	return 0;
}

static int cc770_get_platform_data(struct platform_device *pdev,
				   struct cc770_priv *priv)
{

	struct cc770_platform_data *pdata = dev_get_platdata(&pdev->dev);

	priv->can.clock.freq = pdata->osc_freq;
	if (priv->cpu_interface & CPUIF_DSC)
		priv->can.clock.freq /= 2;
	priv->clkout = pdata->cor;
	priv->bus_config = pdata->bcr;
	priv->cpu_interface = pdata->cir;

	return 0;
}

static int cc770_platform_probe(struct platform_device *pdev)
{
	struct net_device *dev;
	struct cc770_priv *priv;
	struct resource *mem;
	resource_size_t mem_size;
	void __iomem *base;
	int err, irq;

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	irq = platform_get_irq(pdev, 0);
	if (!mem || irq <= 0)
		return -ENODEV;

	mem_size = resource_size(mem);
	if (!request_mem_region(mem->start, mem_size, pdev->name))
		return -EBUSY;

	base = ioremap(mem->start, mem_size);
	if (!base) {
		err = -ENOMEM;
		goto exit_release_mem;
	}

	dev = alloc_cc770dev(0);
	if (!dev) {
		err = -ENOMEM;
		goto exit_unmap_mem;
	}

	dev->irq = irq;
	priv = netdev_priv(dev);
	priv->read_reg = cc770_platform_read_reg;
	priv->write_reg = cc770_platform_write_reg;
	priv->irq_flags = IRQF_SHARED;
	priv->reg_base = base;

	if (pdev->dev.of_node)
		err = cc770_get_of_node_data(pdev, priv);
	else if (dev_get_platdata(&pdev->dev))
		err = cc770_get_platform_data(pdev, priv);
	else
		err = -ENODEV;
	if (err)
		goto exit_free_cc770;

	dev_dbg(&pdev->dev,
		 "reg_base=0x%p irq=%d clock=%d cpu_interface=0x%02x "
		 "bus_config=0x%02x clkout=0x%02x\n",
		 priv->reg_base, dev->irq, priv->can.clock.freq,

Annotation

Implementation Notes