From 57b33ff077beebb68481a2b6b8e5fe58ca998169 Mon Sep 17 00:00:00 2001 From: Gwendal Grignou Date: Tue, 9 Jun 2015 13:04:47 +0200 Subject: 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 Reviewed-by: Dmitry Torokhov Signed-off-by: Javier Martinez Canillas Tested-by: Heiko Stuebner Acked-by: Lee Jones Acked-by: Olof Johansson Signed-off-by: Lee Jones --- drivers/mfd/cros_ec.c | 54 +++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 8 deletions(-) (limited to 'drivers/mfd/cros_ec.c') 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 #include -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) { -- cgit v1.2.3