in arm-ccn.c [1460:1518]
static int arm_ccn_probe(struct platform_device *pdev)
{
struct arm_ccn *ccn;
struct resource *res;
unsigned int irq;
int err;
ccn = devm_kzalloc(&pdev->dev, sizeof(*ccn), GFP_KERNEL);
if (!ccn)
return -ENOMEM;
ccn->dev = &pdev->dev;
platform_set_drvdata(pdev, ccn);
ccn->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(ccn->base))
return PTR_ERR(ccn->base);
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!res)
return -EINVAL;
irq = res->start;
/* Check if we can use the interrupt */
writel(CCN_MN_ERRINT_STATUS__PMU_EVENTS__DISABLE,
ccn->base + CCN_MN_ERRINT_STATUS);
if (readl(ccn->base + CCN_MN_ERRINT_STATUS) &
CCN_MN_ERRINT_STATUS__PMU_EVENTS__DISABLED) {
/* Can set 'disable' bits, so can acknowledge interrupts */
writel(CCN_MN_ERRINT_STATUS__PMU_EVENTS__ENABLE,
ccn->base + CCN_MN_ERRINT_STATUS);
err = devm_request_irq(ccn->dev, irq, arm_ccn_irq_handler,
IRQF_NOBALANCING | IRQF_NO_THREAD,
dev_name(ccn->dev), ccn);
if (err)
return err;
ccn->irq = irq;
}
/* Build topology */
err = arm_ccn_for_each_valid_region(ccn, arm_ccn_get_nodes_num);
if (err)
return err;
ccn->node = devm_kcalloc(ccn->dev, ccn->num_nodes, sizeof(*ccn->node),
GFP_KERNEL);
ccn->xp = devm_kcalloc(ccn->dev, ccn->num_xps, sizeof(*ccn->node),
GFP_KERNEL);
if (!ccn->node || !ccn->xp)
return -ENOMEM;
err = arm_ccn_for_each_valid_region(ccn, arm_ccn_init_nodes);
if (err)
return err;
return arm_ccn_pmu_init(ccn);
}