]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Thu, 10 May 2007 20:32:05 +0000 (13:32 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Thu, 10 May 2007 20:32:05 +0000 (13:32 -0700)
* master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6:
  [SPARC64]: Use alloc_pci_dev() in PCI bus probes.
  [SPARC64]: Bump PROMINTR_MAX to 32.
  [SPARC64]: Fix recursion in PROM tree building.
  [SERIAL] sunzilog: Interrupt enable before ISR handler installed
  [SPARC64] PCI: Consolidate PCI access code into pci_common.c

12 files changed:
arch/sparc64/kernel/pci.c
arch/sparc64/kernel/pci_common.c
arch/sparc64/kernel/pci_fire.c
arch/sparc64/kernel/pci_impl.h
arch/sparc64/kernel/pci_psycho.c
arch/sparc64/kernel/pci_sabre.c
arch/sparc64/kernel/pci_schizo.c
arch/sparc64/kernel/pci_sun4v.c
arch/sparc64/kernel/prom.c
drivers/serial/sunzilog.c
drivers/serial/sunzilog.h
include/asm-sparc64/openprom.h

index d85e1ed7c3e438d3425ab96d103c3f427ca4a38a..cf9a75112d0fa9bdb9e00d09fa9c454ee7e8e17b 100644 (file)
@@ -377,7 +377,7 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
        const char *type;
        u32 class;
 
-       dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL);
+       dev = alloc_pci_dev();
        if (!dev)
                return NULL;
 
index 76faaa8135dd957b0e28ad53499cc47d766babb7..f974fefc3ebc273ceea972b6a936d21888326017 100644 (file)
 #include <asm/oplib.h>
 
 #include "pci_impl.h"
+#include "pci_sun4v.h"
+
+static int config_out_of_range(struct pci_pbm_info *pbm,
+                              unsigned long bus,
+                              unsigned long devfn,
+                              unsigned long reg)
+{
+       if (bus < pbm->pci_first_busno ||
+           bus > pbm->pci_last_busno)
+               return 1;
+       return 0;
+}
+
+static void *sun4u_config_mkaddr(struct pci_pbm_info *pbm,
+                                unsigned long bus,
+                                unsigned long devfn,
+                                unsigned long reg)
+{
+       unsigned long rbits = pbm->config_space_reg_bits;
+
+       if (config_out_of_range(pbm, bus, devfn, reg))
+               return NULL;
+
+       reg = (reg & ((1 << rbits) - 1));
+       devfn <<= rbits;
+       bus <<= rbits + 8;
+
+       return (void *) (pbm->config_space | bus | devfn | reg);
+}
+
+static int sun4u_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
+                             int where, int size, u32 *value)
+{
+       struct pci_pbm_info *pbm = bus_dev->sysdata;
+       unsigned char bus = bus_dev->number;
+       u32 *addr;
+       u16 tmp16;
+       u8 tmp8;
+
+       if (bus_dev == pbm->pci_bus && devfn == 0x00)
+               return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where,
+                                                   size, value);
+
+       switch (size) {
+       case 1:
+               *value = 0xff;
+               break;
+       case 2:
+               *value = 0xffff;
+               break;
+       case 4:
+               *value = 0xffffffff;
+               break;
+       }
+
+       addr = sun4u_config_mkaddr(pbm, bus, devfn, where);
+       if (!addr)
+               return PCIBIOS_SUCCESSFUL;
+
+       switch (size) {
+       case 1:
+               pci_config_read8((u8 *)addr, &tmp8);
+               *value = (u32) tmp8;
+               break;
+
+       case 2:
+               if (where & 0x01) {
+                       printk("pci_read_config_word: misaligned reg [%x]\n",
+                              where);
+                       return PCIBIOS_SUCCESSFUL;
+               }
+               pci_config_read16((u16 *)addr, &tmp16);
+               *value = (u32) tmp16;
+               break;
+
+       case 4:
+               if (where & 0x03) {
+                       printk("pci_read_config_dword: misaligned reg [%x]\n",
+                              where);
+                       return PCIBIOS_SUCCESSFUL;
+               }
+               pci_config_read32(addr, value);
+               break;
+       }
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static int sun4u_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
+                              int where, int size, u32 value)
+{
+       struct pci_pbm_info *pbm = bus_dev->sysdata;
+       unsigned char bus = bus_dev->number;
+       u32 *addr;
+
+       if (bus_dev == pbm->pci_bus && devfn == 0x00)
+               return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where,
+                                                    size, value);
+       addr = sun4u_config_mkaddr(pbm, bus, devfn, where);
+       if (!addr)
+               return PCIBIOS_SUCCESSFUL;
+
+       switch (size) {
+       case 1:
+               pci_config_write8((u8 *)addr, value);
+               break;
+
+       case 2:
+               if (where & 0x01) {
+                       printk("pci_write_config_word: misaligned reg [%x]\n",
+                              where);
+                       return PCIBIOS_SUCCESSFUL;
+               }
+               pci_config_write16((u16 *)addr, value);
+               break;
+
+       case 4:
+               if (where & 0x03) {
+                       printk("pci_write_config_dword: misaligned reg [%x]\n",
+                              where);
+                       return PCIBIOS_SUCCESSFUL;
+               }
+               pci_config_write32(addr, value);
+       }
+       return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops sun4u_pci_ops = {
+       .read =         sun4u_read_pci_cfg,
+       .write =        sun4u_write_pci_cfg,
+};
+
+static int sun4v_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
+                             int where, int size, u32 *value)
+{
+       struct pci_pbm_info *pbm = bus_dev->sysdata;
+       u32 devhandle = pbm->devhandle;
+       unsigned int bus = bus_dev->number;
+       unsigned int device = PCI_SLOT(devfn);
+       unsigned int func = PCI_FUNC(devfn);
+       unsigned long ret;
+
+       if (bus_dev == pbm->pci_bus && devfn == 0x00)
+               return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where,
+                                                   size, value);
+       if (config_out_of_range(pbm, bus, devfn, where)) {
+               ret = ~0UL;
+       } else {
+               ret = pci_sun4v_config_get(devhandle,
+                               HV_PCI_DEVICE_BUILD(bus, device, func),
+                               where, size);
+       }
+       switch (size) {
+       case 1:
+               *value = ret & 0xff;
+               break;
+       case 2:
+               *value = ret & 0xffff;
+               break;
+       case 4:
+               *value = ret & 0xffffffff;
+               break;
+       };
+
+
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static int sun4v_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
+                              int where, int size, u32 value)
+{
+       struct pci_pbm_info *pbm = bus_dev->sysdata;
+       u32 devhandle = pbm->devhandle;
+       unsigned int bus = bus_dev->number;
+       unsigned int device = PCI_SLOT(devfn);
+       unsigned int func = PCI_FUNC(devfn);
+       unsigned long ret;
+
+       if (bus_dev == pbm->pci_bus && devfn == 0x00)
+               return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where,
+                                                    size, value);
+       if (config_out_of_range(pbm, bus, devfn, where)) {
+               /* Do nothing. */
+       } else {
+               ret = pci_sun4v_config_put(devhandle,
+                               HV_PCI_DEVICE_BUILD(bus, device, func),
+                               where, size, value);
+       }
+       return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops sun4v_pci_ops = {
+       .read =         sun4v_read_pci_cfg,
+       .write =        sun4v_write_pci_cfg,
+};
 
 void pci_get_pbm_props(struct pci_pbm_info *pbm)
 {
index 2e0eb4ee8f71a67176d370bfc8d19366d8aec1ad..9198c1a0f7a5df0f9a2cd4bc12b23947080675ff 100644 (file)
                               "i" (ASI_PHYS_BYPASS_EC_E) \
                             : "memory")
 
