| .. | .. |
|---|
| 2 | 2 | /* |
|---|
| 3 | 3 | * twl6030_usb - TWL6030 USB transceiver, talking to OMAP OTG driver. |
|---|
| 4 | 4 | * |
|---|
| 5 | | - * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com |
|---|
| 5 | + * Copyright (C) 2010 Texas Instruments Incorporated - https://www.ti.com |
|---|
| 6 | 6 | * |
|---|
| 7 | 7 | * Author: Hema HK <hemahk@ti.com> |
|---|
| 8 | 8 | */ |
|---|
| .. | .. |
|---|
| 196 | 196 | } |
|---|
| 197 | 197 | static DEVICE_ATTR_RO(vbus); |
|---|
| 198 | 198 | |
|---|
| 199 | +static struct attribute *twl6030_attrs[] = { |
|---|
| 200 | + &dev_attr_vbus.attr, |
|---|
| 201 | + NULL, |
|---|
| 202 | +}; |
|---|
| 203 | +ATTRIBUTE_GROUPS(twl6030); |
|---|
| 204 | + |
|---|
| 199 | 205 | static irqreturn_t twl6030_usb_irq(int irq, void *_twl) |
|---|
| 200 | 206 | { |
|---|
| 201 | 207 | struct twl6030_usb *twl = _twl; |
|---|
| .. | .. |
|---|
| 366 | 372 | } |
|---|
| 367 | 373 | |
|---|
| 368 | 374 | platform_set_drvdata(pdev, twl); |
|---|
| 369 | | - if (device_create_file(&pdev->dev, &dev_attr_vbus)) |
|---|
| 370 | | - dev_warn(&pdev->dev, "could not create sysfs file\n"); |
|---|
| 371 | 375 | |
|---|
| 372 | 376 | INIT_WORK(&twl->set_vbus_work, otg_set_vbus_work); |
|---|
| 373 | 377 | INIT_DELAYED_WORK(&twl->get_status_work, twl6030_status_work); |
|---|
| .. | .. |
|---|
| 378 | 382 | if (status < 0) { |
|---|
| 379 | 383 | dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", |
|---|
| 380 | 384 | twl->irq1, status); |
|---|
| 381 | | - device_remove_file(twl->dev, &dev_attr_vbus); |
|---|
| 382 | | - return status; |
|---|
| 385 | + goto err_put_regulator; |
|---|
| 383 | 386 | } |
|---|
| 384 | 387 | |
|---|
| 385 | 388 | status = request_threaded_irq(twl->irq2, NULL, twl6030_usb_irq, |
|---|
| .. | .. |
|---|
| 388 | 391 | if (status < 0) { |
|---|
| 389 | 392 | dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", |
|---|
| 390 | 393 | twl->irq2, status); |
|---|
| 391 | | - free_irq(twl->irq1, twl); |
|---|
| 392 | | - device_remove_file(twl->dev, &dev_attr_vbus); |
|---|
| 393 | | - return status; |
|---|
| 394 | + goto err_free_irq1; |
|---|
| 394 | 395 | } |
|---|
| 395 | 396 | |
|---|
| 396 | 397 | twl->asleep = 0; |
|---|
| .. | .. |
|---|
| 399 | 400 | dev_info(&pdev->dev, "Initialized TWL6030 USB module\n"); |
|---|
| 400 | 401 | |
|---|
| 401 | 402 | return 0; |
|---|
| 403 | + |
|---|
| 404 | +err_free_irq1: |
|---|
| 405 | + free_irq(twl->irq1, twl); |
|---|
| 406 | +err_put_regulator: |
|---|
| 407 | + regulator_put(twl->usb3v3); |
|---|
| 408 | + |
|---|
| 409 | + return status; |
|---|
| 402 | 410 | } |
|---|
| 403 | 411 | |
|---|
| 404 | 412 | static int twl6030_usb_remove(struct platform_device *pdev) |
|---|
| .. | .. |
|---|
| 413 | 421 | free_irq(twl->irq1, twl); |
|---|
| 414 | 422 | free_irq(twl->irq2, twl); |
|---|
| 415 | 423 | regulator_put(twl->usb3v3); |
|---|
| 416 | | - device_remove_file(twl->dev, &dev_attr_vbus); |
|---|
| 417 | 424 | cancel_work_sync(&twl->set_vbus_work); |
|---|
| 418 | 425 | |
|---|
| 419 | 426 | return 0; |
|---|
| .. | .. |
|---|
| 431 | 438 | .driver = { |
|---|
| 432 | 439 | .name = "twl6030_usb", |
|---|
| 433 | 440 | .of_match_table = of_match_ptr(twl6030_usb_id_table), |
|---|
| 441 | + .dev_groups = twl6030_groups, |
|---|
| 434 | 442 | }, |
|---|
| 435 | 443 | }; |
|---|
| 436 | 444 | |
|---|