in controllers/omap_ssi_port.c [1125:1235]
static int ssi_port_probe(struct platform_device *pd)
{
struct device_node *np = pd->dev.of_node;
struct hsi_port *port;
struct omap_ssi_port *omap_port;
struct hsi_controller *ssi = dev_get_drvdata(pd->dev.parent);
struct omap_ssi_controller *omap_ssi = hsi_controller_drvdata(ssi);
struct gpio_desc *cawake_gpio = NULL;
u32 port_id;
int err;
dev_dbg(&pd->dev, "init ssi port...\n");
if (!ssi->port || !omap_ssi->port) {
dev_err(&pd->dev, "ssi controller not initialized!\n");
err = -ENODEV;
goto error;
}
/* get id of first uninitialized port in controller */
for (port_id = 0; port_id < ssi->num_ports && omap_ssi->port[port_id];
port_id++)
;
if (port_id >= ssi->num_ports) {
dev_err(&pd->dev, "port id out of range!\n");
err = -ENODEV;
goto error;
}
port = ssi->port[port_id];
if (!np) {
dev_err(&pd->dev, "missing device tree data\n");
err = -EINVAL;
goto error;
}
cawake_gpio = devm_gpiod_get(&pd->dev, "ti,ssi-cawake", GPIOD_IN);
if (IS_ERR(cawake_gpio)) {
err = PTR_ERR(cawake_gpio);
dev_err(&pd->dev, "couldn't get cawake gpio (err=%d)!\n", err);
goto error;
}
omap_port = devm_kzalloc(&port->device, sizeof(*omap_port), GFP_KERNEL);
if (!omap_port) {
err = -ENOMEM;
goto error;
}
omap_port->wake_gpio = cawake_gpio;
omap_port->pdev = &pd->dev;
omap_port->port_id = port_id;
INIT_DEFERRABLE_WORK(&omap_port->errqueue_work, ssi_process_errqueue);
INIT_WORK(&omap_port->work, start_tx_work);
/* initialize HSI port */
port->async = ssi_async;
port->setup = ssi_setup;
port->flush = ssi_flush;
port->start_tx = ssi_start_tx;
port->stop_tx = ssi_stop_tx;
port->release = ssi_release;
hsi_port_set_drvdata(port, omap_port);
omap_ssi->port[port_id] = omap_port;
platform_set_drvdata(pd, port);
err = ssi_port_get_iomem(pd, "tx", &omap_port->sst_base,
&omap_port->sst_dma);
if (err < 0)
goto error;
err = ssi_port_get_iomem(pd, "rx", &omap_port->ssr_base,
&omap_port->ssr_dma);
if (err < 0)
goto error;
err = ssi_port_irq(port, pd);
if (err < 0)
goto error;
err = ssi_wake_irq(port, pd);
if (err < 0)
goto error;
ssi_queues_init(omap_port);
spin_lock_init(&omap_port->lock);
spin_lock_init(&omap_port->wk_lock);
omap_port->dev = &port->device;
pm_runtime_use_autosuspend(omap_port->pdev);
pm_runtime_set_autosuspend_delay(omap_port->pdev, 250);
pm_runtime_enable(omap_port->pdev);
#ifdef CONFIG_DEBUG_FS
err = ssi_debug_add_port(omap_port, omap_ssi->dir);
if (err < 0) {
pm_runtime_disable(omap_port->pdev);
goto error;
}
#endif
hsi_add_clients_from_dt(port, np);
dev_info(&pd->dev, "ssi port %u successfully initialized\n", port_id);
return 0;
error:
return err;
}