aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFederico Vaga <federico.vaga@cern.ch>2014-09-02 11:31:41 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-09-24 02:13:13 -0400
commit82a82340bab6c251e0705339f60763718eaa2a22 (patch)
tree949a69ef011d3fdb4046b302029e30b01d13d98b
parent36c53b3cc3fac6952af68f43609b15ae050c9318 (diff)
ipoctal: get carrier driver to avoid rmmod
Signed-off-by: Federico Vaga <federico.vaga@cern.ch> Acked-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/ipack/devices/ipoctal.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/drivers/ipack/devices/ipoctal.c b/drivers/ipack/devices/ipoctal.c
index a1514a79e487..42700815d05f 100644
--- a/drivers/ipack/devices/ipoctal.c
+++ b/drivers/ipack/devices/ipoctal.c
@@ -55,6 +55,12 @@ struct ipoctal {
55 u8 __iomem *int_space; 55 u8 __iomem *int_space;
56}; 56};
57 57
58static inline struct ipoctal *chan_to_ipoctal(struct ipoctal_channel *chan,
59 unsigned int index)
60{
61 return container_of(chan, struct ipoctal, channel[index]);
62}
63
58static void ipoctal_reset_channel(struct ipoctal_channel *channel) 64static void ipoctal_reset_channel(struct ipoctal_channel *channel)
59{ 65{
60 iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr); 66 iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr);
@@ -82,12 +88,20 @@ static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty)
82 88
83static int ipoctal_open(struct tty_struct *tty, struct file *file) 89static int ipoctal_open(struct tty_struct *tty, struct file *file)
84{ 90{
85 struct ipoctal_channel *channel; 91 struct ipoctal_channel *channel = dev_get_drvdata(tty->dev);
92 struct ipoctal *ipoctal = chan_to_ipoctal(channel, tty->index);
93 int err;
86 94
87 channel = dev_get_drvdata(tty->dev);
88 tty->driver_data = channel; 95 tty->driver_data = channel;
89 96
90 return tty_port_open(&channel->tty_port, tty, file); 97 if (!ipack_get_carrier(ipoctal->dev))
98 return -EBUSY;
99
100 err = tty_port_open(&channel->tty_port, tty, file);
101 if (err)
102 ipack_put_carrier(ipoctal->dev);
103
104 return err;
91} 105}
92 106
93static void ipoctal_reset_stats(struct ipoctal_stats *stats) 107static void ipoctal_reset_stats(struct ipoctal_stats *stats)
@@ -629,6 +643,15 @@ static void ipoctal_shutdown(struct tty_struct *tty)
629 clear_bit(ASYNCB_INITIALIZED, &channel->tty_port.flags); 643 clear_bit(ASYNCB_INITIALIZED, &channel->tty_port.flags);
630} 644}
631 645
646static void ipoctal_cleanup(struct tty_struct *tty)
647{
648 struct ipoctal_channel *channel = tty->driver_data;
649 struct ipoctal *ipoctal = chan_to_ipoctal(channel, tty->index);
650
651 /* release the carrier driver */
652 ipack_put_carrier(ipoctal->dev);
653}
654
632static const struct tty_operations ipoctal_fops = { 655static const struct tty_operations ipoctal_fops = {
633 .ioctl = NULL, 656 .ioctl = NULL,
634 .open = ipoctal_open, 657 .open = ipoctal_open,
@@ -640,6 +663,7 @@ static const struct tty_operations ipoctal_fops = {
640 .get_icount = ipoctal_get_icount, 663 .get_icount = ipoctal_get_icount,
641 .hangup = ipoctal_hangup, 664 .hangup = ipoctal_hangup,
642 .shutdown = ipoctal_shutdown, 665 .shutdown = ipoctal_shutdown,
666 .cleanup = ipoctal_cleanup,
643}; 667};
644 668
645static int ipoctal_probe(struct ipack_device *dev) 669static int ipoctal_probe(struct ipack_device *dev)