|
@@ -257,3 +257,185 @@ static void
|
|
|
s3c_irq_uart0_mask(struct irq_data *data)
|
|
|
{
|
|
|
s3c_irqsub_mask(data->irq, INTMSK_UART0, 7);
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+s3c_irq_uart0_unmask(struct irq_data *data)
|
|
|
+{
|
|
|
+ s3c_irqsub_unmask(data->irq, INTMSK_UART0);
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+s3c_irq_uart0_ack(struct irq_data *data)
|
|
|
+{
|
|
|
+ s3c_irqsub_maskack(data->irq, INTMSK_UART0, 7);
|
|
|
+}
|
|
|
+
|
|
|
+static struct irq_chip s3c_irq_uart0 = {
|
|
|
+ .name = "s3c-uart0",
|
|
|
+ .irq_mask = s3c_irq_uart0_mask,
|
|
|
+ .irq_unmask = s3c_irq_uart0_unmask,
|
|
|
+ .irq_ack = s3c_irq_uart0_ack,
|
|
|
+};
|
|
|
+
|
|
|
+/* UART1 */
|
|
|
+
|
|
|
+static void
|
|
|
+s3c_irq_uart1_mask(struct irq_data *data)
|
|
|
+{
|
|
|
+ s3c_irqsub_mask(data->irq, INTMSK_UART1, 7 << 3);
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+s3c_irq_uart1_unmask(struct irq_data *data)
|
|
|
+{
|
|
|
+ s3c_irqsub_unmask(data->irq, INTMSK_UART1);
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+s3c_irq_uart1_ack(struct irq_data *data)
|
|
|
+{
|
|
|
+ s3c_irqsub_maskack(data->irq, INTMSK_UART1, 7 << 3);
|
|
|
+}
|
|
|
+
|
|
|
+static struct irq_chip s3c_irq_uart1 = {
|
|
|
+ .name = "s3c-uart1",
|
|
|
+ .irq_mask = s3c_irq_uart1_mask,
|
|
|
+ .irq_unmask = s3c_irq_uart1_unmask,
|
|
|
+ .irq_ack = s3c_irq_uart1_ack,
|
|
|
+};
|
|
|
+
|
|
|
+/* UART2 */
|
|
|
+
|
|
|
+static void
|
|
|
+s3c_irq_uart2_mask(struct irq_data *data)
|
|
|
+{
|
|
|
+ s3c_irqsub_mask(data->irq, INTMSK_UART2, 7 << 6);
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+s3c_irq_uart2_unmask(struct irq_data *data)
|
|
|
+{
|
|
|
+ s3c_irqsub_unmask(data->irq, INTMSK_UART2);
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+s3c_irq_uart2_ack(struct irq_data *data)
|
|
|
+{
|
|
|
+ s3c_irqsub_maskack(data->irq, INTMSK_UART2, 7 << 6);
|
|
|
+}
|
|
|
+
|
|
|
+static struct irq_chip s3c_irq_uart2 = {
|
|
|
+ .name = "s3c-uart2",
|
|
|
+ .irq_mask = s3c_irq_uart2_mask,
|
|
|
+ .irq_unmask = s3c_irq_uart2_unmask,
|
|
|
+ .irq_ack = s3c_irq_uart2_ack,
|
|
|
+};
|
|
|
+
|
|
|
+/* ADC and Touchscreen */
|
|
|
+
|
|
|
+static void
|
|
|
+s3c_irq_adc_mask(struct irq_data *d)
|
|
|
+{
|
|
|
+ s3c_irqsub_mask(d->irq, INTMSK_ADCPARENT, 3 << 9);
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+s3c_irq_adc_unmask(struct irq_data *d)
|
|
|
+{
|
|
|
+ s3c_irqsub_unmask(d->irq, INTMSK_ADCPARENT);
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+s3c_irq_adc_ack(struct irq_data *d)
|
|
|
+{
|
|
|
+ s3c_irqsub_ack(d->irq, INTMSK_ADCPARENT, 3 << 9);
|
|
|
+}
|
|
|
+
|
|
|
+static struct irq_chip s3c_irq_adc = {
|
|
|
+ .name = "s3c-adc",
|
|
|
+ .irq_mask = s3c_irq_adc_mask,
|
|
|
+ .irq_unmask = s3c_irq_adc_unmask,
|
|
|
+ .irq_ack = s3c_irq_adc_ack,
|
|
|
+};
|
|
|
+
|
|
|
+/* irq demux for adc */
|
|
|
+static void s3c_irq_demux_adc(unsigned int irq,
|
|
|
+ struct irq_desc *desc)
|
|
|
+{
|
|
|
+ unsigned int subsrc, submsk;
|
|
|
+ unsigned int offset = 9;
|
|
|
+
|
|
|
+ /* read the current pending interrupts, and the mask
|
|
|
+ * for what it is available */
|
|
|
+
|
|
|
+ subsrc = __raw_readl(S3C2410_SUBSRCPND);
|
|
|
+ submsk = __raw_readl(S3C2410_INTSUBMSK);
|
|
|
+
|
|
|
+ subsrc &= ~submsk;
|
|
|
+ subsrc >>= offset;
|
|
|
+ subsrc &= 3;
|
|
|
+
|
|
|
+ if (subsrc != 0) {
|
|
|
+ if (subsrc & 1) {
|
|
|
+ generic_handle_irq(IRQ_TC);
|
|
|
+ }
|
|
|
+ if (subsrc & 2) {
|
|
|
+ generic_handle_irq(IRQ_ADC);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void s3c_irq_demux_uart(unsigned int start)
|
|
|
+{
|
|
|
+ unsigned int subsrc, submsk;
|
|
|
+ unsigned int offset = start - IRQ_S3CUART_RX0;
|
|
|
+
|
|
|
+ /* read the current pending interrupts, and the mask
|
|
|
+ * for what it is available */
|
|
|
+
|
|
|
+ subsrc = __raw_readl(S3C2410_SUBSRCPND);
|
|
|
+ submsk = __raw_readl(S3C2410_INTSUBMSK);
|
|
|
+
|
|
|
+ irqdbf2("s3c_irq_demux_uart: start=%d (%d), subsrc=0x%08x,0x%08x\n",
|
|
|
+ start, offset, subsrc, submsk);
|
|
|
+
|
|
|
+ subsrc &= ~submsk;
|
|
|
+ subsrc >>= offset;
|
|
|
+ subsrc &= 7;
|
|
|
+
|
|
|
+ if (subsrc != 0) {
|
|
|
+ if (subsrc & 1)
|
|
|
+ generic_handle_irq(start);
|
|
|
+
|
|
|
+ if (subsrc & 2)
|
|
|
+ generic_handle_irq(start+1);
|
|
|
+
|
|
|
+ if (subsrc & 4)
|
|
|
+ generic_handle_irq(start+2);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* uart demux entry points */
|
|
|
+
|
|
|
+static void
|
|
|
+s3c_irq_demux_uart0(unsigned int irq,
|
|
|
+ struct irq_desc *desc)
|
|
|
+{
|
|
|
+ irq = irq;
|
|
|
+ s3c_irq_demux_uart(IRQ_S3CUART_RX0);
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+s3c_irq_demux_uart1(unsigned int irq,
|
|
|
+ struct irq_desc *desc)
|
|
|
+{
|
|
|
+ irq = irq;
|
|
|
+ s3c_irq_demux_uart(IRQ_S3CUART_RX1);
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+s3c_irq_demux_uart2(unsigned int irq,
|
|
|
+ struct irq_desc *desc)
|
|
|
+{
|
|
|
+ irq = irq;
|