aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tty_ldisc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/tty_ldisc.c')
-rw-r--r--drivers/char/tty_ldisc.c51
1 files changed, 20 insertions, 31 deletions
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c
index cbfacc0bbea5..aafdbaebc16a 100644
--- a/drivers/char/tty_ldisc.c
+++ b/drivers/char/tty_ldisc.c
@@ -175,34 +175,6 @@ static void put_ldops(struct tty_ldisc_ops *ldops)
175} 175}
176 176
177/** 177/**
178 * tty_ldisc_try_get - try and reference an ldisc
179 * @disc: ldisc number
180 *
181 * Attempt to open and lock a line discipline into place. Return
182 * the line discipline refcounted or an error.
183 */
184
185static struct tty_ldisc *tty_ldisc_try_get(int disc)
186{
187 struct tty_ldisc *ld;
188 struct tty_ldisc_ops *ldops;
189
190 ld = kmalloc(sizeof(struct tty_ldisc), GFP_KERNEL);
191 if (ld == NULL)
192 return ERR_PTR(-ENOMEM);
193
194 ldops = get_ldops(disc);
195 if (IS_ERR(ldops)) {
196 kfree(ld);
197 return ERR_CAST(ldops);
198 }
199
200 ld->ops = ldops;
201 atomic_set(&ld->users, 1);
202 return ld;
203}
204
205/**
206 * tty_ldisc_get - take a reference to an ldisc 178 * tty_ldisc_get - take a reference to an ldisc
207 * @disc: ldisc number 179 * @disc: ldisc number
208 * 180 *
@@ -218,14 +190,31 @@ static struct tty_ldisc *tty_ldisc_try_get(int disc)
218static struct tty_ldisc *tty_ldisc_get(int disc) 190static struct tty_ldisc *tty_ldisc_get(int disc)
219{ 191{
220 struct tty_ldisc *ld; 192 struct tty_ldisc *ld;
193 struct tty_ldisc_ops *ldops;
221 194
222 if (disc < N_TTY || disc >= NR_LDISCS) 195 if (disc < N_TTY || disc >= NR_LDISCS)
223 return ERR_PTR(-EINVAL); 196 return ERR_PTR(-EINVAL);
224 ld = tty_ldisc_try_get(disc); 197
225 if (IS_ERR(ld)) { 198 /*
199 * Get the ldisc ops - we may need to request them to be loaded
200 * dynamically and try again.
201 */
202 ldops = get_ldops(disc);
203 if (IS_ERR(ldops)) {
226 request_module("tty-ldisc-%d", disc); 204 request_module("tty-ldisc-%d", disc);
227 ld = tty_ldisc_try_get(disc); 205 ldops = get_ldops(disc);
206 if (IS_ERR(ldops))
207 return ERR_CAST(ldops);
208 }
209
210 ld = kmalloc(sizeof(struct tty_ldisc), GFP_KERNEL);
211 if (ld == NULL) {
212 put_ldops(ldops);
213 return ERR_PTR(-ENOMEM);
228 } 214 }
215
216 ld->ops = ldops;
217 atomic_set(&ld->users, 1);
229 return ld; 218 return ld;
230} 219}
231 220