@@ -128,8 +128,6 @@ struct s3c_hsotg_ep {
128
128
char name [10 ];
129
129
};
130
130
131
- #define S3C_HSOTG_EPS (8+1) /* limit to 9 for the moment */
132
-
133
131
/**
134
132
* struct s3c_hsotg - driver state.
135
133
* @dev: The parent device supplied to the probe function
@@ -140,6 +138,7 @@ struct s3c_hsotg_ep {
140
138
* @irq: The IRQ number we are using
141
139
* @supplies: Definition of USB power supplies
142
140
* @dedicated_fifos: Set if the hardware has dedicated IN-EP fifos.
141
+ * @num_of_eps: Number of available EPs (excluding EP0)
143
142
* @debug_root: root directrory for debugfs.
144
143
* @debug_file: main status file for debugfs.
145
144
* @debug_fifo: FIFO status file for debugfs.
@@ -164,6 +163,7 @@ struct s3c_hsotg {
164
163
struct regulator_bulk_data supplies [ARRAY_SIZE (s3c_hsotg_supply_names )];
165
164
166
165
unsigned int dedicated_fifos :1 ;
166
+ unsigned char num_of_eps ;
167
167
168
168
struct dentry * debug_root ;
169
169
struct dentry * debug_file ;
@@ -177,7 +177,7 @@ struct s3c_hsotg {
177
177
struct usb_gadget gadget ;
178
178
unsigned int setup ;
179
179
unsigned long last_rst ;
180
- struct s3c_hsotg_ep eps [] ;
180
+ struct s3c_hsotg_ep * eps ;
181
181
};
182
182
183
183
/**
@@ -952,7 +952,7 @@ static struct s3c_hsotg_ep *ep_from_windex(struct s3c_hsotg *hsotg,
952
952
if (windex >= 0x100 )
953
953
return NULL ;
954
954
955
- if (idx > S3C_HSOTG_EPS )
955
+ if (idx > hsotg -> num_of_eps )
956
956
return NULL ;
957
957
958
958
if (idx && ep -> dir_in != dir )
@@ -2036,7 +2036,7 @@ static void s3c_hsotg_irq_enumdone(struct s3c_hsotg *hsotg)
2036
2036
if (ep0_mps ) {
2037
2037
int i ;
2038
2038
s3c_hsotg_set_ep_maxpacket (hsotg , 0 , ep0_mps );
2039
- for (i = 1 ; i < S3C_HSOTG_EPS ; i ++ )
2039
+ for (i = 1 ; i < hsotg -> num_of_eps ; i ++ )
2040
2040
s3c_hsotg_set_ep_maxpacket (hsotg , i , ep_mps );
2041
2041
}
2042
2042
@@ -2099,7 +2099,7 @@ static void s3c_hsotg_disconnect(struct s3c_hsotg *hsotg)
2099
2099
{
2100
2100
unsigned ep ;
2101
2101
2102
- for (ep = 0 ; ep < S3C_HSOTG_EPS ; ep ++ )
2102
+ for (ep = 0 ; ep < hsotg -> num_of_eps ; ep ++ )
2103
2103
kill_all_requests (hsotg , & hsotg -> eps [ep ], - ESHUTDOWN , true);
2104
2104
2105
2105
call_gadget (hsotg , disconnect );
@@ -2117,7 +2117,7 @@ static void s3c_hsotg_irq_fifoempty(struct s3c_hsotg *hsotg, bool periodic)
2117
2117
2118
2118
/* look through for any more data to transmit */
2119
2119
2120
- for (epno = 0 ; epno < S3C_HSOTG_EPS ; epno ++ ) {
2120
+ for (epno = 0 ; epno < hsotg -> num_of_eps ; epno ++ ) {
2121
2121
ep = & hsotg -> eps [epno ];
2122
2122
2123
2123
if (!ep -> dir_in )
@@ -2783,6 +2783,45 @@ static void s3c_hsotg_phy_disable(struct s3c_hsotg *hsotg)
2783
2783
hsotg -> plat -> phy_exit (pdev , hsotg -> plat -> phy_type );
2784
2784
}
2785
2785
2786
+ static void s3c_hsotg_init (struct s3c_hsotg * hsotg )
2787
+ {
2788
+ /* unmask subset of endpoint interrupts */
2789
+
2790
+ writel (S3C_DIEPMSK_TimeOUTMsk | S3C_DIEPMSK_AHBErrMsk |
2791
+ S3C_DIEPMSK_EPDisbldMsk | S3C_DIEPMSK_XferComplMsk ,
2792
+ hsotg -> regs + S3C_DIEPMSK );
2793
+
2794
+ writel (S3C_DOEPMSK_SetupMsk | S3C_DOEPMSK_AHBErrMsk |
2795
+ S3C_DOEPMSK_EPDisbldMsk | S3C_DOEPMSK_XferComplMsk ,
2796
+ hsotg -> regs + S3C_DOEPMSK );
2797
+
2798
+ writel (0 , hsotg -> regs + S3C_DAINTMSK );
2799
+
2800
+ /* Be in disconnected state until gadget is registered */
2801
+ __orr32 (hsotg -> regs + S3C_DCTL , S3C_DCTL_SftDiscon );
2802
+
2803
+ if (0 ) {
2804
+ /* post global nak until we're ready */
2805
+ writel (S3C_DCTL_SGNPInNAK | S3C_DCTL_SGOUTNak ,
2806
+ hsotg -> regs + S3C_DCTL );
2807
+ }
2808
+
2809
+ /* setup fifos */
2810
+
2811
+ dev_dbg (hsotg -> dev , "GRXFSIZ=0x%08x, GNPTXFSIZ=0x%08x\n" ,
2812
+ readl (hsotg -> regs + S3C_GRXFSIZ ),
2813
+ readl (hsotg -> regs + S3C_GNPTXFSIZ ));
2814
+
2815
+ s3c_hsotg_init_fifo (hsotg );
2816
+
2817
+ /* set the PLL on, remove the HNP/SRP and set the PHY */
2818
+ writel (S3C_GUSBCFG_PHYIf16 | S3C_GUSBCFG_TOutCal (7 ) | (0x5 << 10 ),
2819
+ hsotg -> regs + S3C_GUSBCFG );
2820
+
2821
+ writel (using_dma (hsotg ) ? S3C_GAHBCFG_DMAEn : 0x0 ,
2822
+ hsotg -> regs + S3C_GAHBCFG );
2823
+ }
2824
+
2786
2825
static int s3c_hsotg_start (struct usb_gadget_driver * driver ,
2787
2826
int (* bind )(struct usb_gadget * ))
2788
2827
{
@@ -2853,7 +2892,7 @@ static int s3c_hsotg_stop(struct usb_gadget_driver *driver)
2853
2892
return - EINVAL ;
2854
2893
2855
2894
/* all endpoints should be shutdown */
2856
- for (ep = 0 ; ep < S3C_HSOTG_EPS ; ep ++ )
2895
+ for (ep = 0 ; ep < hsotg -> num_of_eps ; ep ++ )
2857
2896
s3c_hsotg_ep_disable (& hsotg -> eps [ep ].ep );
2858
2897
2859
2898
call_gadget (hsotg , disconnect );
@@ -2944,53 +2983,28 @@ static void __devinit s3c_hsotg_initep(struct s3c_hsotg *hsotg,
2944
2983
}
2945
2984
}
2946
2985
2947
- static void s3c_hsotg_init (struct s3c_hsotg * hsotg )
2986
+ /**
2987
+ * s3c_hsotg_hw_cfg - read HW configuration registers
2988
+ * @param: The device state
2989
+ *
2990
+ * Read the USB core HW configuration registers
2991
+ */
2992
+ static void s3c_hsotg_hw_cfg (struct s3c_hsotg * hsotg )
2948
2993
{
2949
- u32 cfg4 ;
2950
-
2951
- /* unmask subset of endpoint interrupts */
2952
-
2953
- writel (S3C_DIEPMSK_TimeOUTMsk | S3C_DIEPMSK_AHBErrMsk |
2954
- S3C_DIEPMSK_EPDisbldMsk | S3C_DIEPMSK_XferComplMsk ,
2955
- hsotg -> regs + S3C_DIEPMSK );
2956
-
2957
- writel (S3C_DOEPMSK_SetupMsk | S3C_DOEPMSK_AHBErrMsk |
2958
- S3C_DOEPMSK_EPDisbldMsk | S3C_DOEPMSK_XferComplMsk ,
2959
- hsotg -> regs + S3C_DOEPMSK );
2960
-
2961
- writel (0 , hsotg -> regs + S3C_DAINTMSK );
2962
-
2963
- /* Be in disconnected state until gadget is registered */
2964
- __orr32 (hsotg -> regs + S3C_DCTL , S3C_DCTL_SftDiscon );
2965
-
2966
- if (0 ) {
2967
- /* post global nak until we're ready */
2968
- writel (S3C_DCTL_SGNPInNAK | S3C_DCTL_SGOUTNak ,
2969
- hsotg -> regs + S3C_DCTL );
2970
- }
2971
-
2972
- /* setup fifos */
2973
-
2974
- dev_dbg (hsotg -> dev , "GRXFSIZ=0x%08x, GNPTXFSIZ=0x%08x\n" ,
2975
- readl (hsotg -> regs + S3C_GRXFSIZ ),
2976
- readl (hsotg -> regs + S3C_GNPTXFSIZ ));
2977
-
2978
- s3c_hsotg_init_fifo (hsotg );
2979
-
2980
- /* set the PLL on, remove the HNP/SRP and set the PHY */
2981
- writel (S3C_GUSBCFG_PHYIf16 | S3C_GUSBCFG_TOutCal (7 ) | (0x5 << 10 ),
2982
- hsotg -> regs + S3C_GUSBCFG );
2994
+ u32 cfg2 , cfg4 ;
2995
+ /* check hardware configuration */
2983
2996
2984
- writel ( using_dma ( hsotg ) ? S3C_GAHBCFG_DMAEn : 0x0 ,
2985
- hsotg -> regs + S3C_GAHBCFG ) ;
2997
+ cfg2 = readl ( hsotg -> regs + 0x48 );
2998
+ hsotg -> num_of_eps = ( cfg2 >> 10 ) & 0xF ;
2986
2999
2987
- /* check hardware configuration */
3000
+ dev_info ( hsotg -> dev , "EPs:%d\n" , hsotg -> num_of_eps );
2988
3001
2989
3002
cfg4 = readl (hsotg -> regs + 0x50 );
2990
3003
hsotg -> dedicated_fifos = (cfg4 >> 25 ) & 1 ;
2991
3004
2992
3005
dev_info (hsotg -> dev , "%s fifos\n" ,
2993
3006
hsotg -> dedicated_fifos ? "dedicated" : "shared" );
3007
+
2994
3008
}
2995
3009
2996
3010
static void s3c_hsotg_dump (struct s3c_hsotg * hsotg )
@@ -3284,7 +3298,7 @@ static void __devinit s3c_hsotg_create_debug(struct s3c_hsotg *hsotg)
3284
3298
3285
3299
/* create one file for each endpoint */
3286
3300
3287
- for (epidx = 0 ; epidx < S3C_HSOTG_EPS ; epidx ++ ) {
3301
+ for (epidx = 0 ; epidx < hsotg -> num_of_eps ; epidx ++ ) {
3288
3302
struct s3c_hsotg_ep * ep = & hsotg -> eps [epidx ];
3289
3303
3290
3304
ep -> debugfs = debugfs_create_file (ep -> name , 0444 ,
@@ -3306,7 +3320,7 @@ static void __devexit s3c_hsotg_delete_debug(struct s3c_hsotg *hsotg)
3306
3320
{
3307
3321
unsigned epidx ;
3308
3322
3309
- for (epidx = 0 ; epidx < S3C_HSOTG_EPS ; epidx ++ ) {
3323
+ for (epidx = 0 ; epidx < hsotg -> num_of_eps ; epidx ++ ) {
3310
3324
struct s3c_hsotg_ep * ep = & hsotg -> eps [epidx ];
3311
3325
debugfs_remove (ep -> debugfs );
3312
3326
}
@@ -3320,6 +3334,7 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev)
3320
3334
{
3321
3335
struct s3c_hsotg_plat * plat = pdev -> dev .platform_data ;
3322
3336
struct device * dev = & pdev -> dev ;
3337
+ struct s3c_hsotg_ep * eps ;
3323
3338
struct s3c_hsotg * hsotg ;
3324
3339
struct resource * res ;
3325
3340
int epnum ;
@@ -3332,9 +3347,7 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev)
3332
3347
return - EINVAL ;
3333
3348
}
3334
3349
3335
- hsotg = kzalloc (sizeof (struct s3c_hsotg ) +
3336
- sizeof (struct s3c_hsotg_ep ) * S3C_HSOTG_EPS ,
3337
- GFP_KERNEL );
3350
+ hsotg = kzalloc (sizeof (struct s3c_hsotg ), GFP_KERNEL );
3338
3351
if (!hsotg ) {
3339
3352
dev_err (dev , "cannot get memory\n" );
3340
3353
return - ENOMEM ;
@@ -3401,20 +3414,6 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev)
3401
3414
hsotg -> gadget .dev .parent = dev ;
3402
3415
hsotg -> gadget .dev .dma_mask = dev -> dma_mask ;
3403
3416
3404
- /* setup endpoint information */
3405
-
3406
- INIT_LIST_HEAD (& hsotg -> gadget .ep_list );
3407
- hsotg -> gadget .ep0 = & hsotg -> eps [0 ].ep ;
3408
-
3409
- /* allocate EP0 request */
3410
-
3411
- hsotg -> ctrl_req = s3c_hsotg_ep_alloc_request (& hsotg -> eps [0 ].ep ,
3412
- GFP_KERNEL );
3413
- if (!hsotg -> ctrl_req ) {
3414
- dev_err (dev , "failed to allocate ctrl req\n" );
3415
- goto err_regs ;
3416
- }
3417
-
3418
3417
/* reset the system */
3419
3418
3420
3419
clk_enable (hsotg -> clk );
@@ -3444,14 +3443,45 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev)
3444
3443
3445
3444
s3c_hsotg_corereset (hsotg );
3446
3445
s3c_hsotg_init (hsotg );
3446
+ s3c_hsotg_hw_cfg (hsotg );
3447
+
3448
+ /* hsotg->num_of_eps holds number of EPs other than ep0 */
3449
+
3450
+ if (hsotg -> num_of_eps == 0 ) {
3451
+ dev_err (dev , "wrong number of EPs (zero)\n" );
3452
+ goto err_supplies ;
3453
+ }
3454
+
3455
+ eps = kcalloc (hsotg -> num_of_eps + 1 , sizeof (struct s3c_hsotg_ep ),
3456
+ GFP_KERNEL );
3457
+ if (!eps ) {
3458
+ dev_err (dev , "cannot get memory\n" );
3459
+ goto err_supplies ;
3460
+ }
3461
+
3462
+ hsotg -> eps = eps ;
3463
+
3464
+ /* setup endpoint information */
3465
+
3466
+ INIT_LIST_HEAD (& hsotg -> gadget .ep_list );
3467
+ hsotg -> gadget .ep0 = & hsotg -> eps [0 ].ep ;
3468
+
3469
+ /* allocate EP0 request */
3470
+
3471
+ hsotg -> ctrl_req = s3c_hsotg_ep_alloc_request (& hsotg -> eps [0 ].ep ,
3472
+ GFP_KERNEL );
3473
+ if (!hsotg -> ctrl_req ) {
3474
+ dev_err (dev , "failed to allocate ctrl req\n" );
3475
+ goto err_ep_mem ;
3476
+ }
3447
3477
3448
3478
/* initialise the endpoints now the core has been initialised */
3449
- for (epnum = 0 ; epnum < S3C_HSOTG_EPS ; epnum ++ )
3479
+ for (epnum = 0 ; epnum < hsotg -> num_of_eps ; epnum ++ )
3450
3480
s3c_hsotg_initep (hsotg , & hsotg -> eps [epnum ], epnum );
3451
3481
3452
3482
ret = usb_add_gadget_udc (& pdev -> dev , & hsotg -> gadget );
3453
3483
if (ret )
3454
- goto err_supplies ;
3484
+ goto err_ep_mem ;
3455
3485
3456
3486
s3c_hsotg_create_debug (hsotg );
3457
3487
@@ -3460,6 +3490,9 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev)
3460
3490
our_hsotg = hsotg ;
3461
3491
return 0 ;
3462
3492
3493
+ err_ep_mem :
3494
+ kfree (eps );
3495
+
3463
3496
err_supplies :
3464
3497
s3c_hsotg_phy_disable (hsotg );
3465
3498
0 commit comments