Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1928ce63 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "diag: dci: Add support for new HSIC channel for DCI data"

parents 406c5c31 92395bbf
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -451,7 +451,7 @@ static ssize_t diag_dbgfs_read_mempool(struct file *file, char __user *ubuf,
		diag_pools_array[POOL_DCI_IDX],
		driver->count_dci_pool);

	for (i = 0; i < MAX_HSIC_CH; i++) {
	for (i = 0; i < MAX_HSIC_DATA_CH; i++) {
		if (!diag_hsic[i].hsic_inited)
			continue;
		ret += scnprintf(buf+ret, DEBUG_BUF_SIZE-ret,
@@ -462,7 +462,7 @@ static ssize_t diag_dbgfs_read_mempool(struct file *file, char __user *ubuf,
				diag_hsic[i].count_hsic_pool);
	}

	for (i = 0; i < MAX_HSIC_CH; i++) {
	for (i = 0; i < MAX_HSIC_DATA_CH; i++) {
		if (!diag_hsic[i].hsic_inited)
			continue;
		ret += scnprintf(buf+ret, DEBUG_BUF_SIZE-ret,
@@ -569,7 +569,7 @@ static ssize_t diag_dbgfs_read_bridge(struct file *file, char __user *ubuf,
	bytes_in_buffer += bytes_written;
	bytes_remaining = buf_size - bytes_in_buffer;

	for (i = 0; i < MAX_HSIC_CH; i++) {
	for (i = 0; i < MAX_HSIC_DATA_CH; i++) {
		if (diag_hsic[i].hsic_inited) {
			/* Check if there is room to add another HSIC entry */
			if (bytes_remaining < bytes_hsic_inited)
+13 −4
Original line number Diff line number Diff line
@@ -41,8 +41,12 @@
#define POOL_TYPE_WRITE_STRUCT	4
#define POOL_TYPE_HSIC		5
#define POOL_TYPE_HSIC_2	6
#define POOL_TYPE_HSIC_DCI	7
#define POOL_TYPE_HSIC_DCI_2	8
#define POOL_TYPE_HSIC_WRITE	11
#define POOL_TYPE_HSIC_2_WRITE	12
#define POOL_TYPE_HSIC_DCI_WRITE	13
#define POOL_TYPE_HSIC_DCI_2_WRITE	14
#define POOL_TYPE_ALL		10
#define POOL_TYPE_DCI		20

@@ -53,11 +57,11 @@
#define POOL_DCI_IDX		4
#define POOL_BRIDGE_BASE	POOL_DCI_IDX
#define POOL_HSIC_IDX		(POOL_BRIDGE_BASE + 1)
#define POOL_HSIC_2_IDX		(POOL_BRIDGE_BASE + 2)
#define POOL_HSIC_DCI_IDX	(POOL_BRIDGE_BASE + 2)
#define POOL_HSIC_3_IDX		(POOL_BRIDGE_BASE + 3)
#define POOL_HSIC_4_IDX		(POOL_BRIDGE_BASE + 4)
#define POOL_HSIC_WRITE_IDX	(POOL_BRIDGE_BASE + 5)
#define POOL_HSIC_2_WRITE_IDX	(POOL_BRIDGE_BASE + 6)
#define POOL_HSIC_DCI_WRITE_IDX	(POOL_BRIDGE_BASE + 6)
#define POOL_HSIC_3_WRITE_IDX	(POOL_BRIDGE_BASE + 7)
#define POOL_HSIC_4_WRITE_IDX	(POOL_BRIDGE_BASE + 8)

@@ -170,6 +174,11 @@

#define DIAG_TS_SIZE	50


#define MAX_HSIC_DATA_CH	2
#define MAX_HSIC_DCI_CH		2
#define MAX_HSIC_CH		(MAX_HSIC_DATA_CH + MAX_HSIC_DCI_CH)

/* Maximum number of pkt reg supported at initialization*/
extern int diag_max_reg;
extern int diag_threshold_reg;
@@ -185,8 +194,6 @@ do { \
enum remote_procs {
	MDM = 1,
	MDM2 = 2,
	MDM3 = 3,
	MDM4 = 4,
	QSC = 5,
};

@@ -471,7 +478,9 @@ struct diagchar_dev {
};

extern struct diag_bridge_dev *diag_bridge;
extern struct diag_bridge_dci_dev *diag_bridge_dci;
extern struct diag_hsic_dev *diag_hsic;
extern struct diag_hsic_dci_dev *diag_hsic_dci;
extern struct diagchar_dev *driver;

extern int wrap_enabled;
+35 −15
Original line number Diff line number Diff line
@@ -165,7 +165,7 @@ void diag_clear_hsic_tbl(void)
	int i, j;

	/* Clear for all active HSIC bridges */
	for (j = 0; j < MAX_HSIC_CH; j++) {
	for (j = 0; j < MAX_HSIC_DATA_CH; j++) {
		if (diag_hsic[j].hsic_ch) {
			diag_hsic[j].num_hsic_buf_tbl_entries = 0;
			for (i = 0; i < diag_hsic[j].poolsize_hsic_write; i++) {
@@ -428,8 +428,6 @@ static int diag_get_remote(int remote_info)
	switch (val) {
	case MDM:
	case MDM2:
	case MDM3:
	case MDM4:
	case QSC:
		remote_val = -remote_info;
		break;
@@ -448,7 +446,7 @@ uint16_t diag_get_remote_device_mask(void)
	int i;

	/* Check for MDM processor */
	for (i = 0; i < MAX_HSIC_CH; i++)
	for (i = 0; i < MAX_HSIC_DATA_CH; i++)
		if (diag_hsic[i].hsic_inited)
			remote_dev |= 1 << i;

@@ -471,7 +469,7 @@ int diag_copy_remote(char __user *buf, size_t count, int *pret, int *pnum_data)
	struct diag_write_device hsic_buf_tbl[NUM_HSIC_BUF_TBL_ENTRIES];

	remote_token = diag_get_remote(MDM);
	for (index = 0; index < MAX_HSIC_CH; index++) {
	for (index = 0; index < MAX_HSIC_DATA_CH; index++) {
		if (!diag_hsic[index].hsic_inited) {
			remote_token--;
			continue;
@@ -784,7 +782,7 @@ void diag_cmp_logging_modes_diagfwd_bridge(int old_mode, int new_mode)
	} else if (old_mode == NO_LOGGING_MODE && new_mode
					== MEMORY_DEVICE_MODE) {
		int i;
		for (i = 0; i < MAX_HSIC_CH; i++)
		for (i = 0; i < MAX_HSIC_DATA_CH; i++)
			if (diag_hsic[i].hsic_inited)
				diag_hsic[i].hsic_data_requested =
					driver->real_time_mode ? 1 : 0;
@@ -1605,7 +1603,7 @@ static ssize_t diagchar_write(struct file *file, const char __user *buf,
#endif
#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
		/* send masks to All 9k */
		if ((remote_proc >= MDM) && (remote_proc <= MDM4)) {
		if ((remote_proc >= MDM) && (remote_proc <= MDM2)) {
			index = remote_proc - MDM;
			if (diag_hsic[index].hsic_ch && (payload_size > 0)) {
				/* wait sending mask updates
@@ -1618,7 +1616,8 @@ static ssize_t diagchar_write(struct file *file, const char __user *buf,
				diag_hsic[index].in_busy_hsic_write = 1;
				diag_hsic[index].in_busy_hsic_read_on_device =
									0;
				err = diag_bridge_write(index,
				err = diag_bridge_write(
					hsic_data_bridge_map[index],
					(char *)buf_hdlc, payload_size + 3);
				if (err) {
					pr_err("diag: err sending mask to MDM: %d\n",
@@ -1703,7 +1702,7 @@ static ssize_t diagchar_write(struct file *file, const char __user *buf,
#endif
#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
		/* send masks to All 9k */
		if ((remote_proc >= MDM) && (remote_proc <= MDM4) &&
		if ((remote_proc >= MDM) && (remote_proc <= MDM2) &&
							(payload_size > 0)) {
			index = remote_proc - MDM;
			/*
@@ -1726,7 +1725,8 @@ static ssize_t diagchar_write(struct file *file, const char __user *buf,
				diag_hsic[index].in_busy_hsic_write = 1;
				diag_hsic[index].in_busy_hsic_read_on_device =
									0;
				err = diag_bridge_write(index,
				err = diag_bridge_write(
						hsic_data_bridge_map[index],
						driver->user_space_data_buf +
						token_offset, payload_size);
				if (err) {
@@ -2119,8 +2119,10 @@ inline void diag_sdio_fn(int type) {}
#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
void diagfwd_bridge_fn(int type)
{
	if (type == EXIT)
	if (type == EXIT) {
		diagfwd_bridge_exit();
		diagfwd_bridge_dci_exit();
	}
}
#else
inline void diagfwd_bridge_fn(int type) { }
@@ -2135,14 +2137,26 @@ static int __init diagchar_init(void)
	ret = 0;
	driver = kzalloc(sizeof(struct diagchar_dev) + 5, GFP_KERNEL);
#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
	diag_bridge = kzalloc(MAX_BRIDGES * sizeof(struct diag_bridge_dev),
	diag_bridge = kzalloc(MAX_BRIDGES_DATA * sizeof(struct diag_bridge_dev),
								GFP_KERNEL);
	if (!diag_bridge)
		pr_warn("diag: could not allocate memory for bridges\n");
	diag_hsic = kzalloc(MAX_HSIC_CH * sizeof(struct diag_hsic_dev),
	diag_bridge_dci = kzalloc(MAX_BRIDGES_DCI *
			  sizeof(struct diag_bridge_dci_dev), GFP_KERNEL);
	if (!diag_bridge_dci) {
		pr_warn("diag: could not allocate memory for dci bridges\n");
		goto fail;
	}
	diag_hsic = kzalloc(MAX_HSIC_DATA_CH * sizeof(struct diag_hsic_dev),
								GFP_KERNEL);
	if (!diag_hsic)
		pr_warn("diag: could not allocate memory for hsic ch\n");
	diag_hsic_dci = kzalloc(MAX_HSIC_DCI_CH *
				sizeof(struct diag_hsic_dci_dev), GFP_KERNEL);
	if (!diag_hsic_dci) {
		pr_warn("diag: could not allocate memory for hsic dci ch\n");
		goto fail;
	}
#endif

	if (driver) {
@@ -2177,8 +2191,14 @@ static int __init diagchar_init(void)
		diag_masks_init();
		diagfwd_init();
#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
		diagfwd_bridge_init(HSIC);
		diagfwd_bridge_init(HSIC_2);
		diagfwd_bridge_init(HSIC_DATA_CH);
		diagfwd_bridge_init(HSIC_DATA_CH_2);
		ret = diagfwd_bridge_dci_init(HSIC_DCI_CH);
		if (ret)
			goto fail;
		ret = diagfwd_bridge_dci_init(HSIC_DCI_CH_2);
		if (ret)
			goto fail;
		/* register HSIC device */
		ret = platform_driver_register(&msm_hsic_ch_driver);
		if (ret)
+70 −16
Original line number Diff line number Diff line
/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -31,6 +31,7 @@
#include "diagfwd_bridge.h"

struct diag_bridge_dev *diag_bridge;
struct diag_bridge_dci_dev *diag_bridge_dci;

/* diagfwd_connect_bridge is called when the USB mdm channel is connected */
int diagfwd_connect_bridge(int process_cable)
@@ -39,7 +40,7 @@ int diagfwd_connect_bridge(int process_cable)

	pr_debug("diag: in %s\n", __func__);

	for (i = 0; i < MAX_BRIDGES; i++)
	for (i = 0; i < MAX_BRIDGES_DATA; i++)
		if (diag_bridge[i].enabled)
			connect_bridge(process_cable, i);
	return 0;
@@ -67,7 +68,7 @@ void connect_bridge(int process_cable, uint8_t index)
			diagfwd_connect_smux();
		}
	} else {
		if (index >= MAX_HSIC_CH) {
		if (index >= MAX_HSIC_DATA_CH) {
			pr_err("diag: Invalid hsic channel index %d in %s\n",
							index, __func__);
			mutex_unlock(&diag_bridge[index].bridge_mutex);
@@ -83,7 +84,8 @@ void connect_bridge(int process_cable, uint8_t index)
			if (!diag_hsic[index].hsic_device_opened) {
				hsic_diag_bridge_ops[index].ctxt =
							(void *)(int)(index);
				err = diag_bridge_open(index,
				err = diag_bridge_open(
						hsic_data_bridge_map[index],
						&hsic_diag_bridge_ops[index]);
				if (err) {
					pr_err("diag: HSIC channel open error: %d\n",
@@ -127,7 +129,7 @@ int diagfwd_disconnect_bridge(int process_cable)
	int i;
	pr_debug("diag: In %s, process_cable: %d\n", __func__, process_cable);

	for (i = 0; i < MAX_BRIDGES; i++) {
	for (i = 0; i < MAX_BRIDGES_DATA; i++) {
		if (diag_bridge[i].enabled) {
			mutex_lock(&diag_bridge[i].bridge_mutex);
			/* If the usb cable is being disconnected */
@@ -271,10 +273,8 @@ void diagfwd_bridge_init(int index)
	int ret;
	unsigned char name[20];

	if (index == HSIC) {
	if (index == HSIC_DATA_CH) {
		strlcpy(name, "hsic", sizeof(name));
	} else if (index == HSIC_2) {
		strlcpy(name, "hsic_2", sizeof(name));
	} else if (index == SMUX) {
		strlcpy(name, "smux", sizeof(name));
	} else {
@@ -306,18 +306,15 @@ void diagfwd_bridge_init(int index)
		goto err;
	mutex_init(&diag_bridge[index].bridge_mutex);

	if (index == HSIC || index == HSIC_2) {
	if (index == HSIC_DATA_CH) {
		INIT_WORK(&(diag_bridge[index].usb_read_complete_work),
				 diag_usb_read_complete_hsic_fn);
#ifdef CONFIG_DIAG_OVER_USB
		INIT_WORK(&(diag_bridge[index].diag_read_work),
		      diag_read_usb_hsic_work_fn);
		if (index == HSIC)
		if (index == HSIC_DATA_CH)
			diag_bridge[index].ch = usb_diag_open(DIAG_MDM,
				 (void *)index, diagfwd_bridge_notifier);
		else if (index == HSIC_2)
			diag_bridge[index].ch = usb_diag_open(DIAG_MDM2,
				 (void *)index, diagfwd_bridge_notifier);
		if (IS_ERR(diag_bridge[index].ch)) {
			pr_err("diag: Unable to open USB MDM ch = %d\n", index);
			goto err;
@@ -360,7 +357,7 @@ void diagfwd_bridge_exit(void)
	int i;
	pr_debug("diag: in %s\n", __func__);

	for (i = 0; i < MAX_HSIC_CH; i++) {
	for (i = 0; i < MAX_HSIC_DATA_CH; i++) {
		if (diag_hsic[i].hsic_device_enabled) {
			diag_hsic_close(i);
			diag_hsic[i].hsic_device_enabled = 0;
@@ -379,7 +376,7 @@ void diagfwd_bridge_exit(void)
	platform_driver_unregister(&msm_hsic_ch_driver);
	platform_driver_unregister(&msm_diagfwd_smux_driver);
	/* destroy USB MDM specific variables */
	for (i = 0; i < MAX_BRIDGES; i++) {
	for (i = 0; i < MAX_BRIDGES_DATA; i++) {
		if (diag_bridge[i].enabled) {
#ifdef CONFIG_DIAG_OVER_USB
			usb_diag_close(diag_bridge[i].ch);
@@ -392,3 +389,60 @@ void diagfwd_bridge_exit(void)
	}
	kfree(driver->write_ptr_mdm);
}

int diagfwd_bridge_dci_init(int index)
{
	unsigned char name[20];

	if (!diag_bridge_dci)
		return -EIO;

	/*
	 * Don't return an error code if the channel is not supported. The rest
	 * of the driver initialization should proceed.
	 * diag_bridge_dci[index].enabled is used to check if a particular
	 * bridge instance is initialized.
	 */
	if (index == HSIC_DCI_CH)
		strlcpy(name, "hsic_dci", sizeof(name));
	else
		return 0;

	strlcpy(diag_bridge_dci[index].name, name,
		sizeof(diag_bridge_dci[index].name));
	strlcat(name, "_diag_wq", sizeof(diag_bridge_dci[index].name));
	diag_bridge_dci[index].id = index;
	diag_bridge_dci[index].wq = create_singlethread_workqueue(name);
	if (!diag_bridge_dci[index].wq)
		return -ENOMEM;
	diag_bridge_dci[index].read_len = 0;
	diag_bridge_dci[index].write_len = 0;
	diag_bridge_dci[index].enabled = 1;
	mutex_init(&diag_bridge_dci[index].bridge_mutex);

	return 0;
}

void diagfwd_bridge_dci_exit(void)
{
	int i;
	pr_debug("diag: in %s\n", __func__);

	for (i = 0; i < MAX_HSIC_DCI_CH; i++) {
		if (diag_hsic_dci[i].hsic_device_enabled) {
			diag_hsic_dci_close(i);
			diag_hsic_dci[i].hsic_device_enabled = 0;
			diag_bridge_dci[i].enabled = 0;
		}
		diag_hsic_dci[i].hsic_inited = 0;
	}

	diagmem_exit(driver, POOL_TYPE_ALL);

	for (i = 0; i < MAX_BRIDGES_DCI; i++) {
		if (diag_bridge_dci[i].enabled) {
			destroy_workqueue(diag_bridge_dci[i].wq);
			diag_bridge_dci[i].enabled = 0;
		}
	}
}
+26 −5
Original line number Diff line number Diff line
/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -15,16 +15,26 @@

#include "diagfwd.h"

#define MAX_BRIDGES	5
#define HSIC	0
#define HSIC_2	1
#define SMUX	4
#define MAX_BRIDGES_DATA	3
#define MAX_BRIDGES_DCI		2
#define HSIC_DATA_CH		0
#define HSIC_DATA_CH_2		1
#define HSIC_DCI_CH		0
#define HSIC_DCI_CH_2		1
#define SMUX			2

#define DIAG_DATA_BRIDGE_IDX	0
#define DIAG_DCI_BRIDGE_IDX	1
#define DIAG_DATA_BRIDGE_IDX_2	2
#define DIAG_DCI_BRIDGE_IDX_2	3

int diagfwd_connect_bridge(int);
void connect_bridge(int, uint8_t);
int diagfwd_disconnect_bridge(int);
void diagfwd_bridge_init(int index);
int diagfwd_bridge_dci_init(int index);
void diagfwd_bridge_exit(void);
void diagfwd_bridge_dci_exit(void);
int diagfwd_read_complete_bridge(struct diag_request *diag_read_ptr);

/* Diag-Bridge structure, n bridges can be used at same time
@@ -46,4 +56,15 @@ struct diag_bridge_dev {
	struct work_struct usb_read_complete_work;
};

struct diag_bridge_dci_dev {
	int id;
	char name[20];
	int enabled;
	struct mutex bridge_mutex;
	int read_len;
	int write_len;
	struct workqueue_struct *wq;
	struct work_struct read_complete_work;
};

#endif
Loading