Ejemplo n.º 1
0
static int __devexit hsi_char_remove(struct device *dev)
{
	struct hsi_client *cl = to_hsi_client(dev);
	struct hsi_char_client_data *cl_data = hsi_client_drvdata(cl);
	struct hsi_char_channel *channel = cl_data->channels;
	int i;

	for (i = 0; i < HSI_CHAR_DEVS; i++) {
		if (!(channel->state & HSI_CHST_AVAIL))
			continue;
		if (cl_data->attached) {
			hsi_release_port(channel->cl);
			cl_data->attached = 0;
		}
		channel->state = HSI_CHST_UNAVAIL;
		channel->cl = NULL;
		channel++;
	}

	return 0;
}
Ejemplo n.º 2
0
static int __devinit hsi_char_probe(struct device *dev)
{
	struct hsi_char_client_data *cl_data = &hsi_char_cl_data;
	struct hsi_char_channel *channel = cl_data->channels;
	struct hsi_client *cl = to_hsi_client(dev);
	int i;

	for (i = 0; i < HSI_CHAR_DEVS; i++) {
		if (channel->state == HSI_CHST_AVAIL)
			channel->cl = cl;
		channel++;
	}
	cl->hsi_start_rx = NULL;
	cl->hsi_stop_rx = NULL;
	atomic_set(&cl_data->refcnt, 0);
	atomic_set(&cl_data->breq, 1);
	cl_data->attached = 0;
	hsi_client_set_drvdata(cl, cl_data);

	return 0;
}
Ejemplo n.º 3
0
static int nokia_modem_probe(struct device *dev)
{
	struct device_node *np;
	struct nokia_modem_device *modem;
	struct hsi_client *cl = to_hsi_client(dev);
	struct hsi_port *port = hsi_get_port(cl);
	int irq, pflags, err;
	struct hsi_board_info ssip;
	struct hsi_board_info cmtspeech;

	np = dev->of_node;
	if (!np) {
		dev_err(dev, "device tree node not found\n");
		return -ENXIO;
	}

	modem = devm_kzalloc(dev, sizeof(*modem), GFP_KERNEL);
	if (!modem) {
		dev_err(dev, "Could not allocate memory for nokia_modem_device\n");
		return -ENOMEM;
	}
	dev_set_drvdata(dev, modem);
	modem->device = dev;

	irq = irq_of_parse_and_map(np, 0);
	if (!irq) {
		dev_err(dev, "Invalid rst_ind interrupt (%d)\n", irq);
		return -EINVAL;
	}
	modem->nokia_modem_rst_ind_irq = irq;
	pflags = irq_get_trigger_type(irq);

	tasklet_init(&modem->nokia_modem_rst_ind_tasklet,
			do_nokia_modem_rst_ind_tasklet, (unsigned long)modem);
	err = devm_request_irq(dev, irq, nokia_modem_rst_ind_isr,
				pflags, "modem_rst_ind", modem);
	if (err < 0) {
		dev_err(dev, "Request rst_ind irq(%d) failed (flags %d)\n",
								irq, pflags);
		return err;
	}
	enable_irq_wake(irq);

	if(pm) {
		err = nokia_modem_gpio_probe(dev);
		if (err < 0) {
			dev_err(dev, "Could not probe GPIOs\n");
			goto error1;
		}
	}

	ssip.name = "ssi-protocol";
	ssip.tx_cfg = cl->tx_cfg;
	ssip.rx_cfg = cl->rx_cfg;
	ssip.platform_data = NULL;
	ssip.archdata = NULL;

	modem->ssi_protocol = hsi_new_client(port, &ssip);
	if (!modem->ssi_protocol) {
		dev_err(dev, "Could not register ssi-protocol device\n");
		err = -ENOMEM;
		goto error2;
	}

	err = device_attach(&modem->ssi_protocol->device);
	if (err == 0) {
		dev_dbg(dev, "Missing ssi-protocol driver\n");
		err = -EPROBE_DEFER;
		goto error3;
	} else if (err < 0) {
		dev_err(dev, "Could not load ssi-protocol driver (%d)\n", err);
		goto error3;
	}

	cmtspeech.name = "cmt-speech";
	cmtspeech.tx_cfg = cl->tx_cfg;
	cmtspeech.rx_cfg = cl->rx_cfg;
	cmtspeech.platform_data = NULL;
	cmtspeech.archdata = NULL;

	modem->cmt_speech = hsi_new_client(port, &cmtspeech);
	if (!modem->cmt_speech) {
		dev_err(dev, "Could not register cmt-speech device\n");
		err = -ENOMEM;
		goto error3;
	}

	err = device_attach(&modem->cmt_speech->device);
	if (err == 0) {
		dev_dbg(dev, "Missing cmt-speech driver\n");
		err = -EPROBE_DEFER;
		goto error4;
	} else if (err < 0) {
		dev_err(dev, "Could not load cmt-speech driver (%d)\n", err);
		goto error4;
	}

	dev_info(dev, "Registered Nokia HSI modem\n");

	return 0;

error4:
	hsi_remove_client(&modem->cmt_speech->device, NULL);
error3:
	hsi_remove_client(&modem->ssi_protocol->device, NULL);
error2:
	nokia_modem_gpio_unexport(dev);
error1:
	disable_irq_wake(modem->nokia_modem_rst_ind_irq);
	tasklet_kill(&modem->nokia_modem_rst_ind_tasklet);

	return err;
}
Ejemplo n.º 4
0
struct dlp_channel *dlp_ctrl_ctx_create(unsigned int ch_id,
		unsigned int hsi_channel,
		struct device *dev)
{
	struct hsi_client *client = to_hsi_client(dev);
	struct dlp_channel *ch_ctx;
	struct dlp_ctrl_context *ctrl_ctx;

