Signed-off-by: Bert Vermeulen <bert@xxxxxxxx> --- arch/mips/Kbuild.platforms | 1 + arch/mips/Kconfig | 20 +++ arch/mips/include/asm/mach-realtek/ioremap.h | 29 ++++ arch/mips/include/asm/mach-realtek/irq.h | 69 ++++++++ .../include/asm/mach-realtek/mach-realtek.h | 69 ++++++++ arch/mips/realtek/Makefile | 1 + arch/mips/realtek/Platform | 6 + arch/mips/realtek/irq.c | 157 ++++++++++++++++++ arch/mips/realtek/prom.c | 126 ++++++++++++++ arch/mips/realtek/setup.c | 58 +++++++ 10 files changed, 536 insertions(+) create mode 100644 arch/mips/include/asm/mach-realtek/ioremap.h create mode 100644 arch/mips/include/asm/mach-realtek/irq.h create mode 100644 arch/mips/include/asm/mach-realtek/mach-realtek.h create mode 100644 arch/mips/realtek/Makefile create mode 100644 arch/mips/realtek/Platform create mode 100644 arch/mips/realtek/irq.c create mode 100644 arch/mips/realtek/prom.c create mode 100644 arch/mips/realtek/setup.c diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms index 5483e38b5dc7..e9adc6e7d1d3 100644 --- a/arch/mips/Kbuild.platforms +++ b/arch/mips/Kbuild.platforms @@ -22,6 +22,7 @@ platform-$(CONFIG_NLM_COMMON) += netlogic/ platform-$(CONFIG_PIC32MZDA) += pic32/ platform-$(CONFIG_MACH_PISTACHIO) += pistachio/ platform-$(CONFIG_RALINK) += ralink/ +platform-$(CONFIG_MACH_REALTEK) += realtek/ platform-$(CONFIG_MIKROTIK_RB532) += rb532/ platform-$(CONFIG_SGI_IP22) += sgi-ip22/ platform-$(CONFIG_SGI_IP27) += sgi-ip27/ diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 6b762bebff33..58966ebaed5b 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -624,6 +624,26 @@ config RALINK select ARCH_HAS_RESET_CONTROLLER select RESET_CONTROLLER +config MACH_REALTEK + bool "Realtek RTL8380 based machines" + select DMA_NONCOHERENT + select IRQ_MIPS_CPU + select CSRC_R4K + select CEVT_R4K + select SYS_HAS_CPU_MIPS32_R1 + select SYS_HAS_CPU_MIPS32_R2 + select SYS_SUPPORTS_BIG_ENDIAN + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_MIPS16 + select SYS_SUPPORTS_MULTITHREADING + select SYS_SUPPORTS_VPE_LOADER + select SYS_HAS_EARLY_PRINTK + select SYS_HAS_EARLY_PRINTK_8250 + select USE_GENERIC_EARLY_PRINTK_8250 + select BOOT_RAW + select PINCTRL + select USE_OF + config SGI_IP22 bool "SGI IP22 (Indy/Indigo2)" select ARC_MEMORY diff --git a/arch/mips/include/asm/mach-realtek/ioremap.h b/arch/mips/include/asm/mach-realtek/ioremap.h new file mode 100644 index 000000000000..8847d0b99dad --- /dev/null +++ b/arch/mips/include/asm/mach-realtek/ioremap.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef _RTL8380_IOREMAP_H_ +#define _RTL8380_IOREMAP_H_ + +static inline int is_rtl8380_internal_registers(phys_addr_t offset) +{ + /* IO-Block */ + if (offset >= 0xb8000000 && offset < 0xb9000000) + return 1; + /* Switch block */ + if (offset >= 0xbb000000 && offset < 0xbc000000) + return 1; + return 0; +} + +static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size, + unsigned long flags) +{ + if (is_rtl8380_internal_registers(offset)) + return (void __iomem *)offset; + return NULL; +} + +static inline int plat_iounmap(const volatile void __iomem *addr) +{ + return is_rtl8380_internal_registers((unsigned long)addr); +} + +#endif /* _RTL8380_IOREMAP_H_ */ diff --git a/arch/mips/include/asm/mach-realtek/irq.h b/arch/mips/include/asm/mach-realtek/irq.h new file mode 100644 index 000000000000..e2e2cd6dd27a --- /dev/null +++ b/arch/mips/include/asm/mach-realtek/irq.h @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2006-2012 Tony Wu <tonywu@xxxxxxxxxxx> + * Copyright (C) 2020 Birger Koblitz <mail@xxxxxxxxxxxxxxxxx> + * Copyright (C) 2020 Bert Vermeulen <bert@xxxxxxxx> + * Copyright (C) 2020 John Crispin <john@xxxxxxxxxxx> + */ + +#ifndef _RTL8380_IRQ_H_ +#define _RTL8380_IRQ_H_ + +#define NR_IRQS 32 +#include_next <irq.h> + +/* Global Interrupt Mask Register */ +#define RTL8380_ICTL_GIMR 0x00 +/* Global Interrupt Status Register */ +#define RTL8380_ICTL_GISR 0x04 + +/* Cascaded interrupts */ +#define RTL8380_CPU_IRQ_SHARED0 (MIPS_CPU_IRQ_BASE + 2) +#define RTL8380_CPU_IRQ_UART (MIPS_CPU_IRQ_BASE + 3) +#define RTL8380_CPU_IRQ_SWITCH (MIPS_CPU_IRQ_BASE + 4) +#define RTL8380_CPU_IRQ_SHARED1 (MIPS_CPU_IRQ_BASE + 5) +#define RTL8380_CPU_IRQ_EXTERNAL (MIPS_CPU_IRQ_BASE + 6) +#define RTL8380_CPU_IRQ_COUNTER (MIPS_CPU_IRQ_BASE + 7) + + +/* Interrupt routing register */ +#define RTL8380_IRR0 0x08 +#define RTL8380_IRR1 0x0c +#define RTL8380_IRR2 0x10 +#define RTL8380_IRR3 0x14 + +/* Cascade map */ +#define RTL8380_IRQ_CASCADE_UART0 2 +#define RTL8380_IRQ_CASCADE_UART1 1 +#define RTL8380_IRQ_CASCADE_TC0 5 +#define RTL8380_IRQ_CASCADE_TC1 1 +#define RTL8380_IRQ_CASCADE_OCPTO 1 +#define RTL8380_IRQ_CASCADE_HLXTO 1 +#define RTL8380_IRQ_CASCADE_SLXTO 1 +#define RTL8380_IRQ_CASCADE_NIC 4 +#define RTL8380_IRQ_CASCADE_GPIO_ABCD 4 +#define RTL8380_IRQ_CASCADE_GPIO_EFGH 4 +#define RTL8380_IRQ_CASCADE_RTC 4 +#define RTL8380_IRQ_CASCADE_SWCORE 3 +#define RTL8380_IRQ_CASCADE_WDT_IP1 4 +#define RTL8380_IRQ_CASCADE_WDT_IP2 5 + +/* Pack cascade map into interrupt routing registers */ +#define RTL8380_IRR0_SETTING (\ + (RTL8380_IRQ_CASCADE_UART0 << 28) | \ + (RTL8380_IRQ_CASCADE_UART1 << 24) | \ + (RTL8380_IRQ_CASCADE_TC0 << 20) | \ + (RTL8380_IRQ_CASCADE_TC1 << 16) | \ + (RTL8380_IRQ_CASCADE_OCPTO << 12) | \ + (RTL8380_IRQ_CASCADE_HLXTO << 8) | \ + (RTL8380_IRQ_CASCADE_SLXTO << 4) | \ + (RTL8380_IRQ_CASCADE_NIC << 0)) +#define RTL8380_IRR1_SETTING (\ + (RTL8380_IRQ_CASCADE_GPIO_ABCD << 28) | \ + (RTL8380_IRQ_CASCADE_GPIO_EFGH << 24) | \ + (RTL8380_IRQ_CASCADE_RTC << 20) | \ + (RTL8380_IRQ_CASCADE_SWCORE << 16)) +#define RTL8380_IRR2_SETTING 0 +#define RTL8380_IRR3_SETTING 0 + +#endif /* _RTL8380_IRQ_H_ */ diff --git a/arch/mips/include/asm/mach-realtek/mach-realtek.h b/arch/mips/include/asm/mach-realtek/mach-realtek.h new file mode 100644 index 000000000000..bc6b1e57c00a --- /dev/null +++ b/arch/mips/include/asm/mach-realtek/mach-realtek.h @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2006-2012 Tony Wu <tonywu@xxxxxxxxxxx> + * Copyright (C) 2020 Birger Koblitz <mail@xxxxxxxxxxxxxxxxx> + * Copyright (C) 2020 Bert Vermeulen <bert@xxxxxxxx> + * Copyright (C) 2020 John Crispin <john@xxxxxxxxxxx> + */ + +#ifndef _MACH_REALTEK_H_ +#define _MACH_REALTEK_H_ + +struct realtek_soc_info { + unsigned char *name; + unsigned int id; + unsigned int family; +}; + +/* High 16 bits of MODEL_NAME_INFO register */ +#define RTL8389_FAMILY_ID 0x8389 +#define RTL8328_FAMILY_ID 0x8328 +#define RTL8390_FAMILY_ID 0x8390 +#define RTL8350_FAMILY_ID 0x8350 +#define RTL8380_FAMILY_ID 0x8380 +#define RTL8330_FAMILY_ID 0x8330 + +/* Interrupt numbers/bits */ +#define RTL8380_IRQ_UART0 31 +#define RTL8380_IRQ_UART1 30 +#define RTL8380_IRQ_TC0 29 +#define RTL8380_IRQ_TC1 28 +#define RTL8380_IRQ_OCPTO 27 +#define RTL8380_IRQ_HLXTO 26 +#define RTL8380_IRQ_SLXTO 25 +#define RTL8380_IRQ_NIC 24 +#define RTL8380_IRQ_GPIO_ABCD 23 +#define RTL8380_IRQ_GPIO_EFGH 22 +#define RTL8380_IRQ_RTC 21 +#define RTL8380_IRQ_SWCORE 20 +#define RTL8380_IRQ_WDT_IP1 19 +#define RTL8380_IRQ_WDT_IP2 18 + + +// TODO: move to DT +#define RTL8380_SWITCH_BASE ((volatile void *) 0xBB000000) +#define RTL8380_MODEL_NAME_INFO (RTL8380_SWITCH_BASE + 0x00D4) +#define RTL8390_MODEL_NAME_INFO (RTL8380_SWITCH_BASE + 0x0FF0) + +/* GMII pinmux on RTL838x */ +#define RTL8380_GMII_INTF_SEL (RTL8380_SWITCH_BASE + 0x1000) +#define RTL8380_GMII_INTF_SEL_UART1 BIT(4) +#define RTL8380_GMII_INTF_SEL_JTAG (BIT(2) | BIT(3)) +#define RTL8380_GMII_INTF_SEL_GMII (BIT(0) | BIT(1)) + +/* GMII pinmux on RTL839x */ +#define RTL8390_MAC_IF_CTRL (RTL8380_SWITCH_BASE + 0x04) +#define RTL8390_MAC_IF_CTRL_JTAG BIT(1) +#define RTL8390_MAC_IF_CTRL_UART BIT(0) + +/* Used to detect address length pin strapping on RTL833x/RTL838x */ +#define RTL8380_INT_RW_CTRL (RTL8380_SWITCH_BASE + 0x58) +#define RTL8380_EXT_VERSION (RTL8380_SWITCH_BASE + 0xD0) +#define RTL8380_PLL_CML_CTRL (RTL8380_SWITCH_BASE + 0xFF8) +#define RTL8380_STRAP_DBG (RTL8380_SWITCH_BASE + 0x100C) + +/* Reset */ +#define RTL8380_RST_GLB_CTRL_1 (RTL8380_SWITCH_BASE + 0x40) +#define RTL8390_RST_GLB_CTRL (RTL8380_SWITCH_BASE + 0x14) + +#endif /* _MACH_RTL8380_H_ */ diff --git a/arch/mips/realtek/Makefile b/arch/mips/realtek/Makefile new file mode 100644 index 000000000000..4616928e9883 --- /dev/null +++ b/arch/mips/realtek/Makefile @@ -0,0 +1 @@ +obj-y := setup.o prom.o irq.o diff --git a/arch/mips/realtek/Platform b/arch/mips/realtek/Platform new file mode 100644 index 000000000000..6e6b29b82b81 --- /dev/null +++ b/arch/mips/realtek/Platform @@ -0,0 +1,6 @@ +# +# Realtek RTL8380 SoCs +# +platform-$(CONFIG_MACH_REALTEK) += realtek/ +cflags-$(CONFIG_MACH_REALTEK) += -I$(srctree)/arch/mips/include/asm/mach-realtek/ +load-$(CONFIG_MACH_REALTEK) += 0xffffffff80000000 diff --git a/arch/mips/realtek/irq.c b/arch/mips/realtek/irq.c new file mode 100644 index 000000000000..99c0adb56de3 --- /dev/null +++ b/arch/mips/realtek/irq.c @@ -0,0 +1,157 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2006-2012 Tony Wu <tonywu@xxxxxxxxxxx> + * Copyright (C) 2020 Birger Koblitz <mail@xxxxxxxxxxxxxxxxx> + * Copyright (C) 2020 Bert Vermeulen <bert@xxxxxxxx> + * Copyright (C) 2020 John Crispin <john@xxxxxxxxxxx> + */ + +#include <linux/irqchip.h> +#include <linux/spinlock.h> +#include <linux/of_address.h> +#include <asm/irq_cpu.h> +#include <linux/of_irq.h> +#include <asm/cevt-r4k.h> + +#include <mach-realtek.h> +#include "irq.h" + +#define REG(x) (realtek_ictl_base + x) + +extern struct realtek_soc_info soc_info; + +static DEFINE_RAW_SPINLOCK(irq_lock); +static void __iomem *realtek_ictl_base; + +static void realtek_ictl_enable_irq(struct irq_data *i) +{ + unsigned long flags; + u32 value; + + raw_spin_lock_irqsave(&irq_lock, flags); + + value = readl(REG(RTL8380_ICTL_GIMR)); + value |= BIT(i->hwirq); + writel(value, REG(RTL8380_ICTL_GIMR)); + + raw_spin_unlock_irqrestore(&irq_lock, flags); +} + +static void realtek_ictl_disable_irq(struct irq_data *i) +{ + unsigned long flags; + u32 value; + + raw_spin_lock_irqsave(&irq_lock, flags); + + value = readl(REG(RTL8380_ICTL_GIMR)); + value &= ~BIT(i->hwirq); + writel(value, REG(RTL8380_ICTL_GIMR)); + + raw_spin_unlock_irqrestore(&irq_lock, flags); +} + +static struct irq_chip realtek_ictl_irq = { + .name = "rtl8380", + .irq_enable = realtek_ictl_enable_irq, + .irq_disable = realtek_ictl_disable_irq, + .irq_ack = realtek_ictl_disable_irq, + .irq_mask = realtek_ictl_disable_irq, + .irq_unmask = realtek_ictl_enable_irq, + .irq_eoi = realtek_ictl_enable_irq, +}; + +static int intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) +{ + irq_set_chip_and_handler(hw, &realtek_ictl_irq, handle_level_irq); + + return 0; +} + +static const struct irq_domain_ops irq_domain_ops = { + .map = intc_map, + .xlate = irq_domain_xlate_onecell, +}; + +static void realtek_irq_dispatch(struct irq_desc *desc) +{ + unsigned int pending = readl(REG(RTL8380_ICTL_GIMR)) & readl(REG(RTL8380_ICTL_GISR)); + + if (pending) { + struct irq_domain *domain = irq_desc_get_handler_data(desc); + generic_handle_irq(irq_find_mapping(domain, __ffs(pending))); + } else { + spurious_interrupt(); + } +} + +asmlinkage void plat_irq_dispatch(void) +{ + unsigned int pending; + + pending = read_c0_cause() & read_c0_status() & ST0_IM; + + if (pending & CAUSEF_IP7) + do_IRQ(RTL8380_CPU_IRQ_COUNTER); + + else if (pending & CAUSEF_IP6) + do_IRQ(RTL8380_CPU_IRQ_EXTERNAL); + + else if (pending & CAUSEF_IP5) + do_IRQ(RTL8380_CPU_IRQ_SHARED1); + + else if (pending & CAUSEF_IP4) + do_IRQ(RTL8380_CPU_IRQ_SWITCH); + + else if (pending & CAUSEF_IP3) + do_IRQ(RTL8380_CPU_IRQ_UART); + + else if (pending & CAUSEF_IP2) + do_IRQ(RTL8380_CPU_IRQ_SHARED0); + + else + spurious_interrupt(); +} + +static void __init icu_of_init(struct device_node *node, struct device_node *parent) +{ + struct irq_domain *domain; + + domain = irq_domain_add_simple(node, 32, 0, + &irq_domain_ops, NULL); + irq_set_chained_handler_and_data(2, realtek_irq_dispatch, domain); + irq_set_chained_handler_and_data(5, realtek_irq_dispatch, domain); + + realtek_ictl_base = of_iomap(node, 0); + if (!realtek_ictl_base) + return; + + /* Disable all cascaded interrupts */ + writel(0, REG(RTL8380_ICTL_GIMR)); + + /* Set up interrupt routing */ + writel(RTL8380_IRR0_SETTING, REG(RTL8380_IRR0)); + writel(RTL8380_IRR1_SETTING, REG(RTL8380_IRR1)); + writel(RTL8380_IRR2_SETTING, REG(RTL8380_IRR2)); + writel(RTL8380_IRR3_SETTING, REG(RTL8380_IRR3)); + + /* Clear timer interrupt */ + write_c0_compare(0); + + /* Enable all CPU interrupts */ + write_c0_status(read_c0_status() | ST0_IM); + + /* Enable timer0 and uart0 interrupts */ + writel(BIT(RTL8380_IRQ_TC0) | BIT(RTL8380_IRQ_UART0), REG(RTL8380_ICTL_GIMR)); +} + +static struct of_device_id __initdata of_irq_ids[] = { + { .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_irq_of_init }, + { .compatible = "realtek,rtl8380-intc", .data = icu_of_init }, + {}, +}; + +void __init arch_init_irq(void) +{ + of_irq_init(of_irq_ids); +} diff --git a/arch/mips/realtek/prom.c b/arch/mips/realtek/prom.c new file mode 100644 index 000000000000..be9d34282969 --- /dev/null +++ b/arch/mips/realtek/prom.c @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2006-2012 Tony Wu <tonywu@xxxxxxxxxxx> + * Copyright (C) 2020 Birger Koblitz <mail@xxxxxxxxxxxxxxxxx> + * Copyright (C) 2020 Bert Vermeulen <bert@xxxxxxxx> + * Copyright (C) 2020 John Crispin <john@xxxxxxxxxxx> + */ + +#include <linux/of.h> +#include <linux/of_fdt.h> +#include <linux/libfdt.h> +#include <asm/prom.h> + +#include <mach-realtek.h> + +extern char arcs_cmdline[]; +extern const char __appended_dtb; + +struct realtek_soc_info soc_info; +const void *fdt; + + +const char *get_system_type(void) +{ + return soc_info.name; +} + +void __init prom_free_prom_memory(void) +{ + return; +} + +void __init device_tree_init(void) +{ + if (!fdt_check_header(&__appended_dtb)) { + fdt = &__appended_dtb; + pr_info("Using appended Device Tree.\n"); + } + initial_boot_params = (void *)fdt; + unflatten_and_copy_device_tree(); +} + +static void __init prom_init_cmdline(void) +{ + int argc = fw_arg0; + char **argv = (char **) KSEG1ADDR(fw_arg1); + int i; + + arcs_cmdline[0] = '\0'; + + for (i = 0; i < argc; i++) { + char *p = (char *) KSEG1ADDR(argv[i]); + + if (CPHYSADDR(p) && *p) { + strlcat(arcs_cmdline, p, sizeof(arcs_cmdline)); + strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline)); + } + } + pr_info("Kernel command line: %s\n", arcs_cmdline); +} + +void __init prom_init(void) +{ + void *dtb; + uint32_t model; + + /* uart0 */ + setup_8250_early_printk_port(0xb8002000, 2, 0); + + model = readl(RTL8380_MODEL_NAME_INFO) >> 16; + if (model != 0x8330 && model != 0x8332 && + model != 0x8380 && model != 0x8382 ) + model = readl(RTL8390_MODEL_NAME_INFO) >> 16; + + soc_info.id = model; + + switch (model) { + case 0x8328: + soc_info.name="RTL8328"; + soc_info.family = RTL8328_FAMILY_ID; + break; + case 0x8332: + soc_info.name="RTL8332"; + soc_info.family = RTL8380_FAMILY_ID; + break; + case 0x8380: + soc_info.name="RTL8380"; + soc_info.family = RTL8380_FAMILY_ID; + break; + case 0x8382: + soc_info.name="RTL8382"; + soc_info.family = RTL8380_FAMILY_ID; + break; + case 0x8390: + soc_info.name="RTL8390"; + soc_info.family = RTL8390_FAMILY_ID; + break; + case 0x8391: + soc_info.name="RTL8391"; + soc_info.family = RTL8390_FAMILY_ID; + break; + case 0x8392: + soc_info.name="RTL8392"; + soc_info.family = RTL8390_FAMILY_ID; + break; + case 0x8393: + soc_info.name="RTL8393"; + soc_info.family = RTL8390_FAMILY_ID; + break; + default: + soc_info.name="DEFAULT"; + soc_info.family = 0; + } + pr_info("SoC Type: %s\n", soc_info.name); + prom_init_cmdline(); + + if (fw_passed_dtb) + dtb = (void *)fw_passed_dtb; + else if (__dtb_start != __dtb_end) + dtb = (void *)__dtb_start; + else + panic("no dtb found"); + + __dt_setup_arch(dtb); +} + diff --git a/arch/mips/realtek/setup.c b/arch/mips/realtek/setup.c new file mode 100644 index 000000000000..00b6af2fd541 --- /dev/null +++ b/arch/mips/realtek/setup.c @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2006-2012 Tony Wu <tonywu@xxxxxxxxxxx> + * Copyright (C) 2020 Birger Koblitz <mail@xxxxxxxxxxxxxxxxx> + * Copyright (C) 2020 Bert Vermeulen <bert@xxxxxxxx> + * Copyright (C) 2020 John Crispin <john@xxxxxxxxxxx> + */ + +#include <linux/of_fdt.h> +#include <asm/reboot.h> +#include <asm/time.h> +#include <mach-realtek.h> + +extern struct realtek_soc_info soc_info; + +static void realtek_restart(char *command) +{ + if (soc_info.family == RTL8380_FAMILY_ID) { + /* Reset Global Control1 Register */ + writel(1, RTL8380_RST_GLB_CTRL_1); + } else if (soc_info.family == RTL8390_FAMILY_ID) { + /* If calling reset vector fails, reset entire chip */ + writel(0xFFFFFFFF, RTL8390_RST_GLB_CTRL); + } +} + +static void realtek_halt(void) +{ + printk("System halted.\n"); + while(1); +} + +void __init plat_mem_setup(void) +{ + set_io_port_base(KSEG1); + + _machine_restart = realtek_restart; + _machine_halt = realtek_halt; +} + +void __init plat_time_init(void) +{ + struct device_node *np; + u32 freq = 500000000; + + np = of_find_node_by_name(NULL, "cpus"); + if (!np) { + pr_err("Missing 'cpus' DT node, using default frequency."); + } else { + if (of_property_read_u32(np, "frequency", &freq) < 0) + pr_err("No 'frequency' property in DT, using default."); + else + pr_info("CPU frequency from device tree: %d", freq); + of_node_put(np); + } + + mips_hpt_frequency = freq / 2; +} -- 2.25.1