]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/char/nozomi.c
MIPS: TXx9: Add TX4939 SoC support
[linux-2.6-omap-h63xx.git] / drivers / char / nozomi.c
index dfaab2322de32c09a0adeab709cf5613ca9a0d5f..66a0f931c66ca91bf06b56e0b789edb8a0d68204 100644 (file)
@@ -73,7 +73,7 @@ do {                                                          \
        char tmp[P_BUF_SIZE];                                   \
        snprintf(tmp, sizeof(tmp), ##args);                     \
        printk(_err_flag_ "[%d] %s(): %s\n", __LINE__,          \
-               __FUNCTION__, tmp);                             \
+               __func__, tmp);                         \
 } while (0)
 
 #define DBG1(args...) D_(0x01, ##args)
@@ -190,6 +190,14 @@ enum card_type {
        F32_8 = 8192,   /* 3072 bytes downl. + 1024 bytes uplink * 2 -> 8192 */
 };
 
+/* Initialization states a card can be in */
+enum card_state {
+       NOZOMI_STATE_UKNOWN     = 0,
+       NOZOMI_STATE_ENABLED    = 1,    /* pci device enabled */
+       NOZOMI_STATE_ALLOCATED  = 2,    /* config setup done */
+       NOZOMI_STATE_READY      = 3,    /* flowcontrols received */
+};
+
 /* Two different toggle channels exist */
 enum channel_type {
        CH_A = 0,
@@ -385,6 +393,7 @@ struct nozomi {
        spinlock_t spin_mutex;  /* secures access to registers and tty */
 
        unsigned int index_start;
+       enum card_state state;
        u32 open_ttys;
 };
 
@@ -429,7 +438,7 @@ static void read_mem32(u32 *buf, const void __iomem *mem_addr_start,
                        u32 size_bytes)
 {
        u32 i = 0;
-       const u32 *ptr = (__force u32 *) mem_addr_start;
+       const u32 __iomem *ptr = mem_addr_start;
        u16 *buf16;
 
        if (unlikely(!ptr || !buf))
@@ -439,11 +448,11 @@ static void read_mem32(u32 *buf, const void __iomem *mem_addr_start,
        switch (size_bytes) {
        case 2: /* 2 bytes */
                buf16 = (u16 *) buf;
-               *buf16 = __le16_to_cpu(readw((void __iomem *)ptr));
+               *buf16 = __le16_to_cpu(readw(ptr));
                goto out;
                break;
        case 4: /* 4 bytes */
-               *(buf) = __le32_to_cpu(readl((void __iomem *)ptr));
+               *(buf) = __le32_to_cpu(readl(ptr));
                goto out;
                break;
        }
@@ -452,11 +461,11 @@ static void read_mem32(u32 *buf, const void __iomem *mem_addr_start,
                if (size_bytes - i == 2) {
                        /* Handle 2 bytes in the end */
                        buf16 = (u16 *) buf;
-                       *(buf16) = __le16_to_cpu(readw((void __iomem *)ptr));
+                       *(buf16) = __le16_to_cpu(readw(ptr));
                        i += 2;
                } else {
                        /* Read 4 bytes */
-                       *(buf) = __le32_to_cpu(readl((void __iomem *)ptr));
+                       *(buf) = __le32_to_cpu(readl(ptr));
                        i += 4;
                }
                buf++;
@@ -475,7 +484,7 @@ static u32 write_mem32(void __iomem *mem_addr_start, const u32 *buf,
                        u32 size_bytes)
 {
        u32 i = 0;
-       u32 *ptr = (__force u32 *) mem_addr_start;
+       u32 __iomem *ptr = mem_addr_start;
        const u16 *buf16;
 
        if (unlikely(!ptr || !buf))
@@ -485,7 +494,7 @@ static u32 write_mem32(void __iomem *mem_addr_start, const u32 *buf,
        switch (size_bytes) {
        case 2: /* 2 bytes */
                buf16 = (const u16 *)buf;
-               writew(__cpu_to_le16(*buf16), (void __iomem *)ptr);
+               writew(__cpu_to_le16(*buf16), ptr);
                return 2;
                break;
        case 1: /*
@@ -493,7 +502,7 @@ static u32 write_mem32(void __iomem *mem_addr_start, const u32 *buf,
                 * so falling through..
                 */
        case 4: /* 4 bytes */
-               writel(__cpu_to_le32(*buf), (void __iomem *)ptr);
+               writel(__cpu_to_le32(*buf), ptr);
                return 4;
                break;
        }
@@ -502,11 +511,11 @@ static u32 write_mem32(void __iomem *mem_addr_start, const u32 *buf,
                if (size_bytes - i == 2) {
                        /* 2 bytes */
                        buf16 = (const u16 *)buf;
-                       writew(__cpu_to_le16(*buf16), (void __iomem *)ptr);
+                       writew(__cpu_to_le16(*buf16), ptr);
                        i += 2;
                } else {
                        /* 4 bytes */
-                       writel(__cpu_to_le32(*buf), (void __iomem *)ptr);
+                       writel(__cpu_to_le32(*buf), ptr);
                        i += 4;
                }
                buf++;
@@ -686,6 +695,7 @@ static int nozomi_read_config_table(struct nozomi *dc)
                dc->last_ier = dc->last_ier | CTRL_DL;
                writew(dc->last_ier, dc->reg_ier);
 
+               dc->state = NOZOMI_STATE_ALLOCATED;
                dev_info(&dc->pdev->dev, "Initialization OK!\n");
                return 1;
        }
@@ -944,6 +954,14 @@ static int receive_flow_control(struct nozomi *dc)
        case CTRL_APP2:
                port = PORT_APP2;
                enable_ier = APP2_DL;
+               if (dc->state == NOZOMI_STATE_ALLOCATED) {
+                       /*
+                        * After card initialization the flow control
+                        * received for APP2 is always the last
+                        */
+                       dc->state = NOZOMI_STATE_READY;
+                       dev_info(&dc->pdev->dev, "Device READY!\n");
+               }
                break;
        default:
                dev_err(&dc->pdev->dev,
@@ -1366,22 +1384,12 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev,
 
        dc->pdev = pdev;
 
-       /* Find out what card type it is */
-       nozomi_get_card_type(dc);
-
        ret = pci_enable_device(dc->pdev);
        if (ret) {
                dev_err(&pdev->dev, "Failed to enable PCI Device\n");
                goto err_free;
        }
 
-       start = pci_resource_start(dc->pdev, 0);
-       if (start == 0) {
-               dev_err(&pdev->dev, "No I/O address for card detected\n");
-               ret = -ENODEV;
-               goto err_disable_device;
-       }
-
        ret = pci_request_regions(dc->pdev, NOZOMI_NAME);
        if (ret) {
                dev_err(&pdev->dev, "I/O address 0x%04x already in use\n",
@@ -1389,7 +1397,17 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev,
                goto err_disable_device;
        }
 
-       dc->base_addr = ioremap(start, dc->card_type);
+       start = pci_resource_start(dc->pdev, 0);
+       if (start == 0) {
+               dev_err(&pdev->dev, "No I/O address for card detected\n");
+               ret = -ENODEV;
+               goto err_rel_regs;
+       }
+
+       /* Find out what card type it is */
+       nozomi_get_card_type(dc);
+
+       dc->base_addr = ioremap_nocache(start, dc->card_type);
        if (!dc->base_addr) {
                dev_err(&pdev->dev, "Unable to map card MMIO\n");
                ret = -ENODEV;
@@ -1425,6 +1443,14 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev,
        dc->index_start = ndev_idx * MAX_PORT;
        ndevs[ndev_idx] = dc;
 
+       pci_set_drvdata(pdev, dc);
+
+       /* Enable RESET interrupt */
+       dc->last_ier = RESET;
+       iowrite16(dc->last_ier, dc->reg_ier);
+
+       dc->state = NOZOMI_STATE_ENABLED;
+
        for (i = 0; i < MAX_PORT; i++) {
                mutex_init(&dc->port[i].tty_sem);
                dc->port[i].tty_open_count = 0;
@@ -1433,12 +1459,6 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev,
                                                        &pdev->dev);
        }
 
-       /* Enable  RESET interrupt. */
-       dc->last_ier = RESET;
-       writew(dc->last_ier, dc->reg_ier);
-
-       pci_set_drvdata(pdev, dc);
-
        return 0;
 
 err_free_sbuf:
@@ -1553,7 +1573,7 @@ static int ntty_open(struct tty_struct *tty, struct file *file)
        struct nozomi *dc = get_dc_by_tty(tty);
        unsigned long flags;
 
-       if (!port || !dc)
+       if (!port || !dc || dc->state != NOZOMI_STATE_READY)
                return -ENODEV;
 
        if (mutex_lock_interruptible(&port->tty_sem))
@@ -1704,6 +1724,8 @@ static int ntty_tiocmget(struct tty_struct *tty, struct file *file)
        const struct ctrl_dl *ctrl_dl = &port->ctrl_dl;
        const struct ctrl_ul *ctrl_ul = &port->ctrl_ul;
 
+       /* Note: these could change under us but it is not clear this
+          matters if so */
        return  (ctrl_ul->RTS ? TIOCM_RTS : 0) |
                (ctrl_ul->DTR ? TIOCM_DTR : 0) |
                (ctrl_dl->DCD ? TIOCM_CAR : 0) |
@@ -1716,6 +1738,10 @@ static int ntty_tiocmget(struct tty_struct *tty, struct file *file)
 static int ntty_tiocmset(struct tty_struct *tty, struct file *file,
        unsigned int set, unsigned int clear)
 {
+       struct nozomi *dc = get_dc_by_tty(tty);
+       unsigned long flags;
+
+       spin_lock_irqsave(&dc->spin_mutex, flags);
        if (set & TIOCM_RTS)
                set_rts(tty, 1);
        else if (clear & TIOCM_RTS)
@@ -1725,6 +1751,7 @@ static int ntty_tiocmset(struct tty_struct *tty, struct file *file,
                set_dtr(tty, 1);
        else if (clear & TIOCM_DTR)
                set_dtr(tty, 0);
+       spin_unlock_irqrestore(&dc->spin_mutex, flags);
 
        return 0;
 }
@@ -1762,7 +1789,7 @@ static int ntty_ioctl_tiocgicount(struct port *port, void __user *argp)
        icount.brk = cnow.brk;
        icount.buf_overrun = cnow.buf_overrun;
 
-       return copy_to_user(argp, &icount, sizeof(icount));
+       return copy_to_user(argp, &icount, sizeof(icount)) ? -EFAULT : 0;
 }
 
 static int ntty_ioctl(struct tty_struct *tty, struct file *file,
@@ -1824,16 +1851,6 @@ static void ntty_throttle(struct tty_struct *tty)
        spin_unlock_irqrestore(&dc->spin_mutex, flags);
 }
 
-/* just to discard single character writes */
-static void ntty_put_char(struct tty_struct *tty, unsigned char c)
-{
-       /*
-        * card does not react correct when we write single chars
-        * to the card, so we discard them
-        */
-       DBG2("PUT CHAR Function: %c", c);
-}
-
 /* Returns number of chars in buffer, called by tty layer */
 static s32 ntty_chars_in_buffer(struct tty_struct *tty)
 {
@@ -1867,7 +1884,6 @@ static const struct tty_operations tty_ops = {
        .unthrottle = ntty_unthrottle,
        .throttle = ntty_throttle,
        .chars_in_buffer = ntty_chars_in_buffer,
-       .put_char = ntty_put_char,
        .tiocmget = ntty_tiocmget,
        .tiocmset = ntty_tiocmset,
 };