Commit f2a0bd3753dad7ea4605ebd5435716b39e9f92bb

Authored by Vitaly Bordug
Committed by Paul Mackerras
1 parent 88bdc6f061

[POWERPC] 8xx: powerpc port of core CPM PIC

This covers common CPM access functions, CPM interrupt controller code,
micropatch and a few compatibility things to kee the same driver base
working with arch/ppc. This version is refined with all the comments
(mostly PIC-related) addressed.

Signed-off-by: Vitaly Bordug <vbordug@ru.mvista.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>

Showing 9 changed files with 1414 additions and 10 deletions Side-by-side Diff

arch/powerpc/sysdev/Makefile
... ... @@ -22,5 +22,7 @@
22 22 ifeq ($(ARCH),powerpc)
23 23 obj-$(CONFIG_MTD) += rom.o
24 24 obj-$(CONFIG_CPM2) += cpm2_common.o cpm2_pic.o
  25 +obj-$(CONFIG_8xx) += mpc8xx_pic.o commproc.o
  26 +obj-$(CONFIG_UCODE_PATCH) += micropatch.o
25 27 endif
arch/powerpc/sysdev/commproc.c
  1 +/*
  2 + * General Purpose functions for the global management of the
  3 + * Communication Processor Module.
  4 + * Copyright (c) 1997 Dan error_act (dmalek@jlc.net)
  5 + *
  6 + * In addition to the individual control of the communication
  7 + * channels, there are a few functions that globally affect the
  8 + * communication processor.
  9 + *
  10 + * Buffer descriptors must be allocated from the dual ported memory
  11 + * space. The allocator for that is here. When the communication
  12 + * process is reset, we reclaim the memory available. There is
  13 + * currently no deallocator for this memory.
  14 + * The amount of space available is platform dependent. On the
  15 + * MBX, the EPPC software loads additional microcode into the
  16 + * communication processor, and uses some of the DP ram for this
  17 + * purpose. Current, the first 512 bytes and the last 256 bytes of
  18 + * memory are used. Right now I am conservative and only use the
  19 + * memory that can never be used for microcode. If there are
  20 + * applications that require more DP ram, we can expand the boundaries
  21 + * but then we have to be careful of any downloaded microcode.
  22 + */
  23 +#include <linux/errno.h>
  24 +#include <linux/sched.h>
  25 +#include <linux/kernel.h>
  26 +#include <linux/dma-mapping.h>
  27 +#include <linux/param.h>
  28 +#include <linux/string.h>
  29 +#include <linux/mm.h>
  30 +#include <linux/interrupt.h>
  31 +#include <linux/irq.h>
  32 +#include <linux/module.h>
  33 +#include <asm/mpc8xx.h>
  34 +#include <asm/page.h>
  35 +#include <asm/pgtable.h>
  36 +#include <asm/8xx_immap.h>
  37 +#include <asm/commproc.h>
  38 +#include <asm/io.h>
  39 +#include <asm/tlbflush.h>
  40 +#include <asm/rheap.h>
  41 +#include <asm/prom.h>
  42 +
  43 +#include <asm/fs_pd.h>
  44 +
  45 +#define CPM_MAP_SIZE (0x4000)
  46 +
  47 +static void m8xx_cpm_dpinit(void);
  48 +static uint host_buffer; /* One page of host buffer */
  49 +static uint host_end; /* end + 1 */
  50 +cpm8xx_t *cpmp; /* Pointer to comm processor space */
  51 +cpic8xx_t *cpic_reg;
  52 +
  53 +static struct device_node *cpm_pic_node;
  54 +static struct irq_host *cpm_pic_host;
  55 +
  56 +static void cpm_mask_irq(unsigned int irq)
  57 +{
  58 + unsigned int cpm_vec = (unsigned int)irq_map[irq].hwirq;
  59 +
  60 + clrbits32(&cpic_reg->cpic_cimr, (1 << cpm_vec));
  61 +}
  62 +
  63 +static void cpm_unmask_irq(unsigned int irq)
  64 +{
  65 + unsigned int cpm_vec = (unsigned int)irq_map[irq].hwirq;
  66 +
  67 + setbits32(&cpic_reg->cpic_cimr, (1 << cpm_vec));
  68 +}
  69 +
  70 +static void cpm_end_irq(unsigned int irq)
  71 +{
  72 + unsigned int cpm_vec = (unsigned int)irq_map[irq].hwirq;
  73 +
  74 + out_be32(&cpic_reg->cpic_cisr, (1 << cpm_vec));
  75 +}
  76 +
  77 +static struct irq_chip cpm_pic = {
  78 + .typename = " CPM PIC ",
  79 + .mask = cpm_mask_irq,
  80 + .unmask = cpm_unmask_irq,
  81 + .eoi = cpm_end_irq,
  82 +};
  83 +
  84 +int cpm_get_irq(void)
  85 +{
  86 + int cpm_vec;
  87 +
  88 + /* Get the vector by setting the ACK bit and then reading
  89 + * the register.
  90 + */
  91 + out_be16(&cpic_reg->cpic_civr, 1);
  92 + cpm_vec = in_be16(&cpic_reg->cpic_civr);
  93 + cpm_vec >>= 11;
  94 +
  95 + return irq_linear_revmap(cpm_pic_host, cpm_vec);
  96 +}
  97 +
  98 +static int cpm_pic_host_match(struct irq_host *h, struct device_node *node)
  99 +{
  100 + return cpm_pic_node == node;
  101 +}
  102 +
  103 +static int cpm_pic_host_map(struct irq_host *h, unsigned int virq,
  104 + irq_hw_number_t hw)
  105 +{
  106 + pr_debug("cpm_pic_host_map(%d, 0x%lx)\n", virq, hw);
  107 +
  108 + get_irq_desc(virq)->status |= IRQ_LEVEL;
  109 + set_irq_chip_and_handler(virq, &cpm_pic, handle_fasteoi_irq);
  110 + return 0;
  111 +}
  112 +
  113 +/* The CPM can generate the error interrupt when there is a race condition
  114 + * between generating and masking interrupts. All we have to do is ACK it
  115 + * and return. This is a no-op function so we don't need any special
  116 + * tests in the interrupt handler.
  117 + */
  118 +static irqreturn_t cpm_error_interrupt(int irq, void *dev)
  119 +{
  120 + return IRQ_HANDLED;
  121 +}
  122 +
  123 +static struct irqaction cpm_error_irqaction = {
  124 + .handler = cpm_error_interrupt,
  125 + .mask = CPU_MASK_NONE,
  126 + .name = "error",
  127 +};
  128 +
  129 +static struct irq_host_ops cpm_pic_host_ops = {
  130 + .match = cpm_pic_host_match,
  131 + .map = cpm_pic_host_map,
  132 +};
  133 +
  134 +unsigned int cpm_pic_init(void)
  135 +{
  136 + struct device_node *np = NULL;
  137 + struct resource res;
  138 + unsigned int sirq = NO_IRQ, hwirq, eirq;
  139 + int ret;
  140 +
  141 + pr_debug("cpm_pic_init\n");
  142 +
  143 + np = of_find_compatible_node(NULL, "cpm-pic", "CPM");
  144 + if (np == NULL) {
  145 + printk(KERN_ERR "CPM PIC init: can not find cpm-pic node\n");
  146 + return sirq;
  147 + }
  148 + ret = of_address_to_resource(np, 0, &res);
  149 + if (ret)
  150 + goto end;
  151 +
  152 + cpic_reg = (void *)ioremap(res.start, res.end - res.start + 1);
  153 + if (cpic_reg == NULL)
  154 + goto end;
  155 +
  156 + sirq = irq_of_parse_and_map(np, 0);
  157 + if (sirq == NO_IRQ)
  158 + goto end;
  159 +
  160 + /* Initialize the CPM interrupt controller. */
  161 + hwirq = (unsigned int)irq_map[sirq].hwirq;
  162 + out_be32(&cpic_reg->cpic_cicr,
  163 + (CICR_SCD_SCC4 | CICR_SCC_SCC3 | CICR_SCB_SCC2 | CICR_SCA_SCC1) |
  164 + ((hwirq/2) << 13) | CICR_HP_MASK);
  165 +
  166 + out_be32(&cpic_reg->cpic_cimr, 0);
  167 +
  168 + cpm_pic_node = of_node_get(np);
  169 +
  170 + cpm_pic_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, 64, &cpm_pic_host_ops, 64);
  171 + if (cpm_pic_host == NULL) {
  172 + printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n");
  173 + sirq = NO_IRQ;
  174 + goto end;
  175 + }
  176 + of_node_put(np);
  177 +
  178 + /* Install our own error handler. */
  179 + np = of_find_node_by_type(NULL, "cpm");
  180 + if (np == NULL) {
  181 + printk(KERN_ERR "CPM PIC init: can not find cpm node\n");
  182 + goto end;
  183 + }
  184 + eirq= irq_of_parse_and_map(np, 0);
  185 + if (eirq == NO_IRQ)
  186 + goto end;
  187 +
  188 + if (setup_irq(eirq, &cpm_error_irqaction))
  189 + printk(KERN_ERR "Could not allocate CPM error IRQ!");
  190 +
  191 + setbits32(&cpic_reg->cpic_cicr, CICR_IEN);
  192 +
  193 +end:
  194 + of_node_put(np);
  195 + return sirq;
  196 +}
  197 +
  198 +void cpm_reset(void)
  199 +{
  200 + cpm8xx_t *commproc;
  201 + sysconf8xx_t *siu_conf;
  202 +
  203 + commproc = (cpm8xx_t *)ioremap(CPM_MAP_ADDR, CPM_MAP_SIZE);
  204 +
  205 +#ifdef CONFIG_UCODE_PATCH
  206 + /* Perform a reset.
  207 + */
  208 + out_be16(&commproc->cp_cpcr, CPM_CR_RST | CPM_CR_FLG);
  209 +
  210 + /* Wait for it.
  211 + */
  212 + while (in_be16(&commproc->cp_cpcr) & CPM_CR_FLG);
  213 +
  214 + cpm_load_patch(commproc);
  215 +#endif
  216 +
  217 + /* Set SDMA Bus Request priority 5.
  218 + * On 860T, this also enables FEC priority 6. I am not sure
  219 + * this is what we realy want for some applications, but the
  220 + * manual recommends it.
  221 + * Bit 25, FAM can also be set to use FEC aggressive mode (860T).
  222 + */
  223 + siu_conf = (sysconf8xx_t*)immr_map(im_siu_conf);
  224 + out_be32(&siu_conf->sc_sdcr, 1);
  225 + immr_unmap(siu_conf);
  226 +
  227 + /* Reclaim the DP memory for our use. */
  228 + m8xx_cpm_dpinit();
  229 +
  230 + /* Tell everyone where the comm processor resides.
  231 + */
  232 + cpmp = commproc;
  233 +}
  234 +
  235 +/* We used to do this earlier, but have to postpone as long as possible
  236 + * to ensure the kernel VM is now running.
  237 + */
  238 +static void
  239 +alloc_host_memory(void)
  240 +{
  241 + dma_addr_t physaddr;
  242 +
  243 + /* Set the host page for allocation.
  244 + */
  245 + host_buffer = (uint)dma_alloc_coherent(NULL, PAGE_SIZE, &physaddr,
  246 + GFP_KERNEL);
  247 + host_end = host_buffer + PAGE_SIZE;
  248 +}
  249 +
  250 +/* We also own one page of host buffer space for the allocation of
  251 + * UART "fifos" and the like.
  252 + */
  253 +uint
  254 +m8xx_cpm_hostalloc(uint size)
  255 +{
  256 + uint retloc;
  257 +
  258 + if (host_buffer == 0)
  259 + alloc_host_memory();
  260 +
  261 + if ((host_buffer + size) >= host_end)
  262 + return(0);
  263 +
  264 + retloc = host_buffer;
  265 + host_buffer += size;
  266 +
  267 + return(retloc);
  268 +}
  269 +
  270 +/* Set a baud rate generator. This needs lots of work. There are
  271 + * four BRGs, any of which can be wired to any channel.
  272 + * The internal baud rate clock is the system clock divided by 16.
  273 + * This assumes the baudrate is 16x oversampled by the uart.
  274 + */
  275 +#define BRG_INT_CLK (get_brgfreq())
  276 +#define BRG_UART_CLK (BRG_INT_CLK/16)
  277 +#define BRG_UART_CLK_DIV16 (BRG_UART_CLK/16)
  278 +
  279 +void
  280 +cpm_setbrg(uint brg, uint rate)
  281 +{
  282 + volatile uint *bp;
  283 +
  284 + /* This is good enough to get SMCs running.....
  285 + */
  286 + bp = (uint *)&cpmp->cp_brgc1;
  287 + bp += brg;
  288 + /* The BRG has a 12-bit counter. For really slow baud rates (or
  289 + * really fast processors), we may have to further divide by 16.
  290 + */
  291 + if (((BRG_UART_CLK / rate) - 1) < 4096)
  292 + *bp = (((BRG_UART_CLK / rate) - 1) << 1) | CPM_BRG_EN;
  293 + else
  294 + *bp = (((BRG_UART_CLK_DIV16 / rate) - 1) << 1) |
  295 + CPM_BRG_EN | CPM_BRG_DIV16;
  296 +}
  297 +
  298 +/*
  299 + * dpalloc / dpfree bits.
  300 + */
  301 +static spinlock_t cpm_dpmem_lock;
  302 +/*
  303 + * 16 blocks should be enough to satisfy all requests
  304 + * until the memory subsystem goes up...
  305 + */
  306 +static rh_block_t cpm_boot_dpmem_rh_block[16];
  307 +static rh_info_t cpm_dpmem_info;
  308 +
  309 +#define CPM_DPMEM_ALIGNMENT 8
  310 +static u8* dpram_vbase;
  311 +static uint dpram_pbase;
  312 +
  313 +void m8xx_cpm_dpinit(void)
  314 +{
  315 + spin_lock_init(&cpm_dpmem_lock);
  316 +
  317 + dpram_vbase = immr_map_size(im_cpm.cp_dpmem, CPM_DATAONLY_BASE + CPM_DATAONLY_SIZE);
  318 + dpram_pbase = (uint)&((immap_t *)IMAP_ADDR)->im_cpm.cp_dpmem;
  319 +
  320 + /* Initialize the info header */
  321 + rh_init(&cpm_dpmem_info, CPM_DPMEM_ALIGNMENT,
  322 + sizeof(cpm_boot_dpmem_rh_block) /
  323 + sizeof(cpm_boot_dpmem_rh_block[0]),
  324 + cpm_boot_dpmem_rh_block);
  325 +
  326 + /*
  327 + * Attach the usable dpmem area.
  328 + * XXX: This is actually crap. CPM_DATAONLY_BASE and
  329 + * CPM_DATAONLY_SIZE are a subset of the available dparm. It varies
  330 + * with the processor and the microcode patches applied / activated.
  331 + * But the following should be at least safe.
  332 + */
  333 + rh_attach_region(&cpm_dpmem_info, (void *)CPM_DATAONLY_BASE, CPM_DATAONLY_SIZE);
  334 +}
  335 +
  336 +/*
  337 + * Allocate the requested size worth of DP memory.
  338 + * This function returns an offset into the DPRAM area.
  339 + * Use cpm_dpram_addr() to get the virtual address of the area.
  340 + */
  341 +uint cpm_dpalloc(uint size, uint align)
  342 +{
  343 + void *start;
  344 + unsigned long flags;
  345 +
  346 + spin_lock_irqsave(&cpm_dpmem_lock, flags);
  347 + cpm_dpmem_info.alignment = align;
  348 + start = rh_alloc(&cpm_dpmem_info, size, "commproc");
  349 + spin_unlock_irqrestore(&cpm_dpmem_lock, flags);
  350 +
  351 + return (uint)start;
  352 +}
  353 +EXPORT_SYMBOL(cpm_dpalloc);
  354 +
  355 +int cpm_dpfree(uint offset)
  356 +{
  357 + int ret;
  358 + unsigned long flags;
  359 +
  360 + spin_lock_irqsave(&cpm_dpmem_lock, flags);
  361 + ret = rh_free(&cpm_dpmem_info, (void *)offset);
  362 + spin_unlock_irqrestore(&cpm_dpmem_lock, flags);
  363 +
  364 + return ret;
  365 +}
  366 +EXPORT_SYMBOL(cpm_dpfree);
  367 +
  368 +uint cpm_dpalloc_fixed(uint offset, uint size, uint align)
  369 +{
  370 + void *start;
  371 + unsigned long flags;
  372 +
  373 + spin_lock_irqsave(&cpm_dpmem_lock, flags);
  374 + cpm_dpmem_info.alignment = align;
  375 + start = rh_alloc_fixed(&cpm_dpmem_info, (void *)offset, size, "commproc");
  376 + spin_unlock_irqrestore(&cpm_dpmem_lock, flags);
  377 +
  378 + return (uint)start;
  379 +}
  380 +EXPORT_SYMBOL(cpm_dpalloc_fixed);
  381 +
  382 +void cpm_dpdump(void)
  383 +{
  384 + rh_dump(&cpm_dpmem_info);
  385 +}
  386 +EXPORT_SYMBOL(cpm_dpdump);
  387 +
  388 +void *cpm_dpram_addr(uint offset)
  389 +{
  390 + return (void *)(dpram_vbase + offset);
  391 +}
  392 +EXPORT_SYMBOL(cpm_dpram_addr);
  393 +
  394 +uint cpm_dpram_phys(u8* addr)
  395 +{
  396 + return (dpram_pbase + (uint)(addr - dpram_vbase));
  397 +}
  398 +EXPORT_SYMBOL(cpm_dpram_addr);
