ALSA: usb-audio: add support for Akai MPD16
[safe/jmp/linux-2.6] / arch / sparc / kernel / pcic.c
index cccfc12..d36a8d3 100644 (file)
@@ -10,7 +10,6 @@
  * CP-1200 by Eric Brower.
  */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/init.h>
@@ -18,8 +17,6 @@
 #include <linux/slab.h>
 #include <linux/jiffies.h>
 
-#include <asm/ebus.h>
-#include <asm/sbus.h> /* for sanity check... */
 #include <asm/swift.h> /* for cache flushing. */
 #include <asm/io.h>
 
 
 #include <asm/irq.h>
 #include <asm/oplib.h>
+#include <asm/prom.h>
 #include <asm/pcic.h>
+#include <asm/timex.h>
 #include <asm/timer.h>
 #include <asm/uaccess.h>
+#include <asm/irq_regs.h>
 
-
-unsigned int pcic_pin_to_irq(unsigned int pin, char *name);
+#include "irq.h"
 
 /*
  * I studied different documents and many live PROMs both from 2.30
@@ -161,12 +160,10 @@ static struct pcic_sn2list pcic_known_sysnames[] = {
 static int pcic0_up;
 static struct linux_pcic pcic0;
 
-void * __iomem pcic_regs;
+void __iomem *pcic_regs;
 volatile int pcic_speculative;
 volatile int pcic_trapped;
 
-static void pci_do_gettimeofday(struct timeval *tv);
-static int pci_do_settimeofday(struct timespec *tv);
 
 #define CONFIG_CMD(bus, device_fn, where) (0x80000000 | (((unsigned int)bus) << 16) | (((unsigned int)device_fn) << 8) | (where & ~3))
 
@@ -329,7 +326,7 @@ int __init pcic_probe(void)
        pcic->pcic_res_cfg_addr.name = "pcic_cfg_addr";
        if ((pcic->pcic_config_space_addr =
            ioremap(regs[2].phys_addr, regs[2].reg_size * 2)) == 0) {
-               prom_printf("PCIC: Error, cannot map
+               prom_printf("PCIC: Error, cannot map "
                            "PCI Configuration Space Address.\n");
                prom_halt();
        }
@@ -341,7 +338,7 @@ int __init pcic_probe(void)
        pcic->pcic_res_cfg_data.name = "pcic_cfg_data";
        if ((pcic->pcic_config_space_data =
            ioremap(regs[3].phys_addr, regs[3].reg_size * 2)) == 0) {
-               prom_printf("PCIC: Error, cannot map
+               prom_printf("PCIC: Error, cannot map "
                            "PCI Configuration Space Data.\n");
                prom_halt();
        }
@@ -430,7 +427,6 @@ static int __init pcic_init(void)
 
        pcic_pbm_scan_bus(pcic);
 
-       ebus_init();
        return 0;
 }
 
@@ -439,7 +435,7 @@ int pcic_present(void)
        return pcic0_up;
 }
 
-static int __init pdev_to_pnode(struct linux_pbm_info *pbm, 
+static int __devinit pdev_to_pnode(struct linux_pbm_info *pbm,
                                    struct pci_dev *pdev)
 {
        struct linux_prom_pci_registers regs[PROMREG_MAX];
@@ -493,10 +489,6 @@ static void pcic_map_pci_device(struct linux_pcic *pcic,
                                 * do ioremap() before accessing PC-style I/O,
                                 * we supply virtual, ready to access address.
                                 *
-                                * Ebus devices do not come here even if
-                                * CheerIO makes a similar conversion.
-                                * See ebus.c for details.
-                                *
                                 * Note that request_region()
                                 * works for these devices.
                                 *
@@ -518,8 +510,8 @@ static void pcic_map_pci_device(struct linux_pcic *pcic,
                                 * board in a PCI slot. We must remap it
                                 * under 64K but it is not done yet. XXX
                                 */
-                               printk("PCIC: Skipping I/O space at 0x%lx,"
-                                   "this will Oops if a driver attaches;"
+                               printk("PCIC: Skipping I/O space at 0x%lx, "
+                                   "this will Oops if a driver attaches "
                                    "device '%s' at %02x:%02x)\n", address,
                                    namebuf, dev->bus->number, dev->devfn);
                        }
