diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-07 10:24:18 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-07 10:24:18 -0700 |
commit | e5744abb2fa3629aa5a94e21ca1eae32ff2fe00b (patch) | |
tree | ef90c96390256b073f5255d224aecb2fc1f6ee84 /drivers/mfd/tc3589x.c | |
parent | c29aa153ef0469cddf0146d41ce6494bd76be78b (diff) | |
parent | 2d28ca731b9bb6262f7711241628c7844b0cf7dc (diff) |
Merge tag 'mfd-for-linus-3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
Pull MFD updates from Lee Jones:
"Changes to existing drivers:
- Use of managed resources - omap, twl4030, ti_am335x_tscadc
- Advanced error handling - omap
- Rework clk management - omap
- Device Tree (re-)work - tc3589x, pm8921, da9055, sec
- IRC management overhaul and !BROKEN - pm8921
- Convert to regmap - ssbi, pm8921
- Use simple power-management ops - ucb1x00
- Include file clean-up - adp5520, cs5535, janz, lpc_ich,
- lpc_sch, max14577, mcp-sa11x0, pcf50633-adc, rc5t583,
rdc321x-southbridge, retu, smsc-ece1099, ti-ssp, ti_am335x_tscadc,
tps65912, vexpress-config, wm8350, ywm8350
- Various bug fixes across the subsystem
- NULL/invalid pointer dereference prevention
- Resource leak mitigation,
- Variable used initialised
- Staticise various containers
- Enforce return value checks
New drivers/supported devices:
- Add support for s2mps14 and s2mpa01 to sec
- Add support for da9063 (v5) to da9063
- Add support for atom-c2000 to gpio-ich
- Add support for come-{mbt10,cbt6,chl6} to kempld
- Add support for da9053 to da9052
- Add support for itco-wdt (v3) and baytrail to lpc_ich
- Add new drivers for tps65218, rtsx_usb, bcm590xx
(Re-)moved drivers:
- twl4030 ==> drivers/iio
- ti-ssp ==> /dev/null"
* tag 'mfd-for-linus-3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (103 commits)
mfd: wm5110: Correct default for HEADPHONE_DETECT_1
mfd: arizona: Correct small errors in the DT binding documentation
mfd: arizona: Mark DSP clocking register as volatile
mfd: devicetree: bindings: Add pm8xxx RTC description
mfd: kempld-core: Fix potential hang-up during boot
mfd: sec-core: Fix uninitialized 'regmap_rtc' on S2MPA01
mfd: tps65910: Fix regmap_irq_chip_data leak on mfd_add_devices fail
mfd: tps65910: Fix possible invalid pointer dereference on regmap_add_irq_chip fail
mfd: sec-core: Fix I2C dummy device resource leak on probe failure
mfd: sec-core: Add of_compatible strings for clock MFD cells
mfd: Remove obsolete ti-ssp driver
Documentation: mfd: s2mps11: Describe S5M8767 and S2MPS14 clocks
mfd: bcm590xx: Fix type argument for module device table
mfd: lpc_ich: Add support for Intel Bay Trail SoC
mfd: lpc_ich: Add support for NM10 GPIO
mfd: lpc_ich: Change Avoton to iTCO v3
watchdog: iTCO_wdt: Add support for v3 silicon
mfd: lpc_ich: Add support for iTCO v3
mfd: lpc_ich: Remove lpc_ich_cfg struct use
mfd: lpc_ich: Only configure watchdog or GPIO when present
...
Diffstat (limited to 'drivers/mfd/tc3589x.c')
-rw-r--r-- | drivers/mfd/tc3589x.c | 84 |
1 files changed, 59 insertions, 25 deletions
diff --git a/drivers/mfd/tc3589x.c b/drivers/mfd/tc3589x.c index 2cf636c267d..bd83accc0f6 100644 --- a/drivers/mfd/tc3589x.c +++ b/drivers/mfd/tc3589x.c @@ -13,8 +13,10 @@ #include <linux/slab.h> #include <linux/i2c.h> #include <linux/of.h> +#include <linux/of_device.h> #include <linux/mfd/core.h> #include <linux/mfd/tc3589x.h> +#include <linux/err.h> /** * enum tc3589x_version - indicates the TC3589x version @@ -160,7 +162,7 @@ static const struct mfd_cell tc3589x_dev_gpio[] = { .name = "tc3589x-gpio", .num_resources = ARRAY_SIZE(gpio_resources), .resources = &gpio_resources[0], - .of_compatible = "tc3589x-gpio", + .of_compatible = "toshiba,tc3589x-gpio", }, }; @@ -169,7 +171,7 @@ static const struct mfd_cell tc3589x_dev_keypad[] = { .name = "tc3589x-keypad", .num_resources = ARRAY_SIZE(keypad_resources), .resources = &keypad_resources[0], - .of_compatible = "tc3589x-keypad", + .of_compatible = "toshiba,tc3589x-keypad", }, }; @@ -318,45 +320,74 @@ static int tc3589x_device_init(struct tc3589x *tc3589x) return ret; } -static int tc3589x_of_probe(struct device_node *np, - struct tc3589x_platform_data *pdata) +#ifdef CONFIG_OF +static const struct of_device_id tc3589x_match[] = { + /* Legacy compatible string */ + { .compatible = "tc3589x", .data = (void *) TC3589X_UNKNOWN }, + { .compatible = "toshiba,tc35890", .data = (void *) TC3589X_TC35890 }, + { .compatible = "toshiba,tc35892", .data = (void *) TC3589X_TC35892 }, + { .compatible = "toshiba,tc35893", .data = (void *) TC3589X_TC35893 }, + { .compatible = "toshiba,tc35894", .data = (void *) TC3589X_TC35894 }, + { .compatible = "toshiba,tc35895", .data = (void *) TC3589X_TC35895 }, + { .compatible = "toshiba,tc35896", .data = (void *) TC3589X_TC35896 }, + { } +}; + +MODULE_DEVICE_TABLE(of, tc3589x_match); + +static struct tc3589x_platform_data * +tc3589x_of_probe(struct device *dev, enum tc3589x_version *version) { + struct device_node *np = dev->of_node; + struct tc3589x_platform_data *pdata; struct device_node *child; + const struct of_device_id *of_id; + + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return ERR_PTR(-ENOMEM); + + of_id = of_match_device(tc3589x_match, dev); + if (!of_id) + return ERR_PTR(-ENODEV); + *version = (enum tc3589x_version) of_id->data; for_each_child_of_node(np, child) { - if (!strcmp(child->name, "tc3589x_gpio")) { + if (of_device_is_compatible(child, "toshiba,tc3589x-gpio")) pdata->block |= TC3589x_BLOCK_GPIO; - } - if (!strcmp(child->name, "tc3589x_keypad")) { + if (of_device_is_compatible(child, "toshiba,tc3589x-keypad")) pdata->block |= TC3589x_BLOCK_KEYPAD; - } } - return 0; + return pdata; } +#else +static inline struct tc3589x_platform_data * +tc3589x_of_probe(struct device *dev, enum tc3589x_version *version) +{ + dev_err(dev, "no device tree support\n"); + return ERR_PTR(-ENODEV); +} +#endif static int tc3589x_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { - struct tc3589x_platform_data *pdata = dev_get_platdata(&i2c->dev); struct device_node *np = i2c->dev.of_node; + struct tc3589x_platform_data *pdata = dev_get_platdata(&i2c->dev); struct tc3589x *tc3589x; + enum tc3589x_version version; int ret; if (!pdata) { - if (np) { - pdata = devm_kzalloc(&i2c->dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) - return -ENOMEM; - - ret = tc3589x_of_probe(np, pdata); - if (ret) - return ret; - } - else { + pdata = tc3589x_of_probe(&i2c->dev, &version); + if (IS_ERR(pdata)) { dev_err(&i2c->dev, "No platform data or DT found\n"); - return -EINVAL; + return PTR_ERR(pdata); } + } else { + /* When not probing from device tree we have this ID */ + version = id->driver_data; } if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA @@ -375,7 +406,7 @@ static int tc3589x_probe(struct i2c_client *i2c, tc3589x->pdata = pdata; tc3589x->irq_base = pdata->irq_base; - switch (id->driver_data) { + switch (version) { case TC3589X_TC35893: case TC3589X_TC35895: case TC3589X_TC35896: @@ -471,9 +502,12 @@ static const struct i2c_device_id tc3589x_id[] = { MODULE_DEVICE_TABLE(i2c, tc3589x_id); static struct i2c_driver tc3589x_driver = { - .driver.name = "tc3589x", - .driver.owner = THIS_MODULE, - .driver.pm = &tc3589x_dev_pm_ops, + .driver = { + .name = "tc3589x", + .owner = THIS_MODULE, + .pm = &tc3589x_dev_pm_ops, + .of_match_table = of_match_ptr(tc3589x_match), + }, .probe = tc3589x_probe, .remove = tc3589x_remove, .id_table = tc3589x_id, |