Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 309043
b: refs/heads/master
c: 4c07c7d
h: refs/heads/master
i:
  309041: e07f7c9
  309039: 73820ba
v: v3
  • Loading branch information
Gabor Juhos authored and Ralf Baechle committed May 15, 2012
1 parent 11c250f commit 2757c46
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 6 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 93ef85b5598ad2cc23f38d97ed565027b969c0aa
refs/heads/master: 4c07c7dfa0f3575dc3276c544349fbf181381167
3 changes: 2 additions & 1 deletion trunk/arch/mips/ath79/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include <linux/pci.h>
#include <asm/mach-ath79/ath79.h>
#include <asm/mach-ath79/irq.h>
#include <asm/mach-ath79/pci.h>
#include "pci.h"

Expand Down Expand Up @@ -50,7 +51,7 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
int __init ath79_register_pci(void)
{
if (soc_is_ar724x())
return ar724x_pcibios_init();
return ar724x_pcibios_init(ATH79_CPU_IRQ_IP2);

return -ENODEV;
}
4 changes: 2 additions & 2 deletions trunk/arch/mips/include/asm/mach-ath79/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
#define __ASM_MACH_ATH79_PCI_H

#if defined(CONFIG_PCI) && defined(CONFIG_SOC_AR724X)
int ar724x_pcibios_init(void);
int ar724x_pcibios_init(int irq);
#else
static inline int ar724x_pcibios_init(void) { return 0; }
static inline int ar724x_pcibios_init(int irq) { return 0; }
#endif

#endif /* __ASM_MACH_ATH79_PCI_H */
118 changes: 116 additions & 2 deletions trunk/arch/mips/pci/pci-ar724x.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,32 @@
* by the Free Software Foundation.
*/

#include <linux/irq.h>
#include <linux/pci.h>
#include <asm/mach-ath79/ath79.h>
#include <asm/mach-ath79/ar71xx_regs.h>
#include <asm/mach-ath79/pci.h>

#define AR724X_PCI_CFG_BASE 0x14000000
#define AR724X_PCI_CFG_SIZE 0x1000
#define AR724X_PCI_CTRL_BASE (AR71XX_APB_BASE + 0x000f0000)
#define AR724X_PCI_CTRL_SIZE 0x100

#define AR724X_PCI_MEM_BASE 0x10000000
#define AR724X_PCI_MEM_SIZE 0x08000000

#define AR724X_PCI_REG_INT_STATUS 0x4c
#define AR724X_PCI_REG_INT_MASK 0x50

#define AR724X_PCI_INT_DEV0 BIT(14)

#define AR724X_PCI_IRQ_COUNT 1

#define AR7240_BAR0_WAR_VALUE 0xffff

static DEFINE_SPINLOCK(ar724x_pci_lock);
static void __iomem *ar724x_pci_devcfg_base;
static void __iomem *ar724x_pci_ctrl_base;

static u32 ar724x_pci_bar0_value;
static bool ar724x_pci_bar0_is_cached;
Expand Down Expand Up @@ -164,14 +177,115 @@ static struct pci_controller ar724x_pci_controller = {
.mem_resource = &ar724x_mem_resource,
};

int __init ar724x_pcibios_init(void)
static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
{
void __iomem *base;
u32 pending;

base = ar724x_pci_ctrl_base;

pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) &
__raw_readl(base + AR724X_PCI_REG_INT_MASK);

if (pending & AR724X_PCI_INT_DEV0)
generic_handle_irq(ATH79_PCI_IRQ(0));

else
spurious_interrupt();
}

static void ar724x_pci_irq_unmask(struct irq_data *d)
{
void __iomem *base;
u32 t;

base = ar724x_pci_ctrl_base;

switch (d->irq) {
case ATH79_PCI_IRQ(0):
t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
__raw_writel(t | AR724X_PCI_INT_DEV0,
base + AR724X_PCI_REG_INT_MASK);
/* flush write */
__raw_readl(base + AR724X_PCI_REG_INT_MASK);
}
}

static void ar724x_pci_irq_mask(struct irq_data *d)
{
void __iomem *base;
u32 t;

base = ar724x_pci_ctrl_base;

switch (d->irq) {
case ATH79_PCI_IRQ(0):
t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
__raw_writel(t & ~AR724X_PCI_INT_DEV0,
base + AR724X_PCI_REG_INT_MASK);

/* flush write */
__raw_readl(base + AR724X_PCI_REG_INT_MASK);

t = __raw_readl(base + AR724X_PCI_REG_INT_STATUS);
__raw_writel(t | AR724X_PCI_INT_DEV0,
base + AR724X_PCI_REG_INT_STATUS);

/* flush write */
__raw_readl(base + AR724X_PCI_REG_INT_STATUS);
}
}

static struct irq_chip ar724x_pci_irq_chip = {
.name = "AR724X PCI ",
.irq_mask = ar724x_pci_irq_mask,
.irq_unmask = ar724x_pci_irq_unmask,
.irq_mask_ack = ar724x_pci_irq_mask,
};

static void __init ar724x_pci_irq_init(int irq)
{
void __iomem *base;
int i;

base = ar724x_pci_ctrl_base;

__raw_writel(0, base + AR724X_PCI_REG_INT_MASK);
__raw_writel(0, base + AR724X_PCI_REG_INT_STATUS);

BUILD_BUG_ON(ATH79_PCI_IRQ_COUNT < AR724X_PCI_IRQ_COUNT);

for (i = ATH79_PCI_IRQ_BASE;
i < ATH79_PCI_IRQ_BASE + AR724X_PCI_IRQ_COUNT; i++)
irq_set_chip_and_handler(i, &ar724x_pci_irq_chip,
handle_level_irq);

irq_set_chained_handler(irq, ar724x_pci_irq_handler);
}

int __init ar724x_pcibios_init(int irq)
{
int ret;

ret = -ENOMEM;

ar724x_pci_devcfg_base = ioremap(AR724X_PCI_CFG_BASE,
AR724X_PCI_CFG_SIZE);
if (ar724x_pci_devcfg_base == NULL)
return -ENOMEM;
goto err;

ar724x_pci_ctrl_base = ioremap(AR724X_PCI_CTRL_BASE,
AR724X_PCI_CTRL_SIZE);
if (ar724x_pci_ctrl_base == NULL)
goto err_unmap_devcfg;

ar724x_pci_irq_init(irq);
register_pci_controller(&ar724x_pci_controller);

return PCIBIOS_SUCCESSFUL;

err_unmap_devcfg:
iounmap(ar724x_pci_devcfg_base);
err:
return ret;
}

0 comments on commit 2757c46

Please sign in to comment.