root/drivers/bus/brcmstb_gisb.c

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

DEFINITIONS

This source file includes following definitions.
  1. gisb_read
  2. gisb_read_address
  3. gisb_write
  4. gisb_arb_get_timeout
  5. gisb_arb_set_timeout
  6. brcmstb_gisb_master_to_str
  7. brcmstb_gisb_arb_decode_addr
  8. brcmstb_bus_error_handler
  9. brcmstb_gisb_timeout_handler
  10. brcmstb_gisb_tea_handler
  11. dump_gisb_error
  12. brcmstb_gisb_arb_probe
  13. brcmstb_gisb_arb_suspend
  14. brcmstb_gisb_arb_resume_noirq
  15. brcm_gisb_driver_init

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (C) 2014-2017 Broadcom
   4  */
   5 
   6 #include <linux/init.h>
   7 #include <linux/types.h>
   8 #include <linux/module.h>
   9 #include <linux/platform_device.h>
  10 #include <linux/interrupt.h>
  11 #include <linux/sysfs.h>
  12 #include <linux/io.h>
  13 #include <linux/string.h>
  14 #include <linux/device.h>
  15 #include <linux/list.h>
  16 #include <linux/of.h>
  17 #include <linux/bitops.h>
  18 #include <linux/pm.h>
  19 #include <linux/kernel.h>
  20 #include <linux/kdebug.h>
  21 #include <linux/notifier.h>
  22 
  23 #ifdef CONFIG_MIPS
  24 #include <asm/traps.h>
  25 #endif
  26 
  27 #define  ARB_ERR_CAP_CLEAR              (1 << 0)
  28 #define  ARB_ERR_CAP_STATUS_TIMEOUT     (1 << 12)
  29 #define  ARB_ERR_CAP_STATUS_TEA         (1 << 11)
  30 #define  ARB_ERR_CAP_STATUS_WRITE       (1 << 1)
  31 #define  ARB_ERR_CAP_STATUS_VALID       (1 << 0)
  32 
  33 enum {
  34         ARB_TIMER,
  35         ARB_ERR_CAP_CLR,
  36         ARB_ERR_CAP_HI_ADDR,
  37         ARB_ERR_CAP_ADDR,
  38         ARB_ERR_CAP_STATUS,
  39         ARB_ERR_CAP_MASTER,
  40 };
  41 
  42 static const int gisb_offsets_bcm7038[] = {
  43         [ARB_TIMER]             = 0x00c,
  44         [ARB_ERR_CAP_CLR]       = 0x0c4,
  45         [ARB_ERR_CAP_HI_ADDR]   = -1,
  46         [ARB_ERR_CAP_ADDR]      = 0x0c8,
  47         [ARB_ERR_CAP_STATUS]    = 0x0d0,
  48         [ARB_ERR_CAP_MASTER]    = -1,
  49 };
  50 
  51 static const int gisb_offsets_bcm7278[] = {
  52         [ARB_TIMER]             = 0x008,
  53         [ARB_ERR_CAP_CLR]       = 0x7f8,
  54         [ARB_ERR_CAP_HI_ADDR]   = -1,
  55         [ARB_ERR_CAP_ADDR]      = 0x7e0,
  56         [ARB_ERR_CAP_STATUS]    = 0x7f0,
  57         [ARB_ERR_CAP_MASTER]    = 0x7f4,
  58 };
  59 
  60 static const int gisb_offsets_bcm7400[] = {
  61         [ARB_TIMER]             = 0x00c,
  62         [ARB_ERR_CAP_CLR]       = 0x0c8,
  63         [ARB_ERR_CAP_HI_ADDR]   = -1,
  64         [ARB_ERR_CAP_ADDR]      = 0x0cc,
  65         [ARB_ERR_CAP_STATUS]    = 0x0d4,
  66         [ARB_ERR_CAP_MASTER]    = 0x0d8,
  67 };
  68 
  69 static const int gisb_offsets_bcm7435[] = {
  70         [ARB_TIMER]             = 0x00c,
  71         [ARB_ERR_CAP_CLR]       = 0x168,
  72         [ARB_ERR_CAP_HI_ADDR]   = -1,
  73         [ARB_ERR_CAP_ADDR]      = 0x16c,
  74         [ARB_ERR_CAP_STATUS]    = 0x174,
  75         [ARB_ERR_CAP_MASTER]    = 0x178,
  76 };
  77 
  78 static const int gisb_offsets_bcm7445[] = {
  79         [ARB_TIMER]             = 0x008,
  80         [ARB_ERR_CAP_CLR]       = 0x7e4,
  81         [ARB_ERR_CAP_HI_ADDR]   = 0x7e8,
  82         [ARB_ERR_CAP_ADDR]      = 0x7ec,
  83         [ARB_ERR_CAP_STATUS]    = 0x7f4,
  84         [ARB_ERR_CAP_MASTER]    = 0x7f8,
  85 };
  86 
  87 struct brcmstb_gisb_arb_device {
  88         void __iomem    *base;
  89         const int       *gisb_offsets;
  90         bool            big_endian;
  91         struct mutex    lock;
  92         struct list_head next;
  93         u32 valid_mask;
  94         const char *master_names[sizeof(u32) * BITS_PER_BYTE];
  95         u32 saved_timeout;
  96 };
  97 
  98 static LIST_HEAD(brcmstb_gisb_arb_device_list);
  99 
 100 static u32 gisb_read(struct brcmstb_gisb_arb_device *gdev, int reg)
 101 {
 102         int offset = gdev->gisb_offsets[reg];
 103 
 104         if (offset < 0) {
 105                 /* return 1 if the hardware doesn't have ARB_ERR_CAP_MASTER */
 106                 if (reg == ARB_ERR_CAP_MASTER)
 107                         return 1;
 108                 else
 109                         return 0;
 110         }
 111 
 112         if (gdev->big_endian)
 113                 return ioread32be(gdev->base + offset);
 114         else
 115                 return ioread32(gdev->base + offset);
 116 }
 117 
 118 static u64 gisb_read_address(struct brcmstb_gisb_arb_device *gdev)
 119 {
 120         u64 value;
 121 
 122         value = gisb_read(gdev, ARB_ERR_CAP_ADDR);
 123         value |= (u64)gisb_read(gdev, ARB_ERR_CAP_HI_ADDR) << 32;
 124 
 125         return value;
 126 }
 127 
 128 static void gisb_write(struct brcmstb_gisb_arb_device *gdev, u32 val, int reg)
 129 {
 130         int offset = gdev->gisb_offsets[reg];
 131 
 132         if (offset == -1)
 133                 return;
 134 
 135         if (gdev->big_endian)
 136                 iowrite32be(val, gdev->base + offset);
 137         else
 138                 iowrite32(val, gdev->base + offset);
 139 }
 140 
 141 static ssize_t gisb_arb_get_timeout(struct device *dev,
 142                                     struct device_attribute *attr,
 143                                     char *buf)
 144 {
 145         struct brcmstb_gisb_arb_device *gdev = dev_get_drvdata(dev);
 146         u32 timeout;
 147 
 148         mutex_lock(&gdev->lock);
 149         timeout = gisb_read(gdev, ARB_TIMER);
 150         mutex_unlock(&gdev->lock);
 151 
 152         return sprintf(buf, "%d", timeout);
 153 }
 154 
 155 static ssize_t gisb_arb_set_timeout(struct device *dev,
 156                                     struct device_attribute *attr,
 157                                     const char *buf, size_t count)
 158 {
 159         struct brcmstb_gisb_arb_device *gdev = dev_get_drvdata(dev);
 160         int val, ret;
 161 
 162         ret = kstrtoint(buf, 10, &val);
 163         if (ret < 0)
 164                 return ret;
 165 
 166         if (val == 0 || val >= 0xffffffff)
 167                 return -EINVAL;
 168 
 169         mutex_lock(&gdev->lock);
 170         gisb_write(gdev, val, ARB_TIMER);
 171         mutex_unlock(&gdev->lock);
 172 
 173         return count;
 174 }
 175 
 176 static const char *
 177 brcmstb_gisb_master_to_str(struct brcmstb_gisb_arb_device *gdev,
 178                                                 u32 masters)
 179 {
 180         u32 mask = gdev->valid_mask & masters;
 181 
 182         if (hweight_long(mask) != 1)
 183                 return NULL;
 184 
 185         return gdev->master_names[ffs(mask) - 1];
 186 }
 187 
 188 static int brcmstb_gisb_arb_decode_addr(struct brcmstb_gisb_arb_device *gdev,
 189                                         const char *reason)
 190 {
 191         u32 cap_status;
 192         u64 arb_addr;
 193         u32 master;
 194         const char *m_name;
 195         char m_fmt[11];
 196 
 197         cap_status = gisb_read(gdev, ARB_ERR_CAP_STATUS);
 198 
 199         /* Invalid captured address, bail out */
 200         if (!(cap_status & ARB_ERR_CAP_STATUS_VALID))
 201                 return 1;
 202 
 203         /* Read the address and master */
 204         arb_addr = gisb_read_address(gdev);
 205         master = gisb_read(gdev, ARB_ERR_CAP_MASTER);
 206 
 207         m_name = brcmstb_gisb_master_to_str(gdev, master);
 208         if (!m_name) {
 209                 snprintf(m_fmt, sizeof(m_fmt), "0x%08x", master);
 210                 m_name = m_fmt;
 211         }
 212 
 213         pr_crit("%s: %s at 0x%llx [%c %s], core: %s\n",
 214                 __func__, reason, arb_addr,
 215                 cap_status & ARB_ERR_CAP_STATUS_WRITE ? 'W' : 'R',
 216                 cap_status & ARB_ERR_CAP_STATUS_TIMEOUT ? "timeout" : "",
 217                 m_name);
 218 
 219         /* clear the GISB error */
 220         gisb_write(gdev, ARB_ERR_CAP_CLEAR, ARB_ERR_CAP_CLR);
 221 
 222         return 0;
 223 }
 224 
 225 #ifdef CONFIG_MIPS
 226 static int brcmstb_bus_error_handler(struct pt_regs *regs, int is_fixup)
 227 {
 228         int ret = 0;
 229         struct brcmstb_gisb_arb_device *gdev;
 230         u32 cap_status;
 231 
 232         list_for_each_entry(gdev, &brcmstb_gisb_arb_device_list, next) {
 233                 cap_status = gisb_read(gdev, ARB_ERR_CAP_STATUS);
 234 
 235                 /* Invalid captured address, bail out */
 236                 if (!(cap_status & ARB_ERR_CAP_STATUS_VALID)) {
 237                         is_fixup = 1;
 238                         goto out;
 239                 }
 240 
 241                 ret |= brcmstb_gisb_arb_decode_addr(gdev, "bus error");
 242         }
 243 out:
 244         return is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL;
 245 }
 246 #endif
 247 
 248 static irqreturn_t brcmstb_gisb_timeout_handler(int irq, void *dev_id)
 249 {
 250         brcmstb_gisb_arb_decode_addr(dev_id, "timeout");
 251 
 252         return IRQ_HANDLED;
 253 }
 254 
 255 static irqreturn_t brcmstb_gisb_tea_handler(int irq, void *dev_id)
 256 {
 257         brcmstb_gisb_arb_decode_addr(dev_id, "target abort");
 258 
 259         return IRQ_HANDLED;
 260 }
 261 
 262 /*
 263  * Dump out gisb errors on die or panic.
 264  */
 265 static int dump_gisb_error(struct notifier_block *self, unsigned long v,
 266                            void *p);
 267 
 268 static struct notifier_block gisb_die_notifier = {
 269         .notifier_call = dump_gisb_error,
 270 };
 271 
 272 static struct notifier_block gisb_panic_notifier = {
 273         .notifier_call = dump_gisb_error,
 274 };
 275 
 276 static int dump_gisb_error(struct notifier_block *self, unsigned long v,
 277                            void *p)
 278 {
 279         struct brcmstb_gisb_arb_device *gdev;
 280         const char *reason = "panic";
 281 
 282         if (self == &gisb_die_notifier)
 283                 reason = "die";
 284 
 285         /* iterate over each GISB arb registered handlers */
 286         list_for_each_entry(gdev, &brcmstb_gisb_arb_device_list, next)
 287                 brcmstb_gisb_arb_decode_addr(gdev, reason);
 288 
 289         return NOTIFY_DONE;
 290 }
 291 
 292 static DEVICE_ATTR(gisb_arb_timeout, S_IWUSR | S_IRUGO,
 293                 gisb_arb_get_timeout, gisb_arb_set_timeout);
 294 
 295 static struct attribute *gisb_arb_sysfs_attrs[] = {
 296         &dev_attr_gisb_arb_timeout.attr,
 297         NULL,
 298 };
 299 
 300 static struct attribute_group gisb_arb_sysfs_attr_group = {
 301         .attrs = gisb_arb_sysfs_attrs,
 302 };
 303 
 304 static const struct of_device_id brcmstb_gisb_arb_of_match[] = {
 305         { .compatible = "brcm,gisb-arb",         .data = gisb_offsets_bcm7445 },
 306         { .compatible = "brcm,bcm7445-gisb-arb", .data = gisb_offsets_bcm7445 },
 307         { .compatible = "brcm,bcm7435-gisb-arb", .data = gisb_offsets_bcm7435 },
 308         { .compatible = "brcm,bcm7400-gisb-arb", .data = gisb_offsets_bcm7400 },
 309         { .compatible = "brcm,bcm7278-gisb-arb", .data = gisb_offsets_bcm7278 },
 310         { .compatible = "brcm,bcm7038-gisb-arb", .data = gisb_offsets_bcm7038 },
 311         { },
 312 };
 313 
 314 static int __init brcmstb_gisb_arb_probe(struct platform_device *pdev)
 315 {
 316         struct device_node *dn = pdev->dev.of_node;
 317         struct brcmstb_gisb_arb_device *gdev;
 318         const struct of_device_id *of_id;
 319         struct resource *r;
 320         int err, timeout_irq, tea_irq;
 321         unsigned int num_masters, j = 0;
 322         int i, first, last;
 323 
 324         r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 325         timeout_irq = platform_get_irq(pdev, 0);
 326         tea_irq = platform_get_irq(pdev, 1);
 327 
 328         gdev = devm_kzalloc(&pdev->dev, sizeof(*gdev), GFP_KERNEL);
 329         if (!gdev)
 330                 return -ENOMEM;
 331 
 332         mutex_init(&gdev->lock);
 333         INIT_LIST_HEAD(&gdev->next);
 334 
 335         gdev->base = devm_ioremap_resource(&pdev->dev, r);
 336         if (IS_ERR(gdev->base))
 337                 return PTR_ERR(gdev->base);
 338 
 339         of_id = of_match_node(brcmstb_gisb_arb_of_match, dn);
 340         if (!of_id) {
 341                 pr_err("failed to look up compatible string\n");
 342                 return -EINVAL;
 343         }
 344         gdev->gisb_offsets = of_id->data;
 345         gdev->big_endian = of_device_is_big_endian(dn);
 346 
 347         err = devm_request_irq(&pdev->dev, timeout_irq,
 348                                 brcmstb_gisb_timeout_handler, 0, pdev->name,
 349                                 gdev);
 350         if (err < 0)
 351                 return err;
 352 
 353         err = devm_request_irq(&pdev->dev, tea_irq,
 354                                 brcmstb_gisb_tea_handler, 0, pdev->name,
 355                                 gdev);
 356         if (err < 0)
 357                 return err;
 358 
 359         /* If we do not have a valid mask, assume all masters are enabled */
 360         if (of_property_read_u32(dn, "brcm,gisb-arb-master-mask",
 361                                 &gdev->valid_mask))
 362                 gdev->valid_mask = 0xffffffff;
 363 
 364         /* Proceed with reading the litteral names if we agree on the
 365          * number of masters
 366          */
 367         num_masters = of_property_count_strings(dn,
 368                         "brcm,gisb-arb-master-names");
 369         if (hweight_long(gdev->valid_mask) == num_masters) {
 370                 first = ffs(gdev->valid_mask) - 1;
 371                 last = fls(gdev->valid_mask) - 1;
 372 
 373                 for (i = first; i < last; i++) {
 374                         if (!(gdev->valid_mask & BIT(i)))
 375                                 continue;
 376 
 377                         of_property_read_string_index(dn,
 378                                         "brcm,gisb-arb-master-names", j,
 379                                         &gdev->master_names[i]);
 380                         j++;
 381                 }
 382         }
 383 
 384         err = sysfs_create_group(&pdev->dev.kobj, &gisb_arb_sysfs_attr_group);
 385         if (err)
 386                 return err;
 387 
 388         platform_set_drvdata(pdev, gdev);
 389 
 390         list_add_tail(&gdev->next, &brcmstb_gisb_arb_device_list);
 391 
 392 #ifdef CONFIG_MIPS
 393         board_be_handler = brcmstb_bus_error_handler;
 394 #endif
 395 
 396         if (list_is_singular(&brcmstb_gisb_arb_device_list)) {
 397                 register_die_notifier(&gisb_die_notifier);
 398                 atomic_notifier_chain_register(&panic_notifier_list,
 399                                                &gisb_panic_notifier);
 400         }
 401 
 402         dev_info(&pdev->dev, "registered irqs: %d, %d\n",
 403                  timeout_irq, tea_irq);
 404 
 405         return 0;
 406 }
 407 
 408 #ifdef CONFIG_PM_SLEEP
 409 static int brcmstb_gisb_arb_suspend(struct device *dev)
 410 {
 411         struct brcmstb_gisb_arb_device *gdev = dev_get_drvdata(dev);
 412 
 413         gdev->saved_timeout = gisb_read(gdev, ARB_TIMER);
 414 
 415         return 0;
 416 }
 417 
 418 /* Make sure we provide the same timeout value that was configured before, and
 419  * do this before the GISB timeout interrupt handler has any chance to run.
 420  */
 421 static int brcmstb_gisb_arb_resume_noirq(struct device *dev)
 422 {
 423         struct brcmstb_gisb_arb_device *gdev = dev_get_drvdata(dev);
 424 
 425         gisb_write(gdev, gdev->saved_timeout, ARB_TIMER);
 426 
 427         return 0;
 428 }
 429 #else
 430 #define brcmstb_gisb_arb_suspend       NULL
 431 #define brcmstb_gisb_arb_resume_noirq  NULL
 432 #endif
 433 
 434 static const struct dev_pm_ops brcmstb_gisb_arb_pm_ops = {
 435         .suspend        = brcmstb_gisb_arb_suspend,
 436         .resume_noirq   = brcmstb_gisb_arb_resume_noirq,
 437 };
 438 
 439 static struct platform_driver brcmstb_gisb_arb_driver = {
 440         .driver = {
 441                 .name   = "brcm-gisb-arb",
 442                 .of_match_table = brcmstb_gisb_arb_of_match,
 443                 .pm     = &brcmstb_gisb_arb_pm_ops,
 444         },
 445 };
 446 
 447 static int __init brcm_gisb_driver_init(void)
 448 {
 449         return platform_driver_probe(&brcmstb_gisb_arb_driver,
 450                                      brcmstb_gisb_arb_probe);
 451 }
 452 
 453 module_init(brcm_gisb_driver_init);

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