162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Routines common to most mpc85xx-based boards.
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#include <linux/of.h>
762306a36Sopenharmony_ci#include <linux/of_irq.h>
862306a36Sopenharmony_ci#include <linux/of_platform.h>
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <asm/fsl_pm.h>
1162306a36Sopenharmony_ci#include <soc/fsl/qe/qe.h>
1262306a36Sopenharmony_ci#include <sysdev/cpm2_pic.h>
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include "mpc85xx.h"
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ciconst struct fsl_pm_ops *qoriq_pm_ops;
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_cistatic const struct of_device_id mpc85xx_common_ids[] __initconst = {
1962306a36Sopenharmony_ci	{ .type = "soc", },
2062306a36Sopenharmony_ci	{ .compatible = "soc", },
2162306a36Sopenharmony_ci	{ .compatible = "simple-bus", },
2262306a36Sopenharmony_ci	{ .name = "cpm", },
2362306a36Sopenharmony_ci	{ .name = "localbus", },
2462306a36Sopenharmony_ci	{ .compatible = "gianfar", },
2562306a36Sopenharmony_ci	{ .compatible = "fsl,qe", },
2662306a36Sopenharmony_ci	{ .compatible = "fsl,cpm2", },
2762306a36Sopenharmony_ci	{ .compatible = "fsl,srio", },
2862306a36Sopenharmony_ci	/* So that the DMA channel nodes can be probed individually: */
2962306a36Sopenharmony_ci	{ .compatible = "fsl,eloplus-dma", },
3062306a36Sopenharmony_ci	/* For the PMC driver */
3162306a36Sopenharmony_ci	{ .compatible = "fsl,mpc8548-guts", },
3262306a36Sopenharmony_ci	/* Probably unnecessary? */
3362306a36Sopenharmony_ci	{ .compatible = "gpio-leds", },
3462306a36Sopenharmony_ci	/* For all PCI controllers */
3562306a36Sopenharmony_ci	{ .compatible = "fsl,mpc8540-pci", },
3662306a36Sopenharmony_ci	{ .compatible = "fsl,mpc8548-pcie", },
3762306a36Sopenharmony_ci	{ .compatible = "fsl,p1022-pcie", },
3862306a36Sopenharmony_ci	{ .compatible = "fsl,p1010-pcie", },
3962306a36Sopenharmony_ci	{ .compatible = "fsl,p1023-pcie", },
4062306a36Sopenharmony_ci	{ .compatible = "fsl,p4080-pcie", },
4162306a36Sopenharmony_ci	{ .compatible = "fsl,qoriq-pcie-v2.4", },
4262306a36Sopenharmony_ci	{ .compatible = "fsl,qoriq-pcie-v2.3", },
4362306a36Sopenharmony_ci	{ .compatible = "fsl,qoriq-pcie-v2.2", },
4462306a36Sopenharmony_ci	{ .compatible = "fsl,fman", },
4562306a36Sopenharmony_ci	{},
4662306a36Sopenharmony_ci};
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ciint __init mpc85xx_common_publish_devices(void)
4962306a36Sopenharmony_ci{
5062306a36Sopenharmony_ci	return of_platform_bus_probe(NULL, mpc85xx_common_ids, NULL);
5162306a36Sopenharmony_ci}
5262306a36Sopenharmony_ci#ifdef CONFIG_CPM2
5362306a36Sopenharmony_cistatic void cpm2_cascade(struct irq_desc *desc)
5462306a36Sopenharmony_ci{
5562306a36Sopenharmony_ci	struct irq_chip *chip = irq_desc_get_chip(desc);
5662306a36Sopenharmony_ci	int cascade_irq;
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci	while ((cascade_irq = cpm2_get_irq()) >= 0)
5962306a36Sopenharmony_ci		generic_handle_irq(cascade_irq);
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci	chip->irq_eoi(&desc->irq_data);
6262306a36Sopenharmony_ci}
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_civoid __init mpc85xx_cpm2_pic_init(void)
6662306a36Sopenharmony_ci{
6762306a36Sopenharmony_ci	struct device_node *np;
6862306a36Sopenharmony_ci	int irq;
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci	/* Setup CPM2 PIC */
7162306a36Sopenharmony_ci	np = of_find_compatible_node(NULL, NULL, "fsl,cpm2-pic");
7262306a36Sopenharmony_ci	if (np == NULL) {
7362306a36Sopenharmony_ci		printk(KERN_ERR "PIC init: can not find fsl,cpm2-pic node\n");
7462306a36Sopenharmony_ci		return;
7562306a36Sopenharmony_ci	}
7662306a36Sopenharmony_ci	irq = irq_of_parse_and_map(np, 0);
7762306a36Sopenharmony_ci	if (!irq) {
7862306a36Sopenharmony_ci		of_node_put(np);
7962306a36Sopenharmony_ci		printk(KERN_ERR "PIC init: got no IRQ for cpm cascade\n");
8062306a36Sopenharmony_ci		return;
8162306a36Sopenharmony_ci	}
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci	cpm2_pic_init(np);
8462306a36Sopenharmony_ci	of_node_put(np);
8562306a36Sopenharmony_ci	irq_set_chained_handler(irq, cpm2_cascade);
8662306a36Sopenharmony_ci}
8762306a36Sopenharmony_ci#endif
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci#ifdef CONFIG_QUICC_ENGINE
9062306a36Sopenharmony_civoid __init mpc85xx_qe_par_io_init(void)
9162306a36Sopenharmony_ci{
9262306a36Sopenharmony_ci	struct device_node *np;
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci	np = of_find_node_by_name(NULL, "par_io");
9562306a36Sopenharmony_ci	if (np) {
9662306a36Sopenharmony_ci		struct device_node *ucc;
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci		par_io_init(np);
9962306a36Sopenharmony_ci		of_node_put(np);
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci		for_each_node_by_name(ucc, "ucc")
10262306a36Sopenharmony_ci			par_io_of_config(ucc);
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci	}
10562306a36Sopenharmony_ci}
10662306a36Sopenharmony_ci#endif
107