aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/arm/msm/ssbi.txt18
-rw-r--r--arch/arm/boot/dts/msm8660-surf.dts6
-rw-r--r--arch/arm/boot/dts/msm8960-cdp.dts6
-rw-r--r--drivers/ssbi/ssbi.c81
4 files changed, 62 insertions, 49 deletions
diff --git a/Documentation/devicetree/bindings/arm/msm/ssbi.txt b/Documentation/devicetree/bindings/arm/msm/ssbi.txt
new file mode 100644
index 000000000000..54fd5ced3401
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/ssbi.txt
@@ -0,0 +1,18 @@
1* Qualcomm SSBI
2
3Some Qualcomm MSM devices contain a point-to-point serial bus used to
4communicate with a limited range of devices (mostly power management
5chips).
6
7These require the following properties:
8
9- compatible: "qcom,ssbi"
10
11- qcom,controller-type
12 indicates the SSBI bus variant the controller should use to talk
13 with the slave device. This should be one of "ssbi", "ssbi2", or
14 "pmic-arbiter". The type chosen is determined by the attached
15 slave.
16
17The slave device should be the single child node of the ssbi device
18with a compatible field.
diff --git a/arch/arm/boot/dts/msm8660-surf.dts b/arch/arm/boot/dts/msm8660-surf.dts
index 31f2157cd7d7..67f8670c4d6a 100644
--- a/arch/arm/boot/dts/msm8660-surf.dts
+++ b/arch/arm/boot/dts/msm8660-surf.dts
@@ -38,4 +38,10 @@
38 <0x19c00000 0x1000>; 38 <0x19c00000 0x1000>;
39 interrupts = <0 195 0x0>; 39 interrupts = <0 195 0x0>;
40 }; 40 };
41
42 qcom,ssbi@500000 {
43 compatible = "qcom,ssbi";
44 reg = <0x500000 0x1000>;
45 qcom,controller-type = "pmic-arbiter";
46 };
41}; 47};
diff --git a/arch/arm/boot/dts/msm8960-cdp.dts b/arch/arm/boot/dts/msm8960-cdp.dts
index 9e621b5ad3dd..c9b09a813a4b 100644
--- a/arch/arm/boot/dts/msm8960-cdp.dts
+++ b/arch/arm/boot/dts/msm8960-cdp.dts
@@ -38,4 +38,10 @@
38 <0x16400000 0x1000>; 38 <0x16400000 0x1000>;
39 interrupts = <0 154 0x0>; 39 interrupts = <0 154 0x0>;
40 }; 40 };
41
42 qcom,ssbi@500000 {
43 compatible = "qcom,ssbi";
44 reg = <0x500000 0x1000>;
45 qcom,controller-type = "pmic-arbiter";
46 };
41}; 47};
diff --git a/drivers/ssbi/ssbi.c b/drivers/ssbi/ssbi.c
index da086d49d35c..6fbcb25907ff 100644
--- a/drivers/ssbi/ssbi.c
+++ b/drivers/ssbi/ssbi.c
@@ -26,6 +26,8 @@
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/msm_ssbi.h> 27#include <linux/msm_ssbi.h>
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/of.h>
30#include <linux/of_device.h>
29 31
30/* SSBI 2.0 controller registers */ 32/* SSBI 2.0 controller registers */
31#define SSBI2_CMD 0x0008 33#define SSBI2_CMD 0x0008
@@ -261,56 +263,13 @@ int msm_ssbi_write(struct device *dev, u16 addr, u8 *buf, int len)
261} 263}
262EXPORT_SYMBOL_GPL(msm_ssbi_write); 264EXPORT_SYMBOL_GPL(msm_ssbi_write);
263 265
264static int msm_ssbi_add_slave(struct msm_ssbi *ssbi,
265 const struct msm_ssbi_slave_info *slave)
266{
267 struct platform_device *slave_pdev;
268 int ret;
269
270 if (ssbi->slave) {
271 pr_err("slave already attached??\n");
272 return -EBUSY;
273 }
274
275 slave_pdev = platform_device_alloc(slave->name, -1);
276 if (!slave_pdev) {
277 pr_err("cannot allocate pdev for slave '%s'", slave->name);
278 ret = -ENOMEM;
279 goto err;
280 }
281
282 slave_pdev->dev.parent = ssbi->dev;
283 slave_pdev->dev.platform_data = slave->platform_data;
284
285 ret = platform_device_add(slave_pdev);
286 if (ret) {
287 pr_err("cannot add slave platform device for '%s'\n",
288 slave->name);
289 goto err;
290 }
291
292 ssbi->slave = &slave_pdev->dev;
293 return 0;
294
295err:
296 if (slave_pdev)
297 platform_device_put(slave_pdev);
298 return ret;
299}
300
301static int msm_ssbi_probe(struct platform_device *pdev) 266static int msm_ssbi_probe(struct platform_device *pdev)
302{ 267{
303 const struct msm_ssbi_platform_data *pdata = pdev->dev.platform_data; 268 struct device_node *np = pdev->dev.of_node;
304 struct resource *mem_res; 269 struct resource *mem_res;
305 struct msm_ssbi *ssbi; 270 struct msm_ssbi *ssbi;
306 int ret = 0; 271 int ret = 0;
307 272 const char *type;
308 if (!pdata) {
309 pr_err("missing platform data\n");
310 return -EINVAL;
311 }
312
313 pr_debug("%s\n", pdata->slave.name);
314 273
315 ssbi = kzalloc(sizeof(struct msm_ssbi), GFP_KERNEL); 274 ssbi = kzalloc(sizeof(struct msm_ssbi), GFP_KERNEL);
316 if (!ssbi) { 275 if (!ssbi) {
@@ -334,7 +293,25 @@ static int msm_ssbi_probe(struct platform_device *pdev)
334 ssbi->dev = &pdev->dev; 293 ssbi->dev = &pdev->dev;
335 platform_set_drvdata(pdev, ssbi); 294 platform_set_drvdata(pdev, ssbi);
336 295
337 ssbi->controller_type = pdata->controller_type; 296 type = of_get_property(np, "qcom,controller-type", NULL);
297 if (type == NULL) {
298 pr_err("Missing qcom,controller-type property\n");
299 ret = -EINVAL;
300 goto err_ssbi_controller;
301 }
302 dev_info(&pdev->dev, "SSBI controller type: '%s'\n", type);
303 if (strcmp(type, "ssbi") == 0)
304 ssbi->controller_type = MSM_SBI_CTRL_SSBI;
305 else if (strcmp(type, "ssbi2") == 0)
306 ssbi->controller_type = MSM_SBI_CTRL_SSBI2;
307 else if (strcmp(type, "pmic-arbiter") == 0)
308 ssbi->controller_type = MSM_SBI_CTRL_PMIC_ARBITER;
309 else {
310 pr_err("Unknown qcom,controller-type\n");
311 ret = -EINVAL;
312 goto err_ssbi_controller;
313 }
314
338 if (ssbi->controller_type == MSM_SBI_CTRL_PMIC_ARBITER) { 315 if (ssbi->controller_type == MSM_SBI_CTRL_PMIC_ARBITER) {
339 ssbi->read = msm_ssbi_pa_read_bytes; 316 ssbi->read = msm_ssbi_pa_read_bytes;
340 ssbi->write = msm_ssbi_pa_write_bytes; 317 ssbi->write = msm_ssbi_pa_write_bytes;
@@ -345,13 +322,13 @@ static int msm_ssbi_probe(struct platform_device *pdev)
345 322
346 spin_lock_init(&ssbi->lock); 323 spin_lock_init(&ssbi->lock);
347 324
348 ret = msm_ssbi_add_slave(ssbi, &pdata->slave); 325 ret = of_platform_populate(np, NULL, NULL, &pdev->dev);
349 if (ret) 326 if (ret)
350 goto err_ssbi_add_slave; 327 goto err_ssbi_controller;
351 328
352 return 0; 329 return 0;
353 330
354err_ssbi_add_slave: 331err_ssbi_controller:
355 platform_set_drvdata(pdev, NULL); 332 platform_set_drvdata(pdev, NULL);
356 iounmap(ssbi->base); 333 iounmap(ssbi->base);
357err_ioremap: 334err_ioremap:
@@ -370,12 +347,18 @@ static int msm_ssbi_remove(struct platform_device *pdev)
370 return 0; 347 return 0;
371} 348}
372 349
350static struct of_device_id ssbi_match_table[] = {
351 { .compatible = "qcom,ssbi" },
352 {}
353};
354
373static struct platform_driver msm_ssbi_driver = { 355static struct platform_driver msm_ssbi_driver = {
374 .probe = msm_ssbi_probe, 356 .probe = msm_ssbi_probe,
375 .remove = msm_ssbi_remove, 357 .remove = msm_ssbi_remove,
376 .driver = { 358 .driver = {
377 .name = "msm_ssbi", 359 .name = "msm_ssbi",
378 .owner = THIS_MODULE, 360 .owner = THIS_MODULE,
361 .of_match_table = ssbi_match_table,
379 }, 362 },
380}; 363};
381 364