root/drivers/ssb/host_soc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ssb_host_soc_read8
  2. ssb_host_soc_read16
  3. ssb_host_soc_read32
  4. ssb_host_soc_block_read
  5. ssb_host_soc_write8
  6. ssb_host_soc_write16
  7. ssb_host_soc_write32
  8. ssb_host_soc_block_write
  9. ssb_host_soc_get_invariants

   1 /*
   2  * Sonics Silicon Backplane SoC host related functions.
   3  * Subsystem core
   4  *
   5  * Copyright 2005, Broadcom Corporation
   6  * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
   7  *
   8  * Licensed under the GNU/GPL. See COPYING for details.
   9  */
  10 
  11 #include "ssb_private.h"
  12 
  13 #include <linux/bcm47xx_nvram.h>
  14 #include <linux/ssb/ssb.h>
  15 
  16 static u8 ssb_host_soc_read8(struct ssb_device *dev, u16 offset)
  17 {
  18         struct ssb_bus *bus = dev->bus;
  19 
  20         offset += dev->core_index * SSB_CORE_SIZE;
  21         return readb(bus->mmio + offset);
  22 }
  23 
  24 static u16 ssb_host_soc_read16(struct ssb_device *dev, u16 offset)
  25 {
  26         struct ssb_bus *bus = dev->bus;
  27 
  28         offset += dev->core_index * SSB_CORE_SIZE;
  29         return readw(bus->mmio + offset);
  30 }
  31 
  32 static u32 ssb_host_soc_read32(struct ssb_device *dev, u16 offset)
  33 {
  34         struct ssb_bus *bus = dev->bus;
  35 
  36         offset += dev->core_index * SSB_CORE_SIZE;
  37         return readl(bus->mmio + offset);
  38 }
  39 
  40 #ifdef CONFIG_SSB_BLOCKIO
  41 static void ssb_host_soc_block_read(struct ssb_device *dev, void *buffer,
  42                                     size_t count, u16 offset, u8 reg_width)
  43 {
  44         struct ssb_bus *bus = dev->bus;
  45         void __iomem *addr;
  46 
  47         offset += dev->core_index * SSB_CORE_SIZE;
  48         addr = bus->mmio + offset;
  49 
  50         switch (reg_width) {
  51         case sizeof(u8): {
  52                 u8 *buf = buffer;
  53 
  54                 while (count) {
  55                         *buf = __raw_readb(addr);
  56                         buf++;
  57                         count--;
  58                 }
  59                 break;
  60         }
  61         case sizeof(u16): {
  62                 __le16 *buf = buffer;
  63 
  64                 WARN_ON(count & 1);
  65                 while (count) {
  66                         *buf = (__force __le16)__raw_readw(addr);
  67                         buf++;
  68                         count -= 2;
  69                 }
  70                 break;
  71         }
  72         case sizeof(u32): {
  73                 __le32 *buf = buffer;
  74 
  75                 WARN_ON(count & 3);
  76                 while (count) {
  77                         *buf = (__force __le32)__raw_readl(addr);
  78                         buf++;
  79                         count -= 4;
  80                 }
  81                 break;
  82         }
  83         default:
  84                 WARN_ON(1);
  85         }
  86 }
  87 #endif /* CONFIG_SSB_BLOCKIO */
  88 
  89 static void ssb_host_soc_write8(struct ssb_device *dev, u16 offset, u8 value)
  90 {
  91         struct ssb_bus *bus = dev->bus;
  92 
  93         offset += dev->core_index * SSB_CORE_SIZE;
  94         writeb(value, bus->mmio + offset);
  95 }
  96 
  97 static void ssb_host_soc_write16(struct ssb_device *dev, u16 offset, u16 value)
  98 {
  99         struct ssb_bus *bus = dev->bus;
 100 
 101         offset += dev->core_index * SSB_CORE_SIZE;
 102         writew(value, bus->mmio + offset);
 103 }
 104 
 105 static void ssb_host_soc_write32(struct ssb_device *dev, u16 offset, u32 value)
 106 {
 107         struct ssb_bus *bus = dev->bus;
 108 
 109         offset += dev->core_index * SSB_CORE_SIZE;
 110         writel(value, bus->mmio + offset);
 111 }
 112 
 113 #ifdef CONFIG_SSB_BLOCKIO
 114 static void ssb_host_soc_block_write(struct ssb_device *dev, const void *buffer,
 115                                      size_t count, u16 offset, u8 reg_width)
 116 {
 117         struct ssb_bus *bus = dev->bus;
 118         void __iomem *addr;
 119 
 120         offset += dev->core_index * SSB_CORE_SIZE;
 121         addr = bus->mmio + offset;
 122 
 123         switch (reg_width) {
 124         case sizeof(u8): {
 125                 const u8 *buf = buffer;
 126 
 127                 while (count) {
 128                         __raw_writeb(*buf, addr);
 129                         buf++;
 130                         count--;
 131                 }
 132                 break;
 133         }
 134         case sizeof(u16): {
 135                 const __le16 *buf = buffer;
 136 
 137                 WARN_ON(count & 1);
 138                 while (count) {
 139                         __raw_writew((__force u16)(*buf), addr);
 140                         buf++;
 141                         count -= 2;
 142                 }
 143                 break;
 144         }
 145         case sizeof(u32): {
 146                 const __le32 *buf = buffer;
 147 
 148                 WARN_ON(count & 3);
 149                 while (count) {
 150                         __raw_writel((__force u32)(*buf), addr);
 151                         buf++;
 152                         count -= 4;
 153                 }
 154                 break;
 155         }
 156         default:
 157                 WARN_ON(1);
 158         }
 159 }
 160 #endif /* CONFIG_SSB_BLOCKIO */
 161 
 162 /* Ops for the plain SSB bus without a host-device (no PCI or PCMCIA). */
 163 const struct ssb_bus_ops ssb_host_soc_ops = {
 164         .read8          = ssb_host_soc_read8,
 165         .read16         = ssb_host_soc_read16,
 166         .read32         = ssb_host_soc_read32,
 167         .write8         = ssb_host_soc_write8,
 168         .write16        = ssb_host_soc_write16,
 169         .write32        = ssb_host_soc_write32,
 170 #ifdef CONFIG_SSB_BLOCKIO
 171         .block_read     = ssb_host_soc_block_read,
 172         .block_write    = ssb_host_soc_block_write,
 173 #endif
 174 };
 175 
 176 int ssb_host_soc_get_invariants(struct ssb_bus *bus,
 177                                 struct ssb_init_invariants *iv)
 178 {
 179         char buf[20];
 180         int len, err;
 181 
 182         /* Fill boardinfo structure */
 183         memset(&iv->boardinfo, 0, sizeof(struct ssb_boardinfo));
 184 
 185         len = bcm47xx_nvram_getenv("boardvendor", buf, sizeof(buf));
 186         if (len > 0) {
 187                 err = kstrtou16(strim(buf), 0, &iv->boardinfo.vendor);
 188                 if (err)
 189                         pr_warn("Couldn't parse nvram board vendor entry with value \"%s\"\n",
 190                                 buf);
 191         }
 192         if (!iv->boardinfo.vendor)
 193                 iv->boardinfo.vendor = SSB_BOARDVENDOR_BCM;
 194 
 195         len = bcm47xx_nvram_getenv("boardtype", buf, sizeof(buf));
 196         if (len > 0) {
 197                 err = kstrtou16(strim(buf), 0, &iv->boardinfo.type);
 198                 if (err)
 199                         pr_warn("Couldn't parse nvram board type entry with value \"%s\"\n",
 200                                 buf);
 201         }
 202 
 203         memset(&iv->sprom, 0, sizeof(struct ssb_sprom));
 204         ssb_fill_sprom_with_fallback(bus, &iv->sprom);
 205 
 206         if (bcm47xx_nvram_getenv("cardbus", buf, sizeof(buf)) >= 0)
 207                 iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10);
 208 
 209         return 0;
 210 }

/* [<][>][^][v][top][bottom][index][help] */