in brcmstb_gisb.c [399:501]
static int __init brcmstb_gisb_arb_probe(struct platform_device *pdev)
{
struct device_node *dn = pdev->dev.of_node;
struct brcmstb_gisb_arb_device *gdev;
const struct of_device_id *of_id;
struct resource *r;
int err, timeout_irq, tea_irq, bp_irq;
unsigned int num_masters, j = 0;
int i, first, last;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
timeout_irq = platform_get_irq(pdev, 0);
tea_irq = platform_get_irq(pdev, 1);
bp_irq = platform_get_irq(pdev, 2);
gdev = devm_kzalloc(&pdev->dev, sizeof(*gdev), GFP_KERNEL);
if (!gdev)
return -ENOMEM;
mutex_init(&gdev->lock);
INIT_LIST_HEAD(&gdev->next);
gdev->base = devm_ioremap_resource(&pdev->dev, r);
if (IS_ERR(gdev->base))
return PTR_ERR(gdev->base);
of_id = of_match_node(brcmstb_gisb_arb_of_match, dn);
if (!of_id) {
pr_err("failed to look up compatible string\n");
return -EINVAL;
}
gdev->gisb_offsets = of_id->data;
gdev->big_endian = of_device_is_big_endian(dn);
err = devm_request_irq(&pdev->dev, timeout_irq,
brcmstb_gisb_timeout_handler, 0, pdev->name,
gdev);
if (err < 0)
return err;
err = devm_request_irq(&pdev->dev, tea_irq,
brcmstb_gisb_tea_handler, 0, pdev->name,
gdev);
if (err < 0)
return err;
/* Interrupt is optional */
if (bp_irq > 0) {
err = devm_request_irq(&pdev->dev, bp_irq,
brcmstb_gisb_bp_handler, 0, pdev->name,
gdev);
if (err < 0)
return err;
}
/* If we do not have a valid mask, assume all masters are enabled */
if (of_property_read_u32(dn, "brcm,gisb-arb-master-mask",
&gdev->valid_mask))
gdev->valid_mask = 0xffffffff;
/* Proceed with reading the litteral names if we agree on the
* number of masters
*/
num_masters = of_property_count_strings(dn,
"brcm,gisb-arb-master-names");
if (hweight_long(gdev->valid_mask) == num_masters) {
first = ffs(gdev->valid_mask) - 1;
last = fls(gdev->valid_mask) - 1;
for (i = first; i < last; i++) {
if (!(gdev->valid_mask & BIT(i)))
continue;
of_property_read_string_index(dn,
"brcm,gisb-arb-master-names", j,
&gdev->master_names[i]);
j++;
}
}
err = sysfs_create_group(&pdev->dev.kobj, &gisb_arb_sysfs_attr_group);
if (err)
return err;
platform_set_drvdata(pdev, gdev);
list_add_tail(&gdev->next, &brcmstb_gisb_arb_device_list);
#ifdef CONFIG_MIPS
mips_set_be_handler(brcmstb_bus_error_handler);
#endif
if (list_is_singular(&brcmstb_gisb_arb_device_list)) {
register_die_notifier(&gisb_die_notifier);
atomic_notifier_chain_register(&panic_notifier_list,
&gisb_panic_notifier);
}
dev_info(&pdev->dev, "registered irqs: %d, %d\n",
timeout_irq, tea_irq);
return 0;
}