Merge branch '2018-11-16-master-imports'
[oweals/u-boot.git] / drivers / misc / swap_case.c
index 3b8aa48aad8bcd9522c982faaf3e676693abb385..fa608cec1b92a0a9cd2a55586ddb135fd27df263 100644 (file)
@@ -1,10 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * PCI emulation device which swaps the case of text
  *
  * Copyright (c) 2014 Google, Inc
  * Written by Simon Glass <sjg@chromium.org>
- *
- * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
@@ -22,7 +21,7 @@
  */
 struct swap_case_platdata {
        u16 command;
-       u32 bar[2];
+       u32 bar[6];
 };
 
 #define offset_to_barnum(offset)       \
@@ -119,6 +118,36 @@ static int sandbox_swap_case_read_config(struct udevice *emul, uint offset,
                *valuep = result;
                break;
        }
+       case PCI_CAPABILITY_LIST:
+               *valuep = PCI_CAP_ID_PM_OFFSET;
+               break;
+       case PCI_CAP_ID_PM_OFFSET:
+               *valuep = (PCI_CAP_ID_EXP_OFFSET << 8) | PCI_CAP_ID_PM;
+               break;
+       case PCI_CAP_ID_PM_OFFSET + PCI_CAP_LIST_NEXT:
+               *valuep = PCI_CAP_ID_EXP_OFFSET;
+               break;
+       case PCI_CAP_ID_EXP_OFFSET:
+               *valuep = (PCI_CAP_ID_MSIX_OFFSET << 8) | PCI_CAP_ID_EXP;
+               break;
+       case PCI_CAP_ID_EXP_OFFSET + PCI_CAP_LIST_NEXT:
+               *valuep = PCI_CAP_ID_MSIX_OFFSET;
+               break;
+       case PCI_CAP_ID_MSIX_OFFSET:
+               *valuep = PCI_CAP_ID_MSIX;
+               break;
+       case PCI_CAP_ID_MSIX_OFFSET + PCI_CAP_LIST_NEXT:
+               *valuep = 0;
+               break;
+       case PCI_EXT_CAP_ID_ERR_OFFSET:
+               *valuep = (PCI_EXT_CAP_ID_VC_OFFSET << 20) | PCI_EXT_CAP_ID_ERR;
+               break;
+       case PCI_EXT_CAP_ID_VC_OFFSET:
+               *valuep = (PCI_EXT_CAP_ID_DSN_OFFSET << 20) | PCI_EXT_CAP_ID_VC;
+               break;
+       case PCI_EXT_CAP_ID_DSN_OFFSET:
+               *valuep = PCI_EXT_CAP_ID_DSN;
+               break;
        }
 
        return 0;
@@ -143,6 +172,8 @@ static int sandbox_swap_case_write_config(struct udevice *emul, uint offset,
 
                debug("w bar %d=%lx\n", barnum, value);
                *bar = value;
+               /* space indicator (bit#0) is read-only */
+               *bar |= barinfo[barnum].type;
                break;
        }
        }
@@ -158,11 +189,11 @@ static int sandbox_swap_case_find_bar(struct udevice *emul, unsigned int addr,
 
        for (barnum = 0; barnum < ARRAY_SIZE(barinfo); barnum++) {
                unsigned int size = barinfo[barnum].size;
+               u32 base = plat->bar[barnum] & ~PCI_BASE_ADDRESS_SPACE;
 
-               if (addr >= plat->bar[barnum] &&
-                   addr < plat->bar[barnum] + size) {
+               if (addr >= base && addr < base + size) {
                        *barnump = barnum;
-                       *offsetp = addr - plat->bar[barnum];
+                       *offsetp = addr - base;
                        return 0;
                }
        }
@@ -284,3 +315,10 @@ U_BOOT_DRIVER(sandbox_swap_case_emul) = {
        .priv_auto_alloc_size = sizeof(struct swap_case_priv),
        .platdata_auto_alloc_size = sizeof(struct swap_case_platdata),
 };
+
+static struct pci_device_id sandbox_swap_case_supported[] = {
+       { PCI_VDEVICE(SANDBOX, SANDBOX_PCI_DEVICE_ID), SWAP_CASE_DRV_DATA },
+       {},
+};
+
+U_BOOT_PCI_DEVICE(sandbox_swap_case_emul, sandbox_swap_case_supported);