|
@@ -126,7 +126,7 @@ struct sa1111_dev_info {
|
|
unsigned long skpcr_mask;
|
|
unsigned long skpcr_mask;
|
|
bool dma;
|
|
bool dma;
|
|
unsigned int devid;
|
|
unsigned int devid;
|
|
- unsigned int irq[6];
|
|
|
|
|
|
+ unsigned int hwirq[6];
|
|
};
|
|
};
|
|
|
|
|
|
static struct sa1111_dev_info sa1111_devices[] = {
|
|
static struct sa1111_dev_info sa1111_devices[] = {
|
|
@@ -135,7 +135,7 @@ static struct sa1111_dev_info sa1111_devices[] = {
|
|
.skpcr_mask = SKPCR_UCLKEN,
|
|
.skpcr_mask = SKPCR_UCLKEN,
|
|
.dma = true,
|
|
.dma = true,
|
|
.devid = SA1111_DEVID_USB,
|
|
.devid = SA1111_DEVID_USB,
|
|
- .irq = {
|
|
|
|
|
|
+ .hwirq = {
|
|
IRQ_USBPWR,
|
|
IRQ_USBPWR,
|
|
IRQ_HCIM,
|
|
IRQ_HCIM,
|
|
IRQ_HCIBUFFACC,
|
|
IRQ_HCIBUFFACC,
|
|
@@ -149,7 +149,7 @@ static struct sa1111_dev_info sa1111_devices[] = {
|
|
.skpcr_mask = SKPCR_I2SCLKEN | SKPCR_L3CLKEN,
|
|
.skpcr_mask = SKPCR_I2SCLKEN | SKPCR_L3CLKEN,
|
|
.dma = true,
|
|
.dma = true,
|
|
.devid = SA1111_DEVID_SAC,
|
|
.devid = SA1111_DEVID_SAC,
|
|
- .irq = {
|
|
|
|
|
|
+ .hwirq = {
|
|
AUDXMTDMADONEA,
|
|
AUDXMTDMADONEA,
|
|
AUDXMTDMADONEB,
|
|
AUDXMTDMADONEB,
|
|
AUDRCVDMADONEA,
|
|
AUDRCVDMADONEA,
|
|
@@ -165,7 +165,7 @@ static struct sa1111_dev_info sa1111_devices[] = {
|
|
.offset = SA1111_KBD,
|
|
.offset = SA1111_KBD,
|
|
.skpcr_mask = SKPCR_PTCLKEN,
|
|
.skpcr_mask = SKPCR_PTCLKEN,
|
|
.devid = SA1111_DEVID_PS2_KBD,
|
|
.devid = SA1111_DEVID_PS2_KBD,
|
|
- .irq = {
|
|
|
|
|
|
+ .hwirq = {
|
|
IRQ_TPRXINT,
|
|
IRQ_TPRXINT,
|
|
IRQ_TPTXINT
|
|
IRQ_TPTXINT
|
|
},
|
|
},
|
|
@@ -174,7 +174,7 @@ static struct sa1111_dev_info sa1111_devices[] = {
|
|
.offset = SA1111_MSE,
|
|
.offset = SA1111_MSE,
|
|
.skpcr_mask = SKPCR_PMCLKEN,
|
|
.skpcr_mask = SKPCR_PMCLKEN,
|
|
.devid = SA1111_DEVID_PS2_MSE,
|
|
.devid = SA1111_DEVID_PS2_MSE,
|
|
- .irq = {
|
|
|
|
|
|
+ .hwirq = {
|
|
IRQ_MSRXINT,
|
|
IRQ_MSRXINT,
|
|
IRQ_MSTXINT
|
|
IRQ_MSTXINT
|
|
},
|
|
},
|
|
@@ -183,7 +183,7 @@ static struct sa1111_dev_info sa1111_devices[] = {
|
|
.offset = 0x1800,
|
|
.offset = 0x1800,
|
|
.skpcr_mask = 0,
|
|
.skpcr_mask = 0,
|
|
.devid = SA1111_DEVID_PCMCIA,
|
|
.devid = SA1111_DEVID_PCMCIA,
|
|
- .irq = {
|
|
|
|
|
|
+ .hwirq = {
|
|
IRQ_S0_READY_NINT,
|
|
IRQ_S0_READY_NINT,
|
|
IRQ_S0_CD_VALID,
|
|
IRQ_S0_CD_VALID,
|
|
IRQ_S0_BVD1_STSCHG,
|
|
IRQ_S0_BVD1_STSCHG,
|
|
@@ -194,6 +194,11 @@ static struct sa1111_dev_info sa1111_devices[] = {
|
|
},
|
|
},
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+static int sa1111_map_irq(struct sa1111 *sachip, irq_hw_number_t hwirq)
|
|
|
|
+{
|
|
|
|
+ return irq_create_mapping(sachip->irqdomain, hwirq);
|
|
|
|
+}
|
|
|
|
+
|
|
static void sa1111_handle_irqdomain(struct irq_domain *irqdomain, int irq)
|
|
static void sa1111_handle_irqdomain(struct irq_domain *irqdomain, int irq)
|
|
{
|
|
{
|
|
struct irq_desc *d = irq_to_desc(irq_linear_revmap(irqdomain, irq));
|
|
struct irq_desc *d = irq_to_desc(irq_linear_revmap(irqdomain, irq));
|
|
@@ -360,6 +365,10 @@ static int sa1111_irqdomain_map(struct irq_domain *d, unsigned int irq,
|
|
{
|
|
{
|
|
struct sa1111 *sachip = d->host_data;
|
|
struct sa1111 *sachip = d->host_data;
|
|
|
|
|
|
|
|
+ /* Disallow unavailable interrupts */
|
|
|
|
+ if (hwirq > SSPROR && hwirq < AUDXMTDMADONEA)
|
|
|
|
+ return -EINVAL;
|
|
|
|
+
|
|
irq_set_chip_data(irq, sachip);
|
|
irq_set_chip_data(irq, sachip);
|
|
irq_set_chip_and_handler(irq, &sa1111_irq_chip, handle_edge_irq);
|
|
irq_set_chip_and_handler(irq, &sa1111_irq_chip, handle_edge_irq);
|
|
irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE);
|
|
irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE);
|
|
@@ -443,7 +452,9 @@ static int sa1111_setup_irq(struct sa1111 *sachip, unsigned irq_base)
|
|
|
|
|
|
static void sa1111_remove_irq(struct sa1111 *sachip)
|
|
static void sa1111_remove_irq(struct sa1111 *sachip)
|
|
{
|
|
{
|
|
|
|
+ struct irq_domain *domain = sachip->irqdomain;
|
|
void __iomem *irqbase = sachip->base + SA1111_INTC;
|
|
void __iomem *irqbase = sachip->base + SA1111_INTC;
|
|
|
|
+ int i;
|
|
|
|
|
|
/* disable all IRQs */
|
|
/* disable all IRQs */
|
|
writel_relaxed(0, irqbase + SA1111_INTEN0);
|
|
writel_relaxed(0, irqbase + SA1111_INTEN0);
|
|
@@ -451,10 +462,10 @@ static void sa1111_remove_irq(struct sa1111 *sachip)
|
|
writel_relaxed(0, irqbase + SA1111_WAKEEN0);
|
|
writel_relaxed(0, irqbase + SA1111_WAKEEN0);
|
|
writel_relaxed(0, irqbase + SA1111_WAKEEN1);
|
|
writel_relaxed(0, irqbase + SA1111_WAKEEN1);
|
|
|
|
|
|
- irq_domain_remove(sachip->irqdomain);
|
|
|
|
-
|
|
|
|
irq_set_chained_handler_and_data(sachip->irq, NULL, NULL);
|
|
irq_set_chained_handler_and_data(sachip->irq, NULL, NULL);
|
|
- irq_free_descs(sachip->irq_base, SA1111_IRQ_NR);
|
|
|
|
|
|
+ for (i = 0; i < SA1111_IRQ_NR; i++)
|
|
|
|
+ irq_dispose_mapping(irq_find_mapping(domain, i));
|
|
|
|
+ irq_domain_remove(domain);
|
|
|
|
|
|
release_mem_region(sachip->phys + SA1111_INTC, 512);
|
|
release_mem_region(sachip->phys + SA1111_INTC, 512);
|
|
}
|
|
}
|
|
@@ -595,7 +606,7 @@ static int sa1111_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
|
|
{
|
|
{
|
|
struct sa1111 *sachip = gc_to_sa1111(gc);
|
|
struct sa1111 *sachip = gc_to_sa1111(gc);
|
|
|
|
|
|
- return sachip->irq_base + offset;
|
|
|
|
|
|
+ return sa1111_map_irq(sachip, offset);
|
|
}
|
|
}
|
|
|
|
|
|
static int sa1111_setup_gpios(struct sa1111 *sachip)
|
|
static int sa1111_setup_gpios(struct sa1111 *sachip)
|
|
@@ -746,8 +757,8 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent,
|
|
dev->mapbase = sachip->base + info->offset;
|
|
dev->mapbase = sachip->base + info->offset;
|
|
dev->skpcr_mask = info->skpcr_mask;
|
|
dev->skpcr_mask = info->skpcr_mask;
|
|
|
|
|
|
- for (i = 0; i < ARRAY_SIZE(info->irq); i++)
|
|
|
|
- dev->irq[i] = sachip->irq_base + info->irq[i];
|
|
|
|
|
|
+ for (i = 0; i < ARRAY_SIZE(info->hwirq); i++)
|
|
|
|
+ dev->hwirq[i] = info->hwirq[i];
|
|
|
|
|
|
/*
|
|
/*
|
|
* If the parent device has a DMA mask associated with it, and
|
|
* If the parent device has a DMA mask associated with it, and
|
|
@@ -1380,9 +1391,10 @@ EXPORT_SYMBOL(sa1111_disable_device);
|
|
|
|
|
|
int sa1111_get_irq(struct sa1111_dev *sadev, unsigned num)
|
|
int sa1111_get_irq(struct sa1111_dev *sadev, unsigned num)
|
|
{
|
|
{
|
|
- if (num >= ARRAY_SIZE(sadev->irq))
|
|
|
|
|
|
+ struct sa1111 *sachip = sa1111_chip_driver(sadev);
|
|
|
|
+ if (num >= ARRAY_SIZE(sadev->hwirq))
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
- return sadev->irq[num];
|
|
|
|
|
|
+ return sa1111_map_irq(sachip, sadev->hwirq[num]);
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(sa1111_get_irq);
|
|
EXPORT_SYMBOL_GPL(sa1111_get_irq);
|
|
|
|
|