00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <agnix/agnix.h>
00015 #include <agnix/adi/adi.h>
00016 #include <agnix/spinlock.h>
00017 #include <asm/types.h>
00018 #include <agnix/ioport.h>
00019 #include <agnix/memory.h>
00020 #include <agnix/irq.h>
00021 #include <agnix/console.h>
00022
00023 #define I8259A_CASCADE_IRQ 2
00024
00025 struct chip_pic_parm_s i8259a_pic_parm;
00026
00027 int i8259a_startup_irq(struct chip_s *chip, u8 irq)
00028 {
00029 return 0;
00030 }
00031
00032 int i8259a_shutdown_irq(struct chip_s *chip, u8 irq)
00033 {
00034 return 0;
00035 }
00036
00037 int i8259a_enable_irq(struct chip_s *chip, u8 irq)
00038 {
00039 CHIP_LOCK;
00040
00041 pic_parm(chip)->irq_mask[0] &= ~(1 << irq);
00042 outb((pic_parm(chip)->irq_mask[0]) & 0xFF, INT_CNTRL_1 + 1);
00043 outb((pic_parm(chip)->irq_mask[0] >> 8) & 0xFF, INT_CNTRL_2 + 1);
00044
00045 CHIP_UNLOCK;
00046
00047 return 0;
00048 }
00049
00050 int i8259a_disable_irq(struct chip_s *chip, u8 irq)
00051 {
00052 CHIP_LOCK;
00053
00054 pic_parm(chip)->irq_mask[0] |= 1 << irq;
00055 outb((pic_parm(chip)->irq_mask[0]) & 0xFF, INT_CNTRL_1 + 1);
00056 outb((pic_parm(chip)->irq_mask[0] >> 8) & 0xFF, INT_CNTRL_2 + 1);
00057
00058 CHIP_UNLOCK;
00059
00060
00061 return 0;
00062 }
00063
00064 void i8259a_ack_irq(struct chip_s *chip, u8 irq)
00065 {
00066 CHIP_LOCK;
00067
00068 if (irq <= 7)
00069 outb(0x60 + (irq & 0x07), INT_CNTRL_1);
00070 else
00071 if (irq <= 15) {
00072 outb(0x60 + (irq & 0x07), INT_CNTRL_2);
00073 outb(0x60 + I8259A_CASCADE_IRQ, INT_CNTRL_1);
00074 }
00075
00076 CHIP_UNLOCK;
00077 }
00078
00079 void i8259a_mask_irq(struct chip_s *chip, u8 irq)
00080 {
00081 CHIP_LOCK;
00082 CHIP_UNLOCK;
00083 }
00084
00085 struct chip_pic_ops_s i8259a_pic_ops =
00086 {
00087 .startup_irq = i8259a_startup_irq,
00088 .shutdown_irq = i8259a_shutdown_irq,
00089 .enable_irq = i8259a_enable_irq,
00090 .disable_irq = i8259a_disable_irq,
00091 .ack_irq = i8259a_ack_irq,
00092 .mask_irq = i8259a_mask_irq
00093 };
00094
00095 void i8259a_cascade_irq(u32 data)
00096 {
00097 printk("cascade irq\n");
00098 }
00099
00100 struct irq_routine_s i8259a_cascade_irq_routine = {
00101 .proc = i8259a_cascade_irq,
00102 };
00103
00104 int i8259a_chip_cascade_init(struct chip_s *chip)
00105 {
00106 install_irq(I8259A_CASCADE_IRQ, &i8259a_cascade_irq_routine);
00107
00108 return 0;
00109 }
00110
00111 int i8259a_chip_init(struct chip_s *chip)
00112 {
00113 CHIP_LOCK;
00114
00115 memset(pic_parm(chip)->irq_mask, 0xFF, PIC_MASK_BYTES);
00116
00117 outb(0x11, INT_CNTRL_1);
00118 outb(0x20, INT_CNTRL_1 + 1);
00119 outb(0x04, INT_CNTRL_1 + 1);
00120 outb(0x01, INT_CNTRL_1 + 1);
00121
00122 outb(0x11, INT_CNTRL_2);
00123 outb(0x28, INT_CNTRL_2 + 1);
00124 outb(0x02, INT_CNTRL_2 + 1);
00125 outb(0x01, INT_CNTRL_2 + 1);
00126
00127 outb((u8)((pic_parm(chip)->irq_mask[0]) & 0xFF), INT_CNTRL_1 + 1);
00128 outb((u8)((pic_parm(chip)->irq_mask[0] >> 8) & 0xFF), INT_CNTRL_2 + 1);
00129
00130 CHIP_UNLOCK;
00131
00132 i8259a_chip_cascade_init(chip);
00133
00134 return 0;
00135 }
00136
00137 int i8259a_chip_release(struct chip_s *chip)
00138 {
00139 return 0;
00140 }
00141
00142 struct chip_ops_s i8259a_chip_ops = {
00143 .init = i8259a_chip_init,
00144 .release = i8259a_chip_release
00145 };
00146
00147 struct chip_s i8259a_chip = {
00148 .chip_name = "i8259a",
00149 .chip_class = CHIP_CLASS_PIC,
00150 .chip_vendor = 0x8086,
00151 .chip_priority = 90,
00152 .chip_ops = &i8259a_chip_ops,
00153 .chip_pm_ops = NULL,
00154 .internal_ops = &i8259a_pic_ops,
00155 .internal_parm = &i8259a_pic_parm
00156 };
00157
00158 int __init i8259a_init(void)
00159 {
00160 adi_register_chip(&i8259a_chip);
00161
00162 return 0;
00163 }