Changeset 42502


Ignore:
Timestamp:
2014-09-12T08:53:09+02:00 (3 years ago)
Author:
blogic
Message:

atheros: ar2315-pci: rework the configuration access code

Use raw_{read,write}l accessors and use Abort interrupt to detect a
configuration space read/write errors. The second change improves errors
detection, what improves the device presence detection and helps us to
avoid following (and similar) errors:

pci 0000:00:00.2: ignoring class 0x7e0200 (doesn't match header type 02)
pci 0000:00:00.2: bridge configuration invalid ([bus 03-90]), reconfiguring
pci 0000:00:00.2: not setting up bridge for bus 0000:01

Signed-off-by: Sergey Ryazanov <ryazanov.s.a@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/target/linux/atheros/patches-3.14/105-ar2315_pci.patch

    r42501 r42502  
    88--- /dev/null 
    99+++ b/arch/mips/ar231x/pci.c 
    10 @@ -0,0 +1,336 @@ 
     10@@ -0,0 +1,350 @@ 
    1111+/* 
    1212+ * This program is free software; you can redistribute it and/or 
     
    6666+#define AR2315_IO_SIZE     0x00007fffUL 
    6767+ 
     68+/* Arbitrary size of memory region to access the configuration space */ 
     69+#define AR2315_PCI_CFG_SIZE    0x00100000 
     70+ 
    6871+#define AR2315_PCI_HOST_SLOT   3 
    6972+#define AR2315_PCI_HOST_DEVID  ((0xff18 << 16) | PCI_VENDOR_ID_ATHEROS) 
    7073+ 
    71 +static unsigned long configspace; 
     74+static void __iomem *ar2315_pci_cfg_mem; 
    7275+ 
    7376+static int ar2315_pci_cfg_access(int devfn, int where, int size, u32 *ptr, 
     
    7679+       int func = PCI_FUNC(devfn); 
    7780+       int dev = PCI_SLOT(devfn); 
    78 +       u32 value = 0; 
    79 +       int err = 0; 
    80 +       u32 addr; 
    81 + 
     81+       u32 addr = (1 << (13 + dev)) | (func << 8) | (where & ~3); 
     82+       u32 mask = 0xffffffff >> 8 * (4 - size); 
     83+       u32 sh = (where & 3) * 8; 
     84+       u32 value, isr; 
     85+ 
     86+       /* Prevent access past the remapped area */ 
     87+       if (addr >= AR2315_PCI_CFG_SIZE || dev > 18) 
     88+               return PCIBIOS_DEVICE_NOT_FOUND; 
     89+ 
     90+       /* Clear pending errors */ 
     91+       ar231x_write_reg(AR2315_PCI_ISR, AR2315_PCI_INT_ABORT); 
    8292+       /* Select Configuration access */ 
    8393+       ar231x_mask_reg(AR2315_PCI_MISC_CONFIG, 0, AR2315_PCIMISC_CFG_SEL); 
    84 +       mb(); 
    85 + 
    86 +       addr = (u32)configspace + (1 << (13 + dev)) + (func << 8) + where; 
    87 +       if (size == 1) 
    88 +               addr ^= 0x3; 
    89 +       else if (size == 2) 
    90 +               addr ^= 0x2; 
     94+ 
     95+       mb();   /* PCI must see space change before we begin */ 
     96+ 
     97+       value = __raw_readl(ar2315_pci_cfg_mem + addr); 
     98+ 
     99+       isr = ar231x_read_reg(AR2315_PCI_ISR); 
     100+       if (isr & AR2315_PCI_INT_ABORT) 
     101+               goto exit_err; 
    91102+ 
    92103+       if (write) { 
    93 +               value = *ptr; 
    94 +               if (size == 1) 
    95 +                       err = put_dbe(value, (u8 *)addr); 
    96 +               else if (size == 2) 
    97 +                       err = put_dbe(value, (u16 *)addr); 
    98 +               else if (size == 4) 
    99 +                       err = put_dbe(value, (u32 *)addr); 
     104+               value = (value & ~(mask << sh)) | *ptr << sh; 
     105+               __raw_writel(value, ar2315_pci_cfg_mem + addr); 
     106+               isr = ar231x_read_reg(AR2315_PCI_ISR); 
     107+               if (isr & AR2315_PCI_INT_ABORT) 
     108+                       goto exit_err; 
    100109+       } else { 
    101 +               if (size == 1) 
    102 +                       err = get_dbe(value, (u8 *)addr); 
    103 +               else if (size == 2) 
    104 +                       err = get_dbe(value, (u16 *)addr); 
    105 +               else if (size == 4) 
    106 +                       err = get_dbe(value, (u32 *)addr); 
    107 +               if (err) 
    108 +                       *ptr = 0xffffffff; 
    109 +               else 
    110 +                       *ptr = value; 
     110+               *ptr = (value >> sh) & mask; 
    111111+       } 
    112112+ 
     113+       goto exit; 
     114+ 
     115+exit_err: 
     116+       ar231x_write_reg(AR2315_PCI_ISR, AR2315_PCI_INT_ABORT); 
     117+       if (!write) 
     118+               *ptr = 0xffffffff; 
     119+ 
     120+exit: 
    113121+       /* Select Memory access */ 
    114122+       ar231x_mask_reg(AR2315_PCI_MISC_CONFIG, AR2315_PCIMISC_CFG_SEL, 0); 
    115123+ 
    116 +       return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; 
     124+       return isr & AR2315_PCI_INT_ABORT ? PCIBIOS_DEVICE_NOT_FOUND : 
     125+                                           PCIBIOS_SUCCESSFUL; 
    117126+} 
    118127+ 
     
    130139+                              int where, int size, u32 *value) 
    131140+{ 
    132 +       if ((PCI_SLOT(devfn) != 0) || (PCI_FUNC(devfn) > 2)) 
     141+       if (PCI_SLOT(devfn) == AR2315_PCI_HOST_SLOT) 
    133142+               return PCIBIOS_DEVICE_NOT_FOUND; 
    134143+ 
     
    139148+                               int where, int size, u32 value) 
    140149+{ 
    141 +       if ((PCI_SLOT(devfn) != 0) || (PCI_FUNC(devfn) > 2)) 
     150+       if (PCI_SLOT(devfn) == AR2315_PCI_HOST_SLOT) 
    142151+               return PCIBIOS_DEVICE_NOT_FOUND; 
    143152+ 
     
    283292+ 
    284293+       /* Remap PCI config space */ 
    285 +       configspace = (unsigned long)ioremap_nocache(AR2315_PCIEXT, 
    286 +                                                    1 * 1024 * 1024); 
     294+       ar2315_pci_cfg_mem = ioremap_nocache(AR2315_PCIEXT, 
     295+                                            AR2315_PCI_CFG_SIZE); 
     296+       if (!ar2315_pci_cfg_mem) { 
     297+               pr_err("ar2315-pci: failed to remap PCI config space\n"); 
     298+               return -ENOMEM; 
     299+       } 
     300+ 
    287301+       ar2315_pci_controller.io_map_base = 
    288302+                       (unsigned long)ioremap_nocache(AR2315_MEM_BASE + 
     
    340354+ 
    341355+error: 
    342 +       iounmap((void __iomem *)configspace); 
     356+       iounmap(ar2315_pci_cfg_mem); 
    343357+       return res; 
    344358+} 
Note: See TracChangeset for help on using the changeset viewer.