usb: musb: twl: use mailbox API to send VBUS or ID events
The atomic notifier from twl4030/twl6030 to notifiy VBUS and ID events, is replaced by a direct call to omap musb blue. Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
This commit is contained in:

committed by
Felipe Balbi

parent
1e5acb8d61
commit
c9721438c0
@@ -33,11 +33,11 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/usb/otg.h>
|
||||
#include <linux/usb/musb-omap.h>
|
||||
#include <linux/usb/ulpi.h>
|
||||
#include <linux/i2c/twl.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
/* Register defines */
|
||||
@@ -159,7 +159,7 @@ struct twl4030_usb {
|
||||
enum twl4030_usb_mode usb_mode;
|
||||
|
||||
int irq;
|
||||
u8 linkstat;
|
||||
enum omap_musb_vbus_id_status linkstat;
|
||||
bool vbus_supplied;
|
||||
u8 asleep;
|
||||
bool irq_enabled;
|
||||
@@ -246,10 +246,11 @@ twl4030_usb_clear_bits(struct twl4030_usb *twl, u8 reg, u8 bits)
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static enum usb_phy_events twl4030_usb_linkstat(struct twl4030_usb *twl)
|
||||
static enum omap_musb_vbus_id_status
|
||||
twl4030_usb_linkstat(struct twl4030_usb *twl)
|
||||
{
|
||||
int status;
|
||||
int linkstat = USB_EVENT_NONE;
|
||||
enum omap_musb_vbus_id_status linkstat = OMAP_MUSB_UNKNOWN;
|
||||
struct usb_otg *otg = twl->phy.otg;
|
||||
|
||||
twl->vbus_supplied = false;
|
||||
@@ -273,24 +274,24 @@ static enum usb_phy_events twl4030_usb_linkstat(struct twl4030_usb *twl)
|
||||
twl->vbus_supplied = true;
|
||||
|
||||
if (status & BIT(2))
|
||||
linkstat = USB_EVENT_ID;
|
||||
linkstat = OMAP_MUSB_ID_GROUND;
|
||||
else
|
||||
linkstat = USB_EVENT_VBUS;
|
||||
} else
|
||||
linkstat = USB_EVENT_NONE;
|
||||
linkstat = OMAP_MUSB_VBUS_VALID;
|
||||
} else {
|
||||
if (twl->linkstat != OMAP_MUSB_UNKNOWN)
|
||||
linkstat = OMAP_MUSB_VBUS_OFF;
|
||||
}
|
||||
|
||||
dev_dbg(twl->dev, "HW_CONDITIONS 0x%02x/%d; link %d\n",
|
||||
status, status, linkstat);
|
||||
|
||||
twl->phy.last_event = linkstat;
|
||||
|
||||
/* REVISIT this assumes host and peripheral controllers
|
||||
* are registered, and that both are active...
|
||||
*/
|
||||
|
||||
spin_lock_irq(&twl->lock);
|
||||
twl->linkstat = linkstat;
|
||||
if (linkstat == USB_EVENT_ID) {
|
||||
if (linkstat == OMAP_MUSB_ID_GROUND) {
|
||||
otg->default_a = true;
|
||||
twl->phy.state = OTG_STATE_A_IDLE;
|
||||
} else {
|
||||
@@ -501,10 +502,10 @@ static DEVICE_ATTR(vbus, 0444, twl4030_usb_vbus_show, NULL);
|
||||
static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
|
||||
{
|
||||
struct twl4030_usb *twl = _twl;
|
||||
int status;
|
||||
enum omap_musb_vbus_id_status status;
|
||||
|
||||
status = twl4030_usb_linkstat(twl);
|
||||
if (status >= 0) {
|
||||
if (status > 0) {
|
||||
/* FIXME add a set_power() method so that B-devices can
|
||||
* configure the charger appropriately. It's not always
|
||||
* correct to consume VBUS power, and how much current to
|
||||
@@ -516,13 +517,13 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
|
||||
* USB_LINK_VBUS state. musb_hdrc won't care until it
|
||||
* starts to handle softconnect right.
|
||||
*/
|
||||
if (status == USB_EVENT_NONE)
|
||||
if (status == OMAP_MUSB_VBUS_OFF ||
|
||||
status == OMAP_MUSB_ID_FLOAT)
|
||||
twl4030_phy_suspend(twl, 0);
|
||||
else
|
||||
twl4030_phy_resume(twl);
|
||||
|
||||
atomic_notifier_call_chain(&twl->phy.notifier, status,
|
||||
twl->phy.otg->gadget);
|
||||
omap_musb_mailbox(twl->linkstat);
|
||||
}
|
||||
sysfs_notify(&twl->dev->kobj, NULL, "vbus");
|
||||
|
||||
@@ -531,11 +532,12 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
|
||||
|
||||
static void twl4030_usb_phy_init(struct twl4030_usb *twl)
|
||||
{
|
||||
int status;
|
||||
enum omap_musb_vbus_id_status status;
|
||||
|
||||
status = twl4030_usb_linkstat(twl);
|
||||
if (status >= 0) {
|
||||
if (status == USB_EVENT_NONE) {
|
||||
if (status > 0) {
|
||||
if (status == OMAP_MUSB_VBUS_OFF ||
|
||||
status == OMAP_MUSB_ID_FLOAT) {
|
||||
__twl4030_phy_power(twl, 0);
|
||||
twl->asleep = 1;
|
||||
} else {
|
||||
@@ -543,8 +545,7 @@ static void twl4030_usb_phy_init(struct twl4030_usb *twl)
|
||||
twl->asleep = 0;
|
||||
}
|
||||
|
||||
atomic_notifier_call_chain(&twl->phy.notifier, status,
|
||||
twl->phy.otg->gadget);
|
||||
omap_musb_mailbox(twl->linkstat);
|
||||
}
|
||||
sysfs_notify(&twl->dev->kobj, NULL, "vbus");
|
||||
}
|
||||
@@ -613,6 +614,7 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev)
|
||||
twl->usb_mode = pdata->usb_mode;
|
||||
twl->vbus_supplied = false;
|
||||
twl->asleep = 1;
|
||||
twl->linkstat = OMAP_MUSB_UNKNOWN;
|
||||
|
||||
twl->phy.dev = twl->dev;
|
||||
twl->phy.label = "twl4030";
|
||||
@@ -639,8 +641,6 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev)
|
||||
if (device_create_file(&pdev->dev, &dev_attr_vbus))
|
||||
dev_warn(&pdev->dev, "could not create sysfs file\n");
|
||||
|
||||
ATOMIC_INIT_NOTIFIER_HEAD(&twl->phy.notifier);
|
||||
|
||||
/* Our job is to use irqs and status from the power module
|
||||
* to keep the transceiver disabled when nothing's connected.
|
||||
*
|
||||
|
@@ -26,10 +26,10 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/usb/otg.h>
|
||||
#include <linux/usb/musb-omap.h>
|
||||
#include <linux/i2c/twl.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
@@ -100,7 +100,7 @@ struct twl6030_usb {
|
||||
|
||||
int irq1;
|
||||
int irq2;
|
||||
u8 linkstat;
|
||||
enum omap_musb_vbus_id_status linkstat;
|
||||
u8 asleep;
|
||||
bool irq_enabled;
|
||||
bool vbus_enable;
|
||||
@@ -147,7 +147,7 @@ static int twl6030_phy_init(struct usb_phy *x)
|
||||
dev = twl->dev;
|
||||
pdata = dev->platform_data;
|
||||
|
||||
if (twl->linkstat == USB_EVENT_ID)
|
||||
if (twl->linkstat == OMAP_MUSB_ID_GROUND)
|
||||
pdata->phy_power(twl->dev, 1, 1);
|
||||
else
|
||||
pdata->phy_power(twl->dev, 0, 1);
|
||||
@@ -235,13 +235,13 @@ static ssize_t twl6030_usb_vbus_show(struct device *dev,
|
||||
spin_lock_irqsave(&twl->lock, flags);
|
||||
|
||||
switch (twl->linkstat) {
|
||||
case USB_EVENT_VBUS:
|
||||
case OMAP_MUSB_VBUS_VALID:
|
||||
ret = snprintf(buf, PAGE_SIZE, "vbus\n");
|
||||
break;
|
||||
case USB_EVENT_ID:
|
||||
case OMAP_MUSB_ID_GROUND:
|
||||
ret = snprintf(buf, PAGE_SIZE, "id\n");
|
||||
break;
|
||||
case USB_EVENT_NONE:
|
||||
case OMAP_MUSB_VBUS_OFF:
|
||||
ret = snprintf(buf, PAGE_SIZE, "none\n");
|
||||
break;
|
||||
default:
|
||||
@@ -257,7 +257,7 @@ static irqreturn_t twl6030_usb_irq(int irq, void *_twl)
|
||||
{
|
||||
struct twl6030_usb *twl = _twl;
|
||||
struct usb_otg *otg = twl->phy.otg;
|
||||
int status;
|
||||
enum omap_musb_vbus_id_status status = OMAP_MUSB_UNKNOWN;
|
||||
u8 vbus_state, hw_state;
|
||||
|
||||
hw_state = twl6030_readb(twl, TWL6030_MODULE_ID0, STS_HW_CONDITIONS);
|
||||
@@ -268,22 +268,20 @@ static irqreturn_t twl6030_usb_irq(int irq, void *_twl)
|
||||
if (vbus_state & VBUS_DET) {
|
||||
regulator_enable(twl->usb3v3);
|
||||
twl->asleep = 1;
|
||||
status = USB_EVENT_VBUS;
|
||||
status = OMAP_MUSB_VBUS_VALID;
|
||||
otg->default_a = false;
|
||||
twl->phy.state = OTG_STATE_B_IDLE;
|
||||
twl->linkstat = status;
|
||||
twl->phy.last_event = status;
|
||||
atomic_notifier_call_chain(&twl->phy.notifier,
|
||||
status, otg->gadget);
|
||||
omap_musb_mailbox(status);
|
||||
} else {
|
||||
status = USB_EVENT_NONE;
|
||||
twl->linkstat = status;
|
||||
twl->phy.last_event = status;
|
||||
atomic_notifier_call_chain(&twl->phy.notifier,
|
||||
status, otg->gadget);
|
||||
if (twl->asleep) {
|
||||
regulator_disable(twl->usb3v3);
|
||||
twl->asleep = 0;
|
||||
if (twl->linkstat != OMAP_MUSB_UNKNOWN) {
|
||||
status = OMAP_MUSB_VBUS_OFF;
|
||||
twl->linkstat = status;
|
||||
omap_musb_mailbox(status);
|
||||
if (twl->asleep) {
|
||||
regulator_disable(twl->usb3v3);
|
||||
twl->asleep = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -296,7 +294,7 @@ static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl)
|
||||
{
|
||||
struct twl6030_usb *twl = _twl;
|
||||
struct usb_otg *otg = twl->phy.otg;
|
||||
int status = USB_EVENT_NONE;
|
||||
enum omap_musb_vbus_id_status status = OMAP_MUSB_UNKNOWN;
|
||||
u8 hw_state;
|
||||
|
||||
hw_state = twl6030_readb(twl, TWL6030_MODULE_ID0, STS_HW_CONDITIONS);
|
||||
@@ -308,13 +306,11 @@ static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl)
|
||||
twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_CLR, 0x1);
|
||||
twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_SET,
|
||||
0x10);
|
||||
status = USB_EVENT_ID;
|
||||
status = OMAP_MUSB_ID_GROUND;
|
||||
otg->default_a = true;
|
||||
twl->phy.state = OTG_STATE_A_IDLE;
|
||||
twl->linkstat = status;
|
||||
twl->phy.last_event = status;
|
||||
atomic_notifier_call_chain(&twl->phy.notifier, status,
|
||||
otg->gadget);
|
||||
omap_musb_mailbox(status);
|
||||
} else {
|
||||
twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_CLR,
|
||||
0x10);
|
||||
@@ -419,6 +415,7 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev)
|
||||
twl->irq1 = platform_get_irq(pdev, 0);
|
||||
twl->irq2 = platform_get_irq(pdev, 1);
|
||||
twl->features = pdata->features;
|
||||
twl->linkstat = OMAP_MUSB_UNKNOWN;
|
||||
|
||||
twl->phy.dev = twl->dev;
|
||||
twl->phy.label = "twl6030";
|
||||
@@ -449,8 +446,6 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev)
|
||||
if (device_create_file(&pdev->dev, &dev_attr_vbus))
|
||||
dev_warn(&pdev->dev, "could not create sysfs file\n");
|
||||
|
||||
ATOMIC_INIT_NOTIFIER_HEAD(&twl->phy.notifier);
|
||||
|
||||
INIT_WORK(&twl->set_vbus_work, otg_set_vbus_work);
|
||||
|
||||
twl->irq_enabled = true;
|
||||
|
Reference in New Issue
Block a user