2008-12-02 22:33:44 +03:00
/*
* MUSB OTG controller driver for Blackfin Processors
*
* Copyright 2006 - 2008 Analog Devices Inc .
*
* Enter bugs at http : //blackfin.uclinux.org/
*
* Licensed under the GPL - 2 or later .
*/
# include <linux/module.h>
# include <linux/kernel.h>
# include <linux/sched.h>
# include <linux/list.h>
# include <linux/gpio.h>
# include <linux/io.h>
2012-06-26 16:10:32 +04:00
# include <linux/err.h>
2010-12-02 10:21:05 +03:00
# include <linux/platform_device.h>
# include <linux/dma-mapping.h>
2011-08-05 13:33:05 +04:00
# include <linux/prefetch.h>
2014-04-17 00:28:32 +04:00
# include <linux/usb/usb_phy_generic.h>
2008-12-02 22:33:44 +03:00
# include <asm/cacheflush.h>
# include "musb_core.h"
2011-03-31 06:48:54 +04:00
# include "musbhsdma.h"
2008-12-02 22:33:44 +03:00
# include "blackfin.h"
2010-12-02 10:42:50 +03:00
struct bfin_glue {
struct device * dev ;
struct platform_device * musb ;
2014-04-17 01:16:33 +04:00
struct platform_device * phy ;
2010-12-02 10:42:50 +03:00
} ;
2010-12-02 14:13:09 +03:00
# define glue_to_musb(g) platform_get_drvdata(g->musb)
2010-12-02 10:42:50 +03:00
2008-12-02 22:33:44 +03:00
/*
* Load an endpoint ' s FIFO
*/
void musb_write_fifo ( struct musb_hw_ep * hw_ep , u16 len , const u8 * src )
{
2011-05-18 01:25:03 +04:00
struct musb * musb = hw_ep - > musb ;
2008-12-02 22:33:44 +03:00
void __iomem * fifo = hw_ep - > fifo ;
void __iomem * epio = hw_ep - > regs ;
2009-12-21 17:49:52 +03:00
u8 epnum = hw_ep - > epnum ;
2008-12-02 22:33:44 +03:00
prefetch ( ( u8 * ) src ) ;
musb_writew ( epio , MUSB_TXCOUNT , len ) ;
2011-05-11 13:44:08 +04:00
dev_dbg ( musb - > controller , " TX ep%d fifo %p count %d buf %p, epio %p \n " ,
2008-12-02 22:33:44 +03:00
hw_ep - > epnum , fifo , len , src , epio ) ;
dump_fifo_data ( src , len ) ;
2009-12-21 17:49:52 +03:00
if ( ! ANOMALY_05000380 & & epnum ! = 0 ) {
2009-12-28 14:40:39 +03:00
u16 dma_reg ;
flush_dcache_range ( ( unsigned long ) src ,
( unsigned long ) ( src + len ) ) ;
2009-12-21 17:49:52 +03:00
/* Setup DMA address register */
2009-12-28 14:40:39 +03:00
dma_reg = ( u32 ) src ;
2009-12-21 17:49:52 +03:00
bfin_write16 ( USB_DMA_REG ( epnum , USB_DMAx_ADDR_LOW ) , dma_reg ) ;
SSYNC ( ) ;
2009-12-28 14:40:39 +03:00
dma_reg = ( u32 ) src > > 16 ;
2009-12-21 17:49:52 +03:00
bfin_write16 ( USB_DMA_REG ( epnum , USB_DMAx_ADDR_HIGH ) , dma_reg ) ;
SSYNC ( ) ;
/* Setup DMA count register */
bfin_write16 ( USB_DMA_REG ( epnum , USB_DMAx_COUNT_LOW ) , len ) ;
bfin_write16 ( USB_DMA_REG ( epnum , USB_DMAx_COUNT_HIGH ) , 0 ) ;
SSYNC ( ) ;
/* Enable the DMA */
dma_reg = ( epnum < < 4 ) | DMA_ENA | INT_ENA | DIRECTION ;
bfin_write16 ( USB_DMA_REG ( epnum , USB_DMAx_CTRL ) , dma_reg ) ;
SSYNC ( ) ;
2014-01-02 17:57:47 +04:00
/* Wait for complete */
2009-12-21 17:49:52 +03:00
while ( ! ( bfin_read_USB_DMA_INTERRUPT ( ) & ( 1 < < epnum ) ) )
cpu_relax ( ) ;
/* acknowledge dma interrupt */
bfin_write_USB_DMA_INTERRUPT ( 1 < < epnum ) ;
SSYNC ( ) ;
/* Reset DMA */
bfin_write16 ( USB_DMA_REG ( epnum , USB_DMAx_CTRL ) , 0 ) ;
SSYNC ( ) ;
} else {
SSYNC ( ) ;
if ( unlikely ( ( unsigned long ) src & 0x01 ) )
2009-12-28 14:40:39 +03:00
outsw_8 ( ( unsigned long ) fifo , src , ( len + 1 ) > > 1 ) ;
2009-12-21 17:49:52 +03:00
else
2009-12-28 14:40:39 +03:00
outsw ( ( unsigned long ) fifo , src , ( len + 1 ) > > 1 ) ;
2009-12-21 17:49:52 +03:00
}
2008-12-02 22:33:44 +03:00
}
/*
* Unload an endpoint ' s FIFO
*/
void musb_read_fifo ( struct musb_hw_ep * hw_ep , u16 len , u8 * dst )
{
2011-05-18 01:25:03 +04:00
struct musb * musb = hw_ep - > musb ;
2008-12-02 22:33:44 +03:00
void __iomem * fifo = hw_ep - > fifo ;
u8 epnum = hw_ep - > epnum ;
2009-12-21 17:49:52 +03:00
if ( ANOMALY_05000467 & & epnum ! = 0 ) {
2009-12-28 14:40:39 +03:00
u16 dma_reg ;
2009-12-21 17:49:52 +03:00
2009-12-28 14:40:39 +03:00
invalidate_dcache_range ( ( unsigned long ) dst ,
( unsigned long ) ( dst + len ) ) ;
2009-12-21 17:49:52 +03:00
/* Setup DMA address register */
2009-12-28 14:40:39 +03:00
dma_reg = ( u32 ) dst ;
2009-12-21 17:49:52 +03:00
bfin_write16 ( USB_DMA_REG ( epnum , USB_DMAx_ADDR_LOW ) , dma_reg ) ;
SSYNC ( ) ;
2009-12-28 14:40:39 +03:00
dma_reg = ( u32 ) dst > > 16 ;
2009-12-21 17:49:52 +03:00
bfin_write16 ( USB_DMA_REG ( epnum , USB_DMAx_ADDR_HIGH ) , dma_reg ) ;
SSYNC ( ) ;
/* Setup DMA count register */
bfin_write16 ( USB_DMA_REG ( epnum , USB_DMAx_COUNT_LOW ) , len ) ;
bfin_write16 ( USB_DMA_REG ( epnum , USB_DMAx_COUNT_HIGH ) , 0 ) ;
SSYNC ( ) ;
/* Enable the DMA */
dma_reg = ( epnum < < 4 ) | DMA_ENA | INT_ENA ;
bfin_write16 ( USB_DMA_REG ( epnum , USB_DMAx_CTRL ) , dma_reg ) ;
SSYNC ( ) ;
2014-01-02 17:57:47 +04:00
/* Wait for complete */
2009-12-21 17:49:52 +03:00
while ( ! ( bfin_read_USB_DMA_INTERRUPT ( ) & ( 1 < < epnum ) ) )
cpu_relax ( ) ;
/* acknowledge dma interrupt */
bfin_write_USB_DMA_INTERRUPT ( 1 < < epnum ) ;
SSYNC ( ) ;
/* Reset DMA */
bfin_write16 ( USB_DMA_REG ( epnum , USB_DMAx_CTRL ) , 0 ) ;
SSYNC ( ) ;
} else {
SSYNC ( ) ;
/* Read the last byte of packet with odd size from address fifo + 4
* to trigger 1 byte access to EP0 FIFO .
*/
if ( len = = 1 )
* dst = ( u8 ) inw ( ( unsigned long ) fifo + 4 ) ;
else {
if ( unlikely ( ( unsigned long ) dst & 0x01 ) )
insw_8 ( ( unsigned long ) fifo , dst , len > > 1 ) ;
else
insw ( ( unsigned long ) fifo , dst , len > > 1 ) ;
if ( len & 0x01 )
* ( dst + len - 1 ) = ( u8 ) inw ( ( unsigned long ) fifo + 4 ) ;
}
}
2011-05-11 13:44:08 +04:00
dev_dbg ( musb - > controller , " %cX ep%d fifo %p count %d buf %p \n " ,
2009-11-16 13:49:19 +03:00
' R ' , hw_ep - > epnum , fifo , len , dst ) ;
2008-12-02 22:33:44 +03:00
dump_fifo_data ( dst , len ) ;
}
static irqreturn_t blackfin_interrupt ( int irq , void * __hci )
{
unsigned long flags ;
irqreturn_t retval = IRQ_NONE ;
struct musb * musb = __hci ;
spin_lock_irqsave ( & musb - > lock , flags ) ;
musb - > int_usb = musb_readb ( musb - > mregs , MUSB_INTRUSB ) ;
musb - > int_tx = musb_readw ( musb - > mregs , MUSB_INTRTX ) ;
musb - > int_rx = musb_readw ( musb - > mregs , MUSB_INTRRX ) ;
if ( musb - > int_usb | | musb - > int_tx | | musb - > int_rx ) {
musb_writeb ( musb - > mregs , MUSB_INTRUSB , musb - > int_usb ) ;
musb_writew ( musb - > mregs , MUSB_INTRTX , musb - > int_tx ) ;
musb_writew ( musb - > mregs , MUSB_INTRRX , musb - > int_rx ) ;
retval = musb_interrupt ( musb ) ;
}
2010-03-25 14:25:19 +03:00
/* Start sampling ID pin, when plug is removed from MUSB */
2011-11-24 17:46:26 +04:00
if ( ( musb - > xceiv - > state = = OTG_STATE_B_IDLE
| | musb - > xceiv - > state = = OTG_STATE_A_WAIT_BCON ) | |
2010-10-23 14:12:00 +04:00
( musb - > int_usb & MUSB_INTR_DISCONNECT & & is_host_active ( musb ) ) ) {
2010-03-25 14:25:19 +03:00
mod_timer ( & musb_conn_timer , jiffies + TIMER_DELAY ) ;
musb - > a_wait_bcon = TIMER_DELAY ;
}
2008-12-02 22:33:44 +03:00
spin_unlock_irqrestore ( & musb - > lock , flags ) ;
2010-03-25 14:14:25 +03:00
return retval ;
2008-12-02 22:33:44 +03:00
}
static void musb_conn_timer_handler ( unsigned long _musb )
{
struct musb * musb = ( void * ) _musb ;
unsigned long flags ;
u16 val ;
2010-03-25 14:25:19 +03:00
static u8 toggle ;
2008-12-02 22:33:44 +03:00
spin_lock_irqsave ( & musb - > lock , flags ) ;
2009-03-31 23:30:04 +04:00
switch ( musb - > xceiv - > state ) {
2008-12-02 22:33:44 +03:00
case OTG_STATE_A_IDLE :
case OTG_STATE_A_WAIT_BCON :
/* Start a new session */
val = musb_readw ( musb - > mregs , MUSB_DEVCTL ) ;
2010-03-25 14:25:19 +03:00
val & = ~ MUSB_DEVCTL_SESSION ;
musb_writew ( musb - > mregs , MUSB_DEVCTL , val ) ;
2008-12-02 22:33:44 +03:00
val | = MUSB_DEVCTL_SESSION ;
musb_writew ( musb - > mregs , MUSB_DEVCTL , val ) ;
2010-03-25 14:25:19 +03:00
/* Check if musb is host or peripheral. */
val = musb_readw ( musb - > mregs , MUSB_DEVCTL ) ;
if ( ! ( val & MUSB_DEVCTL_BDEVICE ) ) {
gpio_set_value ( musb - > config - > gpio_vrsel , 1 ) ;
musb - > xceiv - > state = OTG_STATE_A_WAIT_BCON ;
} else {
gpio_set_value ( musb - > config - > gpio_vrsel , 0 ) ;
/* Ignore VBUSERROR and SUSPEND IRQ */
val = musb_readb ( musb - > mregs , MUSB_INTRUSBE ) ;
val & = ~ MUSB_INTR_VBUSERROR ;
musb_writeb ( musb - > mregs , MUSB_INTRUSBE , val ) ;
val = MUSB_INTR_SUSPEND | MUSB_INTR_VBUSERROR ;
musb_writeb ( musb - > mregs , MUSB_INTRUSB , val ) ;
2011-11-24 17:46:26 +04:00
musb - > xceiv - > state = OTG_STATE_B_IDLE ;
2010-03-25 14:25:19 +03:00
}
mod_timer ( & musb_conn_timer , jiffies + TIMER_DELAY ) ;
break ;
case OTG_STATE_B_IDLE :
2011-11-24 17:46:26 +04:00
/*
* Start a new session . It seems that MUSB needs taking
2010-03-25 14:25:19 +03:00
* some time to recognize the type of the plug inserted ?
*/
val = musb_readw ( musb - > mregs , MUSB_DEVCTL ) ;
val | = MUSB_DEVCTL_SESSION ;
musb_writew ( musb - > mregs , MUSB_DEVCTL , val ) ;
2008-12-02 22:33:44 +03:00
val = musb_readw ( musb - > mregs , MUSB_DEVCTL ) ;
2010-03-25 14:25:19 +03:00
2008-12-02 22:33:44 +03:00
if ( ! ( val & MUSB_DEVCTL_BDEVICE ) ) {
gpio_set_value ( musb - > config - > gpio_vrsel , 1 ) ;
2009-03-31 23:30:04 +04:00
musb - > xceiv - > state = OTG_STATE_A_WAIT_BCON ;
2008-12-02 22:33:44 +03:00
} else {
gpio_set_value ( musb - > config - > gpio_vrsel , 0 ) ;
/* Ignore VBUSERROR and SUSPEND IRQ */
val = musb_readb ( musb - > mregs , MUSB_INTRUSBE ) ;
val & = ~ MUSB_INTR_VBUSERROR ;
musb_writeb ( musb - > mregs , MUSB_INTRUSBE , val ) ;
val = MUSB_INTR_SUSPEND | MUSB_INTR_VBUSERROR ;
musb_writeb ( musb - > mregs , MUSB_INTRUSB , val ) ;
2010-03-25 14:25:19 +03:00
/* Toggle the Soft Conn bit, so that we can response to
* the inserting of either A - plug or B - plug .
*/
if ( toggle ) {
val = musb_readb ( musb - > mregs , MUSB_POWER ) ;
val & = ~ MUSB_POWER_SOFTCONN ;
musb_writeb ( musb - > mregs , MUSB_POWER , val ) ;
toggle = 0 ;
} else {
val = musb_readb ( musb - > mregs , MUSB_POWER ) ;
val | = MUSB_POWER_SOFTCONN ;
musb_writeb ( musb - > mregs , MUSB_POWER , val ) ;
toggle = 1 ;
}
/* The delay time is set to 1/4 second by default,
* shortening it , if accelerating A - plug detection
* is needed in OTG mode .
*/
mod_timer ( & musb_conn_timer , jiffies + TIMER_DELAY / 4 ) ;
2008-12-02 22:33:44 +03:00
}
break ;
default :
2011-05-11 13:44:08 +04:00
dev_dbg ( musb - > controller , " %s state not handled \n " ,
2013-03-07 12:39:57 +04:00
usb_otg_state_string ( musb - > xceiv - > state ) ) ;
2008-12-02 22:33:44 +03:00
break ;
}
spin_unlock_irqrestore ( & musb - > lock , flags ) ;
2011-05-11 13:44:08 +04:00
dev_dbg ( musb - > controller , " state is %s \n " ,
2013-03-07 12:39:57 +04:00
usb_otg_state_string ( musb - > xceiv - > state ) ) ;
2008-12-02 22:33:44 +03:00
}
2010-12-01 14:22:05 +03:00
static void bfin_musb_enable ( struct musb * musb )
2008-12-02 22:33:44 +03:00
{
2011-11-24 17:46:26 +04:00
/* REVISIT is this really correct ? */
2008-12-02 22:33:44 +03:00
}
2010-12-01 14:22:05 +03:00
static void bfin_musb_disable ( struct musb * musb )
2008-12-02 22:33:44 +03:00
{
}
2010-12-01 14:22:05 +03:00
static void bfin_musb_set_vbus ( struct musb * musb , int is_on )
2008-12-02 22:33:44 +03:00
{
2010-03-12 11:29:10 +03:00
int value = musb - > config - > gpio_vrsel_active ;
if ( ! is_on )
value = ! value ;
gpio_set_value ( musb - > config - > gpio_vrsel , value ) ;
2008-12-02 22:33:44 +03:00
2011-05-11 13:44:08 +04:00
dev_dbg ( musb - > controller , " VBUS %s, devctl %02x "
2008-12-02 22:33:44 +03:00
/* otg %3x conf %08x prcm %08x */ " \n " ,
2013-03-07 12:39:57 +04:00
usb_otg_state_string ( musb - > xceiv - > state ) ,
2008-12-02 22:33:44 +03:00
musb_readb ( musb - > mregs , MUSB_DEVCTL ) ) ;
}
2012-02-13 15:24:02 +04:00
static int bfin_musb_set_power ( struct usb_phy * x , unsigned mA )
2008-12-02 22:33:44 +03:00
{
return 0 ;
}
2011-03-21 21:06:32 +03:00
static int bfin_musb_vbus_status ( struct musb * musb )
2008-12-02 22:33:44 +03:00
{
return 0 ;
}
2010-12-01 14:22:05 +03:00
static int bfin_musb_set_mode ( struct musb * musb , u8 musb_mode )
2008-12-02 22:33:44 +03:00
{
2009-11-16 13:49:25 +03:00
return - EIO ;
2008-12-02 22:33:44 +03:00
}
2011-03-31 06:48:54 +04:00
static int bfin_musb_adjust_channel_params ( struct dma_channel * channel ,
u16 packet_sz , u8 * mode ,
dma_addr_t * dma_addr , u32 * len )
{
struct musb_dma_channel * musb_channel = channel - > private_data ;
/*
* Anomaly 05000450 might cause data corruption when using DMA
* MODE 1 transmits with short packet . So to work around this ,
* we truncate all MODE 1 transfers down to a multiple of the
* max packet size , and then do the last short packet transfer
* ( if there is any ) using MODE 0.
*/
if ( ANOMALY_05000450 ) {
if ( musb_channel - > transmit & & * mode = = 1 )
* len = * len - ( * len % packet_sz ) ;
}
return 0 ;
}
2010-12-01 14:22:05 +03:00
static void bfin_musb_reg_init ( struct musb * musb )
2008-12-02 22:33:44 +03:00
{
2008-12-02 22:33:45 +03:00
if ( ANOMALY_05000346 ) {
bfin_write_USB_APHY_CALIB ( ANOMALY_05000346_value ) ;
SSYNC ( ) ;
}
2008-12-02 22:33:44 +03:00
2008-12-02 22:33:45 +03:00
if ( ANOMALY_05000347 ) {
bfin_write_USB_APHY_CNTRL ( 0x0 ) ;
SSYNC ( ) ;
}
2008-12-02 22:33:44 +03:00
/* Configure PLL oscillator register */
2010-10-23 14:12:01 +04:00
bfin_write_USB_PLLOSC_CTRL ( 0x3080 |
( ( 480 / musb - > config - > clkin ) < < 1 ) ) ;
2008-12-02 22:33:44 +03:00
SSYNC ( ) ;
bfin_write_USB_SRP_CLKDIV ( ( get_sclk ( ) / 1000 ) / 32 - 1 ) ;
SSYNC ( ) ;
bfin_write_USB_EP_NI0_RXMAXP ( 64 ) ;
SSYNC ( ) ;
bfin_write_USB_EP_NI0_TXMAXP ( 64 ) ;
SSYNC ( ) ;
/* Route INTRUSB/INTR_RX/INTR_TX to USB_INT0*/
bfin_write_USB_GLOBINTR ( 0x7 ) ;
SSYNC ( ) ;
bfin_write_USB_GLOBAL_CTL ( GLOBAL_ENA | EP1_TX_ENA | EP2_TX_ENA |
EP3_TX_ENA | EP4_TX_ENA | EP5_TX_ENA |
EP6_TX_ENA | EP7_TX_ENA | EP1_RX_ENA |
EP2_RX_ENA | EP3_RX_ENA | EP4_RX_ENA |
EP5_RX_ENA | EP6_RX_ENA | EP7_RX_ENA ) ;
SSYNC ( ) ;
2010-12-01 14:22:05 +03:00
}
static int bfin_musb_init ( struct musb * musb )
{
/*
* Rev 1.0 BF549 EZ - KITs require PE7 to be high for both DEVICE
* and OTG HOST modes , while rev 1.1 and greater require PE7 to
* be low for DEVICE mode and high for HOST mode . We set it high
* here because we are in host mode
*/
if ( gpio_request ( musb - > config - > gpio_vrsel , " USB_VRSEL " ) ) {
printk ( KERN_ERR " Failed ro request USB_VRSEL GPIO_%d \n " ,
musb - > config - > gpio_vrsel ) ;
return - ENODEV ;
}
gpio_direction_output ( musb - > config - > gpio_vrsel , 0 ) ;
2012-06-22 15:32:46 +04:00
musb - > xceiv = usb_get_phy ( USB_PHY_TYPE_USB2 ) ;
2012-06-26 16:10:32 +04:00
if ( IS_ERR_OR_NULL ( musb - > xceiv ) ) {
2010-12-01 14:22:05 +03:00
gpio_free ( musb - > config - > gpio_vrsel ) ;
2013-01-04 19:13:58 +04:00
return - EPROBE_DEFER ;
2010-12-01 14:22:05 +03:00
}
bfin_musb_reg_init ( musb ) ;
2008-12-02 22:33:44 +03:00
2011-11-24 17:46:26 +04:00
setup_timer ( & musb_conn_timer , musb_conn_timer_handler ,
( unsigned long ) musb ) ;
musb - > xceiv - > set_power = bfin_musb_set_power ;
2008-12-02 22:33:44 +03:00
musb - > isr = blackfin_interrupt ;
2011-01-21 08:39:20 +03:00
musb - > double_buffer_not_ok = true ;
2008-12-02 22:33:44 +03:00
return 0 ;
}
2010-12-01 14:22:05 +03:00
static int bfin_musb_exit ( struct musb * musb )
2008-12-02 22:33:44 +03:00
{
gpio_free ( musb - > config - > gpio_vrsel ) ;
2012-06-22 15:32:45 +04:00
usb_put_phy ( musb - > xceiv ) ;
2014-04-17 01:05:17 +04:00
2008-12-02 22:33:44 +03:00
return 0 ;
}
2010-12-01 14:22:05 +03:00
2010-12-02 10:48:58 +03:00
static const struct musb_platform_ops bfin_ops = {
2010-12-01 14:22:05 +03:00
. init = bfin_musb_init ,
. exit = bfin_musb_exit ,
. enable = bfin_musb_enable ,
. disable = bfin_musb_disable ,
. set_mode = bfin_musb_set_mode ,
. vbus_status = bfin_musb_vbus_status ,
. set_vbus = bfin_musb_set_vbus ,
2011-03-31 06:48:54 +04:00
. adjust_channel_params = bfin_musb_adjust_channel_params ,
2010-12-01 14:22:05 +03:00
} ;
2010-12-02 10:21:05 +03:00
static u64 bfin_dmamask = DMA_BIT_MASK ( 32 ) ;
2012-11-19 22:21:48 +04:00
static int bfin_probe ( struct platform_device * pdev )
2010-12-02 10:21:05 +03:00
{
2013-04-24 18:21:42 +04:00
struct resource musb_resources [ 2 ] ;
2013-07-30 12:03:12 +04:00
struct musb_hdrc_platform_data * pdata = dev_get_platdata ( & pdev - > dev ) ;
2010-12-02 10:21:05 +03:00
struct platform_device * musb ;
2010-12-02 10:42:50 +03:00
struct bfin_glue * glue ;
2010-12-02 10:21:05 +03:00
int ret = - ENOMEM ;
usb: musb: backfin: Introduce the use of the managed version of kzalloc
This patch moves data allocated using kzalloc to managed data allocated
using devm_kzalloc and cleans now unnecessary kfrees in probe and remove
functions. Also, a label is done away with and err2 and err3 renamed.
The following Coccinelle semantic patch was used for making the change:
@platform@
identifier p, probefn, removefn;
@@
struct platform_driver p = {
.probe = probefn,
.remove = removefn,
};
@prb@
identifier platform.probefn, pdev;
expression e, e1, e2;
@@
probefn(struct platform_device *pdev, ...) {
<+...
- e = kzalloc(e1, e2)
+ e = devm_kzalloc(&pdev->dev, e1, e2)
...
?-kfree(e);
...+>
}
@rem depends on prb@
identifier platform.removefn;
expression e;
@@
removefn(...) {
<...
- kfree(e);
...>
}
Signed-off-by: Himangi Saraogi <himangi774@gmail.com>
Acked-by: Julia Lawall <julia.lawall@lip6.fr>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2014-06-02 00:43:21 +04:00
glue = devm_kzalloc ( & pdev - > dev , sizeof ( * glue ) , GFP_KERNEL ) ;
2014-10-14 11:56:09 +04:00
if ( ! glue )
2010-12-02 10:42:50 +03:00
goto err0 ;
2012-10-31 19:12:43 +04:00
musb = platform_device_alloc ( " musb-hdrc " , PLATFORM_DEVID_AUTO ) ;
2014-10-14 11:56:09 +04:00
if ( ! musb )
usb: musb: backfin: Introduce the use of the managed version of kzalloc
This patch moves data allocated using kzalloc to managed data allocated
using devm_kzalloc and cleans now unnecessary kfrees in probe and remove
functions. Also, a label is done away with and err2 and err3 renamed.
The following Coccinelle semantic patch was used for making the change:
@platform@
identifier p, probefn, removefn;
@@
struct platform_driver p = {
.probe = probefn,
.remove = removefn,
};
@prb@
identifier platform.probefn, pdev;
expression e, e1, e2;
@@
probefn(struct platform_device *pdev, ...) {
<+...
- e = kzalloc(e1, e2)
+ e = devm_kzalloc(&pdev->dev, e1, e2)
...
?-kfree(e);
...+>
}
@rem depends on prb@
identifier platform.removefn;
expression e;
@@
removefn(...) {
<...
- kfree(e);
...>
}
Signed-off-by: Himangi Saraogi <himangi774@gmail.com>
Acked-by: Julia Lawall <julia.lawall@lip6.fr>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2014-06-02 00:43:21 +04:00
goto err0 ;
2010-12-02 10:21:05 +03:00
musb - > dev . parent = & pdev - > dev ;
musb - > dev . dma_mask = & bfin_dmamask ;
musb - > dev . coherent_dma_mask = bfin_dmamask ;
2010-12-02 10:42:50 +03:00
glue - > dev = & pdev - > dev ;
glue - > musb = musb ;
2010-12-02 10:48:58 +03:00
pdata - > platform_ops = & bfin_ops ;
2014-04-17 01:16:33 +04:00
glue - > phy = usb_phy_generic_register ( ) ;
if ( IS_ERR ( glue - > phy ) )
usb: musb: backfin: Introduce the use of the managed version of kzalloc
This patch moves data allocated using kzalloc to managed data allocated
using devm_kzalloc and cleans now unnecessary kfrees in probe and remove
functions. Also, a label is done away with and err2 and err3 renamed.
The following Coccinelle semantic patch was used for making the change:
@platform@
identifier p, probefn, removefn;
@@
struct platform_driver p = {
.probe = probefn,
.remove = removefn,
};
@prb@
identifier platform.probefn, pdev;
expression e, e1, e2;
@@
probefn(struct platform_device *pdev, ...) {
<+...
- e = kzalloc(e1, e2)
+ e = devm_kzalloc(&pdev->dev, e1, e2)
...
?-kfree(e);
...+>
}
@rem depends on prb@
identifier platform.removefn;
expression e;
@@
removefn(...) {
<...
- kfree(e);
...>
}
Signed-off-by: Himangi Saraogi <himangi774@gmail.com>
Acked-by: Julia Lawall <julia.lawall@lip6.fr>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2014-06-02 00:43:21 +04:00
goto err1 ;
2010-12-02 10:42:50 +03:00
platform_set_drvdata ( pdev , glue ) ;
2010-12-02 10:21:05 +03:00
2013-04-24 18:21:42 +04:00
memset ( musb_resources , 0x00 , sizeof ( * musb_resources ) *
ARRAY_SIZE ( musb_resources ) ) ;
musb_resources [ 0 ] . name = pdev - > resource [ 0 ] . name ;
musb_resources [ 0 ] . start = pdev - > resource [ 0 ] . start ;
musb_resources [ 0 ] . end = pdev - > resource [ 0 ] . end ;
musb_resources [ 0 ] . flags = pdev - > resource [ 0 ] . flags ;
musb_resources [ 1 ] . name = pdev - > resource [ 1 ] . name ;
musb_resources [ 1 ] . start = pdev - > resource [ 1 ] . start ;
musb_resources [ 1 ] . end = pdev - > resource [ 1 ] . end ;
musb_resources [ 1 ] . flags = pdev - > resource [ 1 ] . flags ;
ret = platform_device_add_resources ( musb , musb_resources ,
ARRAY_SIZE ( musb_resources ) ) ;
2010-12-02 10:21:05 +03:00
if ( ret ) {
dev_err ( & pdev - > dev , " failed to add resources \n " ) ;
usb: musb: backfin: Introduce the use of the managed version of kzalloc
This patch moves data allocated using kzalloc to managed data allocated
using devm_kzalloc and cleans now unnecessary kfrees in probe and remove
functions. Also, a label is done away with and err2 and err3 renamed.
The following Coccinelle semantic patch was used for making the change:
@platform@
identifier p, probefn, removefn;
@@
struct platform_driver p = {
.probe = probefn,
.remove = removefn,
};
@prb@
identifier platform.probefn, pdev;
expression e, e1, e2;
@@
probefn(struct platform_device *pdev, ...) {
<+...
- e = kzalloc(e1, e2)
+ e = devm_kzalloc(&pdev->dev, e1, e2)
...
?-kfree(e);
...+>
}
@rem depends on prb@
identifier platform.removefn;
expression e;
@@
removefn(...) {
<...
- kfree(e);
...>
}
Signed-off-by: Himangi Saraogi <himangi774@gmail.com>
Acked-by: Julia Lawall <julia.lawall@lip6.fr>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2014-06-02 00:43:21 +04:00
goto err2 ;
2010-12-02 10:21:05 +03:00
}
ret = platform_device_add_data ( musb , pdata , sizeof ( * pdata ) ) ;
if ( ret ) {
dev_err ( & pdev - > dev , " failed to add platform_data \n " ) ;
usb: musb: backfin: Introduce the use of the managed version of kzalloc
This patch moves data allocated using kzalloc to managed data allocated
using devm_kzalloc and cleans now unnecessary kfrees in probe and remove
functions. Also, a label is done away with and err2 and err3 renamed.
The following Coccinelle semantic patch was used for making the change:
@platform@
identifier p, probefn, removefn;
@@
struct platform_driver p = {
.probe = probefn,
.remove = removefn,
};
@prb@
identifier platform.probefn, pdev;
expression e, e1, e2;
@@
probefn(struct platform_device *pdev, ...) {
<+...
- e = kzalloc(e1, e2)
+ e = devm_kzalloc(&pdev->dev, e1, e2)
...
?-kfree(e);
...+>
}
@rem depends on prb@
identifier platform.removefn;
expression e;
@@
removefn(...) {
<...
- kfree(e);
...>
}
Signed-off-by: Himangi Saraogi <himangi774@gmail.com>
Acked-by: Julia Lawall <julia.lawall@lip6.fr>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2014-06-02 00:43:21 +04:00
goto err2 ;
2010-12-02 10:21:05 +03:00
}
ret = platform_device_add ( musb ) ;
if ( ret ) {
dev_err ( & pdev - > dev , " failed to register musb device \n " ) ;
usb: musb: backfin: Introduce the use of the managed version of kzalloc
This patch moves data allocated using kzalloc to managed data allocated
using devm_kzalloc and cleans now unnecessary kfrees in probe and remove
functions. Also, a label is done away with and err2 and err3 renamed.
The following Coccinelle semantic patch was used for making the change:
@platform@
identifier p, probefn, removefn;
@@
struct platform_driver p = {
.probe = probefn,
.remove = removefn,
};
@prb@
identifier platform.probefn, pdev;
expression e, e1, e2;
@@
probefn(struct platform_device *pdev, ...) {
<+...
- e = kzalloc(e1, e2)
+ e = devm_kzalloc(&pdev->dev, e1, e2)
...
?-kfree(e);
...+>
}
@rem depends on prb@
identifier platform.removefn;
expression e;
@@
removefn(...) {
<...
- kfree(e);
...>
}
Signed-off-by: Himangi Saraogi <himangi774@gmail.com>
Acked-by: Julia Lawall <julia.lawall@lip6.fr>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2014-06-02 00:43:21 +04:00
goto err2 ;
2010-12-02 10:21:05 +03:00
}
return 0 ;
2014-04-17 01:16:33 +04:00
err2 :
usb: musb: backfin: Introduce the use of the managed version of kzalloc
This patch moves data allocated using kzalloc to managed data allocated
using devm_kzalloc and cleans now unnecessary kfrees in probe and remove
functions. Also, a label is done away with and err2 and err3 renamed.
The following Coccinelle semantic patch was used for making the change:
@platform@
identifier p, probefn, removefn;
@@
struct platform_driver p = {
.probe = probefn,
.remove = removefn,
};
@prb@
identifier platform.probefn, pdev;
expression e, e1, e2;
@@
probefn(struct platform_device *pdev, ...) {
<+...
- e = kzalloc(e1, e2)
+ e = devm_kzalloc(&pdev->dev, e1, e2)
...
?-kfree(e);
...+>
}
@rem depends on prb@
identifier platform.removefn;
expression e;
@@
removefn(...) {
<...
- kfree(e);
...>
}
Signed-off-by: Himangi Saraogi <himangi774@gmail.com>
Acked-by: Julia Lawall <julia.lawall@lip6.fr>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2014-06-02 00:43:21 +04:00
usb_phy_generic_unregister ( glue - > phy ) ;
2010-12-02 10:21:05 +03:00
2010-12-02 10:42:50 +03:00
err1 :
usb: musb: backfin: Introduce the use of the managed version of kzalloc
This patch moves data allocated using kzalloc to managed data allocated
using devm_kzalloc and cleans now unnecessary kfrees in probe and remove
functions. Also, a label is done away with and err2 and err3 renamed.
The following Coccinelle semantic patch was used for making the change:
@platform@
identifier p, probefn, removefn;
@@
struct platform_driver p = {
.probe = probefn,
.remove = removefn,
};
@prb@
identifier platform.probefn, pdev;
expression e, e1, e2;
@@
probefn(struct platform_device *pdev, ...) {
<+...
- e = kzalloc(e1, e2)
+ e = devm_kzalloc(&pdev->dev, e1, e2)
...
?-kfree(e);
...+>
}
@rem depends on prb@
identifier platform.removefn;
expression e;
@@
removefn(...) {
<...
- kfree(e);
...>
}
Signed-off-by: Himangi Saraogi <himangi774@gmail.com>
Acked-by: Julia Lawall <julia.lawall@lip6.fr>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2014-06-02 00:43:21 +04:00
platform_device_put ( musb ) ;
2010-12-02 10:42:50 +03:00
2010-12-02 10:21:05 +03:00
err0 :
return ret ;
}
2012-11-19 22:26:20 +04:00
static int bfin_remove ( struct platform_device * pdev )
2010-12-02 10:21:05 +03:00
{
2010-12-02 10:42:50 +03:00
struct bfin_glue * glue = platform_get_drvdata ( pdev ) ;
2010-12-02 10:21:05 +03:00
2012-10-23 09:26:00 +04:00
platform_device_unregister ( glue - > musb ) ;
2014-04-17 01:16:33 +04:00
usb_phy_generic_unregister ( glue - > phy ) ;
2010-12-02 10:21:05 +03:00
return 0 ;
}
2010-12-02 14:13:09 +03:00
# ifdef CONFIG_PM
static int bfin_suspend ( struct device * dev )
{
struct bfin_glue * glue = dev_get_drvdata ( dev ) ;
struct musb * musb = glue_to_musb ( glue ) ;
if ( is_host_active ( musb ) )
/*
* During hibernate gpio_vrsel will change from high to low
* low which will generate wakeup event resume the system
* immediately . Set it to 0 before hibernate to avoid this
* wakeup event .
*/
gpio_set_value ( musb - > config - > gpio_vrsel , 0 ) ;
return 0 ;
}
static int bfin_resume ( struct device * dev )
{
struct bfin_glue * glue = dev_get_drvdata ( dev ) ;
struct musb * musb = glue_to_musb ( glue ) ;
bfin_musb_reg_init ( musb ) ;
return 0 ;
}
# endif
2013-09-30 23:02:08 +04:00
static SIMPLE_DEV_PM_OPS ( bfin_pm_ops , bfin_suspend , bfin_resume ) ;
2010-12-02 10:21:05 +03:00
static struct platform_driver bfin_driver = {
2012-01-26 14:40:23 +04:00
. probe = bfin_probe ,
2010-12-02 10:21:05 +03:00
. remove = __exit_p ( bfin_remove ) ,
. driver = {
2011-03-22 21:43:37 +03:00
. name = " musb-blackfin " ,
2013-09-30 23:02:08 +04:00
. pm = & bfin_pm_ops ,
2010-12-02 10:21:05 +03:00
} ,
} ;
MODULE_DESCRIPTION ( " Blackfin MUSB Glue Layer " ) ;
MODULE_AUTHOR ( " Bryan Wy <cooloney@kernel.org> " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;
2012-10-10 22:36:52 +04:00
module_platform_driver ( bfin_driver ) ;