summaryrefslogtreecommitdiff
path: root/drivers/mfd/cros_ec.c
diff options
context:
space:
mode:
authorGwendal Grignou <gwendal@chromium.org>2015-06-09 14:04:47 +0300
committerLee Jones <lee.jones@linaro.org>2015-06-15 15:18:23 +0300
commit57b33ff077beebb68481a2b6b8e5fe58ca998169 (patch)
tree9ebb2bc1a6e413156f1409220c4328c72efbb1b9 /drivers/mfd/cros_ec.c
parentd365407079d33106f76bd486a863de05eb5ae95d (diff)
downloadlinux-57b33ff077beebb68481a2b6b8e5fe58ca998169.tar.xz
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/cros_ec.c')
-rw-r--r--drivers/mfd/cros_ec.c54
1 files changed, 46 insertions, 8 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) {