@@ -593,14 +585,12 @@ pcic_fill_irq(struct linux_pcic *pcic, struct pci_dev *dev, int node)
                        writew(ivec, pcic->pcic_regs+PCI_INT_SELECT_LO);
                }
        }
-
-       return;
 }
 
 /*
  * Normally called from {do_}pci_scan_bus...
  */
-void __init pcibios_fixup_bus(struct pci_bus *bus)
+void __devinit pcibios_fixup_bus(struct pci_bus *bus)
 {
        struct pci_dev *dev;
        int i, has_io, has_mem;
@@ -665,7 +655,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
                /* cookies */
                pcp = pci_devcookie_alloc();
                pcp->pbm = &pcic->pbm;
-               pcp->prom_node = node;
+               pcp->prom_node = of_find_node_by_phandle(node);
                dev->sysdata = pcp;
 
                /* fixing I/O to look like memory */
@@ -677,10 +667,10 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
 }
 
 /*
- * pcic_pin_to_irq() is exported to ebus.c.
+ * pcic_pin_to_irq() is exported to bus probing code
  */
 unsigned int
-pcic_pin_to_irq(unsigned int pin, char *name)
+pcic_pin_to_irq(unsigned int pin, const char *name)
 {
        struct linux_pcic *pcic = &pcic0;
        unsigned int irq;
@@ -708,34 +698,42 @@ static void pcic_clear_clock_irq(void)
        pcic_timer_dummy = readl(pcic0.pcic_regs+PCI_SYS_LIMIT);
 }
 
-static irqreturn_t pcic_timer_handler (int irq, void *h, struct pt_regs *regs)
+static irqreturn_t pcic_timer_handler (int irq, void *h)
 {
        write_seqlock(&xtime_lock);     /* Dummy, to show that we remember */
        pcic_clear_clock_irq();
-       do_timer(regs);
+       do_timer(1);
+       write_sequnlock(&xtime_lock);
 #ifndef CONFIG_SMP
-       update_process_times(user_mode(regs));
+       update_process_times(user_mode(get_irq_regs()));
 #endif
-       write_sequnlock(&xtime_lock);
        return IRQ_HANDLED;
 }
 
 #define USECS_PER_JIFFY  10000  /* We have 100HZ "standard" timer for sparc */
 #define TICK_TIMER_LIMIT ((100*1000000/4)/100)
 
+u32 pci_gettimeoffset(void)
+{
+       /*
+        * We divide all by 100
+        * to have microsecond resolution and to avoid overflow
+        */
+       unsigned long count =
+           readl(pcic0.pcic_regs+PCI_SYS_COUNTER) & ~PCI_SYS_COUNTER_OVERFLOW;
+       count = ((count/100)*USECS_PER_JIFFY) / (TICK_TIMER_LIMIT/100);
+       return count * 1000;
+}
+
+
 void __init pci_time_init(void)
 {
        struct linux_pcic *pcic = &pcic0;
        unsigned long v;
        int timer_irq, irq;
 
-       /* A hack until do_gettimeofday prototype is moved to arch specific headers
-          and btfixupped. Patch do_gettimeofday with ba pci_do_gettimeofday; nop */
-       ((unsigned int *)do_gettimeofday)[0] = 
-           0x10800000 | ((((unsigned long)pci_do_gettimeofday -
-            (unsigned long)do_gettimeofday) >> 2) & 0x003fffff);
-       ((unsigned int *)do_gettimeofday)[1] = 0x01000000;
-       BTFIXUPSET_CALL(bus_do_settimeofday, pci_do_settimeofday, BTFIXUPCALL_NORM);
+       do_arch_gettimeoffset = pci_gettimeoffset;
+
        btfixup();
 
        writel (TICK_TIMER_LIMIT, pcic->pcic_regs+PCI_SYS_LIMIT);
@@ -745,7 +743,7 @@ void __init pci_time_init(void)
        writel (PCI_COUNTER_IRQ_SET(timer_irq, 0),
                pcic->pcic_regs+PCI_COUNTER_IRQ);
        irq = request_irq(timer_irq, pcic_timer_handler,
-                         (SA_INTERRUPT | SA_STATIC_ALLOC), "timer", NULL);
+                         (IRQF_DISABLED | SA_STATIC_ALLOC), "timer", NULL);
        if (irq) {
                prom_printf("time_init: unable to attach IRQ%d\n", timer_irq);
                prom_halt();
@@ -753,96 +751,6 @@ void __init pci_time_init(void)
        local_irq_enable();
 }
 
