Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci-2.6.23
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci-2.6.23
Commits
6e0abdbc
Commit
6e0abdbc
authored
Sep 06, 2006
by
Juha Yrjola
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of /home/git/linux-omap-2.6
parents
40cedbdb
6c4a8512
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
257 additions
and
242 deletions
+257
-242
drivers/usb/musb/musb_gadget.c
drivers/usb/musb/musb_gadget.c
+10
-5
drivers/usb/musb/musb_procfs.c
drivers/usb/musb/musb_procfs.c
+2
-2
drivers/usb/musb/musbdefs.h
drivers/usb/musb/musbdefs.h
+3
-6
drivers/usb/musb/otg.c
drivers/usb/musb/otg.c
+1
-0
drivers/usb/musb/plat_uds.c
drivers/usb/musb/plat_uds.c
+21
-35
drivers/usb/musb/tusb6010.c
drivers/usb/musb/tusb6010.c
+155
-109
drivers/usb/musb/tusb6010.h
drivers/usb/musb/tusb6010.h
+14
-3
drivers/usb/musb/tusb6010_omap.c
drivers/usb/musb/tusb6010_omap.c
+46
-82
drivers/usb/musb/virthub.c
drivers/usb/musb/virthub.c
+5
-0
No files found.
drivers/usb/musb/musb_gadget.c
View file @
6e0abdbc
...
...
@@ -508,7 +508,6 @@ void musb_g_tx(struct musb *pThis, u8 bEnd)
if
(
!
pRequest
)
{
DBG
(
4
,
"%s idle now
\n
"
,
pEnd
->
end_point
.
name
);
musb_platform_try_idle
(
pThis
);
break
;
}
}
...
...
@@ -974,8 +973,7 @@ static int musb_gadget_enable(struct usb_ep *ep,
pEnd
->
dma
?
"dma, "
:
""
,
pEnd
->
wPacketSize
);
pThis
->
status
|=
MUSB_VBUS_STATUS_CHG
;
schedule_work
(
&
pThis
->
irq_work
);
sysfs_notify
(
&
pThis
->
controller
->
kobj
,
NULL
,
"cable"
);
fail:
spin_unlock_irqrestore
(
&
pThis
->
Lock
,
flags
);
...
...
@@ -1018,8 +1016,7 @@ static int musb_gadget_disable(struct usb_ep *ep)
/* abort all pending DMA and requests */
nuke
(
pEnd
,
-
ESHUTDOWN
);
pThis
->
status
|=
MUSB_VBUS_STATUS_CHG
;
/* FIXME not for ep_disable!! */
schedule_work
(
&
pThis
->
irq_work
);
sysfs_notify
(
&
pThis
->
controller
->
kobj
,
NULL
,
"cable"
);
spin_unlock_irqrestore
(
&
(
pThis
->
Lock
),
flags
);
...
...
@@ -1664,6 +1661,9 @@ int __devinit musb_gadget_setup(struct musb *pThis)
musb_g_init_endpoints
(
pThis
);
pThis
->
is_active
=
0
;
musb_platform_try_idle
(
pThis
);
status
=
device_register
(
&
pThis
->
g
.
dev
);
if
(
status
!=
0
)
the_gadget
=
NULL
;
...
...
@@ -1746,6 +1746,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
*/
pThis
->
xceiv
.
gadget
=
&
pThis
->
g
;
pThis
->
xceiv
.
state
=
OTG_STATE_B_IDLE
;
pThis
->
is_active
=
1
;
/* FIXME this ignores the softconnect flag. Drivers are
* allowed hold the peripheral inactive until for example
...
...
@@ -1857,6 +1858,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
musb
->
pGadgetDriver
=
NULL
;
musb
->
g
.
dev
.
driver
=
NULL
;
musb
->
is_active
=
0
;
musb_platform_try_idle
(
musb
);
}
else
retval
=
-
EINVAL
;
...
...
@@ -1944,6 +1946,8 @@ void musb_g_disconnect(struct musb *pThis)
case
OTG_STATE_B_SRP_INIT
:
break
;
}
pThis
->
is_active
=
0
;
}
void
musb_g_reset
(
struct
musb
*
pThis
)
...
...
@@ -1977,6 +1981,7 @@ __acquires(pThis->Lock)
?
USB_SPEED_HIGH
:
USB_SPEED_FULL
;
/* start in USB_STATE_DEFAULT */
pThis
->
is_active
=
1
;
MUSB_DEV_MODE
(
pThis
);
pThis
->
bAddress
=
0
;
pThis
->
ep0_state
=
MGC_END0_STAGE_SETUP
;
...
...
drivers/usb/musb/musb_procfs.c
View file @
6e0abdbc
...
...
@@ -754,11 +754,11 @@ static int musb_proc_read(char *page, char **start,
}
}
musb_platform_try_idle
(
pThis
);
spin_unlock_irqrestore
(
&
pThis
->
Lock
,
flags
);
*
eof
=
1
;
musb_platform_try_idle
(
pThis
);
return
(
buffer
-
page
)
-
off
;
}
...
...
drivers/usb/musb/musbdefs.h
View file @
6e0abdbc
...
...
@@ -197,9 +197,6 @@ enum musb_g_ep0_state {
MGC_END0_STAGE_ACKWAIT
,
/* after zlp, before statusin */
}
__attribute__
((
packed
));
/* driver and cable VBUS status states for musb_irq_work */
#define MUSB_VBUS_STATUS_CHG (1 << 0)
/* failure codes */
#define MUSB_ERR_WAITING 1
#define MUSB_ERR_VBUS -1
...
...
@@ -395,7 +392,6 @@ struct musb {
spinlock_t
Lock
;
struct
clk
*
clock
;
irqreturn_t
(
*
isr
)(
int
,
void
*
,
struct
pt_regs
*
);
struct
work_struct
irq_work
;
#ifdef CONFIG_USB_MUSB_HDRC_HCD
...
...
@@ -450,10 +446,11 @@ struct musb {
u8
board_mode
;
/* enum musb_mode */
int
(
*
board_set_power
)(
int
state
);
u8
status
;
/* status change flags for musb_irq_work */
s8
bFailCode
;
/* one of MUSB_ERR_* failure code */
/* active means connected and not suspended */
unsigned
is_active
:
1
;
unsigned
bIsMultipoint
:
1
;
unsigned
bIsDevice
:
1
;
unsigned
bIsHost
:
1
;
...
...
drivers/usb/musb/otg.c
View file @
6e0abdbc
...
...
@@ -212,6 +212,7 @@ static void otg_timeout(unsigned long ptr)
default:
WARN
(
"timeout in state %d, now what?
\n
"
,
pMachine
->
bState
);
}
musb_platform_try_idle
(
musb
);
spin_unlock_irqrestore
(
&
musb
->
Lock
,
flags
);
}
...
...
drivers/usb/musb/plat_uds.c
View file @
6e0abdbc
...
...
@@ -384,6 +384,7 @@ static irqreturn_t musb_stage0_irq(struct musb * pThis, u8 bIntrUSB,
if
(
bIntrUSB
&
MGC_M_INTR_RESUME
)
{
handled
=
IRQ_HANDLED
;
DBG
(
3
,
"RESUME
\n
"
);
pThis
->
is_active
=
1
;
if
(
devctl
&
MGC_M_DEVCTL_HM
)
{
#ifdef CONFIG_USB_MUSB_HDRC_HCD
...
...
@@ -458,6 +459,7 @@ static irqreturn_t musb_stage0_irq(struct musb * pThis, u8 bIntrUSB,
if
(
bIntrUSB
&
MGC_M_INTR_CONNECT
)
{
handled
=
IRQ_HANDLED
;
pThis
->
is_active
=
1
;
pThis
->
bEnd0Stage
=
MGC_END0_START
;
...
...
@@ -527,6 +529,8 @@ static irqreturn_t musb_stage0_irq(struct musb * pThis, u8 bIntrUSB,
otg_input_changed
(
pThis
,
devctl
,
TRUE
,
FALSE
,
(
power
&
MGC_M_POWER_SUSPENDM
)
?
TRUE
:
FALSE
);
sysfs_notify
(
&
pThis
->
controller
->
kobj
,
NULL
,
"cable"
);
}
handled
=
IRQ_HANDLED
;
...
...
@@ -598,6 +602,7 @@ static irqreturn_t musb_stage2_irq(struct musb * pThis, u8 bIntrUSB,
DBG
(
1
,
"DISCONNECT as %s, devctl %02x
\n
"
,
MUSB_MODE
(
pThis
),
devctl
);
handled
=
IRQ_HANDLED
;
pThis
->
is_active
=
0
;
/* need to check it against pThis, because devctl is going
* to report ID low as soon as the device gets disconnected
...
...
@@ -609,6 +614,8 @@ static irqreturn_t musb_stage2_irq(struct musb * pThis, u8 bIntrUSB,
/* REVISIT all OTG state machine transitions */
otg_input_changed_X
(
pThis
,
FALSE
,
FALSE
);
sysfs_notify
(
&
pThis
->
controller
->
kobj
,
NULL
,
"cable"
);
}
if
(
bIntrUSB
&
MGC_M_INTR_SUSPEND
)
{
...
...
@@ -618,9 +625,15 @@ static irqreturn_t musb_stage2_irq(struct musb * pThis, u8 bIntrUSB,
/* peripheral suspend, may trigger HNP */
if
(
!
(
devctl
&
MGC_M_DEVCTL_HM
))
{
musb_g_suspend
(
pThis
);
#ifdef CONFIG_USB_GADGET_MUSB_HDRC
pThis
->
is_active
=
is_otg_enabled
(
pThis
)
&&
pThis
->
xceiv
.
gadget
->
b_hnp_enable
;
#else
pThis
->
is_active
=
0
;
#endif
otg_input_changed
(
pThis
,
devctl
,
FALSE
,
FALSE
,
TRUE
);
musb_platform_try_idle
(
pThis
);
}
}
else
pThis
->
is_active
=
0
;
}
return
handled
;
...
...
@@ -1416,7 +1429,6 @@ musb_cable_show(struct device *dev, struct device_attribute *attr, char *buf)
v2
=
"connected"
;
else
v2
=
"disconnected"
;
musb_platform_try_idle
(
musb
);
#else
/* NOTE: board-specific issues, like too-big capacitors keeping
* VBUS high for a long time after power has been removed, can
...
...
@@ -1440,6 +1452,7 @@ musb_cable_show(struct device *dev, struct device_attribute *attr, char *buf)
}
else
/* VBUS level below A-Valid */
v2
=
"disconnected"
;
#endif
musb_platform_try_idle
(
musb
);
spin_unlock_irqrestore
(
&
musb
->
Lock
,
flags
);
return
sprintf
(
buf
,
"%s%s
\n
"
,
v1
,
v2
);
...
...
@@ -1448,25 +1461,6 @@ static DEVICE_ATTR(cable, S_IRUGO, musb_cable_show, NULL);
#endif
static
void
musb_irq_work
(
void
*
data
)
{
struct
musb
*
musb
=
(
struct
musb
*
)
data
;
unsigned
long
flags
;
u8
event
=
0
;
spin_lock_irqsave
(
&
musb
->
Lock
,
flags
);
if
(
musb
->
status
&
MUSB_VBUS_STATUS_CHG
)
{
musb
->
status
&=
~
MUSB_VBUS_STATUS_CHG
;
event
=
1
;
}
musb_platform_try_idle
(
musb
);
spin_unlock_irqrestore
(
&
musb
->
Lock
,
flags
);
#ifdef CONFIG_SYSFS
if
(
event
)
sysfs_notify
(
&
musb
->
controller
->
kobj
,
NULL
,
"cable"
);
#endif
}
/* --------------------------------------------------------------------------
* Init support
*/
...
...
@@ -1654,6 +1648,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
goto
fail2
;
}
pThis
->
nIrq
=
nIrq
;
device_init_wakeup
(
dev
,
1
);
pr_info
(
"%s: USB %s mode controller at %p using %s, IRQ %d
\n
"
,
musb_driver_name
,
...
...
@@ -1668,11 +1663,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
?
"DMA"
:
"PIO"
,
pThis
->
nIrq
);
// FIXME:
// - convert to the HCD framework
// - if (board_mode == MUSB_OTG) do startup with peripheral
// - ... involves refcounting updates
#ifdef CONFIG_USB_MUSB_HDRC_HCD
/* host side needs more setup, except for no-host modes */
if
(
pThis
->
board_mode
!=
MUSB_PERIPHERAL
)
{
...
...
@@ -1737,11 +1727,11 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
musb_debug_create
(
"driver/musb_hdrc"
,
pThis
);
else
{
fail:
device_init_wakeup
(
dev
,
0
);
musb_free
(
pThis
);
return
status
;
}
INIT_WORK
(
&
pThis
->
irq_work
,
musb_irq_work
,
pThis
);
#ifdef CONFIG_SYSFS
device_create_file
(
dev
,
&
dev_attr_mode
);
device_create_file
(
dev
,
&
dev_attr_cable
);
...
...
@@ -1796,15 +1786,12 @@ static int __devexit musb_remove(struct platform_device *pdev)
usb_remove_hcd
(
musb_to_hcd
(
musb
));
#endif
musb_free
(
musb
);
device_init_wakeup
(
&
pdev
->
dev
,
0
);
return
0
;
}
#ifdef CONFIG_PM
/* REVISIT when power savings matter on DaVinci, look at turning
* off its phy clock during system suspend iff wakeup is disabled
*/
static
int
musb_suspend
(
struct
platform_device
*
pdev
,
pm_message_t
message
)
{
unsigned
long
flags
;
...
...
@@ -1821,11 +1808,10 @@ static int musb_suspend(struct platform_device *pdev, pm_message_t message)
*/
}
else
if
(
is_host_active
(
musb
))
{
/* we know all the children are suspended; sometimes
* they will even be wakeup-enabled
* they will even be wakeup-enabled
.
*/
}
musb_platform_try_idle
(
musb
);
clk_disable
(
musb
->
clock
);
spin_unlock_irqrestore
(
&
musb
->
Lock
,
flags
);
return
0
;
...
...
drivers/usb/musb/tusb6010.c
View file @
6e0abdbc
...
...
@@ -145,6 +145,10 @@ void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *buf)
/*
* Enables TUSB6010 to use VBUS as power source in peripheral mode.
* In host mode, a local battery must power the TUSB chip as well as
* (through the charge pump) VBUS. For OTG peripherals, the battery
* must power the chip until it enters a confguration that's allowed
* to draw enough current (call it 100mA).
*/
static
inline
void
tusb_enable_vbus_charge
(
struct
musb
*
musb
)
{
...
...
@@ -159,21 +163,29 @@ static inline void tusb_enable_vbus_charge(struct musb *musb)
}
/*
* Idle
s TUSB6010 until next wake-up event interrupt. Use all wake-up
*
events for now. Note that TUSB will not respond if NOR chip select
*
wake-up event is masked. Also note that any access to TUSB will wake
*
it up from idle
.
* Idle
TUSB6010 until next wake-up event; NOR access always wakes.
*
Other code ensures that we idle unless we're connected _and_ the
*
USB link is not suspended ... and tells us the relevant wakeup
*
events
.
*/
static
inline
void
tusb_allow_idle
(
struct
musb
*
musb
,
int
wakeup_mask
)
static
inline
void
tusb_allow_idle
(
struct
musb
*
musb
,
u32
wakeup_enables
)
{
void
__iomem
*
base
=
musb
->
ctrl_base
;
u32
reg
;
musb_writel
(
base
,
TUSB_PRCM_WAKEUP_MASK
,
wakeup_mask
);
wakeup_enables
|=
TUSB_PRCM_WNORCS
;
musb_writel
(
base
,
TUSB_PRCM_WAKEUP_MASK
,
~
wakeup_enables
);
reg
=
musb_readl
(
base
,
TUSB_PRCM_MNGMT
);
reg
&=
~
TUSB_PRCM_MNGMT_CPEN_MASK
;
reg
|=
TUSB_PRCM_MNGMT_SUSPEND_MASK
;
reg
&=
~
(
TUSB_PRCM_MNGMT_OTG_VBUS_DET_EN
|
TUSB_PRCM_MNGMT_15_SW_EN
|
TUSB_PRCM_MNGMT_33_SW_EN
);
reg
|=
TUSB_PRCM_MNGMT_OTG_SESS_END_EN
|
TUSB_PRCM_MNGMT_PM_IDLE
|
TUSB_PRCM_MNGMT_DEV_IDLE
;
musb_writel
(
base
,
TUSB_PRCM_MNGMT
,
reg
);
DBG
(
2
,
"idle, wake on %02x
\n
"
,
wakeup_enables
);
}
/*
...
...
@@ -206,36 +218,117 @@ int musb_platform_get_vbus_status(struct musb *musb)
return
ret
;
}
static
struct
timer_list
musb_idle_timer
;
static
void
musb_do_idle
(
unsigned
long
_musb
)
{
struct
musb
*
musb
=
(
void
*
)
_musb
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
musb
->
Lock
,
flags
);
if
(
!
musb
->
is_active
)
{
u32
wakeups
;
#ifdef CONFIG_USB_GADGET_MUSB_HDRC
if
(
is_peripheral_enabled
(
musb
)
&&
!
musb
->
pGadgetDriver
)
wakeups
=
0
;
else
{
wakeups
=
TUSB_PRCM_WHOSTDISCON
|
TUSB_PRCM_WBUS
|
TUSB_PRCM_WVBUS
;
if
(
is_otg_enabled
(
musb
))
wakeups
|=
TUSB_PRCM_WLD
;
}
#else
wakeups
=
TUSB_PRCM_WHOSTDISCON
|
TUSB_PRCM_WBUS
;
#endif
tusb_allow_idle
(
musb
,
wakeups
);
}
spin_unlock_irqrestore
(
&
musb
->
Lock
,
flags
);
}
/*
* Sets the TUSB6010 idles mode in peripheral mode depending on the
* gadget driver state and cable VBUS status. Needs to be called as
* the last function everywhere where there is register access to
* TUSB6010 because of the NOR flash wake-up capability.
* Caller must take care of locking.
* Maybe put TUSB6010 into idle mode mode depending on USB link status,
* like "disconnected" or "suspended". We'll be woken out of it by
* connect, resume, or disconnect.
*
* Needs to be called as the last function everywhere where there is
* register access to TUSB6010 because of NOR flash wake-up.
* Caller should own controller spinlock.
*
* Delay because peripheral enables D+ pullup 3msec after SE0, and
* we don't want to treat that full speed J as a wakeup event.
* ... peripherals must draw only suspend current after 10 msec.
*/
void
musb_platform_try_idle
(
struct
musb
*
musb
)
{
u32
wakeup_mask
=
0
;
if
(
musb
->
is_active
)
del_timer
(
&
musb_idle_timer
);
else
mod_timer
(
&
musb_idle_timer
,
jiffies
+
(
is_host_active
(
musb
)
?
msecs_to_jiffies
(
3
)
:
0
));
}
/* Suspend with only NOR flash wake-up event enabled if no
* gadget driver is active.
*/
if
(
musb
->
xceiv
.
state
==
OTG_STATE_UNDEFINED
)
{
wakeup_mask
=
0xffff
&
~
TUSB_PRCM_WNORCS
;
tusb_allow_idle
(
musb
,
wakeup_mask
);
return
;
static
inline
void
tusb_otg_ints
(
struct
musb
*
musb
,
u32
int_src
,
void
__iomem
*
base
)
{
u32
otg_stat
=
musb_readl
(
base
,
TUSB_DEV_OTG_STAT
);
/* ID pin */
if
((
int_src
&
TUSB_INT_SRC_ID_STATUS_CHNG
))
{
int
default_a
;
default_a
=
is_host_enabled
(
musb
)
&&
(
otg_stat
&
TUSB_DEV_OTG_STAT_ID_STATUS
);
if
(
default_a
!=
musb
->
xceiv
.
default_a
)
{
musb
->
xceiv
.
default_a
=
default_a
;
if
(
musb
->
xceiv
.
default_a
)
{
musb
->
xceiv
.
state
=
OTG_STATE_A_IDLE
;
/* REVISIT start the session? */
}
else
musb
->
xceiv
.
state
=
OTG_STATE_B_IDLE
;
DBG
(
1
,
"Default-%c
\n
"
,
musb
->
xceiv
.
default_a
?
'A'
:
'B'
);
musb
->
is_active
=
1
;
}
}
/* Use VBUS as power source if available, otherwise suspend
* with all wake-up events enabled.
*
* FIXME only B-device state machine ever _consumes_ VBUS.
/* VBUS state change */
if
(
int_src
&
TUSB_INT_SRC_VBUS_SENSE_CHNG
)
{
/* no vbus ~= disconnect */
if
(
!
is_host_enabled
(
musb
)
||
!
musb
->
xceiv
.
default_a
)
{
/* REVISIT in B-Default state machine, use VBUS power
* for the USB link when (a) non-OTG, since 100 mA is
* always available; or (b) OTG after SET_CONFIGURATION
* enabling 100+ (?) mA draw.
*/
if
(
musb_platform_get_vbus_status
(
musb
))
tusb_enable_vbus_charge
(
musb
);
else
{
wakeup_mask
=
TUSB_PRCM_WLD
;
tusb_allow_idle
(
musb
,
wakeup_mask
);
/* REVISIT use the b_sess_valid comparator, not
* lowpower one; TUSB_DEV_OTG_STAT_SESS_VALID ?
*/
if
(
otg_stat
&
TUSB_DEV_OTG_STAT_VBUS_SENSE
)
{
musb
->
xceiv
.
state
=
OTG_STATE_B_PERIPHERAL
;
musb
->
is_active
=
1
;
/* REVISIT start the session? */
}
else
{
musb
->
xceiv
.
state
=
OTG_STATE_B_IDLE
;
musb
->
is_active
=
0
;
}
DBG
(
1
,
"%s
\n
"
,
musb
->
is_active
?
"b_peripheral"
:
"b_idle"
);
sysfs_notify
(
&
musb
->
controller
->
kobj
,
NULL
,
"cable"
);
}
}
/* OTG timer expiration */
if
(
int_src
&
TUSB_INT_SRC_OTG_TIMEOUT
)
{
DBG
(
3
,
"tusb: OTG timer expired
\n
"
);
musb_writel
(
base
,
TUSB_DEV_OTG_TIMER
,
musb_readl
(
base
,
TUSB_DEV_OTG_TIMER
)
|
TUSB_DEV_OTG_TIMER_ENABLE
);
}
}
...
...
@@ -244,88 +337,43 @@ irqreturn_t tusb_interrupt(int irq, void *__hci, struct pt_regs *r)
struct
musb
*
musb
=
__hci
;
void
__iomem
*
base
=
musb
->
ctrl_base
;
unsigned
long
flags
;
u32
dma_src
,
int_src
,
otg_stat
,
musb_src
=
0
;
u32
dma_src
=
0
,
int_src
;
spin_lock_irqsave
(
&
musb
->
Lock
,
flags
);
dma_src
=
musb_readl
(
base
,
TUSB_DMA_INT_SRC
);
int_src
=
musb_readl
(
base
,
TUSB_INT_SRC
)
&
~
TUSB_INT_SRC_RESERVED_BITS
;
otg_stat
=
musb_readl
(
base
,
TUSB_DEV_OTG_STAT
);
if
(
int_src
&
TUSB_INT_SRC_TXRX_DMA_DONE
)
dma_src
=
musb_readl
(
base
,
TUSB_DMA_INT_SRC
);
DBG
(
3
,
"TUSB interrupt dma: %08x int: %08x otg: %08x
\n
"
,
dma_src
,
int_src
,
otg_stat
);
DBG
(
3
,
"TUSB interrupt dma: %08x int: %08x
\n
"
,
dma_src
,
int_src
);
musb
->
int_usb
=
0
;
musb
->
int_rx
=
0
;
musb
->
int_tx
=
0
;
musb
->
int_regs
=
r
;
if
(
otg_stat
&
TUSB_DEV_OTG_STAT_ID_STATUS
)
{
/* ID pin is up. Either A-plug was removed or TUSB6010
* is in peripheral mode */
/* Still in pheripheral mode? */
if
((
int_src
&
TUSB_INT_SRC_ID_STATUS_CHNG
))
{
DBG
(
3
,
"tusb: Status change
\n
"
);
//goto out;
}
}
/* Peripheral suspend. Cable may be disconnected, try to idle */
if
(
int_src
&
TUSB_INT_SRC_USB_IP_SUSPEND
)
{
musb
->
status
|=
MUSB_VBUS_STATUS_CHG
;
schedule_work
(
&
musb
->
irq_work
);
}
/* Connect and disconnect for host mode */
if
(
int_src
&
TUSB_INT_SRC_USB_IP_CONN
)
{
DBG
(
3
,
"tusb: Connected
\n
"
);
}
else
if
(
int_src
&
TUSB_INT_SRC_USB_IP_DISCON
)
{
DBG
(
3
,
"tusb: Disconnected
\n
"
);
}
/* VBUS state change */
if
((
int_src
&
TUSB_INT_SRC_VBUS_SENSE_CHNG
)
||
(
int_src
&
TUSB_INT_SRC_USB_IP_VBUS_ERR
))
{
musb
->
status
|=
MUSB_VBUS_STATUS_CHG
;
schedule_work
(
&
musb
->
irq_work
);
/* Acknowledge wake-up source interrupts */
if
(
int_src
&
TUSB_INT_SRC_DEV_WAKEUP
)
{
u32
reg
=
musb_readl
(
base
,
TUSB_PRCM_WAKEUP_SOURCE
);
#if 0
DBG(3, "tusb: VBUS changed. VBUS state %d\n",
(otg_stat & TUSB_DEV_OTG_STAT_VBUS_SENSE) ? 1 : 0);
if (!(otg_stat & TUSB_DEV_OTG_STAT_VBUS_SENSE)
&& !(otg_stat & TUSB_DEV_OTG_STAT_ID_STATUS)) {
/* VBUS went off and ID pin is down */
DBG(3, "tusb: No VBUS, starting session\n");
/* Start session again, VBUS will be enabled */
musb_writeb(musb_base, MGC_O_HDRC_DEVCTL,
MGC_M_DEVCTL_SESSION);
}
#endif
musb_writel
(
base
,
TUSB_PRCM_WAKEUP_CLEAR
,
reg
);
if
(
reg
&
~
TUSB_PRCM_WNORCS
)
{
musb
->
is_active
=
1
;
sysfs_notify
(
&
musb
->
controller
->
kobj
,
NULL
,
"cable"
);
}
/* ID pin change */
if
(
int_src
&
TUSB_INT_SRC_ID_STATUS_CHNG
)
{
DBG
(
3
,
"tusb: ID pin changed. State is %d
\n
"
,
(
musb_readl
(
base
,
TUSB_DEV_OTG_STAT
)
&
TUSB_DEV_OTG_STAT_ID_STATUS
)
?
1
:
0
);
DBG
(
3
,
"wake %sactive %02x
\n
"
,
musb
->
is_active
?
""
:
"in"
,
reg
);
}
/* OTG timer expiration */
if
(
int_src
&
TUSB_INT_SRC_OTG_TIMEOUT
)
{
DBG
(
3
,
"tusb: OTG timer expired
\n
"
);
musb_writel
(
base
,
TUSB_DEV_OTG_TIMER
,
musb_readl
(
base
,
TUSB_DEV_OTG_TIMER
)
|
TUSB_DEV_OTG_TIMER_ENABLE
);
}
/* OTG state change reports (annoyingly) not issued by Mentor core */
if
(
int_src
&
(
TUSB_INT_SRC_VBUS_SENSE_CHNG
|
TUSB_INT_SRC_OTG_TIMEOUT
|
TUSB_INT_SRC_ID_STATUS_CHNG
))
tusb_otg_ints
(
musb
,
int_src
,
base
);
/* TX dma callback must be handled here, RX dma callback is
* handled in tusb_omap_dma_cb.
*/
if
((
int_src
&
TUSB_INT_SRC_TXRX_DMA_DONE
)
&&
dma_src
)
{
u32
real_dma_src
=
musb_readl
(
base
,
TUSB_DMA_INT_MASK
);
real_dma_src
=
~
real_dma_src
&
dma_src
;
if
(
tusb_dma_omap
())
{
int
tx_source
=
(
real_dma_src
&
0xffff
);
...
...
@@ -343,27 +391,25 @@ irqreturn_t tusb_interrupt(int irq, void *__hci, struct pt_regs *r)
/* EP interrupts. In OCP mode tusb6010 mirrors the MUSB * interrupts */
if
(
int_src
&
(
TUSB_INT_SRC_USB_IP_TX
|
TUSB_INT_SRC_USB_IP_RX
))
{
musb_src
=
musb_readl
(
base
,
TUSB_USBIP_INT_SRC
);
u32
musb_src
=
musb_readl
(
base
,
TUSB_USBIP_INT_SRC
);
musb_writel
(
base
,
TUSB_USBIP_INT_CLEAR
,
musb_src
);
musb
->
int_rx
=
(((
musb_src
>>
16
)
&
0xffff
)
<<
1
);
musb
->
int_tx
=
(
musb_src
&
0xffff
);
}
musb
->
int_usb
=
(
int_src
&
0xff
);
if
(
musb
->
int_usb
||
musb
->
int_rx
||
musb
->
int_tx
)
musb_interrupt
(
musb
);
}
else
musb
->
int_rx
=
musb
->
int_tx
=
0
;
/* Acknowledge wake-up source interrupts */
if
(
int_src
&
TUSB_INT_SRC_DEV_WAKEUP
)
{
u32
reg
=
musb_readl
(
base
,
TUSB_PRCM_WAKEUP_SOURCE
);
musb_writel
(
base
,
TUSB_PRCM_WAKEUP_CLEAR
,
reg
);
schedule_work
(
&
musb
->
irq_work
);
if
(
int_src
&
(
TUSB_INT_SRC_USB_IP_TX
|
TUSB_INT_SRC_USB_IP_RX
|
0xff
))
{
musb
->
int_usb
=
(
u8
)
int_src
;
musb_interrupt
(
musb
);
}
/* Acknowledge TUSB interrupts. Clear only non-reserved bits */
if
(
int_src
)
musb_writel
(
base
,
TUSB_INT_SRC_CLEAR
,
int_src
&
~
TUSB_INT_MASK_RESERVED_BITS
);
musb
->
int_regs
=
NULL
;
musb_platform_try_idle
(
musb
);
spin_unlock_irqrestore
(
&
musb
->
Lock
,
flags
);
return
IRQ_HANDLED
;
...
...
@@ -589,7 +635,7 @@ int __devinit musb_platform_init(struct musb *musb)
}
musb
->
isr
=
tusb_interrupt
;
musb_platform_try_idle
(
musb
);
setup_timer
(
&
musb_idle_timer
,
musb_do_idle
,
(
unsigned
long
)
musb
);
return
ret
;
}
...
...
drivers/usb/musb/tusb6010.h
View file @
6e0abdbc
...
...
@@ -103,9 +103,20 @@
#define TUSB_PRCM_MNGMT_5V_CPEN (1 << 2)
#define TUSB_PRCM_MNGMT_PM_IDLE (1 << 1)
#define TUSB_PRCM_MNGMT_DEV_IDLE (1 << 0)
#define TUSB_PRCM_MNGMT_PM_CLEAR_MASK ((0x3 << 3) | (0x3 << 0))
#define TUSB_PRCM_MNGMT_CPEN_MASK ((1 << 9) | (0x3 << 3))
#define TUSB_PRCM_MNGMT_SUSPEND_MASK ((1 << 10) | (0x3 << 0))
#define TUSB_PRCM_MNGMT_PM_CLEAR_MASK \
( TUSB_PRCM_MNGMT_15_SW_EN \
| TUSB_PRCM_MNGMT_33_SW_EN \
| TUSB_PRCM_MNGMT_PM_IDLE \
| TUSB_PRCM_MNGMT_DEV_IDLE )
#define TUSB_PRCM_MNGMT_CPEN_MASK \
( TUSB_PRCM_MNGMT_OTG_VBUS_DET_EN \
| TUSB_PRCM_MNGMT_15_SW_EN \
| TUSB_PRCM_MNGMT_33_SW_EN )
#define TUSB_PRCM_MNGMT_SUSPEND_MASK \
( TUSB_PRCM_MNGMT_OTG_SESS_END_EN \
| TUSB_PRCM_MNGMT_PM_IDLE \
| TUSB_PRCM_MNGMT_DEV_IDLE )
/* Wake-up source clear and mask registers */
#define TUSB_PRCM_WAKEUP_SOURCE (TUSB_SYS_REG_BASE + 0x020)
...
...
drivers/usb/musb/tusb6010_omap.c
View file @
6e0abdbc
...
...
@@ -145,7 +145,7 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
struct
musb_hw_ep
*
hw_ep
=
chdat
->
hw_ep
;
void
__iomem
*
ep_conf
=
hw_ep
->
conf
;
void
__iomem
*
musb_base
=
musb
->
pRegs
;
unsigned
long
transferred
,
flags
;
unsigned
long
remaining
,
flags
;
int
ch
;
spin_lock_irqsave
(
&
musb
->
Lock
,
flags
);
...
...
@@ -158,17 +158,19 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
if
(
ch_status
!=
OMAP_DMA_BLOCK_IRQ
)
printk
(
KERN_ERR
"TUSB DMA error status: %i
\n
"
,
ch_status
);
DBG
(
3
,
"ep%i %s dma callback ch: %i status: %x
\n
"
,
DBG
(
2
,
"ep%i %s dma callback ch: %i status: %x
\n
"
,
chdat
->
epnum
,
chdat
->
tx
?
"tx"
:
"rx"
,
ch
,
ch_status
);
if
(
chdat
->
tx
)
transferred
=
musb_readl
(
ep_conf
,
TUSB_EP_TX_OFFSET
);
remaining
=
musb_readl
(
ep_conf
,
TUSB_EP_TX_OFFSET
);
else
transferred
=
musb_readl
(
ep_conf
,
TUSB_EP_RX_OFFSET
);
remaining
=
musb_readl
(
ep_conf
,
TUSB_EP_RX_OFFSET
);
transferred
=
TUSB_EP_CONFIG_XFR_SIZE
(
transferred
);
channel
->
dwActualLength
=
chdat
->
transfer_len
-
transferred
;
remaining
=
TUSB_EP_CONFIG_XFR_SIZE
(
remaining
);
channel
->
dwActualLength
=
chdat
->
transfer_len
-
remaining
;
DBG
(
2
,
"remaining %lu/%lu
\n
"
,
remaining
,
chdat
->
transfer_len
);
if
(
!
dmareq_works
())
tusb_omap_free_shared_dmareq
(
chdat
);
...
...
@@ -192,7 +194,7 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
u16
csr
;
if
(
chdat
->
tx
)
{
DBG
(
3
,
"terminating short tx packet
\n
"
);
DBG
(
2
,
"terminating short tx packet
\n
"
);
MGC_SelectEnd
(
musb_base
,
chdat
->
epnum
);
csr
=
musb_readw
(
hw_ep
->
regs
,
MGC_O_HDRC_TXCSR
);
csr
|=
MGC_M_TXCSR_MODE
|
MGC_M_TXCSR_TXPKTRDY
;
...
...
@@ -221,53 +223,27 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
s8
dmareq
;
s8
sync_dev
;
if
(
len
<
32
)
{
DBG
(
3
,
"dma too short for ep%i %s dma_addr: %08x len: %u
\n
"
,
chdat
->
epnum
,
chdat
->
tx
?
"tx"
:
"rx"
,
dma_addr
,
len
);
if
(
unlikely
(
dma_addr
&
0x1
))
return
FALSE
;
}
#if 0
if ((len % 32 != 0)) {
transfer_len = len / 32;
transfer_len *= 32;
DBG(3, "ep%i short %s dma: %lu/%lu %lu remainder\n",
chdat->epnum, chdat->tx ? "tx" : "rx",
transfer_len, len, len - transfer_len);
} else
transfer_len = len;
#else
if
((
len
%
32
)
!=
0
)
{
DBG
(
3
,
"bad dma length for ep%i %s dma_addr: %08x len: %u
\n
"
,
chdat
->
epnum
,
chdat
->
tx
?
"tx"
:
"rx"
,
dma_addr
,
len
);
if
(
len
<
32
)
return
FALSE
;
}
else
transfer_len
=
len
;
#endif
if
(
dma_addr
&
0x1
)
{
DBG
(
3
,
"unaligned dma address for ep%i %s: %08x
\n
"
,
chdat
->
epnum
,
chdat
->
tx
?
"tx"
:
"rx"
,
dma_addr
);
if
((
len
%
32
!=
0
))
return
FALSE
;
}
else
transfer_len
=
len
;
if
(
dmareq_works
())
{
/* FIXME: Check for allocated dma ch */
ch
=
chdat
->
ch
;
dmareq
=
chdat
->
dmareq
;
sync_dev
=
chdat
->
sync_dev
;
}
else
{
if
(
tusb_omap_use_shared_dmareq
(
chdat
)
!=
0
)
if
(
tusb_omap_use_shared_dmareq
(
chdat
)
!=
0
)
{
DBG
(
3
,
"could not get dma for ep%i
\n
"
,
chdat
->
epnum
);
return
FALSE
;
/* FIXME: Check for allocated dma ch */
}
ch
=
tusb_dma
->
ch
;
dmareq
=
tusb_dma
->
dmareq
;
sync_dev
=
tusb_dma
->
sync_dev
;
omap_set_dma_callback
(
ch
,
tusb_omap_dma_cb
,
channel
);
}
...
...
@@ -278,26 +254,32 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
chdat
->
dma_addr
=
(
void
__iomem
*
)
dma_addr
;
channel
->
bStatus
=
MGC_DMA_STATUS_BUSY
;
DBG
(
3
,
"ep%i %s dma ch%i dma: %08x len: %u packet_sz: %i rndis: %d
\n
"
,
chdat
->
epnum
,
chdat
->
tx
?
"tx"
:
"rx"
,
ch
,
dma_addr
,
transfer_len
,
packet_sz
,
rndis_mode
);
/* Since we're recycling dma areas, we need to clean or invalidate */
if
(
chdat
->
tx
)
consistent_sync
(
phys_to_virt
(
dma_addr
),
len
,
DMA_TO_DEVICE
);
else
consistent_sync
(
phys_to_virt
(
dma_addr
),
len
,
DMA_FROM_DEVICE
);
if
(
chdat
->
tx
)
{
consistent_sync
(
phys_to_virt
(
dma_addr
),
len
,
DMA_TO_DEVICE
);
}
else
consistent_sync
(
phys_to_virt
(
dma_addr
),
len
,
DMA_FROM_DEVICE
);
/* Use 16-bit transfer if dma_addr is not 32-bit aligned */
if
((
dma_addr
&
0x3
)
==
0
)
{
dma_params
.
data_type
=
OMAP_DMA_DATA_TYPE_S32
;
dma_params
.
elem_count
=
8
;
/* Elements in frame */
}
else
{
dma_params
.
data_type
=
OMAP_DMA_DATA_TYPE_S16
;
dma_params
.
elem_count
=
16
;
/* Elements in frame */
fifo
=
hw_ep
->
fifo_async
;
}
dma_params
.
frame_count
=
transfer_len
/
32
;
/* Burst sz frame */
DBG
(
2
,
"ep%i %s dma ch%i dma: %08x len: %u(%u) packet_sz: %i
\n
"
,
chdat
->
epnum
,
chdat
->
tx
?
"tx"
:
"rx"
,
ch
,
dma_addr
,
transfer_len
,
len
,
packet_sz
);
/*
* Prepare omap DMA for transfer
*/
if
(
chdat
->
tx
)
{
dma_params
.
data_type
=
OMAP_DMA_DATA_TYPE_S32
;
dma_params
.
elem_count
=
8
;
/* 8x32-bit burst */
dma_params
.
frame_count
=
transfer_len
/
32
;
/* Burst sz */
dma_params
.
src_amode
=
OMAP_DMA_AMODE_POST_INC
;
dma_params
.
src_start
=
(
unsigned
long
)
dma_addr
;
dma_params
.
src_ei
=
0
;
...
...
@@ -312,13 +294,9 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
dma_params
.
sync_mode
=
OMAP_DMA_SYNC_FRAME
;
dma_params
.
src_or_dst_synch
=
0
;
/* Dest sync */
src_burst
=
OMAP_DMA_DATA_BURST_16
;
dst_burst
=
OMAP_DMA_DATA_BURST_8
;
src_burst
=
OMAP_DMA_DATA_BURST_16
;
/* 16x32 read */
dst_burst
=
OMAP_DMA_DATA_BURST_8
;
/* 8x32 write */
}
else
{
dma_params
.
data_type
=
OMAP_DMA_DATA_TYPE_S32
;
dma_params
.
elem_count
=
8
;
/* 8x32-bit burst */
dma_params
.
frame_count
=
transfer_len
/
32
;
/* Burst sz */
dma_params
.
src_amode
=
OMAP_DMA_AMODE_DOUBLE_IDX
;
dma_params
.
src_start
=
(
unsigned
long
)
fifo
;
dma_params
.
src_ei
=
1
;
...
...
@@ -337,25 +315,11 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
dst_burst
=
OMAP_DMA_DATA_BURST_16
;
/* 16x32 write */
}
/* Use 16x16 transfer if addresses not 32-bit aligned */
if
((
dma_params
.
src_start
&
0x2
)
||
(
dma_params
.
dst_start
&
0x2
))
{
DBG
(
3
,
"using 16x16 async dma from 0x%08lx to 0x%08lx
\n
"
,
dma_params
.
src_start
,
dma_params
.
dst_start
);
dma_params
.
data_type
=
OMAP_DMA_DATA_TYPE_S16
;
dma_params
.
elem_count
=
16
;
/* 16x16-bit burst */
fifo
=
hw_ep
->
fifo_async
;
/* REVISIT: Check if 16x16 sync dma might also work */
if
(
chdat
->
tx
)
dma_params
.
dst_start
=
(
unsigned
long
)
fifo
;
else
dma_params
.
src_start
=
(
unsigned
long
)
fifo
;
}
else
{
DBG
(
3
,
"ep%i %s using 16x32 sync dma from 0x%08lx to 0x%08lx
\n
"
,
DBG
(
2
,
"ep%i %s using %i-bit %s dma from 0x%08lx to 0x%08lx
\n
"
,
chdat
->
epnum
,
chdat
->
tx
?
"tx"
:
"rx"
,
(
dma_params
.
data_type
==
OMAP_DMA_DATA_TYPE_S32
)
?
32
:
16
,
((
dma_addr
&
0x3
)
==
0
)
?
"sync"
:
"async"
,
dma_params
.
src_start
,
dma_params
.
dst_start
);
}
omap_set_dma_params
(
ch
,
&
dma_params
);
omap_set_dma_src_burst_mode
(
ch
,
src_burst
);
...
...
drivers/usb/musb/virthub.c
View file @
6e0abdbc
...
...
@@ -58,11 +58,15 @@ static void musb_port_suspend(struct musb *musb, u8 bSuspend)
musb_writeb
(
pBase
,
MGC_O_HDRC_POWER
,
power
|
MGC_M_POWER_SUSPENDM
);
musb
->
port1_status
|=
USB_PORT_STAT_SUSPEND
;
musb
->
is_active
=
is_otg_enabled
(
musb
)
&&
musb
->
xceiv
.
host
->
b_hnp_enable
;
musb_platform_try_idle
(
musb
);
}
else
if
(
power
&
MGC_M_POWER_SUSPENDM
)
{
DBG
(
3
,
"Root port resumed
\n
"
);
musb_writeb
(
pBase
,
MGC_O_HDRC_POWER
,
power
|
MGC_M_POWER_RESUME
);
musb
->
is_active
=
1
;
musb_writeb
(
pBase
,
MGC_O_HDRC_POWER
,
power
);
musb
->
port1_status
&=
~
USB_PORT_STAT_SUSPEND
;
musb
->
port1_status
|=
USB_PORT_STAT_C_SUSPEND
<<
16
;
...
...
@@ -134,6 +138,7 @@ void musb_root_disconnect(struct musb *musb)
);
musb
->
port1_status
|=
USB_PORT_STAT_C_CONNECTION
<<
16
;
usb_hcd_poll_rh_status
(
musb_to_hcd
(
musb
));
musb
->
is_active
=
0
;
switch
(
musb
->
xceiv
.
state
)
{
case
OTG_STATE_A_HOST
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment