Changeset 44568


Ignore:
Timestamp:
2015-02-27T18:40:17+01:00 (3 years ago)
Author:
jogo
Message:

b53: fix mmap register read/writes > 32 bit

For bcm63xx integrated switches, broadcom changed the data endianess
to match the system endianess. But this only applies to within one word,
which causes 48/64 bit values to be still split into their "litte endian"
groups.

E.g. 48 bit values (with 5 being the most significant byte) aligned

0x00 ..01 or 0123
0x04 2345 45..

will become

0x00 ..10 resp. 3210
0x04 5432 54..

Likewise for 64 bit values.

Signed-off-by: Jonas Gorski <jogo@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/target/linux/generic/files/drivers/net/phy/b53/b53_mmap.c

    r39354 r44568  
    6565static int b53_mmap_read48(struct b53_device *dev, u8 page, u8 reg, u64 *val) 
    6666{ 
    67         u8 __iomem *regs = dev->priv; 
    68  
    69         if (WARN_ON(reg % 4)) 
    70                 return -EINVAL; 
    71  
    72         if (dev->pdata && dev->pdata->big_endian) { 
    73                 *val = readl_be(regs + (page << 8) + reg); 
    74                 *val <<= 16; 
    75                 *val |= readw_be(regs + (page << 8) + reg + 4); 
     67        if (WARN_ON(reg % 2)) 
     68                return -EINVAL; 
     69 
     70        if (reg % 4) { 
     71                u16 lo; 
     72                u32 hi; 
     73 
     74                b53_mmap_read16(dev, page, reg, &lo); 
     75                b53_mmap_read32(dev, page, reg + 2, &hi); 
     76 
     77                *val = ((u64)hi << 16) | lo; 
    7678        } else { 
    77                 *val |= readw(regs + (page << 8) + reg + 4); 
    78                 *val <<= 32; 
    79                 *val = readl(regs + (page << 8) + reg); 
     79                u32 lo; 
     80                u16 hi; 
     81 
     82                b53_mmap_read32(dev, page, reg, &lo); 
     83                b53_mmap_read16(dev, page, reg + 4, &hi); 
     84 
     85                *val = ((u64)hi << 32) | lo; 
    8086        } 
    8187 
     
    8591static int b53_mmap_read64(struct b53_device *dev, u8 page, u8 reg, u64 *val) 
    8692{ 
    87         u8 __iomem *regs = dev->priv; 
    8893        u32 hi, lo; 
    8994 
     
    9196                return -EINVAL; 
    9297 
    93         if (dev->pdata && dev->pdata->big_endian) { 
    94                 lo = readl_be(regs + (page << 8) + reg); 
    95                 hi = readl_be(regs + (page << 8) + reg + 4); 
    96         } else { 
    97                 lo = readl(regs + (page << 8) + reg); 
    98                 hi = readl(regs + (page << 8) + reg + 4); 
    99         } 
     98        b53_mmap_read32(dev, page, reg, &lo); 
     99        b53_mmap_read32(dev, page, reg + 4, &hi); 
    100100 
    101101        *val = ((u64)hi << 32) | lo; 
     
    148148                                    u64 value) 
    149149{ 
    150         u8 __iomem *regs = dev->priv; 
    151  
    152         if (WARN_ON(reg % 4)) 
    153                 return -EINVAL; 
    154  
    155         if (dev->pdata && dev->pdata->big_endian) { 
    156                 writel_be((u32)(value >> 16), regs + (page << 8) + reg); 
    157                 writew_be((u16)value, regs + (page << 8) + reg + 4); 
     150        if (WARN_ON(reg % 2)) 
     151                return -EINVAL; 
     152 
     153        if (reg % 4) { 
     154                u32 hi = (u32)(value >> 16); 
     155                u16 lo = (u16)value; 
     156 
     157                b53_mmap_write16(dev, page, reg, lo); 
     158                b53_mmap_write32(dev, page, reg + 2, hi); 
    158159        } else { 
    159                 writel((u32)value, regs + (page << 8) + reg); 
    160                 writew((u16)(value >> 32), regs + (page << 8) + reg + 4); 
     160                u16 hi = (u16)(value >> 32); 
     161                u32 lo = (u32)value; 
     162 
     163                b53_mmap_write32(dev, page, reg, lo); 
     164                b53_mmap_write16(dev, page, reg + 4, hi); 
    161165        } 
    162166 
     
    167171                             u64 value) 
    168172{ 
    169         u8 __iomem *regs = dev->priv; 
    170  
    171         if (WARN_ON(reg % 4)) 
    172                 return -EINVAL; 
    173  
    174         if (dev->pdata && dev->pdata->big_endian) { 
    175                 writel_be((u32)(value >> 32), regs + (page << 8) + reg); 
    176                 writel_be((u32)value, regs + (page << 8) + reg + 4); 
    177         } else { 
    178                 writel((u32)value, regs + (page << 8) + reg); 
    179                 writel((u32)(value >> 32), regs + (page << 8) + reg + 4); 
    180         } 
     173        u32 hi, lo; 
     174 
     175        hi = (u32)(value >> 32); 
     176        lo = (u32)value; 
     177 
     178        if (WARN_ON(reg % 4)) 
     179                return -EINVAL; 
     180 
     181        b53_mmap_write32(dev, page, reg, lo); 
     182        b53_mmap_write32(dev, page, reg + 4, hi); 
    181183 
    182184        return 0; 
Note: See TracChangeset for help on using the changeset viewer.