-static __inline__ unsigned long do_gettimeoffset(void)
-{
-       /*
-        * We devide all to 100
-        * to have microsecond resolution and to avoid overflow
-        */
-       unsigned long count =
-           readl(pcic0.pcic_regs+PCI_SYS_COUNTER) & ~PCI_SYS_COUNTER_OVERFLOW;
-       count = ((count/100)*USECS_PER_JIFFY) / (TICK_TIMER_LIMIT/100);
-       return count;
-}
-
-extern unsigned long wall_jiffies;
-
-static void pci_do_gettimeofday(struct timeval *tv)
-{
-       unsigned long flags;
-       unsigned long seq;
-       unsigned long usec, sec;
-       unsigned long max_ntp_tick = tick_usec - tickadj;
-
-       do {
-               unsigned long lost;
-
-               seq = read_seqbegin_irqsave(&xtime_lock, flags);
-               usec = do_gettimeoffset();
-               lost = jiffies - wall_jiffies;
-
-               /*
-                * If time_adjust is negative then NTP is slowing the clock
-                * so make sure not to go into next possible interval.
-                * Better to lose some accuracy than have time go backwards..
-                */
-               if (unlikely(time_adjust < 0)) {
-                       usec = min(usec, max_ntp_tick);
-
-                       if (lost)
-                               usec += lost * max_ntp_tick;
-               }
-               else if (unlikely(lost))
-                       usec += lost * tick_usec;
-
-               sec = xtime.tv_sec;
-               usec += (xtime.tv_nsec / 1000);
-       } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
-
-       while (usec >= 1000000) {
-               usec -= 1000000;
-               sec++;
-       }
-
-       tv->tv_sec = sec;
-       tv->tv_usec = usec;
-}
-
-static int pci_do_settimeofday(struct timespec *tv)
-{
-       if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
-               return -EINVAL;
-
-       /*
-        * This is revolting. We need to set "xtime" correctly. However, the
-        * value in this location is the value at the most recent update of
-        * wall time.  Discover what correction gettimeofday() would have
-        * made, and then undo it!
-        */
-       tv->tv_nsec -= 1000 * (do_gettimeoffset() + 
-                               (jiffies - wall_jiffies) * (USEC_PER_SEC / HZ));
-       while (tv->tv_nsec < 0) {
-               tv->tv_nsec += NSEC_PER_SEC;
-               tv->tv_sec--;
-       }
-
-       wall_to_monotonic.tv_sec += xtime.tv_sec - tv->tv_sec;
-       wall_to_monotonic.tv_nsec += xtime.tv_nsec - tv->tv_nsec;
-
-       if (wall_to_monotonic.tv_nsec > NSEC_PER_SEC) {
-               wall_to_monotonic.tv_nsec -= NSEC_PER_SEC;
-               wall_to_monotonic.tv_sec++;
-       }
-       if (wall_to_monotonic.tv_nsec < 0) {
-               wall_to_monotonic.tv_nsec += NSEC_PER_SEC;
-               wall_to_monotonic.tv_sec--;
-       }
-
-       xtime.tv_sec = tv->tv_sec;
-       xtime.tv_nsec = tv->tv_nsec;
-       ntp_clear();
-       return 0;
-}
 
 #if 0
 static void watchdog_reset() {
@@ -853,14 +761,15 @@ static void watchdog_reset() {
 /*
  * Other archs parse arguments here.
  */
-char * __init pcibios_setup(char *str)
+char * __devinit pcibios_setup(char *str)
 {
        return str;
 }
 
-void pcibios_align_resource(void *data, struct resource *res,
-                           unsigned long size, unsigned long align)
+resource_size_t pcibios_align_resource(void *data, const struct resource *res,
+                               resource_size_t size, resource_size_t align)
 {
+       return res->start;
 }
 
 int pcibios_enable_device(struct pci_dev *pdev, int mask)
@@ -896,13 +805,6 @@ static inline unsigned long get_irqmask(int irq_nr)
        return 1 << irq_nr;
 }
 
-static inline char *pcic_irq_itoa(unsigned int irq)
-{
-       static char buff[16];
-       sprintf(buff, "%d", irq);
-       return buff;
-}
-
 static void pcic_disable_irq(unsigned int irq_nr)
 {
        unsigned long mask, flags;
@@ -923,11 +825,6 @@ static void pcic_enable_irq(unsigned int irq_nr)
        local_irq_restore(flags);
 }
 
-static void pcic_clear_profile_irq(int cpu)
-{
-       printk("PCIC: unimplemented code: FILE=%s LINE=%d", __FILE__, __LINE__);
-}
-
 static void pcic_load_profile_irq(int cpu, unsigned int limit)
 {
        printk("PCIC: unimplemented code: FILE=%s LINE=%d", __FILE__, __LINE__);
@@ -953,9 +850,7 @@ void __init sun4m_pci_init_IRQ(void)
        BTFIXUPSET_CALL(enable_pil_irq, pcic_enable_pil_irq, BTFIXUPCALL_NORM);
        BTFIXUPSET_CALL(disable_pil_irq, pcic_disable_pil_irq, BTFIXUPCALL_NORM);
        BTFIXUPSET_CALL(clear_clock_irq, pcic_clear_clock_irq, BTFIXUPCALL_NORM);
-       BTFIXUPSET_CALL(clear_profile_irq, pcic_clear_profile_irq, BTFIXUPCALL_NORM);
        BTFIXUPSET_CALL(load_profile_irq, pcic_load_profile_irq, BTFIXUPCALL_NORM);
-       BTFIXUPSET_CALL(__irq_itoa, pcic_irq_itoa, BTFIXUPCALL_NORM);
 }
 
 int pcibios_assign_resource(struct pci_dev *pdev, int resource)
@@ -963,13 +858,21 @@ int pcibios_assign_resource(struct pci_dev *pdev, int resource)
        return -ENXIO;
 }
 