arch/powerpc/sysdev/micropatch.c
  1 +
  2 +/* Microcode patches for the CPM as supplied by Motorola.
  3 + * This is the one for IIC/SPI. There is a newer one that
  4 + * also relocates SMC2, but this would require additional changes
  5 + * to uart.c, so I am holding off on that for a moment.
  6 + */
  7 +#include <linux/errno.h>
  8 +#include <linux/sched.h>
  9 +#include <linux/kernel.h>
  10 +#include <linux/param.h>
  11 +#include <linux/string.h>
  12 +#include <linux/mm.h>
  13 +#include <linux/interrupt.h>
  14 +#include <asm/irq.h>
  15 +#include <asm/mpc8xx.h>
  16 +#include <asm/page.h>
  17 +#include <asm/pgtable.h>
  18 +#include <asm/8xx_immap.h>
  19 +#include <asm/commproc.h>
  20 +
  21 +/*
  22 + * I2C/SPI relocation patch arrays.
  23 + */
  24 +
  25 +#ifdef CONFIG_I2C_SPI_UCODE_PATCH
  26 +
  27 +uint patch_2000[] = {
  28 + 0x7FFFEFD9,
  29 + 0x3FFD0000,
  30 + 0x7FFB49F7,
  31 + 0x7FF90000,
  32 + 0x5FEFADF7,
  33 + 0x5F89ADF7,
  34 + 0x5FEFAFF7,
  35 + 0x5F89AFF7,
  36 + 0x3A9CFBC8,
  37 + 0xE7C0EDF0,
  38 + 0x77C1E1BB,
  39 + 0xF4DC7F1D,
  40 + 0xABAD932F,
  41 + 0x4E08FDCF,
  42 + 0x6E0FAFF8,
  43 + 0x7CCF76CF,
  44 + 0xFD1FF9CF,
  45 + 0xABF88DC6,
  46 + 0xAB5679F7,
  47 + 0xB0937383,
  48 + 0xDFCE79F7,
  49 + 0xB091E6BB,
  50 + 0xE5BBE74F,
  51 + 0xB3FA6F0F,
  52 + 0x6FFB76CE,
  53 + 0xEE0DF9CF,
  54 + 0x2BFBEFEF,
  55 + 0xCFEEF9CF,
  56 + 0x76CEAD24,
  57 + 0x90B2DF9A,
  58 + 0x7FDDD0BF,
  59 + 0x4BF847FD,
  60 + 0x7CCF76CE,
  61 + 0xCFEF7E1F,
  62 + 0x7F1D7DFD,
  63 + 0xF0B6EF71,
  64 + 0x7FC177C1,
  65 + 0xFBC86079,
  66 + 0xE722FBC8,
  67 + 0x5FFFDFFF,
  68 + 0x5FB2FFFB,
  69 + 0xFBC8F3C8,
  70 + 0x94A67F01,
  71 + 0x7F1D5F39,
  72 + 0xAFE85F5E,
  73 + 0xFFDFDF96,
  74 + 0xCB9FAF7D,
  75 + 0x5FC1AFED,
  76 + 0x8C1C5FC1,
  77 + 0xAFDD5FC3,
  78 + 0xDF9A7EFD,
  79 + 0xB0B25FB2,
  80 + 0xFFFEABAD,
  81 + 0x5FB2FFFE,
  82 + 0x5FCE600B,
  83 + 0xE6BB600B,
  84 + 0x5FCEDFC6,
  85 + 0x27FBEFDF,
  86 + 0x5FC8CFDE,
  87 + 0x3A9CE7C0,
  88 + 0xEDF0F3C8,
  89 + 0x7F0154CD,
  90 + 0x7F1D2D3D,
  91 + 0x363A7570,
  92 + 0x7E0AF1CE,
  93 + 0x37EF2E68,
  94 + 0x7FEE10EC,
  95 + 0xADF8EFDE,
  96 + 0xCFEAE52F,
  97 + 0x7D0FE12B,
  98 + 0xF1CE5F65,
  99 + 0x7E0A4DF8,
  100 + 0xCFEA5F72,
  101 + 0x7D0BEFEE,
  102 + 0xCFEA5F74,
  103 + 0xE522EFDE,
  104 + 0x5F74CFDA,
  105 + 0x0B627385,
  106 + 0xDF627E0A,
  107 + 0x30D8145B,
  108 + 0xBFFFF3C8,
  109 + 0x5FFFDFFF,
  110 + 0xA7F85F5E,
  111 + 0xBFFE7F7D,
  112 + 0x10D31450,
  113 + 0x5F36BFFF,
  114 + 0xAF785F5E,
  115 + 0xBFFDA7F8,
  116 + 0x5F36BFFE,
  117 + 0x77FD30C0,
  118 + 0x4E08FDCF,
  119 + 0xE5FF6E0F,
  120 + 0xAFF87E1F,
  121 + 0x7E0FFD1F,
  122 + 0xF1CF5F1B,
  123 + 0xABF80D5E,
  124 + 0x5F5EFFEF,
  125 + 0x79F730A2,
  126 + 0xAFDD5F34,
  127 + 0x47F85F34,
  128 + 0xAFED7FDD,
  129 + 0x50B24978,
  130 + 0x47FD7F1D,
  131 + 0x7DFD70AD,
  132 + 0xEF717EC1,
  133 + 0x6BA47F01,
  134 + 0x2D267EFD,
  135 + 0x30DE5F5E,
  136 + 0xFFFD5F5E,
  137 + 0xFFEF5F5E,
  138 + 0xFFDF0CA0,
  139 + 0xAFED0A9E,
  140 + 0xAFDD0C3A,
  141 + 0x5F3AAFBD,
  142 + 0x7FBDB082,
  143 + 0x5F8247F8
  144 +};
  145 +
  146 +uint patch_2f00[] = {
  147 + 0x3E303430,
  148 + 0x34343737,
  149 + 0xABF7BF9B,
  150 + 0x994B4FBD,
  151 + 0xBD599493,
  152 + 0x349FFF37,
  153 + 0xFB9B177D,
  154 + 0xD9936956,
  155 + 0xBBFDD697,
  156 + 0xBDD2FD11,
  157 + 0x31DB9BB3,
  158 + 0x63139637,
  159 + 0x93733693,
  160 + 0x193137F7,
  161 + 0x331737AF,
  162 + 0x7BB9B999,
  163 + 0xBB197957,
  164 + 0x7FDFD3D5,
  165 + 0x73B773F7,
  166 + 0x37933B99,
  167 + 0x1D115316,
  168 + 0x99315315,
  169 + 0x31694BF4,
  170 + 0xFBDBD359,
  171 + 0x31497353,
  172 + 0x76956D69,
  173 + 0x7B9D9693,
  174 + 0x13131979,
  175 + 0x79376935
  176 +};
  177 +#endif
  178 +
  179 +/*
  180 + * I2C/SPI/SMC1 relocation patch arrays.
  181 + */
  182 +
  183 +#ifdef CONFIG_I2C_SPI_SMC1_UCODE_PATCH
  184 +
  185 +uint patch_2000[] = {
  186 + 0x3fff0000,
  187 + 0x3ffd0000,
  188 + 0x3ffb0000,
  189 + 0x3ff90000,
  190 + 0x5f13eff8,
  191 + 0x5eb5eff8,
  192 + 0x5f88adf7,
  193 + 0x5fefadf7,
  194 + 0x3a9cfbc8,
  195 + 0x77cae1bb,
  196 + 0xf4de7fad,
  197 + 0xabae9330,
  198 + 0x4e08fdcf,
  199 + 0x6e0faff8,
  200 + 0x7ccf76cf,
  201 + 0xfdaff9cf,
  202 + 0xabf88dc8,
  203 + 0xab5879f7,
  204 + 0xb0925d8d,
  205 + 0xdfd079f7,
  206 + 0xb090e6bb,
  207 + 0xe5bbe74f,
  208 + 0x9e046f0f,
  209 + 0x6ffb76ce,
  210 + 0xee0cf9cf,
  211 + 0x2bfbefef,
  212 + 0xcfeef9cf,
  213 + 0x76cead23,
  214 + 0x90b3df99,
  215 + 0x7fddd0c1,
  216 + 0x4bf847fd,
  217 + 0x7ccf76ce,
  218 + 0xcfef77ca,
  219 + 0x7eaf7fad,
  220 + 0x7dfdf0b7,
  221 + 0xef7a7fca,
  222 + 0x77cafbc8,
  223 + 0x6079e722,
  224 + 0xfbc85fff,
  225 + 0xdfff5fb3,
  226 + 0xfffbfbc8,
  227 + 0xf3c894a5,
  228 + 0xe7c9edf9,
  229 + 0x7f9a7fad,
  230 + 0x5f36afe8,
  231 + 0x5f5bffdf,
  232 + 0xdf95cb9e,
  233 + 0xaf7d5fc3,
  234 + 0xafed8c1b,
  235 + 0x5fc3afdd,
  236 + 0x5fc5df99,
  237 + 0x7efdb0b3,
  238 + 0x5fb3fffe,
  239 + 0xabae5fb3,
  240 + 0xfffe5fd0,
  241 + 0x600be6bb,
  242 + 0x600b5fd0,
  243 + 0xdfc827fb,
  244 + 0xefdf5fca,
  245 + 0xcfde3a9c,
  246 + 0xe7c9edf9,
  247 + 0xf3c87f9e,
  248 + 0x54ca7fed,
  249 + 0x2d3a3637,
  250 + 0x756f7e9a,
  251 + 0xf1ce37ef,
  252 + 0x2e677fee,
  253 + 0x10ebadf8,
  254 + 0xefdecfea,
  255 + 0xe52f7d9f,
  256 + 0xe12bf1ce,
  257 + 0x5f647e9a,
  258 + 0x4df8cfea,
  259 + 0x5f717d9b,
  260 + 0xefeecfea,
  261 + 0x5f73e522,
  262 + 0xefde5f73,
  263 + 0xcfda0b61,
  264 + 0x5d8fdf61,
  265 + 0xe7c9edf9,
  266 + 0x7e9a30d5,
  267 + 0x1458bfff,
  268 + 0xf3c85fff,
  269 + 0xdfffa7f8,
  270 + 0x5f5bbffe,
  271 + 0x7f7d10d0,
  272 + 0x144d5f33,
  273 + 0xbfffaf78,
  274 + 0x5f5bbffd,
  275 + 0xa7f85f33,
  276 + 0xbffe77fd,
  277 + 0x30bd4e08,
  278 + 0xfdcfe5ff,
  279 + 0x6e0faff8,
  280 + 0x7eef7e9f,
  281 + 0xfdeff1cf,
  282 + 0x5f17abf8,
  283 + 0x0d5b5f5b,
  284 + 0xffef79f7,
  285 + 0x309eafdd,
  286 + 0x5f3147f8,
  287 + 0x5f31afed,
  288 + 0x7fdd50af,
  289 + 0x497847fd,
  290 + 0x7f9e7fed,
  291 + 0x7dfd70a9,
  292 + 0xef7e7ece,
  293 + 0x6ba07f9e,
  294 + 0x2d227efd,
  295 + 0x30db5f5b,
  296 + 0xfffd5f5b,
  297 + 0xffef5f5b,
  298 + 0xffdf0c9c,
  299 + 0xafed0a9a,
  300 + 0xafdd0c37,
  301 + 0x5f37afbd,
  302 + 0x7fbdb081,
  303 + 0x5f8147f8,
  304 + 0x3a11e710,
  305 + 0xedf0ccdd,
  306 + 0xf3186d0a,
  307 + 0x7f0e5f06,
  308 + 0x7fedbb38,
  309 + 0x3afe7468,
  310 + 0x7fedf4fc,
  311 + 0x8ffbb951,
  312 + 0xb85f77fd,
  313 + 0xb0df5ddd,
  314 + 0xdefe7fed,
  315 + 0x90e1e74d,
  316 + 0x6f0dcbf7,
  317 + 0xe7decfed,
  318 + 0xcb74cfed,
  319 + 0xcfeddf6d,
  320 + 0x91714f74,
  321 + 0x5dd2deef,
  322 + 0x9e04e7df,
  323 + 0xefbb6ffb,
  324 + 0xe7ef7f0e,
  325 + 0x9e097fed,
  326 + 0xebdbeffa,
  327 + 0xeb54affb,
  328 + 0x7fea90d7,
  329 + 0x7e0cf0c3,
  330 + 0xbffff318,
  331 + 0x5fffdfff,
  332 + 0xac59efea,
  333 + 0x7fce1ee5,
  334 + 0xe2ff5ee1,
  335 + 0xaffbe2ff,
  336 + 0x5ee3affb,
  337 + 0xf9cc7d0f,
  338 + 0xaef8770f,
  339 + 0x7d0fb0c6,
  340 + 0xeffbbfff,
  341 + 0xcfef5ede,
  342 + 0x7d0fbfff,
  343 + 0x5ede4cf8,
  344 + 0x7fddd0bf,
  345 + 0x49f847fd,
  346 + 0x7efdf0bb,
  347 + 0x7fedfffd,
  348 + 0x7dfdf0b7,
  349 + 0xef7e7e1e,
  350 + 0x5ede7f0e,
  351 + 0x3a11e710,
  352 + 0xedf0ccab,
  353 + 0xfb18ad2e,
  354 + 0x1ea9bbb8,
  355 + 0x74283b7e,
  356 + 0x73c2e4bb,
  357 + 0x2ada4fb8,
  358 + 0xdc21e4bb,
  359 + 0xb2a1ffbf,
  360 + 0x5e2c43f8,
  361 + 0xfc87e1bb,
  362 + 0xe74ffd91,
  363 + 0x6f0f4fe8,
  364 + 0xc7ba32e2,
  365 + 0xf396efeb,
  366 + 0x600b4f78,
  367 + 0xe5bb760b,
  368 + 0x53acaef8,
  369 + 0x4ef88b0e,
  370 + 0xcfef9e09,
  371 + 0xabf8751f,
  372 + 0xefef5bac,
  373 + 0x741f4fe8,
  374 + 0x751e760d,
  375 + 0x7fdbf081,
  376 + 0x741cafce,
  377 + 0xefcc7fce,
  378 + 0x751e70ac,
  379 + 0x741ce7bb,
  380 + 0x3372cfed,
  381 + 0xafdbefeb,
  382 + 0xe5bb760b,
  383 + 0x53f2aef8,
  384 + 0xafe8e7eb,
  385 + 0x4bf8771e,
  386 + 0x7e247fed,
  387 + 0x4fcbe2cc,
  388 + 0x7fbc30a9,
  389 + 0x7b0f7a0f,
  390 + 0x34d577fd,
  391 + 0x308b5db7,
  392 + 0xde553e5f,
  393 + 0xaf78741f,
  394 + 0x741f30f0,
  395 + 0xcfef5e2c,
  396 + 0x741f3eac,
  397 + 0xafb8771e,
  398 + 0x5e677fed,
  399 + 0x0bd3e2cc,
  400 + 0x741ccfec,
  401 + 0xe5ca53cd,
  402 + 0x6fcb4f74,
  403 + 0x5dadde4b,
  404 + 0x2ab63d38,
  405 + 0x4bb3de30,
  406 + 0x751f741c,
  407 + 0x6c42effa,
  408 + 0xefea7fce,
  409 + 0x6ffc30be,
  410 + 0xefec3fca,
  411 + 0x30b3de2e,
  412 + 0xadf85d9e,
  413 + 0xaf7daefd,
  414 + 0x5d9ede2e,
  415 + 0x5d9eafdd,
  416 + 0x761f10ac,
  417 + 0x1da07efd,
  418 + 0x30adfffe,
  419 + 0x4908fb18,
  420 + 0x5fffdfff,
  421 + 0xafbb709b,
  422 + 0x4ef85e67,
  423 + 0xadf814ad,
  424 + 0x7a0f70ad,
  425 + 0xcfef50ad,
  426 + 0x7a0fde30,
  427 + 0x5da0afed,
  428 + 0x3c12780f,
  429 + 0xefef780f,
  430 + 0xefef790f,
  431 + 0xa7f85e0f,
  432 + 0xffef790f,
  433 + 0xefef790f,
  434 + 0x14adde2e,
  435 + 0x5d9eadfd,
  436 + 0x5e2dfffb,
  437 + 0xe79addfd,
  438 + 0xeff96079,
  439 + 0x607ae79a,
  440 + 0xddfceff9,
  441 + 0x60795dff,
  442 + 0x607acfef,
  443 + 0xefefefdf,
  444 + 0xefbfef7f,
  445 + 0xeeffedff,
  446 + 0xebffe7ff,
  447 + 0xafefafdf,
  448 + 0xafbfaf7f,
  449 + 0xaeffadff,
  450 + 0xabffa7ff,
  451 + 0x6fef6fdf,
  452 + 0x6fbf6f7f,
  453 + 0x6eff6dff,
  454 + 0x6bff67ff,
  455 + 0x2fef2fdf,
  456 + 0x2fbf2f7f,
  457 + 0x2eff2dff,
  458 + 0x2bff27ff,
  459 + 0x4e08fd1f,
  460 + 0xe5ff6e0f,
  461 + 0xaff87eef,
  462 + 0x7e0ffdef,
  463 + 0xf11f6079,
  464 + 0xabf8f542,
  465 + 0x7e0af11c,
  466 + 0x37cfae3a,
  467 + 0x7fec90be,
  468 + 0xadf8efdc,
  469 + 0xcfeae52f,
  470 + 0x7d0fe12b,
  471 + 0xf11c6079,
  472 + 0x7e0a4df8,
  473 + 0xcfea5dc4,
  474 + 0x7d0befec,
  475 + 0xcfea5dc6,
  476 + 0xe522efdc,
  477 + 0x5dc6cfda,
  478 + 0x4e08fd1f,
  479 + 0x6e0faff8,
  480 + 0x7c1f761f,
  481 + 0xfdeff91f,
  482 + 0x6079abf8,
  483 + 0x761cee24,
  484 + 0xf91f2bfb,
  485 + 0xefefcfec,
  486 + 0xf91f6079,
  487 + 0x761c27fb,
  488 + 0xefdf5da7,
  489 + 0xcfdc7fdd,
  490 + 0xd09c4bf8,
  491 + 0x47fd7c1f,
  492 + 0x761ccfcf,
  493 + 0x7eef7fed,
  494 + 0x7dfdf093,
  495 + 0xef7e7f1e,
  496 + 0x771efb18,
  497 + 0x6079e722,
  498 + 0xe6bbe5bb,
  499 + 0xae0ae5bb,
  500 + 0x600bae85,
  501 + 0xe2bbe2bb,
  502 + 0xe2bbe2bb,
  503 + 0xaf02e2bb,
  504 + 0xe2bb2ff9,
  505 + 0x6079e2bb
  506 +};
  507 +
  508 +uint patch_2f00[] = {
  509 + 0x30303030,
  510 + 0x3e3e3434,
  511 + 0xabbf9b99,
  512 + 0x4b4fbdbd,
  513 + 0x59949334,
  514 + 0x9fff37fb,
  515 + 0x9b177dd9,
  516 + 0x936956bb,
  517 + 0xfbdd697b,
  518 + 0xdd2fd113,
  519 + 0x1db9f7bb,
  520 + 0x36313963,
  521 + 0x79373369,
  522 + 0x3193137f,
  523 + 0x7331737a,
  524 + 0xf7bb9b99,
  525 + 0x9bb19795,
  526 + 0x77fdfd3d,
  527 + 0x573b773f,
  528 + 0x737933f7,
  529 + 0xb991d115,
  530 + 0x31699315,
  531 + 0x31531694,
  532 + 0xbf4fbdbd,
  533 + 0x35931497,
  534 + 0x35376956,
  535 + 0xbd697b9d,
  536 + 0x96931313,
  537 + 0x19797937,
  538 + 0x6935af78,
  539 + 0xb9b3baa3,
  540 + 0xb8788683,
  541 + 0x368f78f7,
  542 + 0x87778733,
  543 + 0x3ffffb3b,
  544 + 0x8e8f78b8,
  545 + 0x1d118e13,
  546 + 0xf3ff3f8b,
  547 + 0x6bd8e173,
  548 + 0xd1366856,
  549 + 0x68d1687b,
  550 + 0x3daf78b8,
  551 + 0x3a3a3f87,
  552 + 0x8f81378f,
  553 + 0xf876f887,
  554 + 0x77fd8778,
  555 + 0x737de8d6,
  556 + 0xbbf8bfff,
  557 + 0xd8df87f7,
  558 + 0xfd876f7b,
  559 + 0x8bfff8bd,
  560 + 0x8683387d,
  561 + 0xb873d87b,
  562 + 0x3b8fd7f8,
  563 + 0xf7338883,
  564 + 0xbb8ee1f8,
  565 + 0xef837377,
  566 + 0x3337b836,
  567 + 0x817d11f8,
  568 + 0x7378b878,
  569 + 0xd3368b7d,
  570 + 0xed731b7d,
  571 + 0x833731f3,
  572 + 0xf22f3f23
  573 +};
  574 +
  575 +uint patch_2e00[] = {
  576 + 0x27eeeeee,
  577 + 0xeeeeeeee,
  578 + 0xeeeeeeee,
  579 + 0xeeeeeeee,
  580 + 0xee4bf4fb,
  581 + 0xdbd259bb,
  582 + 0x1979577f,
  583 + 0xdfd2d573,
  584 + 0xb773f737,
  585 + 0x4b4fbdbd,
  586 + 0x25b9b177,
  587 + 0xd2d17376,
  588 + 0x956bbfdd,
  589 + 0x697bdd2f,
  590 + 0xff9f79ff,
  591 + 0xff9ff22f
  592 +};
  593 +#endif
  594 +
  595 +/*
  596 + * USB SOF patch arrays.
  597 + */
  598 +
  599 +#ifdef CONFIG_USB_SOF_UCODE_PATCH
  600 +
  601 +uint patch_2000[] = {
  602 + 0x7fff0000,
  603 + 0x7ffd0000,
  604 + 0x7ffb0000,
  605 + 0x49f7ba5b,
  606 + 0xba383ffb,
  607 + 0xf9b8b46d,
  608 + 0xe5ab4e07,
  609 + 0xaf77bffe,
  610 + 0x3f7bbf79,
  611 + 0xba5bba38,
  612 + 0xe7676076,
  613 + 0x60750000
  614 +};
  615 +
  616 +uint patch_2f00[] = {
  617 + 0x3030304c,
  618 + 0xcab9e441,
  619 + 0xa1aaf220
  620 +};
  621 +#endif
  622 +
  623 +void
  624 +cpm_load_patch(cpm8xx_t *cp)
  625 +{
  626 + volatile uint *dp; /* Dual-ported RAM. */
  627 + volatile cpm8xx_t *commproc;
  628 + volatile iic_t *iip;
  629 + volatile spi_t *spp;
  630 + volatile smc_uart_t *smp;
  631 + int i;
  632 +
  633 + commproc = cp;
  634 +
  635 +#ifdef CONFIG_USB_SOF_UCODE_PATCH
  636 + commproc->cp_rccr = 0;
  637 +
  638 + dp = (uint *)(commproc->cp_dpmem);
  639 + for (i=0; i<(sizeof(patch_2000)/4); i++)
  640 + *dp++ = patch_2000[i];
  641 +
  642 + dp = (uint *)&(commproc->cp_dpmem[0x0f00]);
  643 + for (i=0; i<(sizeof(patch_2f00)/4); i++)
  644 + *dp++ = patch_2f00[i];
  645 +
  646 + commproc->cp_rccr = 0x0009;
  647 +
  648 + printk("USB SOF microcode patch installed\n");
  649 +#endif /* CONFIG_USB_SOF_UCODE_PATCH */
  650 +
  651 +#if defined(CONFIG_I2C_SPI_UCODE_PATCH) || \
  652 + defined(CONFIG_I2C_SPI_SMC1_UCODE_PATCH)
  653 +
  654 + commproc->cp_rccr = 0;
  655 +
  656 + dp = (uint *)(commproc->cp_dpmem);
  657 + for (i=0; i<(sizeof(patch_2000)/4); i++)
  658 + *dp++ = patch_2000[i];
  659 +
  660 + dp = (uint *)&(commproc->cp_dpmem[0x0f00]);
  661 + for (i=0; i<(sizeof(patch_2f00)/4); i++)
  662 + *dp++ = patch_2f00[i];
  663 +
  664 + iip = (iic_t *)&commproc->cp_dparam[PROFF_IIC];
  665 +# define RPBASE 0x0500
  666 + iip->iic_rpbase = RPBASE;
  667 +
  668 + /* Put SPI above the IIC, also 32-byte aligned.
  669 + */
  670 + i = (RPBASE + sizeof(iic_t) + 31) & ~31;
  671 + spp = (spi_t *)&commproc->cp_dparam[PROFF_SPI];
  672 + spp->spi_rpbase = i;
  673 +
  674 +# if defined(CONFIG_I2C_SPI_UCODE_PATCH)
  675 + commproc->cp_cpmcr1 = 0x802a;
  676 + commproc->cp_cpmcr2 = 0x8028;
  677 + commproc->cp_cpmcr3 = 0x802e;
  678 + commproc->cp_cpmcr4 = 0x802c;
  679 + commproc->cp_rccr = 1;
  680 +
  681 + printk("I2C/SPI microcode patch installed.\n");
  682 +# endif /* CONFIG_I2C_SPI_UCODE_PATCH */
  683 +
  684 +# if defined(CONFIG_I2C_SPI_SMC1_UCODE_PATCH)
  685 +
  686 + dp = (uint *)&(commproc->cp_dpmem[0x0e00]);
  687 + for (i=0; i<(sizeof(patch_2e00)/4); i++)
  688 + *dp++ = patch_2e00[i];
  689 +
  690 + commproc->cp_cpmcr1 = 0x8080;
  691 + commproc->cp_cpmcr2 = 0x808a;
  692 + commproc->cp_cpmcr3 = 0x8028;
  693 + commproc->cp_cpmcr4 = 0x802a;
  694 + commproc->cp_rccr = 3;
  695 +
  696 + smp = (smc_uart_t *)&commproc->cp_dparam[PROFF_SMC1];
  697 + smp->smc_rpbase = 0x1FC0;
  698 +
  699 + printk("I2C/SPI/SMC1 microcode patch installed.\n");
  700 +# endif /* CONFIG_I2C_SPI_SMC1_UCODE_PATCH) */
  701 +
  702 +#endif /* some variation of the I2C/SPI patch was selected */
  703 +}
  704 +
  705 +/*
  706 + * Take this entire routine out, since no one calls it and its
  707 + * logic is suspect.
  708 + */
  709 +
  710 +#if 0
  711 +void
  712 +verify_patch(volatile immap_t *immr)
  713 +{
  714 + volatile uint *dp;
  715 + volatile cpm8xx_t *commproc;
  716 + int i;
  717 +
  718 + commproc = (cpm8xx_t *)&immr->im_cpm;
  719 +
  720 + printk("cp_rccr %x\n", commproc->cp_rccr);
  721 + commproc->cp_rccr = 0;
  722 +
  723 + dp = (uint *)(commproc->cp_dpmem);
  724 + for (i=0; i<(sizeof(patch_2000)/4); i++)
  725 + if (*dp++ != patch_2000[i]) {
  726 + printk("patch_2000 bad at %d\n", i);
  727 + dp--;
  728 + printk("found 0x%X, wanted 0x%X\n", *dp, patch_2000[i]);
  729 + break;
  730 + }
  731 +
  732 + dp = (uint *)&(commproc->cp_dpmem[0x0f00]);
  733 + for (i=0; i<(sizeof(patch_2f00)/4); i++)
  734 + if (*dp++ != patch_2f00[i]) {
  735 + printk("patch_2f00 bad at %d\n", i);
  736 + dp--;
  737 + printk("found 0x%X, wanted 0x%X\n", *dp, patch_2f00[i]);
  738 + break;
  739 + }
  740 +
  741 + commproc->cp_rccr = 0x0009;
  742 +}
  743 +#endif
