aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/cchips/voyagergx
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/sh/cchips/voyagergx
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'arch/sh/cchips/voyagergx')
-rw-r--r--arch/sh/cchips/voyagergx/Makefile8
-rw-r--r--arch/sh/cchips/voyagergx/consistent.c126
-rw-r--r--arch/sh/cchips/voyagergx/irq.c194
-rw-r--r--arch/sh/cchips/voyagergx/setup.c37
4 files changed, 365 insertions, 0 deletions
diff --git a/arch/sh/cchips/voyagergx/Makefile b/arch/sh/cchips/voyagergx/Makefile
new file mode 100644
index 000000000000..085de72fd327
--- /dev/null
+++ b/arch/sh/cchips/voyagergx/Makefile
@@ -0,0 +1,8 @@
1#
2# Makefile for VoyagerGX
3#
4
5obj-y := irq.o setup.o
6
7obj-$(CONFIG_USB_OHCI_HCD) += consistent.o
8
diff --git a/arch/sh/cchips/voyagergx/consistent.c b/arch/sh/cchips/voyagergx/consistent.c
new file mode 100644
index 000000000000..5b92585a38d2
--- /dev/null
+++ b/arch/sh/cchips/voyagergx/consistent.c
@@ -0,0 +1,126 @@
1/*
2 * arch/sh/cchips/voyagergx/consistent.c
3 *
4 * Copyright (C) 2004 Paul Mundt
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/mm.h>
11#include <linux/dma-mapping.h>
12#include <linux/slab.h>
13#include <linux/list.h>
14#include <linux/types.h>
15#include <linux/module.h>
16#include <linux/device.h>
17#include <asm/io.h>
18#include <asm/bus-sh.h>
19
20struct voya_alloc_entry {
21 struct list_head list;
22 unsigned long ofs;
23 unsigned long len;
24};
25
26static DEFINE_SPINLOCK(voya_list_lock);
27static LIST_HEAD(voya_alloc_list);
28
29#define OHCI_SRAM_START 0xb0000000
30#define OHCI_HCCA_SIZE 0x100
31#define OHCI_SRAM_SIZE 0x10000
32
33void *voyagergx_consistent_alloc(struct device *dev, size_t size,
34 dma_addr_t *handle, int flag)
35{
36 struct list_head *list = &voya_alloc_list;
37 struct voya_alloc_entry *entry;
38 struct sh_dev *shdev = to_sh_dev(dev);
39 unsigned long start, end;
40 unsigned long flags;
41
42 /*
43 * The SM501 contains an integrated 8051 with its own SRAM.
44 * Devices within the cchip can all hook into the 8051 SRAM.
45 * We presently use this for the OHCI.
46 *
47 * Everything else goes through consistent_alloc().
48 */
49 if (!dev || dev->bus != &sh_bus_types[SH_BUS_VIRT] ||
50 (dev->bus == &sh_bus_types[SH_BUS_VIRT] &&
51 shdev->dev_id != SH_DEV_ID_USB_OHCI))
52 return NULL;
53
54 start = OHCI_SRAM_START + OHCI_HCCA_SIZE;
55
56 entry = kmalloc(sizeof(struct voya_alloc_entry), GFP_ATOMIC);
57 if (!entry)
58 return ERR_PTR(-ENOMEM);
59
60 entry->len = (size + 15) & ~15;
61
62 /*
63 * The basis for this allocator is dwmw2's malloc.. the
64 * Matrox allocator :-)
65 */
66 spin_lock_irqsave(&voya_list_lock, flags);
67 list_for_each(list, &voya_alloc_list) {
68 struct voya_alloc_entry *p;
69
70 p = list_entry(list, struct voya_alloc_entry, list);
71
72 if (p->ofs - start >= size)
73 goto out;
74
75 start = p->ofs + p->len;
76 }
77
78 end = start + (OHCI_SRAM_SIZE - OHCI_HCCA_SIZE);
79 list = &voya_alloc_list;
80
81 if (end - start >= size) {
82out:
83 entry->ofs = start;
84 list_add_tail(&entry->list, list);
85 spin_unlock_irqrestore(&voya_list_lock, flags);
86
87 *handle = start;
88 return (void *)start;
89 }
90
91 kfree(entry);
92 spin_unlock_irqrestore(&voya_list_lock, flags);
93
94 return ERR_PTR(-EINVAL);
95}
96
97int voyagergx_consistent_free(struct device *dev, size_t size,
98 void *vaddr, dma_addr_t handle)
99{
100 struct voya_alloc_entry *entry;
101 struct sh_dev *shdev = to_sh_dev(dev);
102 unsigned long flags;
103
104 if (!dev || dev->bus != &sh_bus_types[SH_BUS_VIRT] ||
105 (dev->bus == &sh_bus_types[SH_BUS_VIRT] &&
106 shdev->dev_id != SH_DEV_ID_USB_OHCI))
107 return -EINVAL;
108
109 spin_lock_irqsave(&voya_list_lock, flags);
110 list_for_each_entry(entry, &voya_alloc_list, list) {
111 if (entry->ofs != handle)
112 continue;
113
114 list_del(&entry->list);
115 kfree(entry);
116
117 break;
118 }
119 spin_unlock_irqrestore(&voya_list_lock, flags);
120
121 return 0;
122}
123
124EXPORT_SYMBOL(voyagergx_consistent_alloc);
125EXPORT_SYMBOL(voyagergx_consistent_free);
126
diff --git a/arch/sh/cchips/voyagergx/irq.c b/arch/sh/cchips/voyagergx/irq.c
new file mode 100644
index 000000000000..3079234cb65b
--- /dev/null
+++ b/arch/sh/cchips/voyagergx/irq.c
@@ -0,0 +1,194 @@
1/* -------------------------------------------------------------------- */
2/* setup_voyagergx.c: */
3/* -------------------------------------------------------------------- */
4/* This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 Copyright 2003 (c) Lineo uSolutions,Inc.
19*/
20/* -------------------------------------------------------------------- */
21
22#undef DEBUG
23
24#include <linux/config.h>
25#include <linux/sched.h>
26#include <linux/module.h>
27#include <linux/kernel.h>
28#include <linux/param.h>
29#include <linux/ioport.h>
30#include <linux/interrupt.h>
31#include <linux/init.h>
32#include <linux/irq.h>
33
34#include <asm/io.h>
35#include <asm/irq.h>
36#include <asm/rts7751r2d/rts7751r2d.h>
37#include <asm/rts7751r2d/voyagergx_reg.h>
38
39static void disable_voyagergx_irq(unsigned int irq)
40{
41 unsigned long flags, val;
42 unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE);
43
44 pr_debug("disable_voyagergx_irq(%d): mask=%x\n", irq, mask);
45 local_irq_save(flags);
46 val = inl(VOYAGER_INT_MASK);
47 val &= ~mask;
48 outl(val, VOYAGER_INT_MASK);
49 local_irq_restore(flags);
50}
51
52
53static void enable_voyagergx_irq(unsigned int irq)
54{
55 unsigned long flags, val;
56 unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE);
57
58 pr_debug("disable_voyagergx_irq(%d): mask=%x\n", irq, mask);
59 local_irq_save(flags);
60 val = inl(VOYAGER_INT_MASK);
61 val |= mask;
62 outl(val, VOYAGER_INT_MASK);
63 local_irq_restore(flags);
64}
65
66
67static void mask_and_ack_voyagergx(unsigned int irq)
68{
69 disable_voyagergx_irq(irq);
70}
71
72static void end_voyagergx_irq(unsigned int irq)
73{
74 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
75 enable_voyagergx_irq(irq);
76}
77
78static unsigned int startup_voyagergx_irq(unsigned int irq)
79{
80 enable_voyagergx_irq(irq);
81 return 0;
82}
83
84static void shutdown_voyagergx_irq(unsigned int irq)
85{
86 disable_voyagergx_irq(irq);
87}
88
89static struct hw_interrupt_type voyagergx_irq_type = {
90 "VOYAGERGX-IRQ",
91 startup_voyagergx_irq,
92 shutdown_voyagergx_irq,
93 enable_voyagergx_irq,
94 disable_voyagergx_irq,
95 mask_and_ack_voyagergx,
96 end_voyagergx_irq,
97};
98
99static irqreturn_t voyagergx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
100{
101 printk(KERN_INFO
102 "VoyagerGX: spurious interrupt, status: 0x%x\n",
103 inl(INT_STATUS));
104 return IRQ_HANDLED;
105}
106
107
108/*====================================================*/
109
110static struct {
111 int (*func)(int, void *);
112 void *dev;
113} voyagergx_demux[VOYAGER_IRQ_NUM];
114
115void voyagergx_register_irq_demux(int irq,
116 int (*demux)(int irq, void *dev), void *dev)
117{
118 voyagergx_demux[irq - VOYAGER_IRQ_BASE].func = demux;
119 voyagergx_demux[irq - VOYAGER_IRQ_BASE].dev = dev;
120}
121
122void voyagergx_unregister_irq_demux(int irq)
123{
124 voyagergx_demux[irq - VOYAGER_IRQ_BASE].func = 0;
125}
126
127int voyagergx_irq_demux(int irq)
128{
129
130 if (irq == IRQ_VOYAGER ) {
131 unsigned long i = 0, bit __attribute__ ((unused));
132 unsigned long val = inl(INT_STATUS);
133#if 1
134 if ( val & ( 1 << 1 )){
135 i = 1;
136 } else if ( val & ( 1 << 2 )){
137 i = 2;
138 } else if ( val & ( 1 << 6 )){
139 i = 6;
140 } else if( val & ( 1 << 10 )){
141 i = 10;
142 } else if( val & ( 1 << 11 )){
143 i = 11;
144 } else if( val & ( 1 << 12 )){
145 i = 12;
146 } else if( val & ( 1 << 17 )){
147 i = 17;
148 } else {
149 printk("Unexpected IRQ irq = %d status = 0x%08lx\n", irq, val);
150 }
151 pr_debug("voyagergx_irq_demux %d \n", i);
152#else
153 for (bit = 1, i = 0 ; i < VOYAGER_IRQ_NUM ; bit <<= 1, i++)
154 if (val & bit)
155 break;
156#endif
157 if (i < VOYAGER_IRQ_NUM) {
158 irq = VOYAGER_IRQ_BASE + i;
159 if (voyagergx_demux[i].func != 0)
160 irq = voyagergx_demux[i].func(irq, voyagergx_demux[i].dev);
161 }
162 }
163 return irq;
164}
165
166static struct irqaction irq0 = { voyagergx_interrupt, SA_INTERRUPT, 0, "VOYAGERGX", NULL, NULL};
167
168void __init setup_voyagergx_irq(void)
169{
170 int i, flag;
171
172 printk(KERN_INFO "VoyagerGX configured at 0x%x on irq %d(mapped into %d to %d)\n",
173 VOYAGER_BASE,
174 IRQ_VOYAGER,
175 VOYAGER_IRQ_BASE,
176 VOYAGER_IRQ_BASE + VOYAGER_IRQ_NUM - 1);
177
178 for (i=0; i<VOYAGER_IRQ_NUM; i++) {
179 flag = 0;
180 switch (VOYAGER_IRQ_BASE + i) {
181 case VOYAGER_USBH_IRQ:
182 case VOYAGER_8051_IRQ:
183 case VOYAGER_UART0_IRQ:
184 case VOYAGER_UART1_IRQ:
185 case VOYAGER_AC97_IRQ:
186 flag = 1;
187 }
188 if (flag == 1)
189 irq_desc[VOYAGER_IRQ_BASE + i].handler = &voyagergx_irq_type;
190 }
191
192 setup_irq(IRQ_VOYAGER, &irq0);
193}
194
diff --git a/arch/sh/cchips/voyagergx/setup.c b/arch/sh/cchips/voyagergx/setup.c
new file mode 100644
index 000000000000..139ca88ac9e6
--- /dev/null
+++ b/arch/sh/cchips/voyagergx/setup.c
@@ -0,0 +1,37 @@
1/*
2 * arch/sh/cchips/voyagergx/setup.c
3 *
4 * Setup routines for VoyagerGX cchip.
5 *
6 * Copyright (C) 2003 Lineo uSolutions, Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13#include <linux/init.h>
14#include <linux/module.h>
15#include <asm/io.h>
16#include <asm/rts7751r2d/voyagergx_reg.h>
17
18static int __init setup_voyagergx(void)
19{
20 unsigned long val;
21
22 val = inl(DRAM_CTRL);
23 val |= (DRAM_CTRL_CPU_COLUMN_SIZE_256 |
24 DRAM_CTRL_CPU_ACTIVE_PRECHARGE |
25 DRAM_CTRL_CPU_RESET |
26 DRAM_CTRL_REFRESH_COMMAND |
27 DRAM_CTRL_BLOCK_WRITE_TIME |
28 DRAM_CTRL_BLOCK_WRITE_PRECHARGE |
29 DRAM_CTRL_ACTIVE_PRECHARGE |
30 DRAM_CTRL_RESET |
31 DRAM_CTRL_REMAIN_ACTIVE);
32 outl(val, DRAM_CTRL);
33
34 return 0;
35}
36
37module_init(setup_voyagergx);