Esempio n. 1
0
static int __devinit mpc85xx_l2_err_probe(struct platform_device *op)
{
	struct edac_device_ctl_info *edac_dev;
	struct mpc85xx_l2_pdata *pdata;
	struct resource r;
	int res;

	if (!devres_open_group(&op->dev, mpc85xx_l2_err_probe, GFP_KERNEL))
		return -ENOMEM;

	edac_dev = edac_device_alloc_ctl_info(sizeof(*pdata),
					      "cpu", 1, "L", 1, 2, NULL, 0,
					      edac_dev_idx);
	if (!edac_dev) {
		devres_release_group(&op->dev, mpc85xx_l2_err_probe);
		return -ENOMEM;
	}

	pdata = edac_dev->pvt_info;
	pdata->name = "mpc85xx_l2_err";
	pdata->irq = NO_IRQ;
	edac_dev->dev = &op->dev;
	dev_set_drvdata(edac_dev->dev, edac_dev);
	edac_dev->ctl_name = pdata->name;
	edac_dev->dev_name = pdata->name;

	res = of_address_to_resource(op->dev.of_node, 0, &r);
	if (res) {
		printk(KERN_ERR "%s: Unable to get resource for "
		       "L2 err regs\n", __func__);
		goto err;
	}

	/* we only need the error registers */
	r.start += 0xe00;

<<<<<<< HEAD
Esempio n. 2
0
static int __devinit mpc85xx_mc_err_probe(struct of_device *op,
					  const struct of_device_id *match)
{
	struct mem_ctl_info *mci;
	struct mpc85xx_mc_pdata *pdata;
	struct resource r;
	u32 sdram_ctl;
	int res;

	if (!devres_open_group(&op->dev, mpc85xx_mc_err_probe, GFP_KERNEL))
		return -ENOMEM;

	mci = edac_mc_alloc(sizeof(*pdata), 4, 1, edac_mc_idx);
	if (!mci) {
		devres_release_group(&op->dev, mpc85xx_mc_err_probe);
		return -ENOMEM;
	}

	pdata = mci->pvt_info;
	pdata->name = "mpc85xx_mc_err";
	pdata->irq = NO_IRQ;
	mci->dev = &op->dev;
	pdata->edac_idx = edac_mc_idx++;
	dev_set_drvdata(mci->dev, mci);
	mci->ctl_name = pdata->name;
	mci->dev_name = pdata->name;

	res = of_address_to_resource(op->node, 0, &r);
	if (res) {
		printk(KERN_ERR "%s: Unable to get resource for MC err regs\n",
		       __func__);
		goto err;
	}

	if (!devm_request_mem_region(&op->dev, r.start,
				     r.end - r.start + 1, pdata->name)) {
		printk(KERN_ERR "%s: Error while requesting mem region\n",
		       __func__);
		res = -EBUSY;
		goto err;
	}

	pdata->mc_vbase = devm_ioremap(&op->dev, r.start, r.end - r.start + 1);
	if (!pdata->mc_vbase) {
		printk(KERN_ERR "%s: Unable to setup MC err regs\n", __func__);
		res = -ENOMEM;
		goto err;
	}

	sdram_ctl = in_be32(pdata->mc_vbase + MPC85XX_MC_DDR_SDRAM_CFG);
	if (!(sdram_ctl & DSC_ECC_EN)) {
		/* no ECC */
		printk(KERN_WARNING "%s: No ECC DIMMs discovered\n", __func__);
		res = -ENODEV;
		goto err;
	}

	debugf3("%s(): init mci\n", __func__);
	mci->mtype_cap = MEM_FLAG_RDDR | MEM_FLAG_RDDR2 |
	    MEM_FLAG_DDR | MEM_FLAG_DDR2;
	mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED;
	mci->edac_cap = EDAC_FLAG_SECDED;
	mci->mod_name = EDAC_MOD_STR;
	mci->mod_ver = MPC85XX_REVISION;

	if (edac_op_state == EDAC_OPSTATE_POLL)
		mci->edac_check = mpc85xx_mc_check;

	mci->ctl_page_to_phys = NULL;

	mci->scrub_mode = SCRUB_SW_SRC;

	mpc85xx_set_mc_sysfs_attributes(mci);

	mpc85xx_init_csrows(mci);

#ifdef CONFIG_EDAC_DEBUG
	edac_mc_register_mcidev_debug((struct attribute **)debug_attr);
#endif

	/* store the original error disable bits */
	orig_ddr_err_disable =
	    in_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DISABLE);
	out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DISABLE, 0);

	/* clear all error bits */
	out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DETECT, ~0);

	if (edac_mc_add_mc(mci)) {
		debugf3("%s(): failed edac_mc_add_mc()\n", __func__);
		goto err;
	}

	if (edac_op_state == EDAC_OPSTATE_INT) {
		out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_INT_EN,
			 DDR_EIE_MBEE | DDR_EIE_SBEE);

		/* store the original error management threshold */
		orig_ddr_err_sbe = in_be32(pdata->mc_vbase +
					   MPC85XX_MC_ERR_SBE) & 0xff0000;

		/* set threshold to 1 error per interrupt */
		out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_SBE, 0x10000);

		/* register interrupts */
		pdata->irq = irq_of_parse_and_map(op->node, 0);
		res = devm_request_irq(&op->dev, pdata->irq,
				       mpc85xx_mc_isr,
					IRQF_DISABLED | IRQF_SHARED,
				       "[EDAC] MC err", mci);
		if (res < 0) {
			printk(KERN_ERR "%s: Unable to request irq %d for "
			       "MPC85xx DRAM ERR\n", __func__, pdata->irq);
			irq_dispose_mapping(pdata->irq);
			res = -ENODEV;
			goto err2;
		}

		printk(KERN_INFO EDAC_MOD_STR " acquired irq %d for MC\n",
		       pdata->irq);
	}

	devres_remove_group(&op->dev, mpc85xx_mc_err_probe);
	debugf3("%s(): success\n", __func__);
	printk(KERN_INFO EDAC_MOD_STR " MC err registered\n");

	return 0;

