diff --git a/drivers/ipack/devices/ipoctal.c b/drivers/ipack/devices/ipoctal.c index bf71b8952a7c..2169e4b75f98 100644 --- a/drivers/ipack/devices/ipoctal.c +++ b/drivers/ipack/devices/ipoctal.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -54,6 +55,7 @@ struct ipoctal { u8 __iomem *int_space; struct kref kref; struct module *carrier_owner; + struct rw_semaphore remove_sem; bool removed; }; @@ -81,7 +83,7 @@ static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty) channel = dev_get_drvdata(tty->dev); ipoctal = chan_to_ipoctal(channel, tty->index); - + guard(rwsem_read)(&ipoctal->remove_sem); if (ipoctal->removed) return -ENODEV; @@ -476,7 +478,7 @@ static ssize_t ipoctal_write_tty(struct tty_struct *tty, const u8 *buf, struct ipoctal *ipoctal = chan_to_ipoctal(channel, tty->index); size_t char_copied; - + guard(rwsem_read)(&ipoctal->remove_sem); if (ipoctal->removed || !channel->tty_port.xmit_buf) return 0; @@ -522,7 +524,7 @@ static void ipoctal_set_termios(struct tty_struct *tty, struct ipoctal *ipoctal = chan_to_ipoctal(channel, tty->index); speed_t baud; - + guard(rwsem_read)(&ipoctal->remove_sem); if (ipoctal->removed) return; @@ -660,7 +662,7 @@ static void ipoctal_hangup(struct tty_struct *tty) return; ipoctal = chan_to_ipoctal(channel, tty->index); - + guard(rwsem_read)(&ipoctal->remove_sem); if (ipoctal->removed) return; @@ -686,7 +688,7 @@ static void ipoctal_shutdown(struct tty_struct *tty) return; ipoctal = chan_to_ipoctal(channel, tty->index); - + guard(rwsem_read)(&ipoctal->remove_sem); if (ipoctal->removed) return; @@ -736,6 +738,7 @@ static int ipoctal_probe(struct ipack_device *dev) return -ENOMEM; kref_init(&ipoctal->kref); + init_rwsem(&ipoctal->remove_sem); ipoctal->dev = dev; ipoctal->carrier_owner = dev->bus->owner; @@ -755,7 +758,8 @@ static void __ipoctal_remove(struct ipoctal *ipoctal) { int i; - ipoctal->removed = true; + scoped_guard(rwsem_write, &ipoctal->remove_sem) + ipoctal->removed = true; ipoctal->dev->bus->ops->free_irq(ipoctal->dev);