aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/twl4030-core.c300
1 files changed, 84 insertions, 216 deletions
diff --git a/drivers/mfd/twl4030-core.c b/drivers/mfd/twl4030-core.c
index ef9a971e3ead..f5486cce86f4 100644
--- a/drivers/mfd/twl4030-core.c
+++ b/drivers/mfd/twl4030-core.c
@@ -352,258 +352,126 @@ EXPORT_SYMBOL(twl4030_i2c_read_u8);
352 352
353/*----------------------------------------------------------------------*/ 353/*----------------------------------------------------------------------*/
354 354
355/* 355static struct device *add_child(unsigned chip, const char *name,
356 * NOTE: We know the first 8 IRQs after pdata->base_irq are 356 void *pdata, unsigned pdata_len,
357 * for the PIH, and the next are for the PWR_INT SIH, since 357 bool can_wakeup, int irq0, int irq1)
358 * that's how twl_init_irq() sets things up.
359 */
360
361static int add_children(struct twl4030_platform_data *pdata)
362{ 358{
363 struct platform_device *pdev = NULL; 359 struct platform_device *pdev;
364 struct twl4030_client *twl = NULL; 360 struct twl4030_client *twl = &twl4030_modules[chip];
365 int status = 0; 361 int status;
362
363 pdev = platform_device_alloc(name, -1);
364 if (!pdev) {
365 dev_dbg(&twl->client->dev, "can't alloc dev\n");
366 status = -ENOMEM;
367 goto err;
368 }
366 369
367 if (twl_has_bci() && pdata->bci) { 370 device_init_wakeup(&pdev->dev, can_wakeup);
368 twl = &twl4030_modules[3]; 371 pdev->dev.parent = &twl->client->dev;
369 372
370 pdev = platform_device_alloc("twl4030_bci", -1); 373 if (pdata) {
371 if (!pdev) { 374 status = platform_device_add_data(pdev, pdata, pdata_len);
372 pr_debug("%s: can't alloc bci dev\n", DRIVER_NAME); 375 if (status < 0) {
373 status = -ENOMEM; 376 dev_dbg(&pdev->dev, "can't add platform_data\n");
374 goto err; 377 goto err;
375 } 378 }
379 }
376 380
377 if (status == 0) { 381 if (irq0) {
378 pdev->dev.parent = &twl->client->dev; 382 struct resource r[2] = {
379 status = platform_device_add_data(pdev, pdata->bci, 383 { .start = irq0, .flags = IORESOURCE_IRQ, },
380 sizeof(*pdata->bci)); 384 { .start = irq1, .flags = IORESOURCE_IRQ, },
381 if (status < 0) { 385 };
382 dev_dbg(&twl->client->dev,
383 "can't add bci data, %d\n",
384 status);
385 goto err;
386 }
387 }
388
389 if (status == 0) {
390 struct resource r = {
391 .start = pdata->irq_base + 8 + 1,
392 .flags = IORESOURCE_IRQ,
393 };
394
395 status = platform_device_add_resources(pdev, &r, 1);
396 }
397
398 if (status == 0)
399 status = platform_device_add(pdev);
400 386
387 status = platform_device_add_resources(pdev, r, irq1 ? 2 : 1);
401 if (status < 0) { 388 if (status < 0) {
402 platform_device_put(pdev); 389 dev_dbg(&pdev->dev, "can't add irqs\n");
403 dev_dbg(&twl->client->dev,
404 "can't create bci dev, %d\n",
405 status);
406 goto err; 390 goto err;
407 } 391 }
408 } 392 }
409 393
410 if (twl_has_gpio() && pdata->gpio) { 394 status = platform_device_add(pdev);
411 twl = &twl4030_modules[1];
412 395
413 pdev = platform_device_alloc("twl4030_gpio", -1); 396err:
414 if (!pdev) { 397 if (status < 0) {
415 pr_debug("%s: can't alloc gpio dev\n", DRIVER_NAME); 398 platform_device_put(pdev);
416 status = -ENOMEM; 399 dev_err(&twl->client->dev, "can't add %s dev\n", name);
417 goto err; 400 return ERR_PTR(status);
418 } 401 }
419 402 return &pdev->dev;
420 /* more driver model init */ 403}
421 if (status == 0) {
422 pdev->dev.parent = &twl->client->dev;
423 /* device_init_wakeup(&pdev->dev, 1); */
424
425 status = platform_device_add_data(pdev, pdata->gpio,
426 sizeof(*pdata->gpio));
427 if (status < 0) {
428 dev_dbg(&twl->client->dev,
429 "can't add gpio data, %d\n",
430 status);
431 goto err;
432 }
433 }
434 404
435 /* GPIO module IRQ */ 405/*
436 if (status == 0) { 406 * NOTE: We know the first 8 IRQs after pdata->base_irq are
437 struct resource r = { 407 * for the PIH, and the next are for the PWR_INT SIH, since
438 .start = pdata->irq_base + 0, 408 * that's how twl_init_irq() sets things up.
439 .flags = IORESOURCE_IRQ, 409 */
440 };
441 410
442 status = platform_device_add_resources(pdev, &r, 1); 411static int add_children(struct twl4030_platform_data *pdata)
443 } 412{
413 struct device *child;
444 414
445 if (status == 0) 415 if (twl_has_bci() && pdata->bci) {
446 status = platform_device_add(pdev); 416 child = add_child(3, "twl4030_bci",
417 pdata->bci, sizeof(*pdata->bci),
418 false,
419 /* irq0 = CHG_PRES, irq1 = BCI */
420 pdata->irq_base + 8 + 1, pdata->irq_base + 2);
421 if (IS_ERR(child))
422 return PTR_ERR(child);
423 }
447 424
448 if (status < 0) { 425 if (twl_has_gpio() && pdata->gpio) {
449 platform_device_put(pdev); 426 child = add_child(1, "twl4030_gpio",
450 dev_dbg(&twl->client->dev, 427 pdata->gpio, sizeof(*pdata->gpio),
451 "can't create gpio dev, %d\n", 428 false, pdata->irq_base + 0, 0);
452 status); 429 if (IS_ERR(child))
453 goto err; 430 return PTR_ERR(child);
454 }
455 } 431 }
456 432
457 if (twl_has_keypad() && pdata->keypad) { 433 if (twl_has_keypad() && pdata->keypad) {
458 pdev = platform_device_alloc("twl4030_keypad", -1); 434 child = add_child(2, "twl4030_keypad",
459 if (pdev) { 435 pdata->keypad, sizeof(*pdata->keypad),
460 twl = &twl4030_modules[2]; 436 true, pdata->irq_base + 1, 0);
461 pdev->dev.parent = &twl->client->dev; 437 if (IS_ERR(child))
462 device_init_wakeup(&pdev->dev, 1); 438 return PTR_ERR(child);
463 status = platform_device_add_data(pdev, pdata->keypad,
464 sizeof(*pdata->keypad));
465 if (status < 0) {
466 dev_dbg(&twl->client->dev,
467 "can't add keypad data, %d\n",
468 status);
469 platform_device_put(pdev);
470 goto err;
471 }
472 status = platform_device_add(pdev);
473 if (status < 0) {
474 platform_device_put(pdev);
475 dev_dbg(&twl->client->dev,
476 "can't create keypad dev, %d\n",
477 status);
478 goto err;
479 }
480 } else {
481 pr_debug("%s: can't alloc keypad dev\n", DRIVER_NAME);
482 status = -ENOMEM;
483 goto err;
484 }
485 } 439 }
486 440
487 if (twl_has_madc() && pdata->madc) { 441 if (twl_has_madc() && pdata->madc) {
488 pdev = platform_device_alloc("twl4030_madc", -1); 442 child = add_child(2, "twl4030_madc",
489 if (pdev) { 443 pdata->madc, sizeof(*pdata->madc),
490 twl = &twl4030_modules[2]; 444 true, pdata->irq_base + 3, 0);
491 pdev->dev.parent = &twl->client->dev; 445 if (IS_ERR(child))
492 device_init_wakeup(&pdev->dev, 1); 446 return PTR_ERR(child);
493 status = platform_device_add_data(pdev, pdata->madc,
494 sizeof(*pdata->madc));
495 if (status < 0) {
496 platform_device_put(pdev);
497 dev_dbg(&twl->client->dev,
498 "can't add madc data, %d\n",
499 status);
500 goto err;
501 }
502 status = platform_device_add(pdev);
503 if (status < 0) {
504 platform_device_put(pdev);
505 dev_dbg(&twl->client->dev,
506 "can't create madc dev, %d\n",
507 status);
508 goto err;
509 }
510 } else {
511 pr_debug("%s: can't alloc madc dev\n", DRIVER_NAME);
512 status = -ENOMEM;
513 goto err;
514 }
515 } 447 }
516 448
517 if (twl_has_rtc()) { 449 if (twl_has_rtc()) {
518 twl = &twl4030_modules[3];
519
520 pdev = platform_device_alloc("twl4030_rtc", -1);
521 if (!pdev) {
522 pr_debug("%s: can't alloc rtc dev\n", DRIVER_NAME);
523 status = -ENOMEM;
524 } else {
525 pdev->dev.parent = &twl->client->dev;
526 device_init_wakeup(&pdev->dev, 1);
527 }
528
529 /* 450 /*
530 * REVISIT platform_data here currently might use of 451 * REVISIT platform_data here currently might expose the
531 * "msecure" line ... but for now we just expect board 452 * "msecure" line ... but for now we just expect board
532 * setup to tell the chip "we are secure" at all times. 453 * setup to tell the chip "it's always ok to SET_TIME".
533 * Eventually, Linux might become more aware of such 454 * Eventually, Linux might become more aware of such
534 * HW security concerns, and "least privilege". 455 * HW security concerns, and "least privilege".
535 */ 456 */
536 457 child = add_child(3, "twl4030_rtc",
537 /* RTC module IRQ */ 458 NULL, 0,
538 if (status == 0) { 459 true, pdata->irq_base + 8 + 3, 0);
539 struct resource r = { 460 if (IS_ERR(child))
540 .start = pdata->irq_base + 8 + 3, 461 return PTR_ERR(child);
541 .flags = IORESOURCE_IRQ,
542 };
543
544 status = platform_device_add_resources(pdev, &r, 1);
545 }
546
547 if (status == 0)
548 status = platform_device_add(pdev);
549
550 if (status < 0) {
551 platform_device_put(pdev);
552 dev_dbg(&twl->client->dev,
553 "can't create rtc dev, %d\n",
554 status);
555 goto err;
556 }
557 } 462 }
558 463
559 if (twl_has_usb() && pdata->usb) { 464 if (twl_has_usb() && pdata->usb) {
560 twl = &twl4030_modules[0]; 465 child = add_child(0, "twl4030_usb",
561 466 pdata->usb, sizeof(*pdata->usb),
562 pdev = platform_device_alloc("twl4030_usb", -1); 467 true,
563 if (!pdev) { 468 /* irq0 = USB_PRES, irq1 = USB */
564 pr_debug("%s: can't alloc usb dev\n", DRIVER_NAME); 469 pdata->irq_base + 8 + 2, pdata->irq_base + 4);
565 status = -ENOMEM; 470 if (IS_ERR(child))
566 goto err; 471 return PTR_ERR(child);
567 }
568
569 if (status == 0) {
570 pdev->dev.parent = &twl->client->dev;
571 device_init_wakeup(&pdev->dev, 1);
572 status = platform_device_add_data(pdev, pdata->usb,
573 sizeof(*pdata->usb));
574 if (status < 0) {
575 platform_device_put(pdev);
576 dev_dbg(&twl->client->dev,
577 "can't add usb data, %d\n",
578 status);
579 goto err;
580 }
581 }
582
583 if (status == 0) {
584 struct resource r = {
585 .start = pdata->irq_base + 8 + 2,
586 .flags = IORESOURCE_IRQ,
587 };
588
589 status = platform_device_add_resources(pdev, &r, 1);
590 }
591
592 if (status == 0)
593 status = platform_device_add(pdev);
594
595 if (status < 0) {
596 platform_device_put(pdev);
597 dev_dbg(&twl->client->dev,
598 "can't create usb dev, %d\n",
599 status);
600 }
601 } 472 }
602 473
603err: 474 return 0;
604 if (status)
605 pr_err("failed to add twl4030's children (status %d)\n", status);
606 return status;
607} 475}
608 476
609/*----------------------------------------------------------------------*/ 477/*----------------------------------------------------------------------*/