source: trunk/target/linux/ar71xx/patches-3.3/113-MIPS-ath79-add-PCI-IRQ-handling-code-for-AR724X-SoCs.patch @ 30410

Last change on this file since 30410 was 30410, checked in by juhosg, 4 years ago

ar71xx: add preliminary support for 3.3

File size: 5.5 KB
  • arch/mips/ath79/pci.c

    From a4fbc2dec67a5d760e25e3c3a6c392191a5405c6 Mon Sep 17 00:00:00 2001
    From: Gabor Juhos <juhosg@openwrt.org>
    Date: Tue, 22 Nov 2011 14:11:19 +0100
    Subject: [PATCH 13/35] MIPS: ath79: add PCI IRQ handling code for AR724X SoCs
    
    The PCI Host Controller of the AR724x SoC has a
    built-in IRQ controller. The current code does
    not supports that, so the IRQ lines wired to this
    controller are not usable. This leads to failed
    'request_irq' calls:
    
      ath9k 0000:00:00.0: request_irq failed
      ath9k: probe of 0000:00:00.0 failed with error -89
    
    This patch adds support for the IRQ controller
    in order to make PCI IRQs work.
    
    Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
    
    v2: - move the interrupt controller related defines from
          the workaround patch
    ---
     arch/mips/ath79/pci.c                  |    3 +-
     arch/mips/include/asm/mach-ath79/pci.h |    4 +-
     arch/mips/pci/pci-ar724x.c             |  118 +++++++++++++++++++++++++++++++-
     3 files changed, 120 insertions(+), 5 deletions(-)
    
    a b  
    1010 
    1111#include <linux/pci.h> 
    1212#include <asm/mach-ath79/ath79.h> 
     13#include <asm/mach-ath79/irq.h> 
    1314#include <asm/mach-ath79/pci.h> 
    1415#include "pci.h" 
    1516 
    int pcibios_plat_dev_init(struct pci_dev 
    5051int __init ath79_register_pci(void) 
    5152{ 
    5253        if (soc_is_ar724x()) 
    53                 return ar724x_pcibios_init(); 
     54                return ar724x_pcibios_init(ATH79_CPU_IRQ_IP2); 
    5455 
    5556        return -ENODEV; 
    5657} 
  • arch/mips/include/asm/mach-ath79/pci.h

    a b  
    1212#define __ASM_MACH_ATH79_PCI_H 
    1313 
    1414#if defined(CONFIG_PCI) && defined(CONFIG_SOC_AR724X) 
    15 int ar724x_pcibios_init(void); 
     15int ar724x_pcibios_init(int irq); 
    1616#else 
    17 static inline int ar724x_pcibios_init(void) { return 0 }; 
     17static inline int ar724x_pcibios_init(int irq) { return 0 }; 
    1818#endif 
    1919 
    2020#endif /* __ASM_MACH_ATH79_PCI_H */ 
  • arch/mips/pci/pci-ar724x.c

    a b  
    88 *  by the Free Software Foundation. 
    99 */ 
    1010 
     11#include <linux/irq.h> 
    1112#include <linux/pci.h> 
    1213#include <asm/mach-ath79/ath79.h> 
     14#include <asm/mach-ath79/ar71xx_regs.h> 
    1315#include <asm/mach-ath79/pci.h> 
    1416 
    1517#define AR724X_PCI_CFG_BASE     0x14000000 
    1618#define AR724X_PCI_CFG_SIZE     0x1000 
     19#define AR724X_PCI_CTRL_BASE    (AR71XX_APB_BASE + 0x000f0000) 
     20#define AR724X_PCI_CTRL_SIZE    0x100 
     21 
    1722#define AR724X_PCI_MEM_BASE     0x10000000 
    1823#define AR724X_PCI_MEM_SIZE     0x08000000 
    1924 
     25#define AR724X_PCI_REG_INT_STATUS       0x4c 
     26#define AR724X_PCI_REG_INT_MASK         0x50 
     27 
     28#define AR724X_PCI_INT_DEV0             BIT(14) 
     29 
     30#define AR724X_PCI_IRQ_COUNT            1 
     31 
    2032#define AR7240_BAR0_WAR_VALUE   0xffff 
    2133 
    2234static DEFINE_SPINLOCK(ar724x_pci_lock); 
    2335static void __iomem *ar724x_pci_devcfg_base; 
     36static void __iomem *ar724x_pci_ctrl_base; 
    2437 
    2538static u32 ar724x_pci_bar0_value; 
    2639static bool ar724x_pci_bar0_is_cached; 
    static struct pci_controller ar724x_pci_ 
    164177        .mem_resource   = &ar724x_mem_resource, 
    165178}; 
    166179 
    167 int __init ar724x_pcibios_init(void) 
     180static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc) 
     181{ 
     182        void __iomem *base; 
     183        u32 pending; 
     184 
     185        base = ar724x_pci_ctrl_base; 
     186 
     187        pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) & 
     188                  __raw_readl(base + AR724X_PCI_REG_INT_MASK); 
     189 
     190        if (pending & AR724X_PCI_INT_DEV0) 
     191                generic_handle_irq(ATH79_PCI_IRQ(0)); 
     192 
     193        else 
     194                spurious_interrupt(); 
     195} 
     196 
     197static void ar724x_pci_irq_unmask(struct irq_data *d) 
     198{ 
     199        void __iomem *base; 
     200        u32 t; 
     201 
     202        base = ar724x_pci_ctrl_base; 
     203 
     204        switch (d->irq) { 
     205        case ATH79_PCI_IRQ(0): 
     206                t = __raw_readl(base + AR724X_PCI_REG_INT_MASK); 
     207                __raw_writel(t | AR724X_PCI_INT_DEV0, 
     208                             base + AR724X_PCI_REG_INT_MASK); 
     209                /* flush write */ 
     210                __raw_readl(base + AR724X_PCI_REG_INT_MASK); 
     211        } 
     212} 
     213 
     214static void ar724x_pci_irq_mask(struct irq_data *d) 
     215{ 
     216        void __iomem *base; 
     217        u32 t; 
     218 
     219        base = ar724x_pci_ctrl_base; 
     220 
     221        switch (d->irq) { 
     222        case ATH79_PCI_IRQ(0): 
     223                t = __raw_readl(base + AR724X_PCI_REG_INT_MASK); 
     224                __raw_writel(t & ~AR724X_PCI_INT_DEV0, 
     225                             base + AR724X_PCI_REG_INT_MASK); 
     226 
     227                /* flush write */ 
     228                __raw_readl(base + AR724X_PCI_REG_INT_MASK); 
     229 
     230                t = __raw_readl(base + AR724X_PCI_REG_INT_STATUS); 
     231                __raw_writel(t | AR724X_PCI_INT_DEV0, 
     232                             base + AR724X_PCI_REG_INT_STATUS); 
     233 
     234                /* flush write */ 
     235                __raw_readl(base + AR724X_PCI_REG_INT_STATUS); 
     236        } 
     237} 
     238 
     239static struct irq_chip ar724x_pci_irq_chip = { 
     240        .name           = "AR724X PCI ", 
     241        .irq_mask       = ar724x_pci_irq_mask, 
     242        .irq_unmask     = ar724x_pci_irq_unmask, 
     243        .irq_mask_ack   = ar724x_pci_irq_mask, 
     244}; 
     245 
     246static void __init ar724x_pci_irq_init(int irq) 
     247{ 
     248        void __iomem *base; 
     249        int i; 
     250 
     251        base = ar724x_pci_ctrl_base; 
     252 
     253        __raw_writel(0, base + AR724X_PCI_REG_INT_MASK); 
     254        __raw_writel(0, base + AR724X_PCI_REG_INT_STATUS); 
     255 
     256        BUILD_BUG_ON(ATH79_PCI_IRQ_COUNT < AR724X_PCI_IRQ_COUNT); 
     257 
     258        for (i = ATH79_PCI_IRQ_BASE; 
     259             i < ATH79_PCI_IRQ_BASE + AR724X_PCI_IRQ_COUNT; i++) 
     260                irq_set_chip_and_handler(i, &ar724x_pci_irq_chip, 
     261                                         handle_level_irq); 
     262 
     263        irq_set_chained_handler(irq, ar724x_pci_irq_handler); 
     264} 
     265 
     266int __init ar724x_pcibios_init(int irq) 
    168267{ 
     268        int ret; 
     269 
     270        ret = -ENOMEM; 
     271 
    169272        ar724x_pci_devcfg_base = ioremap(AR724X_PCI_CFG_BASE, 
    170273                                         AR724X_PCI_CFG_SIZE); 
    171274        if (ar724x_pci_devcfg_base == NULL) 
    172                 return -ENOMEM; 
     275                goto err; 
    173276 
     277        ar724x_pci_ctrl_base = ioremap(AR724X_PCI_CTRL_BASE, 
     278                                       AR724X_PCI_CTRL_SIZE); 
     279        if (ar724x_pci_ctrl_base == NULL) 
     280                goto err_unmap_devcfg; 
     281 
     282        ar724x_pci_irq_init(irq); 
    174283        register_pci_controller(&ar724x_pci_controller); 
    175284 
    176285        return PCIBIOS_SUCCESSFUL; 
     286 
     287err_unmap_devcfg: 
     288        iounmap(ar724x_pci_devcfg_base); 
     289err: 
     290        return ret; 
    177291} 
Note: See TracBrowser for help on using the repository browser.