Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / arch / ppc / syslib / m8xx_setup.c
index 5ccf071..54303a7 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *  arch/ppc/kernel/setup.c
- *
  *  Copyright (C) 1995  Linus Torvalds
  *  Adapted from 'alpha' version by Gary Thomas
  *  Modified by Cort Dougan (cort@cs.nmt.edu)
@@ -12,7 +10,6 @@
  * bootup setup stuff..
  */
 
-#include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/seq_file.h>
 #include <linux/root_dev.h>
 
+#if defined(CONFIG_MTD) && defined(CONFIG_MTD_PHYSMAP)
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#endif
+
 #include <asm/mmu.h>
 #include <asm/reg.h>
 #include <asm/residual.h>
 #include <asm/bootinfo.h>
 #include <asm/time.h>
 #include <asm/xmon.h>
+#include <asm/ppc_sys.h>
 
 #include "ppc8xx_pic.h"
 
+#ifdef CONFIG_MTD_PHYSMAP
+#define MPC8xxADS_BANK_WIDTH 4
+#endif
+
+#define MPC8xxADS_U_BOOT_SIZE          0x80000
+#define MPC8xxADS_FREE_AREA_OFFSET     MPC8xxADS_U_BOOT_SIZE
+
+#if defined(CONFIG_MTD_PARTITIONS)
+ /*
+   NOTE: bank width and interleave relative to the installed flash
+   should have been chosen within MTD_CFI_GEOMETRY options.
+ */
+static struct mtd_partition mpc8xxads_partitions[] = {
+       {
+               .name = "bootloader",
+               .size = MPC8xxADS_U_BOOT_SIZE,
+               .offset = 0,
+               .mask_flags   = MTD_WRITEABLE,  /* force read-only */
+       }, {
+               .name = "User FS",
+               .offset = MPC8xxADS_FREE_AREA_OFFSET
+       }
+};
+
+#define mpc8xxads_part_num (sizeof (mpc8xxads_partitions) / sizeof (mpc8xxads_partitions[0]))
+
+#endif
+
 static int m8xx_set_rtc_time(unsigned long time);
 static unsigned long m8xx_get_rtc_time(void);
 void m8xx_calibrate_decr(void);
@@ -57,19 +90,26 @@ unsigned char __res[sizeof(bd_t)];
 extern void m8xx_ide_init(void);
 
 extern unsigned long find_available_memory(void);
-extern void m8xx_cpm_reset(uint);
+extern void m8xx_cpm_reset(void);
+extern void m8xx_wdt_handler_install(bd_t *bp);
 extern void rpxfb_alloc_pages(void);
+extern void cpm_interrupt_init(void);
+
+void __attribute__ ((weak))
+board_init(void)
+{
+}
 
 void __init
 m8xx_setup_arch(void)
 {
-       int     cpm_page;
-
-       cpm_page = (int) alloc_bootmem_pages(PAGE_SIZE);
+#if defined(CONFIG_MTD) && defined(CONFIG_MTD_PHYSMAP)
+       bd_t *binfo = (bd_t *)__res;
+#endif
 
        /* Reset the Communication Processor Module.
        */
-       m8xx_cpm_reset(cpm_page);
+       m8xx_cpm_reset();
 
 #ifdef CONFIG_FB_RPX
        rpxfb_alloc_pages();
@@ -102,6 +142,18 @@ m8xx_setup_arch(void)
        }
 #endif
 #endif
+
+#if defined (CONFIG_MPC86XADS) || defined (CONFIG_MPC885ADS)
+#if defined(CONFIG_MTD_PHYSMAP)
+       physmap_configure(binfo->bi_flashstart, binfo->bi_flashsize,
+                                               MPC8xxADS_BANK_WIDTH, NULL);
+#ifdef CONFIG_MTD_PARTITIONS
+       physmap_set_partitions(mpc8xxads_partitions, mpc8xxads_part_num);
+#endif /* CONFIG_MTD_PARTITIONS */
+#endif /* CONFIG_MTD_PHYSMAP */
+#endif
+
+       board_init();
 }
 
 void
@@ -117,9 +169,29 @@ abort(void)
 }
 
 /* A place holder for time base interrupts, if they are ever enabled. */
-void timebase_interrupt(int irq, void * dev, struct pt_regs * regs)
+irqreturn_t timebase_interrupt(int irq, void * dev, struct pt_regs * regs)
 {
        printk ("timebase_interrupt()\n");
+
+       return IRQ_HANDLED;
+}
+
+static struct irqaction tbint_irqaction = {
+       .handler = timebase_interrupt,
+       .mask = CPU_MASK_NONE,
+       .name = "tbint",
+};
+
+/* per-board overridable init_internal_rtc() function. */
+void __init __attribute__ ((weak))
+init_internal_rtc(void)
+{
+       /* Disable the RTC one second and alarm interrupts. */
+       clrbits16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc, (RTCSC_SIE | RTCSC_ALE));
+
+       /* Enable the RTC */
+       setbits16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc, (RTCSC_RTF | RTCSC_RTE));
+
 }
 
 /* The decrementer counts at the system (internal) clock frequency divided by
@@ -132,12 +204,11 @@ void __init m8xx_calibrate_decr(void)
        int freq, fp, divisor;
 
        /* Unlock the SCCR. */
