diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2011-04-21 01:10:08 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-04-29 20:24:32 -0400 |
commit | cb96632c185f13f746d009ec1125539e0b5cd899 (patch) | |
tree | bd11cf833c31ae203389e89818f35b91d37558bf /drivers/usb | |
parent | 409ba9e7c023bdbfd2ecab960532523124de5c81 (diff) |
usb: renesas_usbhs: modify spinlock method
Current renesas_usbhs driver was using spin_trylock to avoid
dead lock / nest lock.
But acording to CONFIG_DEBUG_SPINLOCK, it is BUG under UP environment.
This patch add usbhsg_trylock to avoid this issue.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/renesas_usbhs/mod_gadget.c | 97 |
1 files changed, 61 insertions, 36 deletions
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index 8c721d86bac..d027c80ab35 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c | |||
@@ -119,6 +119,35 @@ struct usbhsg_recip_handle { | |||
119 | #define usbhsg_status_has(gp, b) (gp->status & b) | 119 | #define usbhsg_status_has(gp, b) (gp->status & b) |
120 | 120 | ||
121 | /* | 121 | /* |
122 | * usbhsg_trylock | ||
123 | * | ||
124 | * This driver don't use spin_try_lock | ||
125 | * to avoid warning of CONFIG_DEBUG_SPINLOCK | ||
126 | */ | ||
127 | static spinlock_t *usbhsg_trylock(struct usbhsg_gpriv *gpriv, | ||
128 | unsigned long *flags) | ||
129 | { | ||
130 | spinlock_t *lock = usbhsg_gpriv_to_lock(gpriv); | ||
131 | |||
132 | /* check spin lock status | ||
133 | * to avoid deadlock/nest */ | ||
134 | if (spin_is_locked(lock)) | ||
135 | return NULL; | ||
136 | |||
137 | spin_lock_irqsave(lock, *flags); | ||
138 | |||
139 | return lock; | ||
140 | } | ||
141 | |||
142 | static void usbhsg_unlock(spinlock_t *lock, unsigned long *flags) | ||
143 | { | ||
144 | if (!lock) | ||
145 | return; | ||
146 | |||
147 | spin_unlock_irqrestore(lock, *flags); | ||
148 | } | ||
149 | |||
150 | /* | ||
122 | * list push/pop | 151 | * list push/pop |
123 | */ | 152 | */ |
124 | static void usbhsg_queue_push(struct usbhsg_uep *uep, | 153 | static void usbhsg_queue_push(struct usbhsg_uep *uep, |
@@ -159,9 +188,8 @@ static int __usbhsg_queue_handler(struct usbhsg_uep *uep, int prepare) | |||
159 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); | 188 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); |
160 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); | 189 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); |
161 | struct usbhsg_request *ureq; | 190 | struct usbhsg_request *ureq; |
162 | spinlock_t *lock = usbhsg_gpriv_to_lock(gpriv); | 191 | spinlock_t *lock; |
163 | unsigned long flags; | 192 | unsigned long flags; |
164 | int is_locked; | ||
165 | int ret = 0; | 193 | int ret = 0; |
166 | 194 | ||
167 | if (!uep->handler) { | 195 | if (!uep->handler) { |
@@ -179,7 +207,7 @@ static int __usbhsg_queue_handler(struct usbhsg_uep *uep, int prepare) | |||
179 | * - usb_request :: complete | 207 | * - usb_request :: complete |
180 | * | 208 | * |
181 | * But the caller of this function need not care about spinlock. | 209 | * But the caller of this function need not care about spinlock. |
182 | * This function is using spin_trylock_irqsave for it. | 210 | * This function is using usbhsg_trylock for it. |
183 | * if "is_locked" is 1, this mean this function lock it. | 211 | * if "is_locked" is 1, this mean this function lock it. |
184 | * but if it is 0, this mean it is already under spin lock. | 212 | * but if it is 0, this mean it is already under spin lock. |
185 | * see also | 213 | * see also |
@@ -188,7 +216,8 @@ static int __usbhsg_queue_handler(struct usbhsg_uep *uep, int prepare) | |||
188 | */ | 216 | */ |
189 | 217 | ||
190 | /****************** spin try lock *******************/ | 218 | /****************** spin try lock *******************/ |
191 | is_locked = spin_trylock_irqsave(lock, flags); | 219 | lock = usbhsg_trylock(gpriv, &flags); |
220 | |||
192 | ureq = usbhsg_queue_get(uep); | 221 | ureq = usbhsg_queue_get(uep); |
193 | if (ureq) { | 222 | if (ureq) { |
194 | if (prepare) | 223 | if (prepare) |
@@ -196,8 +225,7 @@ static int __usbhsg_queue_handler(struct usbhsg_uep *uep, int prepare) | |||
196 | else | 225 | else |
197 | ret = uep->handler->try_run(uep, ureq); | 226 | ret = uep->handler->try_run(uep, ureq); |
198 | } | 227 | } |
199 | if (is_locked) | 228 | usbhsg_unlock(lock, &flags); |
200 | spin_unlock_irqrestore(lock, flags); | ||
201 | /******************** spin unlock ******************/ | 229 | /******************** spin unlock ******************/ |
202 | 230 | ||
203 | return ret; | 231 | return ret; |
@@ -228,7 +256,7 @@ static void usbhsg_queue_pop(struct usbhsg_uep *uep, | |||
228 | * It mean "usb_ep_ops :: queue" which is using spinlock is called | 256 | * It mean "usb_ep_ops :: queue" which is using spinlock is called |
229 | * under spinlock. | 257 | * under spinlock. |
230 | * | 258 | * |
231 | * To avoid dead-lock, this driver is using spin_trylock. | 259 | * To avoid dead-lock, this driver is using usbhsg_trylock. |
232 | * CAUTION [*endpoint queue*] | 260 | * CAUTION [*endpoint queue*] |
233 | * CAUTION [*queue handler*] | 261 | * CAUTION [*queue handler*] |
234 | */ | 262 | */ |
@@ -811,7 +839,7 @@ static int usbhsg_ep_enable(struct usb_ep *ep, | |||
811 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); | 839 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); |
812 | struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); | 840 | struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); |
813 | struct usbhs_pipe *pipe; | 841 | struct usbhs_pipe *pipe; |
814 | spinlock_t *lock = usbhsg_gpriv_to_lock(gpriv); | 842 | spinlock_t *lock; |
815 | unsigned long flags; | 843 | unsigned long flags; |
816 | int ret = -EIO; | 844 | int ret = -EIO; |
817 | 845 | ||
@@ -823,7 +851,7 @@ static int usbhsg_ep_enable(struct usb_ep *ep, | |||
823 | return 0; | 851 | return 0; |
824 | 852 | ||
825 | /******************** spin lock ********************/ | 853 | /******************** spin lock ********************/ |
826 | spin_lock_irqsave(lock, flags); | 854 | lock = usbhsg_trylock(gpriv, &flags); |
827 | 855 | ||
828 | pipe = usbhs_pipe_malloc(priv, desc); | 856 | pipe = usbhs_pipe_malloc(priv, desc); |
829 | if (pipe) { | 857 | if (pipe) { |
@@ -838,7 +866,8 @@ static int usbhsg_ep_enable(struct usb_ep *ep, | |||
838 | 866 | ||
839 | ret = 0; | 867 | ret = 0; |
840 | } | 868 | } |
841 | spin_unlock_irqrestore(lock, flags); | 869 | |
870 | usbhsg_unlock(lock, &flags); | ||
842 | /******************** spin unlock ******************/ | 871 | /******************** spin unlock ******************/ |
843 | 872 | ||
844 | return ret; | 873 | return ret; |
@@ -848,14 +877,16 @@ static int usbhsg_ep_disable(struct usb_ep *ep) | |||
848 | { | 877 | { |
849 | struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); | 878 | struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); |
850 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); | 879 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); |
851 | spinlock_t *lock = usbhsg_gpriv_to_lock(gpriv); | 880 | spinlock_t *lock; |
852 | unsigned long flags; | 881 | unsigned long flags; |
853 | int ret; | 882 | int ret; |
854 | 883 | ||
855 | /******************** spin lock ********************/ | 884 | /******************** spin lock ********************/ |
856 | spin_lock_irqsave(lock, flags); | 885 | lock = usbhsg_trylock(gpriv, &flags); |
886 | |||
857 | ret = usbhsg_pipe_disable(uep); | 887 | ret = usbhsg_pipe_disable(uep); |
858 | spin_unlock_irqrestore(lock, flags); | 888 | |
889 | usbhsg_unlock(lock, &flags); | ||
859 | /******************** spin unlock ******************/ | 890 | /******************** spin unlock ******************/ |
860 | 891 | ||
861 | return ret; | 892 | return ret; |
@@ -890,10 +921,9 @@ static int usbhsg_ep_queue(struct usb_ep *ep, struct usb_request *req, | |||
890 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); | 921 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); |
891 | struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); | 922 | struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); |
892 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); | 923 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); |
893 | spinlock_t *lock = usbhsg_gpriv_to_lock(gpriv); | 924 | spinlock_t *lock; |
894 | unsigned long flags; | 925 | unsigned long flags; |
895 | int ret = 0; | 926 | int ret = 0; |
896 | int is_locked; | ||
897 | 927 | ||
898 | /* | 928 | /* |
899 | * CAUTION [*endpoint queue*] | 929 | * CAUTION [*endpoint queue*] |
@@ -904,7 +934,7 @@ static int usbhsg_ep_queue(struct usb_ep *ep, struct usb_request *req, | |||
904 | * it is already under spinlock on this driver. | 934 | * it is already under spinlock on this driver. |
905 | * but it is called frm usb driver, this function should call spinlock. | 935 | * but it is called frm usb driver, this function should call spinlock. |
906 | * | 936 | * |
907 | * This function is using spin_trylock_irqsave to solve this issue. | 937 | * This function is using usbshg_trylock to solve this issue. |
908 | * if "is_locked" is 1, this mean this function lock it. | 938 | * if "is_locked" is 1, this mean this function lock it. |
909 | * but if it is 0, this mean it is already under spin lock. | 939 | * but if it is 0, this mean it is already under spin lock. |
910 | * see also | 940 | * see also |
@@ -913,7 +943,7 @@ static int usbhsg_ep_queue(struct usb_ep *ep, struct usb_request *req, | |||
913 | */ | 943 | */ |
914 | 944 | ||
915 | /******************** spin lock ********************/ | 945 | /******************** spin lock ********************/ |
916 | is_locked = spin_trylock_irqsave(lock, flags); | 946 | lock = usbhsg_trylock(gpriv, &flags); |
917 | 947 | ||
918 | /* param check */ | 948 | /* param check */ |
919 | if (usbhsg_is_not_connected(gpriv) || | 949 | if (usbhsg_is_not_connected(gpriv) || |
@@ -923,8 +953,7 @@ static int usbhsg_ep_queue(struct usb_ep *ep, struct usb_request *req, | |||
923 | else | 953 | else |
924 | usbhsg_queue_push(uep, ureq); | 954 | usbhsg_queue_push(uep, ureq); |
925 | 955 | ||
926 | if (is_locked) | 956 | usbhsg_unlock(lock, &flags); |
927 | spin_unlock_irqrestore(lock, flags); | ||
928 | /******************** spin unlock ******************/ | 957 | /******************** spin unlock ******************/ |
929 | 958 | ||
930 | usbhsg_queue_prepare(uep); | 959 | usbhsg_queue_prepare(uep); |
@@ -937,9 +966,8 @@ static int usbhsg_ep_dequeue(struct usb_ep *ep, struct usb_request *req) | |||
937 | struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); | 966 | struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); |
938 | struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); | 967 | struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); |
939 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); | 968 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); |
940 | spinlock_t *lock = usbhsg_gpriv_to_lock(gpriv); | 969 | spinlock_t *lock; |
941 | unsigned long flags; | 970 | unsigned long flags; |
942 | int is_locked; | ||
943 | 971 | ||
944 | /* | 972 | /* |
945 | * see | 973 | * see |
@@ -949,12 +977,11 @@ static int usbhsg_ep_dequeue(struct usb_ep *ep, struct usb_request *req) | |||
949 | */ | 977 | */ |
950 | 978 | ||
951 | /******************** spin lock ********************/ | 979 | /******************** spin lock ********************/ |
952 | is_locked = spin_trylock_irqsave(lock, flags); | 980 | lock = usbhsg_trylock(gpriv, &flags); |
953 | 981 | ||
954 | usbhsg_queue_pop(uep, ureq, -ECONNRESET); | 982 | usbhsg_queue_pop(uep, ureq, -ECONNRESET); |
955 | 983 | ||
956 | if (is_locked) | 984 | usbhsg_unlock(lock, &flags); |
957 | spin_unlock_irqrestore(lock, flags); | ||
958 | /******************** spin unlock ******************/ | 985 | /******************** spin unlock ******************/ |
959 | 986 | ||
960 | return 0; | 987 | return 0; |
@@ -966,10 +993,9 @@ static int __usbhsg_ep_set_halt_wedge(struct usb_ep *ep, int halt, int wedge) | |||
966 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); | 993 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); |
967 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); | 994 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); |
968 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); | 995 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); |
969 | spinlock_t *lock = usbhsg_gpriv_to_lock(gpriv); | 996 | spinlock_t *lock; |
970 | unsigned long flags; | 997 | unsigned long flags; |
971 | int ret = -EAGAIN; | 998 | int ret = -EAGAIN; |
972 | int is_locked; | ||
973 | 999 | ||
974 | /* | 1000 | /* |
975 | * see | 1001 | * see |
@@ -979,7 +1005,7 @@ static int __usbhsg_ep_set_halt_wedge(struct usb_ep *ep, int halt, int wedge) | |||
979 | */ | 1005 | */ |
980 | 1006 | ||
981 | /******************** spin lock ********************/ | 1007 | /******************** spin lock ********************/ |
982 | is_locked = spin_trylock_irqsave(lock, flags); | 1008 | lock = usbhsg_trylock(gpriv, &flags); |
983 | if (!usbhsg_queue_get(uep)) { | 1009 | if (!usbhsg_queue_get(uep)) { |
984 | 1010 | ||
985 | dev_dbg(dev, "set halt %d (pipe %d)\n", | 1011 | dev_dbg(dev, "set halt %d (pipe %d)\n", |
@@ -998,8 +1024,7 @@ static int __usbhsg_ep_set_halt_wedge(struct usb_ep *ep, int halt, int wedge) | |||
998 | ret = 0; | 1024 | ret = 0; |
999 | } | 1025 | } |
1000 | 1026 | ||
1001 | if (is_locked) | 1027 | usbhsg_unlock(lock, &flags); |
1002 | spin_unlock_irqrestore(lock, flags); | ||
1003 | /******************** spin unlock ******************/ | 1028 | /******************** spin unlock ******************/ |
1004 | 1029 | ||
1005 | return ret; | 1030 | return ret; |
@@ -1038,11 +1063,11 @@ static int usbhsg_try_start(struct usbhs_priv *priv, u32 status) | |||
1038 | struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); | 1063 | struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); |
1039 | struct usbhs_mod *mod = usbhs_mod_get_current(priv); | 1064 | struct usbhs_mod *mod = usbhs_mod_get_current(priv); |
1040 | struct device *dev = usbhs_priv_to_dev(priv); | 1065 | struct device *dev = usbhs_priv_to_dev(priv); |
1041 | spinlock_t *lock = usbhsg_gpriv_to_lock(gpriv); | 1066 | spinlock_t *lock; |
1042 | unsigned long flags; | 1067 | unsigned long flags; |
1043 | 1068 | ||
1044 | /******************** spin lock ********************/ | 1069 | /******************** spin lock ********************/ |
1045 | spin_lock_irqsave(lock, flags); | 1070 | lock = usbhsg_trylock(gpriv, &flags); |
1046 | 1071 | ||
1047 | /* | 1072 | /* |
1048 | * enable interrupt and systems if ready | 1073 | * enable interrupt and systems if ready |
@@ -1083,7 +1108,7 @@ static int usbhsg_try_start(struct usbhs_priv *priv, u32 status) | |||
1083 | usbhs_irq_callback_update(priv, mod); | 1108 | usbhs_irq_callback_update(priv, mod); |
1084 | 1109 | ||
1085 | usbhsg_try_start_unlock: | 1110 | usbhsg_try_start_unlock: |
1086 | spin_unlock_irqrestore(lock, flags); | 1111 | usbhsg_unlock(lock, &flags); |
1087 | /******************** spin unlock ********************/ | 1112 | /******************** spin unlock ********************/ |
1088 | 1113 | ||
1089 | return 0; | 1114 | return 0; |
@@ -1095,11 +1120,11 @@ static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status) | |||
1095 | struct usbhs_mod *mod = usbhs_mod_get_current(priv); | 1120 | struct usbhs_mod *mod = usbhs_mod_get_current(priv); |
1096 | struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); | 1121 | struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); |
1097 | struct device *dev = usbhs_priv_to_dev(priv); | 1122 | struct device *dev = usbhs_priv_to_dev(priv); |
1098 | spinlock_t *lock = usbhsg_gpriv_to_lock(gpriv); | 1123 | spinlock_t *lock; |
1099 | unsigned long flags; | 1124 | unsigned long flags; |
1100 | 1125 | ||
1101 | /******************** spin lock ********************/ | 1126 | /******************** spin lock ********************/ |
1102 | spin_lock_irqsave(lock, flags); | 1127 | lock = usbhsg_trylock(gpriv, &flags); |
1103 | 1128 | ||
1104 | /* | 1129 | /* |
1105 | * disable interrupt and systems if 1st try | 1130 | * disable interrupt and systems if 1st try |
@@ -1127,7 +1152,7 @@ static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status) | |||
1127 | usbhs_sys_function_ctrl(priv, 0); | 1152 | usbhs_sys_function_ctrl(priv, 0); |
1128 | usbhs_sys_usb_ctrl(priv, 0); | 1153 | usbhs_sys_usb_ctrl(priv, 0); |
1129 | 1154 | ||
1130 | spin_unlock_irqrestore(lock, flags); | 1155 | usbhsg_unlock(lock, &flags); |
1131 | /******************** spin unlock ********************/ | 1156 | /******************** spin unlock ********************/ |
1132 | 1157 | ||
1133 | if (gpriv->driver && | 1158 | if (gpriv->driver && |
@@ -1139,7 +1164,7 @@ static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status) | |||
1139 | return 0; | 1164 | return 0; |
1140 | 1165 | ||
1141 | usbhsg_try_stop_unlock: | 1166 | usbhsg_try_stop_unlock: |
1142 | spin_unlock_irqrestore(lock, flags); | 1167 | usbhsg_unlock(lock, &flags); |
1143 | 1168 | ||
1144 | return 0; | 1169 | return 0; |
1145 | } | 1170 | } |