diff options
author | Gwendal Grignou <gwendal@chromium.org> | 2015-06-09 13:04:47 +0200 |
---|---|---|
committer | Lee Jones <lee.jones@linaro.org> | 2015-06-15 13:18:23 +0100 |
commit | 57b33ff077beebb68481a2b6b8e5fe58ca998169 (patch) | |
tree | 9ebb2bc1a6e413156f1409220c4328c72efbb1b9 /drivers/mfd | |
parent | d365407079d33106f76bd486a863de05eb5ae95d (diff) | |
download | linux-57b33ff077beebb68481a2b6b8e5fe58ca998169.tar.bz2 |
mfd: cros_ec: Support multiple EC in a system
Chromebooks can have more than one Embedded Controller so the
cros_ec device id has to be incremented for each EC registered.
Add a new structure to represent multiple EC as different char
devices (e.g: /dev/cros_ec, /dev/cros_pd). It connects to
cros_ec_device and allows sysfs inferface for cros_pd.
Also reduce number of allocated objects, make chromeos sysfs
class object a static and add refcounting to prevent object
deletion while command is in progress.
Signed-off-by: Gwendal Grignou <gwendal@chromium.org>
Reviewed-by: Dmitry Torokhov <dtor@chromium.org>
Signed-off-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Acked-by: Lee Jones <lee.jones@linaro.org>
Acked-by: Olof Johansson <olof@lixom.net>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Diffstat (limited to 'drivers/mfd')
-rw-r--r-- | drivers/mfd/cros_ec.c | 54 | ||||
-rw-r--r-- | drivers/mfd/cros_ec_i2c.c | 1 | ||||
-rw-r--r-- | drivers/mfd/cros_ec_spi.c | 1 |
3 files changed, 46 insertions, 10 deletions
diff --git a/drivers/mfd/cros_ec.c b/drivers/mfd/cros_ec.c index 08d82bfc5268..11b1884bce62 100644 --- a/drivers/mfd/cros_ec.c +++ b/drivers/mfd/cros_ec.c @@ -24,11 +24,29 @@ #include <linux/mfd/core.h> #include <linux/mfd/cros_ec.h> -static const struct mfd_cell cros_devs[] = { - { - .name = "cros-ec-ctl", - .id = PLATFORM_DEVID_AUTO, - }, +#define CROS_EC_DEV_EC_INDEX 0 +#define CROS_EC_DEV_PD_INDEX 1 + +struct cros_ec_platform ec_p = { + .ec_name = CROS_EC_DEV_NAME, + .cmd_offset = EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_EC_INDEX), +}; + +struct cros_ec_platform pd_p = { + .ec_name = CROS_EC_DEV_PD_NAME, + .cmd_offset = EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX), +}; + +struct mfd_cell ec_cell = { + .name = "cros-ec-ctl", + .platform_data = &ec_p, + .pdata_size = sizeof(ec_p), +}; + +struct mfd_cell ec_pd_cell = { + .name = "cros-ec-ctl", + .platform_data = &pd_p, + .pdata_size = sizeof(pd_p), }; int cros_ec_register(struct cros_ec_device *ec_dev) @@ -52,14 +70,34 @@ int cros_ec_register(struct cros_ec_device *ec_dev) cros_ec_query_all(ec_dev); - err = mfd_add_devices(dev, 0, cros_devs, - ARRAY_SIZE(cros_devs), + err = mfd_add_devices(ec_dev->dev, PLATFORM_DEVID_AUTO, &ec_cell, 1, NULL, ec_dev->irq, NULL); if (err) { - dev_err(dev, "failed to add mfd devices\n"); + dev_err(dev, + "Failed to register Embedded Controller subdevice %d\n", + err); return err; } + if (ec_dev->max_passthru) { + /* + * Register a PD device as well on top of this device. + * We make the following assumptions: + * - behind an EC, we have a pd + * - only one device added. + * - the EC is responsive at init time (it is not true for a + * sensor hub. + */ + err = mfd_add_devices(ec_dev->dev, PLATFORM_DEVID_AUTO, + &ec_pd_cell, 1, NULL, ec_dev->irq, NULL); + if (err) { + dev_err(dev, + "Failed to register Power Delivery subdevice %d\n", + err); + return err; + } + } + if (IS_ENABLED(CONFIG_OF) && dev->of_node) { err = of_platform_populate(dev->of_node, NULL, NULL, dev); if (err) { diff --git a/drivers/mfd/cros_ec_i2c.c b/drivers/mfd/cros_ec_i2c.c index 22e8a4ae1711..b9a0963ca5c3 100644 --- a/drivers/mfd/cros_ec_i2c.c +++ b/drivers/mfd/cros_ec_i2c.c @@ -302,7 +302,6 @@ static int cros_ec_i2c_probe(struct i2c_client *client, ec_dev->irq = client->irq; ec_dev->cmd_xfer = cros_ec_cmd_xfer_i2c; ec_dev->pkt_xfer = cros_ec_pkt_xfer_i2c; - ec_dev->ec_name = client->name; ec_dev->phys_name = client->adapter->name; ec_dev->din_size = sizeof(struct ec_host_response_i2c) + sizeof(struct ec_response_get_protocol_info); diff --git a/drivers/mfd/cros_ec_spi.c b/drivers/mfd/cros_ec_spi.c index 4e6f2f6b1095..faba03e2f1ef 100644 --- a/drivers/mfd/cros_ec_spi.c +++ b/drivers/mfd/cros_ec_spi.c @@ -637,7 +637,6 @@ static int cros_ec_spi_probe(struct spi_device *spi) ec_dev->irq = spi->irq; ec_dev->cmd_xfer = cros_ec_cmd_xfer_spi; ec_dev->pkt_xfer = cros_ec_pkt_xfer_spi; - ec_dev->ec_name = ec_spi->spi->modalias; ec_dev->phys_name = dev_name(&ec_spi->spi->dev); ec_dev->din_size = EC_MSG_PREAMBLE_COUNT + sizeof(struct ec_host_response) + |