-       ((volatile immap_t *)IMAP_ADDR)->im_clkrstk.cark_sccrk = ~KAPWR_KEY;
-       ((volatile immap_t *)IMAP_ADDR)->im_clkrstk.cark_sccrk = KAPWR_KEY;
+       out_be32(&((immap_t *)IMAP_ADDR)->im_clkrstk.cark_sccrk, ~KAPWR_KEY);
+       out_be32(&((immap_t *)IMAP_ADDR)->im_clkrstk.cark_sccrk, KAPWR_KEY);
 
        /* Force all 8xx processors to use divide by 16 processor clock. */
-       ((volatile immap_t *)IMAP_ADDR)->im_clkrst.car_sccr |= 0x02000000;
-
+       setbits32(&((immap_t *)IMAP_ADDR)->im_clkrst.car_sccr, 0x02000000);
        /* Processor frequency is MHz.
         * The value 'fp' is the number of decrementer ticks per second.
         */
@@ -163,31 +234,31 @@ void __init m8xx_calibrate_decr(void)
         * we guarantee the registers are locked, then we unlock them
         * for our use.
         */
-       ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk = ~KAPWR_KEY;
-       ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck = ~KAPWR_KEY;
-       ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk    = ~KAPWR_KEY;
-       ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk =  KAPWR_KEY;
-       ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck =  KAPWR_KEY;
-       ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk    =  KAPWR_KEY;
+       out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk, ~KAPWR_KEY);
+       out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck, ~KAPWR_KEY);
+       out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk, ~KAPWR_KEY);
+       out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk, KAPWR_KEY);
+       out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck, KAPWR_KEY);
+       out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk, KAPWR_KEY);
 
-       /* Disable the RTC one second and alarm interrupts. */
-       ((volatile immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc &=
-                                               ~(RTCSC_SIE | RTCSC_ALE);
-       /* Enable the RTC */
-       ((volatile immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc |=
-                                               (RTCSC_RTF | RTCSC_RTE);
+       init_internal_rtc();
 
        /* Enabling the decrementer also enables the timebase interrupts
         * (or from the other point of view, to get decrementer interrupts
         * we have to enable the timebase).  The decrementer interrupt
         * is wired into the vector table, nothing to do here for that.
         */
-       ((volatile immap_t *)IMAP_ADDR)->im_sit.sit_tbscr =
-                               ((mk_int_int_mask(DEC_INTERRUPT) << 8) |
-                                        (TBSCR_TBF | TBSCR_TBE));
+       out_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_tbscr, (mk_int_int_mask(DEC_INTERRUPT) << 8) | (TBSCR_TBF | TBSCR_TBE));
 
-       if (request_8xxirq(DEC_INTERRUPT, timebase_interrupt, 0, "tbint", NULL) != 0)
+       if (setup_irq(DEC_INTERRUPT, &tbint_irqaction))
                panic("Could not allocate timer IRQ!");
+
+#ifdef CONFIG_8xx_WDT
+       /* Install watchdog timer handler early because it might be
+        * already enabled by the bootloader
+        */
+       m8xx_wdt_handler_install(binfo);
+#endif
 }
 
 /* The RTC on the MPC8xx is an internal register.
@@ -197,9 +268,9 @@ void __init m8xx_calibrate_decr(void)
 static int
 m8xx_set_rtc_time(unsigned long time)
 {
-       ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck = KAPWR_KEY;
-       ((volatile immap_t *)IMAP_ADDR)->im_sit.sit_rtc = time;
-       ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck = ~KAPWR_KEY;
+       out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck, KAPWR_KEY);
+       out_be32(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtc, time);
+       out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck, ~KAPWR_KEY);
        return(0);
 }
 
@@ -207,7 +278,7 @@ static unsigned long
 m8xx_get_rtc_time(void)
 {
        /* Get time from the RTC. */
-       return((unsigned long)(((immap_t *)IMAP_ADDR)->im_sit.sit_rtc));
+       return (unsigned long) in_be32(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtc);
 }
 
 static void
@@ -215,14 +286,14 @@ m8xx_restart(char *cmd)
 {
        __volatile__ unsigned char dummy;
 
-       cli();
-       ((immap_t *)IMAP_ADDR)->im_clkrst.car_plprcr |= 0x00000080;
+       local_irq_disable();
 
+       setbits32(&((immap_t *)IMAP_ADDR)->im_clkrst.car_plprcr, 0x00000080);
        /* Clear the ME bit in MSR to cause checkstop on machine check
        */
        mtmsr(mfmsr() & ~0x1000);
 
-       dummy = ((immap_t *)IMAP_ADDR)->im_clkrst.res[0];
+       dummy = in_8(&((immap_t *)IMAP_ADDR)->im_clkrst.res[0]);
        printk("Restart failed\n");
        while(1);
 }
@@ -247,14 +318,22 @@ m8xx_show_percpuinfo(struct seq_file *m, int i)
 
        bp = (bd_t *)__res;
 
-       seq_printf(m, "clock\t\t: %ldMHz\n"
-                  "bus clock\t: %ldMHz\n",
+       seq_printf(m, "clock\t\t: %uMHz\n"
+                  "bus clock\t: %uMHz\n",
                   bp->bi_intfreq / 1000000,
                   bp->bi_busfreq / 1000000);
 
        return 0;
 }
 
+#ifdef CONFIG_PCI
+static struct irqaction mbx_i8259_irqaction = {
+       .handler = mbx_i8259_action,
+       .mask = CPU_MASK_NONE,
+       .name = "i8259 cascade",
+};
+#endif
+
 /* Initialize the internal interrupt controller.  The number of
  * interrupts supported can vary with the processor type, and the
  * 82xx family can have up to 64.
@@ -265,25 +344,25 @@ static void __init
 m8xx_init_IRQ(void)
 {
        int i;
-       void cpm_interrupt_init(void);
 
-        for ( i = 0 ; i < NR_SIU_INTS ; i++ )
-                irq_desc[i].handler = &ppc8xx_pic;
+       for (i = SIU_IRQ_OFFSET ; i < SIU_IRQ_OFFSET + NR_SIU_INTS ; i++)
+               irq_desc[i].chip = &ppc8xx_pic;
 
-       /* We could probably incorporate the CPM into the multilevel
-        * interrupt structure.
-        */
        cpm_interrupt_init();
-        unmask_irq(CPM_INTERRUPT);
 
 #if defined(CONFIG_PCI)
-        for ( i = NR_SIU_INTS ; i < (NR_SIU_INTS + NR_8259_INTS) ; i++ )
-                irq_desc[i].handler = &i8259_pic;
-        i8259_pic.irq_offset = NR_SIU_INTS;
-        i8259_init();
-        request_8xxirq(ISA_BRIDGE_INT, mbx_i8259_action, 0, "8259 cascade", NULL);
-        enable_irq(ISA_BRIDGE_INT);
-#endif
+       for (i = I8259_IRQ_OFFSET ; i < I8259_IRQ_OFFSET + NR_8259_INTS ; i++)
+               irq_desc[i].chip = &i8259_pic;
+
+       i8259_pic_irq_offset = I8259_IRQ_OFFSET;
+       i8259_init(0);
+
+       /* The i8259 cascade interrupt must be level sensitive. */
+
+       clrbits32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel, (0x80000000 >> ISA_BRIDGE_INT));
+       if (setup_irq(ISA_BRIDGE_INT, &mbx_i8259_irqaction))
+               enable_irq(ISA_BRIDGE_INT);
+#endif /* CONFIG_PCI */
 }
 
 /* -------------------------------------------------------------------- */
