static int syscfg_reset_controller_register(struct device *dev, const struct syscfg_reset_controller_data *data) { struct syscfg_reset_controller *rc; size_t size; int i, err; rc = devm_kzalloc(dev, sizeof(*rc), GFP_KERNEL); if (!rc) return -ENOMEM; size = sizeof(struct syscfg_reset_channel) * data->nr_channels; rc->channels = devm_kzalloc(dev, size, GFP_KERNEL); if (!rc->channels) return -ENOMEM; rc->rst.ops = &syscfg_reset_ops, rc->rst.of_node = dev->of_node; rc->rst.nr_resets = data->nr_channels; rc->active_low = data->active_low; for (i = 0; i < data->nr_channels; i++) { struct regmap *map; struct regmap_field *f; const char *compatible = data->channels[i].compatible; map = syscon_regmap_lookup_by_compatible(compatible); if (IS_ERR(map)) return PTR_ERR(map); f = devm_regmap_field_alloc(dev, map, data->channels[i].reset); if (IS_ERR(f)) return PTR_ERR(f); rc->channels[i].reset = f; if (!data->wait_for_ack) continue; f = devm_regmap_field_alloc(dev, map, data->channels[i].ack); if (IS_ERR(f)) return PTR_ERR(f); rc->channels[i].ack = f; } err = reset_controller_register(&rc->rst); if (!err) dev_info(dev, "registered\n"); return err; }
/* * Function to allocate regfields which are common * between syscfg and memory mapped based sensors */ static int st_thermal_alloc_regfields(struct st_thermal_sensor *sensor) { struct device *dev = sensor->dev; struct regmap *regmap = sensor->regmap; const struct reg_field *reg_fields = sensor->cdata->reg_fields; sensor->dcorrect = devm_regmap_field_alloc(dev, regmap, reg_fields[DCORRECT]); sensor->overflow = devm_regmap_field_alloc(dev, regmap, reg_fields[OVERFLOW]); sensor->temp_data = devm_regmap_field_alloc(dev, regmap, reg_fields[DATA]); if (IS_ERR(sensor->dcorrect) || IS_ERR(sensor->overflow) || IS_ERR(sensor->temp_data)) { dev_err(dev, "failed to allocate common regfields\n"); return -EINVAL; } return sensor->ops->alloc_regfields(sensor); }
static int da9063_regulator_probe(struct platform_device *pdev) { struct da9063 *da9063 = dev_get_drvdata(pdev->dev.parent); struct da9063_pdata *da9063_pdata = dev_get_platdata(da9063->dev); struct of_regulator_match *da9063_reg_matches = NULL; struct da9063_regulators_pdata *regl_pdata; const struct da9063_dev_model *model; struct da9063_regulators *regulators; struct da9063_regulator *regl; struct regulator_config config; bool bcores_merged, bmem_bio_merged; int id, irq, n, n_regulators, ret, val; size_t size; regl_pdata = da9063_pdata ? da9063_pdata->regulators_pdata : NULL; if (!regl_pdata) regl_pdata = da9063_parse_regulators_dt(pdev, &da9063_reg_matches); if (IS_ERR(regl_pdata) || regl_pdata->n_regulators == 0) { dev_err(&pdev->dev, "No regulators defined for the platform\n"); return PTR_ERR(regl_pdata); } /* Find regulators set for particular device model */ for (model = regulators_models; model->regulator_info; model++) { if (model->dev_model == da9063->model) break; } if (!model->regulator_info) { dev_err(&pdev->dev, "Chip model not recognised (%u)\n", da9063->model); return -ENODEV; } ret = regmap_read(da9063->regmap, DA9063_REG_CONFIG_H, &val); if (ret < 0) { dev_err(&pdev->dev, "Error while reading BUCKs configuration\n"); return ret; } bcores_merged = val & DA9063_BCORE_MERGE; bmem_bio_merged = val & DA9063_BUCK_MERGE; n_regulators = model->n_regulators; if (bcores_merged) n_regulators -= 2; /* remove BCORE1, BCORE2 */ else n_regulators--; /* remove BCORES_MERGED */ if (bmem_bio_merged) n_regulators -= 2; /* remove BMEM, BIO */ else n_regulators--; /* remove BMEM_BIO_MERGED */ /* Allocate memory required by usable regulators */ size = sizeof(struct da9063_regulators) + n_regulators * sizeof(struct da9063_regulator); regulators = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); if (!regulators) return -ENOMEM; regulators->n_regulators = n_regulators; platform_set_drvdata(pdev, regulators); /* Register all regulators declared in platform information */ n = 0; id = 0; while (n < regulators->n_regulators) { /* Skip regulator IDs depending on merge mode configuration */ switch (id) { case DA9063_ID_BCORE1: case DA9063_ID_BCORE2: if (bcores_merged) { id++; continue; } break; case DA9063_ID_BMEM: case DA9063_ID_BIO: if (bmem_bio_merged) { id++; continue; } break; case DA9063_ID_BCORES_MERGED: if (!bcores_merged) { id++; continue; } break; case DA9063_ID_BMEM_BIO_MERGED: if (!bmem_bio_merged) { id++; continue; } break; } /* Initialise regulator structure */ regl = ®ulators->regulator[n]; regl->hw = da9063; regl->info = &model->regulator_info[id]; regl->desc = regl->info->desc; regl->desc.type = REGULATOR_VOLTAGE; regl->desc.owner = THIS_MODULE; if (regl->info->mode.reg) regl->mode = devm_regmap_field_alloc(&pdev->dev, da9063->regmap, regl->info->mode); if (regl->info->suspend.reg) regl->suspend = devm_regmap_field_alloc(&pdev->dev, da9063->regmap, regl->info->suspend); if (regl->info->sleep.reg) regl->sleep = devm_regmap_field_alloc(&pdev->dev, da9063->regmap, regl->info->sleep); if (regl->info->suspend_sleep.reg) regl->suspend_sleep = devm_regmap_field_alloc(&pdev->dev, da9063->regmap, regl->info->suspend_sleep); if (regl->info->ilimit.reg) regl->ilimit = devm_regmap_field_alloc(&pdev->dev, da9063->regmap, regl->info->ilimit); /* Register regulator */ memset(&config, 0, sizeof(config)); config.dev = &pdev->dev; config.init_data = da9063_get_regulator_initdata(regl_pdata, id); config.driver_data = regl; if (da9063_reg_matches) config.of_node = da9063_reg_matches[id].of_node; config.regmap = da9063->regmap; regl->rdev = devm_regulator_register(&pdev->dev, ®l->desc, &config); if (IS_ERR(regl->rdev)) { dev_err(&pdev->dev, "Failed to register %s regulator\n", regl->desc.name); return PTR_ERR(regl->rdev); } id++; n++; } /* LDOs overcurrent event support */ irq = platform_get_irq_byname(pdev, "LDO_LIM"); if (irq < 0) { dev_err(&pdev->dev, "Failed to get IRQ.\n"); return irq; } ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, da9063_ldo_lim_event, IRQF_TRIGGER_LOW | IRQF_ONESHOT, "LDO_LIM", regulators); if (ret) { dev_err(&pdev->dev, "Failed to request LDO_LIM IRQ.\n"); return ret; } return 0; }
static int da9062_regulator_probe(struct platform_device *pdev) { struct da9062 *chip = dev_get_drvdata(pdev->dev.parent); struct da9062_regulators *regulators; struct da9062_regulator *regl; struct regulator_config config = { }; int irq, n, ret; size_t size; /* Allocate memory required by usable regulators */ size = sizeof(struct da9062_regulators) + DA9062_MAX_REGULATORS * sizeof(struct da9062_regulator); regulators = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); if (!regulators) return -ENOMEM; regulators->n_regulators = DA9062_MAX_REGULATORS; platform_set_drvdata(pdev, regulators); n = 0; while (n < regulators->n_regulators) { /* Initialise regulator structure */ regl = ®ulators->regulator[n]; regl->hw = chip; regl->info = &local_regulator_info[n]; regl->desc = regl->info->desc; regl->desc.type = REGULATOR_VOLTAGE; regl->desc.owner = THIS_MODULE; if (regl->info->mode.reg) regl->mode = devm_regmap_field_alloc( &pdev->dev, chip->regmap, regl->info->mode); if (regl->info->suspend.reg) regl->suspend = devm_regmap_field_alloc( &pdev->dev, chip->regmap, regl->info->suspend); if (regl->info->sleep.reg) regl->sleep = devm_regmap_field_alloc( &pdev->dev, chip->regmap, regl->info->sleep); if (regl->info->suspend_sleep.reg) regl->suspend_sleep = devm_regmap_field_alloc( &pdev->dev, chip->regmap, regl->info->suspend_sleep); if (regl->info->ilimit.reg) regl->ilimit = devm_regmap_field_alloc( &pdev->dev, chip->regmap, regl->info->ilimit); /* Register regulator */ memset(&config, 0, sizeof(config)); config.dev = chip->dev; config.driver_data = regl; config.regmap = chip->regmap; regl->rdev = devm_regulator_register(&pdev->dev, ®l->desc, &config); if (IS_ERR(regl->rdev)) { dev_err(&pdev->dev, "Failed to register %s regulator\n", regl->desc.name); return PTR_ERR(regl->rdev); } n++; } /* LDOs overcurrent event support */ irq = platform_get_irq_byname(pdev, "LDO_LIM"); if (irq < 0) { dev_err(&pdev->dev, "Failed to get IRQ.\n"); return irq; } regulators->irq_ldo_lim = irq; ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, da9062_ldo_lim_event, IRQF_TRIGGER_LOW | IRQF_ONESHOT, "LDO_LIM", regulators); if (ret) { dev_warn(&pdev->dev, "Failed to request LDO_LIM IRQ.\n"); regulators->irq_ldo_lim = -ENXIO; } return 0; }
static int _rsnd_gen_regmap_init(struct rsnd_priv *priv, int id_size, int reg_id, const char *name, const struct rsnd_regmap_field_conf *conf, int conf_size) { struct platform_device *pdev = rsnd_priv_to_pdev(priv); struct rsnd_gen *gen = rsnd_priv_to_gen(priv); struct device *dev = rsnd_priv_to_dev(priv); struct resource *res; struct regmap_config regc; struct regmap_field *regs; struct regmap *regmap; struct reg_field regf; void __iomem *base; int i; memset(®c, 0, sizeof(regc)); regc.reg_bits = 32; regc.val_bits = 32; regc.reg_stride = 4; regc.name = name; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); if (!res) res = platform_get_resource(pdev, IORESOURCE_MEM, reg_id); if (!res) return -ENODEV; base = devm_ioremap_resource(dev, res); if (IS_ERR(base)) return PTR_ERR(base); regmap = devm_regmap_init_mmio(dev, base, ®c); if (IS_ERR(regmap)) return PTR_ERR(regmap); /* RSND_BASE_MAX base */ gen->base[reg_id] = base; gen->regmap[reg_id] = regmap; gen->res[reg_id] = res->start; for (i = 0; i < conf_size; i++) { regf.reg = conf[i].reg_offset; regf.id_offset = conf[i].id_offset; regf.lsb = 0; regf.msb = 31; regf.id_size = id_size; regs = devm_regmap_field_alloc(dev, regmap, regf); if (IS_ERR(regs)) return PTR_ERR(regs); /* RSND_REG_MAX base */ gen->regs[conf[i].idx] = regs; gen->reg_name[conf[i].idx] = conf[i].reg_name; } return 0; }