err2:
	edac_mc_del_mc(&op->dev);
err:
	devres_release_group(&op->dev, mpc85xx_mc_err_probe);
	edac_mc_free(mci);
	return res;
}
Esempio n. 3
0
static int __devinit mpc85xx_l2_err_probe(struct of_device *op,
					  const struct of_device_id *match)
{
	struct edac_device_ctl_info *edac_dev;
	struct mpc85xx_l2_pdata *pdata;
	struct resource r;
	int res;

	if (!devres_open_group(&op->dev, mpc85xx_l2_err_probe, GFP_KERNEL))
		return -ENOMEM;

	edac_dev = edac_device_alloc_ctl_info(sizeof(*pdata),
					      "cpu", 1, "L", 1, 2, NULL, 0,
					      edac_dev_idx);
	if (!edac_dev) {
		devres_release_group(&op->dev, mpc85xx_l2_err_probe);
		return -ENOMEM;
	}

	pdata = edac_dev->pvt_info;
	pdata->name = "mpc85xx_l2_err";
	pdata->irq = NO_IRQ;
	edac_dev->dev = &op->dev;
	dev_set_drvdata(edac_dev->dev, edac_dev);
	edac_dev->ctl_name = pdata->name;
	edac_dev->dev_name = pdata->name;

	res = of_address_to_resource(op->node, 0, &r);
	if (res) {
		printk(KERN_ERR "%s: Unable to get resource for "
		       "L2 err regs\n", __func__);
		goto err;
	}

	/* we only need the error registers */
	r.start += 0xe00;

	if (!devm_request_mem_region(&op->dev, r.start,
				     r.end - r.start + 1, pdata->name)) {
		printk(KERN_ERR "%s: Error while requesting mem region\n",
		       __func__);
		res = -EBUSY;
		goto err;
	}

	pdata->l2_vbase = devm_ioremap(&op->dev, r.start, r.end - r.start + 1);
	if (!pdata->l2_vbase) {
		printk(KERN_ERR "%s: Unable to setup L2 err regs\n", __func__);
		res = -ENOMEM;
		goto err;
	}

	out_be32(pdata->l2_vbase + MPC85XX_L2_ERRDET, ~0);

	orig_l2_err_disable = in_be32(pdata->l2_vbase + MPC85XX_L2_ERRDIS);

	/* clear the err_dis */
	out_be32(pdata->l2_vbase + MPC85XX_L2_ERRDIS, 0);

	edac_dev->mod_name = EDAC_MOD_STR;

	if (edac_op_state == EDAC_OPSTATE_POLL)
		edac_dev->edac_check = mpc85xx_l2_check;

	mpc85xx_set_l2_sysfs_attributes(edac_dev);

	pdata->edac_idx = edac_dev_idx++;

	if (edac_device_add_device(edac_dev) > 0) {
		debugf3("%s(): failed edac_device_add_device()\n", __func__);
		goto err;
	}

	if (edac_op_state == EDAC_OPSTATE_INT) {
		pdata->irq = irq_of_parse_and_map(op->node, 0);
		res = devm_request_irq(&op->dev, pdata->irq,
				       mpc85xx_l2_isr, IRQF_DISABLED,
				       "[EDAC] L2 err", edac_dev);
		if (res < 0) {
			printk(KERN_ERR
			       "%s: Unable to requiest irq %d for "
			       "MPC85xx L2 err\n", __func__, pdata->irq);
			irq_dispose_mapping(pdata->irq);
			res = -ENODEV;
			goto err2;
		}

		printk(KERN_INFO EDAC_MOD_STR " acquired irq %d for L2 Err\n",
		       pdata->irq);

		edac_dev->op_state = OP_RUNNING_INTERRUPT;

		out_be32(pdata->l2_vbase + MPC85XX_L2_ERRINTEN, L2_EIE_MASK);
	}

	devres_remove_group(&op->dev, mpc85xx_l2_err_probe);

	debugf3("%s(): success\n", __func__);
	printk(KERN_INFO EDAC_MOD_STR " L2 err registered\n");

	return 0;

err2:
	edac_device_del_device(&op->dev);
err:
	devres_release_group(&op->dev, mpc85xx_l2_err_probe);
	edac_device_free_ctl_info(edac_dev);
	return res;
}
Esempio n. 4
0
static int __devinit mpc85xx_pci_err_probe(struct of_device *op,
					   const struct of_device_id *match)
{
	struct edac_pci_ctl_info *pci;
	struct mpc85xx_pci_pdata *pdata;
	struct resource r;
	int res = 0;

	if (!devres_open_group(&op->dev, mpc85xx_pci_err_probe, GFP_KERNEL))
		return -ENOMEM;

	pci = edac_pci_alloc_ctl_info(sizeof(*pdata), "mpc85xx_pci_err");
	if (!pci)
		return -ENOMEM;

	pdata = pci->pvt_info;
	pdata->name = "mpc85xx_pci_err";
	pdata->irq = NO_IRQ;
	dev_set_drvdata(&op->dev, pci);
	pci->dev = &op->dev;
	pci->mod_name = EDAC_MOD_STR;
	pci->ctl_name = pdata->name;
	pci->dev_name = op->dev.bus_id;

	if (edac_op_state == EDAC_OPSTATE_POLL)
		pci->edac_check = mpc85xx_pci_check;

	pdata->edac_idx = edac_pci_idx++;

	res = of_address_to_resource(op->node, 0, &r);
	if (res) {
		printk(KERN_ERR "%s: Unable to get resource for "
		       "PCI err regs\n", __func__);
		goto err;
	}

	/* we only need the error registers */
	r.start += 0xe00;

	if (!devm_request_mem_region(&op->dev, r.start,
					r.end - r.start + 1, pdata->name)) {
		printk(KERN_ERR "%s: Error while requesting mem region\n",
		       __func__);
		res = -EBUSY;
		goto err;
	}

	pdata->pci_vbase = devm_ioremap(&op->dev, r.start,
					r.end - r.start + 1);
	if (!pdata->pci_vbase) {
		printk(KERN_ERR "%s: Unable to setup PCI err regs\n", __func__);
		res = -ENOMEM;
		goto err;
	}

	orig_pci_err_cap_dr =
	    in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_CAP_DR);

	/* PCI master abort is expected during config cycles */
	out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_CAP_DR, 0x40);

	orig_pci_err_en = in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EN);

	/* disable master abort reporting */
	out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EN, ~0x40);

	/* clear error bits */
	out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DR, ~0);

	if (edac_pci_add_device(pci, pdata->edac_idx) > 0) {
		debugf3("%s(): failed edac_pci_add_device()\n", __func__);
		goto err;
	}

	if (edac_op_state == EDAC_OPSTATE_INT) {
		pdata->irq = irq_of_parse_and_map(op->node, 0);
		res = devm_request_irq(&op->dev, pdata->irq,
				       mpc85xx_pci_isr, IRQF_DISABLED,
				       "[EDAC] PCI err", pci);
		if (res < 0) {
			printk(KERN_ERR
			       "%s: Unable to requiest irq %d for "
			       "MPC85xx PCI err\n", __func__, pdata->irq);
			irq_dispose_mapping(pdata->irq);
			res = -ENODEV;
			goto err2;
		}

		printk(KERN_INFO EDAC_MOD_STR " acquired irq %d for PCI Err\n",
		       pdata->irq);
	}

	devres_remove_group(&op->dev, mpc85xx_pci_err_probe);
	debugf3("%s(): success\n", __func__);
	printk(KERN_INFO EDAC_MOD_STR " PCI err registered\n");

	return 0;

