static int ssi_add_controller()

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;
}