aboutsummaryrefslogtreecommitdiff
path: root/arch/m68k/atari
diff options
context:
space:
mode:
Diffstat (limited to 'arch/m68k/atari')
-rw-r--r--arch/m68k/atari/ataints.c441
-rw-r--r--arch/m68k/atari/atakeyb.c11
-rw-r--r--arch/m68k/atari/atasound.c1
-rw-r--r--arch/m68k/atari/config.c264
-rw-r--r--arch/m68k/atari/debug.c20
-rw-r--r--arch/m68k/atari/stdma.c2
-rw-r--r--arch/m68k/atari/stram.c383
-rw-r--r--arch/m68k/atari/time.c7
8 files changed, 560 insertions, 569 deletions
diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c
index 39478dd08e6..3d2b63bedf0 100644
--- a/arch/m68k/atari/ataints.c
+++ b/arch/m68k/atari/ataints.c
@@ -41,8 +41,8 @@
#include <linux/init.h>
#include <linux/seq_file.h>
#include <linux/module.h>
+#include <linux/irq.h>
-#include <asm/system.h>
#include <asm/traps.h>
#include <asm/atarihw.h>
@@ -50,6 +50,7 @@
#include <asm/atari_stdma.h>
#include <asm/irq.h>
#include <asm/entry.h>
+#include <asm/io.h>
/*
@@ -60,243 +61,7 @@
* <asm/atariints.h>): Autovector interrupts are 1..7, then follow ST-MFP,
* TT-MFP, SCC, and finally VME interrupts. Vector numbers for the latter can
* be allocated by atari_register_vme_int().
- *
- * Each interrupt can be of three types:
- *
- * - SLOW: The handler runs with all interrupts enabled, except the one it
- * was called by (to avoid reentering). This should be the usual method.
- * But it is currently possible only for MFP ints, since only the MFP
- * offers an easy way to mask interrupts.
- *
- * - FAST: The handler runs with all interrupts disabled. This should be used
- * only for really fast handlers, that just do actions immediately
- * necessary, and let the rest do a bottom half or task queue.
- *
- * - PRIORITIZED: The handler can be interrupted by higher-level ints
- * (greater IPL, no MFP priorities!). This is the method of choice for ints
- * which should be slow, but are not from a MFP.
- *
- * The feature of more than one handler for one int source is still there, but
- * only applicable if all handers are of the same type. To not slow down
- * processing of ints with only one handler by the chaining feature, the list
- * calling function atari_call_irq_list() is only plugged in at the time the
- * second handler is registered.
- *
- * Implementation notes: For fast-as-possible int handling, there are separate
- * entry points for each type (slow/fast/prio). The assembler handler calls
- * the irq directly in the usual case, no C wrapper is involved. In case of
- * multiple handlers, atari_call_irq_list() is registered as handler and calls
- * in turn the real irq's. To ease access from assembler level to the irq
- * function pointer and accompanying data, these two are stored in a separate
- * array, irq_handler[]. The rest of data (type, name) are put into a second
- * array, irq_param, that is accessed from C only. For each slow interrupt (32
- * in all) there are separate handler functions, which makes it possible to
- * hard-code the MFP register address and value, are necessary to mask the
- * int. If there'd be only one generic function, lots of calculations would be
- * needed to determine MFP register and int mask from the vector number :-(
- *
- * Furthermore, slow ints may not lower the IPL below its previous value
- * (before the int happened). This is needed so that an int of class PRIO, on
- * that this int may be stacked, cannot be reentered. This feature is
- * implemented as follows: If the stack frame format is 1 (throwaway), the int
- * is not stacked, and the IPL is anded with 0xfbff, resulting in a new level
- * 2, which still blocks the HSYNC, but no interrupts of interest. If the
- * frame format is 0, the int is nested, and the old IPL value can be found in
- * the sr copy in the frame.
- */
-
-#if 0
-
-#define NUM_INT_SOURCES (8 + NUM_ATARI_SOURCES)
-
-typedef void (*asm_irq_handler)(void);
-
-struct irqhandler {
- irqreturn_t (*handler)(int, void *, struct pt_regs *);
- void *dev_id;
-};
-
-struct irqparam {
- unsigned long flags;
- const char *devname;
-};
-
-/*
- * Array with irq's and their parameter data. This array is accessed from low
- * level assembler code, so an element size of 8 allows usage of index scaling
- * addressing mode.
*/
-static struct irqhandler irq_handler[NUM_INT_SOURCES];
-
-/*
- * This array hold the rest of parameters of int handlers: type
- * (slow,fast,prio) and the name of the handler. These values are only
- * accessed from C
- */
-static struct irqparam irq_param[NUM_INT_SOURCES];
-
-/* check for valid int number (complex, sigh...) */
-#define IS_VALID_INTNO(n) \
- ((n) > 0 && \
- /* autovec and ST-MFP ok anyway */ \
- (((n) < TTMFP_SOURCE_BASE) || \
- /* TT-MFP ok if present */ \
- ((n) >= TTMFP_SOURCE_BASE && (n) < SCC_SOURCE_BASE && \
- ATARIHW_PRESENT(TT_MFP)) || \
- /* SCC ok if present and number even */ \
- ((n) >= SCC_SOURCE_BASE && (n) < VME_SOURCE_BASE && \
- !((n) & 1) && ATARIHW_PRESENT(SCC)) || \
- /* greater numbers ok if they are registered VME vectors */ \
- ((n) >= VME_SOURCE_BASE && (n) < VME_SOURCE_BASE + VME_MAX_SOURCES && \
- free_vme_vec_bitmap & (1 << ((n) - VME_SOURCE_BASE)))))
-
-
-/*
- * Here start the assembler entry points for interrupts
- */
-
-#define IRQ_NAME(nr) atari_slow_irq_##nr##_handler(void)
-
-#define BUILD_SLOW_IRQ(n) \
-asmlinkage void IRQ_NAME(n); \
-/* Dummy function to allow asm with operands. */ \
-void atari_slow_irq_##n##_dummy (void) { \
-__asm__ (__ALIGN_STR "\n" \
-"atari_slow_irq_" #n "_handler:\t" \
-" addl %6,%5\n" /* preempt_count() += HARDIRQ_OFFSET */ \
- SAVE_ALL_INT "\n" \
- GET_CURRENT(%%d0) "\n" \
-" andb #~(1<<(%c3&7)),%a4:w\n" /* mask this interrupt */ \
- /* get old IPL from stack frame */ \
-" bfextu %%sp@(%c2){#5,#3},%%d0\n" \
-" movew %%sr,%%d1\n" \
-" bfins %%d0,%%d1{#21,#3}\n" \
-" movew %%d1,%%sr\n" /* set IPL = previous value */ \
-" addql #1,%a0\n" \
-" lea %a1,%%a0\n" \
-" pea %%sp@\n" /* push addr of frame */ \
-" movel %%a0@(4),%%sp@-\n" /* push handler data */ \
-" pea (%c3+8)\n" /* push int number */ \
-" movel %%a0@,%%a0\n" \
-" jbsr %%a0@\n" /* call the handler */ \
-" addql #8,%%sp\n" \
-" addql #4,%%sp\n" \
-" orw #0x0600,%%sr\n" \
-" andw #0xfeff,%%sr\n" /* set IPL = 6 again */ \
-" orb #(1<<(%c3&7)),%a4:w\n" /* now unmask the int again */ \
-" jbra ret_from_interrupt\n" \
- : : "i" (&kstat_cpu(0).irqs[n+8]), "i" (&irq_handler[n+8]), \
- "n" (PT_OFF_SR), "n" (n), \
- "i" (n & 8 ? (n & 16 ? &tt_mfp.int_mk_a : &st_mfp.int_mk_a) \
- : (n & 16 ? &tt_mfp.int_mk_b : &st_mfp.int_mk_b)), \
- "m" (preempt_count()), "di" (HARDIRQ_OFFSET) \
-); \
- for (;;); /* fake noreturn */ \
-}
-
-BUILD_SLOW_IRQ(0);
-BUILD_SLOW_IRQ(1);
-BUILD_SLOW_IRQ(2);
-BUILD_SLOW_IRQ(3);
-BUILD_SLOW_IRQ(4);
-BUILD_SLOW_IRQ(5);
-BUILD_SLOW_IRQ(6);
-BUILD_SLOW_IRQ(7);
-BUILD_SLOW_IRQ(8);
-BUILD_SLOW_IRQ(9);
-BUILD_SLOW_IRQ(10);
-BUILD_SLOW_IRQ(11);
-BUILD_SLOW_IRQ(12);
-BUILD_SLOW_IRQ(13);
-BUILD_SLOW_IRQ(14);
-BUILD_SLOW_IRQ(15);
-BUILD_SLOW_IRQ(16);
-BUILD_SLOW_IRQ(17);
-BUILD_SLOW_IRQ(18);
-BUILD_SLOW_IRQ(19);
-BUILD_SLOW_IRQ(20);
-BUILD_SLOW_IRQ(21);
-BUILD_SLOW_IRQ(22);
-BUILD_SLOW_IRQ(23);
-BUILD_SLOW_IRQ(24);
-BUILD_SLOW_IRQ(25);
-BUILD_SLOW_IRQ(26);
-BUILD_SLOW_IRQ(27);
-BUILD_SLOW_IRQ(28);
-BUILD_SLOW_IRQ(29);
-BUILD_SLOW_IRQ(30);
-BUILD_SLOW_IRQ(31);
-
-asm_irq_handler slow_handlers[32] = {
- [0] = atari_slow_irq_0_handler,
- [1] = atari_slow_irq_1_handler,
- [2] = atari_slow_irq_2_handler,
- [3] = atari_slow_irq_3_handler,
- [4] = atari_slow_irq_4_handler,
- [5] = atari_slow_irq_5_handler,
- [6] = atari_slow_irq_6_handler,
- [7] = atari_slow_irq_7_handler,
- [8] = atari_slow_irq_8_handler,
- [9] = atari_slow_irq_9_handler,
- [10] = atari_slow_irq_10_handler,
- [11] = atari_slow_irq_11_handler,
- [12] = atari_slow_irq_12_handler,
- [13] = atari_slow_irq_13_handler,
- [14] = atari_slow_irq_14_handler,
- [15] = atari_slow_irq_15_handler,
- [16] = atari_slow_irq_16_handler,
- [17] = atari_slow_irq_17_handler,
- [18] = atari_slow_irq_18_handler,
- [19] = atari_slow_irq_19_handler,
- [20] = atari_slow_irq_20_handler,
- [21] = atari_slow_irq_21_handler,
- [22] = atari_slow_irq_22_handler,
- [23] = atari_slow_irq_23_handler,
- [24] = atari_slow_irq_24_handler,
- [25] = atari_slow_irq_25_handler,
- [26] = atari_slow_irq_26_handler,
- [27] = atari_slow_irq_27_handler,
- [28] = atari_slow_irq_28_handler,
- [29] = atari_slow_irq_29_handler,
- [30] = atari_slow_irq_30_handler,
- [31] = atari_slow_irq_31_handler
-};
-
-asmlinkage void atari_fast_irq_handler( void );
-asmlinkage void atari_prio_irq_handler( void );
-
-/* Dummy function to allow asm with operands. */
-void atari_fast_prio_irq_dummy (void) {
-__asm__ (__ALIGN_STR "\n"
-"atari_fast_irq_handler:\n\t"
- "orw #0x700,%%sr\n" /* disable all interrupts */
-"atari_prio_irq_handler:\n\t"
- "addl %3,%2\n\t" /* preempt_count() += HARDIRQ_OFFSET */
- SAVE_ALL_INT "\n\t"
- GET_CURRENT(%%d0) "\n\t"
- /* get vector number from stack frame and convert to source */
- "bfextu %%sp@(%c1){#4,#10},%%d0\n\t"
- "subw #(0x40-8),%%d0\n\t"
- "jpl 1f\n\t"
- "addw #(0x40-8-0x18),%%d0\n"
- "1:\tlea %a0,%%a0\n\t"
- "addql #1,%%a0@(%%d0:l:4)\n\t"
- "lea irq_handler,%%a0\n\t"
- "lea %%a0@(%%d0:l:8),%%a0\n\t"
- "pea %%sp@\n\t" /* push frame address */
- "movel %%a0@(4),%%sp@-\n\t" /* push handler data */
- "movel %%d0,%%sp@-\n\t" /* push int number */
- "movel %%a0@,%%a0\n\t"
- "jsr %%a0@\n\t" /* and call the handler */
- "addql #8,%%sp\n\t"
- "addql #4,%%sp\n\t"
- "jbra ret_from_interrupt"
- : : "i" (&kstat_cpu(0).irqs), "n" (PT_OFF_FORMATVEC),
- "m" (preempt_count()), "di" (HARDIRQ_OFFSET)
-);
- for (;;);
-}
-#endif
/*
* Bitmap for free interrupt vector numbers
@@ -318,33 +83,174 @@ __ALIGN_STR "\n\t"
extern void atari_microwire_cmd(int cmd);
-extern int atari_SCC_reset_done;
-
-static int atari_startup_irq(unsigned int irq)
+static unsigned int atari_irq_startup(struct irq_data *data)
{
- m68k_irq_startup(irq);
+ unsigned int irq = data->irq;
+
+ m68k_irq_startup(data);
atari_turnon_irq(irq);
atari_enable_irq(irq);
return 0;
}
-static void atari_shutdown_irq(unsigned int irq)
+static void atari_irq_shutdown(struct irq_data *data)
{
+ unsigned int irq = data->irq;
+
atari_disable_irq(irq);
atari_turnoff_irq(irq);
- m68k_irq_shutdown(irq);
+ m68k_irq_shutdown(data);
if (irq == IRQ_AUTO_4)
vectors[VEC_INT4] = falcon_hblhandler;
}
-static struct irq_controller atari_irq_controller = {
+static void atari_irq_enable(struct irq_data *data)
+{
+ atari_enable_irq(data->irq);
+}
+
+static void atari_irq_disable(struct irq_data *data)
+{
+ atari_disable_irq(data->irq);
+}
+
+static struct irq_chip atari_irq_chip = {
.name = "atari",
- .lock = __SPIN_LOCK_UNLOCKED(atari_irq_controller.lock),
- .startup = atari_startup_irq,
- .shutdown = atari_shutdown_irq,
- .enable = atari_enable_irq,
- .disable = atari_disable_irq,
+ .irq_startup = atari_irq_startup,
+ .irq_shutdown = atari_irq_shutdown,
+ .irq_enable = atari_irq_enable,
+ .irq_disable = atari_irq_disable,
+};
+
+/*
+ * ST-MFP timer D chained interrupts - each driver gets its own timer
+ * interrupt instance.
+ */
+
+struct mfptimerbase {
+ volatile struct MFP *mfp;
+ unsigned char mfp_mask, mfp_data;
+ unsigned short int_mask;
+ int handler_irq, mfptimer_irq, server_irq;
+ char *name;
+} stmfp_base = {
+ .mfp = &st_mfp,
+ .int_mask = 0x0,
+ .handler_irq = IRQ_MFP_TIMD,
+ .mfptimer_irq = IRQ_MFP_TIMER1,
+ .name = "MFP Timer D"
+};
+
+static irqreturn_t mfptimer_handler(int irq, void *dev_id)
+{
+ struct mfptimerbase *base = dev_id;
+ int mach_irq;
+ unsigned char ints;
+
+ mach_irq = base->mfptimer_irq;
+ ints = base->int_mask;
+ for (; ints; mach_irq++, ints >>= 1) {
+ if (ints & 1)
+ generic_handle_irq(mach_irq);
+ }
+ return IRQ_HANDLED;
+}
+
+
+static void atari_mfptimer_enable(struct irq_data *data)
+{
+ int mfp_num = data->irq - IRQ_MFP_TIMER1;
+ stmfp_base.int_mask |= 1 << mfp_num;
+ atari_enable_irq(IRQ_MFP_TIMD);
+}
+
+static void atari_mfptimer_disable(struct irq_data *data)
+{
+ int mfp_num = data->irq - IRQ_MFP_TIMER1;
+ stmfp_base.int_mask &= ~(1 << mfp_num);
+ if (!stmfp_base.int_mask)
+ atari_disable_irq(IRQ_MFP_TIMD);
+}
+
+static struct irq_chip atari_mfptimer_chip = {
+ .name = "timer_d",
+ .irq_enable = atari_mfptimer_enable,
+ .irq_disable = atari_mfptimer_disable,
+};
+
+
+/*
+ * EtherNAT CPLD interrupt handling
+ * CPLD interrupt register is at phys. 0x80000023
+ * Need this mapped in at interrupt startup time
+ * Possibly need this mapped on demand anyway -
+ * EtherNAT USB driver needs to disable IRQ before
+ * startup!
+ */
+
+static unsigned char *enat_cpld;
+
+static unsigned int atari_ethernat_startup(struct irq_data *data)
+{
+ int enat_num = 140 - data->irq + 1;
+
+ m68k_irq_startup(data);
+ /*
+ * map CPLD interrupt register
+ */
+ if (!enat_cpld)
+ enat_cpld = (unsigned char *)ioremap((ATARI_ETHERNAT_PHYS_ADDR+0x23), 0x2);
+ /*
+ * do _not_ enable the USB chip interrupt here - causes interrupt storm
+ * and triggers dead interrupt watchdog
+ * Need to reset the USB chip to a sane state in early startup before
+ * removing this hack
+ */
+ if (enat_num == 1)
+ *enat_cpld |= 1 << enat_num;
+
+ return 0;
+}
+
+static void atari_ethernat_enable(struct irq_data *data)
+{
+ int enat_num = 140 - data->irq + 1;
+ /*
+ * map CPLD interrupt register
+ */
+ if (!enat_cpld)
+ enat_cpld = (unsigned char *)ioremap((ATARI_ETHERNAT_PHYS_ADDR+0x23), 0x2);
+ *enat_cpld |= 1 << enat_num;
+}
+
+static void atari_ethernat_disable(struct irq_data *data)
+{
+ int enat_num = 140 - data->irq + 1;
+ /*
+ * map CPLD interrupt register
+ */
+ if (!enat_cpld)
+ enat_cpld = (unsigned char *)ioremap((ATARI_ETHERNAT_PHYS_ADDR+0x23), 0x2);
+ *enat_cpld &= ~(1 << enat_num);
+}
+
+static void atari_ethernat_shutdown(struct irq_data *data)
+{
+ int enat_num = 140 - data->irq + 1;
+ if (enat_cpld) {
+ *enat_cpld &= ~(1 << enat_num);
+ iounmap(enat_cpld);
+ enat_cpld = NULL;
+ }
+}
+
+static struct irq_chip atari_ethernat_chip = {
+ .name = "ethernat",
+ .irq_startup = atari_ethernat_startup,
+ .irq_shutdown = atari_ethernat_shutdown,
+ .irq_enable = atari_ethernat_enable,
+ .irq_disable = atari_ethernat_disable,
};
/*
@@ -360,8 +266,9 @@ static struct irq_controller atari_irq_controller = {
void __init atari_init_IRQ(void)
{
- m68k_setup_user_interrupt(VEC_USER, NUM_ATARI_SOURCES - IRQ_USER, NULL);
- m68k_setup_irq_controller(&atari_irq_controller, 1, NUM_ATARI_SOURCES - 1);
+ m68k_setup_user_interrupt(VEC_USER, NUM_ATARI_SOURCES - IRQ_USER);
+ m68k_setup_irq_controller(&atari_irq_chip, handle_simple_irq, 1,
+ NUM_ATARI_SOURCES - 1);
/* Initialize the MFP(s) */
@@ -388,9 +295,9 @@ void __init atari_init_IRQ(void)
}
if (ATARIHW_PRESENT(SCC) && !atari_SCC_reset_done) {
- scc.cha_a_ctrl = 9;
+ atari_scc.cha_a_ctrl = 9;
MFPDELAY();
- scc.cha_a_ctrl = (char) 0xc0; /* hardware reset */
+ atari_scc.cha_a_ctrl = (char) 0xc0; /* hardware reset */
}
if (ATARIHW_PRESENT(SCU)) {
@@ -423,6 +330,30 @@ void __init atari_init_IRQ(void)
/* Initialize the PSG: all sounds off, both ports output */
sound_ym.rd_data_reg_sel = 7;
sound_ym.wd_data = 0xff;
+
+ m68k_setup_irq_controller(&atari_mfptimer_chip, handle_simple_irq,
+ IRQ_MFP_TIMER1, 8);
+
+ irq_set_status_flags(IRQ_MFP_TIMER1, IRQ_IS_POLLED);
+ irq_set_status_flags(IRQ_MFP_TIMER2, IRQ_IS_POLLED);
+
+ /* prepare timer D data for use as poll interrupt */
+ /* set Timer D data Register - needs to be > 0 */
+ st_mfp.tim_dt_d = 254; /* < 100 Hz */
+ /* start timer D, div = 1:100 */
+ st_mfp.tim_ct_cd = (st_mfp.tim_ct_cd & 0xf0) | 0x6;
+
+ /* request timer D dispatch handler */
+ if (request_irq(IRQ_MFP_TIMD, mfptimer_handler, IRQF_SHARED,
+ stmfp_base.name, &stmfp_base))
+ pr_err("Couldn't register %s interrupt\n", stmfp_base.name);
+
+ /*
+ * EtherNAT ethernet / USB interrupt handlers
+ */
+
+ m68k_setup_irq_controller(&atari_ethernat_chip, handle_simple_irq,
+ 139, 2);
}
@@ -431,7 +362,7 @@ void __init atari_init_IRQ(void)
* hardware with a programmable int vector (probably a VME board).
*/
-unsigned long atari_register_vme_int(void)
+unsigned int atari_register_vme_int(void)
{
int i;
@@ -448,7 +379,7 @@ unsigned long atari_register_vme_int(void)
EXPORT_SYMBOL(atari_register_vme_int);
-void atari_unregister_vme_int(unsigned long irq)
+void atari_unregister_vme_int(unsigned int irq)
{
if (irq >= VME_SOURCE_BASE && irq < VME_SOURCE_BASE + VME_MAX_SOURCES) {
irq -= VME_SOURCE_BASE;
diff --git a/arch/m68k/atari/atakeyb.c b/arch/m68k/atari/atakeyb.c
index 5890897d28b..95022b04b62 100644
--- a/arch/m68k/atari/atakeyb.c
+++ b/arch/m68k/atari/atakeyb.c
@@ -36,13 +36,10 @@
/* Hook for MIDI serial driver */
void (*atari_MIDI_interrupt_hook) (void);
-/* Hook for mouse driver */
-void (*atari_mouse_interrupt_hook) (char *);
/* Hook for keyboard inputdev driver */
void (*atari_input_keyboard_interrupt_hook) (unsigned char, char);
/* Hook for mouse inputdev driver */
void (*atari_input_mouse_interrupt_hook) (char *);
-EXPORT_SYMBOL(atari_mouse_interrupt_hook);
EXPORT_SYMBOL(atari_input_keyboard_interrupt_hook);
EXPORT_SYMBOL(atari_input_mouse_interrupt_hook);
@@ -130,7 +127,7 @@ KEYBOARD_STATE kb_state;
* it's really hard to decide whether they're mouse or keyboard bytes. Since
* overruns usually occur when moving the Atari mouse rapidly, they're seen as
* mouse bytes here. If this is wrong, only a make code of the keyboard gets
- * lost, which isn't too bad. Loosing a break code would be disastrous,
+ * lost, which isn't too bad. Losing a break code would be disastrous,
* because then the keyboard repeat strikes...
*/
@@ -263,8 +260,8 @@ repeat:
kb_state.buf[kb_state.len++] = scancode;
if (kb_state.len == 3) {
kb_state.state = KEYBOARD;
- if (atari_mouse_interrupt_hook)
- atari_mouse_interrupt_hook(kb_state.buf);
+ if (atari_input_mouse_interrupt_hook)
+ atari_input_mouse_interrupt_hook(kb_state.buf);
}
break;
@@ -575,7 +572,7 @@ int atari_keyb_init(void)
kb_state.len = 0;
error = request_irq(IRQ_MFP_ACIA, atari_keyboard_interrupt,
- IRQ_TYPE_SLOW, "keyboard/mouse/MIDI",
+ IRQ_TYPE_SLOW, "keyboard,mouse,MIDI",
atari_keyboard_interrupt);
if (error)
return error;
diff --git a/arch/m68k/atari/atasound.c b/arch/m68k/atari/atasound.c
index d266fe89c12..1c1181ebb94 100644
--- a/arch/m68k/atari/atasound.c
+++ b/arch/m68k/atari/atasound.c
@@ -25,7 +25,6 @@
#include <linux/module.h>
#include <asm/atarihw.h>
-#include <asm/system.h>
#include <asm/irq.h>
#include <asm/pgtable.h>
#include <asm/atariints.h>
diff --git a/arch/m68k/atari/config.c b/arch/m68k/atari/config.c
index ae2d96e5d61..01a62161b08 100644
--- a/arch/m68k/atari/config.c
+++ b/arch/m68k/atari/config.c
@@ -31,15 +31,18 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/usb/isp116x.h>
#include <linux/vt_kern.h>
#include <linux/module.h>
#include <asm/bootinfo.h>
+#include <asm/bootinfo-atari.h>
+#include <asm/byteorder.h>
#include <asm/setup.h>
#include <asm/atarihw.h>
#include <asm/atariints.h>
#include <asm/atari_stram.h>
-#include <asm/system.h>
#include <asm/machdep.h>
#include <asm/hwtest.h>
#include <asm/io.h>
@@ -75,7 +78,7 @@ static void atari_heartbeat(int on);
/* atari specific timer functions (in time.c) */
extern void atari_sched_init(irq_handler_t);
-extern unsigned long atari_gettimeoffset (void);
+extern u32 atari_gettimeoffset(void);
extern int atari_mste_hwclk (int, struct rtc_time *);
extern int atari_tt_hwclk (int, struct rtc_time *);
extern int atari_mste_set_clock_mmss (unsigned long);
@@ -128,14 +131,14 @@ static int __init scc_test(volatile char *ctla)
int __init atari_parse_bootinfo(const struct bi_record *record)
{
int unknown = 0;
- const u_long *data = record->data;
+ const void *data = record->data;
- switch (record->tag) {
+ switch (be16_to_cpu(record->tag)) {
case BI_ATARI_MCH_COOKIE:
- atari_mch_cookie = *data;
+ atari_mch_cookie = be32_to_cpup(data);
break;
case BI_ATARI_MCH_TYPE:
- atari_mch_type = *data;
+ atari_mch_type = be32_to_cpup(data);
break;
default:
unknown = 1;
@@ -205,7 +208,7 @@ void __init config_atari(void)
mach_init_IRQ = atari_init_IRQ;
mach_get_model = atari_get_model;
mach_get_hardware_list = atari_get_hardware_list;
- mach_gettimeoffset = atari_gettimeoffset;
+ arch_gettimeoffset = atari_gettimeoffset;
mach_reset = atari_reset;
mach_max_dma_address = 0xffffff;
#if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE)
@@ -315,7 +318,7 @@ void __init config_atari(void)
ATARIHW_SET(SCC_DMA);
printk("SCC_DMA ");
}
- if (scc_test(&scc.cha_a_ctrl)) {
+ if (scc_test(&atari_scc.cha_a_ctrl)) {
ATARIHW_SET(SCC);
printk("SCC ");
}
@@ -414,9 +417,9 @@ void __init config_atari(void)
* FDC val = 4 -> Supervisor only */
asm volatile ("\n"
" .chip 68030\n"
- " pmove %0@,%/tt1\n"
+ " pmove %0,%/tt1\n"
" .chip 68k"
- : : "a" (&tt1_val));
+ : : "m" (tt1_val));
} else {
asm volatile ("\n"
" .chip 68040\n"
@@ -569,10 +572,10 @@ static void atari_reset(void)
: "d0");
} else
asm volatile ("\n"
- " pmove %0@,%%tc\n"
+ " pmove %0,%%tc\n"
" jmp %1@"
: /* no outputs */
- : "a" (&tc_val), "a" (reset_addr));
+ : "m" (tc_val), "a" (reset_addr));
}
@@ -656,3 +659,240 @@ static void atari_get_hardware_list(struct seq_file *m)
ATARIHW_ANNOUNCE(VME, "VME Bus");
ATARIHW_ANNOUNCE(DSP56K, "DSP56001 processor");
}
+
+/*
+ * MSch: initial platform device support for Atari,
+ * required for EtherNAT/EtherNEC/NetUSBee drivers
+ */
+
+#if defined(CONFIG_ATARI_ETHERNAT) || defined(CONFIG_ATARI_ETHERNEC)
+static void isp1160_delay(struct device *dev, int delay)
+{
+ ndelay(delay);
+}
+#endif
+
+#ifdef CONFIG_ATARI_ETHERNAT
+/*
+ * EtherNAT: SMC91C111 Ethernet chipset, handled by smc91x driver
+ */
+
+#define ATARI_ETHERNAT_IRQ 140
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .name = "smc91x-regs",
+ .start = ATARI_ETHERNAT_PHYS_ADDR,
+ .end = ATARI_ETHERNAT_PHYS_ADDR + 0xfffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .name = "smc91x-irq",
+ .start = ATARI_ETHERNAT_IRQ,
+ .end = ATARI_ETHERNAT_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+
+/*
+ * ISP 1160 - using the isp116x-hcd module
+ */
+
+#define ATARI_USB_PHYS_ADDR 0x80000012
+#define ATARI_USB_IRQ 139
+
+static struct resource isp1160_resources[] = {
+ [0] = {
+ .name = "isp1160-data",
+ .start = ATARI_USB_PHYS_ADDR,
+ .end = ATARI_USB_PHYS_ADDR + 0x1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .name = "isp1160-regs",
+ .start = ATARI_USB_PHYS_ADDR + 0x4,
+ .end = ATARI_USB_PHYS_ADDR + 0x5,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .name = "isp1160-irq",
+ .start = ATARI_USB_IRQ,
+ .end = ATARI_USB_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/* (DataBusWidth16|AnalogOCEnable|DREQOutputPolarity|DownstreamPort15KRSel ) */
+static struct isp116x_platform_data isp1160_platform_data = {
+ /* Enable internal resistors on downstream ports */
+ .sel15Kres = 1,
+ /* On-chip overcurrent protection */
+ .oc_enable = 1,
+ /* INT output polarity */
+ .int_act_high = 1,
+ /* INT edge or level triggered */
+ .int_edge_triggered = 0,
+
+ /* WAKEUP pin connected - NOT SUPPORTED */
+ /* .remote_wakeup_connected = 0, */
+ /* Wakeup by devices on usb bus enabled */
+ .remote_wakeup_enable = 0,
+ .delay = isp1160_delay,
+};
+
+static struct platform_device isp1160_device = {
+ .name = "isp116x-hcd",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(isp1160_resources),
+ .resource = isp1160_resources,
+ .dev = {
+ .platform_data = &isp1160_platform_data,
+ },
+};
+
+static struct platform_device *atari_ethernat_devices[] __initdata = {
+ &smc91x_device,
+ &isp1160_device
+};
+#endif /* CONFIG_ATARI_ETHERNAT */
+
+#ifdef CONFIG_ATARI_ETHERNEC
+/*
+ * EtherNEC: RTL8019 (NE2000 compatible) Ethernet chipset,
+ * handled by ne.c driver
+ */
+
+#define ATARI_ETHERNEC_PHYS_ADDR 0xfffa0000
+#define ATARI_ETHERNEC_BASE 0x300
+#define ATARI_ETHERNEC_IRQ IRQ_MFP_TIMER1
+
+static struct resource rtl8019_resources[] = {
+ [0] = {
+ .name = "rtl8019-regs",
+ .start = ATARI_ETHERNEC_BASE,
+ .end = ATARI_ETHERNEC_BASE + 0x20 - 1,
+ .flags = IORESOURCE_IO,
+ },
+ [1] = {
+ .name = "rtl8019-irq",
+ .start = ATARI_ETHERNEC_IRQ,
+ .end = ATARI_ETHERNEC_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device rtl8019_device = {
+ .name = "ne",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(rtl8019_resources),
+ .resource = rtl8019_resources,
+};
+
+/*
+ * NetUSBee: ISP1160 USB host adapter via ROM-port adapter
+ */
+
+#define ATARI_NETUSBEE_PHYS_ADDR 0xfffa8000
+#define ATARI_NETUSBEE_BASE 0x340
+#define ATARI_NETUSBEE_IRQ IRQ_MFP_TIMER2
+
+static struct resource netusbee_resources[] = {
+ [0] = {
+ .name = "isp1160-data",
+ .start = ATARI_NETUSBEE_BASE,
+ .end = ATARI_NETUSBEE_BASE + 0x1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .name = "isp1160-regs",
+ .start = ATARI_NETUSBEE_BASE + 0x20,
+ .end = ATARI_NETUSBEE_BASE + 0x21,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .name = "isp1160-irq",
+ .start = ATARI_NETUSBEE_IRQ,
+ .end = ATARI_NETUSBEE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/* (DataBusWidth16|AnalogOCEnable|DREQOutputPolarity|DownstreamPort15KRSel ) */
+static struct isp116x_platform_data netusbee_platform_data = {
+ /* Enable internal resistors on downstream ports */
+ .sel15Kres = 1,
+ /* On-chip overcurrent protection */
+ .oc_enable = 1,
+ /* INT output polarity */
+ .int_act_high = 1,
+ /* INT edge or level triggered */
+ .int_edge_triggered = 0,
+
+ /* WAKEUP pin connected - NOT SUPPORTED */
+ /* .remote_wakeup_connected = 0, */
+ /* Wakeup by devices on usb bus enabled */
+ .remote_wakeup_enable = 0,
+ .delay = isp1160_delay,
+};
+
+static struct platform_device netusbee_device = {
+ .name = "isp116x-hcd",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(netusbee_resources),
+ .resource = netusbee_resources,
+ .dev = {
+ .platform_data = &netusbee_platform_data,
+ },
+};
+
+static struct platform_device *atari_netusbee_devices[] __initdata = {
+ &rtl8019_device,
+ &netusbee_device
+};
+#endif /* CONFIG_ATARI_ETHERNEC */
+
+int __init atari_platform_init(void)
+{
+ int rv = 0;
+
+ if (!MACH_IS_ATARI)
+ return -ENODEV;
+
+#ifdef CONFIG_ATARI_ETHERNAT
+ {
+ unsigned char *enatc_virt;
+ enatc_virt = (unsigned char *)ioremap((ATARI_ETHERNAT_PHYS_ADDR+0x23), 0xf);
+ if (hwreg_present(enatc_virt)) {
+ rv = platform_add_devices(atari_ethernat_devices,
+ ARRAY_SIZE(atari_ethernat_devices));
+ }
+ iounmap(enatc_virt);
+ }
+#endif
+
+#ifdef CONFIG_ATARI_ETHERNEC
+ {
+ int error;
+ unsigned char *enec_virt;
+ enec_virt = (unsigned char *)ioremap((ATARI_ETHERNEC_PHYS_ADDR), 0xf);
+ if (hwreg_present(enec_virt)) {
+ error = platform_add_devices(atari_netusbee_devices,
+ ARRAY_SIZE(atari_netusbee_devices));
+ if (error && !rv)
+ rv = error;
+ }
+ iounmap(enec_virt);
+ }
+#endif
+
+ return rv;
+}
+
+arch_initcall(atari_platform_init);
diff --git a/arch/m68k/atari/debug.c b/arch/m68k/atari/debug.c
index 28efdc33c1a..03cb5e08d7c 100644
--- a/arch/m68k/atari/debug.c
+++ b/arch/m68k/atari/debug.c
@@ -53,9 +53,9 @@ static inline void ata_scc_out(char c)
{
do {
MFPDELAY();
- } while (!(scc.cha_b_ctrl & 0x04)); /* wait for tx buf empty */
+ } while (!(atari_scc.cha_b_ctrl & 0x04)); /* wait for tx buf empty */
MFPDELAY();
- scc.cha_b_data = c;
+ atari_scc.cha_b_data = c;
}
static void atari_scc_console_write(struct console *co, const char *str,
@@ -140,9 +140,9 @@ int atari_scc_console_wait_key(struct console *co)
{
do {
MFPDELAY();
- } while (!(scc.cha_b_ctrl & 0x01)); /* wait for rx buf filled */
+ } while (!(atari_scc.cha_b_ctrl & 0x01)); /* wait for rx buf filled */
MFPDELAY();
- return scc.cha_b_data;
+ return atari_scc.cha_b_data;
}
int atari_midi_console_wait_key(struct console *co)
@@ -185,9 +185,9 @@ static void __init atari_init_mfp_port(int cflag)
#define SCC_WRITE(reg, val) \
do { \
- scc.cha_b_ctrl = (reg); \
+ atari_scc.cha_b_ctrl = (reg); \
MFPDELAY(); \
- scc.cha_b_ctrl = (val); \
+ atari_scc.cha_b_ctrl = (val); \
MFPDELAY(); \
} while (0)
@@ -202,7 +202,6 @@ static void __init atari_init_mfp_port(int cflag)
static void __init atari_init_scc_port(int cflag)
{
- extern int atari_SCC_reset_done;
static int clksrc_table[9] =
/* reg 11: 0x50 = BRG, 0x00 = RTxC, 0x28 = TRxC */
{ 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x00, 0x00 };
@@ -240,7 +239,7 @@ static void __init atari_init_scc_port(int cflag)
reg3 = (cflag & CSIZE) == CS8 ? 0xc0 : 0x40;
reg5 = (cflag & CSIZE) == CS8 ? 0x60 : 0x20 | 0x82 /* assert DTR/RTS */;
- (void)scc.cha_b_ctrl; /* reset reg pointer */
+ (void)atari_scc.cha_b_ctrl; /* reset reg pointer */
SCC_WRITE(9, 0xc0); /* reset */
LONG_DELAY(); /* extra delay after WR9 access */
SCC_WRITE(4, (cflag & PARENB) ? ((cflag & PARODD) ? 0x01 : 0x03)
@@ -288,6 +287,8 @@ static void __init atari_init_midi_port(int cflag)
static int __init atari_debug_setup(char *arg)
{
+ bool registered;
+
if (!MACH_IS_ATARI)
return 0;
@@ -295,6 +296,7 @@ static int __init atari_debug_setup(char *arg)
/* defaults to ser2 for a Falcon and ser1 otherwise */
arg = MACH_IS_FALCON ? "ser2" : "ser1";
+ registered = !!atari_console_driver.write;
if (!strcmp(arg, "ser1")) {
/* ST-MFP Modem1 serial port */
atari_init_mfp_port(B9600|CS8);
@@ -318,7 +320,7 @@ static int __init atari_debug_setup(char *arg)
sound_ym.wd_data = sound_ym.rd_data_reg_sel | 0x20; /* strobe H */
atari_console_driver.write = atari_par_console_write;
}
- if (atari_console_driver.write)
+ if (atari_console_driver.write && !registered)
register_console(&atari_console_driver);
return 0;
diff --git a/arch/m68k/atari/stdma.c b/arch/m68k/atari/stdma.c
index 604329fafbb..ddbf43ca885 100644
--- a/arch/m68k/atari/stdma.c
+++ b/arch/m68k/atari/stdma.c
@@ -180,7 +180,7 @@ void __init stdma_init(void)
{
stdma_isr = NULL;
if (request_irq(IRQ_MFP_FDC, stdma_int, IRQ_TYPE_SLOW | IRQF_SHARED,
- "ST-DMA: floppy/ACSI/IDE/Falcon-SCSI", stdma_int))
+ "ST-DMA floppy,ACSI,IDE,Falcon-SCSI", stdma_int))
pr_err("Couldn't register ST-DMA interrupt\n");
}
diff --git a/arch/m68k/atari/stram.c b/arch/m68k/atari/stram.c
index 6ec3b7f3377..5f8cb5a234d 100644
--- a/arch/m68k/atari/stram.c
+++ b/arch/m68k/atari/stram.c
@@ -1,5 +1,5 @@
/*
- * arch/m68k/atari/stram.c: Functions for ST-RAM allocations
+ * Functions for ST-RAM allocations
*
* Copyright 1994-97 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
*
@@ -30,91 +30,36 @@
#include <asm/atari_stram.h>
#include <asm/io.h>
-#undef DEBUG
-
-#ifdef DEBUG
-#define DPRINTK(fmt,args...) printk( fmt, ##args )
-#else
-#define DPRINTK(fmt,args...)
-#endif
-
-#if defined(CONFIG_PROC_FS) && defined(CONFIG_STRAM_PROC)
-/* abbrev for the && above... */
-#define DO_PROC
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#endif
/*
- * ++roman:
- *
- * New version of ST-Ram buffer allocation. Instead of using the
- * 1 MB - 4 KB that remain when the ST-Ram chunk starts at $1000
- * (1 MB granularity!), such buffers are reserved like this:
- *
- * - If the kernel resides in ST-Ram anyway, we can take the buffer
- * from behind the current kernel data space the normal way
- * (incrementing start_mem).
- *
- * - If the kernel is in TT-Ram, stram_init() initializes start and
- * end of the available region. Buffers are allocated from there
- * and mem_init() later marks the such used pages as reserved.
- * Since each TT-Ram chunk is at least 4 MB in size, I hope there
- * won't be an overrun of the ST-Ram region by normal kernel data
- * space.
- *
- * For that, ST-Ram may only be allocated while kernel initialization
- * is going on, or exactly: before mem_init() is called. There is also
- * no provision now for freeing ST-Ram buffers. It seems that isn't
- * really needed.
- *
+ * The ST-RAM allocator allocates memory from a pool of reserved ST-RAM of
+ * configurable size, set aside on ST-RAM init.
+ * As long as this pool is not exhausted, allocation of real ST-RAM can be
+ * guaranteed.
*/
-/* Start and end (virtual) of ST-RAM */
-static void *stram_start, *stram_end;
-
-/* set after memory_init() executed and allocations via start_mem aren't
- * possible anymore */
-static int mem_init_done;
-
/* set if kernel is in ST-RAM */
static int kernel_in_stram;
-typedef struct stram_block {
- struct stram_block *next;
- void *start;
- unsigned long size;
- unsigned flags;
- const char *owner;
-} BLOCK;
-
-/* values for flags field */
-#define BLOCK_FREE 0x01 /* free structure in the BLOCKs pool */
-#define BLOCK_KMALLOCED 0x02 /* structure allocated by kmalloc() */
-#define BLOCK_GFP 0x08 /* block allocated with __get_dma_pages() */
+static struct resource stram_pool = {
+ .name = "ST-RAM Pool"
+};
-/* list of allocated blocks */
-static BLOCK *alloc_list;
+static unsigned long pool_size = 1024*1024;
-/* We can't always use kmalloc() to allocate BLOCK structures, since
- * stram_alloc() can be called rather early. So we need some pool of
- * statically allocated structures. 20 of them is more than enough, so in most
- * cases we never should need to call kmalloc(). */
-#define N_STATIC_BLOCKS 20
-static BLOCK static_blocks[N_STATIC_BLOCKS];
+static unsigned long stram_virt_offset;
-/***************************** Prototypes *****************************/
+static int __init atari_stram_setup(char *arg)
+{
+ if (!MACH_IS_ATARI)
+ return 0;
-static BLOCK *add_region( void *addr, unsigned long size );
-static BLOCK *find_region( void *addr );
-static int remove_region( BLOCK *block );
+ pool_size = memparse(arg, NULL);
+ return 0;
+}
-/************************* End of Prototypes **************************/
+early_param("stram_pool", atari_stram_setup);
-
-/* ------------------------------------------------------------------------ */
-/* Public Interface */
-/* ------------------------------------------------------------------------ */
/*
* This init function is called very early by atari/config.c
@@ -124,253 +69,129 @@ void __init atari_stram_init(void)
{
int i;
- /* initialize static blocks */
- for( i = 0; i < N_STATIC_BLOCKS; ++i )
- static_blocks[i].flags = BLOCK_FREE;
+ /*
+ * determine whether kernel code resides in ST-RAM
+ * (then ST-RAM is the first memory block at virtual 0x0)
+ */
+ kernel_in_stram = (m68k_memory[0].addr == 0);
- /* determine whether kernel code resides in ST-RAM (then ST-RAM is the
- * first memory block at virtual 0x0) */
- stram_start = phys_to_virt(0);
- kernel_in_stram = (stram_start == 0);
-
- for( i = 0; i < m68k_num_memory; ++i ) {
+ for (i = 0; i < m68k_num_memory; ++i) {
if (m68k_memory[i].addr == 0) {
- /* skip first 2kB or page (supervisor-only!) */
- stram_end = stram_start + m68k_memory[i].size;
return;
}
}
+
/* Should never come here! (There is always ST-Ram!) */
- panic( "atari_stram_init: no ST-RAM found!" );
+ panic("atari_stram_init: no ST-RAM found!");
}
/*
* This function is called from setup_arch() to reserve the pages needed for
- * ST-RAM management.
+ * ST-RAM management, if the kernel resides in ST-RAM.
*/
void __init atari_stram_reserve_pages(void *start_mem)
{
- /* always reserve first page of ST-RAM, the first 2 kB are
- * supervisor-only! */
- if (!kernel_in_stram)
- reserve_bootmem(0, PAGE_SIZE, BOOTMEM_DEFAULT);
-
-}
-
-void atari_stram_mem_init_hook (void)
-{
- mem_init_done = 1;
+ if (kernel_in_stram) {
+ pr_debug("atari_stram pool: kernel in ST-RAM, using alloc_bootmem!\n");
+ stram_pool.start = (resource_size_t)alloc_bootmem_low_pages(pool_size);
+ stram_pool.end = stram_pool.start + pool_size - 1;
+ request_resource(&iomem_resource, &stram_pool);
+ stram_virt_offset = 0;
+ pr_debug("atari_stram pool: size = %lu bytes, resource = %pR\n",
+ pool_size, &stram_pool);
+ pr_debug("atari_stram pool: stram_virt_offset = %lx\n",
+ stram_virt_offset);
+ }
}
/*
- * This is main public interface: somehow allocate a ST-RAM block
- *
- * - If we're before mem_init(), we have to make a static allocation. The
- * region is taken in the kernel data area (if the kernel is in ST-RAM) or
- * from the start of ST-RAM (if the kernel is in TT-RAM) and added to the
- * rsvd_stram_* region. The ST-RAM is somewhere in the middle of kernel
- * address space in the latter case.
- *
- * - If mem_init() already has been called, try with __get_dma_pages().
- * This has the disadvantage that it's very hard to get more than 1 page,
- * and it is likely to fail :-(
- *
+ * This function is called as arch initcall to reserve the pages needed for
+ * ST-RAM management, if the kernel does not reside in ST-RAM.
*/
-void *atari_stram_alloc(long size, const char *owner)
+int __init atari_stram_map_pages(void)
{
- void *addr = NULL;
- BLOCK *block;
- int flags;
-
- DPRINTK("atari_stram_alloc(size=%08lx,owner=%s)\n", size, owner);
-
- if (!mem_init_done)
- return alloc_bootmem_low(size);
- else {
- /* After mem_init(): can only resort to __get_dma_pages() */
- addr = (void *)__get_dma_pages(GFP_KERNEL, get_order(size));
- flags = BLOCK_GFP;
- DPRINTK( "atari_stram_alloc: after mem_init, "
- "get_pages=%p\n", addr );
- }
-
- if (addr) {
- if (!(block = add_region( addr, size ))) {
- /* out of memory for BLOCK structure :-( */
- DPRINTK( "atari_stram_alloc: out of mem for BLOCK -- "
- "freeing again\n" );
- free_pages((unsigned long)addr, get_order(size));
- return( NULL );
- }
- block->owner = owner;
- block->flags |= flags;
+ if (!kernel_in_stram) {
+ /*
+ * Skip page 0, as the fhe first 2 KiB are supervisor-only!
+ */
+ pr_debug("atari_stram pool: kernel not in ST-RAM, using ioremap!\n");
+ stram_pool.start = PAGE_SIZE;
+ stram_pool.end = stram_pool.start + pool_size - 1;
+ request_resource(&iomem_resource, &stram_pool);
+ stram_virt_offset = (unsigned long) ioremap(stram_pool.start,
+ resource_size(&stram_pool)) - stram_pool.start;
+ pr_debug("atari_stram pool: size = %lu bytes, resource = %pR\n",
+ pool_size, &stram_pool);
+ pr_debug("atari_stram pool: stram_virt_offset = %lx\n",
+ stram_virt_offset);
}
- return( addr );
+ return 0;
}
-EXPORT_SYMBOL(atari_stram_alloc);
+arch_initcall(atari_stram_map_pages);
-void atari_stram_free( void *addr )
+void *atari_stram_to_virt(unsigned long phys)
{
- BLOCK *block;
-
- DPRINTK( "atari_stram_free(addr=%p)\n", addr );
-
- if (!(block = find_region( addr ))) {
- printk( KERN_ERR "Attempt to free non-allocated ST-RAM block at %p "
- "from %p\n", addr, __builtin_return_address(0) );
- return;
- }
- DPRINTK( "atari_stram_free: found block (%p): size=%08lx, owner=%s, "
- "flags=%02x\n", block, block->size, block->owner, block->flags );
-
- if (!(block->flags & BLOCK_GFP))
- goto fail;
-
- DPRINTK("atari_stram_free: is kmalloced, order_size=%d\n",
- get_order(block->size));
- free_pages((unsigned long)addr, get_order(block->size));
- remove_region( block );
- return;
-
- fail:
- printk( KERN_ERR "atari_stram_free: cannot free block at %p "
- "(called from %p)\n", addr, __builtin_return_address(0) );
+ return (void *)(phys + stram_virt_offset);
}
-EXPORT_SYMBOL(atari_stram_free);
-
-
-/* ------------------------------------------------------------------------ */
-/* Region Management */
-/* ------------------------------------------------------------------------ */
+EXPORT_SYMBOL(atari_stram_to_virt);
-/* insert a region into the alloced list (sorted) */
-static BLOCK *add_region( void *addr, unsigned long size )
+unsigned long atari_stram_to_phys(void *virt)
{
- BLOCK **p, *n = NULL;
- int i;
-
- for( i = 0; i < N_STATIC_BLOCKS; ++i ) {
- if (static_blocks[i].flags & BLOCK_FREE) {
- n = &static_blocks[i];
- n->flags = 0;
- break;
- }
- }
- if (!n && mem_init_done) {
- /* if statics block pool exhausted and we can call kmalloc() already
- * (after mem_init()), try that */
- n = kmalloc( sizeof(BLOCK), GFP_KERNEL );
- if (n)
- n->flags = BLOCK_KMALLOCED;
- }
- if (!n) {
- printk( KERN_ERR "Out of memory for ST-RAM descriptor blocks\n" );
- return( NULL );
- }
- n->start = addr;
- n->size = size;
-
- for( p = &alloc_list; *p; p = &((*p)->next) )
- if ((*p)->start > addr) break;
- n->next = *p;
- *p = n;
-
- return( n );
+ return (unsigned long)(virt - stram_virt_offset);
}
+EXPORT_SYMBOL(atari_stram_to_phys);
-/* find a region (by start addr) in the alloced list */
-static BLOCK *find_region( void *addr )
+void *atari_stram_alloc(unsigned long size, const char *owner)
{
- BLOCK *p;
-
- for( p = alloc_list; p; p = p->next ) {
- if (p->start == addr)
- return( p );
- if (p->start > addr)
- break;
+ struct resource *res;
+ int error;
+
+ pr_debug("atari_stram_alloc: allocate %lu bytes\n", size);
+
+ /* round up */
+ size = PAGE_ALIGN(size);
+
+ res = kzalloc(sizeof(struct resource), GFP_KERNEL);
+ if (!res)
+ return NULL;
+
+ res->name = owner;
+ error = allocate_resource(&stram_pool, res, size, 0, UINT_MAX,
+ PAGE_SIZE, NULL, NULL);
+ if (error < 0) {
+ pr_err("atari_stram_alloc: allocate_resource() failed %d!\n",
+ error);
+ kfree(res);
+ return NULL;
}
- return( NULL );
-}
-
-/* remove a block from the alloced list */
-static int remove_region( BLOCK *block )
-{
- BLOCK **p;
-
- for( p = &alloc_list; *p; p = &((*p)->next) )
- if (*p == block) break;
- if (!*p)
- return( 0 );
-
- *p = block->next;
- if (block->flags & BLOCK_KMALLOCED)
- kfree( block );
- else
- block->flags |= BLOCK_FREE;
- return( 1 );
+ pr_debug("atari_stram_alloc: returning %pR\n", res);
+ return atari_stram_to_virt(res->start);
}
+EXPORT_SYMBOL(atari_stram_alloc);
-
-/* ------------------------------------------------------------------------ */
-/* /proc statistics file stuff */
-/* ------------------------------------------------------------------------ */
-
-#ifdef DO_PROC
-
-#define PRINT_PROC(fmt,args...) seq_printf( m, fmt, ##args )
-
-static int stram_proc_show(struct seq_file *m, void *v)
-{
- BLOCK *p;
-
- PRINT_PROC("Total ST-RAM: %8u kB\n",
- (stram_end - stram_start) >> 10);
- PRINT_PROC( "Allocated regions:\n" );
- for( p = alloc_list; p; p = p->next ) {
- PRINT_PROC("0x%08lx-0x%08lx: %s (",
- virt_to_phys(p->start),
- virt_to_phys(p->start+p->size-1),
- p->owner);
- if (p->flags & BLOCK_GFP)
- PRINT_PROC( "page-alloced)\n" );
- else
- PRINT_PROC( "??)\n" );
- }
-
- return 0;
-}
-
-static int stram_proc_open(struct inode *inode, struct file *file)
+void atari_stram_free(void *addr)
{
- return single_open(file, stram_proc_show, NULL);
-}
+ unsigned long start = atari_stram_to_phys(addr);
+ struct resource *res;
+ unsigned long size;
-static const struct file_operations stram_proc_fops = {
- .open = stram_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
+ res = lookup_resource(&stram_pool, start);
+ if (!res) {
+ pr_err("atari_stram_free: trying to free nonexistent region "
+ "at %p\n", addr);
+ return;
+ }
-static int __init proc_stram_init(void)
-{
- proc_create("stram", 0, NULL, &stram_proc_fops);
- return 0;
+ size = resource_size(res);
+ pr_debug("atari_stram_free: free %lu bytes at %p\n", size, addr);
+ release_resource(res);
+ kfree(res);
}
-module_init(proc_stram_init);
-#endif
-
-
-/*
- * Local variables:
- * c-indent-level: 4
- * tab-width: 4
- * End:
- */
+EXPORT_SYMBOL(atari_stram_free);
diff --git a/arch/m68k/atari/time.c b/arch/m68k/atari/time.c
index a0531f34c61..da8f981c36d 100644
--- a/arch/m68k/atari/time.c
+++ b/arch/m68k/atari/time.c
@@ -17,6 +17,7 @@
#include <linux/rtc.h>
#include <linux/bcd.h>
#include <linux/delay.h>
+#include <linux/export.h>
#include <asm/atariints.h>
@@ -41,9 +42,9 @@ atari_sched_init(irq_handler_t timer_routine)
#define TICK_SIZE 10000
/* This is always executed with interrupts disabled. */
-unsigned long atari_gettimeoffset (void)
+u32 atari_gettimeoffset(void)
{
- unsigned long ticks, offset = 0;
+ u32 ticks, offset = 0;
/* read MFP timer C current value */
ticks = st_mfp.tim_dt_c;
@@ -56,7 +57,7 @@ unsigned long atari_gettimeoffset (void)
ticks = INT_TICKS - ticks;
ticks = ticks * 10000L / INT_TICKS;
- return ticks + offset;
+ return (ticks + offset) * 1000;
}