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

Commit d9e1ba1f authored by Ritesh Kumar's avatar Ritesh Kumar Committed by Gerrit - the friendly Code Review server
Browse files

input: touchscreen: synaptics_dsx: move read write buffer to heap



Move I2C read/write buffers from stack to heap memory in
synaptics_dsx touch driver, to support GSI mode in buses.

Change-Id: I31b24d7f5aacade1256967fadc28d7c216b8400c
Signed-off-by: default avatarRitesh Kumar <riteshk@codeaurora.org>
parent 7b939544
Loading
Loading
Loading
Loading
+151 −112
Original line number Diff line number Diff line
@@ -205,18 +205,6 @@ static ssize_t synaptics_rmi4_secure_touch_show(struct device *dev,
		struct device_attribute *attr, char *buf);
#endif

struct synaptics_rmi4_f01_device_status {
	union {
		struct {
			unsigned char status_code:4;
			unsigned char reserved:2;
			unsigned char flash_prog:1;
			unsigned char unconfigured:1;
		} __packed;
		unsigned char data[1];
	};
};

struct synaptics_rmi4_f11_query_0_5 {
	union {
		struct {
@@ -1922,10 +1910,9 @@ static int synaptics_rmi4_sensor_report(struct synaptics_rmi4_data *rmi4_data,
		bool report)
{
	int retval;
	unsigned char data[MAX_INTR_REGISTERS + 1];
	unsigned char *intr = &data[1];
	unsigned char *data = NULL;
	unsigned char *intr;
	bool was_in_bl_mode;
	struct synaptics_rmi4_f01_device_status status;
	struct synaptics_rmi4_fn *fhandler;
	struct synaptics_rmi4_exp_fhandler *exp_fhandler;
	struct synaptics_rmi4_device_info *rmi;
@@ -1936,6 +1923,14 @@ static int synaptics_rmi4_sensor_report(struct synaptics_rmi4_data *rmi4_data,
	 * Get interrupt status information from F01 Data1 register to
	 * determine the source(s) that are flagging the interrupt.
	 */
	data = kcalloc((MAX_INTR_REGISTERS + 1), sizeof(char), GFP_KERNEL);
	if (!data) {
		retval = -ENOMEM;
		goto exit;
	}

	intr = &data[1];

	retval = synaptics_rmi4_reg_read(rmi4_data,
			rmi4_data->f01_data_base_addr,
			data,
@@ -1944,31 +1939,31 @@ static int synaptics_rmi4_sensor_report(struct synaptics_rmi4_data *rmi4_data,
		dev_err(rmi4_data->pdev->dev.parent,
				"%s: Failed to read interrupt status\n",
				__func__);
		return retval;
		goto exit;
	}

	status.data[0] = data[0];
	if (status.status_code == STATUS_CRC_IN_PROGRESS) {
	rmi4_data->status.data[0] = data[0];
	if (rmi4_data->status.status_code == STATUS_CRC_IN_PROGRESS) {
		retval = synaptics_rmi4_check_status(rmi4_data,
				&was_in_bl_mode);
		if (retval < 0) {
			dev_err(rmi4_data->pdev->dev.parent,
					"%s: Failed to check status\n",
					__func__);
			return retval;
			goto exit;
		}
		retval = synaptics_rmi4_reg_read(rmi4_data,
				rmi4_data->f01_data_base_addr,
				status.data,
				sizeof(status.data));
				rmi4_data->status.data,
				sizeof(rmi4_data->status.data));
		if (retval < 0) {
			dev_err(rmi4_data->pdev->dev.parent,
					"%s: Failed to read device status\n",
					__func__);
			return retval;
			goto exit;
		}
	}
	if (status.unconfigured && !status.flash_prog) {
	if (rmi4_data->status.unconfigured && !rmi4_data->status.flash_prog) {
		pr_notice("%s: spontaneous reset detected\n", __func__);
		retval = synaptics_rmi4_reinit_device(rmi4_data);
		if (retval < 0) {
@@ -1979,7 +1974,7 @@ static int synaptics_rmi4_sensor_report(struct synaptics_rmi4_data *rmi4_data,
	}

	if (!report)
		return retval;
		goto exit;

	/*
	 * Traverse the function handler list and service the source(s)
@@ -2007,7 +2002,8 @@ static int synaptics_rmi4_sensor_report(struct synaptics_rmi4_data *rmi4_data,
		}
	}
	mutex_unlock(&exp_data.mutex);

exit:
	kfree(data);
	return retval;
}

@@ -2068,12 +2064,18 @@ static int synaptics_rmi4_irq_enable(struct synaptics_rmi4_data *rmi4_data,
		bool enable, bool attn_only)
{
	int retval = 0;
	unsigned char data[MAX_INTR_REGISTERS];
	unsigned char *data = NULL;
	const struct synaptics_dsx_board_data *bdata =
			rmi4_data->hw_if->board_data;

	mutex_lock(&(rmi4_data->rmi4_irq_enable_mutex));

	data = kcalloc(MAX_INTR_REGISTERS, sizeof(char), GFP_KERNEL);
	if (!data) {
		retval = -ENOMEM;
		goto exit;
	}

	if (attn_only) {
		retval = synaptics_rmi4_int_enable(rmi4_data, enable);
		goto exit;
@@ -2127,8 +2129,8 @@ static int synaptics_rmi4_irq_enable(struct synaptics_rmi4_data *rmi4_data,
	}

exit:
	kfree(data);
	mutex_unlock(&(rmi4_data->rmi4_irq_enable_mutex));

	return retval;
}

@@ -2532,8 +2534,8 @@ static int synaptics_rmi4_f12_init(struct synaptics_rmi4_data *rmi4_data,
	unsigned char subpacket;
	unsigned char ctrl_23_size;
	unsigned char size_of_2d_data;
	unsigned char size_of_query5;
	unsigned char size_of_query8;
	unsigned char *size_of_query5 = NULL;
	unsigned char *size_of_query8 = NULL;
	unsigned char ctrl_8_offset;
	unsigned char ctrl_20_offset;
	unsigned char ctrl_23_offset;
@@ -2563,6 +2565,18 @@ static int synaptics_rmi4_f12_init(struct synaptics_rmi4_data *rmi4_data,
	extra_data = (struct synaptics_rmi4_f12_extra_data *)fhandler->extra;
	size_of_2d_data = sizeof(struct synaptics_rmi4_f12_finger_data);

	size_of_query5 = kcalloc(1, sizeof(char), GFP_KERNEL);
	if (!size_of_query5) {
		retval = -ENOMEM;
		goto exit;
	}

	size_of_query8 = kcalloc(1, sizeof(char), GFP_KERNEL);
	if (!size_of_query8) {
		retval = -ENOMEM;
		goto exit;
	}

	query_5 = kzalloc(sizeof(*query_5), GFP_KERNEL);
	if (!query_5) {
		dev_err(rmi4_data->pdev->dev.parent,
@@ -2619,19 +2633,19 @@ static int synaptics_rmi4_f12_init(struct synaptics_rmi4_data *rmi4_data,

	retval = synaptics_rmi4_reg_read(rmi4_data,
			fhandler->full_addr.query_base + 4,
			&size_of_query5,
			sizeof(size_of_query5));
			size_of_query5,
			sizeof(*size_of_query5));
	if (retval < 0)
		goto exit;

	if (size_of_query5 > sizeof(query_5->data))
		size_of_query5 = sizeof(query_5->data);
	if (*size_of_query5 > sizeof(query_5->data))
		*size_of_query5 = sizeof(query_5->data);
	memset(query_5->data, 0x00, sizeof(query_5->data));

	retval = synaptics_rmi4_reg_read(rmi4_data,
			fhandler->full_addr.query_base + 5,
			query_5->data,
			size_of_query5);
			*size_of_query5);
	if (retval < 0)
		goto exit;

@@ -2746,26 +2760,26 @@ static int synaptics_rmi4_f12_init(struct synaptics_rmi4_data *rmi4_data,

	retval = synaptics_rmi4_reg_read(rmi4_data,
			fhandler->full_addr.query_base + 7,
			&size_of_query8,
			sizeof(size_of_query8));
			size_of_query8,
			sizeof(*size_of_query8));
	if (retval < 0)
		goto exit;

	if (size_of_query8 > sizeof(query_8->data))
		size_of_query8 = sizeof(query_8->data);
	if (*size_of_query8 > sizeof(query_8->data))
		*size_of_query8 = sizeof(query_8->data);
	memset(query_8->data, 0x00, sizeof(query_8->data));

	retval = synaptics_rmi4_reg_read(rmi4_data,
			fhandler->full_addr.query_base + 8,
			query_8->data,
			size_of_query8);
			*size_of_query8);
	if (retval < 0)
		goto exit;

	/* Determine the presence of the Data0 register */
	extra_data->data1_offset = query_8->data0_is_present;

	if ((size_of_query8 >= 3) && (query_8->data15_is_present)) {
	if ((*size_of_query8 >= 3) && (query_8->data15_is_present)) {
		extra_data->data15_offset = query_8->data0_is_present +
				query_8->data1_is_present +
				query_8->data2_is_present +
@@ -2787,7 +2801,7 @@ static int synaptics_rmi4_f12_init(struct synaptics_rmi4_data *rmi4_data,
	}

#ifdef REPORT_2D_PRESSURE
	if ((size_of_query8 >= 5) && (query_8->data29_is_present)) {
	if ((*size_of_query8 >= 5) && (query_8->data29_is_present)) {
		extra_data->data29_offset = query_8->data0_is_present +
				query_8->data1_is_present +
				query_8->data2_is_present +
@@ -2935,6 +2949,8 @@ static int synaptics_rmi4_f12_init(struct synaptics_rmi4_data *rmi4_data,
	}

exit:
	kfree(size_of_query5);
	kfree(size_of_query8);
	kfree(query_5);
	kfree(query_8);
	kfree(ctrl_8);
@@ -3160,16 +3176,15 @@ static int synaptics_rmi4_check_status(struct synaptics_rmi4_data *rmi4_data,
{
	int retval;
	int timeout = CHECK_STATUS_TIMEOUT_MS;
	struct synaptics_rmi4_f01_device_status status;

	retval = synaptics_rmi4_reg_read(rmi4_data,
			rmi4_data->f01_data_base_addr,
			status.data,
			sizeof(status.data));
			rmi4_data->status.data,
			sizeof(rmi4_data->status.data));
	if (retval < 0)
		return retval;

	while (status.status_code == STATUS_CRC_IN_PROGRESS) {
	while (rmi4_data->status.status_code == STATUS_CRC_IN_PROGRESS) {
		if (timeout > 0)
			msleep(20);
		else
@@ -3177,8 +3192,8 @@ static int synaptics_rmi4_check_status(struct synaptics_rmi4_data *rmi4_data,

		retval = synaptics_rmi4_reg_read(rmi4_data,
				rmi4_data->f01_data_base_addr,
				status.data,
				sizeof(status.data));
				rmi4_data->status.data,
				sizeof(rmi4_data->status.data));
		if (retval < 0)
			return retval;

@@ -3188,11 +3203,11 @@ static int synaptics_rmi4_check_status(struct synaptics_rmi4_data *rmi4_data,
	if (timeout != CHECK_STATUS_TIMEOUT_MS)
		*was_in_bl_mode = true;

	if (status.flash_prog == 1) {
	if (rmi4_data->status.flash_prog == 1) {
		rmi4_data->flash_prog_mode = true;
		pr_notice("%s: In flash prog mode, status = 0x%02x\n",
				__func__,
				status.status_code);
				rmi4_data->status.status_code);
	} else {
		rmi4_data->flash_prog_mode = false;
	}
@@ -3203,32 +3218,39 @@ static int synaptics_rmi4_check_status(struct synaptics_rmi4_data *rmi4_data,
static int synaptics_rmi4_set_configured(struct synaptics_rmi4_data *rmi4_data)
{
	int retval;
	unsigned char device_ctrl;
	unsigned char *device_ctrl = NULL;

	device_ctrl = kcalloc(1, sizeof(char), GFP_KERNEL);
	if (!device_ctrl) {
		retval = -ENOMEM;
		goto exit;
	}

	retval = synaptics_rmi4_reg_read(rmi4_data,
			rmi4_data->f01_ctrl_base_addr,
			&device_ctrl,
			sizeof(device_ctrl));
			device_ctrl,
			sizeof(*device_ctrl));
	if (retval < 0) {
		dev_err(rmi4_data->pdev->dev.parent,
				"%s: Failed to set configured\n",
				__func__);
		return retval;
		goto exit;
	}

	rmi4_data->no_sleep_setting = device_ctrl & NO_SLEEP_ON;
	device_ctrl |= CONFIGURED;
	rmi4_data->no_sleep_setting = *device_ctrl & NO_SLEEP_ON;
	*device_ctrl |= CONFIGURED;

	retval = synaptics_rmi4_reg_write(rmi4_data,
			rmi4_data->f01_ctrl_base_addr,
			&device_ctrl,
			sizeof(device_ctrl));
			device_ctrl,
			sizeof(*device_ctrl));
	if (retval < 0) {
		dev_err(rmi4_data->pdev->dev.parent,
				"%s: Failed to set configured\n",
				__func__);
	}

exit:
	kfree(device_ctrl);
	return retval;
}

@@ -3265,7 +3287,6 @@ static int synaptics_rmi4_query_device(struct synaptics_rmi4_data *rmi4_data)
	bool f01found;
	bool f35found;
	bool was_in_bl_mode;
	struct synaptics_rmi4_fn_desc rmi_fd;
	struct synaptics_rmi4_fn *fhandler;
	struct synaptics_rmi4_device_info *rmi;

@@ -3286,8 +3307,8 @@ static int synaptics_rmi4_query_device(struct synaptics_rmi4_data *rmi4_data)

			retval = synaptics_rmi4_reg_read(rmi4_data,
					pdt_entry_addr,
					(unsigned char *)&rmi_fd,
					sizeof(rmi_fd));
					(unsigned char *)&rmi4_data->rmi_fd,
					sizeof(rmi4_data->rmi_fd));
			if (retval < 0)
				return retval;

@@ -3295,7 +3316,7 @@ static int synaptics_rmi4_query_device(struct synaptics_rmi4_data *rmi4_data)

			fhandler = NULL;

			if (rmi_fd.fn_number == 0) {
			if (rmi4_data->rmi_fd.fn_number == 0) {
				dev_dbg(rmi4_data->pdev->dev.parent,
						"%s: Reached end of PDT\n",
						__func__);
@@ -3304,28 +3325,30 @@ static int synaptics_rmi4_query_device(struct synaptics_rmi4_data *rmi4_data)

			dev_dbg(rmi4_data->pdev->dev.parent,
					"%s: F%02x found (page %d)\n",
					__func__, rmi_fd.fn_number,
					__func__, rmi4_data->rmi_fd.fn_number,
					page_number);

			switch (rmi_fd.fn_number) {
			switch (rmi4_data->rmi_fd.fn_number) {
			case SYNAPTICS_RMI4_F01:
				if (rmi_fd.intr_src_count == 0)
				if (rmi4_data->rmi_fd.intr_src_count == 0)
					break;

				f01found = true;

				retval = synaptics_rmi4_alloc_fh(&fhandler,
						&rmi_fd, page_number);
						&rmi4_data->rmi_fd,
						page_number);
				if (retval < 0) {
					dev_err(rmi4_data->pdev->dev.parent,
						"%s: Failed to alloc for F%d\n",
						__func__,
							rmi_fd.fn_number);
						rmi4_data->rmi_fd.fn_number);
					return retval;
				}

				retval = synaptics_rmi4_f01_init(rmi4_data,
						fhandler, &rmi_fd, intr_count);
						fhandler, &rmi4_data->rmi_fd,
						intr_count);
				if (retval < 0)
					return retval;

@@ -3349,59 +3372,65 @@ static int synaptics_rmi4_query_device(struct synaptics_rmi4_data *rmi4_data)

				break;
			case SYNAPTICS_RMI4_F11:
				if (rmi_fd.intr_src_count == 0)
				if (rmi4_data->rmi_fd.intr_src_count == 0)
					break;

				retval = synaptics_rmi4_alloc_fh(&fhandler,
						&rmi_fd, page_number);
						&rmi4_data->rmi_fd,
						page_number);
				if (retval < 0) {
					dev_err(rmi4_data->pdev->dev.parent,
						"%s: Failed to alloc for F%d\n",
						__func__,
							rmi_fd.fn_number);
						rmi4_data->rmi_fd.fn_number);
					return retval;
				}

				retval = synaptics_rmi4_f11_init(rmi4_data,
						fhandler, &rmi_fd, intr_count);
						fhandler, &rmi4_data->rmi_fd,
						intr_count);
				if (retval < 0)
					return retval;
				break;
			case SYNAPTICS_RMI4_F12:
				if (rmi_fd.intr_src_count == 0)
				if (rmi4_data->rmi_fd.intr_src_count == 0)
					break;

				retval = synaptics_rmi4_alloc_fh(&fhandler,
						&rmi_fd, page_number);
						&rmi4_data->rmi_fd,
						page_number);
				if (retval < 0) {
					dev_err(rmi4_data->pdev->dev.parent,
						"%s: Failed to alloc for F%d\n",
						__func__,
							rmi_fd.fn_number);
						rmi4_data->rmi_fd.fn_number);
					return retval;
				}

				retval = synaptics_rmi4_f12_init(rmi4_data,
						fhandler, &rmi_fd, intr_count);
						fhandler, &rmi4_data->rmi_fd,
						intr_count);
				if (retval < 0)
					return retval;
				break;
			case SYNAPTICS_RMI4_F1A:
				if (rmi_fd.intr_src_count == 0)
				if (rmi4_data->rmi_fd.intr_src_count == 0)
					break;

				retval = synaptics_rmi4_alloc_fh(&fhandler,
						&rmi_fd, page_number);
						&rmi4_data->rmi_fd,
						page_number);
				if (retval < 0) {
					dev_err(rmi4_data->pdev->dev.parent,
						"%s: Failed to alloc for F%d\n",
						__func__,
							rmi_fd.fn_number);
						rmi4_data->rmi_fd.fn_number);
					return retval;
				}

				retval = synaptics_rmi4_f1a_init(rmi4_data,
						fhandler, &rmi_fd, intr_count);
						fhandler, &rmi4_data->rmi_fd,
						intr_count);
				if (retval < 0) {
#ifdef IGNORE_FN_INIT_FAILURE
					kfree(fhandler);
@@ -3413,25 +3442,27 @@ static int synaptics_rmi4_query_device(struct synaptics_rmi4_data *rmi4_data)
				break;
#ifdef USE_DATA_SERVER
			case SYNAPTICS_RMI4_F21:
				if (rmi_fd.intr_src_count == 0)
				if (rmi4_data->rmi_fd.intr_src_count == 0)
					break;

				retval = synaptics_rmi4_alloc_fh(&fhandler,
						&rmi_fd, page_number);
						&rmi4_data->rmi_fd,
						page_number);
				if (retval < 0) {
					dev_err(rmi4_data->pdev->dev.parent,
						"%s: Failed to alloc for F%d\n",
						__func__,
							rmi_fd.fn_number);
						rmi4_data->rmi_fd.fn_number);
					return retval;
				}

				fhandler->fn_number = rmi_fd.fn_number;
				fhandler->fn_number =
					rmi4_data->rmi_fd.fn_number;
				fhandler->num_of_data_sources =
						rmi_fd.intr_src_count;
					rmi4_data->rmi_fd.intr_src_count;

				synaptics_rmi4_set_intr_mask(fhandler, &rmi_fd,
						intr_count);
				synaptics_rmi4_set_intr_mask(fhandler,
						&rmi4_data->rmi_fd, intr_count);
				break;
#endif
			case SYNAPTICS_RMI4_F35:
@@ -3440,16 +3471,16 @@ static int synaptics_rmi4_query_device(struct synaptics_rmi4_data *rmi4_data)
#ifdef F51_DISCRETE_FORCE
			case SYNAPTICS_RMI4_F51:
				rmi4_data->f51_query_base_addr =
						rmi_fd.query_base_addr |
					rmi4_data->rmi_fd.query_base_addr |
					(page_number << 8);
				break;
#endif
			}

			/* Accumulate the interrupt count */
			intr_count += rmi_fd.intr_src_count;
			intr_count += rmi4_data->rmi_fd.intr_src_count;

			if (fhandler && rmi_fd.intr_src_count) {
			if (fhandler && rmi4_data->rmi_fd.intr_src_count) {
				list_add_tail(&fhandler->link,
						&rmi->support_fn_list);
			}
@@ -4366,39 +4397,47 @@ static int synaptics_rmi4_sleep_enable(struct synaptics_rmi4_data *rmi4_data,
		bool enable)
{
	int retval;
	unsigned char device_ctrl;
	unsigned char *device_ctrl = NULL;
	unsigned char no_sleep_setting = rmi4_data->no_sleep_setting;

	device_ctrl = kcalloc(1, sizeof(char), GFP_KERNEL);
	if (!device_ctrl) {
		retval = -ENOMEM;
		goto exit;
	}

	retval = synaptics_rmi4_reg_read(rmi4_data,
			rmi4_data->f01_ctrl_base_addr,
			&device_ctrl,
			sizeof(device_ctrl));
			device_ctrl,
			sizeof(*device_ctrl));
	if (retval < 0) {
		dev_err(rmi4_data->pdev->dev.parent,
				"%s: Failed to read device control\n",
				__func__);
		return retval;
		goto exit;
	}

	device_ctrl = device_ctrl & ~MASK_3BIT;
	*device_ctrl = *device_ctrl & ~MASK_3BIT;
	if (enable)
		device_ctrl = device_ctrl | SENSOR_SLEEP;
		*device_ctrl = *device_ctrl | SENSOR_SLEEP;
	else
		device_ctrl = device_ctrl | no_sleep_setting | NORMAL_OPERATION;
		*device_ctrl = *device_ctrl | no_sleep_setting |
			NORMAL_OPERATION;

	retval = synaptics_rmi4_reg_write(rmi4_data,
			rmi4_data->f01_ctrl_base_addr,
			&device_ctrl,
			sizeof(device_ctrl));
			device_ctrl,
			sizeof(*device_ctrl));
	if (retval < 0) {
		dev_err(rmi4_data->pdev->dev.parent,
				"%s: Failed to write device control\n",
				__func__);
		return retval;
		goto exit;
	}

	rmi4_data->sensor_sleep = enable;

exit:
	kfree(device_ctrl);
	return retval;
}

+13 −0
Original line number Diff line number Diff line
@@ -289,6 +289,17 @@ struct synaptics_rmi4_device_info {
	struct list_head support_fn_list;
};

struct synaptics_rmi4_f01_device_status {
	union {
		struct {
			unsigned char status_code:4;
			unsigned char reserved:2;
			unsigned char flash_prog:1;
			unsigned char unconfigured:1;
		} __packed;
		unsigned char data[1];
	};
};
/*
 * struct synaptics_rmi4_data - RMI4 device instance data
 * @pdev: pointer to platform device
@@ -363,6 +374,8 @@ struct synaptics_rmi4_data {
	const struct synaptics_dsx_hw_interface *hw_if;
	struct synaptics_rmi4_device_info rmi4_mod_info;
	struct synaptics_rmi4_input_settings input_settings;
	struct synaptics_rmi4_fn_desc rmi_fd;
	struct synaptics_rmi4_f01_device_status status;
	struct kobject *board_prop_dir;
	struct regulator *pwr_reg;
	struct regulator *bus_reg;
+97 −63
Original line number Diff line number Diff line
@@ -1388,30 +1388,42 @@ static int fwu_parse_image_info(void)

static int fwu_read_flash_status(void)
{
	int retval;
	unsigned char status;
	unsigned char command;
	int retval = 0;
	unsigned char *status = NULL;
	unsigned char *command = NULL;
	struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;

	status = kcalloc(1, sizeof(char), GFP_KERNEL);
	if (!status) {
		retval = -ENOMEM;
		goto exit;
	}

	command = kcalloc(1, sizeof(char), GFP_KERNEL);
	if (!command) {
		retval = -ENOMEM;
		goto exit;
	}

	retval = synaptics_rmi4_reg_read(rmi4_data,
			fwu->f34_fd.data_base_addr + fwu->off.flash_status,
			&status,
			sizeof(status));
			status,
			sizeof(*status));
	if (retval < 0) {
		dev_err(rmi4_data->pdev->dev.parent,
				"%s: Failed to read flash status\n",
				__func__);
		return retval;
		goto exit;
	}

	fwu->in_bl_mode = status >> 7;
	fwu->in_bl_mode = *status >> 7;

	if (fwu->bl_version == BL_V5)
		fwu->flash_status = (status >> 4) & MASK_3BIT;
		fwu->flash_status = (*status >> 4) & MASK_3BIT;
	else if (fwu->bl_version == BL_V6)
		fwu->flash_status = status & MASK_3BIT;
		fwu->flash_status = *status & MASK_3BIT;
	else if (fwu->bl_version == BL_V7 || fwu->bl_version == BL_V8)
		fwu->flash_status = status & MASK_5BIT;
		fwu->flash_status = *status & MASK_5BIT;

	if (fwu->write_bootloader)
		fwu->flash_status = 0x00;
@@ -1429,26 +1441,28 @@ static int fwu_read_flash_status(void)

	retval = synaptics_rmi4_reg_read(rmi4_data,
			fwu->f34_fd.data_base_addr + fwu->off.flash_cmd,
			&command,
			sizeof(command));
			command,
			sizeof(*command));
	if (retval < 0) {
		dev_err(rmi4_data->pdev->dev.parent,
				"%s: Failed to read flash command\n",
				__func__);
		return retval;
		goto exit;
	}

	if (fwu->bl_version == BL_V5)
		fwu->command = command & MASK_4BIT;
		fwu->command = *command & MASK_4BIT;
	else if (fwu->bl_version == BL_V6)
		fwu->command = command & MASK_6BIT;
		fwu->command = *command & MASK_6BIT;
	else if (fwu->bl_version == BL_V7 || fwu->bl_version == BL_V8)
		fwu->command = command;
		fwu->command = *command;

	if (fwu->write_bootloader)
		fwu->command = 0x00;

	return 0;
exit:
	kfree(status);
	kfree(command);
	return retval;
}

static int fwu_wait_for_idle(int timeout_ms, bool poll)
@@ -2062,10 +2076,22 @@ static int fwu_read_f34_v5v6_queries(void)
	unsigned char count;
	unsigned char base;
	unsigned char offset;
	unsigned char buf[10];
	struct f34_v5v6_flash_properties_2 properties_2;
	unsigned char *buf = NULL;
	struct f34_v5v6_flash_properties_2 *properties_2 = NULL;
	struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;

	buf = kcalloc(10, sizeof(char), GFP_KERNEL);
	if (!buf) {
		retval = -ENOMEM;
		goto exit;
	}

	properties_2 = kzalloc(sizeof(*properties_2), GFP_KERNEL);
	if (!properties_2) {
		retval = -ENOMEM;
		goto exit;
	}

	base = fwu->f34_fd.query_base_addr;

	retval = synaptics_rmi4_reg_read(rmi4_data,
@@ -2076,7 +2102,7 @@ static int fwu_read_f34_v5v6_queries(void)
		dev_err(rmi4_data->pdev->dev.parent,
				"%s: Failed to read bootloader ID\n",
				__func__);
		return retval;
		goto exit;
	}

	if (fwu->bl_version == BL_V5) {
@@ -2103,7 +2129,7 @@ static int fwu_read_f34_v5v6_queries(void)
		dev_err(rmi4_data->pdev->dev.parent,
				"%s: Failed to read block size info\n",
				__func__);
		return retval;
		goto exit;
	}

	batohs(&fwu->block_size, &(buf[0]));
@@ -2124,7 +2150,7 @@ static int fwu_read_f34_v5v6_queries(void)
		dev_err(rmi4_data->pdev->dev.parent,
				"%s: Failed to read flash properties\n",
				__func__);
		return retval;
		goto exit;
	}

	count = 4;
@@ -2146,7 +2172,7 @@ static int fwu_read_f34_v5v6_queries(void)
		dev_err(rmi4_data->pdev->dev.parent,
				"%s: Failed to read block count info\n",
				__func__);
		return retval;
		goto exit;
	}

	batohs(&fwu->blkcount.ui_firmware, &(buf[0]));
@@ -2178,17 +2204,17 @@ static int fwu_read_f34_v5v6_queries(void)
	if (fwu->flash_properties.has_query4) {
		retval = synaptics_rmi4_reg_read(rmi4_data,
				base + fwu->off.properties_2,
				properties_2.data,
				sizeof(properties_2.data));
				properties_2->data,
				sizeof(properties_2->data));
		if (retval < 0) {
			dev_err(rmi4_data->pdev->dev.parent,
					"%s: Failed to read flash properties 2\n",
					__func__);
			return retval;
			goto exit;
		}
		offset = fwu->off.properties_2 + 1;
		count = 0;
		if (properties_2.has_guest_code) {
		if (properties_2->has_guest_code) {
			retval = synaptics_rmi4_reg_read(rmi4_data,
					base + offset + count,
					buf,
@@ -2197,7 +2223,7 @@ static int fwu_read_f34_v5v6_queries(void)
				dev_err(rmi4_data->pdev->dev.parent,
						"%s: Failed to read guest code block count\n",
						__func__);
				return retval;
				goto exit;
			}

			batohs(&fwu->blkcount.guest_code, &(buf[0]));
@@ -2205,7 +2231,7 @@ static int fwu_read_f34_v5v6_queries(void)
			fwu->has_guest_code = true;
		}
#ifdef SYNA_TDDI
		if (properties_2.has_force_config) {
		if (properties_2->has_force_config) {
			retval = synaptics_rmi4_reg_read(rmi4_data,
					base + offset + count,
					buf,
@@ -2214,13 +2240,13 @@ static int fwu_read_f34_v5v6_queries(void)
				dev_err(rmi4_data->pdev->dev.parent,
					"%s: Failed to read tddi force block count\n",
					__func__);
				return retval;
				goto exit;
			}
			batohs(&fwu->blkcount.tddi_force_config, &(buf[0]));
			count++;
			fwu->has_force_config = true;
		}
		if (properties_2.has_lockdown_data) {
		if (properties_2->has_lockdown_data) {
			retval = synaptics_rmi4_reg_read(rmi4_data,
					base + offset + count,
					buf,
@@ -2229,13 +2255,13 @@ static int fwu_read_f34_v5v6_queries(void)
				dev_err(rmi4_data->pdev->dev.parent,
					"%s: Failed to read tddi lockdown block count\n",
					__func__);
				return retval;
				goto exit;
			}
			batohs(&fwu->blkcount.tddi_lockdown_data, &(buf[0]));
			count++;
			fwu->has_lockdown_data = true;
		}
		if (properties_2.has_lcm_data) {
		if (properties_2->has_lcm_data) {
			retval = synaptics_rmi4_reg_read(rmi4_data,
					base + offset + count,
					buf,
@@ -2244,13 +2270,13 @@ static int fwu_read_f34_v5v6_queries(void)
				dev_err(rmi4_data->pdev->dev.parent,
					"%s: Failed to read tddi lcm block count\n",
					__func__);
				return retval;
				goto exit;
			}
			batohs(&fwu->blkcount.tddi_lcm_data, &(buf[0]));
			count++;
			fwu->has_lcm_data = true;
		}
		if (properties_2.has_oem_data) {
		if (properties_2->has_oem_data) {
			retval = synaptics_rmi4_reg_read(rmi4_data,
					base + offset + count,
					buf,
@@ -2259,7 +2285,7 @@ static int fwu_read_f34_v5v6_queries(void)
				dev_err(rmi4_data->pdev->dev.parent,
					"%s: Failed to read tddi oem block count\n",
					__func__);
				return retval;
				goto exit;
			}
			batohs(&fwu->blkcount.tddi_oem_data, &(buf[0]));
			fwu->has_oem_data = true;
@@ -2268,8 +2294,10 @@ static int fwu_read_f34_v5v6_queries(void)
	}

	fwu->has_utility_param = false;

	return 0;
exit:
	kfree(properties_2);
	kfree(buf);
	return retval;
}

static int fwu_read_f34_queries(void)
@@ -2790,7 +2818,6 @@ static int fwu_scan_pdt(void)
	bool f01found = false;
	bool f34found = false;
	bool f35found = false;
	struct synaptics_rmi4_fn_desc rmi_fd;
	struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;

	fwu->in_ub_mode = false;
@@ -2798,38 +2825,38 @@ static int fwu_scan_pdt(void)
	for (addr = PDT_START; addr > PDT_END; addr -= PDT_ENTRY_SIZE) {
		retval = synaptics_rmi4_reg_read(rmi4_data,
				addr,
				(unsigned char *)&rmi_fd,
				sizeof(rmi_fd));
				(unsigned char *)&rmi4_data->rmi_fd,
				sizeof(rmi4_data->rmi_fd));
		if (retval < 0)
			return retval;

		if (rmi_fd.fn_number) {
		if (rmi4_data->rmi_fd.fn_number) {
			dev_dbg(rmi4_data->pdev->dev.parent,
					"%s: Found F%02x\n",
					__func__, rmi_fd.fn_number);
			switch (rmi_fd.fn_number) {
					__func__, rmi4_data->rmi_fd.fn_number);
			switch (rmi4_data->rmi_fd.fn_number) {
			case SYNAPTICS_RMI4_F01:
				f01found = true;

				rmi4_data->f01_query_base_addr =
						rmi_fd.query_base_addr;
					rmi4_data->rmi_fd.query_base_addr;
				rmi4_data->f01_ctrl_base_addr =
						rmi_fd.ctrl_base_addr;
					rmi4_data->rmi_fd.ctrl_base_addr;
				rmi4_data->f01_data_base_addr =
						rmi_fd.data_base_addr;
					rmi4_data->rmi_fd.data_base_addr;
				rmi4_data->f01_cmd_base_addr =
						rmi_fd.cmd_base_addr;
					rmi4_data->rmi_fd.cmd_base_addr;
				break;
			case SYNAPTICS_RMI4_F34:
				f34found = true;
				fwu->f34_fd.query_base_addr =
						rmi_fd.query_base_addr;
					rmi4_data->rmi_fd.query_base_addr;
				fwu->f34_fd.ctrl_base_addr =
						rmi_fd.ctrl_base_addr;
					rmi4_data->rmi_fd.ctrl_base_addr;
				fwu->f34_fd.data_base_addr =
						rmi_fd.data_base_addr;
					rmi4_data->rmi_fd.data_base_addr;

				switch (rmi_fd.fn_version) {
				switch (rmi4_data->rmi_fd.fn_version) {
				case F34_V0:
					fwu->bl_version = BL_V5;
					break;
@@ -2847,7 +2874,7 @@ static int fwu_scan_pdt(void)
				}

				fwu->intr_mask = 0;
				intr_src = rmi_fd.intr_src_count;
				intr_src = rmi4_data->rmi_fd.intr_src_count;
				intr_off = intr_count % 8;
				for (ii = intr_off;
						ii < (intr_src + intr_off);
@@ -2858,20 +2885,20 @@ static int fwu_scan_pdt(void)
			case SYNAPTICS_RMI4_F35:
				f35found = true;
				fwu->f35_fd.query_base_addr =
						rmi_fd.query_base_addr;
					rmi4_data->rmi_fd.query_base_addr;
				fwu->f35_fd.ctrl_base_addr =
						rmi_fd.ctrl_base_addr;
					rmi4_data->rmi_fd.ctrl_base_addr;
				fwu->f35_fd.data_base_addr =
						rmi_fd.data_base_addr;
					rmi4_data->rmi_fd.data_base_addr;
				fwu->f35_fd.cmd_base_addr =
						rmi_fd.cmd_base_addr;
					rmi4_data->rmi_fd.cmd_base_addr;
				break;
			}
		} else {
			break;
		}

		intr_count += rmi_fd.intr_src_count;
		intr_count += rmi4_data->rmi_fd.intr_src_count;
	}

	if (!f01found || !f34found) {
@@ -5568,7 +5595,7 @@ static int synaptics_rmi4_fwu_init(struct synaptics_rmi4_data *rmi4_data)
{
	int retval;
	unsigned char attr_count;
	struct pdt_properties pdt_props;
	struct pdt_properties *pdt_props = NULL;

	if (fwu) {
		dev_dbg(rmi4_data->pdev->dev.parent,
@@ -5577,6 +5604,12 @@ static int synaptics_rmi4_fwu_init(struct synaptics_rmi4_data *rmi4_data)
		return 0;
	}

	pdt_props = kzalloc(sizeof(*pdt_props), GFP_KERNEL);
	if (!pdt_props) {
		retval = -ENOMEM;
		goto exit;
	}

	fwu = kzalloc(sizeof(*fwu), GFP_KERNEL);
	if (!fwu) {
		dev_err(rmi4_data->pdev->dev.parent,
@@ -5599,13 +5632,13 @@ static int synaptics_rmi4_fwu_init(struct synaptics_rmi4_data *rmi4_data)

	retval = synaptics_rmi4_reg_read(rmi4_data,
			PDT_PROPS,
			pdt_props.data,
			sizeof(pdt_props.data));
			pdt_props->data,
			sizeof(pdt_props->data));
	if (retval < 0) {
		dev_dbg(rmi4_data->pdev->dev.parent,
				"%s: Failed to read PDT properties, assuming 0x00\n",
				__func__);
	} else if (pdt_props.has_bsr) {
	} else if (pdt_props->has_bsr) {
		dev_err(rmi4_data->pdev->dev.parent,
				"%s: Reflash for LTS not currently supported\n",
				__func__);
@@ -5697,6 +5730,7 @@ static int synaptics_rmi4_fwu_init(struct synaptics_rmi4_data *rmi4_data)
	fwu = NULL;

exit:
	kfree(pdt_props);
	return retval;
}

+19 −5

File changed.

Preview size limit exceeded, changes collapsed.

+32 −22

File changed.

Preview size limit exceeded, changes collapsed.