arch/powerpc/sysdev/mpc8xx_pic.c
  1 +#include <linux/kernel.h>
  2 +#include <linux/module.h>
  3 +#include <linux/stddef.h>
  4 +#include <linux/init.h>
  5 +#include <linux/sched.h>
  6 +#include <linux/signal.h>
  7 +#include <linux/irq.h>
  8 +#include <linux/dma-mapping.h>
  9 +#include <asm/prom.h>
  10 +#include <asm/irq.h>
  11 +#include <asm/io.h>
  12 +#include <asm/8xx_immap.h>
  13 +#include <asm/mpc8xx.h>
  14 +
  15 +#include "mpc8xx_pic.h"
  16 +
  17 +
  18 +#define PIC_VEC_SPURRIOUS 15
  19 +
  20 +extern int cpm_get_irq(struct pt_regs *regs);
  21 +
  22 +static struct device_node *mpc8xx_pic_node;
  23 +static struct irq_host *mpc8xx_pic_host;
  24 +#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
  25 +static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
  26 +static sysconf8xx_t *siu_reg;
  27 +
  28 +int cpm_get_irq(struct pt_regs *regs);
  29 +
  30 +static void mpc8xx_unmask_irq(unsigned int virq)
  31 +{
  32 + int bit, word;
  33 + unsigned int irq_nr = (unsigned int)irq_map[virq].hwirq;
  34 +
  35 + bit = irq_nr & 0x1f;
  36 + word = irq_nr >> 5;
  37 +
  38 + ppc_cached_irq_mask[word] |= (1 << (31-bit));
  39 + out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]);
  40 +}
  41 +
  42 +static void mpc8xx_mask_irq(unsigned int virq)
  43 +{
  44 + int bit, word;
  45 + unsigned int irq_nr = (unsigned int)irq_map[virq].hwirq;
  46 +
  47 + bit = irq_nr & 0x1f;
  48 + word = irq_nr >> 5;
  49 +
  50 + ppc_cached_irq_mask[word] &= ~(1 << (31-bit));
  51 + out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]);
  52 +}
  53 +
  54 +static void mpc8xx_ack(unsigned int virq)
  55 +{
  56 + int bit;
  57 + unsigned int irq_nr = (unsigned int)irq_map[virq].hwirq;
  58 +
  59 + bit = irq_nr & 0x1f;
  60 + out_be32(&siu_reg->sc_sipend, 1 << (31-bit));
  61 +}
  62 +
  63 +static void mpc8xx_end_irq(unsigned int virq)
  64 +{
  65 + int bit, word;
  66 + unsigned int irq_nr = (unsigned int)irq_map[virq].hwirq;
  67 +
  68 + bit = irq_nr & 0x1f;
  69 + word = irq_nr >> 5;
  70 +
  71 + ppc_cached_irq_mask[word] |= (1 << (31-bit));
  72 + out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]);
  73 +}
  74 +
  75 +static int mpc8xx_set_irq_type(unsigned int virq, unsigned int flow_type)
  76 +{
  77 + struct irq_desc *desc = get_irq_desc(virq);
  78 +
  79 + desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
  80 + desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
  81 + if (flow_type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
  82 + desc->status |= IRQ_LEVEL;
  83 +
  84 + if (flow_type & IRQ_TYPE_EDGE_FALLING) {
  85 + irq_hw_number_t hw = (unsigned int)irq_map[virq].hwirq;
  86 + unsigned int siel = in_be32(&siu_reg->sc_siel);
  87 +
  88 + /* only external IRQ senses are programmable */
  89 + if ((hw & 1) == 0) {
  90 + siel |= (0x80000000 >> hw);
  91 + out_be32(&siu_reg->sc_siel, siel);
  92 + desc->handle_irq = handle_edge_irq;
  93 + }
  94 + }
  95 + return 0;
  96 +}
  97 +
  98 +static struct irq_chip mpc8xx_pic = {
  99 + .typename = " MPC8XX SIU ",
  100 + .unmask = mpc8xx_unmask_irq,
  101 + .mask = mpc8xx_mask_irq,
  102 + .ack = mpc8xx_ack,
  103 + .eoi = mpc8xx_end_irq,
  104 + .set_type = mpc8xx_set_irq_type,
  105 +};
  106 +
  107 +unsigned int mpc8xx_get_irq(void)
  108 +{
  109 + int irq;
  110 +
  111 + /* For MPC8xx, read the SIVEC register and shift the bits down
  112 + * to get the irq number.
  113 + */
  114 + irq = in_be32(&siu_reg->sc_sivec) >> 26;
  115 +
  116 + if (irq == PIC_VEC_SPURRIOUS)
  117 + irq = NO_IRQ;
  118 +
  119 + return irq_linear_revmap(mpc8xx_pic_host, irq);
  120 +
  121 +}
  122 +
  123 +static int mpc8xx_pic_host_match(struct irq_host *h, struct device_node *node)
  124 +{
  125 + return mpc8xx_pic_node == node;
  126 +}
  127 +
  128 +static int mpc8xx_pic_host_map(struct irq_host *h, unsigned int virq,
  129 + irq_hw_number_t hw)
  130 +{
  131 + pr_debug("mpc8xx_pic_host_map(%d, 0x%lx)\n", virq, hw);
  132 +
  133 + /* Set default irq handle */
  134 + set_irq_chip_and_handler(virq, &mpc8xx_pic, handle_level_irq);
  135 + return 0;
  136 +}
  137 +
  138 +
  139 +static int mpc8xx_pic_host_xlate(struct irq_host *h, struct device_node *ct,
  140 + u32 *intspec, unsigned int intsize,
  141 + irq_hw_number_t *out_hwirq, unsigned int *out_flags)
  142 +{
  143 + static unsigned char map_pic_senses[4] = {
  144 + IRQ_TYPE_EDGE_RISING,
  145 + IRQ_TYPE_LEVEL_LOW,
  146 + IRQ_TYPE_LEVEL_HIGH,
  147 + IRQ_TYPE_EDGE_FALLING,
  148 + };
  149 +
  150 + *out_hwirq = intspec[0];
  151 + if (intsize > 1 && intspec[1] < 4)
  152 + *out_flags = map_pic_senses[intspec[1]];
  153 + else
  154 + *out_flags = IRQ_TYPE_NONE;
  155 +
  156 + return 0;
  157 +}
  158 +
  159 +
  160 +static struct irq_host_ops mpc8xx_pic_host_ops = {
  161 + .match = mpc8xx_pic_host_match,
  162 + .map = mpc8xx_pic_host_map,
  163 + .xlate = mpc8xx_pic_host_xlate,
  164 +};
  165 +
  166 +int mpc8xx_pic_init(void)
  167 +{
  168 + struct resource res;
  169 + struct device_node *np = NULL;
  170 + int ret;
  171 +
  172 + np = of_find_node_by_type(np, "mpc8xx-pic");
  173 +
  174 + if (np == NULL) {
  175 + printk(KERN_ERR "Could not find open-pic node\n");
  176 + return -ENOMEM;
  177 + }
  178 +
  179 + mpc8xx_pic_node = of_node_get(np);
  180 +
  181 + ret = of_address_to_resource(np, 0, &res);
  182 + of_node_put(np);
  183 + if (ret)
  184 + return ret;
  185 +
  186 + siu_reg = (void *)ioremap(res.start, res.end - res.start + 1);
  187 + if (siu_reg == NULL)
  188 + return -EINVAL;
  189 +
  190 + mpc8xx_pic_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, 64, &mpc8xx_pic_host_ops, 64);
  191 + if (mpc8xx_pic_host == NULL) {
  192 + printk(KERN_ERR "MPC8xx PIC: failed to allocate irq host!\n");
  193 + ret = -ENOMEM;
  194 + }
  195 +
  196 + return ret;
  197 +}
