Commit d925eab6 authored by Matthew Wilcox's avatar Matthew Wilcox Committed by David S. Miller

[PATCH] PA-RISC driver update for 2.6.2

PA-RISC specific driver updates:

 - Stop pasting __FILE__
 - Improve card-mode Dino support (James Bottomley)
 - Fix dev->bridge rename (James Bottomley)
 - iosapic/SBA/LBA cleanups (Grant Grundler)
 - Improve LED support (Helge Deller)
 - Fix mux driver (Ryan Bradetich)
 - Make STI framebuffer work on RDI PrecisionBook (Helge Deller)
parent 537c1ab3
......@@ -106,6 +106,9 @@ config IOMMU_SBA
#config PCI_EPIC
# bool "EPIC/SAGA PCI support"
# depends on PCI
# default y
# help
# Say Y here for V-class PCI, DMA/IOMMU, IRQ subsystem support.
config SUPERIO
bool "SuperIO (SuckyIO) support"
......
......@@ -364,11 +364,11 @@ ccio_alloc_range(struct ioc *ioc, unsigned long pages_needed)
CCIO_FIND_FREE_MAPPING(ioc, res_idx, mask, 64);
#endif
} else {
panic(__FILE__ ": %s() Too many pages to map. pages_needed: %ld\n",
__FUNCTION__, pages_needed);
panic("%s: %s() Too many pages to map. pages_needed: %ld\n",
__FILE__, __FUNCTION__, pages_needed);
}
panic(__FILE__ ": %s() I/O MMU is out of mapping resources.\n",
panic("%s: %s() I/O MMU is out of mapping resources.\n", __FILE__,
__FUNCTION__);
resource_found:
......@@ -441,7 +441,7 @@ ccio_free_range(struct ioc *ioc, dma_addr_t iova, unsigned long pages_mapped)
CCIO_FREE_MAPPINGS(ioc, res_idx, mask, 64);
#endif
} else {
panic(__FILE__ ":%s() Too many pages to unmap.\n",
panic("%s:%s() Too many pages to unmap.\n", __FILE__,
__FUNCTION__);
}
}
......@@ -1447,7 +1447,8 @@ ccio_ioc_init(struct ioc *ioc)
ioc->pdir_base = (u64 *)__get_free_pages(GFP_KERNEL,
get_order(ioc->pdir_size));
if(NULL == ioc->pdir_base) {
panic(__FILE__ ":%s() could not allocate I/O Page Table\n", __FUNCTION__);
panic("%s:%s() could not allocate I/O Page Table\n", __FILE__,
__FUNCTION__);
}
memset(ioc->pdir_base, 0, ioc->pdir_size);
......@@ -1461,7 +1462,8 @@ ccio_ioc_init(struct ioc *ioc)
ioc->res_map = (u8 *)__get_free_pages(GFP_KERNEL,
get_order(ioc->res_size));
if(NULL == ioc->res_map) {
panic(__FILE__ ":%s() could not allocate resource map\n", __FUNCTION__);
panic("%s:%s() could not allocate resource map\n", __FILE__,
__FUNCTION__);
}
memset(ioc->res_map, 0, ioc->res_size);
......@@ -1627,11 +1629,11 @@ int ccio_request_resource(const struct parisc_device *dev,
if (!ioc) {
parent = &iomem_resource;
} else if ((ioc->mmio_region->start <= dev->hpa) &&
(dev->hpa < ioc->mmio_region->end)) {
} else if ((ioc->mmio_region->start <= res->start) &&
(res->end <= ioc->mmio_region->end)) {
parent = ioc->mmio_region;
} else if (((ioc->mmio_region + 1)->start <= dev->hpa) &&
(dev->hpa < (ioc->mmio_region + 1)->end)) {
} else if (((ioc->mmio_region + 1)->start <= res->start) &&
(res->end <= (ioc->mmio_region + 1)->end)) {
parent = ioc->mmio_region + 1;
} else {
return -EBUSY;
......
......@@ -175,7 +175,7 @@ static int dino_current_bus = 0;
static int dino_cfg_read(struct pci_bus *bus, unsigned int devfn, int where,
int size, u32 *val)
{
struct dino_device *d = DINO_DEV(parisc_walk_tree(bus->dev));
struct dino_device *d = DINO_DEV(parisc_walk_tree(bus->bridge));
u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
u32 v = DINO_CFG_TOK(local_bus, devfn, where & ~3);
unsigned long base_addr = d->hba.base_addr;
......@@ -209,7 +209,7 @@ static int dino_cfg_read(struct pci_bus *bus, unsigned int devfn, int where,
static int dino_cfg_write(struct pci_bus *bus, unsigned int devfn, int where,
int size, u32 val)
{
struct dino_device *d = DINO_DEV(parisc_walk_tree(bus->dev));
struct dino_device *d = DINO_DEV(parisc_walk_tree(bus->bridge));
u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
u32 v = DINO_CFG_TOK(local_bus, devfn, where & ~3);
unsigned long base_addr = d->hba.base_addr;
......@@ -468,14 +468,14 @@ static void __init
dino_card_setup(struct pci_bus *bus, unsigned long base_addr)
{
int i;
struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->dev));
struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->bridge));
struct resource *res;
char name[128];
int size;
res = &dino_dev->hba.lmmio_space;
res->flags = IORESOURCE_MEM;
size = snprintf(name, sizeof(name), "Dino LMMIO (%s)", bus->dev->bus_id);
size = snprintf(name, sizeof(name), "Dino LMMIO (%s)", bus->bridge->bus_id);
res->name = kmalloc(size+1, GFP_KERNEL);
if(res->name)
strcpy((char *)res->name, name);
......@@ -489,7 +489,7 @@ dino_card_setup(struct pci_bus *bus, unsigned long base_addr)
struct list_head *ln, *tmp_ln;
printk(KERN_ERR "Dino: cannot attach bus %s\n",
bus->dev->bus_id);
bus->bridge->bus_id);
/* kill the bus, we can't do anything with it */
list_for_each_safe(ln, tmp_ln, &bus->devices) {
struct pci_dev *dev = pci_dev_b(ln);
......@@ -560,11 +560,11 @@ dino_fixup_bus(struct pci_bus *bus)
{
struct list_head *ln;
struct pci_dev *dev;
struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->dev));
struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->bridge));
int port_base = HBA_PORT_BASE(dino_dev->hba.hba_num);
DBG(KERN_WARNING "%s(0x%p) bus %d sysdata 0x%p\n",
__FUNCTION__, bus, bus->secondary, bus->dev->platform_data);
__FUNCTION__, bus, bus->secondary, bus->bridge->platform_data);
/* Firmware doesn't set up card-mode dino, so we have to */
if (is_card_dino(&dino_dev->hba.dev->id)) {
......@@ -572,15 +572,23 @@ dino_fixup_bus(struct pci_bus *bus)
} else if(bus->parent == NULL) {
/* must have a dino above it, reparent the resources
* into the dino window */
int i;
struct resource *res = &dino_dev->hba.lmmio_space;
bus->resource[0] = &(dino_dev->hba.io_space);
bus->resource[1] = &(dino_dev->hba.lmmio_space);
for(i = 0; i < DINO_MAX_LMMIO_RESOURCES; i++) {
if(res[i].flags == 0)
break;
bus->resource[i+1] = &res[i];
}
} else if(bus->self) {
int i;
pci_read_bridge_bases(bus);
for(i = 0; i < PCI_NUM_RESOURCES; i++) {
for(i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) {
if((bus->self->resource[i].flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
continue;
......@@ -642,11 +650,10 @@ dino_fixup_bus(struct pci_bus *bus)
* care about an expansion rom on parisc, since it
* usually contains (x86) bios code) */
dev->resource[PCI_ROM_RESOURCE].flags = 0;
dev->resource[PCI_ROM_RESOURCE].start = 0;
dev->resource[PCI_ROM_RESOURCE].end = 0;
if(dev->irq == 255) {
#define DINO_FIX_UNASSIGNED_INTERRUPTS
#ifdef DINO_FIX_UNASSIGNED_INTERRUPTS
/* This code tries to assign an unassigned
......@@ -660,7 +667,7 @@ dino_fixup_bus(struct pci_bus *bus)
dino_cfg_read(dev->bus, dev->devfn, PCI_INTERRUPT_PIN, 1, &irq_pin);
dev->irq = (irq_pin + PCI_SLOT(dev->devfn) - 1) % 4 ;
dino_cfg_write(dev->bus, dev->devfn, PCI_INTERRUPT_LINE, 1, dev->irq);
dev->irq += dino_dev->dino_region->data.irqbase
dev->irq += dino_dev->dino_region->data.irqbase;
printk(KERN_WARNING "Device %s has undefined IRQ, setting to %d\n", dev->slot_name, irq_pin);
#else
dev->irq = 65535;
......@@ -741,9 +748,9 @@ dino_card_init(struct dino_device *dino_dev)
static int __init
dino_bridge_init(struct dino_device *dino_dev, const char *name)
{
unsigned long io_addr, bpos;
int result;
struct resource *res;
unsigned long io_addr;
int result, i, count=0;
struct resource *res, *prevres = NULL;
/*
* Decoding IO_ADDR_EN only works for Built-in Dino
* since PDC has already initialized this.
......@@ -755,21 +762,51 @@ dino_bridge_init(struct dino_device *dino_dev, const char *name)
return -ENODEV;
}
for (bpos = 0; (io_addr & (1 << bpos)) == 0; bpos++)
;
res = &dino_dev->hba.lmmio_space;
res->flags = IORESOURCE_MEM;
for (i = 0; i < 32; i++) {
unsigned long start, end;
if((io_addr & (1 << i)) == 0)
continue;
res->start = (unsigned long)(signed int)(0xf0000000 | (bpos << 23));
res->end = res->start + 8 * 1024 * 1024 - 1;
start = (unsigned long)(signed int)(0xf0000000 | (i << 23));
end = start + 8 * 1024 * 1024 - 1;
result = ccio_request_resource(dino_dev->hba.dev, res);
if (result < 0) {
printk(KERN_ERR "%s: failed to claim PCI Bus address space!\n", name);
return result;
DBG("DINO RANGE %d is at 0x%lx-0x%lx\n", count,
start, end);
if(prevres && prevres->end + 1 == start) {
prevres->end = end;
} else {
if(count >= DINO_MAX_LMMIO_RESOURCES) {
printk(KERN_ERR "%s is out of resource windows for range %d (0x%lx-0x%lx)\n", name, count, start, end);
break;
}
prevres = res;
res->start = start;
res->end = end;
res->flags = IORESOURCE_MEM;
res->name = kmalloc(64, GFP_KERNEL);
if(res->name)
snprintf((char *)res->name, 64, "%s LMMIO %d",
name, count);
res++;
count++;
}
}
res = &dino_dev->hba.lmmio_space;
for(i = 0; i < DINO_MAX_LMMIO_RESOURCES; i++) {
if(res[i].flags == 0)
break;
result = ccio_request_resource(dino_dev->hba.dev, &res[i]);
if (result < 0) {
printk(KERN_ERR "%s: failed to claim PCI Bus address space %d (0x%lx-0x%lx)!\n", name, i, res[i].start, res[i].end);
return result;
}
}
return 0;
}
......@@ -850,10 +887,8 @@ static int __init dino_common_init(struct parisc_device *dev,
res = &dino_dev->hba.io_space;
if (dev->id.hversion == 0x680 || is_card_dino(&dev->id)) {
res->name = "Dino I/O Port";
dino_dev->hba.lmmio_space.name = "Dino LMMIO";
} else {
res->name = "Cujo I/O Port";
dino_dev->hba.lmmio_space.name = "Cujo LMMIO";
}
res->start = HBA_PORT_BASE(dino_dev->hba.hba_num);
res->end = res->start + (HBA_PORT_SPACE_SIZE - 1);
......
/*
* EISA "eeprom" support routines
*
* Copyright (C) 2001 Thomas Bogendoerfer <tsbogend at parisc-linux.org>
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
......
This diff is collapsed.
/*
* Private structs/constants for PARISC IOSAPIC support
*
* Copyright (C) 2000 Hewlett Packard (Grant Grundler)
* Copyright (C) 2000,2003 Grant Grundler (grundler at parisc-linux.org)
* Copyright (C) 2002 Matthew Wilcox (willy at parisc-linux.org)
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
** This file is private to iosapic driver.
** If stuff needs to be used by another driver, move it to a common file.
......@@ -107,16 +130,16 @@ struct iosapic_irt {
#endif
struct vector_info {
struct iosapic_info *vi_ios; /* I/O SAPIC this vector is on */
struct irt_entry *vi_irte; /* IRT entry */
u32 *vi_eoi_addr; /* precalculate EOI reg address */
u32 vi_eoi_data; /* IA64: ? PA: swapped txn_data */
int vi_txn_irq; /* virtual IRQ number for processor */
ulong vi_txn_addr; /* IA64: id_eid PA: partial HPA */
ulong vi_txn_data; /* IA64: vector PA: EIR bit */
u8 vi_status; /* status/flags */
u8 vi_irqline; /* INTINn(IRQ) */
char vi_name[32]; /* user visible identity */
struct iosapic_info *iosapic; /* I/O SAPIC this vector is on */
struct irt_entry *irte; /* IRT entry */
u32 *eoi_addr; /* precalculate EOI reg address */
u32 eoi_data; /* IA64: ? PA: swapped txn_data */
int txn_irq; /* virtual IRQ number for processor */
ulong txn_addr; /* IA64: id_eid PA: partial HPA */
ulong txn_data; /* IA64: vector PA: EIR bit */
u8 status; /* status/flags */
u8 irqline; /* INTINn(IRQ) */
char name[32]; /* user visible identity */
};
......
......@@ -185,8 +185,6 @@ struct lba_device {
void *iosapic_obj;
#ifdef __LP64__
unsigned long lmmio_base; /* PA_VIEW - fixup MEM addresses */
unsigned long gmmio_base; /* PA_VIEW - Not used (yet) */
unsigned long iop_base; /* PA_VIEW - for IO port accessor funcs */
#endif
......@@ -508,7 +506,7 @@ lba_rd_cfg(struct lba_device *d, u32 tok, u8 reg, u32 size)
static int lba_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 *data)
{
struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->dev));
struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->bridge));
u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
u32 tok = LBA_CFG_TOK(local_bus, devfn);
......@@ -518,7 +516,7 @@ static int lba_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int si
with risk we will miss PCI bus errors. */
*data = lba_rd_cfg(d, tok, pos, size);
DBG_CFG("%s(%x+%2x) -> 0x%x (a)\n", __FUNCTION__, tok, pos, *data);
return(*data == ~0UL);
return(*data == ~0U);
}
if (LBA_SKIP_PROBE(d) && (!lba_device_present(bus->secondary, devfn, d)))
......@@ -592,7 +590,7 @@ lba_wr_cfg( struct lba_device *d, u32 tok, u8 reg, u32 data, u32 size)
static int lba_cfg_write(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 data)
{
struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->dev));
struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->bridge));
u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
u32 tok = LBA_CFG_TOK(local_bus,devfn);
......@@ -695,20 +693,23 @@ lba_fixup_bus(struct pci_bus *bus)
{
struct list_head *ln;
#ifdef FBB_SUPPORT
u16 fbb_enable = PCI_STATUS_FAST_BACK;
u16 status;
#endif
struct lba_device *ldev = LBA_DEV(parisc_walk_tree(bus->dev));
struct lba_device *ldev = LBA_DEV(parisc_walk_tree(bus->bridge));
int lba_portbase = HBA_PORT_BASE(ldev->hba.hba_num);
DBG("lba_fixup_bus(0x%p) bus %d sysdata 0x%p\n",
bus, bus->secondary, bus->dev->platform_data);
bus, bus->secondary, bus->bridge->platform_data);
/*
** Properly Setup MMIO resources for this bus.
** pci_alloc_primary_bus() mangles this.
*/
if (NULL == bus->self) {
if (bus->self) {
/* PCI-PCI Bridge */
pci_read_bridge_bases(bus);
} else {
/* Host-PCI Bridge */
int err;
DBG("lba_fixup_bus() %s [%lx/%lx]/%x\n",
......@@ -725,59 +726,29 @@ lba_fixup_bus(struct pci_bus *bus)
BUG();
lba_dump_res(&ioport_resource, 2);
}
err = request_resource(&iomem_resource, &(ldev->hba.lmmio_space));
if (err < 0) {
BUG();
lba_dump_res(&iomem_resource, 2);
}
bus->resource[0] = &(ldev->hba.io_space);
bus->resource[1] = &(ldev->hba.lmmio_space);
} else {
/* KLUGE ALERT!
** PCI-PCI Bridge resource munging.
** This hack should go away in the near future.
** It's based on the Alpha port.
*/
int i;
u16 cmd;
for (i = 0; i < 4; i++) {
bus->resource[i] =
&bus->self->resource[PCI_BRIDGE_RESOURCES+i];
bus->resource[i]->name = bus->name;
#ifdef __LP64__
if (ldev->hba.gmmio_space.flags) {
err = request_resource(&iomem_resource, &(ldev->hba.gmmio_space));
if (err < 0) {
BUG();
lba_dump_res(&iomem_resource, 2);
}
bus->resource[2] = &(ldev->hba.gmmio_space);
}
#if 0
bus->resource[0]->flags |= pci_bridge_check_io(bus->self);
#else
bus->resource[0]->flags |= IORESOURCE_IO;
#endif
bus->resource[1]->flags |= IORESOURCE_MEM;
bus->resource[2]->flags = 0; /* Don't support prefetchable */
bus->resource[3]->flags = 0; /* not used */
/*
** If the PPB is enabled (ie already configured) then
** just read those values.
*/
(void) pci_read_config_word(bus->self, PCI_COMMAND, &cmd);
if (cmd & (PCI_COMMAND_MEMORY | PCI_COMMAND_IO)) {
pci_read_bridge_bases(bus);
} else {
/* Not configured.
** For now, propagate HBA limits to the bus;
** PCI will adjust them later.
*/
bus->resource[0]->end = ldev->hba.io_space.end;
bus->resource[1]->end = ldev->hba.lmmio_space.end;
}
/* Turn off downstream PF memory address range by default */
bus->resource[2]->start = 1024*1024;
bus->resource[2]->end = bus->resource[2]->start - 1;
/* advertize Host bridge resources to PCI bus */
bus->resource[0] = &(ldev->hba.io_space);
bus->resource[1] = &(ldev->hba.lmmio_space);
}
list_for_each(ln, &bus->devices) {
int i;
struct pci_dev *dev = pci_dev_b(ln);
......@@ -785,7 +756,7 @@ lba_fixup_bus(struct pci_bus *bus)
DBG("lba_fixup_bus() %s\n", pci_name(dev));
/* Virtualize Device/Bridge Resources. */
for (i = 0; i < PCI_NUM_RESOURCES; i++) {
for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) {
struct resource *res = &dev->resource[i];
/* If resource not allocated - skip it */
......@@ -817,7 +788,7 @@ lba_fixup_bus(struct pci_bus *bus)
** No one on the bus can be allowed to use them.
*/
(void) pci_read_config_word(dev, PCI_STATUS, &status);
fbb_enable &= status;
bus->bridge_ctl &= ~(status & PCI_STATUS_FAST_BACK);
#endif
#ifdef __LP64__
......@@ -1069,6 +1040,7 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
lba_dev->hba.bus_num.start = p->start;
lba_dev->hba.bus_num.end = p->end;
break;
case PAT_LMMIO:
/* used to fix up pre-initialized MEM BARs */
lba_dev->hba.lmmio_space_offset = p->start - io->start;
......@@ -1080,23 +1052,28 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
r->flags = IORESOURCE_MEM;
r->parent = r->sibling = r->child = NULL;
break;
case PAT_GMMIO:
printk(KERN_WARNING MODULE_NAME
" range[%d] : ignoring GMMIO (0x%lx)\n",
i, p->start);
lba_dev->gmmio_base = p->start;
/* MMIO space > 4GB phys addr; for 64-bit BAR */
r = &(lba_dev->hba.gmmio_space);
r->name = "LBA GMMIO";
r->start = p->start;
r->end = p->end;
r->flags = IORESOURCE_MEM;
r->parent = r->sibling = r->child = NULL;
break;
case PAT_NPIOP:
printk(KERN_WARNING MODULE_NAME
" range[%d] : ignoring NPIOP (0x%lx)\n",
i, p->start);
break;
case PAT_PIOP:
/*
** Postable I/O port space is per PCI host adapter.
** base of 64MB PIOP region
*/
/* save base of 64MB PIOP region */
lba_dev->iop_base = p->start;
r = &(lba_dev->hba.io_space);
......@@ -1106,6 +1083,7 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
r->flags = IORESOURCE_IO;
r->parent = r->sibling = r->child = NULL;
break;
default:
printk(KERN_WARNING MODULE_NAME
" range[%d] : unknown pat range type (0x%lx)\n",
......@@ -1259,7 +1237,11 @@ lba_hw_init(struct lba_device *d)
#endif /* DEBUG_LBA_PAT */
#ifdef __LP64__
#warning FIXME add support for PDC_PAT_IO "Get slot status" - OLAR support
/*
* FIXME add support for PDC_PAT_IO "Get slot status" - OLAR support
* Only N-Class and up can really make use of Get slot status.
* maybe L-class too but I've never played with it there.
*/
#endif
/* PDC_PAT_BUG: exhibited in rev 40.48 on L2000 */
......
......@@ -3,7 +3,7 @@
*
* (c) Copyright 2000 Red Hat Software
* (c) Copyright 2000 Helge Deller <hdeller@redhat.com>
* (c) Copyright 2001-2003 Helge Deller <deller@gmx.de>
* (c) Copyright 2001-2004 Helge Deller <deller@gmx.de>
* (c) Copyright 2001 Randolph Chung <tausq@debian.org>
*
* This program is free software; you can redistribute it and/or modify
......@@ -56,6 +56,7 @@ static int led_heartbeat = 1;
static int led_diskio = 1;
static int led_lanrxtx = 1;
static char lcd_text[32];
static char lcd_text_default[] = "Linux " UTS_RELEASE;
#if 0
#define DPRINTK(x) printk x
......@@ -196,19 +197,11 @@ static int led_proc_write(struct file *file, const char *buf,
break;
case LED_HASLCD:
while (*cur && cur[strlen(cur)-1] == '\n')
cur[strlen(cur)-1] = 0;
if (*cur == 0)
{
/* reset to default */
lcd_print("Linux " UTS_RELEASE);
}
else
{
/* chop off trailing \n.. if the user gives multiple
* \n then it's all their fault.. */
if (*cur && cur[strlen(cur)-1] == '\n')
cur[strlen(cur)-1] = 0;
lcd_print(cur);
}
cur = lcd_text_default;
lcd_print(cur);
break;
default:
return 0;
......@@ -438,11 +431,7 @@ static __inline__ int led_get_diskio_activity(void)
#define HEARTBEAT_2ND_RANGE_START (HZ*22/100)
#define HEARTBEAT_2ND_RANGE_END (HEARTBEAT_2ND_RANGE_START + HEARTBEAT_LEN)
#if HZ==100
#define NORMALIZED_COUNT(count) (count)
#else
#define NORMALIZED_COUNT(count) (count/(HZ/100))
#endif
#define NORMALIZED_COUNT(count) (count/(HZ/100))
static void led_tasklet_func(unsigned long unused)
{
......@@ -567,7 +556,7 @@ int __init register_led_driver(int model, char *cmd_reg, char *data_reg)
printk(KERN_INFO "LCD display at %p,%p registered\n",
LCD_CMD_REG , LCD_DATA_REG);
led_func_ptr = led_LCD_driver;
lcd_print( "Linux " UTS_RELEASE );
lcd_print( lcd_text_default );
led_type = LED_HASLCD;
break;
......
......@@ -44,6 +44,11 @@
#define MODULE_NAME "SBA"
#ifdef CONFIG_PROC_FS
/* depends on proc fs support. But costs CPU performance */
#undef SBA_COLLECT_STATS
#endif
/*
** The number of debug flags is a clue - this code is fragile.
** Don't even think about messing with it unless you have
......@@ -217,7 +222,7 @@ struct ioc {
} saved[DELAYED_RESOURCE_CNT];
#endif
#ifdef CONFIG_PROC_FS
#ifdef SBA_COLLECT_STATS
#define SBA_SEARCH_SAMPLE 0x100
unsigned long avg_search[SBA_SEARCH_SAMPLE];
unsigned long avg_idx; /* current index into avg_search */
......@@ -560,7 +565,7 @@ static int
sba_alloc_range(struct ioc *ioc, size_t size)
{
unsigned int pages_needed = size >> IOVP_SHIFT;
#ifdef CONFIG_PROC_FS
#ifdef SBA_COLLECT_STATS
unsigned long cr_start = mfctl(16);
#endif
unsigned long pide;
......@@ -579,7 +584,8 @@ sba_alloc_range(struct ioc *ioc, size_t size)
if (pide >= (ioc->res_size << 3)) {
pide = sba_search_bitmap(ioc, pages_needed);
if (pide >= (ioc->res_size << 3))
panic(__FILE__ ": I/O MMU @ %lx is out of mapping resources\n", ioc->ioc_hpa);
panic("%s: I/O MMU @ %lx is out of mapping resources\n",
__FILE__, ioc->ioc_hpa);
}
#ifdef ASSERT_PDIR_SANITY
......@@ -594,7 +600,7 @@ sba_alloc_range(struct ioc *ioc, size_t size)
(uint) ((unsigned long) ioc->res_hint - (unsigned long) ioc->res_map),
ioc->res_bitshift );
#ifdef CONFIG_PROC_FS
#ifdef SBA_COLLECT_STATS
{
unsigned long cr_end = mfctl(16);
unsigned long tmp = cr_end - cr_start;
......@@ -636,7 +642,7 @@ sba_free_range(struct ioc *ioc, dma_addr_t iova, size_t size)
__FUNCTION__, (uint) iova, size,
bits_not_wanted, m, pide, res_ptr, *res_ptr);
#ifdef CONFIG_PROC_FS
#ifdef SBA_COLLECT_STATS
ioc->used_pages -= bits_not_wanted;
#endif
......@@ -854,7 +860,7 @@ sba_map_single(struct device *dev, void *addr, size_t size,
sba_check_pdir(ioc,"Check before sba_map_single()");
#endif
#ifdef CONFIG_PROC_FS
#ifdef SBA_COLLECT_STATS
ioc->msingle_calls++;
ioc->msingle_pages += size >> IOVP_SHIFT;
#endif
......@@ -929,7 +935,7 @@ sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size,
spin_lock_irqsave(&ioc->res_lock, flags);
#ifdef CONFIG_PROC_FS
#ifdef SBA_COLLECT_STATS
ioc->usingle_calls++;
ioc->usingle_pages += size >> IOVP_SHIFT;
#endif
......@@ -1057,7 +1063,7 @@ sba_fill_pdir(
printk(KERN_DEBUG " %2d : %08lx/%05x %p/%05x\n",
nents,
(unsigned long) sg_dma_address(startsg), cnt,
sg_virt_address(startsg), startsg->length
sg_virt_addr(startsg), startsg->length
);
#else
DBG_RUN_SG(" %d : %08lx/%05x %p/%05x\n",
......@@ -1093,7 +1099,7 @@ sba_fill_pdir(
cnt += dma_offset;
dma_offset=0; /* only want offset on first chunk */
cnt = ROUNDUP(cnt, IOVP_SIZE);
#ifdef CONFIG_PROC_FS
#ifdef SBA_COLLECT_STATS
ioc->msg_pages += cnt >> IOVP_SHIFT;
#endif
do {
......@@ -1300,7 +1306,7 @@ sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
}
#endif
#ifdef CONFIG_PROC_FS
#ifdef SBA_COLLECT_STATS
ioc->msg_calls++;
#endif
......@@ -1365,7 +1371,7 @@ sba_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents,
ioc = GET_IOC(dev);
ASSERT(ioc);
#ifdef CONFIG_PROC_FS
#ifdef SBA_COLLECT_STATS
ioc->usg_calls++;
#endif
......@@ -1378,7 +1384,7 @@ sba_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents,
while (sg_dma_len(sglist) && nents--) {
sba_unmap_single(dev, sg_dma_address(sglist), sg_dma_len(sglist), direction);
#ifdef CONFIG_PROC_FS
#ifdef SBA_COLLECT_STATS
ioc->usg_pages += ((sg_dma_address(sglist) & ~IOVP_MASK) + sg_dma_len(sglist) + IOVP_SIZE - 1) >> PAGE_SHIFT;
ioc->usingle_calls--; /* kluge since call is unmap_sg() */
#endif
......@@ -1680,6 +1686,21 @@ sba_hw_init(struct sba_device *sba_dev)
int num_ioc;
u64 ioc_ctl;
if (!is_pdc_pat()) {
/* Shutdown the USB controller on Astro-based workstations.
** Once we reprogram the IOMMU, the next DMA performed by
** USB will HPMC the box.
*/
pdc_io_reset_devices();
/*
** XXX May need something more sophisticated to deal
** with DMA from LAN. Maybe use page zero boot device
** as a handle to talk to PDC about which device to
** shutdown. This also needs to work for is_pdc_pat().
*/
}
ioc_ctl = READ_REG(sba_dev->sba_hpa+IOC_CTRL);
DBG_INIT("%s() hpa 0x%lx ioc_ctl 0x%Lx ->",
__FUNCTION__, sba_dev->sba_hpa, ioc_ctl);
......@@ -1766,7 +1787,8 @@ sba_common_init(struct sba_device *sba_dev)
if (NULL == sba_dev->ioc[i].res_map)
{
panic(__FILE__ ":%s() could not allocate resource map\n", __FUNCTION__ );
panic("%s:%s() could not allocate resource map\n",
__FILE__, __FUNCTION__ );
}
memset(sba_dev->ioc[i].res_map, 0, res_size);
......@@ -1829,7 +1851,9 @@ static int sba_proc_info(char *buf, char **start, off_t offset, int len)
struct sba_device *sba_dev = sba_list;
struct ioc *ioc = &sba_dev->ioc[0]; /* FIXME: Multi-IOC support! */
int total_pages = (int) (ioc->res_size << 3); /* 8 bits per byte */
#ifdef SBA_COLLECT_STATS
unsigned long i = 0, avg = 0, min, max;
#endif
sprintf(buf, "%s rev %d.%d\n",
sba_dev->name,
......@@ -1841,12 +1865,13 @@ static int sba_proc_info(char *buf, char **start, off_t offset, int len)
(int) ((ioc->res_size << 3) * sizeof(u64)), /* 8 bits/byte */
total_pages);
sprintf(buf, "%sResource bitmap : %d bytes (%d pages)\n",
buf, ioc->res_size, ioc->res_size << 3); /* 8 bits per byte */
#ifdef SBA_COLLECT_STATS
sprintf(buf, "%sIO PDIR entries : %ld free %ld used (%d%%)\n", buf,
total_pages - ioc->used_pages, ioc->used_pages,
(int) (ioc->used_pages * 100 / total_pages));
sprintf(buf, "%sResource bitmap : %d bytes (%d pages)\n",
buf, ioc->res_size, ioc->res_size << 3); /* 8 bits per byte */
min = max = ioc->avg_search[0];
for (i = 0; i < SBA_SEARCH_SAMPLE; i++) {
......@@ -1876,6 +1901,7 @@ static int sba_proc_info(char *buf, char **start, off_t offset, int len)
sprintf(buf, "%spci_unmap_sg() : %12ld calls %12ld pages (avg %d/1000)\n",
buf, ioc->usg_calls, ioc->usg_pages,
(int) ((ioc->usg_pages * 1000)/ioc->usg_calls));
#endif
return strlen(buf);
}
......
This diff is collapsed.
......@@ -24,6 +24,7 @@
#include <linux/serial.h>
#include <linux/console.h>
#include <linux/slab.h>
#include <linux/delay.h> /* for udelay */
#include <asm/io.h>
#include <asm/parisc-device.h>
......@@ -47,15 +48,17 @@
#define MUX_STATUS(status) ((status & 0xF000) == 0x8000)
#define MUX_BREAK(status) ((status & 0xF000) == 0x2000)
#define UART_NR 8
struct mux_card {
struct uart_port ports[UART_NR];
struct uart_driver drv;
struct mux_card *next;
};
static struct mux_card mux_card_head = {
.next = NULL,
#define MUX_NR 256
static unsigned int port_cnt = 0;
static struct uart_port mux_ports[MUX_NR];
static struct uart_driver mux_driver = {
.owner = THIS_MODULE,
.driver_name = "ttyB",
.dev_name = "ttyB",
.major = MUX_MAJOR,
.minor = 0,
.nr = MUX_NR,
};
static struct timer_list mux_timer;
......@@ -181,7 +184,7 @@ static void mux_write(struct uart_port *port)
return;
}
count = (port->fifosize >> 1) - UART_GET_FIFO_CNT(port);
count = (port->fifosize) - UART_GET_FIFO_CNT(port);
do {
UART_PUT_CHAR(port, xmit->buf[xmit->tail]);
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
......@@ -191,6 +194,9 @@ static void mux_write(struct uart_port *port)
} while(--count > 0);
while(UART_GET_FIFO_CNT(port))
udelay(1);
if(uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(port);
......@@ -361,28 +367,46 @@ static int mux_verify_port(struct uart_port *port, struct serial_struct *ser)
static void mux_poll(unsigned long unused)
{
int i;
struct mux_card *card = &mux_card_head;
while(card) {
for(i = 0; i < UART_NR; ++i) {
if(!card->ports[i].info)
continue;
for(i = 0; i < port_cnt; ++i) {
if(!mux_ports[i].info)
continue;
mux_read(&card->ports[i]);
mux_write(&card->ports[i]);
}
card = card->next;
mux_read(&mux_ports[i]);
mux_write(&mux_ports[i]);
}
mod_timer(&mux_timer, jiffies + MUX_POLL_DELAY);
}
#ifdef CONFIG_SERIAL_MUX_CONSOLE
static void mux_console_write(struct console *co, const char *s, unsigned count)
{
while(count--)
pdc_iodc_putc(*s++);
}
static int mux_console_setup(struct console *co, char *options)
{
return 0;
}
struct tty_driver *mux_console_device(struct console *co, int *index)
{
*index = co->index;
return mux_driver.tty_driver;
}
static struct console mux_console = {
.name = "ttyB",
.flags = CON_PRINTBUFFER,
.write = mux_console_write,
.device = mux_console_device,
.setup = mux_console_setup,
.flags = CON_BOOT|CON_PRINTBUFFER|CON_ENABLED,
.index = 0,
};
#define MUX_CONSOLE &mux_console
#else
#define MUX_CONSOLE NULL
......@@ -416,77 +440,53 @@ static struct uart_ops mux_pops = {
*/
static int __init mux_probe(struct parisc_device *dev)
{
int i, j, ret, ports, port_cnt = 0;
u8 iodc_data[8];
int i, status, ports;
u8 iodc_data[32];
unsigned long bytecnt;
struct uart_port *port;
struct mux_card *card = &mux_card_head;
ret = pdc_iodc_read(&bytecnt, dev->hpa, 0, iodc_data, 8);
if(ret != PDC_OK) {
status = pdc_iodc_read(&bytecnt, dev->hpa, 0, iodc_data, 32);
if(status != PDC_OK) {
printk(KERN_ERR "Serial mux: Unable to read IODC.\n");
return 1;
}
ports = GET_MUX_PORTS(iodc_data);
printk(KERN_INFO "Serial mux driver (%d ports) Revision: 0.2\n",
ports);
if(!card->drv.nr) {
init_timer(&mux_timer);
mux_timer.function = mux_poll;
} else {
port_cnt += UART_NR;
while(card->next) {
card = card->next;
port_cnt += UART_NR;
}
}
for(i = 0; i < ports / UART_NR; ++i) {
if(card->drv.nr) {
card->next = kmalloc(sizeof(struct mux_card), GFP_KERNEL);
if(!card->next) {
printk(KERN_ERR "Serial mux: Unable to allocate memory.\n");
return 1;
}
memset(card->next, '\0', sizeof(struct mux_card));
card = card->next;
}
printk(KERN_INFO "Serial mux driver (%d ports) Revision: 0.3\n", ports);
card->drv.owner = THIS_MODULE;
card->drv.driver_name = "ttyB";
card->drv.dev_name = "ttyB";
card->drv.major = MUX_MAJOR;
card->drv.minor = port_cnt;
card->drv.nr = UART_NR;
card->drv.cons = MUX_CONSOLE;
if(!port_cnt) {
mux_driver.cons = MUX_CONSOLE;
ret = uart_register_driver(&card->drv);
if(ret) {
status = uart_register_driver(&mux_driver);
if(status) {
printk(KERN_ERR "Serial mux: Unable to register driver.\n");
return 1;
}
for(j = 0; j < UART_NR; ++j) {
port = &card->ports[j];
port->iobase = 0;
port->mapbase = dev->hpa + MUX_OFFSET + (j * MUX_LINE_OFFSET);
port->membase = ioremap(port->mapbase, MUX_LINE_OFFSET);
port->iotype = SERIAL_IO_MEM;
port->type = PORT_MUX;
port->irq = SERIAL_IRQ_NONE;
port->uartclk = 0;
port->fifosize = MUX_FIFO_SIZE;
port->ops = &mux_pops;
port->flags = UPF_BOOT_AUTOCONF;
port->line = j;
ret = uart_add_one_port(&card->drv, port);
BUG_ON(ret);
}
port_cnt += UART_NR;
init_timer(&mux_timer);
mux_timer.function = mux_poll;
}
for(i = 0; i < ports; ++i, ++port_cnt) {
port = &mux_ports[port_cnt];
port->iobase = 0;
port->mapbase = dev->hpa + MUX_OFFSET + (i * MUX_LINE_OFFSET);
port->membase = ioremap(port->mapbase, MUX_LINE_OFFSET);
port->iotype = SERIAL_IO_MEM;
port->type = PORT_MUX;
port->irq = SERIAL_IRQ_NONE;
port->uartclk = 0;
port->fifosize = MUX_FIFO_SIZE;
port->ops = &mux_pops;
port->flags = UPF_BOOT_AUTOCONF;
port->line = port_cnt;
status = uart_add_one_port(&mux_driver, port);
BUG_ON(status);
}
#ifdef CONFIG_SERIAL_MUX_CONSOLE
register_console(&mux_console);
#endif
return 0;
}
......@@ -497,7 +497,7 @@ static struct parisc_device_id mux_tbl[] = {
MODULE_DEVICE_TABLE(parisc, mux_tbl);
static struct parisc_driver mux_driver = {
static struct parisc_driver serial_mux_driver = {
.name = "Serial MUX",
.id_table = mux_tbl,
.probe = mux_probe,
......@@ -510,7 +510,7 @@ static struct parisc_driver mux_driver = {
*/
static int __init mux_init(void)
{
return register_parisc_driver(&mux_driver);
return register_parisc_driver(&serial_mux_driver);
}
/**
......@@ -521,13 +521,12 @@ static int __init mux_init(void)
static void __exit mux_exit(void)
{
int i;
struct mux_card *card = &mux_card_head;
for (i = 0; i < UART_NR; i++) {
uart_remove_one_port(&card->drv, &card->ports[i]);
for (i = 0; i < port_cnt; i++) {
uart_remove_one_port(&mux_driver, &mux_ports[i]);
}
uart_unregister_driver(&card->drv);
uart_unregister_driver(&mux_driver);
}
module_init(mux_init);
......
......@@ -588,18 +588,18 @@ sti_select_font(struct sti_cooked_rom *rom,
static void __init
sti_dump_rom(struct sti_rom *rom)
{
printk(KERN_INFO "STI id %04x-%04x, conforms to spec rev. %d.%02x\n",
printk(KERN_INFO " id %04x-%04x, conforms to spec rev. %d.%02x\n",
rom->graphics_id[0],
rom->graphics_id[1],
rom->revno[0] >> 4,
rom->revno[0] & 0x0f);
DPRINTK((" supports %d monitors\n", rom->num_mons));
DPRINTK((" font start %08x\n", rom->font_start));
DPRINTK((" region list %08x\n", rom->region_list));
DPRINTK((" init_graph %08x\n", rom->init_graph));
DPRINTK((" bus support %02x\n", rom->bus_support));
DPRINTK((" ext bus support %02x\n", rom->ext_bus_support));
DPRINTK((" alternate code type %d\n", rom->alt_code_type));
DPRINTK((" supports %d monitors\n", rom->num_mons));
DPRINTK((" font start %08x\n", rom->font_start));
DPRINTK((" region list %08x\n", rom->region_list));
DPRINTK((" init_graph %08x\n", rom->init_graph));
DPRINTK((" bus support %02x\n", rom->bus_support));
DPRINTK((" ext bus support %02x\n", rom->ext_bus_support));
DPRINTK((" alternate code type %d\n", rom->alt_code_type));
}
......@@ -869,14 +869,14 @@ sti_try_rom_generic(unsigned long address, unsigned long hpa, struct pci_dev *pd
ok = 0;
if ((sig & 0xff) == 0x01) {
printk(KERN_INFO "STI byte mode ROM at %08lx, hpa at %08lx\n",
address, hpa);
DPRINTK((" byte mode ROM at %08lx, hpa at %08lx\n",
address, hpa));
ok = sti_read_rom(0, sti, address);
}
if ((sig & 0xffff) == 0x0303) {
printk(KERN_INFO "STI word mode ROM at %08lx, hpa at %08lx\n",
address, hpa);
DPRINTK((" word mode ROM at %08lx, hpa at %08lx\n",
address, hpa));
ok = sti_read_rom(1, sti, address);
}
......@@ -903,7 +903,7 @@ sti_try_rom_generic(unsigned long address, unsigned long hpa, struct pci_dev *pd
sti_dump_globcfg(sti->glob_cfg, sti->sti_mem_request);
sti_dump_outptr(sti);
printk(KERN_INFO "STI device: %s\n", sti->outptr.dev_name );
printk(KERN_INFO " graphics card name: %s\n", sti->outptr.dev_name );
sti_roms[num_sti_roms] = sti;
num_sti_roms++;
......
......@@ -3,7 +3,7 @@
* Low level Frame buffer driver for HP workstations with
* STI (standard text interface) video firmware.
*
* Copyright (C) 2001-2002 Helge Deller <deller@gmx.de>
* Copyright (C) 2001-2004 Helge Deller <deller@gmx.de>
* Portions Copyright (C) 2001 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
*
* Based on:
......@@ -39,10 +39,10 @@
*/
/* TODO:
* - remove the static fb_info to support multiple cards
* - 1bpp mode is completely untested
* - add support for h/w acceleration
* - add hardware cursor
* - automatically disable double buffering (e.g. on RDI precisionbook laptop)
*/
......@@ -51,6 +51,8 @@
* #undef FALLBACK_TO_1BPP to reject support for unsupported cards */
#undef FALLBACK_TO_1BPP
#undef DEBUG_STIFB_REGS /* debug sti register accesses */
#include <linux/config.h>
#include <linux/module.h>
......@@ -154,8 +156,27 @@ static int __initdata stifb_force_bpp[MAX_STI_ROMS];
#define READ_BYTE(fb,reg) __raw_readb((fb)->info.fix.mmio_start + (reg))
#define READ_WORD(fb,reg) __raw_readl((fb)->info.fix.mmio_start + (reg))
#define WRITE_BYTE(value,fb,reg) __raw_writeb((value),(fb)->info.fix.mmio_start + (reg))
#define WRITE_WORD(value,fb,reg) __raw_writel((value),(fb)->info.fix.mmio_start + (reg))
#ifndef DEBUG_STIFB_REGS
# define DEBUG_OFF()
# define DEBUG_ON()
# define WRITE_BYTE(value,fb,reg) __raw_writeb((value),(fb)->info.fix.mmio_start + (reg))
# define WRITE_WORD(value,fb,reg) __raw_writel((value),(fb)->info.fix.mmio_start + (reg))
#else
static int debug_on = 1;
# define DEBUG_OFF() debug_on=0
# define DEBUG_ON() debug_on=1
# define WRITE_BYTE(value,fb,reg) do { if (debug_on) \
printk(KERN_DEBUG "%30s: WRITE_BYTE(0x%06x) = 0x%02x (old=0x%02x)\n", \
__FUNCTION__, reg, value, READ_BYTE(fb,reg)); \
__raw_writeb((value),(fb)->info.fix.mmio_start + (reg)); } while (0)
# define WRITE_WORD(value,fb,reg) do { if (debug_on) \
printk(KERN_DEBUG "%30s: WRITE_WORD(0x%06x) = 0x%08x (old=0x%08x)\n", \
__FUNCTION__, reg, value, READ_WORD(fb,reg)); \
__raw_writel((value),(fb)->info.fix.mmio_start + (reg)); } while (0)
#endif /* DEBUG_STIFB_REGS */
#define ENABLE 1 /* for enabling/disabling screen */
#define DISABLE 0
......@@ -390,7 +411,7 @@ ARTIST_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable)
WRITE_WORD(val, fb, REG_6)
#define NGLE_LONG_FB_ADDRESS(fbaddrbase, x, y) ( \
(u32) (fbaddrbase) + \
(u32) (fbaddrbase) + \
( (unsigned int) ( (y) << 13 ) | \
(unsigned int) ( (x) << 2 ) ) \
)
......@@ -449,6 +470,13 @@ SETUP_ATTR_ACCESS(struct stifb_info *fb, unsigned BufferNumber)
static void
SET_ATTR_SIZE(struct stifb_info *fb, int width, int height)
{
/* REG_6 seems to have special values when run on a
RDI precisionbook parisc laptop (INTERNAL_EG_DX1024 or
INTERNAL_EG_X1024). The values are:
0x2f0: internal (LCD) & external display enabled
0x2a0: external display only
0x000: zero on standard artist graphic cards
*/
WRITE_WORD(0x00000000, fb, REG_6);
WRITE_WORD((width<<16) | height, fb, REG_9);
WRITE_WORD(0x05000000, fb, REG_6);
......@@ -730,7 +758,7 @@ hyperResetPlanes(struct stifb_info *fb, int enable)
controlPlaneReg = 0x00000F00; /* 0x00000100 should be enought, but lets clear all 4 bits */
switch (enable) {
case 1: /* ENABLE */
case ENABLE:
/* clear screen */
if (IS_24_DEVICE(fb))
ngleDepth24_ClearImagePlanes(fb);
......@@ -750,7 +778,7 @@ hyperResetPlanes(struct stifb_info *fb, int enable)
hyperUndoITE(fb);
break;
case 0: /* DISABLE */
case DISABLE:
/* clear screen */
if (IS_24_DEVICE(fb))
ngleDepth24_ClearImagePlanes(fb);
......@@ -974,6 +1002,8 @@ stifb_setcolreg(u_int regno, u_int red, u_int green,
green >>= 8;
blue >>= 8;
DEBUG_OFF();
START_IMAGE_COLORMAP_ACCESS(fb);
if (fb->info.var.grayscale) {
......@@ -1005,6 +1035,8 @@ stifb_setcolreg(u_int regno, u_int red, u_int green,
FINISH_IMAGE_COLORMAP_ACCESS(fb);
}
DEBUG_ON();
return 0;
}
......@@ -1144,17 +1176,28 @@ stifb_init_fb(struct sti_struct *sti, int force_bpp)
/* only supported cards are allowed */
switch (fb->id) {
case CRT_ID_VISUALIZE_EG:
/* look for a double buffering device like e.g. the
"INTERNAL_EG_DX1024" in the RDI precisionbook laptop
which won't work. The same device in non-double
buffering mode returns "INTERNAL_EG_X1024". */
if (strstr(sti->outptr.dev_name, "EG_DX")) {
printk(KERN_WARNING
"stifb: ignoring '%s'. Disable double buffering in IPL menu.\n",
sti->outptr.dev_name);
goto out_err0;
}
/* fall though */
case S9000_ID_ARTIST:
case S9000_ID_HCRX:
case S9000_ID_TIMBER:
case S9000_ID_A1659A:
case S9000_ID_A1439A:
case CRT_ID_VISUALIZE_EG:
break;
default:
printk(KERN_WARNING "stifb: Unsupported gfx card id 0x%08x\n",
fb->id);
goto out_err1;
printk(KERN_WARNING "stifb: '%s' (id: 0x%08x) not supported.\n",
sti->outptr.dev_name, fb->id);
goto out_err0;
}
/* default to 8 bpp on most graphic chips */
......@@ -1232,7 +1275,7 @@ stifb_init_fb(struct sti_struct *sti, int force_bpp)
"stifb: Unsupported graphics card (id=0x%08x) "
"- skipping.\n",
fb->id);
goto out_err1;
goto out_err0;
#endif
}
......@@ -1306,12 +1349,13 @@ stifb_init_fb(struct sti_struct *sti, int force_bpp)
sti->info = info; /* save for unregister_framebuffer() */
printk(KERN_INFO
"fb%d: %s %dx%d-%d frame buffer device, id: %04x, mmio: 0x%04lx\n",
"fb%d: %s %dx%d-%d frame buffer device, %s, id: %04x, mmio: 0x%04lx\n",
fb->info.node,
fix->id,
var->xres,
var->yres,
var->bits_per_pixel,
sti->outptr.dev_name,
fb->id,
fix->mmio_start);
......@@ -1324,16 +1368,24 @@ stifb_init_fb(struct sti_struct *sti, int force_bpp)
release_mem_region(fix->smem_start, fix->smem_len);
out_err1:
fb_dealloc_cmap(&info->cmap);
out_err0:
kfree(fb);
return -ENXIO;
}
static int stifb_disabled __initdata;
int __init
stifb_init(void)
{
struct sti_struct *sti;
int i;
if (stifb_disabled) {
printk(KERN_INFO "stifb: disabled by \"stifb=off\" kernel parameter\n");
return -ENXIO;
}
for (i = 1; i < MAX_STI_ROMS; i++) {
sti = sti_get_rom(i);
if (!sti)
......@@ -1379,6 +1431,11 @@ stifb_setup(char *options)
if (!options || !*options)
return 0;
if (strncmp(options, "off", 3) == 0) {
stifb_disabled = 1;
options += 3;
}
if (strncmp(options, "bpp", 3) == 0) {
options += 3;
for (i = 0; i < MAX_STI_ROMS; i++) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment