Re: [PATCH v3 3/7] mfd: cros_ec: Move protocol helpers out of the MFD driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, 22 May 2015, Javier Martinez Canillas wrote:

> The MFD driver should only have the logic to instantiate its child devices
> and setup any shared resources that will be used by the subdevices drivers.
> 
> The cros_ec MFD is more complex than expected since it also has helpers to
> communicate with the EC. So the driver will only get more bigger as other
> protocols are supported in the future. So move the communication protocol
> helpers to its own driver as drivers/platform/chrome/cros_ec_proto.c.
> 
> Suggested-by: Lee Jones <lee.jones@xxxxxxxxxx>
> Signed-off-by: Javier Martinez Canillas <javier.martinez@xxxxxxxxxxxxxxx>
> ---
> 
> Changes since v2: None, new patch.
> ---
>  drivers/i2c/busses/Kconfig              |   2 +-
>  drivers/input/keyboard/Kconfig          |   2 +-
>  drivers/mfd/Kconfig                     |   5 +-
>  drivers/mfd/cros_ec.c                   |  96 --------------------------

:)

Acked-by: Lee Jones <lee.jones@xxxxxxxxxx>

>  drivers/platform/chrome/Kconfig         |   9 ++-
>  drivers/platform/chrome/Makefile        |   1 +
>  drivers/platform/chrome/cros_ec_proto.c | 115 ++++++++++++++++++++++++++++++++
>  7 files changed, 128 insertions(+), 102 deletions(-)
>  create mode 100644 drivers/platform/chrome/cros_ec_proto.c
> 
> diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
> index 2255af23b9c7..5f1c1c4f5d87 100644
> --- a/drivers/i2c/busses/Kconfig
> +++ b/drivers/i2c/busses/Kconfig
> @@ -1103,7 +1103,7 @@ config I2C_SIBYTE
>  
>  config I2C_CROS_EC_TUNNEL
>  	tristate "ChromeOS EC tunnel I2C bus"
> -	depends on MFD_CROS_EC
> +	depends on CROS_EC_PROTO
>  	help
>  	  If you say yes here you get an I2C bus that will tunnel i2c commands
>  	  through to the other side of the ChromeOS EC to the i2c bus
> diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
> index 106fbac7f8c5..e8eb60c6d83e 100644
> --- a/drivers/input/keyboard/Kconfig
> +++ b/drivers/input/keyboard/Kconfig
> @@ -677,7 +677,7 @@ config KEYBOARD_W90P910
>  config KEYBOARD_CROS_EC
>  	tristate "ChromeOS EC keyboard"
>  	select INPUT_MATRIXKMAP
> -	depends on MFD_CROS_EC
> +	depends on CROS_EC_PROTO
>  	help
>  	  Say Y here to enable the matrix keyboard used by ChromeOS devices
>  	  and implemented on the ChromeOS EC. You must enable one bus option
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index d5ad04dad081..927ba61e5bf9 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -94,6 +94,7 @@ config MFD_AXP20X
>  config MFD_CROS_EC
>  	tristate "ChromeOS Embedded Controller"
>  	select MFD_CORE
> +	select CROS_EC_PROTO
>  	help
>  	  If you say Y here you get support for the ChromeOS Embedded
>  	  Controller (EC) providing keyboard, battery and power services.
> @@ -102,7 +103,7 @@ config MFD_CROS_EC
>  
>  config MFD_CROS_EC_I2C
>  	tristate "ChromeOS Embedded Controller (I2C)"
> -	depends on MFD_CROS_EC && I2C
> +	depends on MFD_CROS_EC && CROS_EC_PROTO && I2C
>  
>  	help
>  	  If you say Y here, you get support for talking to the ChromeOS
> @@ -112,7 +113,7 @@ config MFD_CROS_EC_I2C
>  
>  config MFD_CROS_EC_SPI
>  	tristate "ChromeOS Embedded Controller (SPI)"
> -	depends on MFD_CROS_EC && SPI && OF
> +	depends on MFD_CROS_EC && CROS_EC_PROTO && SPI && OF
>  
>  	---help---
>  	  If you say Y here, you get support for talking to the ChromeOS EC
> diff --git a/drivers/mfd/cros_ec.c b/drivers/mfd/cros_ec.c
> index 4a0f6dfcd376..d857f6a2b57b 100644
> --- a/drivers/mfd/cros_ec.c
> +++ b/drivers/mfd/cros_ec.c
> @@ -23,102 +23,6 @@
>  #include <linux/module.h>
>  #include <linux/mfd/core.h>
>  #include <linux/mfd/cros_ec.h>
> -#include <linux/mfd/cros_ec_commands.h>
> -#include <linux/delay.h>
> -
> -#define EC_COMMAND_RETRIES	50
> -
> -int cros_ec_prepare_tx(struct cros_ec_device *ec_dev,
> -		       struct cros_ec_command *msg)
> -{
> -	uint8_t *out;
> -	int csum, i;
> -
> -	BUG_ON(msg->outsize > EC_PROTO2_MAX_PARAM_SIZE);
> -	out = ec_dev->dout;
> -	out[0] = EC_CMD_VERSION0 + msg->version;
> -	out[1] = msg->command;
> -	out[2] = msg->outsize;
> -	csum = out[0] + out[1] + out[2];
> -	for (i = 0; i < msg->outsize; i++)
> -		csum += out[EC_MSG_TX_HEADER_BYTES + i] = msg->data[i];
> -	out[EC_MSG_TX_HEADER_BYTES + msg->outsize] = (uint8_t)(csum & 0xff);
> -
> -	return EC_MSG_TX_PROTO_BYTES + msg->outsize;
> -}
> -EXPORT_SYMBOL(cros_ec_prepare_tx);
> -
> -int cros_ec_check_result(struct cros_ec_device *ec_dev,
> -			 struct cros_ec_command *msg)
> -{
> -	switch (msg->result) {
> -	case EC_RES_SUCCESS:
> -		return 0;
> -	case EC_RES_IN_PROGRESS:
> -		dev_dbg(ec_dev->dev, "command 0x%02x in progress\n",
> -			msg->command);
> -		return -EAGAIN;
> -	default:
> -		dev_dbg(ec_dev->dev, "command 0x%02x returned %d\n",
> -			msg->command, msg->result);
> -		return 0;
> -	}
> -}
> -EXPORT_SYMBOL(cros_ec_check_result);
> -
> -int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev,
> -		     struct cros_ec_command *msg)
> -{
> -	int ret;
> -
> -	mutex_lock(&ec_dev->lock);
> -	ret = ec_dev->cmd_xfer(ec_dev, msg);
> -	if (msg->result == EC_RES_IN_PROGRESS) {
> -		int i;
> -		struct cros_ec_command *status_msg;
> -		struct ec_response_get_comms_status *status;
> -
> -		status_msg = kmalloc(sizeof(*status_msg) + sizeof(*status),
> -				     GFP_KERNEL);
> -		if (!status_msg) {
> -			ret = -ENOMEM;
> -			goto exit;
> -		}
> -
> -		status_msg->version = 0;
> -		status_msg->command = EC_CMD_GET_COMMS_STATUS;
> -		status_msg->insize = sizeof(*status);
> -		status_msg->outsize = 0;
> -
> -		/*
> -		 * Query the EC's status until it's no longer busy or
> -		 * we encounter an error.
> -		 */
> -		for (i = 0; i < EC_COMMAND_RETRIES; i++) {
> -			usleep_range(10000, 11000);
> -
> -			ret = ec_dev->cmd_xfer(ec_dev, status_msg);
> -			if (ret < 0)
> -				break;
> -
> -			msg->result = status_msg->result;
> -			if (status_msg->result != EC_RES_SUCCESS)
> -				break;
> -
> -			status = (struct ec_response_get_comms_status *)
> -				 status_msg->data;
> -			if (!(status->flags & EC_COMMS_STATUS_PROCESSING))
> -				break;
> -		}
> -
> -		kfree(status_msg);
> -	}
> -exit:
> -	mutex_unlock(&ec_dev->lock);
> -
> -	return ret;
> -}
> -EXPORT_SYMBOL(cros_ec_cmd_xfer);
>  
>  static const struct mfd_cell cros_devs[] = {
>  	{
> diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig
> index 2a6531a5fde8..cb1329919527 100644
> --- a/drivers/platform/chrome/Kconfig
> +++ b/drivers/platform/chrome/Kconfig
> @@ -40,7 +40,7 @@ config CHROMEOS_PSTORE
>  
>  config CROS_EC_CHARDEV
>          tristate "Chrome OS Embedded Controller userspace device interface"
> -        depends on MFD_CROS_EC
> +        depends on CROS_EC_PROTO
>          ---help---
>            This driver adds support to talk with the ChromeOS EC from userspace.
>  
> @@ -49,7 +49,7 @@ config CROS_EC_CHARDEV
>  
>  config CROS_EC_LPC
>          tristate "ChromeOS Embedded Controller (LPC)"
> -        depends on MFD_CROS_EC && (X86 || COMPILE_TEST)
> +        depends on MFD_CROS_EC && CROS_EC_PROTO && (X86 || COMPILE_TEST)
>          help
>            If you say Y here, you get support for talking to the ChromeOS EC
>            over an LPC bus. This uses a simple byte-level protocol with a
> @@ -59,4 +59,9 @@ config CROS_EC_LPC
>            To compile this driver as a module, choose M here: the
>            module will be called cros_ec_lpc.
>  
> +config CROS_EC_PROTO
> +        bool
> +        help
> +          ChromeOS EC communication protocol helpers.
> +
>  endif # CHROMEOS_PLATFORMS
> diff --git a/drivers/platform/chrome/Makefile b/drivers/platform/chrome/Makefile
> index bd8d8601e875..4a11b010f5d8 100644
> --- a/drivers/platform/chrome/Makefile
> +++ b/drivers/platform/chrome/Makefile
> @@ -4,3 +4,4 @@ obj-$(CONFIG_CHROMEOS_PSTORE)	+= chromeos_pstore.o
>  cros_ec_devs-objs               := cros_ec_dev.o cros_ec_sysfs.o cros_ec_lightbar.o
>  obj-$(CONFIG_CROS_EC_CHARDEV)   += cros_ec_devs.o
>  obj-$(CONFIG_CROS_EC_LPC)       += cros_ec_lpc.o
> +obj-$(CONFIG_CROS_EC_PROTO)	+= cros_ec_proto.o
> diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c
> new file mode 100644
> index 000000000000..58e98a24fd08
> --- /dev/null
> +++ b/drivers/platform/chrome/cros_ec_proto.c
> @@ -0,0 +1,115 @@
> +/*
> + * ChromeOS EC communication protocol helper functions
> + *
> + * Copyright (C) 2015 Google, Inc
> + *
> + * This software is licensed under the terms of the GNU General Public
> + * License version 2, as published by the Free Software Foundation, and
> + * may be copied, distributed, and modified under those terms.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +#include <linux/mfd/cros_ec.h>
> +#include <linux/delay.h>
> +#include <linux/device.h>
> +#include <linux/module.h>
> +#include <linux/slab.h>
> +
> +#define EC_COMMAND_RETRIES	50
> +
> +int cros_ec_prepare_tx(struct cros_ec_device *ec_dev,
> +		       struct cros_ec_command *msg)
> +{
> +	uint8_t *out;
> +	int csum, i;
> +
> +	BUG_ON(msg->outsize > EC_PROTO2_MAX_PARAM_SIZE);
> +	out = ec_dev->dout;
> +	out[0] = EC_CMD_VERSION0 + msg->version;
> +	out[1] = msg->command;
> +	out[2] = msg->outsize;
> +	csum = out[0] + out[1] + out[2];
> +	for (i = 0; i < msg->outsize; i++)
> +		csum += out[EC_MSG_TX_HEADER_BYTES + i] = msg->data[i];
> +	out[EC_MSG_TX_HEADER_BYTES + msg->outsize] = (uint8_t)(csum & 0xff);
> +
> +	return EC_MSG_TX_PROTO_BYTES + msg->outsize;
> +}
> +EXPORT_SYMBOL(cros_ec_prepare_tx);
> +
> +int cros_ec_check_result(struct cros_ec_device *ec_dev,
> +			 struct cros_ec_command *msg)
> +{
> +	switch (msg->result) {
> +	case EC_RES_SUCCESS:
> +		return 0;
> +	case EC_RES_IN_PROGRESS:
> +		dev_dbg(ec_dev->dev, "command 0x%02x in progress\n",
> +			msg->command);
> +		return -EAGAIN;
> +	default:
> +		dev_dbg(ec_dev->dev, "command 0x%02x returned %d\n",
> +			msg->command, msg->result);
> +		return 0;
> +	}
> +}
> +EXPORT_SYMBOL(cros_ec_check_result);
> +
> +int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev,
> +		     struct cros_ec_command *msg)
> +{
> +	int ret;
> +
> +	mutex_lock(&ec_dev->lock);
> +	ret = ec_dev->cmd_xfer(ec_dev, msg);
> +	if (msg->result == EC_RES_IN_PROGRESS) {
> +		int i;
> +		struct cros_ec_command *status_msg;
> +		struct ec_response_get_comms_status *status;
> +
> +		status_msg = kmalloc(sizeof(*status_msg) + sizeof(*status),
> +				     GFP_KERNEL);
> +		if (!status_msg) {
> +			ret = -ENOMEM;
> +			goto exit;
> +		}
> +
> +		status_msg->version = 0;
> +		status_msg->command = EC_CMD_GET_COMMS_STATUS;
> +		status_msg->insize = sizeof(*status);
> +		status_msg->outsize = 0;
> +
> +		/*
> +		 * Query the EC's status until it's no longer busy or
> +		 * we encounter an error.
> +		 */
> +		for (i = 0; i < EC_COMMAND_RETRIES; i++) {
> +			usleep_range(10000, 11000);
> +
> +			ret = ec_dev->cmd_xfer(ec_dev, status_msg);
> +			if (ret < 0)
> +				break;
> +
> +			msg->result = status_msg->result;
> +			if (status_msg->result != EC_RES_SUCCESS)
> +				break;
> +
> +			status = (struct ec_response_get_comms_status *)
> +				 status_msg->data;
> +			if (!(status->flags & EC_COMMS_STATUS_PROCESSING))
> +				break;
> +		}
> +
> +		kfree(status_msg);
> +	}
> +exit:
> +	mutex_unlock(&ec_dev->lock);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL(cros_ec_cmd_xfer);

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
--
To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux SoC Development]     [Linux Rockchip Development]     [Linux USB Development]     [Video for Linux]     [Linux Audio Users]     [Linux SCSI]     [Yosemite News]

  Powered by Linux