arch/powerpc/sysdev/mpc8xx_pic.h
  1 +#ifndef _PPC_KERNEL_MPC8xx_H
  2 +#define _PPC_KERNEL_MPC8xx_H
  3 +
  4 +#include <linux/irq.h>
  5 +#include <linux/interrupt.h>
  6 +
  7 +extern struct hw_interrupt_type mpc8xx_pic;
  8 +
  9 +int mpc8xx_pic_init(void);
  10 +unsigned int mpc8xx_get_irq(void);
  11 +
  12 +#endif /* _PPC_KERNEL_PPC8xx_H */
include/asm-powerpc/fs_pd.h
... ... @@ -11,20 +11,12 @@
11 11  
12 12 #ifndef FS_PD_H
13 13 #define FS_PD_H
14   -#include <asm/cpm2.h>
15 14 #include <sysdev/fsl_soc.h>
16 15 #include <asm/time.h>
17 16  
18   -static inline int uart_baudrate(void)
19   -{
20   - return get_baudrate();
21   -}
  17 +#ifdef CONFIG_CPM2
  18 +#include <asm/cpm2.h>
22 19  
23   -static inline int uart_clock(void)
24   -{
25   - return ppc_proc_freq;
26   -}
27   -
28 20 #define cpm2_map(member) \
29 21 ({ \
30 22 u32 offset = offsetof(cpm2_map_t, member); \
... ... @@ -41,6 +33,39 @@
41 33 })
42 34  
43 35 #define cpm2_unmap(addr) iounmap(addr)
  36 +#endif
  37 +
  38 +#ifdef CONFIG_8xx
  39 +#include <asm/8xx_immap.h>
  40 +#include <asm/mpc8xx.h>
  41 +
  42 +#define immr_map(member) \
  43 +({ \
  44 + u32 offset = offsetof(immap_t, member); \
  45 + void *addr = ioremap (IMAP_ADDR + offset, \
  46 + sizeof( ((immap_t*)0)->member)); \
  47 + addr; \
  48 +})
  49 +
  50 +#define immr_map_size(member, size) \
  51 +({ \
  52 + u32 offset = offsetof(immap_t, member); \
  53 + void *addr = ioremap (IMAP_ADDR + offset, size); \
  54 + addr; \
  55 +})
  56 +
  57 +#define immr_unmap(addr) iounmap(addr)
  58 +#endif
  59 +
  60 +static inline int uart_baudrate(void)
  61 +{
  62 + return get_baudrate();
  63 +}
  64 +
  65 +static inline int uart_clock(void)
  66 +{
  67 + return ppc_proc_freq;
  68 +}
