To allow instantiating subdevices such as the regulator and poweroff
devices that do not have corresponding device tree nodes with a
"compatible" property, use devm_mfd_add_devices() with MFD cells instead
of devm_of_platform_populate(). Since different PMICs in the SC27xx
series contain different components, use separate MFD cell tables for
each PMIC model. Define cells for all components that have upstream
drivers at this point.
Signed-off-by: Otto Pflüger <otto.pflueger@abscue.de>
---
drivers/mfd/sprd-sc27xx-spi.c | 62 ++++++++++++++++++++++++++++++++++++-------
1 file changed, 53 insertions(+), 9 deletions(-)
diff --git a/drivers/mfd/sprd-sc27xx-spi.c b/drivers/mfd/sprd-sc27xx-spi.c
index d6b4350779e6..eb57023fdc3c 100644
--- a/drivers/mfd/sprd-sc27xx-spi.c
+++ b/drivers/mfd/sprd-sc27xx-spi.c
@@ -14,6 +14,11 @@
#include <linux/spi/spi.h>
#include <uapi/linux/usb/charger.h>
+enum sprd_pmic_type {
+ PMIC_TYPE_SC2730,
+ PMIC_TYPE_SC2731,
+};
+
#define SPRD_PMIC_INT_MASK_STATUS 0x0
#define SPRD_PMIC_INT_RAW_STATUS 0x4
#define SPRD_PMIC_INT_EN 0x8
@@ -50,6 +55,29 @@ struct sprd_pmic_data {
u32 charger_det;
};
+static const struct mfd_cell sc2730_devices[] = {
+ MFD_CELL_OF("sc2730-adc", NULL, NULL, 0, 0, "sprd,sc2730-adc"),
+ MFD_CELL_OF("sc2730-bltc", NULL, NULL, 0, 0, "sprd,sc2730-bltc"),
+ MFD_CELL_OF("sc2730-efuse", NULL, NULL, 0, 0, "sprd,sc2730-efuse"),
+ MFD_CELL_OF("sc2730-eic", NULL, NULL, 0, 0, "sprd,sc2730-eic"),
+ MFD_CELL_OF("sc2730-fgu", NULL, NULL, 0, 0, "sprd,sc2730-fgu"),
+ MFD_CELL_OF("sc2730-rtc", NULL, NULL, 0, 0, "sprd,sc2730-rtc"),
+ MFD_CELL_OF("sc2730-vibrator", NULL, NULL, 0, 0, "sprd,sc2730-vibrator"),
+};
+
+static const struct mfd_cell sc2731_devices[] = {
+ MFD_CELL_OF("sc2731-adc", NULL, NULL, 0, 0, "sprd,sc2731-adc"),
+ MFD_CELL_OF("sc2731-bltc", NULL, NULL, 0, 0, "sprd,sc2731-bltc"),
+ MFD_CELL_OF("sc2731-charger", NULL, NULL, 0, 0, "sprd,sc2731-charger"),
+ MFD_CELL_OF("sc2731-efuse", NULL, NULL, 0, 0, "sprd,sc2731-efuse"),
+ MFD_CELL_OF("sc2731-eic", NULL, NULL, 0, 0, "sprd,sc2731-eic"),
+ MFD_CELL_OF("sc2731-fgu", NULL, NULL, 0, 0, "sprd,sc2731-fgu"),
+ MFD_CELL_NAME("sc2731-poweroff"),
+ MFD_CELL_NAME("sc2731-regulator"),
+ MFD_CELL_OF("sc2731-rtc", NULL, NULL, 0, 0, "sprd,sc2731-rtc"),
+ MFD_CELL_OF("sc2731-vibrator", NULL, NULL, 0, 0, "sprd,sc2731-vibrator"),
+};
+
/*
* Since different PMICs of SC27xx series can have different interrupt
* base address and irq number, we should save irq number and irq base
@@ -152,12 +180,26 @@ static const struct regmap_config sprd_pmic_config = {
static int sprd_pmic_probe(struct spi_device *spi)
{
struct sprd_pmic *ddata;
+ enum sprd_pmic_type pmic_type;
const struct sprd_pmic_data *pdata;
- int ret, i;
+ const struct mfd_cell *cells;
+ int ret, i, num_cells;
+
+ pmic_type = (enum sprd_pmic_type)of_device_get_match_data(&spi->dev);
- pdata = of_device_get_match_data(&spi->dev);
- if (!pdata) {
- dev_err(&spi->dev, "No matching driver data found\n");
+ switch (pmic_type) {
+ case PMIC_TYPE_SC2730:
+ pdata = &sc2730_data;
+ cells = sc2730_devices;
+ num_cells = ARRAY_SIZE(sc2730_devices);
+ break;
+ case PMIC_TYPE_SC2731:
+ pdata = &sc2731_data;
+ cells = sc2731_devices;
+ num_cells = ARRAY_SIZE(sc2731_devices);
+ break;
+ default:
+ dev_err(&spi->dev, "Invalid device ID\n");
return -EINVAL;
}
@@ -204,7 +246,9 @@ static int sprd_pmic_probe(struct spi_device *spi)
return ret;
}
- ret = devm_of_platform_populate(&spi->dev);
+ ret = devm_mfd_add_devices(&spi->dev, PLATFORM_DEVID_AUTO,
+ cells, num_cells, NULL, 0,
+ regmap_irq_get_domain(ddata->irq_data));
if (ret) {
dev_err(&spi->dev, "Failed to populate sub-devices %d\n", ret);
return ret;
@@ -241,15 +285,15 @@ static DEFINE_SIMPLE_DEV_PM_OPS(sprd_pmic_pm_ops,
sprd_pmic_suspend, sprd_pmic_resume);
static const struct of_device_id sprd_pmic_match[] = {
- { .compatible = "sprd,sc2730", .data = &sc2730_data },
- { .compatible = "sprd,sc2731", .data = &sc2731_data },
+ { .compatible = "sprd,sc2730", .data = (void *)PMIC_TYPE_SC2730 },
+ { .compatible = "sprd,sc2731", .data = (void *)PMIC_TYPE_SC2731 },
{},
};
MODULE_DEVICE_TABLE(of, sprd_pmic_match);
static const struct spi_device_id sprd_pmic_spi_ids[] = {
- { .name = "sc2730", .driver_data = (unsigned long)&sc2730_data },
- { .name = "sc2731", .driver_data = (unsigned long)&sc2731_data },
+ { .name = "sc2730", .driver_data = PMIC_TYPE_SC2730 },
+ { .name = "sc2731", .driver_data = PMIC_TYPE_SC2731 },
{},
};
MODULE_DEVICE_TABLE(spi, sprd_pmic_spi_ids);
--
2.51.0
Hi Otto,
kernel test robot noticed the following build warnings:
[auto build test WARNING on 85964cdcad0fac9a0eb7b87a0f9d88cc074b854c]
url: https://github.com/intel-lab-lkp/linux/commits/Otto-Pfl-ger/dt-bindings-rtc-sc2731-Add-compatible-for-SC2730/20260327-162827
base: 85964cdcad0fac9a0eb7b87a0f9d88cc074b854c
patch link: https://lore.kernel.org/r/20260325-sc27xx-mfd-cells-v2-3-d0ebb60aa4a7%40abscue.de
patch subject: [PATCH v2 3/5] mfd: sprd-sc27xx: Switch to devm_mfd_add_devices()
config: sparc64-allmodconfig (https://download.01.org/0day-ci/archive/20260329/202603291013.6DnmGjG3-lkp@intel.com/config)
compiler: clang version 23.0.0git (https://github.com/llvm/llvm-project 054e11d1a17e5ba88bb1a8ef32fad3346e80b186)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260329/202603291013.6DnmGjG3-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603291013.6DnmGjG3-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> drivers/mfd/sprd-sc27xx-spi.c:188:14: warning: cast to smaller integer type 'enum sprd_pmic_type' from 'const void *' [-Wvoid-pointer-to-enum-cast]
188 | pmic_type = (enum sprd_pmic_type)of_device_get_match_data(&spi->dev);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
vim +188 drivers/mfd/sprd-sc27xx-spi.c
179
180 static int sprd_pmic_probe(struct spi_device *spi)
181 {
182 struct sprd_pmic *ddata;
183 enum sprd_pmic_type pmic_type;
184 const struct sprd_pmic_data *pdata;
185 const struct mfd_cell *cells;
186 int ret, i, num_cells;
187
> 188 pmic_type = (enum sprd_pmic_type)of_device_get_match_data(&spi->dev);
189
190 switch (pmic_type) {
191 case PMIC_TYPE_SC2730:
192 pdata = &sc2730_data;
193 cells = sc2730_devices;
194 num_cells = ARRAY_SIZE(sc2730_devices);
195 break;
196 case PMIC_TYPE_SC2731:
197 pdata = &sc2731_data;
198 cells = sc2731_devices;
199 num_cells = ARRAY_SIZE(sc2731_devices);
200 break;
201 default:
202 dev_err(&spi->dev, "Invalid device ID\n");
203 return -EINVAL;
204 }
205
206 ddata = devm_kzalloc(&spi->dev, sizeof(*ddata), GFP_KERNEL);
207 if (!ddata)
208 return -ENOMEM;
209
210 ddata->regmap = devm_regmap_init(&spi->dev, &sprd_pmic_regmap,
211 &spi->dev, &sprd_pmic_config);
212 if (IS_ERR(ddata->regmap)) {
213 ret = PTR_ERR(ddata->regmap);
214 dev_err(&spi->dev, "Failed to allocate register map %d\n", ret);
215 return ret;
216 }
217
218 spi_set_drvdata(spi, ddata);
219 ddata->dev = &spi->dev;
220 ddata->irq = spi->irq;
221 ddata->pdata = pdata;
222
223 ddata->irq_chip.name = dev_name(&spi->dev);
224 ddata->irq_chip.status_base =
225 pdata->irq_base + SPRD_PMIC_INT_MASK_STATUS;
226 ddata->irq_chip.unmask_base = pdata->irq_base + SPRD_PMIC_INT_EN;
227 ddata->irq_chip.ack_base = 0;
228 ddata->irq_chip.num_regs = 1;
229 ddata->irq_chip.num_irqs = pdata->num_irqs;
230
231 ddata->irqs = devm_kcalloc(&spi->dev,
232 pdata->num_irqs, sizeof(struct regmap_irq),
233 GFP_KERNEL);
234 if (!ddata->irqs)
235 return -ENOMEM;
236
237 ddata->irq_chip.irqs = ddata->irqs;
238 for (i = 0; i < pdata->num_irqs; i++)
239 ddata->irqs[i].mask = BIT(i);
240
241 ret = devm_regmap_add_irq_chip(&spi->dev, ddata->regmap, ddata->irq,
242 IRQF_ONESHOT, 0,
243 &ddata->irq_chip, &ddata->irq_data);
244 if (ret) {
245 dev_err(&spi->dev, "Failed to add PMIC irq chip %d\n", ret);
246 return ret;
247 }
248
249 ret = devm_mfd_add_devices(&spi->dev, PLATFORM_DEVID_AUTO,
250 cells, num_cells, NULL, 0,
251 regmap_irq_get_domain(ddata->irq_data));
252 if (ret) {
253 dev_err(&spi->dev, "Failed to populate sub-devices %d\n", ret);
254 return ret;
255 }
256
257 ret = devm_device_init_wakeup(&spi->dev);
258 if (ret)
259 return dev_err_probe(&spi->dev, ret, "Failed to init wakeup\n");
260
261 return 0;
262 }
263
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
© 2016 - 2026 Red Hat, Inc.