err2:
	edac_pci_del_device(&op->dev);
err:
	edac_pci_free_ctl_info(pci);
	devres_release_group(&op->dev, mpc85xx_pci_err_probe);
	return res;
}
static int __devinit highbank_l2_err_probe(struct platform_device *pdev)
{
	struct edac_device_ctl_info *dci;
	struct hb_l2_drvdata *drvdata;
	struct resource *r;
	int res = 0;

	dci = edac_device_alloc_ctl_info(sizeof(*drvdata), "cpu",
		1, "L", 1, 2, NULL, 0, 0);
	if (!dci)
		return -ENOMEM;

	drvdata = dci->pvt_info;
	dci->dev = &pdev->dev;
	platform_set_drvdata(pdev, dci);

	if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL))
		return -ENOMEM;

	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!r) {
		dev_err(&pdev->dev, "Unable to get mem resource\n");
		res = -ENODEV;
		goto err;
	}

	if (!devm_request_mem_region(&pdev->dev, r->start,
				     resource_size(r), dev_name(&pdev->dev))) {
		dev_err(&pdev->dev, "Error while requesting mem region\n");
		res = -EBUSY;
		goto err;
	}

	drvdata->base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
	if (!drvdata->base) {
		dev_err(&pdev->dev, "Unable to map regs\n");
		res = -ENOMEM;
		goto err;
	}

	drvdata->db_irq = platform_get_irq(pdev, 0);
	res = devm_request_irq(&pdev->dev, drvdata->db_irq,
			       highbank_l2_err_handler,
			       0, dev_name(&pdev->dev), dci);
	if (res < 0)
		goto err;

	drvdata->sb_irq = platform_get_irq(pdev, 1);
	res = devm_request_irq(&pdev->dev, drvdata->sb_irq,
			       highbank_l2_err_handler,
			       0, dev_name(&pdev->dev), dci);
	if (res < 0)
		goto err;

	dci->mod_name = dev_name(&pdev->dev);
	dci->dev_name = dev_name(&pdev->dev);

	if (edac_device_add_device(dci))
		goto err;

	devres_close_group(&pdev->dev, NULL);
	return 0;
