aboutsummaryrefslogtreecommitdiff
path: root/drivers/parisc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/parisc')
-rw-r--r--drivers/parisc/Kconfig11
-rw-r--r--drivers/parisc/README.dino3
-rw-r--r--drivers/parisc/asp.c8
-rw-r--r--drivers/parisc/ccio-dma.c180
-rw-r--r--drivers/parisc/ccio-rm-dma.c1
-rw-r--r--drivers/parisc/dino.c180
-rw-r--r--drivers/parisc/eisa.c45
-rw-r--r--drivers/parisc/eisa_eeprom.c29
-rw-r--r--drivers/parisc/eisa_enumerator.c20
-rw-r--r--drivers/parisc/gsc.c85
-rw-r--r--drivers/parisc/gsc.h4
-rw-r--r--drivers/parisc/hppb.c24
-rw-r--r--drivers/parisc/iommu-helpers.h17
-rw-r--r--drivers/parisc/iosapic.c182
-rw-r--r--drivers/parisc/iosapic_private.h2
-rw-r--r--drivers/parisc/lasi.c7
-rw-r--r--drivers/parisc/lba_pci.c506
-rw-r--r--drivers/parisc/led.c150
-rw-r--r--drivers/parisc/pdc_stable.c234
-rw-r--r--drivers/parisc/power.c207
-rw-r--r--drivers/parisc/sba_iommu.c497
-rw-r--r--drivers/parisc/superio.c67
-rw-r--r--drivers/parisc/wax.c5
23 files changed, 1108 insertions, 1356 deletions
diff --git a/drivers/parisc/Kconfig b/drivers/parisc/Kconfig
index 1d3b84b4af3..592de566e72 100644
--- a/drivers/parisc/Kconfig
+++ b/drivers/parisc/Kconfig
@@ -103,12 +103,10 @@ config IOMMU_SBA
depends on PCI_LBA
default PCI_LBA
-#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 IOMMU_HELPER
+ bool
+ depends on IOMMU_SBA || IOMMU_CCIO
+ default y
source "drivers/pcmcia/Kconfig"
@@ -130,6 +128,7 @@ config SUPERIO
config CHASSIS_LCD_LED
bool "Chassis LCD and LED support"
default y
+ select VM_EVENT_COUNTERS
help
Say Y here if you want to enable support for the Heartbeat,
Disk/Network activities LEDs on some PA-RISC machines,
diff --git a/drivers/parisc/README.dino b/drivers/parisc/README.dino
index 097324f34bb..1627426996c 100644
--- a/drivers/parisc/README.dino
+++ b/drivers/parisc/README.dino
@@ -10,8 +10,7 @@
** PCI bus. HP-supplied graphics cards that utilize the PCI bus are
** not affected."
**
-** REVISIT: "go/pci_defect" link below is stale.
-** HP Internal can use <http://hpfcdma.fc.hp.com:80/Dino/>
+** http://h20000.www2.hp.com/bizsupport/TechSupport/Home.jsp?locale=en_US&prodTypeId=12454&prodSeriesId=44443
**
** Product First Good Serial Number
** C200/C240 (US) US67350000
diff --git a/drivers/parisc/asp.c b/drivers/parisc/asp.c
index 558420bc9f8..6a1ab2512a5 100644
--- a/drivers/parisc/asp.c
+++ b/drivers/parisc/asp.c
@@ -15,7 +15,6 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/module.h>
-#include <linux/slab.h>
#include <linux/types.h>
#include <asm/io.h>
#include <asm/led.h>
@@ -71,8 +70,7 @@ static void asp_choose_irq(struct parisc_device *dev, void *ctrl)
*/
#define ASP_INTERRUPT_ADDR 0xf0800000
-int __init
-asp_init_chip(struct parisc_device *dev)
+static int __init asp_init_chip(struct parisc_device *dev)
{
struct gsc_irq gsc_irq;
int ret;
@@ -82,13 +80,13 @@ asp_init_chip(struct parisc_device *dev)
asp.hpa = ASP_INTERRUPT_ADDR;
printk(KERN_INFO "%s version %d at 0x%lx found.\n",
- asp.name, asp.version, dev->hpa.start);
+ asp.name, asp.version, (unsigned long)dev->hpa.start);
/* the IRQ ASP should use */
ret = -EBUSY;
dev->irq = gsc_claim_irq(&gsc_irq, ASP_GSC_IRQ);
if (dev->irq < 0) {
- printk(KERN_ERR "%s(): cannot get GSC irq\n", __FUNCTION__);
+ printk(KERN_ERR "%s(): cannot get GSC irq\n", __func__);
goto out;
}
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
index 68cb3a08005..8b490d77054 100644
--- a/drivers/parisc/ccio-dma.c
+++ b/drivers/parisc/ccio-dma.c
@@ -32,6 +32,7 @@
*/
#include <linux/types.h>
+#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/spinlock.h>
@@ -41,6 +42,9 @@
#include <linux/reboot.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <linux/scatterlist.h>
+#include <linux/iommu-helper.h>
+#include <linux/export.h>
#include <asm/byteorder.h>
#include <asm/cache.h> /* for L1_CACHE_BYTES */
@@ -63,18 +67,10 @@
#undef DEBUG_CCIO_RUN_SG
#ifdef CONFIG_PROC_FS
-/*
- * CCIO_SEARCH_TIME can help measure how fast the bitmap search is.
- * impacts performance though - ditch it if you don't use it.
- */
-#define CCIO_SEARCH_TIME
-#undef CCIO_MAP_STATS
-#else
-#undef CCIO_SEARCH_TIME
-#undef CCIO_MAP_STATS
+/* depends on proc fs support. But costs CPU performance. */
+#undef CCIO_COLLECT_STATS
#endif
-#include <linux/proc_fs.h>
#include <asm/runway.h> /* for proc_runway_root */
#ifdef DEBUG_CCIO_INIT
@@ -236,12 +232,10 @@ struct ioc {
u32 res_size; /* size of resource map in bytes */
spinlock_t res_lock;
-#ifdef CCIO_SEARCH_TIME
+#ifdef CCIO_COLLECT_STATS
#define CCIO_SEARCH_SAMPLE 0x100
unsigned long avg_search[CCIO_SEARCH_SAMPLE];
unsigned long avg_idx; /* current index into avg_search */
-#endif
-#ifdef CCIO_MAP_STATS
unsigned long used_pages;
unsigned long msingle_calls;
unsigned long msingle_pages;
@@ -292,7 +286,6 @@ static int ioc_count;
#define PDIR_INDEX(iovp) ((iovp)>>IOVP_SHIFT)
#define MKIOVP(pdir_idx) ((long)(pdir_idx) << IOVP_SHIFT)
#define MKIOVA(iovp,offset) (dma_addr_t)((long)iovp | (long)offset)
-#define ROUNDUP(x,y) ((x + ((y)-1)) & ~((y)-1))
/*
** Don't worry about the 150% average search length on a miss.
@@ -301,13 +294,17 @@ static int ioc_count;
*/
#define CCIO_SEARCH_LOOP(ioc, res_idx, mask, size) \
for(; res_ptr < res_end; ++res_ptr) { \
- if(0 == (*res_ptr & mask)) { \
- *res_ptr |= mask; \
- res_idx = (unsigned int)((unsigned long)res_ptr - (unsigned long)ioc->res_map); \
- ioc->res_hint = res_idx + (size >> 3); \
- goto resource_found; \
- } \
- }
+ int ret;\
+ unsigned int idx;\
+ idx = (unsigned int)((unsigned long)res_ptr - (unsigned long)ioc->res_map); \
+ ret = iommu_is_span_boundary(idx << 3, pages_needed, 0, boundary_size);\
+ if ((0 == (*res_ptr & mask)) && !ret) { \
+ *res_ptr |= mask; \
+ res_idx = idx;\
+ ioc->res_hint = res_idx + (size >> 3); \
+ goto resource_found; \
+ } \
+ }
#define CCIO_FIND_FREE_MAPPING(ioa, res_idx, mask, size) \
u##size *res_ptr = (u##size *)&((ioc)->res_map[ioa->res_hint & ~((size >> 3) - 1)]); \
@@ -340,11 +337,12 @@ static int ioc_count;
* of available pages for the requested size.
*/
static int
-ccio_alloc_range(struct ioc *ioc, size_t size)
+ccio_alloc_range(struct ioc *ioc, struct device *dev, size_t size)
{
unsigned int pages_needed = size >> IOVP_SHIFT;
unsigned int res_idx;
-#ifdef CCIO_SEARCH_TIME
+ unsigned long boundary_size;
+#ifdef CCIO_COLLECT_STATS
unsigned long cr_start = mfctl(16);
#endif
@@ -352,17 +350,20 @@ ccio_alloc_range(struct ioc *ioc, size_t size)
BUG_ON((pages_needed * IOVP_SIZE) > DMA_CHUNK_SIZE);
DBG_RES("%s() size: %d pages_needed %d\n",
- __FUNCTION__, size, pages_needed);
+ __func__, size, pages_needed);
/*
** "seek and ye shall find"...praying never hurts either...
** ggg sacrifices another 710 to the computer gods.
*/
+ boundary_size = ALIGN((unsigned long long)dma_get_seg_boundary(dev) + 1,
+ 1ULL << IOVP_SHIFT) >> IOVP_SHIFT;
+
if (pages_needed <= 8) {
/*
* LAN traffic will not thrash the TLB IFF the same NIC
- * uses 8 adjacent pages to map seperate payload data.
+ * uses 8 adjacent pages to map separate payload data.
* ie the same byte in the resource bit map.
*/
#if 0
@@ -385,18 +386,18 @@ ccio_alloc_range(struct ioc *ioc, size_t size)
#endif
} else {
panic("%s: %s() Too many pages to map. pages_needed: %u\n",
- __FILE__, __FUNCTION__, pages_needed);
+ __FILE__, __func__, pages_needed);
}
panic("%s: %s() I/O MMU is out of mapping resources.\n", __FILE__,
- __FUNCTION__);
+ __func__);
resource_found:
DBG_RES("%s() res_idx %d res_hint: %d\n",
- __FUNCTION__, res_idx, ioc->res_hint);
+ __func__, res_idx, ioc->res_hint);
-#ifdef CCIO_SEARCH_TIME
+#ifdef CCIO_COLLECT_STATS
{
unsigned long cr_end = mfctl(16);
unsigned long tmp = cr_end - cr_start;
@@ -405,8 +406,6 @@ resource_found:
}
ioc->avg_search[ioc->avg_idx++] = cr_start;
ioc->avg_idx &= CCIO_SEARCH_SAMPLE - 1;
-#endif
-#ifdef CCIO_MAP_STATS
ioc->used_pages += pages_needed;
#endif
/*
@@ -440,9 +439,9 @@ ccio_free_range(struct ioc *ioc, dma_addr_t iova, unsigned long pages_mapped)
BUG_ON(pages_mapped > BITS_PER_LONG);
DBG_RES("%s(): res_idx: %d pages_mapped %d\n",
- __FUNCTION__, res_idx, pages_mapped);
+ __func__, res_idx, pages_mapped);
-#ifdef CCIO_MAP_STATS
+#ifdef CCIO_COLLECT_STATS
ioc->used_pages -= pages_mapped;
#endif
@@ -452,10 +451,10 @@ ccio_free_range(struct ioc *ioc, dma_addr_t iova, unsigned long pages_mapped)
unsigned long mask = ~(~0UL >> pages_mapped);
CCIO_FREE_MAPPINGS(ioc, res_idx, mask, 8);
#else
- CCIO_FREE_MAPPINGS(ioc, res_idx, 0xff, 8);
+ CCIO_FREE_MAPPINGS(ioc, res_idx, 0xffUL, 8);
#endif
} else if(pages_mapped <= 16) {
- CCIO_FREE_MAPPINGS(ioc, res_idx, 0xffff, 16);
+ CCIO_FREE_MAPPINGS(ioc, res_idx, 0xffffUL, 16);
} else if(pages_mapped <= 32) {
CCIO_FREE_MAPPINGS(ioc, res_idx, ~(unsigned int)0, 32);
#ifdef __LP64__
@@ -464,7 +463,7 @@ ccio_free_range(struct ioc *ioc, dma_addr_t iova, unsigned long pages_mapped)
#endif
} else {
panic("%s:%s() Too many pages to unmap.\n", __FILE__,
- __FUNCTION__);
+ __func__);
}
}
@@ -486,7 +485,7 @@ typedef unsigned long space_t;
** This bit tells U2 to do R/M/W for partial cachelines. "Streaming"
** data can avoid this if the mapping covers full cache lines.
** o STOP_MOST is needed for atomicity across cachelines.
-** Apperently only "some EISA devices" need this.
+** Apparently only "some EISA devices" need this.
** Using CONFIG_ISA is hack. Only the IOA with EISA under it needs
** to use this hint iff the EISA devices needs this feature.
** According to the U2 ERS, STOP_MOST enabled pages hurt performance.
@@ -554,7 +553,7 @@ static u32 hint_lookup[] = {
* (Load Coherence Index) instruction. The 8 bits used for the virtual
* index are bits 12:19 of the value returned by LCI.
*/
-void CCIO_INLINE
+static void CCIO_INLINE
ccio_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba,
unsigned long hints)
{
@@ -652,7 +651,7 @@ ccio_clear_io_tlb(struct ioc *ioc, dma_addr_t iovp, size_t byte_cnt)
* Mark the I/O Pdir entries invalid and blow away the corresponding I/O
* TLB entries.
*
- * FIXME: at some threshhold it might be "cheaper" to just blow
+ * FIXME: at some threshold it might be "cheaper" to just blow
* away the entire I/O TLB instead of individual entries.
*
* FIXME: Uturn has 256 TLB entries. We don't need to purge every
@@ -668,7 +667,7 @@ ccio_mark_invalid(struct ioc *ioc, dma_addr_t iova, size_t byte_cnt)
size_t saved_byte_cnt;
/* round up to nearest page size */
- saved_byte_cnt = byte_cnt = ROUNDUP(byte_cnt, IOVP_SIZE);
+ saved_byte_cnt = byte_cnt = ALIGN(byte_cnt, IOVP_SIZE);
while(byte_cnt > 0) {
/* invalidate one page at a time */
@@ -751,21 +750,21 @@ ccio_map_single(struct device *dev, void *addr, size_t size,
offset = ((unsigned long) addr) & ~IOVP_MASK;
/* round up to nearest IOVP_SIZE */
- size = ROUNDUP(size + offset, IOVP_SIZE);
+ size = ALIGN(size + offset, IOVP_SIZE);
spin_lock_irqsave(&ioc->res_lock, flags);
-#ifdef CCIO_MAP_STATS
+#ifdef CCIO_COLLECT_STATS
ioc->msingle_calls++;
ioc->msingle_pages += size >> IOVP_SHIFT;
#endif
- idx = ccio_alloc_range(ioc, size);
+ idx = ccio_alloc_range(ioc, dev, size);
iovp = (dma_addr_t)MKIOVP(idx);
pdir_start = &(ioc->pdir_base[idx]);
DBG_RUN("%s() 0x%p -> 0x%lx size: %0x%x\n",
- __FUNCTION__, addr, (long)iovp | offset, size);
+ __func__, addr, (long)iovp | offset, size);
/* If not cacheline aligned, force SAFE_DMA on the whole mess */
if((size % L1_CACHE_BYTES) || ((unsigned long)addr % L1_CACHE_BYTES))
@@ -810,15 +809,15 @@ ccio_unmap_single(struct device *dev, dma_addr_t iova, size_t size,
ioc = GET_IOC(dev);
DBG_RUN("%s() iovp 0x%lx/%x\n",
- __FUNCTION__, (long)iova, size);
+ __func__, (long)iova, size);
iova ^= offset; /* clear offset bits */
size += offset;
- size = ROUNDUP(size, IOVP_SIZE);
+ size = ALIGN(size, IOVP_SIZE);
spin_lock_irqsave(&ioc->res_lock, flags);
-#ifdef CCIO_MAP_STATS
+#ifdef CCIO_COLLECT_STATS
ioc->usingle_calls++;
ioc->usingle_pages += size >> IOVP_SHIFT;
#endif
@@ -884,7 +883,7 @@ ccio_free_consistent(struct device *dev, size_t size, void *cpu_addr,
*/
#define PIDE_FLAG 0x80000000UL
-#ifdef CCIO_MAP_STATS
+#ifdef CCIO_COLLECT_STATS
#define IOMMU_MAP_STATS
#endif
#include "iommu-helpers.h"
@@ -912,7 +911,7 @@ ccio_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
BUG_ON(!dev);
ioc = GET_IOC(dev);
- DBG_RUN_SG("%s() START %d entries\n", __FUNCTION__, nents);
+ DBG_RUN_SG("%s() START %d entries\n", __func__, nents);
/* Fast path single entry scatterlists. */
if (nents == 1) {
@@ -928,7 +927,7 @@ ccio_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
spin_lock_irqsave(&ioc->res_lock, flags);
-#ifdef CCIO_MAP_STATS
+#ifdef CCIO_COLLECT_STATS
ioc->msg_calls++;
#endif
@@ -940,7 +939,7 @@ ccio_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
** w/o this association, we wouldn't have coherent DMA!
** Access to the virtual address is what forces a two pass algorithm.
*/
- coalesced = iommu_coalesce_chunks(ioc, sglist, nents, ccio_alloc_range);
+ coalesced = iommu_coalesce_chunks(ioc, dev, sglist, nents, ccio_alloc_range);
/*
** Program the I/O Pdir
@@ -956,7 +955,7 @@ ccio_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
BUG_ON(coalesced != filled);
- DBG_RUN_SG("%s() DONE %d mappings\n", __FUNCTION__, filled);
+ DBG_RUN_SG("%s() DONE %d mappings\n", __func__, filled);
for (i = 0; i < filled; i++)
current_len += sg_dma_len(sglist + i);
@@ -985,15 +984,15 @@ ccio_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents,
ioc = GET_IOC(dev);
DBG_RUN_SG("%s() START %d entries, %08lx,%x\n",
- __FUNCTION__, nents, sg_virt_addr(sglist), sglist->length);
+ __func__, nents, sg_virt_addr(sglist), sglist->length);
-#ifdef CCIO_MAP_STATS
+#ifdef CCIO_COLLECT_STATS
ioc->usg_calls++;
#endif
while(sg_dma_len(sglist) && nents--) {
-#ifdef CCIO_MAP_STATS
+#ifdef CCIO_COLLECT_STATS
ioc->usg_pages += sg_dma_len(sglist) >> PAGE_SHIFT;
#endif
ccio_unmap_single(dev, sg_dma_address(sglist),
@@ -1001,7 +1000,7 @@ ccio_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents,
++sglist;
}
- DBG_RUN_SG("%s() DONE (nents %d)\n", __FUNCTION__, nents);
+ DBG_RUN_SG("%s() DONE (nents %d)\n", __func__, nents);
}
static struct hppa_dma_ops ccio_ops = {
@@ -1027,8 +1026,10 @@ static int ccio_proc_info(struct seq_file *m, void *p)
while (ioc != NULL) {
unsigned int total_pages = ioc->res_size << 3;
+#ifdef CCIO_COLLECT_STATS
unsigned long avg = 0, min, max;
int j;
+#endif
len += seq_printf(m, "%s\n", ioc->name);
@@ -1038,7 +1039,7 @@ static int ccio_proc_info(struct seq_file *m, void *p)
len += seq_printf(m, "IO PDIR size : %d bytes (%d entries)\n",
total_pages * 8, total_pages);
-#ifdef CCIO_MAP_STATS
+#ifdef CCIO_COLLECT_STATS
len += seq_printf(m, "IO PDIR entries : %ld free %ld used (%d%%)\n",
total_pages - ioc->used_pages, ioc->used_pages,
(int)(ioc->used_pages * 100 / total_pages));
@@ -1047,7 +1048,7 @@ static int ccio_proc_info(struct seq_file *m, void *p)
len += seq_printf(m, "Resource bitmap : %d bytes (%d pages)\n",
ioc->res_size, total_pages);
-#ifdef CCIO_SEARCH_TIME
+#ifdef CCIO_COLLECT_STATS
min = max = ioc->avg_search[0];
for(j = 0; j < CCIO_SEARCH_SAMPLE; ++j) {
avg += ioc->avg_search[j];
@@ -1059,8 +1060,7 @@ static int ccio_proc_info(struct seq_file *m, void *p)
avg /= CCIO_SEARCH_SAMPLE;
len += seq_printf(m, " Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n",
min, avg, max);
-#endif
-#ifdef CCIO_MAP_STATS
+
len += seq_printf(m, "pci_map_single(): %8ld calls %8ld pages (avg %d/1000)\n",
ioc->msingle_calls, ioc->msingle_pages,
(int)((ioc->msingle_pages * 1000)/ioc->msingle_calls));
@@ -1078,7 +1078,7 @@ static int ccio_proc_info(struct seq_file *m, void *p)
len += seq_printf(m, "pci_unmap_sg() : %8ld calls %8ld pages (avg %d/1000)\n\n\n",
ioc->usg_calls, ioc->usg_pages,
(int)((ioc->usg_pages * 1000)/ioc->usg_calls));
-#endif /* CCIO_MAP_STATS */
+#endif /* CCIO_COLLECT_STATS */
ioc = ioc->next;
}
@@ -1091,7 +1091,7 @@ static int ccio_proc_info_open(struct inode *inode, struct file *file)
return single_open(file, &ccio_proc_info, NULL);
}
-static struct file_operations ccio_proc_info_fops = {
+static const struct file_operations ccio_proc_info_fops = {
.owner = THIS_MODULE,
.open = ccio_proc_info_open,
.read = seq_read,
@@ -1127,14 +1127,14 @@ static int ccio_proc_bitmap_open(struct inode *inode, struct file *file)
return single_open(file, &ccio_proc_bitmap_info, NULL);
}
-static struct file_operations ccio_proc_bitmap_fops = {
+static const struct file_operations ccio_proc_bitmap_fops = {
.owner = THIS_MODULE,
.open = ccio_proc_bitmap_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
-#endif
+#endif /* CONFIG_PROC_FS */
/**
* ccio_find_ioc - Find the ioc in the ioc_list
@@ -1215,7 +1215,7 @@ static int
ccio_get_iotlb_size(struct parisc_device *dev)
{
if (dev->spa_shift == 0) {
- panic("%s() : Can't determine I/O TLB size.\n", __FUNCTION__);
+ panic("%s() : Can't determine I/O TLB size.\n", __func__);
}
return (1 << dev->spa_shift);
}
@@ -1227,7 +1227,7 @@ ccio_get_iotlb_size(struct parisc_device *dev)
#endif /* 0 */
/* We *can't* support JAVA (T600). Venture there at your own risk. */
-static struct parisc_device_id ccio_tbl[] = {
+static const struct parisc_device_id ccio_tbl[] = {
{ HPHW_IOA, HVERSION_REV_ANY_ID, U2_IOA_RUNWAY, 0xb }, /* U2 */
{ HPHW_IOA, HVERSION_REV_ANY_ID, UTURN_IOA_RUNWAY, 0xb }, /* UTurn */
{ 0, }
@@ -1242,10 +1242,10 @@ static struct parisc_driver ccio_driver = {
};
/**
- * ccio_ioc_init - Initalize the I/O Controller
+ * ccio_ioc_init - Initialize the I/O Controller
* @ioc: The I/O Controller.
*
- * Initalize the I/O Controller which includes setting up the
+ * Initialize the I/O Controller which includes setting up the
* I/O Page Directory, the resource map, and initalizing the
* U2/Uturn chip into virtual mode.
*/
@@ -1267,7 +1267,7 @@ ccio_ioc_init(struct ioc *ioc)
** Hot-Plug/Removal of PCI cards. (aka PCI OLARD).
*/
- iova_space_size = (u32) (num_physpages / count_parisc_driver(&ccio_driver));
+ iova_space_size = (u32) (totalram_pages / count_parisc_driver(&ccio_driver));
/* limit IOVA space size to 1MB-1GB */
@@ -1305,15 +1305,15 @@ ccio_ioc_init(struct ioc *ioc)
BUG_ON((1 << get_order(ioc->pdir_size)) != (ioc->pdir_size >> PAGE_SHIFT));
DBG_INIT("%s() hpa 0x%p mem %luMB IOV %dMB (%d bits)\n",
- __FUNCTION__, ioc->ioc_regs,
- (unsigned long) num_physpages >> (20 - PAGE_SHIFT),
+ __func__, ioc->ioc_regs,
+ (unsigned long) totalram_pages >> (20 - PAGE_SHIFT),
iova_space_size>>20,
iov_order + PAGE_SHIFT);
ioc->pdir_base = (u64 *)__get_free_pages(GFP_KERNEL,
get_order(ioc->pdir_size));
if(NULL == ioc->pdir_base) {
- panic("%s() could not allocate I/O Page Table\n", __FUNCTION__);
+ panic("%s() could not allocate I/O Page Table\n", __func__);
}
memset(ioc->pdir_base, 0, ioc->pdir_size);
@@ -1322,12 +1322,12 @@ ccio_ioc_init(struct ioc *ioc)
/* resource map size dictated by pdir_size */
ioc->res_size = (ioc->pdir_size / sizeof(u64)) >> 3;
- DBG_INIT("%s() res_size 0x%x\n", __FUNCTION__, ioc->res_size);
+ DBG_INIT("%s() res_size 0x%x\n", __func__, ioc->res_size);
ioc->res_map = (u8 *)__get_free_pages(GFP_KERNEL,
get_order(ioc->res_size));
if(NULL == ioc->res_map) {
- panic("%s() could not allocate resource map\n", __FUNCTION__);
+ panic("%s() could not allocate resource map\n", __func__);
}
memset(ioc->res_map, 0, ioc->res_size);
@@ -1370,7 +1370,7 @@ ccio_ioc_init(struct ioc *ioc)
}
}
-static void
+static void __init
ccio_init_resource(struct resource *res, char *name, void __iomem *ioaddr)
{
int result;
@@ -1399,7 +1399,7 @@ ccio_init_resource(struct resource *res, char *name, void __iomem *ioaddr)
result = insert_resource(&iomem_resource, res);
if (result < 0) {
printk(KERN_ERR "%s() failed to claim CCIO bus address space (%08lx,%08lx)\n",
- __FUNCTION__, res->start, res->end);
+ __func__, (unsigned long)res->start, (unsigned long)res->end);
}
}
@@ -1537,12 +1537,11 @@ int ccio_request_resource(const struct parisc_device *dev,
* If so, initialize the chip and tell other partners in crime they
* have work to do.
*/
-static int ccio_probe(struct parisc_device *dev)
+static int __init ccio_probe(struct parisc_device *dev)
{
int i;
struct ioc *ioc, **ioc_p = &ioc_list;
- struct proc_dir_entry *info_entry, *bitmap_entry;
-
+
ioc = kzalloc(sizeof(struct ioc), GFP_KERNEL);
if (ioc == NULL) {
printk(KERN_ERR MODULE_NAME ": memory allocation failure\n");
@@ -1551,7 +1550,8 @@ static int ccio_probe(struct parisc_device *dev)
ioc->name = dev->id.hversion == U2_IOA_RUNWAY ? "U2" : "UTurn";
- printk(KERN_INFO "Found %s at 0x%lx\n", ioc->name, dev->hpa.start);
+ printk(KERN_INFO "Found %s at 0x%lx\n", ioc->name,
+ (unsigned long)dev->hpa.start);
for (i = 0; i < ioc_count; i++) {
ioc_p = &(*ioc_p)->next;
@@ -1568,27 +1568,23 @@ static int ccio_probe(struct parisc_device *dev)
/* if this fails, no I/O cards will work, so may as well bug */
BUG_ON(dev->dev.platform_data == NULL);
HBA_DATA(dev->dev.platform_data)->iommu = ioc;
-
- if (ioc_count == 0) {
- info_entry = create_proc_entry(MODULE_NAME, 0, proc_runway_root);
- if (info_entry)
- info_entry->proc_fops = &ccio_proc_info_fops;
- bitmap_entry = create_proc_entry(MODULE_NAME"-bitmap", 0, proc_runway_root);
- if (bitmap_entry)
- bitmap_entry->proc_fops = &ccio_proc_bitmap_fops;
+#ifdef CONFIG_PROC_FS
+ if (ioc_count == 0) {
+ proc_create(MODULE_NAME, 0, proc_runway_root,
+ &ccio_proc_info_fops);
+ proc_create(MODULE_NAME"-bitmap", 0, proc_runway_root,
+ &ccio_proc_bitmap_fops);
}
-
+#endif
ioc_count++;
- parisc_vmerge_boundary = IOVP_SIZE;
- parisc_vmerge_max_size = BITS_PER_LONG * IOVP_SIZE;
parisc_has_iommu();
return 0;
}
/**
- * ccio_init - ccio initalization procedure.
+ * ccio_init - ccio initialization procedure.
*
* Register this driver.
*/
diff --git a/drivers/parisc/ccio-rm-dma.c b/drivers/parisc/ccio-rm-dma.c
index 356b8357bcc..f78f6f1aef4 100644
--- a/drivers/parisc/ccio-rm-dma.c
+++ b/drivers/parisc/ccio-rm-dma.c
@@ -38,6 +38,7 @@
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/pci.h>
+#include <linux/gfp.h>
#include <asm/uaccess.h>
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
index 0d96c50ffe9..9eae9834bcc 100644
--- a/drivers/parisc/dino.c
+++ b/drivers/parisc/dino.c
@@ -55,7 +55,6 @@
#include <asm/pdc.h>
#include <asm/page.h>
-#include <asm/system.h>
#include <asm/io.h>
#include <asm/hardware.h>
@@ -175,12 +174,12 @@ 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->bridge));
- u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
+ u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start;
u32 v = DINO_CFG_TOK(local_bus, devfn, where & ~3);
void __iomem *base_addr = d->hba.base_addr;
unsigned long flags;
- DBG("%s: %p, %d, %d, %d\n", __FUNCTION__, base_addr, devfn, where,
+ DBG("%s: %p, %d, %d, %d\n", __func__, base_addr, devfn, where,
size);
spin_lock_irqsave(&d->dinosaur_pen, flags);
@@ -210,12 +209,12 @@ 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->bridge));
- u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
+ u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start;
u32 v = DINO_CFG_TOK(local_bus, devfn, where & ~3);
void __iomem *base_addr = d->hba.base_addr;
unsigned long flags;
- DBG("%s: %p, %d, %d, %d\n", __FUNCTION__, base_addr, devfn, where,
+ DBG("%s: %p, %d, %d, %d\n", __func__, base_addr, devfn, where,
size);
spin_lock_irqsave(&d->dinosaur_pen, flags);
@@ -287,7 +286,7 @@ DINO_PORT_OUT(b, 8, 3)
DINO_PORT_OUT(w, 16, 2)
DINO_PORT_OUT(l, 32, 0)
-struct pci_port_ops dino_port_ops = {
+static struct pci_port_ops dino_port_ops = {
.inb = dino_in8,
.inw = dino_in16,
.inl = dino_in32,
@@ -296,25 +295,25 @@ struct pci_port_ops dino_port_ops = {
.outl = dino_out32
};
-static void dino_disable_irq(unsigned int irq)
+static void dino_mask_irq(struct irq_data *d)
{
- struct dino_device *dino_dev = irq_desc[irq].chip_data;
- int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS);
+ struct dino_device *dino_dev = irq_data_get_irq_chip_data(d);
+ int local_irq = gsc_find_local_irq(d->irq, dino_dev->global_irq, DINO_LOCAL_IRQS);
- DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, dino_dev, irq);
+ DBG(KERN_WARNING "%s(0x%p, %d)\n", __func__, dino_dev, d->irq);
/* Clear the matching bit in the IMR register */
dino_dev->imr &= ~(DINO_MASK_IRQ(local_irq));
__raw_writel(dino_dev->imr, dino_dev->hba.base_addr+DINO_IMR);
}
-static void dino_enable_irq(unsigned int irq)
+static void dino_unmask_irq(struct irq_data *d)
{
- struct dino_device *dino_dev = irq_desc[irq].chip_data;
- int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS);
+ struct dino_device *dino_dev = irq_data_get_irq_chip_data(d);
+ int local_irq = gsc_find_local_irq(d->irq, dino_dev->global_irq, DINO_LOCAL_IRQS);
u32 tmp;
- DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, dino_dev, irq);
+ DBG(KERN_WARNING "%s(0x%p, %d)\n", __func__, dino_dev, d->irq);
/*
** clear pending IRQ bits
@@ -340,25 +339,15 @@ static void dino_enable_irq(unsigned int irq)
tmp = __raw_readl(dino_dev->hba.base_addr+DINO_ILR);
if (tmp & DINO_MASK_IRQ(local_irq)) {
DBG(KERN_WARNING "%s(): IRQ asserted! (ILR 0x%x)\n",
- __FUNCTION__, tmp);
+ __func__, tmp);
gsc_writel(dino_dev->txn_data, dino_dev->txn_addr);
}
}
-static unsigned int dino_startup_irq(unsigned int irq)
-{
- dino_enable_irq(irq);
- return 0;
-}
-
-static struct hw_interrupt_type dino_interrupt_type = {
- .typename = "GSC-PCI",
- .startup = dino_startup_irq,
- .shutdown = dino_disable_irq,
- .enable = dino_enable_irq,
- .disable = dino_disable_irq,
- .ack = no_ack_irq,
- .end = no_end_irq,
+static struct irq_chip dino_interrupt_type = {
+ .name = "GSC-PCI",
+ .irq_unmask = dino_unmask_irq,
+ .irq_mask = dino_mask_irq,
};
@@ -368,8 +357,7 @@ static struct hw_interrupt_type dino_interrupt_type = {
* ilr_loop counter is a kluge to prevent a "stuck" IRQ line from
* wedging the CPU. Could be removed or made optional at some point.
*/
-static irqreturn_t
-dino_isr(int irq, void *intr_dev, struct pt_regs *regs)
+static irqreturn_t dino_isr(int irq, void *intr_dev)
{
struct dino_device *dino_dev = intr_dev;
u32 mask;
@@ -389,8 +377,8 @@ ilr_again:
int local_irq = __ffs(mask);
int irq = dino_dev->global_irq[local_irq];
DBG(KERN_DEBUG "%s(%d, %p) mask 0x%x\n",
- __FUNCTION__, irq, intr_dev, mask);
- __do_IRQ(irq, regs);
+ __func__, irq, intr_dev, mask);
+ generic_handle_irq(irq);
mask &= ~(1 << local_irq);
} while (mask);
@@ -442,7 +430,7 @@ static void dino_choose_irq(struct parisc_device *dev, void *ctrl)
* Cirrus 6832 Cardbus reports wrong irq on RDI Tadpole PARISC Laptop (deller@gmx.de)
* (the irqs are off-by-one, not sure yet if this is a cirrus, dino-hardware or dino-driver problem...)
*/
-static void __devinit quirk_cirrus_cardbus(struct pci_dev *dev)
+static void quirk_cirrus_cardbus(struct pci_dev *dev)
{
u8 new_irq = dev->irq - 1;
printk(KERN_INFO "PCI: Cirrus Cardbus IRQ fixup for %s, from %d to %d\n",
@@ -478,7 +466,7 @@ dino_card_setup(struct pci_bus *bus, void __iomem *base_addr)
res = &dino_dev->hba.lmmio_space;
res->flags = IORESOURCE_MEM;
size = scnprintf(name, sizeof(name), "Dino LMMIO (%s)",
- bus->bridge->bus_id);
+ dev_name(bus->bridge));
res->name = kmalloc(size+1, GFP_KERNEL);
if(res->name)
strcpy((char *)res->name, name);
@@ -489,15 +477,12 @@ dino_card_setup(struct pci_bus *bus, void __iomem *base_addr)
if (ccio_allocate_resource(dino_dev->hba.dev, res, _8MB,
F_EXTEND(0xf0000000UL) | _8MB,
F_EXTEND(0xffffffffUL) &~ _8MB, _8MB) < 0) {
- struct list_head *ln, *tmp_ln;
+ struct pci_dev *dev, *tmp;
printk(KERN_ERR "Dino: cannot attach bus %s\n",
- bus->bridge->bus_id);
+ dev_name(bus->bridge));
/* 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);
-
- list_del(&dev->global_list);
+ list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) {
list_del(&dev->bus_list);
}
@@ -547,7 +532,7 @@ dino_card_fixup(struct pci_dev *dev)
** The additional "-1" adjusts for skewing the IRQ<->slot.
*/
dino_cfg_read(dev->bus, dev->devfn, PCI_INTERRUPT_PIN, 1, &irq_pin);
- dev->irq = (irq_pin + PCI_SLOT(dev->devfn) - 1) % 4 ;
+ dev->irq = pci_swizzle_interrupt_pin(dev, irq_pin) - 1;
/* Shouldn't really need to do this but it's in case someone tries
** to bypass PCI services and look at the card themselves.
@@ -562,32 +547,17 @@ dino_card_fixup(struct pci_dev *dev)
static void __init
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->bridge));
- int port_base = HBA_PORT_BASE(dino_dev->hba.hba_num);
DBG(KERN_WARNING "%s(0x%p) bus %d platform_data 0x%p\n",
- __FUNCTION__, bus, bus->secondary,
+ __func__, bus, bus->busn_res.start,
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)) {
dino_card_setup(bus, dino_dev->hba.base_addr);
- } 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);
- 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) {
+ } else if (bus->parent) {
int i;
pci_read_bridge_bases(bus);
@@ -610,23 +580,18 @@ dino_fixup_bus(struct pci_bus *bus)
}
- DBG("DEBUG %s assigning %d [0x%lx,0x%lx]\n",
- bus->self->dev.bus_id, i,
- bus->self->resource[i].start,
- bus->self->resource[i].end);
- pci_assign_resource(bus->self, i);
- DBG("DEBUG %s after assign %d [0x%lx,0x%lx]\n",
- bus->self->dev.bus_id, i,
- bus->self->resource[i].start,
- bus->self->resource[i].end);
+ DBG("DEBUG %s assigning %d [%pR]\n",
+ dev_name(&bus->self->dev), i,
+ &bus->self->resource[i]);
+ WARN_ON(pci_assign_resource(bus->self, i));
+ DBG("DEBUG %s after assign %d [%pR]\n",
+ dev_name(&bus->self->dev), i,
+ &bus->self->resource[i]);
}
}
- list_for_each(ln, &bus->devices) {
- int i;
-
- dev = pci_dev_b(ln);
+ list_for_each_entry(dev, &bus->devices, bus_list) {
if (is_card_dino(&dino_dev->hba.dev->id))
dino_card_fixup(dev);
@@ -637,21 +602,6 @@ dino_fixup_bus(struct pci_bus *bus)
if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)
continue;
- /* Adjust the I/O Port space addresses */
- for (i = 0; i < PCI_NUM_RESOURCES; i++) {
- struct resource *res = &dev->resource[i];
- if (res->flags & IORESOURCE_IO) {
- res->start |= port_base;
- res->end |= port_base;
- }
-#ifdef __LP64__
- /* Sign Extend MMIO addresses */
- else if (res->flags & IORESOURCE_MEM) {
- res->start |= F_EXTEND(0UL);
- res->end |= F_EXTEND(0UL);
- }
-#endif
- }
/* null out the ROM resource if there is one (we don't
* care about an expansion rom on parisc, since it
* usually contains (x86) bios code) */
@@ -672,7 +622,7 @@ dino_fixup_bus(struct pci_bus *bus)
dino_cfg_read(dev->bus, dev->devfn,
PCI_INTERRUPT_PIN, 1, &irq_pin);
- irq_pin = (irq_pin + PCI_SLOT(dev->devfn) - 1) % 4 ;
+ irq_pin = pci_swizzle_interrupt_pin(dev, irq_pin) - 1;
printk(KERN_WARNING "Device %s has undefined IRQ, "
"setting to %d\n", pci_name(dev), irq_pin);
dino_cfg_write(dev->bus, dev->devfn,
@@ -690,7 +640,7 @@ dino_fixup_bus(struct pci_bus *bus)
}
-struct pci_bios_ops dino_bios_ops = {
+static struct pci_bios_ops dino_bios_ops = {
.init = dino_bios_init,
.fixup_bus = dino_fixup_bus
};
@@ -819,7 +769,8 @@ dino_bridge_init(struct dino_device *dino_dev, const char *name)
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);
+ printk(KERN_ERR "%s: failed to claim PCI Bus address "
+ "space %d (%pR)!\n", name, i, &res[i]);
return result;
}
}
@@ -899,7 +850,8 @@ static int __init dino_common_init(struct parisc_device *dev,
if (request_resource(&ioport_resource, res) < 0) {
printk(KERN_ERR "%s: request I/O Port region failed "
"0x%lx/%lx (hpa 0x%p)\n",
- name, res->start, res->end, dino_dev->hba.base_addr);
+ name, (unsigned long)res->start, (unsigned long)res->end,
+ dino_dev->hba.base_addr);
return 1;
}
@@ -936,8 +888,10 @@ static int __init dino_probe(struct parisc_device *dev)
const char *version = "unknown";
char *name;
int is_cujo = 0;
+ LIST_HEAD(resources);
struct pci_bus *bus;
unsigned long hpa = dev->hpa.start;
+ int max;
name = "Dino";
if (is_card_dino(&dev->id)) {
@@ -1012,25 +966,45 @@ static int __init dino_probe(struct parisc_device *dev)
dev->dev.platform_data = dino_dev;
+ pci_add_resource_offset(&resources, &dino_dev->hba.io_space,
+ HBA_PORT_BASE(dino_dev->hba.hba_num));
+ if (dino_dev->hba.lmmio_space.flags)
+ pci_add_resource_offset(&resources, &dino_dev->hba.lmmio_space,
+ dino_dev->hba.lmmio_space_offset);
+ if (dino_dev->hba.elmmio_space.flags)
+ pci_add_resource_offset(&resources, &dino_dev->hba.elmmio_space,
+ dino_dev->hba.lmmio_space_offset);
+ if (dino_dev->hba.gmmio_space.flags)
+ pci_add_resource(&resources, &dino_dev->hba.gmmio_space);
+
+ dino_dev->hba.bus_num.start = dino_current_bus;
+ dino_dev->hba.bus_num.end = 255;
+ dino_dev->hba.bus_num.flags = IORESOURCE_BUS;
+ pci_add_resource(&resources, &dino_dev->hba.bus_num);
/*
** It's not used to avoid chicken/egg problems
** with configuration accessor functions.
*/
- bus = pci_scan_bus_parented(&dev->dev, dino_current_bus,
- &dino_cfg_ops, NULL);
- if(bus) {
- pci_bus_add_devices(bus);
- /* This code *depends* on scanning being single threaded
- * if it isn't, this global bus number count will fail
- */
- dino_current_bus = bus->subordinate + 1;
- pci_bus_assign_resources(bus);
- } else {
- printk(KERN_ERR "ERROR: failed to scan PCI bus on %s (probably duplicate bus number %d)\n", dev->dev.bus_id, dino_current_bus);
+ dino_dev->hba.hba_bus = bus = pci_create_root_bus(&dev->dev,
+ dino_current_bus, &dino_cfg_ops, NULL, &resources);
+ if (!bus) {
+ printk(KERN_ERR "ERROR: failed to scan PCI bus on %s (duplicate bus number %d?)\n",
+ dev_name(&dev->dev), dino_current_bus);
+ pci_free_resource_list(&resources);
/* increment the bus number in case of duplicates */
dino_current_bus++;
+ return 0;
}
- dino_dev->hba.hba_bus = bus;
+
+ max = pci_scan_child_bus(bus);
+ pci_bus_update_busn_res_end(bus, max);
+
+ /* This code *depends* on scanning being single threaded
+ * if it isn't, this global bus number count will fail
+ */
+ dino_current_bus = max + 1;
+ pci_bus_assign_resources(bus);
+ pci_bus_add_devices(bus);
return 0;
}
diff --git a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c
index 884965cedec..103095bbe8c 100644
--- a/drivers/parisc/eisa.c
+++ b/drivers/parisc/eisa.c
@@ -33,7 +33,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
-#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/eisa.h>
@@ -145,8 +144,9 @@ static unsigned int eisa_irq_level __read_mostly; /* default to edge triggered *
/* called by free irq */
-static void eisa_disable_irq(unsigned int irq)
+static void eisa_mask_irq(struct irq_data *d)
{
+ unsigned int irq = d->irq;
unsigned long flags;
EISA_DBG("disable irq %d\n", irq);
@@ -165,8 +165,9 @@ static void eisa_disable_irq(unsigned int irq)
}
/* called by request irq */
-static void eisa_enable_irq(unsigned int irq)
+static void eisa_unmask_irq(struct irq_data *d)
{
+ unsigned int irq = d->irq;
unsigned long flags;
EISA_DBG("enable irq %d\n", irq);
@@ -183,23 +184,13 @@ static void eisa_enable_irq(unsigned int irq)
EISA_DBG("pic1 mask %02x\n", eisa_in8(0xa1));
}
-static unsigned int eisa_startup_irq(unsigned int irq)
-{
- eisa_enable_irq(irq);
- return 0;
-}
-
-static struct hw_interrupt_type eisa_interrupt_type = {
- .typename = "EISA",
- .startup = eisa_startup_irq,
- .shutdown = eisa_disable_irq,
- .enable = eisa_enable_irq,
- .disable = eisa_disable_irq,
- .ack = no_ack_irq,
- .end = no_end_irq,
+static struct irq_chip eisa_interrupt_type = {
+ .name = "EISA",
+ .irq_unmask = eisa_unmask_irq,
+ .irq_mask = eisa_mask_irq,
};
-static irqreturn_t eisa_irq(int wax_irq, void *intr_dev, struct pt_regs *regs)
+static irqreturn_t eisa_irq(int wax_irq, void *intr_dev)
{
int irq = gsc_readb(0xfc01f000); /* EISA supports 16 irqs */
unsigned long flags;
@@ -234,7 +225,7 @@ static irqreturn_t eisa_irq(int wax_irq, void *intr_dev, struct pt_regs *regs)
}
spin_unlock_irqrestore(&eisa_irq_lock, flags);
- __do_IRQ(irq, regs);
+ generic_handle_irq(irq);
spin_lock_irqsave(&eisa_irq_lock, flags);
/* unmask */
@@ -249,7 +240,7 @@ static irqreturn_t eisa_irq(int wax_irq, void *intr_dev, struct pt_regs *regs)
return IRQ_HANDLED;
}
-static irqreturn_t dummy_irq2_handler(int _, void *dev, struct pt_regs *regs)
+static irqreturn_t dummy_irq2_handler(int _, void *dev)
{
printk(KERN_ALERT "eisa: uhh, irq2?\n");
return IRQ_HANDLED;
@@ -308,14 +299,14 @@ static void init_eisa_pic(void)
#define is_mongoose(dev) (dev->id.sversion == 0x00076)
-static int __devinit eisa_probe(struct parisc_device *dev)
+static int __init eisa_probe(struct parisc_device *dev)
{
int i, result;
char *name = is_mongoose(dev) ? "Mongoose" : "Wax";
printk(KERN_INFO "%s EISA Adapter found at 0x%08lx\n",
- name, dev->hpa.start);
+ name, (unsigned long)dev->hpa.start);
eisa_dev.hba.dev = dev;
eisa_dev.hba.iommu = ccio_get_iommu(dev);
@@ -347,10 +338,10 @@ static int __devinit eisa_probe(struct parisc_device *dev)
}
/* Reserve IRQ2 */
- irq_desc[2].action = &irq2_action;
-
+ setup_irq(2, &irq2_action);
for (i = 0; i < 16; i++) {
- irq_desc[i].chip = &eisa_interrupt_type;
+ irq_set_chip_and_handler(i, &eisa_interrupt_type,
+ handle_simple_irq);
}
EISA_bus = 1;
@@ -374,7 +365,7 @@ static int __devinit eisa_probe(struct parisc_device *dev)
if (result >= 0) {
/* FIXME : Don't enumerate the bus twice. */
eisa_dev.root.dev = &dev->dev;
- dev->dev.driver_data = &eisa_dev.root;
+ dev_set_drvdata(&dev->dev, &eisa_dev.root);
eisa_dev.root.bus_base_addr = 0;
eisa_dev.root.res = &eisa_dev.hba.io_space;
eisa_dev.root.slots = result;
@@ -388,7 +379,7 @@ static int __devinit eisa_probe(struct parisc_device *dev)
return 0;
}
-static struct parisc_device_id eisa_tbl[] = {
+static const struct parisc_device_id eisa_tbl[] = {
{ HPHW_BA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00076 }, /* Mongoose */
{ HPHW_BA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00090 }, /* Wax EISA */
{ 0, }
diff --git a/drivers/parisc/eisa_eeprom.c b/drivers/parisc/eisa_eeprom.c
index e13aafa70bf..783906fe659 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,
@@ -54,7 +43,7 @@ static ssize_t eisa_eeprom_read(struct file * file,
ssize_t ret;
int i;
- if (*ppos >= HPEE_MAX_LENGTH)
+ if (*ppos < 0 || *ppos >= HPEE_MAX_LENGTH)
return 0;
count = *ppos + count < HPEE_MAX_LENGTH ? count : HPEE_MAX_LENGTH - *ppos;
@@ -74,16 +63,9 @@ static ssize_t eisa_eeprom_read(struct file * file,
return ret;
}
-static int eisa_eeprom_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd,
- unsigned long arg)
-{
- return -ENOTTY;
-}
-
static int eisa_eeprom_open(struct inode *inode, struct file *file)
{
- if (file->f_mode & 2)
+ if (file->f_mode & FMODE_WRITE)
return -EINVAL;
return 0;
@@ -97,11 +79,10 @@ static int eisa_eeprom_release(struct inode *inode, struct file *file)
/*
* The various file operations we support.
*/
-static struct file_operations eisa_eeprom_fops = {
+static const struct file_operations eisa_eeprom_fops = {
.owner = THIS_MODULE,
.llseek = eisa_eeprom_llseek,
.read = eisa_eeprom_read,
- .ioctl = eisa_eeprom_ioctl,
.open = eisa_eeprom_open,
.release = eisa_eeprom_release,
};
diff --git a/drivers/parisc/eisa_enumerator.c b/drivers/parisc/eisa_enumerator.c
index 6d8aae003f6..caa15313375 100644
--- a/drivers/parisc/eisa_enumerator.c
+++ b/drivers/parisc/eisa_enumerator.c
@@ -98,10 +98,10 @@ static int configure_memory(const unsigned char *buf,
res->start = mem_parent->start + get_24(buf+len+2);
res->end = res->start + get_16(buf+len+5)*1024;
res->flags = IORESOURCE_MEM;
- printk("memory %lx-%lx ", res->start, res->end);
+ printk("memory %lx-%lx ", (unsigned long)res->start, (unsigned long)res->end);
result = request_resource(mem_parent, res);
if (result < 0) {
- printk("\n" KERN_ERR "EISA Enumerator: failed to claim EISA Bus address space!\n");
+ printk(KERN_ERR "EISA Enumerator: failed to claim EISA Bus address space!\n");
return result;
}
}
@@ -188,10 +188,10 @@ static int configure_port(const unsigned char *buf, struct resource *io_parent,
res->start = get_16(buf+len+1);
res->end = get_16(buf+len+1)+(c&HPEE_PORT_SIZE_MASK)+1;
res->flags = IORESOURCE_IO;
- printk("ioports %lx-%lx ", res->start, res->end);
+ printk("ioports %lx-%lx ", (unsigned long)res->start, (unsigned long)res->end);
result = request_resource(io_parent, res);
if (result < 0) {
- printk("\n" KERN_ERR "EISA Enumerator: failed to claim EISA Bus address space!\n");
+ printk(KERN_ERR "EISA Enumerator: failed to claim EISA Bus address space!\n");
return result;
}
}
@@ -224,7 +224,7 @@ static int configure_port_init(const unsigned char *buf)
case HPEE_PORT_INIT_WIDTH_BYTE:
s=1;
if (c & HPEE_PORT_INIT_MASK) {
- printk("\n" KERN_WARNING "port_init: unverified mask attribute\n");
+ printk(KERN_WARNING "port_init: unverified mask attribute\n");
outb((inb(get_16(buf+len+1) &
get_8(buf+len+3)) |
get_8(buf+len+4)), get_16(buf+len+1));
@@ -249,7 +249,7 @@ static int configure_port_init(const unsigned char *buf)
case HPEE_PORT_INIT_WIDTH_DWORD:
s=4;
if (c & HPEE_PORT_INIT_MASK) {
- printk("\n" KERN_WARNING "port_init: unverified mask attribute\n");
+ printk(KERN_WARNING "port_init: unverified mask attribute\n");
outl((inl(get_16(buf+len+1) &
get_32(buf+len+3)) |
get_32(buf+len+7)), get_16(buf+len+1));
@@ -259,7 +259,7 @@ static int configure_port_init(const unsigned char *buf)
break;
default:
- printk("\n" KERN_ERR "Invalid port init word %02x\n", c);
+ printk(KERN_ERR "Invalid port init word %02x\n", c);
return 0;
}
@@ -297,7 +297,7 @@ static int configure_type_string(const unsigned char *buf)
/* just skip past the type field */
len = get_8(buf);
if (len > 80) {
- printk("\n" KERN_ERR "eisa_enumerator: type info field too long (%d, max is 80)\n", len);
+ printk(KERN_ERR "eisa_enumerator: type info field too long (%d, max is 80)\n", len);
}
return 1+len;
@@ -398,7 +398,7 @@ static int parse_slot_config(int slot,
}
if (p0 + function_len < pos) {
- printk("\n" KERN_ERR "eisa_enumerator: function %d length mis-match "
+ printk(KERN_ERR "eisa_enumerator: function %d length mis-match "
"got %d, expected %d\n",
num_func, pos-p0, function_len);
res=-1;
@@ -460,7 +460,7 @@ static int init_slot(int slot, struct eeprom_eisa_slot_info *es)
slot, id_string);
print_eisa_id(id_string, es->eisa_slot_id);
- printk(" expected %s \n", id_string);
+ printk(" expected %s\n", id_string);
return -1;
diff --git a/drivers/parisc/gsc.c b/drivers/parisc/gsc.c
index b45aa5c675a..1bab5a2cd35 100644
--- a/drivers/parisc/gsc.c
+++ b/drivers/parisc/gsc.c
@@ -19,7 +19,6 @@
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/module.h>
-#include <linux/slab.h>
#include <linux/types.h>
#include <asm/hardware.h>
@@ -73,7 +72,7 @@ EXPORT_SYMBOL(gsc_alloc_irq);
EXPORT_SYMBOL(gsc_claim_irq);
/* Common interrupt demultiplexer used by Asp, Lasi & Wax. */
-irqreturn_t gsc_asic_intr(int gsc_asic_irq, void *dev, struct pt_regs *regs)
+irqreturn_t gsc_asic_intr(int gsc_asic_irq, void *dev)
{
unsigned long irr;
struct gsc_asic *gsc_asic = dev;
@@ -87,7 +86,7 @@ irqreturn_t gsc_asic_intr(int gsc_asic_irq, void *dev, struct pt_regs *regs)
do {
int local_irq = __ffs(irr);
unsigned int irq = gsc_asic->global_irq[local_irq];
- __do_IRQ(irq, regs);
+ generic_handle_irq(irq);
irr &= ~(1 << local_irq);
} while (irr);
@@ -106,13 +105,13 @@ int gsc_find_local_irq(unsigned int irq, int *global_irqs, int limit)
return NO_IRQ;
}
-static void gsc_asic_disable_irq(unsigned int irq)
+static void gsc_asic_mask_irq(struct irq_data *d)
{
- struct gsc_asic *irq_dev = irq_desc[irq].chip_data;
- int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32);
+ struct gsc_asic *irq_dev = irq_data_get_irq_chip_data(d);
+ int local_irq = gsc_find_local_irq(d->irq, irq_dev->global_irq, 32);
u32 imr;
- DEBPRINTK(KERN_DEBUG "%s(%d) %s: IMR 0x%x\n", __FUNCTION__, irq,
+ DEBPRINTK(KERN_DEBUG "%s(%d) %s: IMR 0x%x\n", __func__, d->irq,
irq_dev->name, imr);
/* Disable the IRQ line by clearing the bit in the IMR */
@@ -121,13 +120,13 @@ static void gsc_asic_disable_irq(unsigned int irq)
gsc_writel(imr, irq_dev->hpa + OFFSET_IMR);
}
-static void gsc_asic_enable_irq(unsigned int irq)
+static void gsc_asic_unmask_irq(struct irq_data *d)
{
- struct gsc_asic *irq_dev = irq_desc[irq].chip_data;
- int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32);
+ struct gsc_asic *irq_dev = irq_data_get_irq_chip_data(d);
+ int local_irq = gsc_find_local_irq(d->irq, irq_dev->global_irq, 32);
u32 imr;
- DEBPRINTK(KERN_DEBUG "%s(%d) %s: IMR 0x%x\n", __FUNCTION__, irq,
+ DEBPRINTK(KERN_DEBUG "%s(%d) %s: IMR 0x%x\n", __func__, d->irq,
irq_dev->name, imr);
/* Enable the IRQ line by setting the bit in the IMR */
@@ -140,31 +139,22 @@ static void gsc_asic_enable_irq(unsigned int irq)
*/
}
-static unsigned int gsc_asic_startup_irq(unsigned int irq)
-{
- gsc_asic_enable_irq(irq);
- return 0;
-}
-
-static struct hw_interrupt_type gsc_asic_interrupt_type = {
- .typename = "GSC-ASIC",
- .startup = gsc_asic_startup_irq,
- .shutdown = gsc_asic_disable_irq,
- .enable = gsc_asic_enable_irq,
- .disable = gsc_asic_disable_irq,
- .ack = no_ack_irq,
- .end = no_end_irq,
+static struct irq_chip gsc_asic_interrupt_type = {
+ .name = "GSC-ASIC",
+ .irq_unmask = gsc_asic_unmask_irq,
+ .irq_mask = gsc_asic_mask_irq,
};
-int gsc_assign_irq(struct hw_interrupt_type *type, void *data)
+int gsc_assign_irq(struct irq_chip *type, void *data)
{
static int irq = GSC_IRQ_BASE;
if (irq > GSC_IRQ_MAX)
return NO_IRQ;
- irq_desc[irq].chip = type;
- irq_desc[irq].chip_data = data;
+ irq_set_chip_and_handler(irq, type, handle_simple_irq);
+ irq_set_chip_data(irq, data);
+
return irq++;
}
@@ -182,29 +172,34 @@ void gsc_asic_assign_irq(struct gsc_asic *asic, int local_irq, int *irqp)
*irqp = irq;
}
-static struct device *next_device(struct klist_iter *i)
+struct gsc_fixup_struct {
+ void (*choose_irq)(struct parisc_device *, void *);
+ void *ctrl;
+};
+
+static int gsc_fixup_irqs_callback(struct device *dev, void *data)
{
- struct klist_node * n = klist_next(i);
- return n ? container_of(n, struct device, knode_parent) : NULL;
+ struct parisc_device *padev = to_parisc_device(dev);
+ struct gsc_fixup_struct *gf = data;
+
+ /* work-around for 715/64 and others which have parent
+ at path [5] and children at path [5/0/x] */
+ if (padev->id.hw_type == HPHW_FAULTY)
+ gsc_fixup_irqs(padev, gf->ctrl, gf->choose_irq);
+ gf->choose_irq(padev, gf->ctrl);
+
+ return 0;
}
void gsc_fixup_irqs(struct parisc_device *parent, void *ctrl,
void (*choose_irq)(struct parisc_device *, void *))
{
- struct device *dev;
- struct klist_iter i;
-
- klist_iter_init(&parent->dev.klist_children, &i);
- while ((dev = next_device(&i))) {
- struct parisc_device *padev = to_parisc_device(dev);
-
- /* work-around for 715/64 and others which have parent
- at path [5] and children at path [5/0/x] */
- if (padev->id.hw_type == HPHW_FAULTY)
- return gsc_fixup_irqs(padev, ctrl, choose_irq);
- choose_irq(padev, ctrl);
- }
- klist_iter_exit(&i);
+ struct gsc_fixup_struct data = {
+ .choose_irq = choose_irq,
+ .ctrl = ctrl,
+ };
+
+ device_for_each_child(&parent->dev, &data, gsc_fixup_irqs_callback);
}
int gsc_common_setup(struct parisc_device *parent, struct gsc_asic *gsc_asic)
diff --git a/drivers/parisc/gsc.h b/drivers/parisc/gsc.h
index a3dc456709d..b9d7bfb68e2 100644
--- a/drivers/parisc/gsc.h
+++ b/drivers/parisc/gsc.h
@@ -38,10 +38,10 @@ struct gsc_asic {
int gsc_common_setup(struct parisc_device *parent, struct gsc_asic *gsc_asic);
int gsc_alloc_irq(struct gsc_irq *dev); /* dev needs an irq */
int gsc_claim_irq(struct gsc_irq *dev, int irq); /* dev needs this irq */
-int gsc_assign_irq(struct hw_interrupt_type *type, void *data);
+int gsc_assign_irq(struct irq_chip *type, void *data);
int gsc_find_local_irq(unsigned int irq, int *global_irq, int limit);
void gsc_fixup_irqs(struct parisc_device *parent, void *ctrl,
void (*choose)(struct parisc_device *child, void *ctrl));
void gsc_asic_assign_irq(struct gsc_asic *asic, int local_irq, int *irqp);
-irqreturn_t gsc_asic_intr(int irq, void *dev, struct pt_regs *regs);
+irqreturn_t gsc_asic_intr(int irq, void *dev);
diff --git a/drivers/parisc/hppb.c b/drivers/parisc/hppb.c
index 07dc2b6d4e9..898208e4f30 100644
--- a/drivers/parisc/hppb.c
+++ b/drivers/parisc/hppb.c
@@ -10,31 +10,26 @@
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
-** This Driver currently only supports the console (port 0) on the MUX.
-** Additional work will be needed on this driver to enable the full
-** functionality of the MUX.
-**
*/
#include <linux/types.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/slab.h>
+#include <linux/dma-mapping.h>
#include <linux/ioport.h>
#include <asm/io.h>
#include <asm/hardware.h>
#include <asm/parisc-device.h>
-#include <linux/pci.h>
-
struct hppb_card {
unsigned long hpa;
struct resource mmio_region;
struct hppb_card *next;
};
-struct hppb_card hppb_card_head = {
+static struct hppb_card hppb_card_head = {
.hpa = 0,
.next = NULL,
};
@@ -67,7 +62,8 @@ static int hppb_probe(struct parisc_device *dev)
}
card = card->next;
}
- printk(KERN_INFO "Found GeckoBoa at 0x%lx\n", dev->hpa.start);
+ printk(KERN_INFO "Found GeckoBoa at 0x%llx\n",
+ (unsigned long long) dev->hpa.start);
card->hpa = dev->hpa.start;
card->mmio_region.name = "HP-PB Bus";
@@ -78,16 +74,18 @@ static int hppb_probe(struct parisc_device *dev)
status = ccio_request_resource(dev, &card->mmio_region);
if(status < 0) {
- printk(KERN_ERR "%s: failed to claim HP-PB bus space (%08lx, %08lx)\n",
- __FILE__, card->mmio_region.start, card->mmio_region.end);
+ printk(KERN_ERR "%s: failed to claim HP-PB bus space (%pR)\n",
+ __FILE__, &card->mmio_region);
}
return 0;
}
-
static struct parisc_device_id hppb_tbl[] = {
- { HPHW_BCPORT, HVERSION_REV_ANY_ID, 0x500, 0xc },
+ { HPHW_BCPORT, HVERSION_REV_ANY_ID, 0x500, 0xc }, /* E25 and K */
+ { HPHW_BCPORT, 0x0, 0x501, 0xc }, /* E35 */
+ { HPHW_BCPORT, 0x0, 0x502, 0xc }, /* E45 */
+ { HPHW_BCPORT, 0x0, 0x503, 0xc }, /* E55 */
{ 0, }
};
@@ -98,7 +96,7 @@ static struct parisc_driver hppb_driver = {
};
/**
- * hppb_init - HP-PB bus initalization procedure.
+ * hppb_init - HP-PB bus initialization procedure.
*
* Register this driver.
*/
diff --git a/drivers/parisc/iommu-helpers.h b/drivers/parisc/iommu-helpers.h
index 38d9e1aba1d..8c33491b21f 100644
--- a/drivers/parisc/iommu-helpers.h
+++ b/drivers/parisc/iommu-helpers.h
@@ -1,3 +1,5 @@
+#include <linux/prefetch.h>
+
/**
* iommu_fill_pdir - Insert coalesced scatter/gather chunks into the I/O Pdir.
* @ioc: The I/O Controller.
@@ -95,12 +97,14 @@ iommu_fill_pdir(struct ioc *ioc, struct scatterlist *startsg, int nents,
*/
static inline unsigned int
-iommu_coalesce_chunks(struct ioc *ioc, struct scatterlist *startsg, int nents,
- int (*iommu_alloc_range)(struct ioc *, size_t))
+iommu_coalesce_chunks(struct ioc *ioc, struct device *dev,
+ struct scatterlist *startsg, int nents,
+ int (*iommu_alloc_range)(struct ioc *, struct device *, size_t))
{
struct scatterlist *contig_sg; /* contig chunk head */
unsigned long dma_offset, dma_len; /* start/len of DMA stream */
unsigned int n_mappings = 0;
+ unsigned int max_seg_size = dma_get_max_seg_size(dev);
while (nents > 0) {
@@ -138,10 +142,13 @@ iommu_coalesce_chunks(struct ioc *ioc, struct scatterlist *startsg, int nents,
** exceed DMA_CHUNK_SIZE if we coalesce the
** next entry.
*/
- if(unlikely(ROUNDUP(dma_len + dma_offset + startsg->length,
+ if(unlikely(ALIGN(dma_len + dma_offset + startsg->length,
IOVP_SIZE) > DMA_CHUNK_SIZE))
break;
+ if (startsg->length + dma_len > max_seg_size)
+ break;
+
/*
** Next see if we can append the next chunk (i.e.
** it must end on one page and begin on another
@@ -158,10 +165,10 @@ iommu_coalesce_chunks(struct ioc *ioc, struct scatterlist *startsg, int nents,
** Allocate space for DMA stream.
*/
sg_dma_len(contig_sg) = dma_len;
- dma_len = ROUNDUP(dma_len + dma_offset, IOVP_SIZE);
+ dma_len = ALIGN(dma_len + dma_offset, IOVP_SIZE);
sg_dma_address(contig_sg) =
PIDE_FLAG
- | (iommu_alloc_range(ioc, dma_len) << IOVP_SHIFT)
+ | (iommu_alloc_range(ioc, dev, dma_len) << IOVP_SHIFT)
| dma_offset;
n_mappings++;
}
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
index 1fbda77cefc..9ee04b4b68b 100644
--- a/drivers/parisc/iosapic.c
+++ b/drivers/parisc/iosapic.c
@@ -50,12 +50,12 @@
**
** PA Firmware
** -----------
-** PA-RISC platforms have two fundementally different types of firmware.
+** PA-RISC platforms have two fundamentally different types of firmware.
** For PCI devices, "Legacy" PDC initializes the "INTERRUPT_LINE" register
** and BARs similar to a traditional PC BIOS.
** The newer "PAT" firmware supports PDC calls which return tables.
-** PAT firmware only initializes PCI Console and Boot interface.
-** With these tables, the OS can progam all other PCI devices.
+** PAT firmware only initializes the PCI Console and Boot interface.
+** With these tables, the OS can program all other PCI devices.
**
** One such PAT PDC call returns the "Interrupt Routing Table" (IRT).
** The IRT maps each PCI slot's INTA-D "output" line to an I/O SAPIC
@@ -140,14 +140,13 @@
#include <asm/pdc.h>
#include <asm/pdcpat.h>
#include <asm/page.h>
-#include <asm/system.h>
#include <asm/io.h> /* read/write functions */
#ifdef CONFIG_SUPERIO
#include <asm/superio.h>
#endif
-#include <asm/iosapic.h>
-#include "./iosapic_private.h"
+#include <asm/ropes.h>
+#include "iosapic_private.h"
#define MODULE_NAME "iosapic"
@@ -487,7 +486,7 @@ iosapic_xlate_pin(struct iosapic_info *isi, struct pci_dev *pcidev)
}
/* Check if pcidev behind a PPB */
- if (NULL != pcidev->bus->self) {
+ if (pcidev->bus->parent) {
/* Convert pcidev INTR_PIN into something we
** can lookup in the IRT.
*/
@@ -519,15 +518,13 @@ iosapic_xlate_pin(struct iosapic_info *isi, struct pci_dev *pcidev)
**
** Advantage is it's really easy to implement.
*/
- intr_pin = ((intr_pin-1)+PCI_SLOT(pcidev->devfn)) % 4;
- intr_pin++; /* convert back to INTA-D (1-4) */
+ intr_pin = pci_swizzle_interrupt_pin(pcidev, intr_pin);
#endif /* PCI_BRIDGE_FUNCS */
/*
- ** Locate the host slot the PPB nearest the Host bus
- ** adapter.
- */
- while (NULL != p->parent->self)
+ * Locate the host slot of the PPB.
+ */
+ while (p->parent->parent)
p = p->parent;
intr_slot = PCI_SLOT(p->self->devfn);
@@ -535,7 +532,7 @@ iosapic_xlate_pin(struct iosapic_info *isi, struct pci_dev *pcidev)
intr_slot = PCI_SLOT(pcidev->devfn);
}
DBG_IRT("iosapic_xlate_pin: bus %d slot %d pin %d\n",
- pcidev->bus->secondary, intr_slot, intr_pin);
+ pcidev->bus->busn_res.start, intr_slot, intr_pin);
return irt_find_irqline(isi, intr_slot, intr_pin);
}
@@ -617,15 +614,10 @@ iosapic_set_irt_data( struct vector_info *vi, u32 *dp0, u32 *dp1)
}
-static struct vector_info *iosapic_get_vector(unsigned int irq)
-{
- return irq_desc[irq].chip_data;
-}
-
-static void iosapic_disable_irq(unsigned int irq)
+static void iosapic_mask_irq(struct irq_data *d)
{
unsigned long flags;
- struct vector_info *vi = iosapic_get_vector(irq);
+ struct vector_info *vi = irq_data_get_irq_chip_data(d);
u32 d0, d1;
spin_lock_irqsave(&iosapic_lock, flags);
@@ -635,9 +627,9 @@ static void iosapic_disable_irq(unsigned int irq)
spin_unlock_irqrestore(&iosapic_lock, flags);
}
-static void iosapic_enable_irq(unsigned int irq)
+static void iosapic_unmask_irq(struct irq_data *d)
{
- struct vector_info *vi = iosapic_get_vector(irq);
+ struct vector_info *vi = irq_data_get_irq_chip_data(d);
u32 d0, d1;
/* data is initialized by fixup_irq */
@@ -673,44 +665,34 @@ printk("\n");
* enables their IRQ. It can lead to "interesting" race conditions
* in the driver initialization sequence.
*/
- DBG(KERN_DEBUG "enable_irq(%d): eoi(%p, 0x%x)\n", irq,
+ DBG(KERN_DEBUG "enable_irq(%d): eoi(%p, 0x%x)\n", d->irq,
vi->eoi_addr, vi->eoi_data);
iosapic_eoi(vi->eoi_addr, vi->eoi_data);
}
-/*
- * PARISC only supports PCI devices below I/O SAPIC.
- * PCI only supports level triggered in order to share IRQ lines.
- * ergo I/O SAPIC must always issue EOI on parisc.
- *
- * i386/ia64 support ISA devices and have to deal with
- * edge-triggered interrupts too.
- */
-static void iosapic_end_irq(unsigned int irq)
+static void iosapic_eoi_irq(struct irq_data *d)
{
- struct vector_info *vi = iosapic_get_vector(irq);
- DBG(KERN_DEBUG "end_irq(%d): eoi(%p, 0x%x)\n", irq,
- vi->eoi_addr, vi->eoi_data);
- iosapic_eoi(vi->eoi_addr, vi->eoi_data);
-}
+ struct vector_info *vi = irq_data_get_irq_chip_data(d);
-static unsigned int iosapic_startup_irq(unsigned int irq)
-{
- iosapic_enable_irq(irq);
- return 0;
+ iosapic_eoi(vi->eoi_addr, vi->eoi_data);
+ cpu_eoi_irq(d);
}
#ifdef CONFIG_SMP
-static void iosapic_set_affinity_irq(unsigned int irq, cpumask_t dest)
+static int iosapic_set_affinity_irq(struct irq_data *d,
+ const struct cpumask *dest, bool force)
{
- struct vector_info *vi = iosapic_get_vector(irq);
+ struct vector_info *vi = irq_data_get_irq_chip_data(d);
u32 d0, d1, dummy_d0;
unsigned long flags;
+ int dest_cpu;
- if (cpu_check_affinity(irq, &dest))
- return;
+ dest_cpu = cpu_check_affinity(d, dest);
+ if (dest_cpu < 0)
+ return -1;
- vi->txn_addr = txn_affinity_addr(irq, first_cpu(dest));
+ cpumask_copy(d->affinity, cpumask_of(dest_cpu));
+ vi->txn_addr = txn_affinity_addr(d->irq, dest_cpu);
spin_lock_irqsave(&iosapic_lock, flags);
/* d1 contains the destination CPU, so only want to set that
@@ -719,19 +701,19 @@ static void iosapic_set_affinity_irq(unsigned int irq, cpumask_t dest)
iosapic_set_irt_data(vi, &dummy_d0, &d1);
iosapic_wr_irt_entry(vi, d0, d1);
spin_unlock_irqrestore(&iosapic_lock, flags);
+
+ return 0;
}
#endif
-static struct hw_interrupt_type iosapic_interrupt_type = {
- .typename = "IO-SAPIC-level",
- .startup = iosapic_startup_irq,
- .shutdown = iosapic_disable_irq,
- .enable = iosapic_enable_irq,
- .disable = iosapic_disable_irq,
- .ack = no_ack_irq,
- .end = iosapic_end_irq,
+static struct irq_chip iosapic_interrupt_type = {
+ .name = "IO-SAPIC-level",
+ .irq_unmask = iosapic_unmask_irq,
+ .irq_mask = iosapic_mask_irq,
+ .irq_ack = cpu_ack_irq,
+ .irq_eoi = iosapic_eoi_irq,
#ifdef CONFIG_SMP
- .set_affinity = iosapic_set_affinity_irq,
+ .irq_set_affinity = iosapic_set_affinity_irq,
#endif
};
@@ -829,6 +811,86 @@ int iosapic_fixup_irq(void *isi_obj, struct pci_dev *pcidev)
return pcidev->irq;
}
+static struct iosapic_info *iosapic_list;
+
+#ifdef CONFIG_64BIT
+int iosapic_serial_irq(struct parisc_device *dev)
+{
+ struct iosapic_info *isi;
+ struct irt_entry *irte;
+ struct vector_info *vi;
+ int cnt;
+ int intin;
+
+ intin = (dev->mod_info >> 24) & 15;
+
+ /* lookup IRT entry for isi/slot/pin set */
+ for (cnt = 0; cnt < irt_num_entry; cnt++) {
+ irte = &irt_cell[cnt];
+ if (COMPARE_IRTE_ADDR(irte, dev->mod0) &&
+ irte->dest_iosapic_intin == intin)
+ break;
+ }
+ if (cnt >= irt_num_entry)
+ return 0; /* no irq found, force polling */
+
+ DBG_IRT("iosapic_serial_irq(): irte %p %x %x %x %x %x %x %x %x\n",
+ irte,
+ irte->entry_type,
+ irte->entry_length,
+ irte->polarity_trigger,
+ irte->src_bus_irq_devno,
+ irte->src_bus_id,
+ irte->src_seg_id,
+ irte->dest_iosapic_intin,
+ (u32) irte->dest_iosapic_addr);
+
+ /* search for iosapic */
+ for (isi = iosapic_list; isi; isi = isi->isi_next)
+ if (isi->isi_hpa == dev->mod0)
+ break;
+ if (!isi)
+ return 0; /* no iosapic found, force polling */
+
+ /* get vector info for this input line */
+ vi = isi->isi_vector + intin;
+ DBG_IRT("iosapic_serial_irq: line %d vi 0x%p\n", iosapic_intin, vi);
+
+ /* If this IRQ line has already been setup, skip it */
+ if (vi->irte)
+ goto out;
+
+ vi->irte = irte;
+
+ /*
+ * Allocate processor IRQ
+ *
+ * XXX/FIXME The txn_alloc_irq() code and related code should be
+ * moved to enable_irq(). That way we only allocate processor IRQ
+ * bits for devices that actually have drivers claiming them.
+ * Right now we assign an IRQ to every PCI device present,
+ * regardless of whether it's used or not.
+ */
+ vi->txn_irq = txn_alloc_irq(8);
+
+ if (vi->txn_irq < 0)
+ panic("I/O sapic: couldn't get TXN IRQ\n");
+
+ /* enable_irq() will use txn_* to program IRdT */
+ vi->txn_addr = txn_alloc_addr(vi->txn_irq);
+ vi->txn_data = txn_alloc_data(vi->txn_irq);
+
+ vi->eoi_addr = isi->addr + IOSAPIC_REG_EOI;
+ vi->eoi_data = cpu_to_le32(vi->txn_data);
+
+ cpu_claim_irq(vi->txn_irq, &iosapic_interrupt_type, vi);
+
+ out:
+
+ return vi->txn_irq;
+}
+#endif
+
/*
** squirrel away the I/O Sapic Version
@@ -873,7 +935,7 @@ void *iosapic_register(unsigned long hpa)
return NULL;
}
- isi = (struct iosapic_info *)kzalloc(sizeof(struct iosapic_info), GFP_KERNEL);
+ isi = kzalloc(sizeof(struct iosapic_info), GFP_KERNEL);
if (!isi) {
BUG();
return NULL;
@@ -884,8 +946,8 @@ void *iosapic_register(unsigned long hpa)
isi->isi_version = iosapic_rd_version(isi);
isi->isi_num_vectors = IOSAPIC_IRDT_MAX_ENTRY(isi->isi_version) + 1;
- vip = isi->isi_vector = (struct vector_info *)
- kzalloc(sizeof(struct vector_info) * isi->isi_num_vectors, GFP_KERNEL);
+ vip = isi->isi_vector = kcalloc(isi->isi_num_vectors,
+ sizeof(struct vector_info), GFP_KERNEL);
if (vip == NULL) {
kfree(isi);
return NULL;
@@ -895,6 +957,8 @@ void *iosapic_register(unsigned long hpa)
vip->irqline = (unsigned char) cnt;
vip->iosapic = isi;
}
+ isi->isi_next = iosapic_list;
+ iosapic_list = isi;
return isi;
}
diff --git a/drivers/parisc/iosapic_private.h b/drivers/parisc/iosapic_private.h
index 41e7ec2a44a..6e05e30a245 100644
--- a/drivers/parisc/iosapic_private.h
+++ b/drivers/parisc/iosapic_private.h
@@ -132,7 +132,7 @@ struct iosapic_irt {
struct vector_info {
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 __iomem *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 */
diff --git a/drivers/parisc/lasi.c b/drivers/parisc/lasi.c
index cb3d2817612..e65727ca9fc 100644
--- a/drivers/parisc/lasi.c
+++ b/drivers/parisc/lasi.c
@@ -107,7 +107,7 @@ lasi_init_irq(struct gsc_asic *this_lasi)
#else
-void __init lasi_led_init(unsigned long lasi_hpa)
+static void __init lasi_led_init(unsigned long lasi_hpa)
{
unsigned long datareg;
@@ -163,8 +163,7 @@ static void lasi_power_off(void)
gsc_writel(0x02, datareg);
}
-int __init
-lasi_init_chip(struct parisc_device *dev)
+static int __init lasi_init_chip(struct parisc_device *dev)
{
extern void (*chassis_power_off)(void);
struct gsc_asic *lasi;
@@ -193,7 +192,7 @@ lasi_init_chip(struct parisc_device *dev)
dev->irq = gsc_alloc_irq(&gsc_irq);
if (dev->irq < 0) {
printk(KERN_ERR "%s(): cannot get GSC irq\n",
- __FUNCTION__);
+ __func__);
kfree(lasi);
return -EBUSY;
}
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
index 3fe4a77fa16..37e71ff6408 100644
--- a/drivers/parisc/lba_pci.c
+++ b/drivers/parisc/lba_pci.c
@@ -34,21 +34,19 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/spinlock.h>
-#include <linux/init.h> /* for __init and __devinit */
+#include <linux/init.h> /* for __init */
#include <linux/pci.h>
#include <linux/ioport.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <asm/byteorder.h>
#include <asm/pdc.h>
#include <asm/pdcpat.h>
#include <asm/page.h>
-#include <asm/system.h>
+#include <asm/ropes.h>
#include <asm/hardware.h> /* for register_parisc_driver() stuff */
#include <asm/parisc-device.h>
-#include <asm/iosapic.h> /* for iosapic_register() */
#include <asm/io.h> /* read/write stuff */
#undef DEBUG_LBA /* general stuff */
@@ -100,113 +98,10 @@
#define MODULE_NAME "LBA"
-#define LBA_FUNC_ID 0x0000 /* function id */
-#define LBA_FCLASS 0x0008 /* function class, bist, header, rev... */
-#define LBA_CAPABLE 0x0030 /* capabilities register */
-
-#define LBA_PCI_CFG_ADDR 0x0040 /* poke CFG address here */
-#define LBA_PCI_CFG_DATA 0x0048 /* read or write data here */
-
-#define LBA_PMC_MTLT 0x0050 /* Firmware sets this - read only. */
-#define LBA_FW_SCRATCH 0x0058 /* Firmware writes the PCI bus number here. */
-#define LBA_ERROR_ADDR 0x0070 /* On error, address gets logged here */
-
-#define LBA_ARB_MASK 0x0080 /* bit 0 enable arbitration. PAT/PDC enables */
-#define LBA_ARB_PRI 0x0088 /* firmware sets this. */
-#define LBA_ARB_MODE 0x0090 /* firmware sets this. */
-#define LBA_ARB_MTLT 0x0098 /* firmware sets this. */
-
-#define LBA_MOD_ID 0x0100 /* Module ID. PDC_PAT_CELL reports 4 */
-
-#define LBA_STAT_CTL 0x0108 /* Status & Control */
-#define LBA_BUS_RESET 0x01 /* Deassert PCI Bus Reset Signal */
-#define CLEAR_ERRLOG 0x10 /* "Clear Error Log" cmd */
-#define CLEAR_ERRLOG_ENABLE 0x20 /* "Clear Error Log" Enable */
-#define HF_ENABLE 0x40 /* enable HF mode (default is -1 mode) */
-
-#define LBA_LMMIO_BASE 0x0200 /* < 4GB I/O address range */
-#define LBA_LMMIO_MASK 0x0208
-
-#define LBA_GMMIO_BASE 0x0210 /* > 4GB I/O address range */
-#define LBA_GMMIO_MASK 0x0218
-
-#define LBA_WLMMIO_BASE 0x0220 /* All < 4GB ranges under the same *SBA* */
-#define LBA_WLMMIO_MASK 0x0228
-
-#define LBA_WGMMIO_BASE 0x0230 /* All > 4GB ranges under the same *SBA* */
-#define LBA_WGMMIO_MASK 0x0238
-
-#define LBA_IOS_BASE 0x0240 /* I/O port space for this LBA */
-#define LBA_IOS_MASK 0x0248
-
-#define LBA_ELMMIO_BASE 0x0250 /* Extra LMMIO range */
-#define LBA_ELMMIO_MASK 0x0258
-
-#define LBA_EIOS_BASE 0x0260 /* Extra I/O port space */
-#define LBA_EIOS_MASK 0x0268
-
-#define LBA_GLOBAL_MASK 0x0270 /* Mercury only: Global Address Mask */
-#define LBA_DMA_CTL 0x0278 /* firmware sets this */
-
-#define LBA_IBASE 0x0300 /* SBA DMA support */
-#define LBA_IMASK 0x0308
-
-/* FIXME: ignore DMA Hint stuff until we can measure performance */
-#define LBA_HINT_CFG 0x0310
-#define LBA_HINT_BASE 0x0380 /* 14 registers at every 8 bytes. */
-
-#define LBA_BUS_MODE 0x0620
-
-/* ERROR regs are needed for config cycle kluges */
-#define LBA_ERROR_CONFIG 0x0680
-#define LBA_SMART_MODE 0x20
-#define LBA_ERROR_STATUS 0x0688
-#define LBA_ROPE_CTL 0x06A0
-
-#define LBA_IOSAPIC_BASE 0x800 /* Offset of IRQ logic */
-
/* non-postable I/O port space, densely packed */
#define LBA_PORT_BASE (PCI_F_EXTEND | 0xfee00000UL)
static void __iomem *astro_iop_base __read_mostly;
-#define ELROY_HVERS 0x782
-#define MERCURY_HVERS 0x783
-#define QUICKSILVER_HVERS 0x784
-
-static inline int IS_ELROY(struct parisc_device *d)
-{
- return (d->id.hversion == ELROY_HVERS);
-}
-
-static inline int IS_MERCURY(struct parisc_device *d)
-{
- return (d->id.hversion == MERCURY_HVERS);
-}
-
-static inline int IS_QUICKSILVER(struct parisc_device *d)
-{
- return (d->id.hversion == QUICKSILVER_HVERS);
-}
-
-
-/*
-** lba_device: Per instance Elroy data structure
-*/
-struct lba_device {
- struct pci_hba_data hba;
-
- spinlock_t lba_lock;
- void *iosapic_obj;
-
-#ifdef CONFIG_64BIT
- void __iomem * iop_base; /* PA_VIEW - for IO port accessor funcs */
-#endif
-
- int flags; /* state/functionality enabled */
- int hw_rev; /* HW revision of chip */
-};
-
-
static u32 lba_t32;
/* lba flags */
@@ -271,7 +166,8 @@ lba_dump_res(struct resource *r, int d)
printk(KERN_DEBUG "(%p)", r->parent);
for (i = d; i ; --i) printk(" ");
- printk(KERN_DEBUG "%p [%lx,%lx]/%lx\n", r, r->start, r->end, r->flags);
+ printk(KERN_DEBUG "%p [%lx,%lx]/%lx\n", r,
+ (long)r->start, (long)r->end, r->flags);
lba_dump_res(r->child, d+2);
lba_dump_res(r->sibling, d);
}
@@ -293,8 +189,8 @@ lba_dump_res(struct resource *r, int d)
static int lba_device_present(u8 bus, u8 dfn, struct lba_device *d)
{
- u8 first_bus = d->hba.hba_bus->secondary;
- u8 last_sub_bus = d->hba.hba_bus->subordinate;
+ u8 first_bus = d->hba.hba_bus->busn_res.start;
+ u8 last_sub_bus = d->hba.hba_bus->busn_res.end;
if ((bus < first_bus) ||
(bus > last_sub_bus) ||
@@ -468,7 +364,7 @@ lba_rd_cfg(struct lba_device *d, u32 tok, u8 reg, u32 size)
static int elroy_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->bridge));
- u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
+ u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start;
u32 tok = LBA_CFG_TOK(local_bus, devfn);
void __iomem *data_reg = d->hba.base_addr + LBA_PCI_CFG_DATA;
@@ -480,12 +376,12 @@ static int elroy_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int
/* original - Generate config cycle on broken elroy
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);
+ DBG_CFG("%s(%x+%2x) -> 0x%x (a)\n", __func__, tok, pos, *data);
return 0;
}
- if (LBA_SKIP_PROBE(d) && !lba_device_present(bus->secondary, devfn, d)) {
- DBG_CFG("%s(%x+%2x) -> -1 (b)\n", __FUNCTION__, tok, pos);
+ if (LBA_SKIP_PROBE(d) && !lba_device_present(bus->busn_res.start, devfn, d)) {
+ DBG_CFG("%s(%x+%2x) -> -1 (b)\n", __func__, tok, pos);
/* either don't want to look or know device isn't present. */
*data = ~0U;
return(0);
@@ -501,7 +397,7 @@ static int elroy_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int
case 2: *data = READ_REG16(data_reg + (pos & 2)); break;
case 4: *data = READ_REG32(data_reg); break;
}
- DBG_CFG("%s(%x+%2x) -> 0x%x (c)\n", __FUNCTION__, tok, pos, *data);
+ DBG_CFG("%s(%x+%2x) -> 0x%x (c)\n", __func__, tok, pos, *data);
return 0;
}
@@ -535,7 +431,7 @@ lba_wr_cfg(struct lba_device *d, u32 tok, u8 reg, u32 data, u32 size)
static int elroy_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->bridge));
- u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
+ u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start;
u32 tok = LBA_CFG_TOK(local_bus,devfn);
if ((pos > 255) || (devfn > 255))
@@ -544,16 +440,16 @@ static int elroy_cfg_write(struct pci_bus *bus, unsigned int devfn, int pos, int
if (!LBA_SKIP_PROBE(d)) {
/* Original Workaround */
lba_wr_cfg(d, tok, pos, (u32) data, size);
- DBG_CFG("%s(%x+%2x) = 0x%x (a)\n", __FUNCTION__, tok, pos,data);
+ DBG_CFG("%s(%x+%2x) = 0x%x (a)\n", __func__, tok, pos,data);
return 0;
}
- if (LBA_SKIP_PROBE(d) && (!lba_device_present(bus->secondary, devfn, d))) {
- DBG_CFG("%s(%x+%2x) = 0x%x (b)\n", __FUNCTION__, tok, pos,data);
+ if (LBA_SKIP_PROBE(d) && (!lba_device_present(bus->busn_res.start, devfn, d))) {
+ DBG_CFG("%s(%x+%2x) = 0x%x (b)\n", __func__, tok, pos,data);
return 1; /* New Workaround */
}
- DBG_CFG("%s(%x+%2x) = 0x%x (c)\n", __FUNCTION__, tok, pos, data);
+ DBG_CFG("%s(%x+%2x) = 0x%x (c)\n", __func__, tok, pos, data);
/* Basic Algorithm */
LBA_CFG_ADDR_SETUP(d, tok | pos);
@@ -585,7 +481,7 @@ static struct pci_ops elroy_cfg_ops = {
static int mercury_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->bridge));
- u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
+ u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start;
u32 tok = LBA_CFG_TOK(local_bus, devfn);
void __iomem *data_reg = d->hba.base_addr + LBA_PCI_CFG_DATA;
@@ -618,13 +514,13 @@ static int mercury_cfg_write(struct pci_bus *bus, unsigned int devfn, int pos, i
{
struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->bridge));
void __iomem *data_reg = d->hba.base_addr + LBA_PCI_CFG_DATA;
- u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
+ u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start;
u32 tok = LBA_CFG_TOK(local_bus,devfn);
if ((pos > 255) || (devfn > 255))
return -EINVAL;
- DBG_CFG("%s(%x+%2x) <- 0x%x (c)\n", __FUNCTION__, tok, pos, data);
+ DBG_CFG("%s(%x+%2x) <- 0x%x (c)\n", __func__, tok, pos, data);
LBA_CFG_TR4_ADDR_SETUP(d, tok | pos);
switch(size) {
@@ -660,44 +556,6 @@ lba_bios_init(void)
#ifdef CONFIG_64BIT
/*
-** Determine if a device is already configured.
-** If so, reserve it resources.
-**
-** Read PCI cfg command register and see if I/O or MMIO is enabled.
-** PAT has to enable the devices it's using.
-**
-** Note: resources are fixed up before we try to claim them.
-*/
-static void
-lba_claim_dev_resources(struct pci_dev *dev)
-{
- u16 cmd;
- int i, srch_flags;
-
- (void) pci_read_config_word(dev, PCI_COMMAND, &cmd);
-
- srch_flags = (cmd & PCI_COMMAND_IO) ? IORESOURCE_IO : 0;
- if (cmd & PCI_COMMAND_MEMORY)
- srch_flags |= IORESOURCE_MEM;
-
- if (!srch_flags)
- return;
-
- for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
- if (dev->resource[i].flags & srch_flags) {
- pci_claim_resource(dev, i);
- DBG(" claimed %s %d [%lx,%lx]/%lx\n",
- pci_name(dev), i,
- dev->resource[i].start,
- dev->resource[i].end,
- dev->resource[i].flags
- );
- }
- }
-}
-
-
-/*
* truncate_pat_collision: Deal with overlaps or outright collisions
* between PAT PDC reported ranges.
*
@@ -750,13 +608,60 @@ truncate_pat_collision(struct resource *root, struct resource *new)
printk(KERN_WARNING "LBA: Truncating lmmio_space [%lx/%lx] "
"to [%lx,%lx]\n",
start, end,
- new->start, new->end );
+ (long)new->start, (long)new->end );
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 lba_claim_dev_resources(dev) do { } while (0)
#define truncate_pat_collision(r,n) (0)
#endif
@@ -772,26 +677,29 @@ truncate_pat_collision(struct resource *root, struct resource *new)
static void
lba_fixup_bus(struct pci_bus *bus)
{
- struct list_head *ln;
+ struct pci_dev *dev;
#ifdef FBB_SUPPORT
u16 status;
#endif
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 platform_data 0x%p\n",
- bus, bus->secondary, bus->bridge->platform_data);
+ bus, (int)bus->busn_res.start, bus->bridge->platform_data);
/*
** Properly Setup MMIO resources for this bus.
** pci_alloc_primary_bus() mangles this.
*/
- if (bus->self) {
+ if (bus->parent) {
+ int i;
/* PCI-PCI Bridge */
pci_read_bridge_bases(bus);
+ for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) {
+ pci_claim_resource(bus->self, i);
+ }
} else {
/* Host-PCI Bridge */
- int err, i;
+ int err;
DBG("lba_fixup_bus() %s [%lx/%lx]/%lx\n",
ldev->hba.io_space.name,
@@ -807,51 +715,30 @@ lba_fixup_bus(struct pci_bus *bus)
lba_dump_res(&ioport_resource, 2);
BUG();
}
- /* advertize Host bridge resources to PCI bus */
- bus->resource[0] = &(ldev->hba.io_space);
- i = 1;
- if (ldev->hba.elmmio_space.start) {
+ if (ldev->hba.elmmio_space.flags) {
err = request_resource(&iomem_resource,
&(ldev->hba.elmmio_space));
if (err < 0) {
printk("FAILED: lba_fixup_bus() request for "
"elmmio_space [%lx/%lx]\n",
- ldev->hba.elmmio_space.start,
- ldev->hba.elmmio_space.end);
+ (long)ldev->hba.elmmio_space.start,
+ (long)ldev->hba.elmmio_space.end);
/* lba_dump_res(&iomem_resource, 2); */
/* BUG(); */
- } else
- bus->resource[i++] = &(ldev->hba.elmmio_space);
+ }
}
-
- /* Overlaps with elmmio can (and should) fail here.
- * We will prune (or ignore) the distributed range.
- *
- * FIXME: SBA code should register all elmmio ranges first.
- * that would take care of elmmio ranges routed
- * to a different rope (already discovered) from
- * getting registered *after* LBA code has already
- * registered it's distributed lmmio range.
- */
- if (truncate_pat_collision(&iomem_resource,
- &(ldev->hba.lmmio_space))) {
-
- printk(KERN_WARNING "LBA: lmmio_space [%lx/%lx] duplicate!\n",
- ldev->hba.lmmio_space.start,
- ldev->hba.lmmio_space.end);
- } else {
+ if (ldev->hba.lmmio_space.flags) {
err = request_resource(&iomem_resource, &(ldev->hba.lmmio_space));
if (err < 0) {
printk(KERN_ERR "FAILED: lba_fixup_bus() request for "
"lmmio_space [%lx/%lx]\n",
- ldev->hba.lmmio_space.start,
- ldev->hba.lmmio_space.end);
- } else
- bus->resource[i++] = &(ldev->hba.lmmio_space);
+ (long)ldev->hba.lmmio_space.start,
+ (long)ldev->hba.lmmio_space.end);
+ }
}
#ifdef CONFIG_64BIT
@@ -861,20 +748,18 @@ lba_fixup_bus(struct pci_bus *bus)
if (err < 0) {
printk("FAILED: lba_fixup_bus() request for "
"gmmio_space [%lx/%lx]\n",
- ldev->hba.gmmio_space.start,
- ldev->hba.gmmio_space.end);
+ (long)ldev->hba.gmmio_space.start,
+ (long)ldev->hba.gmmio_space.end);
lba_dump_res(&iomem_resource, 2);
BUG();
}
- bus->resource[i++] = &(ldev->hba.gmmio_space);
}
#endif
}
- list_for_each(ln, &bus->devices) {
+ list_for_each_entry(dev, &bus->devices, bus_list) {
int i;
- struct pci_dev *dev = pci_dev_b(ln);
DBG("lba_fixup_bus() %s\n", pci_name(dev));
@@ -886,26 +771,12 @@ lba_fixup_bus(struct pci_bus *bus)
if (!res->start)
continue;
- if (res->flags & IORESOURCE_IO) {
- DBG("lba_fixup_bus() I/O Ports [%lx/%lx] -> ",
- res->start, res->end);
- res->start |= lba_portbase;
- res->end |= lba_portbase;
- DBG("[%lx/%lx]\n", res->start, res->end);
- } else if (res->flags & IORESOURCE_MEM) {
- /*
- ** Convert PCI (IO_VIEW) addresses to
- ** processor (PA_VIEW) addresses
- */
- DBG("lba_fixup_bus() MMIO [%lx/%lx] -> ",
- res->start, res->end);
- res->start = PCI_HOST_ADDR(HBA_DATA(ldev), res->start);
- res->end = PCI_HOST_ADDR(HBA_DATA(ldev), res->end);
- DBG("[%lx/%lx]\n", res->start, res->end);
- } else {
- DBG("lba_fixup_bus() WTF? 0x%lx [%lx/%lx] XXX",
- res->flags, res->start, res->end);
- }
+ /*
+ ** FIXME: this will result in whinging for devices
+ ** that share expansion ROMs (think quad tulip), but
+ ** isn't harmful.
+ */
+ pci_claim_resource(dev, i);
}
#ifdef FBB_SUPPORT
@@ -917,11 +788,6 @@ lba_fixup_bus(struct pci_bus *bus)
bus->bridge_ctl &= ~(status & PCI_STATUS_FAST_BACK);
#endif
- if (is_pdc_pat()) {
- /* Claim resources for PDC's devices */
- lba_claim_dev_resources(dev);
- }
-
/*
** P2PB's have no IRQs. ignore them.
*/
@@ -938,7 +804,7 @@ lba_fixup_bus(struct pci_bus *bus)
** Can't fixup here anyway....garr...
*/
if (fbb_enable) {
- if (bus->self) {
+ if (bus->parent) {
u8 control;
/* enable on PPB */
(void) pci_read_config_byte(bus->self, PCI_BRIDGE_CONTROL, &control);
@@ -951,7 +817,7 @@ lba_fixup_bus(struct pci_bus *bus)
}
/* Lastly enable FBB/PERR/SERR on all devices too */
- list_for_each(ln, &bus->devices) {
+ list_for_each_entry(dev, &bus->devices, bus_list) {
(void) pci_read_config_word(dev, PCI_COMMAND, &status);
status |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR | fbb_enable;
(void) pci_write_config_word(dev, PCI_COMMAND, status);
@@ -960,7 +826,7 @@ lba_fixup_bus(struct pci_bus *bus)
}
-struct pci_bios_ops lba_bios_ops = {
+static struct pci_bios_ops lba_bios_ops = {
.init = lba_bios_init,
.fixup_bus = lba_fixup_bus,
};
@@ -1026,7 +892,7 @@ LBA_PORT_IN(32, 0)
#define LBA_PORT_OUT(size, mask) \
static void lba_astro_out##size (struct pci_hba_data *d, u16 addr, u##size val) \
{ \
- DBG_PORT("%s(0x%p, 0x%x, 0x%x)\n", __FUNCTION__, d, addr, val); \
+ DBG_PORT("%s(0x%p, 0x%x, 0x%x)\n", __func__, d, addr, val); \
WRITE_REG##size(val, astro_iop_base + addr); \
if (LBA_DEV(d)->hw_rev < 3) \
lba_t32 = READ_U32(d->base_addr + LBA_FUNC_ID); \
@@ -1068,7 +934,7 @@ static struct pci_port_ops lba_astro_port_ops = {
static u##size lba_pat_in##size (struct pci_hba_data *l, u16 addr) \
{ \
u##size t; \
- DBG_PORT("%s(0x%p, 0x%x) ->", __FUNCTION__, l, addr); \
+ DBG_PORT("%s(0x%p, 0x%x) ->", __func__, l, addr); \
t = READ_REG##size(PIOP_TO_GMMIO(LBA_DEV(l), addr)); \
DBG_PORT(" 0x%x\n", t); \
return (t); \
@@ -1083,8 +949,8 @@ LBA_PORT_IN(32, 0)
#define LBA_PORT_OUT(size, mask) \
static void lba_pat_out##size (struct pci_hba_data *l, u16 addr, u##size val) \
{ \
- void *where = (void *) PIOP_TO_GMMIO(LBA_DEV(l), addr); \
- DBG_PORT("%s(0x%p, 0x%x, 0x%x)\n", __FUNCTION__, l, addr, val); \
+ void __iomem *where = PIOP_TO_GMMIO(LBA_DEV(l), addr); \
+ DBG_PORT("%s(0x%p, 0x%x, 0x%x)\n", __func__, l, addr, val); \
WRITE_REG##size(val, where); \
/* flush the I/O down to the elroy at least */ \
lba_t32 = READ_U32(l->base_addr + LBA_FUNC_ID); \
@@ -1116,28 +982,38 @@ static void
lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
{
unsigned long bytecnt;
- pdc_pat_cell_mod_maddr_block_t pa_pdc_cell; /* PA_VIEW */
- pdc_pat_cell_mod_maddr_block_t io_pdc_cell; /* IO_VIEW */
long io_count;
long status; /* PDC return status */
long pa_count;
+ pdc_pat_cell_mod_maddr_block_t *pa_pdc_cell; /* PA_VIEW */
+ pdc_pat_cell_mod_maddr_block_t *io_pdc_cell; /* IO_VIEW */
int i;
+ pa_pdc_cell = kzalloc(sizeof(pdc_pat_cell_mod_maddr_block_t), GFP_KERNEL);
+ if (!pa_pdc_cell)
+ return;
+
+ io_pdc_cell = kzalloc(sizeof(pdc_pat_cell_mod_maddr_block_t), GFP_KERNEL);
+ if (!io_pdc_cell) {
+ kfree(pa_pdc_cell);
+ return;
+ }
+
/* return cell module (IO view) */
status = pdc_pat_cell_module(&bytecnt, pa_dev->pcell_loc, pa_dev->mod_index,
- PA_VIEW, & pa_pdc_cell);
- pa_count = pa_pdc_cell.mod[1];
+ PA_VIEW, pa_pdc_cell);
+ pa_count = pa_pdc_cell->mod[1];
status |= pdc_pat_cell_module(&bytecnt, pa_dev->pcell_loc, pa_dev->mod_index,
- IO_VIEW, &io_pdc_cell);
- io_count = io_pdc_cell.mod[1];
+ IO_VIEW, io_pdc_cell);
+ io_count = io_pdc_cell->mod[1];
/* We've already done this once for device discovery...*/
if (status != PDC_OK) {
panic("pdc_pat_cell_module() call failed for LBA!\n");
}
- if (PAT_GET_ENTITY(pa_pdc_cell.mod_info) != PAT_ENTITY_LBA) {
+ if (PAT_GET_ENTITY(pa_pdc_cell->mod_info) != PAT_ENTITY_LBA) {
panic("pdc_pat_cell_module() entity returned != PAT_ENTITY_LBA!\n");
}
@@ -1152,30 +1028,39 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
} *p, *io;
struct resource *r;
- p = (void *) &(pa_pdc_cell.mod[2+i*3]);
- io = (void *) &(io_pdc_cell.mod[2+i*3]);
+ p = (void *) &(pa_pdc_cell->mod[2+i*3]);
+ io = (void *) &(io_pdc_cell->mod[2+i*3]);
/* Convert the PAT range data to PCI "struct resource" */
switch(p->type & 0xff) {
case PAT_PBNUM:
lba_dev->hba.bus_num.start = p->start;
lba_dev->hba.bus_num.end = p->end;
+ lba_dev->hba.bus_num.flags = IORESOURCE_BUS;
break;
case PAT_LMMIO:
/* used to fix up pre-initialized MEM BARs */
- if (!lba_dev->hba.lmmio_space.start) {
+ 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%02lx LMMIO",
- lba_dev->hba.bus_num.start);
+ "PCI%02x LMMIO",
+ (int)lba_dev->hba.bus_num.start);
lba_dev->hba.lmmio_space_offset = p->start -
io->start;
r = &lba_dev->hba.lmmio_space;
r->name = lba_dev->hba.lmmio_name;
- } else if (!lba_dev->hba.elmmio_space.start) {
+ } else if (!lba_dev->hba.elmmio_space.flags) {
sprintf(lba_dev->hba.elmmio_name,
- "PCI%02lx ELMMIO",
- lba_dev->hba.bus_num.start);
+ "PCI%02x ELMMIO",
+ (int)lba_dev->hba.bus_num.start);
r = &lba_dev->hba.elmmio_space;
r->name = lba_dev->hba.elmmio_name;
} else {
@@ -1192,8 +1077,8 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
case PAT_GMMIO:
/* MMIO space > 4GB phys addr; for 64-bit BAR */
- sprintf(lba_dev->hba.gmmio_name, "PCI%02lx GMMIO",
- lba_dev->hba.bus_num.start);
+ sprintf(lba_dev->hba.gmmio_name, "PCI%02x GMMIO",
+ (int)lba_dev->hba.bus_num.start);
r = &lba_dev->hba.gmmio_space;
r->name = lba_dev->hba.gmmio_name;
r->start = p->start;
@@ -1215,8 +1100,8 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
*/
lba_dev->iop_base = ioremap_nocache(p->start, 64 * 1024 * 1024);
- sprintf(lba_dev->hba.io_name, "PCI%02lx Ports",
- lba_dev->hba.bus_num.start);
+ sprintf(lba_dev->hba.io_name, "PCI%02x Ports",
+ (int)lba_dev->hba.bus_num.start);
r = &lba_dev->hba.io_space;
r->name = lba_dev->hba.io_name;
r->start = HBA_PORT_BASE(lba_dev->hba.hba_num);
@@ -1232,6 +1117,9 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
break;
}
}
+
+ kfree(pa_pdc_cell);
+ kfree(io_pdc_cell);
}
#else
/* keep compiler from complaining about missing declarations */
@@ -1264,13 +1152,14 @@ lba_legacy_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
r->name = "LBA PCI Busses";
r->start = lba_num & 0xff;
r->end = (lba_num>>8) & 0xff;
+ r->flags = IORESOURCE_BUS;
/* Set up local PCI Bus resources - we don't need them for
** Legacy boxes but it's nice to see in /proc/iomem.
*/
r = &(lba_dev->hba.lmmio_space);
- sprintf(lba_dev->hba.lmmio_name, "PCI%02lx LMMIO",
- lba_dev->hba.bus_num.start);
+ sprintf(lba_dev->hba.lmmio_name, "PCI%02x LMMIO",
+ (int)lba_dev->hba.bus_num.start);
r->name = lba_dev->hba.lmmio_name;
#if 1
@@ -1378,8 +1267,8 @@ lba_legacy_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
** an existing (but unused portion of) distributed range.
*/
r = &(lba_dev->hba.elmmio_space);
- sprintf(lba_dev->hba.elmmio_name, "PCI%02lx ELMMIO",
- lba_dev->hba.bus_num.start);
+ sprintf(lba_dev->hba.elmmio_name, "PCI%02x ELMMIO",
+ (int)lba_dev->hba.bus_num.start);
r->name = lba_dev->hba.elmmio_name;
#if 1
@@ -1400,8 +1289,8 @@ lba_legacy_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
#endif
r = &(lba_dev->hba.io_space);
- sprintf(lba_dev->hba.io_name, "PCI%02lx Ports",
- lba_dev->hba.bus_num.start);
+ sprintf(lba_dev->hba.io_name, "PCI%02x Ports",
+ (int)lba_dev->hba.bus_num.start);
r->name = lba_dev->hba.io_name;
r->flags = IORESOURCE_IO;
r->start = READ_REG32(lba_dev->hba.base_addr + LBA_IOS_BASE) & ~1L;
@@ -1509,23 +1398,32 @@ lba_hw_init(struct lba_device *d)
return 0;
}
-
+/*
+ * Unfortunately, when firmware numbers busses, it doesn't take into account
+ * Cardbus bridges. So we have to renumber the busses to suit ourselves.
+ * Elroy/Mercury don't actually know what bus number they're attached to;
+ * we use bus 0 to indicate the directly attached bus and any other bus
+ * number will be taken care of by the PCI-PCI bridge.
+ */
+static unsigned int lba_next_bus = 0;
/*
-** Determine if lba should claim this chip (return 0) or not (return 1).
-** If so, initialize the chip and tell other partners in crime they
-** have work to do.
-*/
+ * Determine if lba should claim this chip (return 0) or not (return 1).
+ * If so, initialize the chip and tell other partners in crime they
+ * have work to do.
+ */
static int __init
lba_driver_probe(struct parisc_device *dev)
{
struct lba_device *lba_dev;
+ LIST_HEAD(resources);
struct pci_bus *lba_bus;
struct pci_ops *cfg_ops;
u32 func_class;
void *tmp_obj;
char *version;
void __iomem *addr = ioremap_nocache(dev->hpa.start, 4096);
+ int max;
/* Read HW Rev First */
func_class = READ_REG32(addr + LBA_FCLASS);
@@ -1542,8 +1440,8 @@ lba_driver_probe(struct parisc_device *dev)
default: version = "TR4+";
}
- printk(KERN_INFO "%s version %s (0x%x) found at 0x%lx\n",
- MODULE_NAME, version, func_class & 0xf, dev->hpa.start);
+ printk(KERN_INFO "Elroy version %s (0x%x) found at 0x%lx\n",
+ version, func_class & 0xf, (long)dev->hpa.start);
if (func_class < 2) {
printk(KERN_WARNING "Can't support LBA older than "
@@ -1563,23 +1461,26 @@ lba_driver_probe(struct parisc_device *dev)
}
} else if (IS_MERCURY(dev) || IS_QUICKSILVER(dev)) {
+ int major, minor;
+
func_class &= 0xff;
- version = kmalloc(6, GFP_KERNEL);
- snprintf(version, 6, "TR%d.%d",(func_class >> 4),(func_class & 0xf));
+ major = func_class >> 4, minor = func_class & 0xf;
+
/* We could use one printk for both Elroy and Mercury,
* but for the mask for func_class.
*/
- printk(KERN_INFO "%s version %s (0x%x) found at 0x%lx\n",
- MODULE_NAME, version, func_class & 0xff, dev->hpa.start);
+ printk(KERN_INFO "%s version TR%d.%d (0x%x) found at 0x%lx\n",
+ IS_MERCURY(dev) ? "Mercury" : "Quicksilver", major,
+ minor, func_class, (long)dev->hpa.start);
+
cfg_ops = &mercury_cfg_ops;
} else {
- printk(KERN_ERR "Unknown LBA found at 0x%lx\n", dev->hpa.start);
+ printk(KERN_ERR "Unknown LBA found at 0x%lx\n",
+ (long)dev->hpa.start);
return -ENODEV;
}
- /*
- ** Tell I/O SAPIC driver we have a IRQ handler/region.
- */
+ /* Tell I/O SAPIC driver we have a IRQ handler/region. */
tmp_obj = iosapic_register(dev->hpa.start + LBA_IOSAPIC_BASE);
/* NOTE: PCI devices (e.g. 103c:1005 graphics card) which don't
@@ -1600,6 +1501,7 @@ lba_driver_probe(struct parisc_device *dev)
lba_dev->hba.dev = dev;
lba_dev->iosapic_obj = tmp_obj; /* save interrupt handle */
lba_dev->hba.iommu = sba_get_iommu(dev); /* get iommu data */
+ parisc_set_drvdata(dev, lba_dev);
/* ------------ Second : initialize common stuff ---------- */
pci_bios = &lba_bios_ops;
@@ -1627,16 +1529,49 @@ lba_driver_probe(struct parisc_device *dev)
lba_legacy_resources(dev, lba_dev);
}
- /*
- ** Tell PCI support another PCI bus was found.
- ** Walks PCI bus for us too.
- */
+ if (lba_dev->hba.bus_num.start < lba_next_bus)
+ lba_dev->hba.bus_num.start = lba_next_bus;
+
+ /* Overlaps with elmmio can (and should) fail here.
+ * We will prune (or ignore) the distributed range.
+ *
+ * FIXME: SBA code should register all elmmio ranges first.
+ * that would take care of elmmio ranges routed
+ * to a different rope (already discovered) from
+ * getting registered *after* LBA code has already
+ * registered it's distributed lmmio range.
+ */
+ if (truncate_pat_collision(&iomem_resource,
+ &(lba_dev->hba.lmmio_space))) {
+ printk(KERN_WARNING "LBA: lmmio_space [%lx/%lx] duplicate!\n",
+ (long)lba_dev->hba.lmmio_space.start,
+ (long)lba_dev->hba.lmmio_space.end);
+ lba_dev->hba.lmmio_space.flags = 0;
+ }
+
+ pci_add_resource_offset(&resources, &lba_dev->hba.io_space,
+ HBA_PORT_BASE(lba_dev->hba.hba_num));
+ if (lba_dev->hba.elmmio_space.flags)
+ pci_add_resource_offset(&resources, &lba_dev->hba.elmmio_space,
+ lba_dev->hba.lmmio_space_offset);
+ if (lba_dev->hba.lmmio_space.flags)
+ pci_add_resource_offset(&resources, &lba_dev->hba.lmmio_space,
+ lba_dev->hba.lmmio_space_offset);
+ if (lba_dev->hba.gmmio_space.flags)
+ pci_add_resource(&resources, &lba_dev->hba.gmmio_space);
+
+ pci_add_resource(&resources, &lba_dev->hba.bus_num);
+
dev->dev.platform_data = lba_dev;
lba_bus = lba_dev->hba.hba_bus =
- pci_scan_bus_parented(&dev->dev, lba_dev->hba.bus_num.start,
- cfg_ops, NULL);
- if (lba_bus)
- pci_bus_add_devices(lba_bus);
+ pci_create_root_bus(&dev->dev, lba_dev->hba.bus_num.start,
+ cfg_ops, NULL, &resources);
+ if (!lba_bus) {
+ pci_free_resource_list(&resources);
+ return 0;
+ }
+
+ max = pci_scan_child_bus(lba_bus);
/* This is in lieu of calling pci_assign_unassigned_resources() */
if (is_pdc_pat()) {
@@ -1655,8 +1590,6 @@ lba_driver_probe(struct parisc_device *dev)
lba_dump_res(&lba_dev->hba.lmmio_space, 2);
#endif
}
- pci_enable_bridges(lba_bus);
-
/*
** Once PCI register ops has walked the bus, access to config
@@ -1667,6 +1600,9 @@ lba_driver_probe(struct parisc_device *dev)
lba_dev->flags |= LBA_FLAG_SKIP_PROBE;
}
+ lba_next_bus = max + 1;
+ pci_bus_add_devices(lba_bus);
+
/* Whew! Finally done! Tell services we got this one covered. */
return 0;
}
@@ -1708,7 +1644,7 @@ void lba_set_iregs(struct parisc_device *lba, u32 ibase, u32 imask)
WARN_ON((ibase & 0x001fffff) != 0);
WARN_ON((imask & 0x001fffff) != 0);
- DBG("%s() ibase 0x%x imask 0x%x\n", __FUNCTION__, ibase, imask);
+ DBG("%s() ibase 0x%x imask 0x%x\n", __func__, ibase, imask);
WRITE_REG32( imask, base_addr + LBA_IMASK);
WRITE_REG32( ibase, base_addr + LBA_IBASE);
iounmap(base_addr);
diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c
index bf00fa2537b..b4824313199 100644
--- a/drivers/parisc/led.c
+++ b/drivers/parisc/led.c
@@ -3,7 +3,7 @@
*
* (c) Copyright 2000 Red Hat Software
* (c) Copyright 2000 Helge Deller <hdeller@redhat.com>
- * (c) Copyright 2001-2005 Helge Deller <deller@gmx.de>
+ * (c) Copyright 2001-2009 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
@@ -38,6 +38,7 @@
#include <linux/kernel_stat.h>
#include <linux/reboot.h>
#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
#include <linux/ctype.h>
#include <linux/blkdev.h>
#include <linux/workqueue.h>
@@ -63,11 +64,12 @@ static unsigned int led_diskio __read_mostly = 1;
static unsigned int led_lanrxtx __read_mostly = 1;
static char lcd_text[32] __read_mostly;
static char lcd_text_default[32] __read_mostly;
+static int lcd_no_led_support __read_mostly = 0; /* KittyHawk doesn't support LED on its LCD */
static struct workqueue_struct *led_wq;
-static void led_work_func(void *);
-static DECLARE_WORK(led_task, led_work_func, NULL);
+static void led_work_func(struct work_struct *);
+static DECLARE_DELAYED_WORK(led_task, led_work_func);
#if 0
#define DPRINTK(x) printk x
@@ -114,7 +116,7 @@ lcd_info __attribute__((aligned(8))) __read_mostly =
.lcd_width = 16,
.lcd_cmd_reg_addr = KITTYHAWK_LCD_CMD,
.lcd_data_reg_addr = KITTYHAWK_LCD_DATA,
- .min_cmd_delay = 40,
+ .min_cmd_delay = 80,
.reset_cmd1 = 0x80,
.reset_cmd2 = 0xc0,
};
@@ -134,9 +136,12 @@ static int start_task(void)
/* Display the default text now */
if (led_type == LED_HASLCD) lcd_print( lcd_text_default );
+ /* KittyHawk has no LED support on its LCD */
+ if (lcd_no_led_support) return 0;
+
/* Create the work queue and queue the LED task */
led_wq = create_singlethread_workqueue("led_wq");
- queue_work(led_wq, &led_task);
+ queue_delayed_work(led_wq, &led_task, 0);
return 0;
}
@@ -147,60 +152,49 @@ device_initcall(start_task);
static void (*led_func_ptr) (unsigned char) __read_mostly;
#ifdef CONFIG_PROC_FS
-static int led_proc_read(char *page, char **start, off_t off, int count,
- int *eof, void *data)
+static int led_proc_show(struct seq_file *m, void *v)
{
- char *out = page;
- int len;
-
- switch ((long)data)
+ switch ((long)m->private)
{
case LED_NOLCD:
- out += sprintf(out, "Heartbeat: %d\n", led_heartbeat);
- out += sprintf(out, "Disk IO: %d\n", led_diskio);
- out += sprintf(out, "LAN Rx/Tx: %d\n", led_lanrxtx);
+ seq_printf(m, "Heartbeat: %d\n", led_heartbeat);
+ seq_printf(m, "Disk IO: %d\n", led_diskio);
+ seq_printf(m, "LAN Rx/Tx: %d\n", led_lanrxtx);
break;
case LED_HASLCD:
- out += sprintf(out, "%s\n", lcd_text);
+ seq_printf(m, "%s\n", lcd_text);
break;
default:
- *eof = 1;
return 0;
}
+ return 0;
+}
- len = out - page - off;
- if (len < count) {
- *eof = 1;
- if (len <= 0) return 0;
- } else {
- len = count;
- }
- *start = page + off;
- return len;
+static int led_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, led_proc_show, PDE_DATA(inode));
}
-static int led_proc_write(struct file *file, const char *buf,
- unsigned long count, void *data)
+
+static ssize_t led_proc_write(struct file *file, const char *buf,
+ size_t count, loff_t *pos)
{
- char *cur, lbuf[count + 1];
+ void *data = PDE_DATA(file_inode(file));
+ char *cur, lbuf[32];
int d;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
- memset(lbuf, 0, count + 1);
+ if (count >= sizeof(lbuf))
+ count = sizeof(lbuf)-1;
if (copy_from_user(lbuf, buf, count))
return -EFAULT;
+ lbuf[count] = 0;
cur = lbuf;
- /* skip initial spaces */
- while (*cur && isspace(*cur))
- {
- cur++;
- }
-
switch ((long)data)
{
case LED_NOLCD:
@@ -240,6 +234,15 @@ parse_error:
return -EINVAL;
}
+static const struct file_operations led_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = led_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .write = led_proc_write,
+};
+
static int __init led_create_procfs(void)
{
struct proc_dir_entry *proc_pdc_root = NULL;
@@ -249,24 +252,19 @@ static int __init led_create_procfs(void)
proc_pdc_root = proc_mkdir("pdc", 0);
if (!proc_pdc_root) return -1;
- proc_pdc_root->owner = THIS_MODULE;
- ent = create_proc_entry("led", S_IFREG|S_IRUGO|S_IWUSR, proc_pdc_root);
- if (!ent) return -1;
- ent->nlink = 1;
- ent->data = (void *)LED_NOLCD; /* LED */
- ent->read_proc = led_proc_read;
- ent->write_proc = led_proc_write;
- ent->owner = THIS_MODULE;
+
+ if (!lcd_no_led_support)
+ {
+ ent = proc_create_data("led", S_IRUGO|S_IWUSR, proc_pdc_root,
+ &led_proc_fops, (void *)LED_NOLCD); /* LED */
+ if (!ent) return -1;
+ }
if (led_type == LED_HASLCD)
{
- ent = create_proc_entry("lcd", S_IFREG|S_IRUGO|S_IWUSR, proc_pdc_root);
+ ent = proc_create_data("lcd", S_IRUGO|S_IWUSR, proc_pdc_root,
+ &led_proc_fops, (void *)LED_HASLCD); /* LCD */
if (!ent) return -1;
- ent->nlink = 1;
- ent->data = (void *)LED_HASLCD; /* LCD */
- ent->read_proc = led_proc_read;
- ent->write_proc = led_proc_write;
- ent->owner = THIS_MODULE;
}
return 0;
@@ -356,32 +354,28 @@ static __inline__ int led_get_net_activity(void)
#ifndef CONFIG_NET
return 0;
#else
- static unsigned long rx_total_last, tx_total_last;
- unsigned long rx_total, tx_total;
+ static u64 rx_total_last, tx_total_last;
+ u64 rx_total, tx_total;
struct net_device *dev;
int retval;
rx_total = tx_total = 0;
- /* we are running as a workqueue task, so locking dev_base
- * for reading should be OK */
- read_lock(&dev_base_lock);
+ /* we are running as a workqueue task, so we can use an RCU lookup */
rcu_read_lock();
- for (dev = dev_base; dev; dev = dev->next) {
- struct net_device_stats *stats;
+ for_each_netdev_rcu(&init_net, dev) {
+ const struct rtnl_link_stats64 *stats;
+ struct rtnl_link_stats64 temp;
struct in_device *in_dev = __in_dev_get_rcu(dev);
if (!in_dev || !in_dev->ifa_list)
continue;
- if (LOOPBACK(in_dev->ifa_list->ifa_local))
- continue;
- if (!dev->get_stats)
+ if (ipv4_is_loopback(in_dev->ifa_list->ifa_local))
continue;
- stats = dev->get_stats(dev);
+ stats = dev_get_stats(dev, &temp);
rx_total += stats->rx_packets;
tx_total += stats->tx_packets;
}
rcu_read_unlock();
- read_unlock(&dev_base_lock);
retval = 0;
@@ -443,7 +437,7 @@ static __inline__ int led_get_diskio_activity(void)
#define LED_UPDATE_INTERVAL (1 + (HZ*19/1000))
-static void led_work_func (void *unused)
+static void led_work_func (struct work_struct *unused)
{
static unsigned long last_jiffies;
static unsigned long count_HZ; /* counter in range 0..HZ */
@@ -473,9 +467,20 @@ static void led_work_func (void *unused)
if (likely(led_lanrxtx)) currentleds |= led_get_net_activity();
if (likely(led_diskio)) currentleds |= led_get_diskio_activity();
- /* blink all LEDs twice a second if we got an Oops (HPMC) */
- if (unlikely(oops_in_progress))
- currentleds = (count_HZ<=(HZ/2)) ? 0 : 0xff;
+ /* blink LEDs if we got an Oops (HPMC) */
+ if (unlikely(oops_in_progress)) {
+ if (boot_cpu_data.cpu_type >= pcxl2) {
+ /* newer machines don't have loadavg. LEDs, so we
+ * let all LEDs blink twice per second instead */
+ currentleds = (count_HZ <= (HZ/2)) ? 0 : 0xff;
+ } else {
+ /* old machines: blink loadavg. LEDs twice per second */
+ if (count_HZ <= (HZ/2))
+ currentleds &= ~(LED4|LED5|LED6|LED7);
+ else
+ currentleds |= (LED4|LED5|LED6|LED7);
+ }
+ }
if (currentleds != lastleds)
{
@@ -521,7 +526,7 @@ static int led_halt(struct notifier_block *nb, unsigned long event, void *buf)
/* Cancel the work item and delete the queue */
if (led_wq) {
- cancel_rearming_delayed_workqueue(led_wq, &led_task);
+ cancel_delayed_work_sync(&led_task);
destroy_workqueue(led_wq);
led_wq = NULL;
}
@@ -579,7 +584,7 @@ int __init register_led_driver(int model, unsigned long cmd_reg, unsigned long d
default:
printk(KERN_ERR "%s: Wrong LCD/LED model %d !\n",
- __FUNCTION__, lcd_info.model);
+ __func__, lcd_info.model);
return 1;
}
@@ -590,7 +595,7 @@ int __init register_led_driver(int model, unsigned long cmd_reg, unsigned long d
/* Ensure the work is queued */
if (led_wq) {
- queue_work(led_wq, &led_task);
+ queue_delayed_work(led_wq, &led_task, 0);
}
return 0;
@@ -631,7 +636,7 @@ void __init register_led_regions(void)
** avoid a race condition while writing the CMD/DATA register pair.
**
*/
-int lcd_print( char *str )
+int lcd_print( const char *str )
{
int i;
@@ -640,7 +645,7 @@ int lcd_print( char *str )
/* temporarily disable the led work task */
if (led_wq)
- cancel_rearming_delayed_workqueue(led_wq, &led_task);
+ cancel_delayed_work_sync(&led_task);
/* copy display string to buffer for procfs */
strlcpy(lcd_text, str, sizeof(lcd_text));
@@ -660,7 +665,7 @@ int lcd_print( char *str )
/* re-queue the work */
if (led_wq) {
- queue_work(led_wq, &led_task);
+ queue_delayed_work(led_wq, &led_task, 0);
}
return lcd_info.lcd_width;
@@ -684,7 +689,7 @@ int __init led_init(void)
int ret;
snprintf(lcd_text_default, sizeof(lcd_text_default),
- "Linux %s", system_utsname.release);
+ "Linux %s", init_utsname()->release);
/* Work around the buggy PDC of KittyHawk-machines */
switch (CPU_HVERSION) {
@@ -695,6 +700,7 @@ int __init led_init(void)
case 0x58B: /* KittyHawk DC2 100 (K200) */
printk(KERN_INFO "%s: KittyHawk-Machine (hversion 0x%x) found, "
"LED detection skipped.\n", __FILE__, CPU_HVERSION);
+ lcd_no_led_support = 1;
goto found; /* use the preinitialized values of lcd_info */
}
diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c
index ea1b7a63598..0f54ab6260d 100644
--- a/drivers/parisc/pdc_stable.c
+++ b/drivers/parisc/pdc_stable.c
@@ -120,15 +120,15 @@ struct pdcspath_entry pdcspath_entry_##_name = { \
};
#define PDCS_ATTR(_name, _mode, _show, _store) \
-struct subsys_attribute pdcs_attr_##_name = { \
- .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE}, \
+struct kobj_attribute pdcs_attr_##_name = { \
+ .attr = {.name = __stringify(_name), .mode = _mode}, \
.show = _show, \
.store = _store, \
};
#define PATHS_ATTR(_name, _mode, _show, _store) \
struct pdcspath_attribute paths_attr_##_name = { \
- .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE}, \
+ .attr = {.name = __stringify(_name), .mode = _mode}, \
.show = _show, \
.store = _store, \
};
@@ -141,7 +141,7 @@ struct pdcspath_attribute paths_attr_##_name = { \
* @entry: A pointer to an allocated pdcspath_entry.
*
* The general idea is that you don't read from the Stable Storage every time
- * you access the files provided by the facilites. We store a copy of the
+ * you access the files provided by the facilities. We store a copy of the
* content of the stable storage WRT various paths in these structs. We read
* these structs when reading the files, and we will write to these structs when
* writing to the files, and only then write them back to the Stable Storage.
@@ -212,12 +212,10 @@ pdcspath_store(struct pdcspath_entry *entry)
entry, devpath, entry->addr);
/* addr, devpath and count must be word aligned */
- if (pdc_stable_write(entry->addr, devpath, sizeof(*devpath)) != PDC_OK) {
- printk(KERN_ERR "%s: an error occured when writing to PDC.\n"
+ if (pdc_stable_write(entry->addr, devpath, sizeof(*devpath)) != PDC_OK)
+ WARN(1, KERN_ERR "%s: an error occurred when writing to PDC.\n"
"It is likely that the Stable Storage data has been corrupted.\n"
"Please check it carefully upon next reboot.\n", __func__);
- WARN_ON(1);
- }
/* kobject is already registered */
entry->ready = 2;
@@ -282,6 +280,7 @@ pdcspath_hwpath_write(struct pdcspath_entry *entry, const char *buf, size_t coun
unsigned short i;
char in[count+1], *temp;
struct device *dev;
+ int ret;
if (!entry || !buf || !count)
return -EINVAL;
@@ -333,7 +332,9 @@ pdcspath_hwpath_write(struct pdcspath_entry *entry, const char *buf, size_t coun
/* Update the symlink to the real device */
sysfs_remove_link(&entry->kobj, "device");
- sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device");
+ ret = sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device");
+ WARN_ON(ret);
+
write_unlock(&entry->rw_lock);
printk(KERN_INFO PDCS_PREFIX ": changed \"%s\" path to \"%s\"\n",
@@ -367,7 +368,7 @@ pdcspath_layer_read(struct pdcspath_entry *entry, char *buf)
if (!i) /* entry is not ready */
return -ENODATA;
- for (i = 0; devpath->layers[i] && (likely(i < 6)); i++)
+ for (i = 0; i < 6 && devpath->layers[i]; i++)
out += sprintf(out, "%u ", devpath->layers[i]);
out += sprintf(out, "\n");
@@ -478,7 +479,7 @@ pdcspath_attr_store(struct kobject *kobj, struct attribute *attr,
return ret;
}
-static struct sysfs_ops pdcspath_attr_ops = {
+static const struct sysfs_ops pdcspath_attr_ops = {
.show = pdcspath_attr_show,
.store = pdcspath_attr_store,
};
@@ -520,17 +521,17 @@ static struct pdcspath_entry *pdcspath_entries[] = {
/**
* pdcs_size_read - Stable Storage size output.
- * @entry: An allocated and populated subsytem struct. We don't use it tho.
* @buf: The output buffer to write to.
*/
-static ssize_t
-pdcs_size_read(struct subsystem *entry, char *buf)
+static ssize_t pdcs_size_read(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
{
char *out = buf;
-
- if (!entry || !buf)
+
+ if (!buf)
return -EINVAL;
-
+
/* show the size of the stable storage */
out += sprintf(out, "%ld\n", pdcs_size);
@@ -539,17 +540,17 @@ pdcs_size_read(struct subsystem *entry, char *buf)
/**
* pdcs_auto_read - Stable Storage autoboot/search flag output.
- * @entry: An allocated and populated subsytem struct. We don't use it tho.
* @buf: The output buffer to write to.
* @knob: The PF_AUTOBOOT or PF_AUTOSEARCH flag
*/
-static ssize_t
-pdcs_auto_read(struct subsystem *entry, char *buf, int knob)
+static ssize_t pdcs_auto_read(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf, int knob)
{
char *out = buf;
struct pdcspath_entry *pathentry;
- if (!entry || !buf)
+ if (!buf)
return -EINVAL;
/* Current flags are stored in primary boot path entry */
@@ -565,40 +566,37 @@ pdcs_auto_read(struct subsystem *entry, char *buf, int knob)
/**
* pdcs_autoboot_read - Stable Storage autoboot flag output.
- * @entry: An allocated and populated subsytem struct. We don't use it tho.
* @buf: The output buffer to write to.
*/
-static inline ssize_t
-pdcs_autoboot_read(struct subsystem *entry, char *buf)
+static ssize_t pdcs_autoboot_read(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
{
- return pdcs_auto_read(entry, buf, PF_AUTOBOOT);
+ return pdcs_auto_read(kobj, attr, buf, PF_AUTOBOOT);
}
/**
* pdcs_autosearch_read - Stable Storage autoboot flag output.
- * @entry: An allocated and populated subsytem struct. We don't use it tho.
* @buf: The output buffer to write to.
*/
-static inline ssize_t
-pdcs_autosearch_read(struct subsystem *entry, char *buf)
+static ssize_t pdcs_autosearch_read(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
{
- return pdcs_auto_read(entry, buf, PF_AUTOSEARCH);
+ return pdcs_auto_read(kobj, attr, buf, PF_AUTOSEARCH);
}
/**
* pdcs_timer_read - Stable Storage timer count output (in seconds).
- * @entry: An allocated and populated subsytem struct. We don't use it tho.
* @buf: The output buffer to write to.
*
* The value of the timer field correponds to a number of seconds in powers of 2.
*/
-static ssize_t
-pdcs_timer_read(struct subsystem *entry, char *buf)
+static ssize_t pdcs_timer_read(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
{
char *out = buf;
struct pdcspath_entry *pathentry;
- if (!entry || !buf)
+ if (!buf)
return -EINVAL;
/* Current flags are stored in primary boot path entry */
@@ -615,15 +613,14 @@ pdcs_timer_read(struct subsystem *entry, char *buf)
/**
* pdcs_osid_read - Stable Storage OS ID register output.
- * @entry: An allocated and populated subsytem struct. We don't use it tho.
* @buf: The output buffer to write to.
*/
-static ssize_t
-pdcs_osid_read(struct subsystem *entry, char *buf)
+static ssize_t pdcs_osid_read(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
{
char *out = buf;
- if (!entry || !buf)
+ if (!buf)
return -EINVAL;
out += sprintf(out, "%s dependent data (0x%.4x)\n",
@@ -634,18 +631,17 @@ pdcs_osid_read(struct subsystem *entry, char *buf)
/**
* pdcs_osdep1_read - Stable Storage OS-Dependent data area 1 output.
- * @entry: An allocated and populated subsytem struct. We don't use it tho.
* @buf: The output buffer to write to.
*
* This can hold 16 bytes of OS-Dependent data.
*/
-static ssize_t
-pdcs_osdep1_read(struct subsystem *entry, char *buf)
+static ssize_t pdcs_osdep1_read(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
{
char *out = buf;
u32 result[4];
- if (!entry || !buf)
+ if (!buf)
return -EINVAL;
if (pdc_stable_read(PDCS_ADDR_OSD1, &result, sizeof(result)) != PDC_OK)
@@ -661,18 +657,17 @@ pdcs_osdep1_read(struct subsystem *entry, char *buf)
/**
* pdcs_diagnostic_read - Stable Storage Diagnostic register output.
- * @entry: An allocated and populated subsytem struct. We don't use it tho.
* @buf: The output buffer to write to.
*
* I have NFC how to interpret the content of that register ;-).
*/
-static ssize_t
-pdcs_diagnostic_read(struct subsystem *entry, char *buf)
+static ssize_t pdcs_diagnostic_read(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
{
char *out = buf;
u32 result;
- if (!entry || !buf)
+ if (!buf)
return -EINVAL;
/* get diagnostic */
@@ -686,18 +681,17 @@ pdcs_diagnostic_read(struct subsystem *entry, char *buf)
/**
* pdcs_fastsize_read - Stable Storage FastSize register output.
- * @entry: An allocated and populated subsytem struct. We don't use it tho.
* @buf: The output buffer to write to.
*
* This register holds the amount of system RAM to be tested during boot sequence.
*/
-static ssize_t
-pdcs_fastsize_read(struct subsystem *entry, char *buf)
+static ssize_t pdcs_fastsize_read(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
{
char *out = buf;
u32 result;
- if (!entry || !buf)
+ if (!buf)
return -EINVAL;
/* get fast-size */
@@ -715,13 +709,12 @@ pdcs_fastsize_read(struct subsystem *entry, char *buf)
/**
* pdcs_osdep2_read - Stable Storage OS-Dependent data area 2 output.
- * @entry: An allocated and populated subsytem struct. We don't use it tho.
* @buf: The output buffer to write to.
*
* This can hold pdcs_size - 224 bytes of OS-Dependent data, when available.
*/
-static ssize_t
-pdcs_osdep2_read(struct subsystem *entry, char *buf)
+static ssize_t pdcs_osdep2_read(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
{
char *out = buf;
unsigned long size;
@@ -733,7 +726,7 @@ pdcs_osdep2_read(struct subsystem *entry, char *buf)
size = pdcs_size - 224;
- if (!entry || !buf)
+ if (!buf)
return -EINVAL;
for (i=0; i<size; i+=4) {
@@ -748,7 +741,6 @@ pdcs_osdep2_read(struct subsystem *entry, char *buf)
/**
* pdcs_auto_write - This function handles autoboot/search flag modifying.
- * @entry: An allocated and populated subsytem struct. We don't use it tho.
* @buf: The input buffer to read from.
* @count: The number of bytes to be read.
* @knob: The PF_AUTOBOOT or PF_AUTOSEARCH flag
@@ -757,8 +749,9 @@ pdcs_osdep2_read(struct subsystem *entry, char *buf)
* We expect a precise syntax:
* \"n\" (n == 0 or 1) to toggle AutoBoot Off or On
*/
-static ssize_t
-pdcs_auto_write(struct subsystem *entry, const char *buf, size_t count, int knob)
+static ssize_t pdcs_auto_write(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf,
+ size_t count, int knob)
{
struct pdcspath_entry *pathentry;
unsigned char flags;
@@ -768,7 +761,7 @@ pdcs_auto_write(struct subsystem *entry, const char *buf, size_t count, int knob
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
- if (!entry || !buf || !count)
+ if (!buf || !count)
return -EINVAL;
/* We'll use a local copy of buf */
@@ -784,12 +777,9 @@ pdcs_auto_write(struct subsystem *entry, const char *buf, size_t count, int knob
read_unlock(&pathentry->rw_lock);
DPRINTK("%s: flags before: 0x%X\n", __func__, flags);
-
- temp = in;
-
- while (*temp && isspace(*temp))
- temp++;
-
+
+ temp = skip_spaces(in);
+
c = *temp++ - '0';
if ((c != 0) && (c != 1))
goto parse_error;
@@ -823,7 +813,6 @@ parse_error:
/**
* pdcs_autoboot_write - This function handles autoboot flag modifying.
- * @entry: An allocated and populated subsytem struct. We don't use it tho.
* @buf: The input buffer to read from.
* @count: The number of bytes to be read.
*
@@ -831,15 +820,15 @@ parse_error:
* We expect a precise syntax:
* \"n\" (n == 0 or 1) to toggle AutoSearch Off or On
*/
-static inline ssize_t
-pdcs_autoboot_write(struct subsystem *entry, const char *buf, size_t count)
+static ssize_t pdcs_autoboot_write(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
{
- return pdcs_auto_write(entry, buf, count, PF_AUTOBOOT);
+ return pdcs_auto_write(kobj, attr, buf, count, PF_AUTOBOOT);
}
/**
* pdcs_autosearch_write - This function handles autosearch flag modifying.
- * @entry: An allocated and populated subsytem struct. We don't use it tho.
* @buf: The input buffer to read from.
* @count: The number of bytes to be read.
*
@@ -847,15 +836,15 @@ pdcs_autoboot_write(struct subsystem *entry, const char *buf, size_t count)
* We expect a precise syntax:
* \"n\" (n == 0 or 1) to toggle AutoSearch Off or On
*/
-static inline ssize_t
-pdcs_autosearch_write(struct subsystem *entry, const char *buf, size_t count)
+static ssize_t pdcs_autosearch_write(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
{
- return pdcs_auto_write(entry, buf, count, PF_AUTOSEARCH);
+ return pdcs_auto_write(kobj, attr, buf, count, PF_AUTOSEARCH);
}
/**
* pdcs_osdep1_write - Stable Storage OS-Dependent data area 1 input.
- * @entry: An allocated and populated subsytem struct. We don't use it tho.
* @buf: The input buffer to read from.
* @count: The number of bytes to be read.
*
@@ -863,15 +852,16 @@ pdcs_autosearch_write(struct subsystem *entry, const char *buf, size_t count)
* write approach. It's up to userspace to deal with it when constructing
* its input buffer.
*/
-static ssize_t
-pdcs_osdep1_write(struct subsystem *entry, const char *buf, size_t count)
+static ssize_t pdcs_osdep1_write(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
{
u8 in[16];
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
- if (!entry || !buf || !count)
+ if (!buf || !count)
return -EINVAL;
if (unlikely(pdcs_osid != OS_ID_LINUX))
@@ -892,7 +882,6 @@ pdcs_osdep1_write(struct subsystem *entry, const char *buf, size_t count)
/**
* pdcs_osdep2_write - Stable Storage OS-Dependent data area 2 input.
- * @entry: An allocated and populated subsytem struct. We don't use it tho.
* @buf: The input buffer to read from.
* @count: The number of bytes to be read.
*
@@ -900,8 +889,9 @@ pdcs_osdep1_write(struct subsystem *entry, const char *buf, size_t count)
* byte-by-byte write approach. It's up to userspace to deal with it when
* constructing its input buffer.
*/
-static ssize_t
-pdcs_osdep2_write(struct subsystem *entry, const char *buf, size_t count)
+static ssize_t pdcs_osdep2_write(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
{
unsigned long size;
unsigned short i;
@@ -910,7 +900,7 @@ pdcs_osdep2_write(struct subsystem *entry, const char *buf, size_t count)
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
- if (!entry || !buf || !count)
+ if (!buf || !count)
return -EINVAL;
if (unlikely(pdcs_size <= 224))
@@ -948,21 +938,25 @@ static PDCS_ATTR(diagnostic, 0400, pdcs_diagnostic_read, NULL);
static PDCS_ATTR(fastsize, 0400, pdcs_fastsize_read, NULL);
static PDCS_ATTR(osdep2, 0600, pdcs_osdep2_read, pdcs_osdep2_write);
-static struct subsys_attribute *pdcs_subsys_attrs[] = {
- &pdcs_attr_size,
- &pdcs_attr_autoboot,
- &pdcs_attr_autosearch,
- &pdcs_attr_timer,
- &pdcs_attr_osid,
- &pdcs_attr_osdep1,
- &pdcs_attr_diagnostic,
- &pdcs_attr_fastsize,
- &pdcs_attr_osdep2,
+static struct attribute *pdcs_subsys_attrs[] = {
+ &pdcs_attr_size.attr,
+ &pdcs_attr_autoboot.attr,
+ &pdcs_attr_autosearch.attr,
+ &pdcs_attr_timer.attr,
+ &pdcs_attr_osid.attr,
+ &pdcs_attr_osdep1.attr,
+ &pdcs_attr_diagnostic.attr,
+ &pdcs_attr_fastsize.attr,
+ &pdcs_attr_osdep2.attr,
NULL,
};
-static decl_subsys(paths, &ktype_pdcspath, NULL);
-static decl_subsys(stable, NULL, NULL);
+static struct attribute_group pdcs_attr_group = {
+ .attrs = pdcs_subsys_attrs,
+};
+
+static struct kobject *stable_kobj;
+static struct kset *paths_kset;
/**
* pdcs_register_pathentries - Prepares path entries kobjects for sysfs usage.
@@ -992,21 +986,24 @@ pdcs_register_pathentries(void)
if (err < 0)
continue;
- if ((err = kobject_set_name(&entry->kobj, "%s", entry->name)))
+ entry->kobj.kset = paths_kset;
+ err = kobject_init_and_add(&entry->kobj, &ktype_pdcspath, NULL,
+ "%s", entry->name);
+ if (err)
return err;
- kobj_set_kset_s(entry, paths_subsys);
- if ((err = kobject_register(&entry->kobj)))
- return err;
-
+
/* kobject is now registered */
write_lock(&entry->rw_lock);
entry->ready = 2;
/* Add a nice symlink to the real device */
- if (entry->dev)
- sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device");
+ if (entry->dev) {
+ err = sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device");
+ WARN_ON(err);
+ }
write_unlock(&entry->rw_lock);
+ kobject_uevent(&entry->kobj, KOBJ_ADD);
}
return 0;
@@ -1024,7 +1021,7 @@ pdcs_unregister_pathentries(void)
for (i = 0; (entry = pdcspath_entries[i]); i++) {
read_lock(&entry->rw_lock);
if (entry->ready >= 2)
- kobject_unregister(&entry->kobj);
+ kobject_put(&entry->kobj);
read_unlock(&entry->rw_lock);
}
}
@@ -1036,8 +1033,7 @@ pdcs_unregister_pathentries(void)
static int __init
pdc_stable_init(void)
{
- struct subsys_attribute *attr;
- int i, rc = 0, error = 0;
+ int rc = 0, error = 0;
u32 result;
/* find the size of the stable storage */
@@ -1057,21 +1053,24 @@ pdc_stable_init(void)
/* the actual result is 16 bits away */
pdcs_osid = (u16)(result >> 16);
- /* For now we'll register the stable subsys within this driver */
- if ((rc = firmware_register(&stable_subsys)))
+ /* For now we'll register the directory at /sys/firmware/stable */
+ stable_kobj = kobject_create_and_add("stable", firmware_kobj);
+ if (!stable_kobj) {
+ rc = -ENOMEM;
goto fail_firmreg;
+ }
/* Don't forget the root entries */
- for (i = 0; (attr = pdcs_subsys_attrs[i]) && !error; i++)
- if (attr->show)
- error = subsys_create_file(&stable_subsys, attr);
-
- /* register the paths subsys as a subsystem of stable subsys */
- kset_set_kset_s(&paths_subsys, stable_subsys);
- if ((rc = subsystem_register(&paths_subsys)))
- goto fail_subsysreg;
+ error = sysfs_create_group(stable_kobj, &pdcs_attr_group);
- /* now we create all "files" for the paths subsys */
+ /* register the paths kset as a child of the stable kset */
+ paths_kset = kset_create_and_add("paths", NULL, stable_kobj);
+ if (!paths_kset) {
+ rc = -ENOMEM;
+ goto fail_ksetreg;
+ }
+
+ /* now we create all "files" for the paths kset */
if ((rc = pdcs_register_pathentries()))
goto fail_pdcsreg;
@@ -1079,10 +1078,10 @@ pdc_stable_init(void)
fail_pdcsreg:
pdcs_unregister_pathentries();
- subsystem_unregister(&paths_subsys);
+ kset_unregister(paths_kset);
-fail_subsysreg:
- firmware_unregister(&stable_subsys);
+fail_ksetreg:
+ kobject_put(stable_kobj);
fail_firmreg:
printk(KERN_INFO PDCS_PREFIX " bailing out\n");
@@ -1093,9 +1092,8 @@ static void __exit
pdc_stable_exit(void)
{
pdcs_unregister_pathentries();
- subsystem_unregister(&paths_subsys);
-
- firmware_unregister(&stable_subsys);
+ kset_unregister(paths_kset);
+ kobject_put(stable_kobj);
}
diff --git a/drivers/parisc/power.c b/drivers/parisc/power.c
index fad5a33bf0f..90cca5e3805 100644
--- a/drivers/parisc/power.c
+++ b/drivers/parisc/power.c
@@ -1,8 +1,8 @@
/*
- * linux/arch/parisc/kernel/power.c
+ * linux/drivers/parisc/power.c
* HP PARISC soft power switch support driver
*
- * Copyright (c) 2001-2005 Helge Deller <deller@gmx.de>
+ * Copyright (c) 2001-2007 Helge Deller <deller@gmx.de>
* All rights reserved.
*
*
@@ -29,7 +29,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
*
*
- *
* HINT:
* Support of the soft power switch button may be enabled or disabled at
* runtime through the "/proc/sys/kernel/power" procfs entry.
@@ -38,34 +37,29 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
-#include <linux/string.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/workqueue.h>
+#include <linux/kthread.h>
+#include <linux/pm.h>
#include <asm/pdc.h>
#include <asm/io.h>
#include <asm/led.h>
-#include <asm/uaccess.h>
+#define DRIVER_NAME "powersw"
+#define KTHREAD_NAME "kpowerswd"
-#ifdef DEBUG
-# define DPRINTK(x...) printk(x)
-#else
-# define DPRINTK(x...)
-#endif
-
-
-/* filename in /proc which can be used to enable/disable the power switch */
-#define SYSCTL_FILENAME "sys/kernel/power"
+/* how often should the power button be polled ? */
+#define POWERSWITCH_POLL_PER_SEC 2
+/* how long does the power button needs to be down until we react ? */
+#define POWERSWITCH_DOWN_SEC 2
+/* assembly code to access special registers */
+/* taken from PCXL ERS page 82 */
#define DIAG_CODE(code) (0x14000000 + ((code)<<5))
-/* this will go to processor.h or any other place... */
-/* taken from PCXL ERS page 82 */
#define MFCPU_X(rDiagReg, t_ch, t_th, code) \
(DIAG_CODE(code) + ((rDiagReg)<<21) + ((t_ch)<<16) + ((t_th)<<0) )
@@ -76,112 +70,95 @@
#define __getDIAG(dr) ( { \
register unsigned long __res asm("r28");\
__asm__ __volatile__ ( \
- ".word %1\n nop\n" : "=&r" (__res) : "i" (MFCPU_T(dr,28)) \
+ ".word %1" : "=&r" (__res) : "i" (MFCPU_T(dr,28) ) \
); \
__res; \
} )
-
-static void deferred_poweroff(void *dummy)
-{
- extern int cad_pid; /* from kernel/sys.c */
- if (kill_proc(cad_pid, SIGINT, 1)) {
- /* just in case killing init process failed */
- machine_power_off();
- }
-}
-
-/*
- * This function gets called from interrupt context.
- * As it's called within an interrupt, it wouldn't sync if we don't
- * use schedule_work().
- */
-
-static DECLARE_WORK(poweroff_work, deferred_poweroff, NULL);
-
-static void poweroff(void)
-{
- static int powering_off __read_mostly;
-
- if (powering_off)
- return;
-
- powering_off++;
- schedule_work(&poweroff_work);
-}
-
-
-/* local time-counter for shutdown */
+/* local shutdown counter */
static int shutdown_timer __read_mostly;
/* check, give feedback and start shutdown after one second */
static void process_shutdown(void)
{
if (shutdown_timer == 0)
- DPRINTK(KERN_INFO "Shutdown requested...\n");
+ printk(KERN_ALERT KTHREAD_NAME ": Shutdown requested...\n");
shutdown_timer++;
/* wait until the button was pressed for 1 second */
- if (shutdown_timer == HZ) {
-#if defined (DEBUG) || defined(CONFIG_CHASSIS_LCD_LED)
- static char msg[] = "Shutting down...";
-#endif
- DPRINTK(KERN_INFO "%s\n", msg);
+ if (shutdown_timer == (POWERSWITCH_DOWN_SEC*POWERSWITCH_POLL_PER_SEC)) {
+ static const char msg[] = "Shutting down...";
+ printk(KERN_INFO KTHREAD_NAME ": %s\n", msg);
lcd_print(msg);
- poweroff();
+
+ /* send kill signal */
+ if (kill_cad_pid(SIGINT, 1)) {
+ /* just in case killing init process failed */
+ if (pm_power_off)
+ pm_power_off();
+ }
}
}
-/* main power switch tasklet struct (scheduled from time.c) */
-DECLARE_TASKLET_DISABLED(power_tasklet, NULL, 0);
+/* main power switch task struct */
+static struct task_struct *power_task;
+
+/* filename in /proc which can be used to enable/disable the power switch */
+#define SYSCTL_FILENAME "sys/kernel/power"
/* soft power switch enabled/disabled */
int pwrsw_enabled __read_mostly = 1;
-/*
- * On gecko style machines (e.g. 712/xx and 715/xx)
- * the power switch status is stored in Bit 0 ("the highest bit")
- * of CPU diagnose register 25.
- *
- */
-static void gecko_tasklet_func(unsigned long unused)
+/* main kernel thread worker. It polls the button state */
+static int kpowerswd(void *param)
{
- if (unlikely(!pwrsw_enabled))
- return;
-
- if (__getDIAG(25) & 0x80000000) {
- /* power switch button not pressed or released again */
- /* Warning: Some machines do never reset this DIAG flag! */
- shutdown_timer = 0;
- } else {
- process_shutdown();
- }
-}
-
+ __set_current_state(TASK_RUNNING);
+
+ do {
+ int button_not_pressed;
+ unsigned long soft_power_reg = (unsigned long) param;
+
+ schedule_timeout_interruptible(pwrsw_enabled ? HZ : HZ/POWERSWITCH_POLL_PER_SEC);
+ __set_current_state(TASK_RUNNING);
+
+ if (unlikely(!pwrsw_enabled))
+ continue;
+
+ if (soft_power_reg) {
+ /*
+ * Non-Gecko-style machines:
+ * Check the power switch status which is read from the
+ * real I/O location at soft_power_reg.
+ * Bit 31 ("the lowest bit) is the status of the power switch.
+ * This bit is "1" if the button is NOT pressed.
+ */
+ button_not_pressed = (gsc_readl(soft_power_reg) & 0x1);
+ } else {
+ /*
+ * On gecko style machines (e.g. 712/xx and 715/xx)
+ * the power switch status is stored in Bit 0 ("the highest bit")
+ * of CPU diagnose register 25.
+ * Warning: Some machines never reset the DIAG flag, even if
+ * the button has been released again.
+ */
+ button_not_pressed = (__getDIAG(25) & 0x80000000);
+ }
+
+ if (likely(button_not_pressed)) {
+ if (unlikely(shutdown_timer && /* avoid writing if not necessary */
+ shutdown_timer < (POWERSWITCH_DOWN_SEC*POWERSWITCH_POLL_PER_SEC))) {
+ shutdown_timer = 0;
+ printk(KERN_INFO KTHREAD_NAME ": Shutdown request aborted.\n");
+ }
+ } else
+ process_shutdown();
+
+
+ } while (!kthread_should_stop());
-
-/*
- * Check the power switch status which is read from the
- * real I/O location at soft_power_reg.
- * Bit 31 ("the lowest bit) is the status of the power switch.
- */
-
-static void polling_tasklet_func(unsigned long soft_power_reg)
-{
- unsigned long current_status;
-
- if (unlikely(!pwrsw_enabled))
- return;
-
- current_status = gsc_readl(soft_power_reg);
- if (current_status & 0x1) {
- /* power switch button not pressed */
- shutdown_timer = 0;
- } else {
- process_shutdown();
- }
+ return 0;
}
@@ -189,7 +166,7 @@ static void polling_tasklet_func(unsigned long soft_power_reg)
* powerfail interruption handler (irq IRQ_FROM_REGION(CPU_IRQ_REGION)+2)
*/
#if 0
-static void powerfail_interrupt(int code, void *x, struct pt_regs *regs)
+static void powerfail_interrupt(int code, void *x)
{
printk(KERN_CRIT "POWERFAIL INTERRUPTION !\n");
poweroff();
@@ -221,7 +198,7 @@ static struct notifier_block parisc_panic_block = {
static int __init power_init(void)
{
unsigned long ret;
- unsigned long soft_power_reg = 0;
+ unsigned long soft_power_reg;
#if 0
request_irq( IRQ_FROM_REGION(CPU_IRQ_REGION)+2, &powerfail_interrupt,
@@ -236,44 +213,44 @@ static int __init power_init(void)
soft_power_reg = -1UL;
switch (soft_power_reg) {
- case 0: printk(KERN_INFO "Gecko-style soft power switch enabled.\n");
- power_tasklet.func = gecko_tasklet_func;
+ case 0: printk(KERN_INFO DRIVER_NAME ": Gecko-style soft power switch enabled.\n");
break;
- case -1UL: printk(KERN_INFO "Soft power switch support not available.\n");
+ case -1UL: printk(KERN_INFO DRIVER_NAME ": Soft power switch support not available.\n");
return -ENODEV;
- default: printk(KERN_INFO "Soft power switch enabled, polling @ 0x%08lx.\n",
+ default: printk(KERN_INFO DRIVER_NAME ": Soft power switch at 0x%08lx enabled.\n",
soft_power_reg);
- power_tasklet.data = soft_power_reg;
- power_tasklet.func = polling_tasklet_func;
+ }
+
+ power_task = kthread_run(kpowerswd, (void*)soft_power_reg, KTHREAD_NAME);
+ if (IS_ERR(power_task)) {
+ printk(KERN_ERR DRIVER_NAME ": thread creation failed. Driver not loaded.\n");
+ pdc_soft_power_button(0);
+ return -EIO;
}
/* Register a call for panic conditions. */
atomic_notifier_chain_register(&panic_notifier_list,
&parisc_panic_block);
- tasklet_enable(&power_tasklet);
-
return 0;
}
static void __exit power_exit(void)
{
- if (!power_tasklet.func)
- return;
+ kthread_stop(power_task);
- tasklet_disable(&power_tasklet);
atomic_notifier_chain_unregister(&panic_notifier_list,
&parisc_panic_block);
- power_tasklet.func = NULL;
+
pdc_soft_power_button(0);
}
-module_init(power_init);
+arch_initcall(power_init);
module_exit(power_exit);
-MODULE_AUTHOR("Helge Deller");
+MODULE_AUTHOR("Helge Deller <deller@gmx.de>");
MODULE_DESCRIPTION("Soft power switch driver");
MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
index 8b473281551..1ff1b67e8b2 100644
--- a/drivers/parisc/sba_iommu.c
+++ b/drivers/parisc/sba_iommu.c
@@ -28,6 +28,8 @@
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/pci.h>
+#include <linux/scatterlist.h>
+#include <linux/iommu-helper.h>
#include <asm/byteorder.h>
#include <asm/io.h>
@@ -37,23 +39,18 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <linux/module.h>
+#include <asm/ropes.h>
+#include <asm/mckinley.h> /* for proc_mckinley_root */
#include <asm/runway.h> /* for proc_runway_root */
+#include <asm/page.h> /* for PAGE0 */
#include <asm/pdc.h> /* for PDC_MODEL_* */
#include <asm/pdcpat.h> /* for is_pdc_pat() */
#include <asm/parisc-device.h>
-
-/* declared in arch/parisc/kernel/setup.c */
-extern struct proc_dir_entry * proc_mckinley_root;
-
#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
@@ -92,202 +89,12 @@ extern struct proc_dir_entry * proc_mckinley_root;
#define DBG_RES(x...)
#endif
-#if defined(CONFIG_64BIT)
-/* "low end" PA8800 machines use ZX1 chipset: PAT PDC and only run 64-bit */
-#define ZX1_SUPPORT
-#endif
-
#define SBA_INLINE __inline__
-
-/*
-** The number of pdir entries to "free" before issueing
-** a read to PCOM register to flush out PCOM writes.
-** Interacts with allocation granularity (ie 4 or 8 entries
-** allocated and free'd/purged at a time might make this
-** less interesting).
-*/
-#define DELAYED_RESOURCE_CNT 16
-
#define DEFAULT_DMA_HINT_REG 0
-#define ASTRO_RUNWAY_PORT 0x582
-#define IKE_MERCED_PORT 0x803
-#define REO_MERCED_PORT 0x804
-#define REOG_MERCED_PORT 0x805
-#define PLUTO_MCKINLEY_PORT 0x880
-
-#define SBA_FUNC_ID 0x0000 /* function id */
-#define SBA_FCLASS 0x0008 /* function class, bist, header, rev... */
-
-#define IS_ASTRO(id) ((id)->hversion == ASTRO_RUNWAY_PORT)
-#define IS_IKE(id) ((id)->hversion == IKE_MERCED_PORT)
-#define IS_PLUTO(id) ((id)->hversion == PLUTO_MCKINLEY_PORT)
-
-#define SBA_FUNC_SIZE 4096 /* SBA configuration function reg set */
-
-#define ASTRO_IOC_OFFSET (32 * SBA_FUNC_SIZE)
-#define PLUTO_IOC_OFFSET (1 * SBA_FUNC_SIZE)
-/* Ike's IOC's occupy functions 2 and 3 */
-#define IKE_IOC_OFFSET(p) ((p+2) * SBA_FUNC_SIZE)
-
-#define IOC_CTRL 0x8 /* IOC_CTRL offset */
-#define IOC_CTRL_TC (1 << 0) /* TOC Enable */
-#define IOC_CTRL_CE (1 << 1) /* Coalesce Enable */
-#define IOC_CTRL_DE (1 << 2) /* Dillon Enable */
-#define IOC_CTRL_RM (1 << 8) /* Real Mode */
-#define IOC_CTRL_NC (1 << 9) /* Non Coherent Mode */
-#define IOC_CTRL_D4 (1 << 11) /* Disable 4-byte coalescing */
-#define IOC_CTRL_DD (1 << 13) /* Disable distr. LMMIO range coalescing */
-
-#define MAX_IOC 2 /* per Ike. Pluto/Astro only have 1. */
-
-#define ROPES_PER_IOC 8 /* per Ike half or Pluto/Astro */
-
-
-/*
-** Offsets into MBIB (Function 0 on Ike and hopefully Astro)
-** Firmware programs this stuff. Don't touch it.
-*/
-#define LMMIO_DIRECT0_BASE 0x300
-#define LMMIO_DIRECT0_MASK 0x308
-#define LMMIO_DIRECT0_ROUTE 0x310
-
-#define LMMIO_DIST_BASE 0x360
-#define LMMIO_DIST_MASK 0x368
-#define LMMIO_DIST_ROUTE 0x370
-
-#define IOS_DIST_BASE 0x390
-#define IOS_DIST_MASK 0x398
-#define IOS_DIST_ROUTE 0x3A0
-
-#define IOS_DIRECT_BASE 0x3C0
-#define IOS_DIRECT_MASK 0x3C8
-#define IOS_DIRECT_ROUTE 0x3D0
-
-/*
-** Offsets into I/O TLB (Function 2 and 3 on Ike)
-*/
-#define ROPE0_CTL 0x200 /* "regbus pci0" */
-#define ROPE1_CTL 0x208
-#define ROPE2_CTL 0x210
-#define ROPE3_CTL 0x218
-#define ROPE4_CTL 0x220
-#define ROPE5_CTL 0x228
-#define ROPE6_CTL 0x230
-#define ROPE7_CTL 0x238
-
-#define IOC_ROPE0_CFG 0x500 /* pluto only */
-#define IOC_ROPE_AO 0x10 /* Allow "Relaxed Ordering" */
-
-
-
-#define HF_ENABLE 0x40
-
-
-#define IOC_IBASE 0x300 /* IO TLB */
-#define IOC_IMASK 0x308
-#define IOC_PCOM 0x310
-#define IOC_TCNFG 0x318
-#define IOC_PDIR_BASE 0x320
-
-/* AGP GART driver looks for this */
-#define SBA_IOMMU_COOKIE 0x0000badbadc0ffeeUL
-
-
-/*
-** IOC supports 4/8/16/64KB page sizes (see TCNFG register)
-** It's safer (avoid memory corruption) to keep DMA page mappings
-** equivalently sized to VM PAGE_SIZE.
-**
-** We really can't avoid generating a new mapping for each
-** page since the Virtual Coherence Index has to be generated
-** and updated for each page.
-**
-** PAGE_SIZE could be greater than IOVP_SIZE. But not the inverse.
-*/
-#define IOVP_SIZE PAGE_SIZE
-#define IOVP_SHIFT PAGE_SHIFT
-#define IOVP_MASK PAGE_MASK
-
-#define SBA_PERF_CFG 0x708 /* Performance Counter stuff */
-#define SBA_PERF_MASK1 0x718
-#define SBA_PERF_MASK2 0x730
-
-
-/*
-** Offsets into PCI Performance Counters (functions 12 and 13)
-** Controlled by PERF registers in function 2 & 3 respectively.
-*/
-#define SBA_PERF_CNT1 0x200
-#define SBA_PERF_CNT2 0x208
-#define SBA_PERF_CNT3 0x210
-
-
-struct ioc {
- void __iomem *ioc_hpa; /* I/O MMU base address */
- char *res_map; /* resource map, bit == pdir entry */
- u64 *pdir_base; /* physical base address */
- unsigned long ibase; /* pdir IOV Space base - shared w/lba_pci */
- unsigned long imask; /* pdir IOV Space mask - shared w/lba_pci */
-#ifdef ZX1_SUPPORT
- unsigned long iovp_mask; /* help convert IOVA to IOVP */
-#endif
- unsigned long *res_hint; /* next avail IOVP - circular search */
- spinlock_t res_lock;
- unsigned int res_bitshift; /* from the LEFT! */
- unsigned int res_size; /* size of resource map in bytes */
-#ifdef SBA_HINT_SUPPORT
-/* FIXME : DMA HINTs not used */
- unsigned long hint_mask_pdir; /* bits used for DMA hints */
- unsigned int hint_shift_pdir;
-#endif
-#if DELAYED_RESOURCE_CNT > 0
- int saved_cnt;
- struct sba_dma_pair {
- dma_addr_t iova;
- size_t size;
- } saved[DELAYED_RESOURCE_CNT];
-#endif
-
-#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 */
- unsigned long used_pages;
- unsigned long msingle_calls;
- unsigned long msingle_pages;
- unsigned long msg_calls;
- unsigned long msg_pages;
- unsigned long usingle_calls;
- unsigned long usingle_pages;
- unsigned long usg_calls;
- unsigned long usg_pages;
-#endif
-
- /* STUFF We don't need in performance path */
- unsigned int pdir_size; /* in bytes, determined by IOV Space size */
-};
-
-struct sba_device {
- struct sba_device *next; /* list of SBA's in system */
- struct parisc_device *dev; /* dev found in bus walk */
- struct parisc_device_id *iodc; /* data about dev from firmware */
- const char *name;
- void __iomem *sba_hpa; /* base address */
- spinlock_t sba_lock;
- unsigned int flags; /* state/functionality enabled */
- unsigned int hw_rev; /* HW revision of chip */
-
- struct resource chip_resv; /* MMIO reserved for chip */
- struct resource iommu_resv; /* MMIO reserved for iommu */
-
- unsigned int num_ioc; /* number of on-board IOC's */
- struct ioc ioc[MAX_IOC];
-};
-
-
-static struct sba_device *sba_list;
+struct sba_device *sba_list;
+EXPORT_SYMBOL_GPL(sba_list);
static unsigned long ioc_needs_fdc = 0;
@@ -300,12 +107,16 @@ static unsigned long piranha_bad_128k = 0;
/* Looks nice and keeps the compiler happy */
#define SBA_DEV(d) ((struct sba_device *) (d))
+#ifdef CONFIG_AGP_PARISC
+#define SBA_AGP_SUPPORT
+#endif /*CONFIG_AGP_PARISC*/
+
#ifdef SBA_AGP_SUPPORT
-static int reserve_sba_gart = 1;
+static int sba_reserve_agpgart = 1;
+module_param(sba_reserve_agpgart, int, 0444);
+MODULE_PARM_DESC(sba_reserve_agpgart, "Reserve half of IO pdir as AGPGART");
#endif
-#define ROUNDUP(x,y) ((x + ((y)-1)) & ~((y)-1))
-
/************************************
** SBA register read and write support
@@ -505,6 +316,12 @@ sba_dump_sg( struct ioc *ioc, struct scatterlist *startsg, int nents)
#define RESMAP_MASK(n) (~0UL << (BITS_PER_LONG - (n)))
#define RESMAP_IDX_MASK (sizeof(unsigned long) - 1)
+static unsigned long ptr_to_pide(struct ioc *ioc, unsigned long *res_ptr,
+ unsigned int bitshiftcnt)
+{
+ return (((unsigned long)res_ptr - (unsigned long)ioc->res_map) << 3)
+ + bitshiftcnt;
+}
/**
* sba_search_bitmap - find free space in IO PDIR resource bitmap
@@ -516,19 +333,36 @@ sba_dump_sg( struct ioc *ioc, struct scatterlist *startsg, int nents)
* Cool perf optimization: search for log2(size) bits at a time.
*/
static SBA_INLINE unsigned long
-sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted)
+sba_search_bitmap(struct ioc *ioc, struct device *dev,
+ unsigned long bits_wanted)
{
unsigned long *res_ptr = ioc->res_hint;
unsigned long *res_end = (unsigned long *) &(ioc->res_map[ioc->res_size]);
- unsigned long pide = ~0UL;
+ unsigned long pide = ~0UL, tpide;
+ unsigned long boundary_size;
+ unsigned long shift;
+ int ret;
+
+ boundary_size = ALIGN((unsigned long long)dma_get_seg_boundary(dev) + 1,
+ 1ULL << IOVP_SHIFT) >> IOVP_SHIFT;
+
+#if defined(ZX1_SUPPORT)
+ BUG_ON(ioc->ibase & ~IOVP_MASK);
+ shift = ioc->ibase >> IOVP_SHIFT;
+#else
+ shift = 0;
+#endif
if (bits_wanted > (BITS_PER_LONG/2)) {
/* Search word at a time - no mask needed */
for(; res_ptr < res_end; ++res_ptr) {
- if (*res_ptr == 0) {
+ tpide = ptr_to_pide(ioc, res_ptr, 0);
+ ret = iommu_is_span_boundary(tpide, bits_wanted,
+ shift,
+ boundary_size);
+ if ((*res_ptr == 0) && !ret) {
*res_ptr = RESMAP_MASK(bits_wanted);
- pide = ((unsigned long)res_ptr - (unsigned long)ioc->res_map);
- pide <<= 3; /* convert to bit address */
+ pide = tpide;
break;
}
}
@@ -543,7 +377,7 @@ sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted)
** SBA HW features in the unmap path.
*/
unsigned long o = 1 << get_order(bits_wanted << PAGE_SHIFT);
- uint bitshiftcnt = ROUNDUP(ioc->res_bitshift, o);
+ uint bitshiftcnt = ALIGN(ioc->res_bitshift, o);
unsigned long mask;
if (bitshiftcnt >= BITS_PER_LONG) {
@@ -552,16 +386,18 @@ sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted)
}
mask = RESMAP_MASK(bits_wanted) >> bitshiftcnt;
- DBG_RES("%s() o %ld %p", __FUNCTION__, o, res_ptr);
+ DBG_RES("%s() o %ld %p", __func__, o, res_ptr);
while(res_ptr < res_end)
{
DBG_RES(" %p %lx %lx\n", res_ptr, mask, *res_ptr);
WARN_ON(mask == 0);
- if(((*res_ptr) & mask) == 0) {
+ tpide = ptr_to_pide(ioc, res_ptr, bitshiftcnt);
+ ret = iommu_is_span_boundary(tpide, bits_wanted,
+ shift,
+ boundary_size);
+ if ((((*res_ptr) & mask) == 0) && !ret) {
*res_ptr |= mask; /* mark resources busy! */
- pide = ((unsigned long)res_ptr - (unsigned long)ioc->res_map);
- pide <<= 3; /* convert to bit address */
- pide += bitshiftcnt;
+ pide = tpide;
break;
}
mask >>= o;
@@ -596,7 +432,7 @@ sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted)
* resource bit map.
*/
static int
-sba_alloc_range(struct ioc *ioc, size_t size)
+sba_alloc_range(struct ioc *ioc, struct device *dev, size_t size)
{
unsigned int pages_needed = size >> IOVP_SHIFT;
#ifdef SBA_COLLECT_STATS
@@ -604,9 +440,9 @@ sba_alloc_range(struct ioc *ioc, size_t size)
#endif
unsigned long pide;
- pide = sba_search_bitmap(ioc, pages_needed);
+ pide = sba_search_bitmap(ioc, dev, pages_needed);
if (pide >= (ioc->res_size << 3)) {
- pide = sba_search_bitmap(ioc, pages_needed);
+ pide = sba_search_bitmap(ioc, dev, pages_needed);
if (pide >= (ioc->res_size << 3))
panic("%s: I/O MMU @ %p is out of mapping resources\n",
__FILE__, ioc->ioc_hpa);
@@ -620,7 +456,7 @@ sba_alloc_range(struct ioc *ioc, size_t size)
#endif
DBG_RES("%s(%x) %d -> %lx hint %x/%x\n",
- __FUNCTION__, size, pages_needed, pide,
+ __func__, size, pages_needed, pide,
(uint) ((unsigned long) ioc->res_hint - (unsigned long) ioc->res_map),
ioc->res_bitshift );
@@ -663,7 +499,7 @@ sba_free_range(struct ioc *ioc, dma_addr_t iova, size_t size)
unsigned long m = RESMAP_MASK(bits_not_wanted) >> (pide & (BITS_PER_LONG - 1));
DBG_RES("%s( ,%x,%x) %x/%lx %x %p %lx\n",
- __FUNCTION__, (uint) iova, size,
+ __func__, (uint) iova, size,
bits_not_wanted, m, pide, res_ptr, *res_ptr);
#ifdef SBA_COLLECT_STATS
@@ -727,7 +563,7 @@ typedef unsigned long space_t;
* IOMMU uses little endian for the pdir.
*/
-void SBA_INLINE
+static void SBA_INLINE
sba_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba,
unsigned long hint)
{
@@ -739,9 +575,9 @@ sba_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba,
mtsp(sid,1);
asm("lci 0(%%sr1, %1), %0" : "=r" (ci) : "r" (vba));
- pa |= (ci >> 12) & 0xff; /* move CI (8 bits) into lowest byte */
+ pa |= (ci >> PAGE_SHIFT) & 0xff; /* move CI (8 bits) into lowest byte */
- pa |= 0x8000000000000000ULL; /* set "valid" bit */
+ pa |= SBA_PDIR_VALID_BIT; /* set "valid" bit */
*pdir_ptr = cpu_to_le64(pa); /* swap and store into I/O Pdir */
/*
@@ -834,7 +670,7 @@ sba_mark_invalid(struct ioc *ioc, dma_addr_t iova, size_t byte_cnt)
* @dev: instance of PCI owned by the driver that's asking
* @mask: number of address bits this PCI device can handle
*
- * See Documentation/DMA-mapping.txt
+ * See Documentation/DMA-API-HOWTO.txt
*/
static int sba_dma_supported( struct device *dev, u64 mask)
{
@@ -846,8 +682,8 @@ static int sba_dma_supported( struct device *dev, u64 mask)
return(0);
}
- /* Documentation/DMA-mapping.txt tells drivers to try 64-bit first,
- * then fall back to 32-bit if that fails.
+ /* Documentation/DMA-API-HOWTO.txt tells drivers to try 64-bit
+ * first, then fall back to 32-bit if that fails.
* We are just "encouraging" 32-bit DMA masks here since we can
* never allow IOMMU bypass unless we add special support for ZX1.
*/
@@ -872,7 +708,7 @@ static int sba_dma_supported( struct device *dev, u64 mask)
* @size: number of bytes to map in driver buffer.
* @direction: R/W or both.
*
- * See Documentation/DMA-mapping.txt
+ * See Documentation/DMA-API-HOWTO.txt
*/
static dma_addr_t
sba_map_single(struct device *dev, void *addr, size_t size,
@@ -902,11 +738,11 @@ sba_map_single(struct device *dev, void *addr, size_t size,
ioc->msingle_calls++;
ioc->msingle_pages += size >> IOVP_SHIFT;
#endif
- pide = sba_alloc_range(ioc, size);
+ pide = sba_alloc_range(ioc, dev, size);
iovp = (dma_addr_t) pide << IOVP_SHIFT;
DBG_RUN("%s() 0x%p -> 0x%lx\n",
- __FUNCTION__, addr, (long) iovp | offset);
+ __func__, addr, (long) iovp | offset);
pdir_start = &(ioc->pdir_base[pide]);
@@ -951,7 +787,7 @@ sba_map_single(struct device *dev, void *addr, size_t size,
* @size: number of bytes mapped in driver buffer.
* @direction: R/W or both.
*
- * See Documentation/DMA-mapping.txt
+ * See Documentation/DMA-API-HOWTO.txt
*/
static void
sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size,
@@ -964,13 +800,13 @@ sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size,
unsigned long flags;
dma_addr_t offset;
- DBG_RUN("%s() iovp 0x%lx/%x\n", __FUNCTION__, (long) iova, size);
+ DBG_RUN("%s() iovp 0x%lx/%x\n", __func__, (long) iova, size);
ioc = GET_IOC(dev);
offset = iova & ~IOVP_MASK;
iova ^= offset; /* clear offset bits */
size += offset;
- size = ROUNDUP(size, IOVP_SIZE);
+ size = ALIGN(size, IOVP_SIZE);
spin_lock_irqsave(&ioc->res_lock, flags);
@@ -1027,7 +863,7 @@ sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size,
* @size: number of bytes mapped in driver buffer.
* @dma_handle: IOVA of new buffer.
*
- * See Documentation/DMA-mapping.txt
+ * See Documentation/DMA-API-HOWTO.txt
*/
static void *sba_alloc_consistent(struct device *hwdev, size_t size,
dma_addr_t *dma_handle, gfp_t gfp)
@@ -1037,7 +873,7 @@ static void *sba_alloc_consistent(struct device *hwdev, size_t size,
if (!hwdev) {
/* only support PCI */
*dma_handle = 0;
- return 0;
+ return NULL;
}
ret = (void *) __get_free_pages(gfp, get_order(size));
@@ -1058,7 +894,7 @@ static void *sba_alloc_consistent(struct device *hwdev, size_t size,
* @vaddr: virtual address IOVA of "consistent" buffer.
* @dma_handler: IO virtual address of "consistent" buffer.
*
- * See Documentation/DMA-mapping.txt
+ * See Documentation/DMA-API-HOWTO.txt
*/
static void
sba_free_consistent(struct device *hwdev, size_t size, void *vaddr,
@@ -1093,7 +929,7 @@ int dump_run_sg = 0;
* @nents: number of entries in list
* @direction: R/W or both.
*
- * See Documentation/DMA-mapping.txt
+ * See Documentation/DMA-API-HOWTO.txt
*/
static int
sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
@@ -1103,7 +939,7 @@ sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
int coalesced, filled = 0;
unsigned long flags;
- DBG_RUN_SG("%s() START %d entries\n", __FUNCTION__, nents);
+ DBG_RUN_SG("%s() START %d entries\n", __func__, nents);
ioc = GET_IOC(dev);
@@ -1138,7 +974,7 @@ sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
** w/o this association, we wouldn't have coherent DMA!
** Access to the virtual address is what forces a two pass algorithm.
*/
- coalesced = iommu_coalesce_chunks(ioc, sglist, nents, sba_alloc_range);
+ coalesced = iommu_coalesce_chunks(ioc, dev, sglist, nents, sba_alloc_range);
/*
** Program the I/O Pdir
@@ -1164,7 +1000,7 @@ sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
spin_unlock_irqrestore(&ioc->res_lock, flags);
- DBG_RUN_SG("%s() DONE %d mappings\n", __FUNCTION__, filled);
+ DBG_RUN_SG("%s() DONE %d mappings\n", __func__, filled);
return filled;
}
@@ -1177,7 +1013,7 @@ sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
* @nents: number of entries in list
* @direction: R/W or both.
*
- * See Documentation/DMA-mapping.txt
+ * See Documentation/DMA-API-HOWTO.txt
*/
static void
sba_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents,
@@ -1189,7 +1025,7 @@ sba_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents,
#endif
DBG_RUN_SG("%s() START %d entries, %p,%x\n",
- __FUNCTION__, nents, sg_virt_addr(sglist), sglist->length);
+ __func__, nents, sg_virt_addr(sglist), sglist->length);
ioc = GET_IOC(dev);
@@ -1213,7 +1049,7 @@ sba_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents,
++sglist;
}
- DBG_RUN_SG("%s() DONE (nents %d)\n", __FUNCTION__, nents);
+ DBG_RUN_SG("%s() DONE (nents %d)\n", __func__, nents);
#ifdef ASSERT_PDIR_SANITY
spin_lock_irqsave(&ioc->res_lock, flags);
@@ -1284,7 +1120,7 @@ sba_alloc_pdir(unsigned int pdir_size)
pdir_base = __get_free_pages(GFP_KERNEL, pdir_order);
if (NULL == (void *) pdir_base) {
panic("%s() could not allocate I/O Page Table\n",
- __FUNCTION__);
+ __func__);
}
/* If this is not PA8700 (PCX-W2)
@@ -1372,31 +1208,49 @@ sba_alloc_pdir(unsigned int pdir_size)
return (void *) pdir_base;
}
-static struct device *next_device(struct klist_iter *i)
+struct ibase_data_struct {
+ struct ioc *ioc;
+ int ioc_num;
+};
+
+static int setup_ibase_imask_callback(struct device *dev, void *data)
{
- struct klist_node * n = klist_next(i);
- return n ? container_of(n, struct device, knode_parent) : NULL;
+ /* lba_set_iregs() is in drivers/parisc/lba_pci.c */
+ extern void lba_set_iregs(struct parisc_device *, u32, u32);
+ struct parisc_device *lba = to_parisc_device(dev);
+ struct ibase_data_struct *ibd = data;
+ int rope_num = (lba->hpa.start >> 13) & 0xf;
+ if (rope_num >> 3 == ibd->ioc_num)
+ lba_set_iregs(lba, ibd->ioc->ibase, ibd->ioc->imask);
+ return 0;
}
/* setup Mercury or Elroy IBASE/IMASK registers. */
static void
setup_ibase_imask(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
{
- /* lba_set_iregs() is in drivers/parisc/lba_pci.c */
- extern void lba_set_iregs(struct parisc_device *, u32, u32);
- struct device *dev;
- struct klist_iter i;
-
- klist_iter_init(&sba->dev.klist_children, &i);
- while ((dev = next_device(&i))) {
- struct parisc_device *lba = to_parisc_device(dev);
- int rope_num = (lba->hpa.start >> 13) & 0xf;
- if (rope_num >> 3 == ioc_num)
- lba_set_iregs(lba, ioc->ibase, ioc->imask);
- }
- klist_iter_exit(&i);
+ struct ibase_data_struct ibase_data = {
+ .ioc = ioc,
+ .ioc_num = ioc_num,
+ };
+
+ device_for_each_child(&sba->dev, &ibase_data,
+ setup_ibase_imask_callback);
}
+#ifdef SBA_AGP_SUPPORT
+static int
+sba_ioc_find_quicksilver(struct device *dev, void *data)
+{
+ int *agp_found = data;
+ struct parisc_device *lba = to_parisc_device(dev);
+
+ if (IS_QUICKSILVER(lba))
+ *agp_found = 1;
+ return 0;
+}
+#endif
+
static void
sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
{
@@ -1427,7 +1281,7 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
ioc->pdir_size = (iova_space_size / IOVP_SIZE) * sizeof(u64);
DBG_INIT("%s() hpa 0x%p IOV %dMB (%d bits)\n",
- __FUNCTION__, ioc->ioc_hpa, iova_space_size >> 20,
+ __func__, ioc->ioc_hpa, iova_space_size >> 20,
iov_order + PAGE_SHIFT);
ioc->pdir_base = (void *) __get_free_pages(GFP_KERNEL,
@@ -1438,7 +1292,7 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
memset(ioc->pdir_base, 0, ioc->pdir_size);
DBG_INIT("%s() pdir %p size %x\n",
- __FUNCTION__, ioc->pdir_base, ioc->pdir_size);
+ __func__, ioc->pdir_base, ioc->pdir_size);
#ifdef SBA_HINT_SUPPORT
ioc->hint_shift_pdir = iov_order + PAGE_SHIFT;
@@ -1498,6 +1352,7 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
WRITE_REG(ioc->ibase | 31, ioc->ioc_hpa + IOC_PCOM);
#ifdef SBA_AGP_SUPPORT
+
/*
** If an AGP device is present, only use half of the IOV space
** for PCI DMA. Unfortunately we can't know ahead of time
@@ -1506,28 +1361,22 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
** We program the next pdir index after we stop w/ a key for
** the GART code to handshake on.
*/
- device=NULL;
- for (lba = sba->child; lba; lba = lba->sibling) {
- if (IS_QUICKSILVER(lba))
- break;
- }
+ device_for_each_child(&sba->dev, &agp_found, sba_ioc_find_quicksilver);
- if (lba) {
- DBG_INIT("%s: Reserving half of IOVA space for AGP GART support\n", __FUNCTION__);
+ if (agp_found && sba_reserve_agpgart) {
+ printk(KERN_INFO "%s: reserving %dMb of IOVA space for agpgart\n",
+ __func__, (iova_space_size/2) >> 20);
ioc->pdir_size /= 2;
- ((u64 *)ioc->pdir_base)[PDIR_INDEX(iova_space_size/2)] = SBA_IOMMU_COOKIE;
- } else {
- DBG_INIT("%s: No GART needed - no AGP controller found\n", __FUNCTION__);
+ ioc->pdir_base[PDIR_INDEX(iova_space_size/2)] = SBA_AGPGART_COOKIE;
}
-#endif /* 0 */
-
+#endif /*SBA_AGP_SUPPORT*/
}
static void
sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
{
u32 iova_space_size, iova_space_mask;
- unsigned int pdir_size, iov_order;
+ unsigned int pdir_size, iov_order, tcnfg;
/*
** Determine IOVA Space size from memory size.
@@ -1543,7 +1392,7 @@ sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
** for DMA hints - ergo only 30 bits max.
*/
- iova_space_size = (u32) (num_physpages/global_ioc_cnt);
+ iova_space_size = (u32) (totalram_pages/global_ioc_cnt);
/* limit IOVA space size to 1MB-1GB */
if (iova_space_size < (1 << (20 - PAGE_SHIFT))) {
@@ -1566,16 +1415,16 @@ sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
ioc->pdir_size = pdir_size = (iova_space_size/IOVP_SIZE) * sizeof(u64);
DBG_INIT("%s() hpa 0x%lx mem %ldMB IOV %dMB (%d bits)\n",
- __FUNCTION__,
+ __func__,
ioc->ioc_hpa,
- (unsigned long) num_physpages >> (20 - PAGE_SHIFT),
+ (unsigned long) totalram_pages >> (20 - PAGE_SHIFT),
iova_space_size>>20,
iov_order + PAGE_SHIFT);
ioc->pdir_base = sba_alloc_pdir(pdir_size);
DBG_INIT("%s() pdir %p size %x\n",
- __FUNCTION__, ioc->pdir_base, pdir_size);
+ __func__, ioc->pdir_base, pdir_size);
#ifdef SBA_HINT_SUPPORT
/* FIXME : DMA HINTs not used */
@@ -1603,7 +1452,7 @@ sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
#endif
DBG_INIT("%s() IOV base 0x%lx mask 0x%0lx\n",
- __FUNCTION__, ioc->ibase, ioc->imask);
+ __func__, ioc->ibase, ioc->imask);
/*
** FIXME: Hint registers are programmed with default hint
@@ -1619,8 +1468,19 @@ sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
WRITE_REG(ioc->ibase | 1, ioc->ioc_hpa+IOC_IBASE);
WRITE_REG(ioc->imask, ioc->ioc_hpa+IOC_IMASK);
- /* Set I/O PDIR Page size to 4K */
- WRITE_REG(0, ioc->ioc_hpa+IOC_TCNFG);
+ /* Set I/O PDIR Page size to system page size */
+ switch (PAGE_SHIFT) {
+ case 12: tcnfg = 0; break; /* 4K */
+ case 13: tcnfg = 1; break; /* 8K */
+ case 14: tcnfg = 2; break; /* 16K */
+ case 16: tcnfg = 3; break; /* 64K */
+ default:
+ panic(__FILE__ "Unsupported system page size %d",
+ 1 << PAGE_SHIFT);
+ break;
+ }
+ /* Set I/O PDIR Page size to PAGE_SIZE (4k/16k/...) */
+ WRITE_REG(tcnfg, ioc->ioc_hpa+IOC_TCNFG);
/*
** Clear I/O TLB of any possible entries.
@@ -1630,7 +1490,7 @@ sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
ioc->ibase = 0; /* used by SBA_IOVA and related macros */
- DBG_INIT("%s() DONE\n", __FUNCTION__);
+ DBG_INIT("%s() DONE\n", __func__);
}
@@ -1701,10 +1561,10 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa,
}
#endif
- if (!IS_PLUTO(sba_dev->iodc)) {
+ if (!IS_PLUTO(sba_dev->dev)) {
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);
+ __func__, sba_dev->sba_hpa, ioc_ctl);
ioc_ctl &= ~(IOC_CTRL_RM | IOC_CTRL_NC | IOC_CTRL_CE);
ioc_ctl |= IOC_CTRL_DD | IOC_CTRL_D4 | IOC_CTRL_TC;
/* j6700 v1.6 firmware sets 0x294f */
@@ -1718,9 +1578,8 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa,
#endif
} /* if !PLUTO */
- if (IS_ASTRO(sba_dev->iodc)) {
+ if (IS_ASTRO(sba_dev->dev)) {
int err;
- /* PAT_PDC (L-class) also reports the same goofy base */
sba_dev->ioc[0].ioc_hpa = ioc_remap(sba_dev, ASTRO_IOC_OFFSET);
num_ioc = 1;
@@ -1730,13 +1589,9 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa,
err = request_resource(&iomem_resource, &(sba_dev->chip_resv));
BUG_ON(err < 0);
- } else if (IS_PLUTO(sba_dev->iodc)) {
+ } else if (IS_PLUTO(sba_dev->dev)) {
int err;
- /* We use a negative value for IOC HPA so it gets
- * corrected when we add it with IKE's IOC offset.
- * Doesnt look clean, but fewer code.
- */
sba_dev->ioc[0].ioc_hpa = ioc_remap(sba_dev, PLUTO_IOC_OFFSET);
num_ioc = 1;
@@ -1752,14 +1607,14 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa,
err = request_resource(&iomem_resource, &(sba_dev->iommu_resv));
WARN_ON(err < 0);
} else {
- /* IS_IKE (ie N-class, L3000, L1500) */
+ /* IKE, REO */
sba_dev->ioc[0].ioc_hpa = ioc_remap(sba_dev, IKE_IOC_OFFSET(0));
sba_dev->ioc[1].ioc_hpa = ioc_remap(sba_dev, IKE_IOC_OFFSET(1));
num_ioc = 2;
/* TODO - LOOKUP Ike/Stretch chipset mem map */
}
- /* XXX: What about Reo? */
+ /* XXX: What about Reo Grande? */
sba_dev->num_ioc = num_ioc;
for (i = 0; i < num_ioc; i++) {
@@ -1774,7 +1629,7 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa,
* Overrides bit 1 in DMA Hint Sets.
* Improves netperf UDP_STREAM by ~10% for bcm5701.
*/
- if (IS_PLUTO(sba_dev->iodc)) {
+ if (IS_PLUTO(sba_dev->dev)) {
void __iomem *rope_cfg;
unsigned long cfg_val;
@@ -1803,7 +1658,7 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa,
READ_REG(sba_dev->ioc[i].ioc_hpa + 0x400)
);
- if (IS_PLUTO(sba_dev->iodc)) {
+ if (IS_PLUTO(sba_dev->dev)) {
sba_ioc_init_pluto(sba_dev->dev, &(sba_dev->ioc[i]), i);
} else {
sba_ioc_init(sba_dev->dev, &(sba_dev->ioc[i]), i);
@@ -1840,7 +1695,7 @@ sba_common_init(struct sba_device *sba_dev)
res_size >>= 3; /* convert bit count to byte count */
DBG_INIT("%s() res_size 0x%x\n",
- __FUNCTION__, res_size);
+ __func__, res_size);
sba_dev->ioc[i].res_size = res_size;
sba_dev->ioc[i].res_map = (char *) __get_free_pages(GFP_KERNEL, get_order(res_size));
@@ -1853,7 +1708,7 @@ sba_common_init(struct sba_device *sba_dev)
if (NULL == sba_dev->ioc[i].res_map)
{
panic("%s:%s() could not allocate resource map\n",
- __FILE__, __FUNCTION__ );
+ __FILE__, __func__ );
}
memset(sba_dev->ioc[i].res_map, 0, res_size);
@@ -1890,7 +1745,7 @@ sba_common_init(struct sba_device *sba_dev)
#endif
DBG_INIT("%s() %d res_map %x %p\n",
- __FUNCTION__, i, res_size, sba_dev->ioc[i].res_map);
+ __func__, i, res_size, sba_dev->ioc[i].res_map);
}
spin_lock_init(&sba_dev->sba_lock);
@@ -1989,7 +1844,7 @@ sba_proc_open(struct inode *i, struct file *f)
return single_open(f, &sba_proc_info, NULL);
}
-static struct file_operations sba_proc_fops = {
+static const struct file_operations sba_proc_fops = {
.owner = THIS_MODULE,
.open = sba_proc_open,
.read = seq_read,
@@ -2021,7 +1876,7 @@ sba_proc_bitmap_open(struct inode *i, struct file *f)
return single_open(f, &sba_proc_bitmap_info, NULL);
}
-static struct file_operations sba_proc_bitmap_fops = {
+static const struct file_operations sba_proc_bitmap_fops = {
.owner = THIS_MODULE,
.open = sba_proc_bitmap_open,
.read = seq_read,
@@ -2039,7 +1894,7 @@ static struct parisc_device_id sba_tbl[] = {
{ 0, }
};
-int sba_driver_callback(struct parisc_device *);
+static int sba_driver_callback(struct parisc_device *);
static struct parisc_driver sba_driver = {
.name = MODULE_NAME,
@@ -2052,22 +1907,23 @@ static struct parisc_driver sba_driver = {
** If so, initialize the chip and tell other partners in crime they
** have work to do.
*/
-int
-sba_driver_callback(struct parisc_device *dev)
+static int sba_driver_callback(struct parisc_device *dev)
{
struct sba_device *sba_dev;
u32 func_class;
int i;
char *version;
void __iomem *sba_addr = ioremap_nocache(dev->hpa.start, SBA_FUNC_SIZE);
- struct proc_dir_entry *info_entry, *bitmap_entry, *root;
+#ifdef CONFIG_PROC_FS
+ struct proc_dir_entry *root;
+#endif
sba_dump_ranges(sba_addr);
/* Read HW Rev First */
func_class = READ_REG(sba_addr + SBA_FCLASS);
- if (IS_ASTRO(&dev->id)) {
+ if (IS_ASTRO(dev)) {
unsigned long fclass;
static char astro_rev[]="Astro ?.?";
@@ -2078,11 +1934,11 @@ sba_driver_callback(struct parisc_device *dev)
astro_rev[8] = '0' + (char) ((fclass & 0x18) >> 3);
version = astro_rev;
- } else if (IS_IKE(&dev->id)) {
+ } else if (IS_IKE(dev)) {
static char ike_rev[] = "Ike rev ?";
ike_rev[8] = '0' + (char) (func_class & 0xff);
version = ike_rev;
- } else if (IS_PLUTO(&dev->id)) {
+ } else if (IS_PLUTO(dev)) {
static char pluto_rev[]="Pluto ?.?";
pluto_rev[6] = '0' + (char) ((func_class & 0xf0) >> 4);
pluto_rev[8] = '0' + (char) (func_class & 0x0f);
@@ -2097,12 +1953,12 @@ sba_driver_callback(struct parisc_device *dev)
global_ioc_cnt = count_parisc_driver(&sba_driver);
/* Astro and Pluto have one IOC per SBA */
- if ((!IS_ASTRO(&dev->id)) || (!IS_PLUTO(&dev->id)))
+ if ((!IS_ASTRO(dev)) || (!IS_PLUTO(dev)))
global_ioc_cnt *= 2;
}
- printk(KERN_INFO "%s found %s at 0x%lx\n",
- MODULE_NAME, version, dev->hpa.start);
+ printk(KERN_INFO "%s found %s at 0x%llx\n",
+ MODULE_NAME, version, (unsigned long long)dev->hpa.start);
sba_dev = kzalloc(sizeof(struct sba_device), GFP_KERNEL);
if (!sba_dev) {
@@ -2117,7 +1973,6 @@ sba_driver_callback(struct parisc_device *dev)
sba_dev->dev = dev;
sba_dev->hw_rev = func_class;
- sba_dev->iodc = &dev->id;
sba_dev->name = dev->name;
sba_dev->sba_hpa = sba_addr;
@@ -2139,18 +1994,10 @@ sba_driver_callback(struct parisc_device *dev)
break;
}
- info_entry = create_proc_entry("sba_iommu", 0, root);
- bitmap_entry = create_proc_entry("sba_iommu-bitmap", 0, root);
-
- if (info_entry)
- info_entry->proc_fops = &sba_proc_fops;
-
- if (bitmap_entry)
- bitmap_entry->proc_fops = &sba_proc_bitmap_fops;
+ proc_create("sba_iommu", 0, root, &sba_proc_fops);
+ proc_create("sba_iommu-bitmap", 0, root, &sba_proc_bitmap_fops);
#endif
- parisc_vmerge_boundary = IOVP_SIZE;
- parisc_vmerge_max_size = IOVP_SIZE * BITS_PER_LONG;
parisc_has_iommu();
return 0;
}
@@ -2176,7 +2023,7 @@ void __init sba_init(void)
void * sba_get_iommu(struct parisc_device *pci_hba)
{
struct parisc_device *sba_dev = parisc_parent(pci_hba);
- struct sba_device *sba = sba_dev->dev.driver_data;
+ struct sba_device *sba = dev_get_drvdata(&sba_dev->dev);
char t = sba_dev->id.hw_type;
int iocnum = (pci_hba->hw_path >> 3); /* rope # */
@@ -2197,7 +2044,7 @@ void * sba_get_iommu(struct parisc_device *pci_hba)
void sba_directed_lmmio(struct parisc_device *pci_hba, struct resource *r)
{
struct parisc_device *sba_dev = parisc_parent(pci_hba);
- struct sba_device *sba = sba_dev->dev.driver_data;
+ struct sba_device *sba = dev_get_drvdata(&sba_dev->dev);
char t = sba_dev->id.hw_type;
int i;
int rope = (pci_hba->hw_path & (ROPES_PER_IOC-1)); /* rope # */
@@ -2223,6 +2070,7 @@ void sba_directed_lmmio(struct parisc_device *pci_hba, struct resource *r)
r->start = (base & ~1UL) | PCI_F_EXTEND;
size = ~ READ_REG32(reg + LMMIO_DIRECT0_MASK);
r->end = r->start + size;
+ r->flags = IORESOURCE_MEM;
}
}
@@ -2239,7 +2087,7 @@ void sba_directed_lmmio(struct parisc_device *pci_hba, struct resource *r)
void sba_distributed_lmmio(struct parisc_device *pci_hba, struct resource *r )
{
struct parisc_device *sba_dev = parisc_parent(pci_hba);
- struct sba_device *sba = sba_dev->dev.driver_data;
+ struct sba_device *sba = dev_get_drvdata(&sba_dev->dev);
char t = sba_dev->id.hw_type;
int base, size;
int rope = (pci_hba->hw_path & (ROPES_PER_IOC-1)); /* rope # */
@@ -2259,4 +2107,5 @@ void sba_distributed_lmmio(struct parisc_device *pci_hba, struct resource *r )
size = (~READ_REG32(sba->sba_hpa + LMMIO_DIST_MASK)) / ROPES_PER_IOC;
r->start += rope * (size + 1); /* adjust base for this rope */
r->end = r->start + size;
+ r->flags = IORESOURCE_MEM;
}
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c
index 4ee26a6d9e2..a042d065a0c 100644
--- a/drivers/parisc/superio.c
+++ b/drivers/parisc/superio.c
@@ -73,6 +73,7 @@
#include <linux/termios.h>
#include <linux/tty.h>
#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
#include <linux/delay.h>
#include <asm/io.h>
@@ -94,7 +95,7 @@ static struct superio_device sio_dev;
#define PFX SUPERIO ": "
static irqreturn_t
-superio_interrupt(int parent_irq, void *devp, struct pt_regs *regs)
+superio_interrupt(int parent_irq, void *devp)
{
u8 results;
u8 local_irq;
@@ -138,7 +139,7 @@ superio_interrupt(int parent_irq, void *devp, struct pt_regs *regs)
}
/* Call the appropriate device's interrupt */
- __do_IRQ(local_irq, regs);
+ generic_handle_irq(local_irq);
/* set EOI - forces a new interrupt if a lower priority device
* still needs service.
@@ -154,6 +155,7 @@ superio_init(struct pci_dev *pcidev)
struct superio_device *sio = &sio_dev;
struct pci_dev *pdev = sio->lio_pdev;
u16 word;
+ int ret;
if (sio->suckyio_irq_enabled)
return;
@@ -167,7 +169,7 @@ superio_init(struct pci_dev *pcidev)
/* ...then properly fixup the USB to point at suckyio PIC */
sio->usb_pdev->irq = superio_fixup_irq(sio->usb_pdev);
- printk(KERN_INFO PFX "Found NS87560 Legacy I/O device at %s (IRQ %i) \n",
+ printk(KERN_INFO PFX "Found NS87560 Legacy I/O device at %s (IRQ %i)\n",
pci_name(pdev), pdev->irq);
pci_read_config_dword (pdev, SIO_SP1BAR, &sio->sp1_base);
@@ -199,7 +201,8 @@ superio_init(struct pci_dev *pcidev)
pci_write_config_word (pdev, PCI_COMMAND, word);
pci_set_master (pdev);
- pci_enable_device(pdev);
+ ret = pci_enable_device(pdev);
+ BUG_ON(ret < 0); /* not too much we can do about this... */
/*
* Next project is programming the onboard interrupt controllers.
@@ -271,7 +274,7 @@ superio_init(struct pci_dev *pcidev)
else
printk(KERN_ERR PFX "USB regulator not initialized!\n");
- if (request_irq(pdev->irq, superio_interrupt, IRQF_DISABLED,
+ if (request_irq(pdev->irq, superio_interrupt, 0,
SUPERIO, (void *)sio)) {
printk(KERN_ERR PFX "could not get irq\n");
@@ -283,8 +286,9 @@ superio_init(struct pci_dev *pcidev)
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_LIO, superio_init);
-static void superio_disable_irq(unsigned int irq)
+static void superio_mask_irq(struct irq_data *d)
{
+ unsigned int irq = d->irq;
u8 r8;
if ((irq < 1) || (irq == 2) || (irq > 7)) {
@@ -300,8 +304,9 @@ static void superio_disable_irq(unsigned int irq)
outb (r8,IC_PIC1+1);
}
-static void superio_enable_irq(unsigned int irq)
+static void superio_unmask_irq(struct irq_data *d)
{
+ unsigned int irq = d->irq;
u8 r8;
if ((irq < 1) || (irq == 2) || (irq > 7)) {
@@ -316,20 +321,10 @@ static void superio_enable_irq(unsigned int irq)
outb (r8,IC_PIC1+1);
}
-static unsigned int superio_startup_irq(unsigned int irq)
-{
- superio_enable_irq(irq);
- return 0;
-}
-
-static struct hw_interrupt_type superio_interrupt_type = {
- .typename = SUPERIO,
- .startup = superio_startup_irq,
- .shutdown = superio_disable_irq,
- .enable = superio_enable_irq,
- .disable = superio_disable_irq,
- .ack = no_ack_irq,
- .end = no_end_irq,
+static struct irq_chip superio_interrupt_type = {
+ .name = SUPERIO,
+ .irq_unmask = superio_unmask_irq,
+ .irq_mask = superio_mask_irq,
};
#ifdef DEBUG_SUPERIO_INIT
@@ -353,14 +348,15 @@ int superio_fixup_irq(struct pci_dev *pcidev)
BUG();
return -1;
}
- printk("superio_fixup_irq(%s) ven 0x%x dev 0x%x from %p\n",
+ printk("superio_fixup_irq(%s) ven 0x%x dev 0x%x from %pf\n",
pci_name(pcidev),
pcidev->vendor, pcidev->device,
__builtin_return_address(0));
#endif
for (i = 0; i < 16; i++) {
- irq_desc[i].chip = &superio_interrupt_type;
+ irq_set_chip_and_handler(i, &superio_interrupt_type,
+ handle_simple_irq);
}
/*
@@ -389,7 +385,7 @@ int superio_fixup_irq(struct pci_dev *pcidev)
return local_irq;
}
-static void __devinit superio_serial_init(void)
+static void __init superio_serial_init(void)
{
#ifdef CONFIG_SERIAL_8250
int retval;
@@ -400,7 +396,6 @@ static void __devinit superio_serial_init(void)
serial_port.type = PORT_16550A;
serial_port.uartclk = 115200*16;
serial_port.fifosize = 16;
- spin_lock_init(&serial_port.lock);
/* serial port #1 */
serial_port.iobase = sio_dev.sp1_base;
@@ -423,14 +418,15 @@ static void __devinit superio_serial_init(void)
}
-static void __devinit superio_parport_init(void)
+static void __init superio_parport_init(void)
{
#ifdef CONFIG_PARPORT_PC
if (!parport_pc_probe_port(sio_dev.pp_base,
0 /*base_hi*/,
PAR_IRQ,
PARPORT_DMA_NONE /* dma */,
- NULL /*struct pci_dev* */) )
+ NULL /*struct pci_dev* */,
+ 0 /* shared irq flags */))
printk(KERN_WARNING PFX "Probing parallel port failed.\n");
#endif /* CONFIG_PARPORT_PC */
@@ -450,7 +446,7 @@ static void superio_fixup_pci(struct pci_dev *pdev)
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87415, superio_fixup_pci);
-static int __devinit
+static int __init
superio_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
struct superio_device *sio = &sio_dev;
@@ -485,7 +481,7 @@ superio_probe(struct pci_dev *dev, const struct pci_device_id *id)
return -ENODEV;
}
-static struct pci_device_id superio_tbl[] = {
+static const struct pci_device_id superio_tbl[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_LIO) },
{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_USB) },
{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87415) },
@@ -498,15 +494,4 @@ static struct pci_driver superio_driver = {
.probe = superio_probe,
};
-static int __init superio_modinit(void)
-{
- return pci_register_driver(&superio_driver);
-}
-
-static void __exit superio_exit(void)
-{
- pci_unregister_driver(&superio_driver);
-}
-
-module_init(superio_modinit);
-module_exit(superio_exit);
+module_pci_driver(superio_driver);
diff --git a/drivers/parisc/wax.c b/drivers/parisc/wax.c
index 813c2c24ab1..da9d5ad1353 100644
--- a/drivers/parisc/wax.c
+++ b/drivers/parisc/wax.c
@@ -68,8 +68,7 @@ wax_init_irq(struct gsc_asic *wax)
// gsc_writel(0xFFFFFFFF, base+0x2000); /* RS232-B on Wax */
}
-int __init
-wax_init_chip(struct parisc_device *dev)
+static int __init wax_init_chip(struct parisc_device *dev)
{
struct gsc_asic *wax;
struct parisc_device *parent;
@@ -93,7 +92,7 @@ wax_init_chip(struct parisc_device *dev)
dev->irq = gsc_claim_irq(&gsc_irq, WAX_GSC_IRQ);
if (dev->irq < 0) {
printk(KERN_ERR "%s(): cannot get GSC irq\n",
- __FUNCTION__);
+ __func__);
kfree(wax);
return -EBUSY;
}