44 69  
45 70 #endif
include/asm-powerpc/mpc8xx.h
  1 +/* This is the single file included by all MPC8xx build options.
  2 + * Since there are many different boards and no standard configuration,
  3 + * we have a unique include file for each. Rather than change every
  4 + * file that has to include MPC8xx configuration, they all include
  5 + * this one and the configuration switching is done here.
  6 + */
  7 +#ifdef __KERNEL__
  8 +#ifndef __CONFIG_8xx_DEFS
  9 +#define __CONFIG_8xx_DEFS
  10 +
  11 +
  12 +#ifdef CONFIG_8xx
  13 +
  14 +#ifdef CONFIG_FADS
  15 +#include <platforms/fads.h>
  16 +#endif
  17 +
  18 +#if defined(CONFIG_MPC885ADS)
  19 +#include <platforms/8xx/mpc885ads.h>
  20 +#endif
  21 +
  22 +#endif /* CONFIG_8xx */
  23 +#endif /* __CONFIG_8xx_DEFS */
  24 +#endif /* __KERNEL__ */
include/asm-powerpc/time.h
... ... @@ -39,6 +39,8 @@
39 39 extern void wakeup_decrementer(void);
40 40 extern void snapshot_timebase(void);
41 41  
  42 +extern void set_dec_cpu6(unsigned int val);
  43 +
42 44 /* Some sane defaults: 125 MHz timebase, 1GHz processor */
43 45 extern unsigned long ppc_proc_freq;
44 46 #define DEFAULT_PROC_FREQ (DEFAULT_TB_FREQ * 8)
include/asm-ppc/commproc.h
... ... @@ -77,6 +77,7 @@
77 77 extern uint cpm_dpalloc_fixed(uint offset, uint size, uint align);
78 78 extern void cpm_dpdump(void);
79 79 extern void *cpm_dpram_addr(uint offset);
  80 +extern uint cpm_dpram_phys(u8* addr);
80 81 extern void cpm_setbrg(uint brg, uint rate);
81 82  
82 83 extern uint m8xx_cpm_hostalloc(uint size);