On Tue, Jun 4, 2019 at 8:20 AM Enric Balletbo i Serra <[email protected]> wrote: > > The CrOS EC is gaining lots of subdevices that are autodetectable by > sending the EC_FEATURE_GET_CMD, it takes fair amount of boiler plate > code to add those devices. So, add a struct that can be used to quickly > add new subdevices without having to duplicate code. > > Signed-off-by: Enric Balletbo i Serra <[email protected]> > --- > > drivers/mfd/cros_ec_dev.c | 132 +++++++++++++++++++++----------------- > 1 file changed, 74 insertions(+), 58 deletions(-) > > diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c > index 6fcfc8f17e03..49e4ab7ebb71 100644 > --- a/drivers/mfd/cros_ec_dev.c > +++ b/drivers/mfd/cros_ec_dev.c > @@ -34,6 +34,18 @@ struct cros_feature_to_name { > const char *desc; > }; > > +/** > + * cros_feature_to_cells - CrOS feature id to mfd cells association. > + * @id: The feature identifier. > + * @mfd_cells: Pointer to the array of mfd cells that needs to be added. > + * @num_cells: Number of mfd cells into the array. > + */ > +struct cros_feature_to_cells { > + unsigned int id; > + const struct mfd_cell *mfd_cells; > + unsigned int num_cells; > +}; > + > static const struct cros_feature_to_name cros_mcu_devices[] = { > { > .id = EC_FEATURE_FINGERPRINT, > @@ -52,6 +64,48 @@ static const struct cros_feature_to_name > cros_mcu_devices[] = { > }, > }; > > +static const struct mfd_cell cros_ec_cec_cells[] = { > + { .name = "cros-ec-cec", }, > +}; > + > +static const struct mfd_cell cros_ec_rtc_cells[] = { > + { .name = "cros-ec-rtc", }, > +}; > + > +static const struct mfd_cell cros_usbpd_charger_cells[] = { > + { .name = "cros-usbpd-charger", }, > + { .name = "cros-usbpd-logger", }, > +}; > + > +static const struct cros_feature_to_cells cros_subdevices[] = { > + { > + .id = EC_FEATURE_CEC, > + .mfd_cells = cros_ec_cec_cells, > + .num_cells = ARRAY_SIZE(cros_ec_cec_cells), > + }, > + { > + .id = EC_FEATURE_RTC, > + .mfd_cells = cros_ec_rtc_cells, > + .num_cells = ARRAY_SIZE(cros_ec_rtc_cells), > + }, > + { > + .id = EC_FEATURE_USB_PD, > + .mfd_cells = cros_usbpd_charger_cells, > + .num_cells = ARRAY_SIZE(cros_usbpd_charger_cells), > + }, > +}; > + > +static const struct mfd_cell cros_ec_platform_cells[] = { > + { .name = "cros-ec-chardev", }, > + { .name = "cros-ec-debugfs", }, > + { .name = "cros-ec-lightbar", }, > + { .name = "cros-ec-sysfs", }, > +}; > + > +static const struct mfd_cell cros_ec_vbc_cells[] = { > + { .name = "cros-ec-vbc", } > +}; > + > static int cros_ec_check_features(struct cros_ec_dev *ec, int feature) > { > struct cros_ec_command *msg; > @@ -211,30 +265,6 @@ static void cros_ec_sensors_register(struct cros_ec_dev > *ec) > kfree(msg); > } > > -static const struct mfd_cell cros_ec_cec_cells[] = { > - { .name = "cros-ec-cec" } > -}; > - > -static const struct mfd_cell cros_ec_rtc_cells[] = { > - { .name = "cros-ec-rtc" } > -}; > - > -static const struct mfd_cell cros_usbpd_charger_cells[] = { > - { .name = "cros-usbpd-charger" }, > - { .name = "cros-usbpd-logger" }, > -}; > - > -static const struct mfd_cell cros_ec_platform_cells[] = { > - { .name = "cros-ec-chardev" }, > - { .name = "cros-ec-debugfs" }, > - { .name = "cros-ec-lightbar" }, > - { .name = "cros-ec-sysfs" }, > -}; > - > -static const struct mfd_cell cros_ec_vbc_cells[] = { > - { .name = "cros-ec-vbc" } > -}; > - > static int ec_device_probe(struct platform_device *pdev) > { > int retval = -ENOMEM; > @@ -292,42 +322,28 @@ static int ec_device_probe(struct platform_device *pdev) > if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE)) > cros_ec_sensors_register(ec); > > - /* Check whether this EC instance has CEC host command support */ > - if (cros_ec_check_features(ec, EC_FEATURE_CEC)) { > - retval = mfd_add_devices(ec->dev, PLATFORM_DEVID_AUTO, > - cros_ec_cec_cells, > - ARRAY_SIZE(cros_ec_cec_cells), > - NULL, 0, NULL); > - if (retval) > - dev_err(ec->dev, > - "failed to add cros-ec-cec device: %d\n", > - retval); > - } > - > - /* Check whether this EC instance has RTC host command support */ > - if (cros_ec_check_features(ec, EC_FEATURE_RTC)) { > - retval = mfd_add_devices(ec->dev, PLATFORM_DEVID_AUTO, > - cros_ec_rtc_cells, > - ARRAY_SIZE(cros_ec_rtc_cells), > - NULL, 0, NULL); > - if (retval) > - dev_err(ec->dev, > - "failed to add cros-ec-rtc device: %d\n", > - retval); > - } > - > - /* Check whether this EC instance has the PD charge manager */ > - if (cros_ec_check_features(ec, EC_FEATURE_USB_PD)) { > - retval = mfd_add_devices(ec->dev, PLATFORM_DEVID_AUTO, > - cros_usbpd_charger_cells, > - ARRAY_SIZE(cros_usbpd_charger_cells), > - NULL, 0, NULL); > - if (retval) > - dev_err(ec->dev, > - "failed to add cros-usbpd-charger device: > %d\n", > - retval); > + /* > + * The following subdevices can be detected by sending the > + * EC_FEATURE_GET_CMD Embedded Controller device. > + */ > + for (i = 0; i < ARRAY_SIZE(cros_subdevices); i++) { > + if (cros_ec_check_features(ec, cros_subdevices[i].id)) { > + retval = mfd_add_devices(ec->dev, PLATFORM_DEVID_AUTO, > + cros_subdevices[i].mfd_cells, > + cros_subdevices[i].num_cells, > + NULL, 0, NULL); Nit: you can replace mfd_add_devices() call by mfd_add_hotplug_devices(). > + if (retval) > + dev_err(ec->dev, > + "failed to add %s subdevice: %d\n", > + cros_subdevices[i].mfd_cells->name, > + retval); > + } > } > > + /* > + * The following subdevices cannot be detected by sending the > + * EC_FEATURE_GET_CMD to the Embedded Controller device. > + */ > retval = mfd_add_devices(ec->dev, PLATFORM_DEVID_AUTO, > cros_ec_platform_cells, > ARRAY_SIZE(cros_ec_platform_cells), > -- > 2.20.1 >