-/* Fire config space address format is nearly identical to
- * that of SCHIZO and PSYCHO, except that in order to accomodate
- * PCI-E extended config space the encoding can handle 12 bits
- * of register address:
- *
- *  32     28 27 20 19    15 14      12 11  2  1 0
- * -------------------------------------------------
- * |0 0 0 0 0| bus | device | function | reg | 0 0 |
- * -------------------------------------------------
- */
-#define FIRE_CONFIG_BASE(PBM)  ((PBM)->config_space)
-#define FIRE_CONFIG_ENCODE(BUS, DEVFN, REG)    \
-       (((unsigned long)(BUS)   << 20) |       \
-        ((unsigned long)(DEVFN) << 12)  |      \
-        ((unsigned long)(REG)))
-
-static void *fire_pci_config_mkaddr(struct pci_pbm_info *pbm,
-                                     unsigned char bus,
-                                     unsigned int devfn,
-                                     int where)
-{
-       if (!pbm)
-               return NULL;
-       return (void *)
-               (FIRE_CONFIG_BASE(pbm) |
-                FIRE_CONFIG_ENCODE(bus, devfn, where));
-}
-
-/* FIRE PCI configuration space accessors. */
-
-static int fire_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
-                            int where, int size, u32 *value)
-{
-       struct pci_pbm_info *pbm = bus_dev->sysdata;
-       unsigned char bus = bus_dev->number;
-       u32 *addr;
-       u16 tmp16;
-       u8 tmp8;
-
-       if (bus_dev == pbm->pci_bus && devfn == 0x00)
-               return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where,
-                                                   size, value);
-       switch (size) {
-       case 1:
-               *value = 0xff;
-               break;
-       case 2:
-               *value = 0xffff;
-               break;
-       case 4:
-               *value = 0xffffffff;
-               break;
-       }
-
-       addr = fire_pci_config_mkaddr(pbm, bus, devfn, where);
-       if (!addr)
-               return PCIBIOS_SUCCESSFUL;
-
-       switch (size) {
-       case 1:
-               pci_config_read8((u8 *)addr, &tmp8);
-               *value = tmp8;
-               break;
-
-       case 2:
-               if (where & 0x01) {
-                       printk("pci_read_config_word: misaligned reg [%x]\n",
-                              where);
-                       return PCIBIOS_SUCCESSFUL;
-               }
-               pci_config_read16((u16 *)addr, &tmp16);
-               *value = tmp16;
-               break;
-
-       case 4:
-               if (where & 0x03) {
-                       printk("pci_read_config_dword: misaligned reg [%x]\n",
-                              where);
-                       return PCIBIOS_SUCCESSFUL;
-               }
-
-               pci_config_read32(addr, value);
-               break;
-       }
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int fire_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
-                             int where, int size, u32 value)
-{
-       struct pci_pbm_info *pbm = bus_dev->sysdata;
-       unsigned char bus = bus_dev->number;
-       u32 *addr;
-
-       if (bus_dev == pbm->pci_bus && devfn == 0x00)
-               return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where,
-                                                    size, value);
-       addr = fire_pci_config_mkaddr(pbm, bus, devfn, where);
-       if (!addr)
-               return PCIBIOS_SUCCESSFUL;
-
-       switch (size) {
-       case 1:
-               pci_config_write8((u8 *)addr, value);
-               break;
-
-       case 2:
-               if (where & 0x01) {
-                       printk("pci_write_config_word: misaligned reg [%x]\n",
-                              where);
-                       return PCIBIOS_SUCCESSFUL;
-               }
-               pci_config_write16((u16 *)addr, value);
-               break;
-
-       case 4:
-               if (where & 0x03) {
-                       printk("pci_write_config_dword: misaligned reg [%x]\n",
-                              where);
-                       return PCIBIOS_SUCCESSFUL;
-               }
-
-               pci_config_write32(addr, value);
-       }
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops pci_fire_ops = {
-       .read   =       fire_read_pci_cfg,
-       .write  =       fire_write_pci_cfg,
-};
-
 static void pci_fire_scan_bus(struct pci_pbm_info *pbm)
 {
        pbm->pci_bus = pci_scan_one_pbm(pbm);
@@ -314,7 +182,8 @@ static void pci_fire_pbm_init(struct pci_controller_info *p,
        pci_pbm_root = pbm;
 
        pbm->scan_bus = pci_fire_scan_bus;
-       pbm->pci_ops = &pci_fire_ops;
+       pbm->pci_ops = &sun4u_pci_ops;
+       pbm->config_space_reg_bits = 12;
 
        pbm->index = pci_num_pbms++;
 
index 8e38023868aafd81a509c07194b76b84ccbee70b..f660c2b685ebfe6c8682dff6facfe8f8acaf9e8f 100644 (file)
@@ -77,6 +77,9 @@ struct pci_pbm_info {
        /* Base of PCI Config space, can be per-PBM or shared. */
        unsigned long                   config_space;
 
+       /* This will be 12 on PCI-E controllers, 8 elsewhere.  */
+       unsigned long                   config_space_reg_bits;
+
        /* State of 66MHz capabilities on this PBM. */
        int                             is_66mhz_capable;
        int                             all_devs_66mhz;
@@ -156,4 +159,7 @@ extern void pci_config_write8(u8 *addr, u8 val);
 extern void pci_config_write16(u16 *addr, u16 val);
 extern void pci_config_write32(u32 *addr, u32 val);
 
+extern struct pci_ops sun4u_pci_ops;
+extern struct pci_ops sun4v_pci_ops;
+
 #endif /* !(PCI_IMPL_H) */
index 2edcb1dd13c3744674c6e96cba7f39e1be12a477..598393a2df168d1e92910cc9bc2a6866bb933013 100644 (file)
@@ -94,122 +94,6 @@ static void *psycho_pci_config_mkaddr(struct pci_pbm_info *pbm,
                 PSYCHO_CONFIG_ENCODE(bus, devfn, where));
 }
 
-static int psycho_out_of_range(struct pci_pbm_info *pbm,
-                              unsigned char bus,
-                              unsigned char devfn)
-{
-       return ((bus == pbm->pci_first_busno) &&
-               PCI_SLOT(devfn) > 8);
-}
-
-/* PSYCHO PCI configuration space accessors. */
-
-static int psycho_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
-                              int where, int size, u32 *value)
-{
-       struct pci_pbm_info *pbm = bus_dev->sysdata;
-       unsigned char bus = bus_dev->number;
-       u32 *addr;
-       u16 tmp16;
-       u8 tmp8;
-
-       if (bus_dev == pbm->pci_bus && devfn == 0x00)
-               return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where,
-                                                   size, value);
-
-       switch (size) {
-       case 1:
-               *value = 0xff;
-               break;
-       case 2:
-               *value = 0xffff;
-               break;
-       case 4:
-               *value = 0xffffffff;
-               break;
-       }
-
-       addr = psycho_pci_config_mkaddr(pbm, bus, devfn, where);
-       if (!addr)
-               return PCIBIOS_SUCCESSFUL;
-
-       if (psycho_out_of_range(pbm, bus, devfn))
-               return PCIBIOS_SUCCESSFUL;
-       switch (size) {
-       case 1:
-               pci_config_read8((u8 *)addr, &tmp8);
-               *value = (u32) tmp8;
-               break;
-
-       case 2:
-               if (where & 0x01) {
-                       printk("pci_read_config_word: misaligned reg [%x]\n",
-                              where);
-                       return PCIBIOS_SUCCESSFUL;
-               }
-               pci_config_read16((u16 *)addr, &tmp16);
-               *value = (u32) tmp16;
-               break;
-
-       case 4:
-               if (where & 0x03) {
-                       printk("pci_read_config_dword: misaligned reg [%x]\n",
-                              where);
-                       return PCIBIOS_SUCCESSFUL;
-               }
-               pci_config_read32(addr, value);
-               break;
-       }
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int psycho_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
-                               int where, int size, u32 value)
-{
-       struct pci_pbm_info *pbm = bus_dev->sysdata;
-       unsigned char bus = bus_dev->number;
-       u32 *addr;
-
-       if (bus_dev == pbm->pci_bus && devfn == 0x00)
-               return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where,
-                                                    size, value);
-       addr = psycho_pci_config_mkaddr(pbm, bus, devfn, where);
-       if (!addr)
-               return PCIBIOS_SUCCESSFUL;
-
-       if (psycho_out_of_range(pbm, bus, devfn))
-               return PCIBIOS_SUCCESSFUL;
-
-       switch (size) {
-       case 1:
-               pci_config_write8((u8 *)addr, value);
-               break;
-
-       case 2:
-               if (where & 0x01) {
-                       printk("pci_write_config_word: misaligned reg [%x]\n",
-                              where);
-                       return PCIBIOS_SUCCESSFUL;
-               }
-               pci_config_write16((u16 *)addr, value);
-               break;
-
-       case 4:
-               if (where & 0x03) {
-                       printk("pci_write_config_dword: misaligned reg [%x]\n",
-                              where);
-                       return PCIBIOS_SUCCESSFUL;
-               }
-               pci_config_write32(addr, value);
-       }
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops psycho_ops = {
-       .read =         psycho_read_pci_cfg,
-       .write =        psycho_write_pci_cfg,
-};
-
 /* PSYCHO error handling support. */
 enum psycho_error_type {
        UE_ERR, CE_ERR, PCI_ERR
@@ -1089,7 +973,8 @@ static void psycho_pbm_init(struct pci_controller_info *p,
        pci_pbm_root = pbm;
 
        pbm->scan_bus = psycho_scan_bus;
-       pbm->pci_ops = &psycho_ops;
+       pbm->pci_ops = &sun4u_pci_ops;
+       pbm->config_space_reg_bits = 8;
 
        pbm->index = pci_num_pbms++;
 
index 4cefe6e83b24cfc02783a21b5dc0a80c4721f558..e2377796de894e6f08164cfca6f4870f4192eb36 100644 (file)
 #define SABRE_MEMSPACE         0x100000000UL
 #define SABRE_MEMSPACE_SIZE    0x07fffffffUL
 
-/* UltraSparc-IIi Programmer's Manual, page 325, PCI
- * configuration space address format:
- * 
- *  32             24 23 16 15    11 10       8 7   2  1 0
- * ---------------------------------------------------------
- * |0 0 0 0 0 0 0 0 1| bus | device | function | reg | 0 0 |
- * ---------------------------------------------------------
- */
-#define SABRE_CONFIG_BASE(PBM) \
-       ((PBM)->config_space | (1UL << 24))
-#define SABRE_CONFIG_ENCODE(BUS, DEVFN, REG)   \
-       (((unsigned long)(BUS)   << 16) |       \
-        ((unsigned long)(DEVFN) << 8)  |       \
-        ((unsigned long)(REG)))
-
 static int hummingbird_p;
 static struct pci_bus *sabre_root_bus;
 
-static void *sabre_pci_config_mkaddr(struct pci_pbm_info *pbm,
-                                    unsigned char bus,
-                                    unsigned int devfn,
-                                    int where)
-{
-       if (!pbm)
-               return NULL;
-       return (void *)
-               (SABRE_CONFIG_BASE(pbm) |
-                SABRE_CONFIG_ENCODE(bus, devfn, where));
-}
-
-static int sabre_out_of_range(unsigned char devfn)
-{
-       if (hummingbird_p)
-               return 0;
-
-       return (((PCI_SLOT(devfn) == 0) && (PCI_FUNC(devfn) > 0)) ||
-               ((PCI_SLOT(devfn) == 1) && (PCI_FUNC(devfn) > 1)) ||
-               (PCI_SLOT(devfn) > 1));
-}
-
-static int __sabre_out_of_range(struct pci_pbm_info *pbm,
-                               unsigned char bus,
-                               unsigned char devfn)
-{
-       if (hummingbird_p)
-               return 0;
-
-       return ((pbm->parent == 0) ||
-               ((pbm == &pbm->parent->pbm_A) &&
-                (bus == pbm->pci_first_busno) &&
-                PCI_SLOT(devfn) > 8));
-}
-
-static int __sabre_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
-                               int where, int size, u32 *value)
-{
-       struct pci_pbm_info *pbm = bus_dev->sysdata;
-       unsigned char bus = bus_dev->number;
-       u32 *addr;
-       u16 tmp16;
-       u8 tmp8;
-
-       switch (size) {
-       case 1:
-               *value = 0xff;
-               break;
-       case 2:
-               *value = 0xffff;
-               break;
-       case 4:
-               *value = 0xffffffff;
-               break;
-       }
-
-       addr = sabre_pci_config_mkaddr(pbm, bus, devfn, where);
-       if (!addr)
-               return PCIBIOS_SUCCESSFUL;
-
-       if (__sabre_out_of_range(pbm, bus, devfn))
-               return PCIBIOS_SUCCESSFUL;
-
-       switch (size) {
-       case 1:
-               pci_config_read8((u8 *) addr, &tmp8);
-               *value = tmp8;
-               break;
-
-       case 2:
-               if (where & 0x01) {
-                       printk("pci_read_config_word: misaligned reg [%x]\n",
-                              where);
-                       return PCIBIOS_SUCCESSFUL;
-               }
-               pci_config_read16((u16 *) addr, &tmp16);
-               *value = tmp16;
-               break;
-
-       case 4:
-               if (where & 0x03) {
-                       printk("pci_read_config_dword: misaligned reg [%x]\n",
-                              where);
-                       return PCIBIOS_SUCCESSFUL;
-               }
-               pci_config_read32(addr, value);
-               break;
-       }
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int sabre_read_pci_cfg(struct pci_bus *bus, unsigned int devfn,
-                             int where, int size, u32 *value)
-{
-       struct pci_pbm_info *pbm = bus->sysdata;
-
-       if (bus == pbm->pci_bus && devfn == 0x00)
-               return pci_host_bridge_read_pci_cfg(bus, devfn, where,
-                                                   size, value);
-
-       if (!bus->number && sabre_out_of_range(devfn)) {
-               switch (size) {
-               case 1:
-                       *value = 0xff;
-                       break;
-               case 2:
-                       *value = 0xffff;
-                       break;
-               case 4:
-                       *value = 0xffffffff;
-                       break;
-               }
-               return PCIBIOS_SUCCESSFUL;
-       }
-
-       if (bus->number || PCI_SLOT(devfn))
-               return __sabre_read_pci_cfg(bus, devfn, where, size, value);
-
-       /* When accessing PCI config space of the PCI controller itself (bus
-        * 0, device slot 0, function 0) there are restrictions.  Each
-        * register must be accessed as it's natural size.  Thus, for example
-        * the Vendor ID must be accessed as a 16-bit quantity.
-        */
-
-       switch (size) {
-       case 1:
-               if (where < 8) {
-                       u32 tmp32;
-                       u16 tmp16;
-
-                       __sabre_read_pci_cfg(bus, devfn, where & ~1, 2, &tmp32);
-                       tmp16 = (u16) tmp32;
-                       if (where & 1)
-                               *value = tmp16 >> 8;
-                       else
-                               *value = tmp16 & 0xff;
-               } else
-                       return __sabre_read_pci_cfg(bus, devfn, where, 1, value);
-               break;
-
-       case 2:
-               if (where < 8)
-                       return __sabre_read_pci_cfg(bus, devfn, where, 2, value);
-               else {
-                       u32 tmp32;
-                       u8 tmp8;
-
-                       __sabre_read_pci_cfg(bus, devfn, where, 1, &tmp32);
-                       tmp8 = (u8) tmp32;
-                       *value = tmp8;
-                       __sabre_read_pci_cfg(bus, devfn, where + 1, 1, &tmp32);
-                       tmp8 = (u8) tmp32;
-                       *value |= tmp8 << 8;
-               }
-               break;
-
-       case 4: {
-               u32 tmp32;
-               u16 tmp16;
-
-               sabre_read_pci_cfg(bus, devfn, where, 2, &tmp32);
-               tmp16 = (u16) tmp32;
-               *value = tmp16;
-               sabre_read_pci_cfg(bus, devfn, where + 2, 2, &tmp32);
-               tmp16 = (u16) tmp32;
-               *value |= tmp16 << 16;
-               break;
-       }
-       }
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int __sabre_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
-                                int where, int size, u32 value)
-{
-       struct pci_pbm_info *pbm = bus_dev->sysdata;
-       unsigned char bus = bus_dev->number;
-       u32 *addr;
-
-       addr = sabre_pci_config_mkaddr(pbm, bus, devfn, where);
-       if (!addr)
-               return PCIBIOS_SUCCESSFUL;
-
-       if (__sabre_out_of_range(pbm, bus, devfn))
-               return PCIBIOS_SUCCESSFUL;
-
-       switch (size) {
-       case 1:
-               pci_config_write8((u8 *) addr, value);
-               break;
-
-       case 2:
-               if (where & 0x01) {
-                       printk("pci_write_config_word: misaligned reg [%x]\n",
-                              where);
-                       return PCIBIOS_SUCCESSFUL;
-               }
-               pci_config_write16((u16 *) addr, value);
-               break;
-
-       case 4:
-               if (where & 0x03) {
-                       printk("pci_write_config_dword: misaligned reg [%x]\n",
-                              where);
-                       return PCIBIOS_SUCCESSFUL;
-               }
-               pci_config_write32(addr, value);
-               break;
-       }
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int sabre_write_pci_cfg(struct pci_bus *bus, unsigned int devfn,
-                              int where, int size, u32 value)
-{
-       struct pci_pbm_info *pbm = bus->sysdata;
-
-       if (bus == pbm->pci_bus && devfn == 0x00)
-               return pci_host_bridge_write_pci_cfg(bus, devfn, where,
-                                                    size, value);
-
-       if (bus->number)
-               return __sabre_write_pci_cfg(bus, devfn, where, size, value);
-
-       if (sabre_out_of_range(devfn))
-               return PCIBIOS_SUCCESSFUL;
-
-       switch (size) {
-       case 1:
-               if (where < 8) {
-                       u32 tmp32;
-                       u16 tmp16;
-
-                       __sabre_read_pci_cfg(bus, devfn, where & ~1, 2, &tmp32);
-                       tmp16 = (u16) tmp32;
-                       if (where & 1) {
-                               value &= 0x00ff;
-                               value |= tmp16 << 8;
-                       } else {
-                               value &= 0xff00;
-                               value |= tmp16;
-                       }
-                       tmp32 = (u32) tmp16;
-                       return __sabre_write_pci_cfg(bus, devfn, where & ~1, 2, tmp32);
-               } else
-                       return __sabre_write_pci_cfg(bus, devfn, where, 1, value);
-               break;
-       case 2:
-               if (where < 8)
-                       return __sabre_write_pci_cfg(bus, devfn, where, 2, value);
-               else {
-                       __sabre_write_pci_cfg(bus, devfn, where, 1, value & 0xff);
-                       __sabre_write_pci_cfg(bus, devfn, where + 1, 1, value >> 8);
-               }
-               break;
-       case 4:
-               sabre_write_pci_cfg(bus, devfn, where, 2, value & 0xffff);
-               sabre_write_pci_cfg(bus, devfn, where + 2, 2, value >> 16);
-               break;
-       }
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops sabre_ops = {
-       .read =         sabre_read_pci_cfg,
-       .write =        sabre_write_pci_cfg,
-};
-
 /* SABRE error handling support. */
 static void sabre_check_iommu_error(struct pci_pbm_info *pbm,
                                    unsigned long afsr,
@@ -1010,7 +725,8 @@ static void sabre_pbm_init(struct pci_controller_info *p, struct pci_pbm_info *p
        printk("%s: SABRE PCI Bus Module\n", pbm->name);
 
        pbm->scan_bus = sabre_scan_bus;
-       pbm->pci_ops = &sabre_ops;
+       pbm->pci_ops = &sun4u_pci_ops;
+       pbm->config_space_reg_bits = 8;
 
        pbm->index = pci_num_pbms++;
 
index e375d72b8eed0acf1ab8b46a7038008325512c33..ae76898bbe2b0fcfa239669f31a794eb56191935 100644 (file)
@@ -104,125 +104,6 @@ static void *schizo_pci_config_mkaddr(struct pci_pbm_info *pbm,
                 SCHIZO_CONFIG_ENCODE(bus, devfn, where));
 }
 
-/* Just make sure the bus number is in range.  */
-static int schizo_out_of_range(struct pci_pbm_info *pbm,
-                              unsigned char bus,
-                              unsigned char devfn)
-{
-       if (bus < pbm->pci_first_busno ||
-           bus > pbm->pci_last_busno)
-               return 1;
-       return 0;
-}
-
-/* SCHIZO PCI configuration space accessors. */
-
-static int schizo_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
-                              int where, int size, u32 *value)
-{
-       struct pci_pbm_info *pbm = bus_dev->sysdata;
-       unsigned char bus = bus_dev->number;
-       u32 *addr;
-       u16 tmp16;
-       u8 tmp8;
-
-       if (bus_dev == pbm->pci_bus && devfn == 0x00)
-               return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where,
-                                                   size, value);
-       switch (size) {
-       case 1:
-               *value = 0xff;
-               break;
-       case 2:
-               *value = 0xffff;
-               break;
-       case 4:
-               *value = 0xffffffff;
-               break;
-       }
-
-       addr = schizo_pci_config_mkaddr(pbm, bus, devfn, where);
-       if (!addr)
-               return PCIBIOS_SUCCESSFUL;
-
-       if (schizo_out_of_range(pbm, bus, devfn))
-               return PCIBIOS_SUCCESSFUL;
-       switch (size) {
-       case 1:
-               pci_config_read8((u8 *)addr, &tmp8);
-               *value = tmp8;
-               break;
-
-       case 2:
-               if (where & 0x01) {
-                       printk("pci_read_config_word: misaligned reg [%x]\n",
-                              where);
-                       return PCIBIOS_SUCCESSFUL;
-               }
-               pci_config_read16((u16 *)addr, &tmp16);
-               *value = tmp16;
-               break;
-
-       case 4:
-               if (where & 0x03) {
-                       printk("pci_read_config_dword: misaligned reg [%x]\n",
-                              where);
-                       return PCIBIOS_SUCCESSFUL;
-               }
-               pci_config_read32(addr, value);
-               break;
-       }
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int schizo_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
-                               int where, int size, u32 value)
-{
-       struct pci_pbm_info *pbm = bus_dev->sysdata;
-       unsigned char bus = bus_dev->number;
-       u32 *addr;
-
-       if (bus_dev == pbm->pci_bus && devfn == 0x00)
-               return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where,
-                                                    size, value);
-       addr = schizo_pci_config_mkaddr(pbm, bus, devfn, where);
-       if (!addr)
-               return PCIBIOS_SUCCESSFUL;
-
-       if (schizo_out_of_range(pbm, bus, devfn))
-               return PCIBIOS_SUCCESSFUL;
-
-       switch (size) {
-       case 1:
-               pci_config_write8((u8 *)addr, value);
-               break;
-
-       case 2:
-               if (where & 0x01) {
-                       printk("pci_write_config_word: misaligned reg [%x]\n",
-                              where);
-                       return PCIBIOS_SUCCESSFUL;
-               }
-               pci_config_write16((u16 *)addr, value);
-               break;
-
-       case 4:
-               if (where & 0x03) {
-                       printk("pci_write_config_dword: misaligned reg [%x]\n",
-                              where);
-                       return PCIBIOS_SUCCESSFUL;
-               }
-
-               pci_config_write32(addr, value);
-       }
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops schizo_ops = {
-       .read =         schizo_read_pci_cfg,
-       .write =        schizo_write_pci_cfg,
-};
-
 /* SCHIZO error handling support. */
 enum schizo_error_type {
        UE_ERR, CE_ERR, PCI_ERR, SAFARI_ERR
@@ -1494,7 +1375,8 @@ static void schizo_pbm_init(struct pci_controller_info *p,
        pci_pbm_root = pbm;
 
        pbm->scan_bus = schizo_scan_bus;
-       pbm->pci_ops = &schizo_ops;
+       pbm->pci_ops = &sun4u_pci_ops;
+       pbm->config_space_reg_bits = 8;
 
        pbm->index = pci_num_pbms++;
 
index 0c76a8891a96b270bd8e5ff279134333fbf70823..34df4047587a4db2c95506410e5e2edd96b35837 100644 (file)
@@ -593,89 +593,6 @@ const struct pci_iommu_ops pci_sun4v_iommu_ops = {
        .dma_sync_sg_for_cpu            = pci_4v_dma_sync_sg_for_cpu,
 };
 
-static inline int pci_sun4v_out_of_range(struct pci_pbm_info *pbm, unsigned int bus, unsigned int device, unsigned int func)
-{
-       if (bus < pbm->pci_first_busno ||
-           bus > pbm->pci_last_busno)
-               return 1;
-       return 0;
-}
-
-static int pci_sun4v_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
-                                 int where, int size, u32 *value)
-{
-       struct pci_pbm_info *pbm = bus_dev->sysdata;
-       u32 devhandle = pbm->devhandle;
-       unsigned int bus = bus_dev->number;
-       unsigned int device = PCI_SLOT(devfn);
-       unsigned int func = PCI_FUNC(devfn);
-       unsigned long ret;
-
-       if (bus_dev == pbm->pci_bus && devfn == 0x00)
-               return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where,
-                                                   size, value);
-       if (pci_sun4v_out_of_range(pbm, bus, device, func)) {
-               ret = ~0UL;
-       } else {
-               ret = pci_sun4v_config_get(devhandle,
-                               HV_PCI_DEVICE_BUILD(bus, device, func),
-                               where, size);
-#if 0
-               printk("rcfg: [%x:%x:%x:%d]=[%lx]\n",
-                      devhandle, HV_PCI_DEVICE_BUILD(bus, device, func),
-                      where, size, ret);
-#endif
-       }
-       switch (size) {
-       case 1:
-               *value = ret & 0xff;
-               break;
-       case 2:
-               *value = ret & 0xffff;
-               break;
-       case 4:
-               *value = ret & 0xffffffff;
-               break;
-       };
-
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int pci_sun4v_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
-                                  int where, int size, u32 value)
-{
-       struct pci_pbm_info *pbm = bus_dev->sysdata;
-       u32 devhandle = pbm->devhandle;
-       unsigned int bus = bus_dev->number;
-       unsigned int device = PCI_SLOT(devfn);
-       unsigned int func = PCI_FUNC(devfn);
-       unsigned long ret;
-
-       if (bus_dev == pbm->pci_bus && devfn == 0x00)
-               return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where,
-                                                    size, value);
-       if (pci_sun4v_out_of_range(pbm, bus, device, func)) {
-               /* Do nothing. */
-       } else {
-               ret = pci_sun4v_config_put(devhandle,
-                               HV_PCI_DEVICE_BUILD(bus, device, func),
-                               where, size, value);
-#if 0
-               printk("wcfg: [%x:%x:%x:%d] v[%x] == [%lx]\n",
-                      devhandle, HV_PCI_DEVICE_BUILD(bus, device, func),
-                      where, size, value, ret);
-#endif
-       }
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops pci_sun4v_ops = {
-       .read =         pci_sun4v_read_pci_cfg,
-       .write =        pci_sun4v_write_pci_cfg,
-};
-
-
 static void pci_sun4v_scan_bus(struct pci_pbm_info *pbm)
 {
        struct property *prop;
@@ -1238,7 +1155,8 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node
        pci_pbm_root = pbm;
 
        pbm->scan_bus = pci_sun4v_scan_bus;
-       pbm->pci_ops = &pci_sun4v_ops;
+       pbm->pci_ops = &sun4v_pci_ops;
+       pbm->config_space_reg_bits = 12;
 
        pbm->index = pci_num_pbms++;
 
index c54d4d8af0142530d861074fe6afdb8b9081d207..b7976b14d0bac15319520d13316cb4492605eeb7 100644 (file)
@@ -1636,10 +1636,21 @@ static struct device_node * __init create_node(phandle node, struct device_node
 
 static struct device_node * __init build_tree(struct device_node *parent, phandle node, struct device_node ***nextp)
 {
+       struct device_node *ret = NULL, *prev_sibling = NULL;
        struct device_node *dp;
 
-       dp = create_node(node, parent);
-       if (dp) {
+       while (1) {
+               dp = create_node(node, parent);
+               if (!dp)
+                       break;
+
+               if (prev_sibling)
+                       prev_sibling->sibling = dp;
+
+               if (!ret)
+                       ret = dp;
+               prev_sibling = dp;
+
                *(*nextp) = dp;
                *nextp = &dp->allnext;
 
@@ -1648,10 +1659,10 @@ static struct device_node * __init build_tree(struct device_node *parent, phandl
 
                dp->child = build_tree(dp, prom_getchild(node), nextp);
 
-               dp->sibling = build_tree(parent, prom_getsibling(node), nextp);
+               node = prom_getsibling(node);
        }
 
-       return dp;
+       return ret;
 }
 
 void __init prom_build_devicetree(void)
index da73205e54cded364297a9df504316229e7f7c6c..0985193dc57d1ce9aefbb548b0fb527d88343485 100644 (file)
@@ -92,6 +92,8 @@ struct uart_sunzilog_port {
 #define SUNZILOG_FLAG_REGS_HELD                0x00000040
 #define SUNZILOG_FLAG_TX_STOPPED       0x00000080
 #define SUNZILOG_FLAG_TX_ACTIVE                0x00000100
+#define SUNZILOG_FLAG_ESCC             0x00000200
+#define SUNZILOG_FLAG_ISR_HANDLER      0x00000400
 
        unsigned int cflag;
 
@@ -174,9 +176,11 @@ static void sunzilog_clear_fifo(struct zilog_channel __iomem *channel)
 /* This function must only be called when the TX is not busy.  The UART
  * port lock must be held and local interrupts disabled.
  */
-static void __load_zsregs(struct zilog_channel __iomem *channel, unsigned char *regs)
+static int __load_zsregs(struct zilog_channel __iomem *channel, unsigned char *regs)
 {
        int i;
+       int escc;
+       unsigned char r15;
 
        /* Let pending transmits finish.  */
        for (i = 0; i < 1000; i++) {
@@ -229,11 +233,25 @@ static void __load_zsregs(struct zilog_channel __iomem *channel, unsigned char *
        write_zsreg(channel, R14, regs[R14]);
 
        /* External status interrupt control.  */
-       write_zsreg(channel, R15, regs[R15]);
+       write_zsreg(channel, R15, (regs[R15] | WR7pEN) & ~FIFOEN);
+
+       /* ESCC Extension Register */
+       r15 = read_zsreg(channel, R15);
+       if (r15 & 0x01) {
+               write_zsreg(channel, R7,  regs[R7p]);
+
+               /* External status interrupt and FIFO control.  */
+               write_zsreg(channel, R15, regs[R15] & ~WR7pEN);
+               escc = 1;
+       } else {
+                /* Clear FIFO bit case it is an issue */
+               regs[R15] &= ~FIFOEN;
+               escc = 0;
+       }
 
        /* Reset external status interrupts.  */
-       write_zsreg(channel, R0, RES_EXT_INT);
-       write_zsreg(channel, R0, RES_EXT_INT);
+       write_zsreg(channel, R0, RES_EXT_INT); /* First Latch  */
+       write_zsreg(channel, R0, RES_EXT_INT); /* Second Latch */
 
        /* Rewrite R3/R5, this time without enables masked.  */
        write_zsreg(channel, R3, regs[R3]);
@@ -241,6 +259,8 @@ static void __load_zsregs(struct zilog_channel __iomem *channel, unsigned char *
 
        /* Rewrite R1, this time without IRQ enabled masked.  */
        write_zsreg(channel, R1, regs[R1]);
+
+       return escc;
 }
 
 /* Reprogram the Zilog channel HW registers with the copies found in the
@@ -731,7 +751,7 @@ static void sunzilog_enable_ms(struct uart_port *port)
                up->curregs[R15] = new_reg;
 
                /* NOTE: Not subject to 'transmitter active' rule.  */ 
-               write_zsreg(channel, R15, up->curregs[R15]);
+               write_zsreg(channel, R15, up->curregs[R15] & ~WR7pEN);
        }
 }
 
@@ -861,44 +881,44 @@ sunzilog_convert_to_zs(struct uart_sunzilog_port *up, unsigned int cflag,
        up->curregs[R14] = BRSRC | BRENAB;
 
        /* Character size, stop bits, and parity. */
-       up->curregs[3] &= ~RxN_MASK;
-       up->curregs[5] &= ~TxN_MASK;
+       up->curregs[R3] &= ~RxN_MASK;
+       up->curregs[R5] &= ~TxN_MASK;
        switch (cflag & CSIZE) {
        case CS5:
-               up->curregs[3] |= Rx5;
-               up->curregs[5] |= Tx5;
+               up->curregs[R3] |= Rx5;
+               up->curregs[R5] |= Tx5;
                up->parity_mask = 0x1f;
                break;
        case CS6:
-               up->curregs[3] |= Rx6;
-               up->curregs[5] |= Tx6;
+               up->curregs[R3] |= Rx6;
+               up->curregs[R5] |= Tx6;
                up->parity_mask = 0x3f;
                break;
        case CS7:
-               up->curregs[3] |= Rx7;
-               up->curregs[5] |= Tx7;
+               up->curregs[R3] |= Rx7;
+               up->curregs[R5] |= Tx7;
                up->parity_mask = 0x7f;
                break;
        case CS8:
        default:
-               up->curregs[3] |= Rx8;
-               up->curregs[5] |= Tx8;
+               up->curregs[R3] |= Rx8;
+               up->curregs[R5] |= Tx8;
                up->parity_mask = 0xff;
                break;
        };
-       up->curregs[4] &= ~0x0c;
+       up->curregs[R4] &= ~0x0c;
        if (cflag & CSTOPB)
-               up->curregs[4] |= SB2;
+               up->curregs[R4] |= SB2;
        else
-               up->curregs[4] |= SB1;
+               up->curregs[R4] |= SB1;
        if (cflag & PARENB)
-               up->curregs[4] |= PAR_ENAB;
+               up->curregs[R4] |= PAR_ENAB;
        else
-               up->curregs[4] &= ~PAR_ENAB;
+               up->curregs[R4] &= ~PAR_ENAB;
        if (!(cflag & PARODD))
-               up->curregs[4] |= PAR_EVEN;
+               up->curregs[R4] |= PAR_EVEN;
        else
-               up->curregs[4] &= ~PAR_EVEN;
+               up->curregs[R4] &= ~PAR_EVEN;
 
        up->port.read_status_mask = Rx_OVR;
        if (iflag & INPCK)
@@ -952,7 +972,9 @@ sunzilog_set_termios(struct uart_port *port, struct ktermios *termios,
 
 static const char *sunzilog_type(struct uart_port *port)
 {
-       return "zs";
+       struct uart_sunzilog_port *up = UART_ZILOG(port);
+
+       return (up->flags & SUNZILOG_FLAG_ESCC) ? "zs (ESCC)" : "zs";
 }
 
 /* We do not request/release mappings of the registers here, this
@@ -1170,7 +1192,7 @@ static int __init sunzilog_console_setup(struct console *con, char *options)
 
        spin_lock_irqsave(&up->port.lock, flags);
 
-       up->curregs[R15] = BRKIE;
+       up->curregs[R15] |= BRKIE;
        sunzilog_convert_to_zs(up, con->cflag, 0, brg);
 
        sunzilog_set_mctrl(&up->port, TIOCM_DTR | TIOCM_RTS);
@@ -1229,7 +1251,7 @@ static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channe
                baud = 4800;
        }
 
-       up->curregs[R15] = BRKIE;
+       up->curregs[R15] |= BRKIE;
        brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR);
        sunzilog_convert_to_zs(up, up->cflag, 0, brg);
        sunzilog_set_mctrl(&up->port, TIOCM_DTR | TIOCM_RTS);
@@ -1283,8 +1305,18 @@ static void __devinit sunzilog_init_hw(struct uart_sunzilog_port *up)
 
        if (up->flags & (SUNZILOG_FLAG_CONS_KEYB |
                         SUNZILOG_FLAG_CONS_MOUSE)) {
+               up->curregs[R1] = EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB;
+               up->curregs[R4] = PAR_EVEN | X16CLK | SB1;
+               up->curregs[R3] = RxENAB | Rx8;
+               up->curregs[R5] = TxENAB | Tx8;
+               up->curregs[R6] = 0x00; /* SDLC Address */
+               up->curregs[R7] = 0x7E; /* SDLC Flag    */
+               up->curregs[R9] = NV;
+               up->curregs[R7p] = 0x00;
                sunzilog_init_kbdms(up, up->port.line);
-               up->curregs[R9] |= (NV | MIE);
+               /* Only enable interrupts if an ISR handler available */
+               if (up->flags & SUNZILOG_FLAG_ISR_HANDLER)
+                       up->curregs[R9] |= MIE;
                write_zsreg(channel, R9, up->curregs[R9]);
        } else {
                /* Normal serial TTY. */
@@ -1293,7 +1325,9 @@ static void __devinit sunzilog_init_hw(struct uart_sunzilog_port *up)
                up->curregs[R4] = PAR_EVEN | X16CLK | SB1;
                up->curregs[R3] = RxENAB | Rx8;
                up->curregs[R5] = TxENAB | Tx8;
-               up->curregs[R9] = NV | MIE;
+               up->curregs[R6] = 0x00; /* SDLC Address */
+               up->curregs[R7] = 0x7E; /* SDLC Flag    */
+               up->curregs[R9] = NV;
                up->curregs[R10] = NRZ;
                up->curregs[R11] = TCBR | RCBR;
                baud = 9600;
@@ -1301,7 +1335,14 @@ static void __devinit sunzilog_init_hw(struct uart_sunzilog_port *up)
                up->curregs[R12] = (brg & 0xff);
                up->curregs[R13] = (brg >> 8) & 0xff;
                up->curregs[R14] = BRSRC | BRENAB;
-               __load_zsregs(channel, up->curregs);
+               up->curregs[R15] = FIFOEN; /* Use FIFO if on ESCC */
+               up->curregs[R7p] = TxFIFO_LVL | RxFIFO_LVL;
+               if (__load_zsregs(channel, up->curregs)) {
+                       up->flags |= SUNZILOG_FLAG_ESCC;
+               }
+               /* Only enable interrupts if an ISR handler available */
+               if (up->flags & SUNZILOG_FLAG_ISR_HANDLER)
+                       up->curregs[R9] |= MIE;
                write_zsreg(channel, R9, up->curregs[R9]);
        }
 
@@ -1390,12 +1431,14 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
                        return err;
                }
        } else {
-               printk(KERN_INFO "%s: Keyboard at MMIO %lx (irq = %d) "
-                      "is a zs\n",
-                      op->dev.bus_id, up[0].port.mapbase, op->irqs[0]);
-               printk(KERN_INFO "%s: Mouse at MMIO %lx (irq = %d) "
-                      "is a zs\n",
-                      op->dev.bus_id, up[1].port.mapbase, op->irqs[0]);
+               printk(KERN_INFO "%s: Keyboard at MMIO 0x%lx (irq = %d) "
+                      "is a %s\n",
+                      op->dev.bus_id, up[0].port.mapbase, op->irqs[0],
+                      sunzilog_type (&up[0].port));
+               printk(KERN_INFO "%s: Mouse at MMIO 0x%lx (irq = %d) "
+                      "is a %s\n",
+                      op->dev.bus_id, up[1].port.mapbase, op->irqs[0],
+                      sunzilog_type (&up[1].port));
        }
 
        dev_set_drvdata(&op->dev, &up[0]);
@@ -1487,10 +1530,23 @@ static int __init sunzilog_init(void)
                goto out_unregister_uart;
 
        if (zilog_irq != -1) {
+               struct uart_sunzilog_port *up = sunzilog_irq_chain;
                err = request_irq(zilog_irq, sunzilog_interrupt, IRQF_SHARED,
                                  "zs", sunzilog_irq_chain);
                if (err)
                        goto out_unregister_driver;
+
+               /* Enable Interrupts */
+               while (up) {
+                       struct zilog_channel __iomem *channel;
+
+                       /* printk (KERN_INFO "Enable IRQ for ZILOG Hardware %p\n", up); */
+                       channel          = ZILOG_CHANNEL_FROM_PORT(&up->port);
+                       up->flags       |= SUNZILOG_FLAG_ISR_HANDLER;
+                       up->curregs[R9] |= MIE;
+                       write_zsreg(channel, R9, up->curregs[R9]);
+                       up = up->next;
+               }
        }
 
 out:
@@ -1515,6 +1571,20 @@ static void __exit sunzilog_exit(void)
        of_unregister_driver(&zs_driver);
 
        if (zilog_irq != -1) {
+               struct uart_sunzilog_port *up = sunzilog_irq_chain;
+
+               /* Disable Interrupts */
+               while (up) {
+                       struct zilog_channel __iomem *channel;
+
+                       /* printk (KERN_INFO "Disable IRQ for ZILOG Hardware %p\n", up); */
+                       channel          = ZILOG_CHANNEL_FROM_PORT(&up->port);
+                       up->flags       &= ~SUNZILOG_FLAG_ISR_HANDLER;
+                       up->curregs[R9] &= ~MIE;
+                       write_zsreg(channel, R9, up->curregs[R9]);
+                       up = up->next;
+               }
+
                free_irq(zilog_irq, sunzilog_irq_chain);
                zilog_irq = -1;
        }
index 7939b6d712706d9e20df1aed03ac4e6796e59a25..5dec7b47cc3845ee2fbbe53fe7be1334d14aff8c 100644 (file)
@@ -13,7 +13,8 @@ struct zilog_layout {
        struct zilog_channel channelA;
 };
 
-#define NUM_ZSREGS    16
+#define        NUM_ZSREGS      17
+#define        R7p             16 /* Written as R7 with P15 bit 0 set */
 
 /* Conversion routines to/from brg time constants from/to bits
  * per second.
@@ -127,6 +128,15 @@ struct zilog_layout {
 
 /* Write Register 7 (Sync bits 8-15/SDLC 01111110) */
 
+/* Write Register 7' (ESCC Only) */
+#define        AUTO_TxFLAG     1       /* Automatic Tx SDLC Flag */
+#define        AUTO_EOM_RST    2       /* Automatic EOM Reset */
+#define        AUTOnRTS        4       /* Automatic /RTS pin deactivation */
+#define        RxFIFO_LVL      8       /* Receive FIFO interrupt level */
+#define        nDTRnREQ        0x10    /* /DTR/REQ timing */
+#define        TxFIFO_LVL      0x20    /* Transmit FIFO interrupt level */
+#define        EXT_RD_EN       0x40    /* Extended read register enable */
+
 /* Write Register 8 (transmit buffer) */
 
 /* Write Register 9 (Master interrupt control) */
@@ -135,6 +145,7 @@ struct zilog_layout {
 #define        DLC     4       /* Disable Lower Chain */
 #define        MIE     8       /* Master Interrupt Enable */
 #define        STATHI  0x10    /* Status high */
+#define        SWIACK  0x20    /* Software Interrupt Ack (not on NMOS) */
 #define        NORESET 0       /* No reset on write to R9 */
 #define        CHRB    0x40    /* Reset channel B */
 #define        CHRA    0x80    /* Reset channel A */
@@ -187,7 +198,9 @@ struct zilog_layout {
 #define        SNRZI   0xe0    /* Set NRZI mode */
 
 /* Write Register 15 (external/status interrupt control) */
+#define        WR7pEN  1       /* WR7' Enable (ESCC only) */
 #define        ZCIE    2       /* Zero count IE */
+#define        FIFOEN  4       /* FIFO Enable (ESCC only) */
 #define        DCDIE   8       /* DCD IE */
 #define        SYNCIE  0x10    /* Sync/hunt IE */
 #define        CTSIE   0x20    /* CTS IE */
@@ -241,6 +254,10 @@ struct zilog_layout {
 #define        CHATxIP 0x10            /* Channel A Tx IP */
 #define        CHARxIP 0x20            /* Channel A Rx IP */
 
+/* Read Register 6 (LSB frame byte count [Not on NMOS]) */
+
+/* Read Register 7 (MSB frame byte count and FIFO status [Not on NMOS]) */
+
 /* Read Register 8 (receive data register) */
 
 /* Read Register 10  (misc status bits) */
index e01b80559c93f164c8ec056aa624bffae6104038..26ec046715c86c3bee6e5911336e5ac858349d31 100644 (file)
@@ -177,7 +177,7 @@ struct linux_nodeops {
 /* More fun PROM structures for device probing. */
 #define PROMREG_MAX     24
 #define PROMVADDR_MAX   16
-#define PROMINTR_MAX    15
+#define PROMINTR_MAX    32
 
 struct linux_prom_registers {
        unsigned which_io;      /* hi part of physical address                  */