Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-2.6
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Tue, 11 Mar 2008 01:04:00 +0000 (18:04 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Tue, 11 Mar 2008 01:04:00 +0000 (18:04 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-2.6:
  drivers: fix dma_get_required_mask
  firmware: provide stubs for the FW_LOADER=n case
  nozomi: fix initialization and early flow control access
  sysdev: fix problem with sysdev_class being re-registered

drivers/base/platform.c
drivers/base/sys.c
drivers/char/nozomi.c
include/linux/firmware.h

index efaf282c438c4108b1f01c41dc6b873c0fde669d..911ec600fe71dec287cf922441a8cf53855ecf3f 100644 (file)
@@ -648,7 +648,7 @@ u64 dma_get_required_mask(struct device *dev)
                high_totalram += high_totalram - 1;
                mask = (((u64)high_totalram) << 32) + 0xffffffff;
        }
-       return mask & *dev->dma_mask;
+       return mask;
 }
 EXPORT_SYMBOL_GPL(dma_get_required_mask);
 #endif
index 2f79c55acdcc6af406a9e03b469a4853eefee808..8e13fd9421635753f7b634ba4177b5df003a074f 100644 (file)
@@ -133,6 +133,7 @@ int sysdev_class_register(struct sysdev_class * cls)
        pr_debug("Registering sysdev class '%s'\n",
                 kobject_name(&cls->kset.kobj));
        INIT_LIST_HEAD(&cls->drivers);
+       memset(&cls->kset.kobj, 0x00, sizeof(struct kobject));
        cls->kset.kobj.parent = &system_kset->kobj;
        cls->kset.kobj.ktype = &ktype_sysdev_class;
        cls->kset.kobj.kset = system_kset;
@@ -227,6 +228,9 @@ int sysdev_register(struct sys_device * sysdev)
 
        pr_debug("Registering sys device '%s'\n", kobject_name(&sysdev->kobj));
 
+       /* initialize the kobject to 0, in case it had previously been used */
+       memset(&sysdev->kobj, 0x00, sizeof(struct kobject));
+
        /* Make sure the kset is set */
        sysdev->kobj.kset = &cls->kset;
 
index dfaab2322de32c09a0adeab709cf5613ca9a0d5f..6d0dc5f9b6bbc015b4b4323d02fb6ed83b7e81e9 100644 (file)
@@ -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;
 };
 
@@ -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,6 +1397,16 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev,
                goto err_disable_device;
        }
 
+       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(start, dc->card_type);
        if (!dc->base_addr) {
                dev_err(&pdev->dev, "Unable to map card MMIO\n");
@@ -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))
@@ -1716,6 +1736,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 +1749,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 +1787,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,
index 33d8f2087b6ea92557c6497a605e3f925e7700e4..4d10c7328d2dabafcee9cf285bf263ba6988b3cd 100644 (file)
@@ -10,7 +10,10 @@ struct firmware {
        size_t size;
        u8 *data;
 };
+
 struct device;
+
+#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
 int request_firmware(const struct firmware **fw, const char *name,
                     struct device *device);
 int request_firmware_nowait(
@@ -19,4 +22,24 @@ int request_firmware_nowait(
        void (*cont)(const struct firmware *fw, void *context));
 
 void release_firmware(const struct firmware *fw);
+#else
+static inline int request_firmware(const struct firmware **fw,
+                                  const char *name,
+                                  struct device *device)
+{
+       return -EINVAL;
+}
+static inline int request_firmware_nowait(
+       struct module *module, int uevent,
+       const char *name, struct device *device, void *context,
+       void (*cont)(const struct firmware *fw, void *context))
+{
+       return -EINVAL;
+}
+
+static inline void release_firmware(const struct firmware *fw)
+{
+}
+#endif
+
 #endif