aboutsummaryrefslogtreecommitdiff
path: root/drivers/parisc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/parisc')
-rw-r--r--drivers/parisc/eisa_eeprom.c15
-rw-r--r--drivers/parisc/lba_pci.c56
2 files changed, 58 insertions, 13 deletions
diff --git a/drivers/parisc/eisa_eeprom.c b/drivers/parisc/eisa_eeprom.c
index af212c6a6158..783906fe659a 100644
--- a/drivers/parisc/eisa_eeprom.c
+++ b/drivers/parisc/eisa_eeprom.c
@@ -31,20 +31,9 @@
#define EISA_EEPROM_MINOR 241
-static loff_t eisa_eeprom_llseek(struct file *file, loff_t offset, int origin )
+static loff_t eisa_eeprom_llseek(struct file *file, loff_t offset, int origin)
{
- switch (origin) {
- case 0:
- /* nothing to do */
- break;
- case 1:
- offset += file->f_pos;
- break;
- case 2:
- offset += HPEE_MAX_LENGTH;
- break;
- }
- return (offset >= 0 && offset < HPEE_MAX_LENGTH) ? (file->f_pos = offset) : -EINVAL;
+ return fixed_size_llseek(file, offset, origin, HPEE_MAX_LENGTH);
}
static ssize_t eisa_eeprom_read(struct file * file,
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
index 1f05913ae677..19f6f70c67d3 100644
--- a/drivers/parisc/lba_pci.c
+++ b/drivers/parisc/lba_pci.c
@@ -613,6 +613,54 @@ truncate_pat_collision(struct resource *root, struct resource *new)
return 0; /* truncation successful */
}
+/*
+ * extend_lmmio_len: extend lmmio range to maximum length
+ *
+ * This is needed at least on C8000 systems to get the ATI FireGL card
+ * working. On other systems we will currently not extend the lmmio space.
+ */
+static unsigned long
+extend_lmmio_len(unsigned long start, unsigned long end, unsigned long lba_len)
+{
+ struct resource *tmp;
+
+ pr_debug("LMMIO mismatch: PAT length = 0x%lx, MASK register = 0x%lx\n",
+ end - start, lba_len);
+
+ lba_len = min(lba_len+1, 256UL*1024*1024); /* limit to 256 MB */
+
+ pr_debug("LBA: lmmio_space [0x%lx-0x%lx] - original\n", start, end);
+
+ if (boot_cpu_data.cpu_type < mako) {
+ pr_info("LBA: Not a C8000 system - not extending LMMIO range.\n");
+ return end;
+ }
+
+ end += lba_len;
+ if (end < start) /* fix overflow */
+ end = -1ULL;
+
+ pr_debug("LBA: lmmio_space [0x%lx-0x%lx] - current\n", start, end);
+
+ /* first overlap */
+ for (tmp = iomem_resource.child; tmp; tmp = tmp->sibling) {
+ pr_debug("LBA: testing %pR\n", tmp);
+ if (tmp->start == start)
+ continue; /* ignore ourself */
+ if (tmp->end < start)
+ continue;
+ if (tmp->start > end)
+ continue;
+ if (end >= tmp->start)
+ end = tmp->start - 1;
+ }
+
+ pr_info("LBA: lmmio_space [0x%lx-0x%lx] - new\n", start, end);
+
+ /* return new end */
+ return end;
+}
+
#else
#define truncate_pat_collision(r,n) (0)
#endif
@@ -994,6 +1042,14 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
case PAT_LMMIO:
/* used to fix up pre-initialized MEM BARs */
if (!lba_dev->hba.lmmio_space.flags) {
+ unsigned long lba_len;
+
+ lba_len = ~READ_REG32(lba_dev->hba.base_addr
+ + LBA_LMMIO_MASK);
+ if ((p->end - p->start) != lba_len)
+ p->end = extend_lmmio_len(p->start,
+ p->end, lba_len);
+
sprintf(lba_dev->hba.lmmio_name,
"PCI%02x LMMIO",
(int)lba_dev->hba.bus_num.start);