diff options
author | Haojian Zhuang <haojian.zhuang@gmail.com> | 2012-09-21 06:06:52 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2012-10-02 05:43:13 -0400 |
commit | 2e57d56747e601b3e0ff6697e524025d0504d161 (patch) | |
tree | 29a7c677878d39f64e90dfbdf7063a11c08d4c15 /drivers/mfd/88pm860x-core.c | |
parent | 837c8293ba24d08cd7438d82ad9bb8d2fb0f8a5b (diff) |
mfd: 88pm860x: Device tree support
Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd/88pm860x-core.c')
-rw-r--r-- | drivers/mfd/88pm860x-core.c | 62 |
1 files changed, 53 insertions, 9 deletions
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c index 5b56fe8250b4..fdaf6861ce95 100644 --- a/drivers/mfd/88pm860x-core.c +++ b/drivers/mfd/88pm860x-core.c | |||
@@ -16,6 +16,8 @@ | |||
16 | #include <linux/irq.h> | 16 | #include <linux/irq.h> |
17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
18 | #include <linux/irqdomain.h> | 18 | #include <linux/irqdomain.h> |
19 | #include <linux/of.h> | ||
20 | #include <linux/of_platform.h> | ||
19 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
20 | #include <linux/regmap.h> | 22 | #include <linux/regmap.h> |
21 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
@@ -1112,12 +1114,6 @@ static void __devexit pm860x_device_exit(struct pm860x_chip *chip) | |||
1112 | mfd_remove_devices(chip->dev); | 1114 | mfd_remove_devices(chip->dev); |
1113 | } | 1115 | } |
1114 | 1116 | ||
1115 | static const struct i2c_device_id pm860x_id_table[] = { | ||
1116 | { "88PM860x", 0 }, | ||
1117 | {} | ||
1118 | }; | ||
1119 | MODULE_DEVICE_TABLE(i2c, pm860x_id_table); | ||
1120 | |||
1121 | static int verify_addr(struct i2c_client *i2c) | 1117 | static int verify_addr(struct i2c_client *i2c) |
1122 | { | 1118 | { |
1123 | unsigned short addr_8607[] = {0x30, 0x34}; | 1119 | unsigned short addr_8607[] = {0x30, 0x34}; |
@@ -1144,21 +1140,52 @@ static struct regmap_config pm860x_regmap_config = { | |||
1144 | .val_bits = 8, | 1140 | .val_bits = 8, |
1145 | }; | 1141 | }; |
1146 | 1142 | ||
1143 | static int __devinit pm860x_dt_init(struct device_node *np, | ||
1144 | struct device *dev, | ||
1145 | struct pm860x_platform_data *pdata) | ||
1146 | { | ||
1147 | int ret; | ||
1148 | |||
1149 | if (of_get_property(np, "marvell,88pm860x-irq-read-clr", NULL)) | ||
1150 | pdata->irq_mode = 1; | ||
1151 | ret = of_property_read_u32(np, "marvell,88pm860x-slave-addr", | ||
1152 | &pdata->companion_addr); | ||
1153 | if (ret) { | ||
1154 | dev_err(dev, "Not found \"marvell,88pm860x-slave-addr\" " | ||
1155 | "property\n"); | ||
1156 | pdata->companion_addr = 0; | ||
1157 | } | ||
1158 | return 0; | ||
1159 | } | ||
1160 | |||
1147 | static int __devinit pm860x_probe(struct i2c_client *client, | 1161 | static int __devinit pm860x_probe(struct i2c_client *client, |
1148 | const struct i2c_device_id *id) | 1162 | const struct i2c_device_id *id) |
1149 | { | 1163 | { |
1150 | struct pm860x_platform_data *pdata = client->dev.platform_data; | 1164 | struct pm860x_platform_data *pdata = client->dev.platform_data; |
1165 | struct device_node *node = client->dev.of_node; | ||
1151 | struct pm860x_chip *chip; | 1166 | struct pm860x_chip *chip; |
1152 | int ret; | 1167 | int ret; |
1153 | 1168 | ||
1154 | if (!pdata) { | 1169 | if (node && !pdata) { |
1170 | /* parse DT to get platform data */ | ||
1171 | pdata = devm_kzalloc(&client->dev, | ||
1172 | sizeof(struct pm860x_platform_data), | ||
1173 | GFP_KERNEL); | ||
1174 | if (!pdata) | ||
1175 | return -ENOMEM; | ||
1176 | ret = pm860x_dt_init(node, &client->dev, pdata); | ||
1177 | if (ret) | ||
1178 | goto err; | ||
1179 | } else if (!pdata) { | ||
1155 | pr_info("No platform data in %s!\n", __func__); | 1180 | pr_info("No platform data in %s!\n", __func__); |
1156 | return -EINVAL; | 1181 | return -EINVAL; |
1157 | } | 1182 | } |
1158 | 1183 | ||
1159 | chip = kzalloc(sizeof(struct pm860x_chip), GFP_KERNEL); | 1184 | chip = kzalloc(sizeof(struct pm860x_chip), GFP_KERNEL); |
1160 | if (chip == NULL) | 1185 | if (chip == NULL) { |
1161 | return -ENOMEM; | 1186 | ret = -ENOMEM; |
1187 | goto err; | ||
1188 | } | ||
1162 | 1189 | ||
1163 | chip->id = verify_addr(client); | 1190 | chip->id = verify_addr(client); |
1164 | chip->regmap = regmap_init_i2c(client, &pm860x_regmap_config); | 1191 | chip->regmap = regmap_init_i2c(client, &pm860x_regmap_config); |
@@ -1198,6 +1225,10 @@ static int __devinit pm860x_probe(struct i2c_client *client, | |||
1198 | 1225 | ||
1199 | pm860x_device_init(chip, pdata); | 1226 | pm860x_device_init(chip, pdata); |
1200 | return 0; | 1227 | return 0; |
1228 | err: | ||
1229 | if (node) | ||
1230 | devm_kfree(&client->dev, pdata); | ||
1231 | return ret; | ||
1201 | } | 1232 | } |
1202 | 1233 | ||
1203 | static int __devexit pm860x_remove(struct i2c_client *client) | 1234 | static int __devexit pm860x_remove(struct i2c_client *client) |
@@ -1238,11 +1269,24 @@ static int pm860x_resume(struct device *dev) | |||
1238 | 1269 | ||
1239 | static SIMPLE_DEV_PM_OPS(pm860x_pm_ops, pm860x_suspend, pm860x_resume); | 1270 | static SIMPLE_DEV_PM_OPS(pm860x_pm_ops, pm860x_suspend, pm860x_resume); |
1240 | 1271 | ||
1272 | static const struct i2c_device_id pm860x_id_table[] = { | ||
1273 | { "88PM860x", 0 }, | ||
1274 | {} | ||
1275 | }; | ||
1276 | MODULE_DEVICE_TABLE(i2c, pm860x_id_table); | ||
1277 | |||
1278 | static const struct of_device_id pm860x_dt_ids[] = { | ||
1279 | { .compatible = "marvell,88pm860x", }, | ||
1280 | {}, | ||
1281 | }; | ||
1282 | MODULE_DEVICE_TABLE(of, pm860x_dt_ids); | ||
1283 | |||
1241 | static struct i2c_driver pm860x_driver = { | 1284 | static struct i2c_driver pm860x_driver = { |
1242 | .driver = { | 1285 | .driver = { |
1243 | .name = "88PM860x", | 1286 | .name = "88PM860x", |
1244 | .owner = THIS_MODULE, | 1287 | .owner = THIS_MODULE, |
1245 | .pm = &pm860x_pm_ops, | 1288 | .pm = &pm860x_pm_ops, |
1289 | .of_match_table = of_match_ptr(pm860x_dt_ids), | ||
1246 | }, | 1290 | }, |
1247 | .probe = pm860x_probe, | 1291 | .probe = pm860x_probe, |
1248 | .remove = __devexit_p(pm860x_remove), | 1292 | .remove = __devexit_p(pm860x_remove), |