@@ -334,7 +413,7 @@ m8xx_map_io(void)
        io_block_mapping(_IO_BASE,_IO_BASE,_IO_BASE_SIZE, _PAGE_IO);
 #endif
 #endif
-#ifdef CONFIG_HTDMSOUND
+#if defined(CONFIG_HTDMSOUND) || defined(CONFIG_RPXTOUCH) || defined(CONFIG_FB_RPX)
        io_block_mapping(HIOX_CSR_ADDR, HIOX_CSR_ADDR, HIOX_CSR_SIZE, _PAGE_IO);
 #endif
 #ifdef CONFIG_FADS
@@ -343,6 +422,9 @@ m8xx_map_io(void)
 #ifdef CONFIG_PCI
         io_block_mapping(PCI_CSR_ADDR, PCI_CSR_ADDR, PCI_CSR_SIZE, _PAGE_IO);
 #endif
+#if defined(CONFIG_NETTA)
+       io_block_mapping(_IO_BASE,_IO_BASE,_IO_BASE_SIZE, _PAGE_IO);
+#endif
 }
 
 void __init
@@ -373,9 +455,10 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
                strcpy(cmd_line, (char *)(r6+KERNELBASE));
        }
 
+       identify_ppc_sys_by_name(BOARD_CHIP_NAME);
+
        ppc_md.setup_arch               = m8xx_setup_arch;
        ppc_md.show_percpuinfo          = m8xx_show_percpuinfo;
-       ppc_md.irq_canonicalize = NULL;
        ppc_md.init_IRQ                 = m8xx_init_IRQ;
        ppc_md.get_irq                  = m8xx_get_irq;
        ppc_md.init                     = NULL;
@@ -392,7 +475,7 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
        ppc_md.find_end_of_memory       = m8xx_find_end_of_memory;
        ppc_md.setup_io_mappings        = m8xx_map_io;
 
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
+#if defined(CONFIG_BLK_DEV_MPC8xx_IDE)
        m8xx_ide_init();
 #endif
 }