static int altr_edac_a10_probe()

in altera_edac.c [2080:2173]


static int altr_edac_a10_probe(struct platform_device *pdev)
{
	struct altr_arria10_edac *edac;
	struct device_node *child;

	edac = devm_kzalloc(&pdev->dev, sizeof(*edac), GFP_KERNEL);
	if (!edac)
		return -ENOMEM;

	edac->dev = &pdev->dev;
	platform_set_drvdata(pdev, edac);
	INIT_LIST_HEAD(&edac->a10_ecc_devices);

	edac->ecc_mgr_map =
		altr_sysmgr_regmap_lookup_by_phandle(pdev->dev.of_node,
						     "altr,sysmgr-syscon");

	if (IS_ERR(edac->ecc_mgr_map)) {
		edac_printk(KERN_ERR, EDAC_DEVICE,
			    "Unable to get syscon altr,sysmgr-syscon\n");
		return PTR_ERR(edac->ecc_mgr_map);
	}

	edac->irq_chip.name = pdev->dev.of_node->name;
	edac->irq_chip.irq_mask = a10_eccmgr_irq_mask;
	edac->irq_chip.irq_unmask = a10_eccmgr_irq_unmask;
	edac->domain = irq_domain_add_linear(pdev->dev.of_node, 64,
					     &a10_eccmgr_ic_ops, edac);
	if (!edac->domain) {
		dev_err(&pdev->dev, "Error adding IRQ domain\n");
		return -ENOMEM;
	}

	edac->sb_irq = platform_get_irq(pdev, 0);
	if (edac->sb_irq < 0) {
		dev_err(&pdev->dev, "No SBERR IRQ resource\n");
		return edac->sb_irq;
	}

	irq_set_chained_handler_and_data(edac->sb_irq,
					 altr_edac_a10_irq_handler,
					 edac);

#ifdef CONFIG_64BIT
	{
		int dberror, err_addr;

		edac->panic_notifier.notifier_call = s10_edac_dberr_handler;
		atomic_notifier_chain_register(&panic_notifier_list,
					       &edac->panic_notifier);

		/* Printout a message if uncorrectable error previously. */
		regmap_read(edac->ecc_mgr_map, S10_SYSMGR_UE_VAL_OFST,
			    &dberror);
		if (dberror) {
			regmap_read(edac->ecc_mgr_map, S10_SYSMGR_UE_ADDR_OFST,
				    &err_addr);
			edac_printk(KERN_ERR, EDAC_DEVICE,
				    "Previous Boot UE detected[0x%X] @ 0x%X\n",
				    dberror, err_addr);
			/* Reset the sticky registers */
			regmap_write(edac->ecc_mgr_map,
				     S10_SYSMGR_UE_VAL_OFST, 0);
			regmap_write(edac->ecc_mgr_map,
				     S10_SYSMGR_UE_ADDR_OFST, 0);
		}
	}
#else
	edac->db_irq = platform_get_irq(pdev, 1);
	if (edac->db_irq < 0) {
		dev_err(&pdev->dev, "No DBERR IRQ resource\n");
		return edac->db_irq;
	}
	irq_set_chained_handler_and_data(edac->db_irq,
					 altr_edac_a10_irq_handler, edac);
#endif

	for_each_child_of_node(pdev->dev.of_node, child) {
		if (!of_device_is_available(child))
			continue;

		if (of_match_node(altr_edac_a10_device_of_match, child))
			altr_edac_a10_device_add(edac, child);

#ifdef CONFIG_EDAC_ALTERA_SDRAM
		else if (of_device_is_compatible(child, "altr,sdram-edac-a10"))
			of_platform_populate(pdev->dev.of_node,
					     altr_sdram_ctrl_of_match,
					     NULL, &pdev->dev);
#endif
	}

	return 0;
}