diff --git a/arch/powerpc/include/asm/mpc52xx.h b/arch/powerpc/include/asm/mpc52xx.h index 81a23932a160..52e049cd9e68 100644 --- a/arch/powerpc/include/asm/mpc52xx.h +++ b/arch/powerpc/include/asm/mpc52xx.h @@ -273,6 +273,7 @@ extern void mpc5200_setup_xlb_arbiter(void); extern void mpc52xx_declare_of_platform_devices(void); extern void mpc52xx_map_common_devices(void); extern int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv); +extern unsigned int mpc52xx_get_xtal_freq(struct device_node *node); extern void mpc52xx_restart(char *cmd); /* mpc52xx_pic.c */ diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c index e9d2cf632eeb..8e3dd5a0f228 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_common.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c @@ -205,6 +205,43 @@ int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv) } EXPORT_SYMBOL(mpc52xx_set_psc_clkdiv); +/** + * mpc52xx_get_xtal_freq - Get SYS_XTAL_IN frequency for a device + * + * @node: device node + * + * Returns the frequency of the external oscillator clock connected + * to the SYS_XTAL_IN pin, or 0 if it cannot be determined. + */ +unsigned int mpc52xx_get_xtal_freq(struct device_node *node) +{ + u32 val; + unsigned int freq; + + if (!mpc52xx_cdm) + return 0; + + freq = mpc52xx_find_ipb_freq(node); + if (!freq) + return 0; + + if (in_8(&mpc52xx_cdm->ipb_clk_sel) & 0x1) + freq *= 2; + + val = in_be32(&mpc52xx_cdm->rstcfg); + if (val & (1 << 5)) + freq *= 8; + else + freq *= 4; + if (val & (1 << 6)) + freq /= 12; + else + freq /= 16; + + return freq; +} +EXPORT_SYMBOL(mpc52xx_get_xtal_freq); + /** * mpc52xx_restart: ppc_md->restart hook for mpc5200 using the watchdog timer */