summaryrefslogtreecommitdiffstats
path: root/drivers/platform
diff options
context:
space:
mode:
authorEnric Balletbo i Serra <enric.balletbo@collabora.com>2019-09-02 11:53:00 +0200
committerLee Jones <lee.jones@linaro.org>2019-09-02 12:32:57 +0200
commit7aa703bb8824384baad732043a925b46a4f3efa8 (patch)
treef20c98444eb7ad23266bdc603e7c4cf6793bcccf /drivers/platform
parentLinus 5.3-rc1 (diff)
downloadlinux-7aa703bb8824384baad732043a925b46a4f3efa8.tar.xz
linux-7aa703bb8824384baad732043a925b46a4f3efa8.zip
mfd / platform: cros_ec: Handle chained ECs as platform devices
An MFD is a device that contains several sub-devices (cells). For instance, the ChromeOS EC fits in this description as usually contains a charger and can have other devices with different functions like a Real-Time Clock, an Audio codec, a Real-Time Clock, ... If you look at the driver, though, we're doing something odd. We have two MFD cros-ec drivers where one of them (cros-ec-core) instantiates another MFD driver as sub-driver (cros-ec-dev), and the latest instantiates the different sub-devices (Real-Time Clock, Audio codec, etc). MFD ------------------------------------------ cros-ec-core |___ mfd-cellA (cros-ec-dev) | |__ mfd-cell0 | |__ mfd-cell1 | |__ ... | |___ mfd-cellB (cros-ec-dev) |__ mfd-cell0 |__ mfd-cell1 |__ ... The problem that was trying to solve is to describe some kind of topology for the case where we have an EC (cros-ec) chained with another EC (cros-pd). Apart from that this extends the bounds of what MFD was designed to do we might be interested on have other kinds of topology that can't be implemented in that way. Let's prepare the code to move the cros-ec-core part from MFD to platform/chrome as this is clearly a platform specific thing non-related to a MFD device. platform/chrome | MFD ------------------------------------------ | cros-ec ________|___ cros-ec-dev | |__ mfd-cell0 | |__ mfd-cell1 | |__ ... | cros-pd ________|___ cros-ec-dev | |__ mfd-cell0 | |__ mfd-cell1 | |__ ... Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com> Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Reviewed-by: Gwendal Grignou <gwendal@chromium.org> Tested-by: Gwendal Grignou <gwendal@chromium.org> Signed-off-by: Lee Jones <lee.jones@linaro.org>
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/chrome/cros_ec_i2c.c8
-rw-r--r--drivers/platform/chrome/cros_ec_lpc.c3
-rw-r--r--drivers/platform/chrome/cros_ec_rpmsg.c2
-rw-r--r--drivers/platform/chrome/cros_ec_spi.c8
4 files changed, 20 insertions, 1 deletions
diff --git a/drivers/platform/chrome/cros_ec_i2c.c b/drivers/platform/chrome/cros_ec_i2c.c
index 61d75395f86d..6bb82dfa7dae 100644
--- a/drivers/platform/chrome/cros_ec_i2c.c
+++ b/drivers/platform/chrome/cros_ec_i2c.c
@@ -307,6 +307,13 @@ static int cros_ec_i2c_probe(struct i2c_client *client,
return 0;
}
+static int cros_ec_i2c_remove(struct i2c_client *client)
+{
+ struct cros_ec_device *ec_dev = i2c_get_clientdata(client);
+
+ return cros_ec_unregister(ec_dev);
+}
+
#ifdef CONFIG_PM_SLEEP
static int cros_ec_i2c_suspend(struct device *dev)
{
@@ -357,6 +364,7 @@ static struct i2c_driver cros_ec_driver = {
.pm = &cros_ec_i2c_pm_ops,
},
.probe = cros_ec_i2c_probe,
+ .remove = cros_ec_i2c_remove,
.id_table = cros_ec_i2c_id,
};
diff --git a/drivers/platform/chrome/cros_ec_lpc.c b/drivers/platform/chrome/cros_ec_lpc.c
index 2c44c7f3322a..5939c4a5869c 100644
--- a/drivers/platform/chrome/cros_ec_lpc.c
+++ b/drivers/platform/chrome/cros_ec_lpc.c
@@ -421,6 +421,7 @@ static int cros_ec_lpc_probe(struct platform_device *pdev)
static int cros_ec_lpc_remove(struct platform_device *pdev)
{
+ struct cros_ec_device *ec_dev = platform_get_drvdata(pdev);
struct acpi_device *adev;
adev = ACPI_COMPANION(&pdev->dev);
@@ -428,7 +429,7 @@ static int cros_ec_lpc_remove(struct platform_device *pdev)
acpi_remove_notify_handler(adev->handle, ACPI_ALL_NOTIFY,
cros_ec_lpc_acpi_notify);
- return 0;
+ return cros_ec_unregister(ec_dev);
}
static const struct acpi_device_id cros_ec_lpc_acpi_device_ids[] = {
diff --git a/drivers/platform/chrome/cros_ec_rpmsg.c b/drivers/platform/chrome/cros_ec_rpmsg.c
index 5d3fb2abad1d..520e507bfa54 100644
--- a/drivers/platform/chrome/cros_ec_rpmsg.c
+++ b/drivers/platform/chrome/cros_ec_rpmsg.c
@@ -233,6 +233,8 @@ static void cros_ec_rpmsg_remove(struct rpmsg_device *rpdev)
struct cros_ec_device *ec_dev = dev_get_drvdata(&rpdev->dev);
struct cros_ec_rpmsg *ec_rpmsg = ec_dev->priv;
+ cros_ec_unregister(ec_dev);
+
cancel_work_sync(&ec_rpmsg->host_event_work);
}
diff --git a/drivers/platform/chrome/cros_ec_spi.c b/drivers/platform/chrome/cros_ec_spi.c
index 006a8ff64057..2e21f2776063 100644
--- a/drivers/platform/chrome/cros_ec_spi.c
+++ b/drivers/platform/chrome/cros_ec_spi.c
@@ -785,6 +785,13 @@ static int cros_ec_spi_probe(struct spi_device *spi)
return 0;
}
+static int cros_ec_spi_remove(struct spi_device *spi)
+{
+ struct cros_ec_device *ec_dev = spi_get_drvdata(spi);
+
+ return cros_ec_unregister(ec_dev);
+}
+
#ifdef CONFIG_PM_SLEEP
static int cros_ec_spi_suspend(struct device *dev)
{
@@ -823,6 +830,7 @@ static struct spi_driver cros_ec_driver_spi = {
.pm = &cros_ec_spi_pm_ops,
},
.probe = cros_ec_spi_probe,
+ .remove = cros_ec_spi_remove,
.id_table = cros_ec_spi_id,
};