~ubuntu-branches/ubuntu/precise/linux-linaro-u8500/precise

« back to all changes in this revision

Viewing changes to drivers/usb/serial/mct_u232.c

  • Committer: Bazaar Package Importer
  • Author(s): John Rigby, Upstream Fixes, Andy Green, John Rigby
  • Date: 2011-04-14 12:16:06 UTC
  • Revision ID: james.westby@ubuntu.com-20110414121606-b77podkyqgr2oix7
Tags: 2.6.38-1002.3
[ Upstream Fixes ]

* MUSB: shutdown: Make sure block is awake before doing shutdown
  - LP: #745737
* Fixed gpio polarity of gpio USB-phy reset.
  - LP: #747639

[ Andy Green ]

* LINARO: SAUCE: disable CONFIG_OMAP_RESET_CLOCKS
  - LP: #752900

[ John Rigby ]

* Rebase to new upstreams:
  Linux v2.6.38.1
  linaro-linux-2.6.38-upstream-29Mar2011
  Ubuntu-2.6.38-7.35
* SAUCE: OMAP4: clock: wait for module to become accessible on
  a clk enable
  - LP: #745737
* Rebase to new upstreams:
  Linux v2.6.38.2
  linaro-linux-2.6.38-upstream-5Apr2011
  Ubuntu-2.6.38-8.41
  - LP: #732842
* Update configs for device tree, dvfs and lttng
* LINARO: add building of dtb's
* LINARO: SAUCE: Disable lowest operating freqs on omap34xx
  - LP: #732912

Show diffs side-by-side

added added

removed removed

Lines of Context:
78
78
#include <asm/unaligned.h>
79
79
#include <linux/usb.h>
80
80
#include <linux/usb/serial.h>
 
81
#include <linux/serial.h>
 
82
#include <linux/ioctl.h>
81
83
#include "mct_u232.h"
82
84
 
83
85
/*
104
106
static int  mct_u232_tiocmget(struct tty_struct *tty, struct file *file);
105
107
static int  mct_u232_tiocmset(struct tty_struct *tty, struct file *file,
106
108
                        unsigned int set, unsigned int clear);
 
109
static int  mct_u232_ioctl(struct tty_struct *tty, struct file *file,
 
110
                        unsigned int cmd, unsigned long arg);
 
111
static int  mct_u232_get_icount(struct tty_struct *tty,
 
112
                        struct serial_icounter_struct *icount);
107
113
static void mct_u232_throttle(struct tty_struct *tty);
108
114
static void mct_u232_unthrottle(struct tty_struct *tty);
109
115
 
150
156
        .tiocmset =          mct_u232_tiocmset,
151
157
        .attach =            mct_u232_startup,
152
158
        .release =           mct_u232_release,
 
159
        .ioctl =             mct_u232_ioctl,
 
160
        .get_icount =        mct_u232_get_icount,
153
161
};
154
162
 
155
 
 
156
163
struct mct_u232_private {
157
164
        spinlock_t lock;
158
165
        unsigned int         control_state; /* Modem Line Setting (TIOCM) */
160
167
        unsigned char        last_lsr;      /* Line Status Register */
161
168
        unsigned char        last_msr;      /* Modem Status Register */
162
169
        unsigned int         rx_flags;      /* Throttling flags */
 
170
        struct async_icount  icount;
 
171
        wait_queue_head_t    msr_wait;  /* for handling sleeping while waiting
 
172
                                                for msr change to happen */
163
173
};
164
174
 
165
175
#define THROTTLED               0x01
386
396
        return rc;
387
397
} /* mct_u232_get_modem_stat */
388
398
 
 
399
static void mct_u232_msr_to_icount(struct async_icount *icount,
 
400
                                                unsigned char msr)
 
401
{
 
402
        /* Translate Control Line states */
 
403
        if (msr & MCT_U232_MSR_DDSR)
 
404
                icount->dsr++;
 
405
        if (msr & MCT_U232_MSR_DCTS)
 
406
                icount->cts++;
 
407
        if (msr & MCT_U232_MSR_DRI)
 
408
                icount->rng++;
 
409
        if (msr & MCT_U232_MSR_DCD)
 
410
                icount->dcd++;
 
411
} /* mct_u232_msr_to_icount */
 
412
 
389
413
static void mct_u232_msr_to_state(unsigned int *control_state,
390
414
                                                unsigned char msr)