err:
	devres_release_group(&pdev->dev, NULL);
	edac_device_free_ctl_info(dci);
	return res;
}
Esempio n. 6
0
/**
 * ahci_platform_get_resources - Get platform resources
 * @pdev: platform device to get resources for
 *
 * This function allocates an ahci_host_priv struct, and gets the following
 * resources, storing a reference to them inside the returned struct:
 *
 * 1) mmio registers (IORESOURCE_MEM 0, mandatory)
 * 2) regulator for controlling the targets power (optional)
 * 3) 0 - AHCI_MAX_CLKS clocks, as specified in the devs devicetree node,
 *    or for non devicetree enabled platforms a single clock
 *	4) phy (optional)
 *
 * RETURNS:
 * The allocated ahci_host_priv on success, otherwise an ERR_PTR value
 */
struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct ahci_host_priv *hpriv;
	struct clk *clk;
	int i, rc = -ENOMEM;

	if (!devres_open_group(dev, NULL, GFP_KERNEL))
		return ERR_PTR(-ENOMEM);

	hpriv = devres_alloc(ahci_platform_put_resources, sizeof(*hpriv),
			     GFP_KERNEL);
	if (!hpriv)
		goto err_out;

	devres_add(dev, hpriv);

	hpriv->mmio = devm_ioremap_resource(dev,
			      platform_get_resource(pdev, IORESOURCE_MEM, 0));
	if (IS_ERR(hpriv->mmio)) {
		dev_err(dev, "no mmio space\n");
		rc = PTR_ERR(hpriv->mmio);
		goto err_out;
	}

	hpriv->target_pwr = devm_regulator_get_optional(dev, "target");
	if (IS_ERR(hpriv->target_pwr)) {
		rc = PTR_ERR(hpriv->target_pwr);
		if (rc == -EPROBE_DEFER)
			goto err_out;
		hpriv->target_pwr = NULL;
	}

	for (i = 0; i < AHCI_MAX_CLKS; i++) {
		/*
		 * For now we must use clk_get(dev, NULL) for the first clock,
		 * because some platforms (da850, spear13xx) are not yet
		 * converted to use devicetree for clocks.  For new platforms
		 * this is equivalent to of_clk_get(dev->of_node, 0).
		 */
		if (i == 0)
			clk = clk_get(dev, NULL);
		else
			clk = of_clk_get(dev->of_node, i);

		if (IS_ERR(clk)) {
			rc = PTR_ERR(clk);
			if (rc == -EPROBE_DEFER)
				goto err_out;
			break;
		}
		hpriv->clks[i] = clk;
	}

	hpriv->phy = devm_phy_get(dev, "sata-phy");
	if (IS_ERR(hpriv->phy)) {
		rc = PTR_ERR(hpriv->phy);
		switch (rc) {
		case -ENODEV:
		case -ENOSYS:
			/* continue normally */
			hpriv->phy = NULL;
			break;

		case -EPROBE_DEFER:
			goto err_out;

		default:
			dev_err(dev, "couldn't get sata-phy\n");
			goto err_out;
		}
	}

	pm_runtime_enable(dev);
	pm_runtime_get_sync(dev);
	hpriv->got_runtime_pm = true;

	devres_remove_group(dev, NULL);
	return hpriv;

err_out:
	devres_release_group(dev, NULL);
	return ERR_PTR(rc);
}