	ch_ctx = kzalloc(sizeof(struct dlp_channel), GFP_KERNEL);
	if (!ch_ctx) {
		pr_err(DRVNAME ": Out of memory (ctrl_ch_ctx)\n");
		return NULL;
	}

	/* Allocate the context private data */
	ctrl_ctx = kzalloc(sizeof(struct dlp_ctrl_context), GFP_KERNEL);
	if (!ctrl_ctx) {
		pr_err(DRVNAME ": Out of memory (ctrl_ctx)\n");
		goto free_ch;
	}

	/* Create a workqueue to to manage:
	 *	- Modem readiness
	 *	- HSI TX timeout
	 */
	ctrl_ctx->wq = create_singlethread_workqueue(DRVNAME "-ctrl_wq");
	if (!ctrl_ctx->wq) {
		pr_err(DRVNAME ": Unable to create CTRL workqueue\n");
		goto free_ctx;
	}

	/* Save params */
	ch_ctx->ch_data = ctrl_ctx;
	ch_ctx->ch_id = ch_id;
	ch_ctx->hsi_channel = hsi_channel;
	ch_ctx->rx.config = client->rx_cfg;
	ch_ctx->tx.config = client->tx_cfg;

	spin_lock_init(&ch_ctx->lock);
	INIT_WORK(&ctrl_ctx->tx_timeout_work, dlp_ctrl_handle_tx_timeout);
	spin_lock_init(&ctrl_ctx->open_lock);

	/* Register PDUs push, cleanup CBs */
	ch_ctx->push_rx_pdus = dlp_ctrl_push_rx_pdus;
	ch_ctx->cleanup = dlp_ctrl_ctx_cleanup;

	dlp_xfer_ctx_init(ch_ctx,
			  DLP_CTRL_TX_PDU_SIZE, 0, 0, 0, NULL, HSI_MSG_WRITE);

	dlp_xfer_ctx_init(ch_ctx,
			  DLP_CTRL_RX_PDU_SIZE, 0, 0, 0, NULL, HSI_MSG_READ);

	/* Set ch_ctx, not yet done in the probe */
	DLP_CHANNEL_CTX(DLP_CHANNEL_CTRL) = ch_ctx;

	return ch_ctx;

free_ctx:
	kfree(ctrl_ctx);

free_ch:
	kfree(ch_ctx);
	return NULL;
}