391
415
{
422
446
        if (!priv)
423
447
                return -ENOMEM;
424
448
        spin_lock_init(&priv->lock);
 
449
        init_waitqueue_head(&priv->msr_wait);
425
450
        usb_set_serial_port_data(serial->port[0], priv);
426
451
 
427
452
        init_waitqueue_head(&serial->port[0]->write_wait);
621
646
        /* Record Control Line states */
622
647
        mct_u232_msr_to_state(&priv->control_state, priv->last_msr);
623
648
 
 
649
        mct_u232_msr_to_icount(&priv->icount, priv->last_msr);
 
650
 
624
651
#if 0
625
652
        /* Not yet handled. See belkin_sa.c for further information */
626
653
        /* Now to report any errors */
647
674
                tty_kref_put(tty);
648
675
        }
649
676
#endif
 
677
        wake_up_interruptible(&priv->msr_wait);
650
678
        spin_unlock_irqrestore(&priv->lock, flags);
651
679
exit:
652
680
        retval = usb_submit_urb(urb, GFP_ATOMIC);
826
854
        }
827
855
}
828
856
 
829
 
 
830
857
static void mct_u232_unthrottle(struct tty_struct *tty)
831
858
{
832
859
        struct usb_serial_port *port = tty->driver_data;
847
874
        }
848
875
}
849
876
 
 
877
static int  mct_u232_ioctl(struct tty_struct *tty, struct file *file,
 
878
                        unsigned int cmd, unsigned long arg)
 
879
{
 
880
        DEFINE_WAIT(wait);
 
881
        struct usb_serial_port *port = tty->driver_data;
 
882
        struct mct_u232_private *mct_u232_port = usb_get_serial_port_data(port);
 
883
        struct async_icount cnow, cprev;
 
884
        unsigned long flags;
 
885
 
 
886
        dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd);
 
887
 
 
888
        switch (cmd) {
 
889
 
 
890
        case TIOCMIWAIT:
 
891
 
 
892
                dbg("%s (%d) TIOCMIWAIT", __func__,  port->number);
 
893
 
 
894
                spin_lock_irqsave(&mct_u232_port->lock, flags);
 
895
                cprev = mct_u232_port->icount;
 
896
                spin_unlock_irqrestore(&mct_u232_port->lock, flags);
 
897
                for ( ; ; ) {
 
898
                        prepare_to_wait(&mct_u232_port->msr_wait,
 
899
                                        &wait, TASK_INTERRUPTIBLE);
 
900
                        schedule();
 
901
                        finish_wait(&mct_u232_port->msr_wait, &wait);
 
902
                        /* see if a signal did it */
 
903
                        if (signal_pending(current))
 
904
                                return -ERESTARTSYS;
 
905
                        spin_lock_irqsave(&mct_u232_port->lock, flags);
 
906
                        cnow = mct_u232_port->icount;
 
907
                        spin_unlock_irqrestore(&mct_u232_port->lock, flags);
 
908
                        if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
 
909
                            cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
 
910
                                return -EIO; /* no change => error */
 
911
                        if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
 
912
                            ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
 
913
                            ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
 
914
                            ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) {
 
915
                                return 0;
 
916
                        }
 
917
                        cprev = cnow;
 
918
                }
 
919
 
 
920
        }
 
921
        return -ENOIOCTLCMD;
 
922
}
 
923
 
 
924
static int  mct_u232_get_icount(struct tty_struct *tty,
 
925
                        struct serial_icounter_struct *icount)
 
926
{
 
927
        struct usb_serial_port *port = tty->driver_data;
 
928
        struct mct_u232_private *mct_u232_port = usb_get_serial_port_data(port);
 
929
        struct async_icount *ic = &mct_u232_port->icount;
 
930
        unsigned long flags;
 
931
 
 
932
        spin_lock_irqsave(&mct_u232_port->lock, flags);
 
933
 
 
934
        icount->cts = ic->cts;
 
935
        icount->dsr = ic->dsr;
 
936
        icount->rng = ic->rng;
 
937
        icount->dcd = ic->dcd;
 
938
        icount->rx = ic->rx;
 
939
        icount->tx = ic->tx;
 
940
        icount->frame = ic->frame;
 
941
        icount->overrun = ic->overrun;
 
942
        icount->parity = ic->parity;
 
943
        icount->brk = ic->brk;
 
944
        icount->buf_overrun = ic->buf_overrun;
 
945
 
 
946
        spin_unlock_irqrestore(&mct_u232_port->lock, flags);
 
947
 
 
948
        dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d",
 
949
                __func__,  port->number, icount->rx, icount->tx);
 
950
        return 0;
 
951
}
 
952
 
850
953
static int __init mct_u232_init(void)
851
954
{
852
955
        int retval;