in controllers/omap_ssi_core.c [346:420]
static int ssi_add_controller(struct hsi_controller *ssi,
struct platform_device *pd)
{
struct omap_ssi_controller *omap_ssi;
int err;
omap_ssi = devm_kzalloc(&ssi->device, sizeof(*omap_ssi), GFP_KERNEL);
if (!omap_ssi)
return -ENOMEM;
err = ida_simple_get(&platform_omap_ssi_ida, 0, 0, GFP_KERNEL);
if (err < 0)
return err;
ssi->id = err;
ssi->owner = THIS_MODULE;
ssi->device.parent = &pd->dev;
dev_set_name(&ssi->device, "ssi%d", ssi->id);
hsi_controller_set_drvdata(ssi, omap_ssi);
omap_ssi->dev = &ssi->device;
err = ssi_get_iomem(pd, "sys", &omap_ssi->sys, NULL);
if (err < 0)
goto out_err;
err = ssi_get_iomem(pd, "gdd", &omap_ssi->gdd, NULL);
if (err < 0)
goto out_err;
err = platform_get_irq_byname(pd, "gdd_mpu");
if (err < 0)
goto out_err;
omap_ssi->gdd_irq = err;
tasklet_init(&omap_ssi->gdd_tasklet, ssi_gdd_tasklet,
(unsigned long)ssi);
err = devm_request_irq(&ssi->device, omap_ssi->gdd_irq, ssi_gdd_isr,
0, "gdd_mpu", ssi);
if (err < 0) {
dev_err(&ssi->device, "Request GDD IRQ %d failed (%d)",
omap_ssi->gdd_irq, err);
goto out_err;
}
omap_ssi->port = devm_kcalloc(&ssi->device, ssi->num_ports,
sizeof(*omap_ssi->port), GFP_KERNEL);
if (!omap_ssi->port) {
err = -ENOMEM;
goto out_err;
}
omap_ssi->fck = devm_clk_get(&ssi->device, "ssi_ssr_fck");
if (IS_ERR(omap_ssi->fck)) {
dev_err(&pd->dev, "Could not acquire clock \"ssi_ssr_fck\": %li\n",
PTR_ERR(omap_ssi->fck));
err = -ENODEV;
goto out_err;
}
omap_ssi->fck_nb.notifier_call = ssi_clk_event;
omap_ssi->fck_nb.priority = INT_MAX;
clk_notifier_register(omap_ssi->fck, &omap_ssi->fck_nb);
/* TODO: find register, which can be used to detect context loss */
omap_ssi->get_loss = NULL;
omap_ssi->max_speed = UINT_MAX;
spin_lock_init(&omap_ssi->lock);
err = hsi_register_controller(ssi);
if (err < 0)
goto out_err;
return 0;
out_err:
ida_simple_remove(&platform_omap_ssi_ida, ssi->id);
return err;
}