diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/regulator/Kconfig | 6 | ||||
-rw-r--r-- | drivers/regulator/bd71815-regulator.c | 4 | ||||
-rw-r--r-- | drivers/regulator/core.c | 9 | ||||
-rw-r--r-- | drivers/regulator/dummy.c | 3 | ||||
-rw-r--r-- | drivers/regulator/lp872x.c | 38 | ||||
-rw-r--r-- | drivers/regulator/max8973-regulator.c | 4 | ||||
-rw-r--r-- | drivers/regulator/pwm-regulator.c | 12 | ||||
-rw-r--r-- | drivers/regulator/qcom_smd-regulator.c | 49 | ||||
-rw-r--r-- | drivers/regulator/rtq6752-regulator.c | 18 | ||||
-rw-r--r-- | drivers/regulator/s5m8767.c | 21 | ||||
-rw-r--r-- | drivers/regulator/ti-abb-regulator.c | 31 | ||||
-rw-r--r-- | drivers/regulator/vqmmc-ipq4019-regulator.c | 4 | ||||
-rw-r--r-- | drivers/spi/spi.c | 41 |
13 files changed, 147 insertions, 93 deletions
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 4fd13b06231f..27578e9504d2 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -609,12 +609,12 @@ config REGULATOR_MAX8952 modes ranging from 0.77V to 1.40V by 0.01V steps. config REGULATOR_MAX8973 - tristate "Maxim MAX8973 voltage regulator " + tristate "Maxim MAX8973A voltage regulator" depends on I2C depends on THERMAL && THERMAL_OF select REGMAP_I2C help - The MAXIM MAX8973 high-efficiency. three phase, DC-DC step-down + The MAXIM MAX8973A high-efficiency. three phase, DC-DC step-down switching regulator delivers up to 9A of output current. Each phase operates at a 2MHz fixed frequency with a 120 deg shift from the adjacent phase, allowing the use of small magnetic component. @@ -1181,7 +1181,7 @@ config REGULATOR_STPMIC1 config REGULATOR_TI_ABB tristate "TI Adaptive Body Bias on-chip LDO" - depends on ARCH_OMAP + depends on ARCH_OMAP || COMPILE_TEST help Select this option to support Texas Instruments' on-chip Adaptive Body Bias (ABB) LDO regulators. It is recommended that this option be diff --git a/drivers/regulator/bd71815-regulator.c b/drivers/regulator/bd71815-regulator.c index 16edd9062ca9..acaa6607898e 100644 --- a/drivers/regulator/bd71815-regulator.c +++ b/drivers/regulator/bd71815-regulator.c @@ -461,9 +461,9 @@ static const struct regulator_ops bd7181x_led_regulator_ops = { .min_uV = (min), \ .uV_step = (step), \ .vsel_reg = (vsel), \ - .vsel_mask = 0x3f, \ + .vsel_mask = BD71815_VOLT_MASK, \ .enable_reg = (ereg), \ - .enable_mask = 0x04, \ + .enable_mask = BD71815_BUCK_RUN_ON, \ .ramp_reg = (ereg), \ .ramp_mask = BD71815_BUCK_RAMPRATE_MASK, \ .ramp_delay_table = bd7181x_ramp_table, \ diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index ca6caba8a191..21a2b28ab0ca 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1151,9 +1151,10 @@ static int machine_constraints_voltage(struct regulator_dev *rdev, } if (current_uV < 0) { - rdev_err(rdev, - "failed to get the current voltage: %pe\n", - ERR_PTR(current_uV)); + if (current_uV != -EPROBE_DEFER) + rdev_err(rdev, + "failed to get the current voltage: %pe\n", + ERR_PTR(current_uV)); return current_uV; } @@ -1570,7 +1571,7 @@ static int set_supply(struct regulator_dev *rdev, { int err; - rdev_info(rdev, "supplied by %s\n", rdev_get_name(supply_rdev)); + rdev_dbg(rdev, "supplied by %s\n", rdev_get_name(supply_rdev)); if (!try_module_get(supply_rdev->owner)) return -ENODEV; diff --git a/drivers/regulator/dummy.c b/drivers/regulator/dummy.c index d8059f596391..24e586f93855 100644 --- a/drivers/regulator/dummy.c +++ b/drivers/regulator/dummy.c @@ -45,7 +45,8 @@ static int dummy_regulator_probe(struct platform_device *pdev) config.dev = &pdev->dev; config.init_data = &dummy_initdata; - dummy_regulator_rdev = regulator_register(&dummy_desc, &config); + dummy_regulator_rdev = devm_regulator_register(&pdev->dev, &dummy_desc, + &config); if (IS_ERR(dummy_regulator_rdev)) { ret = PTR_ERR(dummy_regulator_rdev); pr_err("Failed to register regulator: %d\n", ret); diff --git a/drivers/regulator/lp872x.c b/drivers/regulator/lp872x.c index e84be29533f4..1dba5dbcd461 100644 --- a/drivers/regulator/lp872x.c +++ b/drivers/regulator/lp872x.c @@ -10,13 +10,12 @@ #include <linux/i2c.h> #include <linux/regmap.h> #include <linux/err.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/delay.h> #include <linux/regulator/lp872x.h> #include <linux/regulator/driver.h> #include <linux/platform_device.h> #include <linux/of.h> -#include <linux/of_gpio.h> #include <linux/regulator/of_regulator.h> /* Registers : LP8720/8725 shared */ @@ -250,12 +249,12 @@ static int lp872x_regulator_enable_time(struct regulator_dev *rdev) } static void lp872x_set_dvs(struct lp872x *lp, enum lp872x_dvs_sel dvs_sel, - int gpio) + struct gpio_desc *gpio) { enum lp872x_dvs_state state; state = dvs_sel == SEL_V1 ? DVS_HIGH : DVS_LOW; - gpio_set_value(gpio, state); + gpiod_set_value(gpio, state); lp->dvs_pin = state; } @@ -321,7 +320,7 @@ static int lp872x_buck_set_voltage_sel(struct regulator_dev *rdev, u8 addr, mask = LP872X_VOUT_M; struct lp872x_dvs *dvs = lp->pdata ? lp->pdata->dvs : NULL; - if (dvs && gpio_is_valid(dvs->gpio)) + if (dvs && dvs->gpio) lp872x_set_dvs(lp, dvs->vsel, dvs->gpio); addr = lp872x_select_buck_vout_addr(lp, buck); @@ -675,7 +674,6 @@ static const struct regulator_desc lp8725_regulator_desc[] = { static int lp872x_init_dvs(struct lp872x *lp) { - int ret, gpio; struct lp872x_dvs *dvs = lp->pdata ? lp->pdata->dvs : NULL; enum lp872x_dvs_state pinstate; u8 mask[] = { LP8720_EXT_DVS_M, LP8725_DVS1_M | LP8725_DVS2_M }; @@ -684,15 +682,15 @@ static int lp872x_init_dvs(struct lp872x *lp) if (!dvs) goto set_default_dvs_mode; - gpio = dvs->gpio; - if (!gpio_is_valid(gpio)) + if (!dvs->gpio) goto set_default_dvs_mode; pinstate = dvs->init_state; - ret = devm_gpio_request_one(lp->dev, gpio, pinstate, "LP872X DVS"); - if (ret) { - dev_err(lp->dev, "gpio request err: %d\n", ret); - return ret; + dvs->gpio = devm_gpiod_get_optional(lp->dev, "ti,dvs", pinstate); + + if (IS_ERR(dvs->gpio)) { + dev_err(lp->dev, "gpio request err: %ld\n", PTR_ERR(dvs->gpio)); + return PTR_ERR(dvs->gpio); } lp->dvs_pin = pinstate; @@ -706,20 +704,17 @@ set_default_dvs_mode: static int lp872x_hw_enable(struct lp872x *lp) { - int ret, gpio; - if (!lp->pdata) return -EINVAL; - gpio = lp->pdata->enable_gpio; - if (!gpio_is_valid(gpio)) + if (!lp->pdata->enable_gpio) return 0; /* Always set enable GPIO high. */ - ret = devm_gpio_request_one(lp->dev, gpio, GPIOF_OUT_INIT_HIGH, "LP872X EN"); - if (ret) { - dev_err(lp->dev, "gpio request err: %d\n", ret); - return ret; + lp->pdata->enable_gpio = devm_gpiod_get_optional(lp->dev, "enable", GPIOD_OUT_HIGH); + if (IS_ERR(lp->pdata->enable_gpio)) { + dev_err(lp->dev, "gpio request err: %ld\n", PTR_ERR(lp->pdata->enable_gpio)); + return PTR_ERR(lp->pdata->enable_gpio); } /* Each chip has a different enable delay. */ @@ -844,13 +839,10 @@ static struct lp872x_platform_data if (!pdata->dvs) return ERR_PTR(-ENOMEM); - pdata->dvs->gpio = of_get_named_gpio(np, "ti,dvs-gpio", 0); of_property_read_u8(np, "ti,dvs-vsel", (u8 *)&pdata->dvs->vsel); of_property_read_u8(np, "ti,dvs-state", &dvs_state); pdata->dvs->init_state = dvs_state ? DVS_HIGH : DVS_LOW; - pdata->enable_gpio = of_get_named_gpio(np, "enable-gpios", 0); - if (of_get_child_count(np) == 0) goto out; diff --git a/drivers/regulator/max8973-regulator.c b/drivers/regulator/max8973-regulator.c index 8da8f9b6c4fd..80b65cb87cef 100644 --- a/drivers/regulator/max8973-regulator.c +++ b/drivers/regulator/max8973-regulator.c @@ -1,7 +1,7 @@ /* - * max8973-regulator.c -- Maxim max8973 + * max8973-regulator.c -- Maxim max8973A * - * Regulator driver for MAXIM 8973 DC-DC step-down switching regulator. + * Regulator driver for MAXIM 8973A DC-DC step-down switching regulator. * * Copyright (c) 2012, NVIDIA Corporation. * diff --git a/drivers/regulator/pwm-regulator.c b/drivers/regulator/pwm-regulator.c index 7629476d94ae..b9eeaff1c661 100644 --- a/drivers/regulator/pwm-regulator.c +++ b/drivers/regulator/pwm-regulator.c @@ -352,15 +352,9 @@ static int pwm_regulator_probe(struct platform_device *pdev) config.init_data = init_data; drvdata->pwm = devm_pwm_get(&pdev->dev, NULL); - if (IS_ERR(drvdata->pwm)) { - ret = PTR_ERR(drvdata->pwm); - if (ret == -EPROBE_DEFER) - dev_dbg(&pdev->dev, - "Failed to get PWM, deferring probe\n"); - else - dev_err(&pdev->dev, "Failed to get PWM: %d\n", ret); - return ret; - } + if (IS_ERR(drvdata->pwm)) + return dev_err_probe(&pdev->dev, PTR_ERR(drvdata->pwm), + "Failed to get PWM\n"); if (init_data->constraints.boot_on || init_data->constraints.always_on) gpio_flags = GPIOD_OUT_HIGH; diff --git a/drivers/regulator/qcom_smd-regulator.c b/drivers/regulator/qcom_smd-regulator.c index 198fcc6551f6..8bac024dde8b 100644 --- a/drivers/regulator/qcom_smd-regulator.c +++ b/drivers/regulator/qcom_smd-regulator.c @@ -738,6 +738,24 @@ static const struct regulator_desc mp5496_ldoa2 = { .ops = &rpm_mp5496_ops, }; +static const struct regulator_desc pm2250_lvftsmps = { + .linear_ranges = (struct linear_range[]) { + REGULATOR_LINEAR_RANGE(320000, 0, 269, 4000), + }, + .n_linear_ranges = 1, + .n_voltages = 270, + .ops = &rpm_smps_ldo_ops, +}; + +static const struct regulator_desc pm2250_ftsmps = { + .linear_ranges = (struct linear_range[]) { + REGULATOR_LINEAR_RANGE(640000, 0, 269, 8000), + }, + .n_linear_ranges = 1, + .n_voltages = 270, + .ops = &rpm_smps_ldo_ops, +}; + struct rpm_regulator_data { const char *name; u32 type; @@ -1170,6 +1188,36 @@ static const struct rpm_regulator_data rpm_pms405_regulators[] = { {} }; +static const struct rpm_regulator_data rpm_pm2250_regulators[] = { + { "s1", QCOM_SMD_RPM_SMPA, 1, &pm2250_lvftsmps, "vdd_s1" }, + { "s2", QCOM_SMD_RPM_SMPA, 2, &pm2250_lvftsmps, "vdd_s2" }, + { "s3", QCOM_SMD_RPM_SMPA, 3, &pm2250_lvftsmps, "vdd_s3" }, + { "s4", QCOM_SMD_RPM_SMPA, 4, &pm2250_ftsmps, "vdd_s4" }, + { "l1", QCOM_SMD_RPM_LDOA, 1, &pm660_nldo660, "vdd_l1_l2_l3_l5_l6_l7_l8_l9_l10_l11_l12" }, + { "l2", QCOM_SMD_RPM_LDOA, 2, &pm660_nldo660, "vdd_l1_l2_l3_l5_l6_l7_l8_l9_l10_l11_l12" }, + { "l3", QCOM_SMD_RPM_LDOA, 3, &pm660_nldo660, "vdd_l1_l2_l3_l5_l6_l7_l8_l9_l10_l11_l12" }, + { "l4", QCOM_SMD_RPM_LDOA, 4, &pm660_pldo660, "vdd_l4_l17_l18_l19_l20_l21_l22" }, + { "l5", QCOM_SMD_RPM_LDOA, 5, &pm660_nldo660, "vdd_l1_l2_l3_l5_l6_l7_l8_l9_l10_l11_l12" }, + { "l6", QCOM_SMD_RPM_LDOA, 6, &pm660_nldo660, "vdd_l1_l2_l3_l5_l6_l7_l8_l9_l10_l11_l12" }, + { "l7", QCOM_SMD_RPM_LDOA, 7, &pm660_nldo660, "vdd_l1_l2_l3_l5_l6_l7_l8_l9_l10_l11_l12" }, + { "l8", QCOM_SMD_RPM_LDOA, 8, &pm660_nldo660, "vdd_l1_l2_l3_l5_l6_l7_l8_l9_l10_l11_l12" }, + { "l9", QCOM_SMD_RPM_LDOA, 9, &pm660_nldo660, "vdd_l1_l2_l3_l5_l6_l7_l8_l9_l10_l11_l12" }, + { "l10", QCOM_SMD_RPM_LDOA, 10, &pm660_nldo660, "vdd_l1_l2_l3_l5_l6_l7_l8_l9_l10_l11_l12" }, + { "l11", QCOM_SMD_RPM_LDOA, 11, &pm660_nldo660, "vdd_l1_l2_l3_l5_l6_l7_l8_l9_l10_l11_l12" }, + { "l12", QCOM_SMD_RPM_LDOA, 12, &pm660_nldo660, "vdd_l1_l2_l3_l5_l6_l7_l8_l9_l10_l11_l12" }, + { "l13", QCOM_SMD_RPM_LDOA, 13, &pm660_ht_lvpldo, "vdd_l13_l14_l15_l16" }, + { "l14", QCOM_SMD_RPM_LDOA, 14, &pm660_ht_lvpldo, "vdd_l13_l14_l15_l16" }, + { "l15", QCOM_SMD_RPM_LDOA, 15, &pm660_ht_lvpldo, "vdd_l13_l14_l15_l16" }, + { "l16", QCOM_SMD_RPM_LDOA, 16, &pm660_ht_lvpldo, "vdd_l13_l14_l15_l16" }, + { "l17", QCOM_SMD_RPM_LDOA, 17, &pm660_pldo660, "vdd_l4_l17_l18_l19_l20_l21_l22" }, + { "l18", QCOM_SMD_RPM_LDOA, 18, &pm660_pldo660, "vdd_l4_l17_l18_l19_l20_l21_l22" }, + { "l19", QCOM_SMD_RPM_LDOA, 19, &pm660_pldo660, "vdd_l4_l17_l18_l19_l20_l21_l22" }, + { "l20", QCOM_SMD_RPM_LDOA, 20, &pm660_pldo660, "vdd_l4_l17_l18_l19_l20_l21_l22" }, + { "l21", QCOM_SMD_RPM_LDOA, 21, &pm660_pldo660, "vdd_l4_l17_l18_l19_l20_l21_l22" }, + { "l22", QCOM_SMD_RPM_LDOA, 22, &pm660_pldo660, "vdd_l4_l17_l18_l19_l20_l21_l22" }, + {} +}; + static const struct of_device_id rpm_of_match[] = { { .compatible = "qcom,rpm-mp5496-regulators", .data = &rpm_mp5496_regulators }, { .compatible = "qcom,rpm-pm8841-regulators", .data = &rpm_pm8841_regulators }, @@ -1186,6 +1234,7 @@ static const struct of_device_id rpm_of_match[] = { { .compatible = "qcom,rpm-pmi8994-regulators", .data = &rpm_pmi8994_regulators }, { .compatible = "qcom,rpm-pmi8998-regulators", .data = &rpm_pmi8998_regulators }, { .compatible = "qcom,rpm-pms405-regulators", .data = &rpm_pms405_regulators }, + { .compatible = "qcom,rpm-pm2250-regulators", .data = &rpm_pm2250_regulators }, {} }; MODULE_DEVICE_TABLE(of, rpm_of_match); diff --git a/drivers/regulator/rtq6752-regulator.c b/drivers/regulator/rtq6752-regulator.c index 609d3fcf4923..dfe45fb67353 100644 --- a/drivers/regulator/rtq6752-regulator.c +++ b/drivers/regulator/rtq6752-regulator.c @@ -54,14 +54,14 @@ static int rtq6752_set_vdd_enable(struct regulator_dev *rdev) int rid = rdev_get_id(rdev), ret; mutex_lock(&priv->lock); - if (priv->enable_gpio) { - gpiod_set_value(priv->enable_gpio, 1); + if (!priv->enable_flag) { + if (priv->enable_gpio) { + gpiod_set_value(priv->enable_gpio, 1); - usleep_range(RTQ6752_I2CRDY_TIMEUS, - RTQ6752_I2CRDY_TIMEUS + 100); - } + usleep_range(RTQ6752_I2CRDY_TIMEUS, + RTQ6752_I2CRDY_TIMEUS + 100); + } - if (!priv->enable_flag) { regcache_cache_only(priv->regmap, false); ret = regcache_sync(priv->regmap); if (ret) { @@ -91,11 +91,11 @@ static int rtq6752_set_vdd_disable(struct regulator_dev *rdev) if (!priv->enable_flag) { regcache_cache_only(priv->regmap, true); regcache_mark_dirty(priv->regmap); - } - if (priv->enable_gpio) - gpiod_set_value(priv->enable_gpio, 0); + if (priv->enable_gpio) + gpiod_set_value(priv->enable_gpio, 0); + } mutex_unlock(&priv->lock); return 0; diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index 7c111bbdc2af..35269f998210 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -850,18 +850,15 @@ static int s5m8767_pmic_probe(struct platform_device *pdev) /* DS4 GPIO */ gpio_direction_output(pdata->buck_ds[2], 0x0); - if (pdata->buck2_gpiodvs || pdata->buck3_gpiodvs || - pdata->buck4_gpiodvs) { - regmap_update_bits(s5m8767->iodev->regmap_pmic, - S5M8767_REG_BUCK2CTRL, 1 << 1, - (pdata->buck2_gpiodvs) ? (1 << 1) : (0 << 1)); - regmap_update_bits(s5m8767->iodev->regmap_pmic, - S5M8767_REG_BUCK3CTRL, 1 << 1, - (pdata->buck3_gpiodvs) ? (1 << 1) : (0 << 1)); - regmap_update_bits(s5m8767->iodev->regmap_pmic, - S5M8767_REG_BUCK4CTRL, 1 << 1, - (pdata->buck4_gpiodvs) ? (1 << 1) : (0 << 1)); - } + regmap_update_bits(s5m8767->iodev->regmap_pmic, + S5M8767_REG_BUCK2CTRL, 1 << 1, + (pdata->buck2_gpiodvs) ? (1 << 1) : (0 << 1)); + regmap_update_bits(s5m8767->iodev->regmap_pmic, + S5M8767_REG_BUCK3CTRL, 1 << 1, + (pdata->buck3_gpiodvs) ? (1 << 1) : (0 << 1)); + regmap_update_bits(s5m8767->iodev->regmap_pmic, + S5M8767_REG_BUCK4CTRL, 1 << 1, + (pdata->buck4_gpiodvs) ? (1 << 1) : (0 << 1)); /* Initialize GPIO DVS registers */ for (i = 0; i < 8; i++) { diff --git a/drivers/regulator/ti-abb-regulator.c b/drivers/regulator/ti-abb-regulator.c index 9f0a4d50cead..2931a0b89bff 100644 --- a/drivers/regulator/ti-abb-regulator.c +++ b/drivers/regulator/ti-abb-regulator.c @@ -725,9 +725,7 @@ static int ti_abb_probe(struct platform_device *pdev) /* Map ABB resources */ if (abb->regs->setup_off || abb->regs->control_off) { - pname = "base-address"; - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); - abb->base = devm_ioremap_resource(dev, res); + abb->base = devm_platform_ioremap_resource_byname(pdev, "base-address"); if (IS_ERR(abb->base)) return PTR_ERR(abb->base); @@ -735,35 +733,18 @@ static int ti_abb_probe(struct platform_device *pdev) abb->control_reg = abb->base + abb->regs->control_off; } else { - pname = "control-address"; - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); - abb->control_reg = devm_ioremap_resource(dev, res); + abb->control_reg = devm_platform_ioremap_resource_byname(pdev, "control-address"); if (IS_ERR(abb->control_reg)) return PTR_ERR(abb->control_reg); - pname = "setup-address"; - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); - abb->setup_reg = devm_ioremap_resource(dev, res); + abb->setup_reg = devm_platform_ioremap_resource_byname(pdev, "setup-address"); if (IS_ERR(abb->setup_reg)) return PTR_ERR(abb->setup_reg); } - pname = "int-address"; - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); - if (!res) { - dev_err(dev, "Missing '%s' IO resource\n", pname); - return -ENODEV; - } - /* - * We may have shared interrupt register offsets which are - * write-1-to-clear between domains ensuring exclusivity. - */ - abb->int_base = devm_ioremap(dev, res->start, - resource_size(res)); - if (!abb->int_base) { - dev_err(dev, "Unable to map '%s'\n", pname); - return -ENOMEM; - } + abb->int_base = devm_platform_ioremap_resource_byname(pdev, "int-address"); + if (IS_ERR(abb->int_base)) + return PTR_ERR(abb->int_base); /* Map Optional resources */ pname = "efuse-address"; diff --git a/drivers/regulator/vqmmc-ipq4019-regulator.c b/drivers/regulator/vqmmc-ipq4019-regulator.c index 6d5ae25d08d1..c4213f096fe5 100644 --- a/drivers/regulator/vqmmc-ipq4019-regulator.c +++ b/drivers/regulator/vqmmc-ipq4019-regulator.c @@ -48,7 +48,6 @@ static int ipq4019_regulator_probe(struct platform_device *pdev) struct regulator_init_data *init_data; struct regulator_config cfg = {}; struct regulator_dev *rdev; - struct resource *res; struct regmap *rmap; void __iomem *base; @@ -57,8 +56,7 @@ static int ipq4019_regulator_probe(struct platform_device *pdev) if (!init_data) return -EINVAL; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 926b68aa45d3..2a2f41b6df68 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -451,6 +451,47 @@ int __spi_register_driver(struct module *owner, struct spi_driver *sdrv) { sdrv->driver.owner = owner; sdrv->driver.bus = &spi_bus_type; + + /* + * For Really Good Reasons we use spi: modaliases not of: + * modaliases for DT so module autoloading won't work if we + * don't have a spi_device_id as well as a compatible string. + */ + if (sdrv->driver.of_match_table) { + const struct of_device_id *of_id; + + for (of_id = sdrv->driver.of_match_table; of_id->compatible[0]; + of_id++) { + const char *of_name; + + /* Strip off any vendor prefix */ + of_name = strnchr(of_id->compatible, + sizeof(of_id->compatible), ','); + if (of_name) + of_name++; + else + of_name = of_id->compatible; + + if (sdrv->id_table) { + const struct spi_device_id *spi_id; + + for (spi_id = sdrv->id_table; spi_id->name[0]; + spi_id++) + if (strcmp(spi_id->name, of_name) == 0) + break; + + if (spi_id->name[0]) + continue; + } else { + if (strcmp(sdrv->driver.name, of_name) == 0) + continue; + } + + pr_warn("SPI driver %s has no spi_device_id for %s\n", + sdrv->driver.name, of_id->compatible); + } + } + return driver_register(&sdrv->driver); } EXPORT_SYMBOL_GPL(__spi_register_driver); |