+struct device_node *pci_device_to_OF_node(struct pci_dev *pdev)
+{
+       struct pcidev_cookie *pc = pdev->sysdata;
+
+       return pc->prom_node;
+}
+EXPORT_SYMBOL(pci_device_to_OF_node);
+
 /*
  * This probably belongs here rather than ioport.c because
  * we do not want this crud linked into SBus kernels.
  * Also, think for a moment about likes of floppy.c that
  * include architecture specific parts. They may want to redefine ins/outs.
  *
- * We do not use horroble macroses here because we want to
+ * We do not use horrible macros here because we want to
  * advance pointer by sizeof(size).
  */
 void outsb(unsigned long addr, const void *src, unsigned long count)
@@ -981,6 +884,7 @@ void outsb(unsigned long addr, const void *src, unsigned long count)
                /* addr += 1; */
        }
 }
+EXPORT_SYMBOL(outsb);
 
 void outsw(unsigned long addr, const void *src, unsigned long count)
 {
@@ -991,6 +895,7 @@ void outsw(unsigned long addr, const void *src, unsigned long count)
                /* addr += 2; */
        }
 }
+EXPORT_SYMBOL(outsw);
 
 void outsl(unsigned long addr, const void *src, unsigned long count)
 {
@@ -1001,6 +906,7 @@ void outsl(unsigned long addr, const void *src, unsigned long count)
                /* addr += 4; */
        }
 }
+EXPORT_SYMBOL(outsl);
 
 void insb(unsigned long addr, void *dst, unsigned long count)
 {
@@ -1011,6 +917,7 @@ void insb(unsigned long addr, void *dst, unsigned long count)
                /* addr += 1; */
        }
 }
+EXPORT_SYMBOL(insb);
 
 void insw(unsigned long addr, void *dst, unsigned long count)
 {
@@ -1021,6 +928,7 @@ void insw(unsigned long addr, void *dst, unsigned long count)
                /* addr += 2; */
        }
 }
+EXPORT_SYMBOL(insw);
 
 void insl(unsigned long addr, void *dst, unsigned long count)
 {
@@ -1034,5 +942,6 @@ void insl(unsigned long addr, void *dst, unsigned long count)
                /* addr += 4; */
        }
 }
+EXPORT_SYMBOL(insl);
 
 subsys_initcall(pcic_init);