drivers/net/can/mscan/mpc5xxx_can.c
Source file repositories/reference/linux-study-clean/drivers/net/can/mscan/mpc5xxx_can.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/can/mscan/mpc5xxx_can.c- Extension
.c- Size
- 12577 bytes
- Lines
- 450
- 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.
- 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 or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/module.hlinux/interrupt.hlinux/platform_device.hlinux/property.hlinux/netdevice.hlinux/can/dev.hlinux/of.hlinux/of_address.hlinux/of_irq.hlinux/of_platform.hsysdev/fsl_soc.hlinux/clk.hlinux/io.hasm/mpc52xx.hmscan.h
Detected Declarations
struct mpc5xxx_can_datafunction mpc52xx_can_get_clockfunction mpc52xx_can_get_clockfunction mpc512x_can_get_clockfunction mpc512x_can_put_clockfunction mpc512x_can_get_clockfunction mpc5xxx_can_probefunction mpc5xxx_can_removefunction mpc5xxx_can_suspendfunction mpc5xxx_can_resume
Annotated Snippet
struct mpc5xxx_can_data {
unsigned int type;
u32 (*get_clock)(struct platform_device *ofdev, const char *clock_name,
int *mscan_clksrc);
void (*put_clock)(struct platform_device *ofdev);
};
#ifdef CONFIG_PPC_MPC52xx
static const struct of_device_id mpc52xx_cdm_ids[] = {
{ .compatible = "fsl,mpc5200-cdm", },
{}
};
static u32 mpc52xx_can_get_clock(struct platform_device *ofdev,
const char *clock_name, int *mscan_clksrc)
{
unsigned int pvr;
struct mpc52xx_cdm __iomem *cdm;
struct device_node *np_cdm;
unsigned int freq;
u32 val;
pvr = mfspr(SPRN_PVR);
/*
* Either the oscillator clock (SYS_XTAL_IN) or the IP bus clock
* (IP_CLK) can be selected as MSCAN clock source. According to
* the MPC5200 user's manual, the oscillator clock is the better
* choice as it has less jitter. For this reason, it is selected
* by default. Unfortunately, it can not be selected for the old
* MPC5200 Rev. A chips due to a hardware bug (check errata).
*/
if (clock_name && strcmp(clock_name, "ip") == 0)
*mscan_clksrc = MSCAN_CLKSRC_BUS;
else
*mscan_clksrc = MSCAN_CLKSRC_XTAL;
freq = mpc5xxx_get_bus_frequency(&ofdev->dev);
if (!freq)
return 0;
if (*mscan_clksrc == MSCAN_CLKSRC_BUS || pvr == 0x80822011)
return freq;
/* Determine SYS_XTAL_IN frequency from the clock domain settings */
np_cdm = of_find_matching_node(NULL, mpc52xx_cdm_ids);
if (!np_cdm) {
dev_err(&ofdev->dev, "can't get clock node!\n");
return 0;
}
cdm = of_iomap(np_cdm, 0);
if (!cdm) {
of_node_put(np_cdm);
dev_err(&ofdev->dev, "can't map clock node!\n");
return 0;
}
if (in_8(&cdm->ipb_clk_sel) & 0x1)
freq *= 2;
val = in_be32(&cdm->rstcfg);
freq *= (val & (1 << 5)) ? 8 : 4;
freq /= (val & (1 << 6)) ? 12 : 16;
of_node_put(np_cdm);
iounmap(cdm);
return freq;
}
#else /* !CONFIG_PPC_MPC52xx */
static u32 mpc52xx_can_get_clock(struct platform_device *ofdev,
const char *clock_name, int *mscan_clksrc)
{
return 0;
}
#endif /* CONFIG_PPC_MPC52xx */
#ifdef CONFIG_PPC_MPC512x
static u32 mpc512x_can_get_clock(struct platform_device *ofdev,
const char *clock_source, int *mscan_clksrc)
{
struct device_node *np;
u32 clockdiv;
enum {
CLK_FROM_AUTO,
CLK_FROM_IPS,
CLK_FROM_SYS,
CLK_FROM_REF,
} clk_from;
struct clk *clk_in, *clk_can;
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/module.h`, `linux/interrupt.h`, `linux/platform_device.h`, `linux/property.h`, `linux/netdevice.h`, `linux/can/dev.h`, `linux/of.h`.
- Detected declarations: `struct mpc5xxx_can_data`, `function mpc52xx_can_get_clock`, `function mpc52xx_can_get_clock`, `function mpc512x_can_get_clock`, `function mpc512x_can_put_clock`, `function mpc512x_can_get_clock`, `function mpc5xxx_can_probe`, `function mpc5xxx_can_remove`, `function mpc5xxx_can_suspend`, `function mpc5xxx_can_resume`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: source implementation candidate.
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.