| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * twl4030_usb - TWL4030 USB transceiver, talking to OMAP OTG controller |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2004-2007 Texas Instruments |
|---|
| 5 | 6 | * Copyright (C) 2008 Nokia Corporation |
|---|
| 6 | 7 | * Contact: Felipe Balbi <felipe.balbi@nokia.com> |
|---|
| 7 | | - * |
|---|
| 8 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 9 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 10 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 11 | | - * (at your option) any later version. |
|---|
| 12 | | - * |
|---|
| 13 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 14 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 15 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 16 | | - * GNU General Public License for more details. |
|---|
| 17 | | - * |
|---|
| 18 | | - * You should have received a copy of the GNU General Public License |
|---|
| 19 | | - * along with this program; if not, write to the Free Software |
|---|
| 20 | | - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
|---|
| 21 | 8 | * |
|---|
| 22 | 9 | * Current status: |
|---|
| 23 | 10 | * - HS USB ULPI mode works. |
|---|
| .. | .. |
|---|
| 172 | 159 | |
|---|
| 173 | 160 | int irq; |
|---|
| 174 | 161 | enum musb_vbus_id_status linkstat; |
|---|
| 162 | + atomic_t connected; |
|---|
| 175 | 163 | bool vbus_supplied; |
|---|
| 176 | 164 | bool musb_mailbox_pending; |
|---|
| 177 | 165 | |
|---|
| .. | .. |
|---|
| 575 | 563 | { |
|---|
| 576 | 564 | struct twl4030_usb *twl = _twl; |
|---|
| 577 | 565 | enum musb_vbus_id_status status; |
|---|
| 578 | | - bool status_changed = false; |
|---|
| 579 | 566 | int err; |
|---|
| 580 | 567 | |
|---|
| 581 | 568 | status = twl4030_usb_linkstat(twl); |
|---|
| 582 | 569 | |
|---|
| 583 | 570 | mutex_lock(&twl->lock); |
|---|
| 584 | | - if (status >= 0 && status != twl->linkstat) { |
|---|
| 585 | | - status_changed = |
|---|
| 586 | | - cable_present(twl->linkstat) != |
|---|
| 587 | | - cable_present(status); |
|---|
| 588 | | - twl->linkstat = status; |
|---|
| 589 | | - } |
|---|
| 571 | + twl->linkstat = status; |
|---|
| 590 | 572 | mutex_unlock(&twl->lock); |
|---|
| 591 | 573 | |
|---|
| 592 | | - if (status_changed) { |
|---|
| 593 | | - /* FIXME add a set_power() method so that B-devices can |
|---|
| 594 | | - * configure the charger appropriately. It's not always |
|---|
| 595 | | - * correct to consume VBUS power, and how much current to |
|---|
| 596 | | - * consume is a function of the USB configuration chosen |
|---|
| 597 | | - * by the host. |
|---|
| 598 | | - * |
|---|
| 599 | | - * REVISIT usb_gadget_vbus_connect(...) as needed, ditto |
|---|
| 600 | | - * its disconnect() sibling, when changing to/from the |
|---|
| 601 | | - * USB_LINK_VBUS state. musb_hdrc won't care until it |
|---|
| 602 | | - * starts to handle softconnect right. |
|---|
| 603 | | - */ |
|---|
| 604 | | - if (cable_present(status)) { |
|---|
| 574 | + if (cable_present(status)) { |
|---|
| 575 | + if (atomic_add_unless(&twl->connected, 1, 1)) { |
|---|
| 576 | + dev_dbg(twl->dev, "%s: cable connected %i\n", |
|---|
| 577 | + __func__, status); |
|---|
| 605 | 578 | pm_runtime_get_sync(twl->dev); |
|---|
| 606 | | - } else { |
|---|
| 579 | + twl->musb_mailbox_pending = true; |
|---|
| 580 | + } |
|---|
| 581 | + } else { |
|---|
| 582 | + if (atomic_add_unless(&twl->connected, -1, 0)) { |
|---|
| 583 | + dev_dbg(twl->dev, "%s: cable disconnected %i\n", |
|---|
| 584 | + __func__, status); |
|---|
| 607 | 585 | pm_runtime_mark_last_busy(twl->dev); |
|---|
| 608 | 586 | pm_runtime_put_autosuspend(twl->dev); |
|---|
| 587 | + twl->musb_mailbox_pending = true; |
|---|
| 609 | 588 | } |
|---|
| 610 | | - twl->musb_mailbox_pending = true; |
|---|
| 611 | 589 | } |
|---|
| 612 | 590 | if (twl->musb_mailbox_pending) { |
|---|
| 613 | 591 | err = musb_mailbox(status); |
|---|