ARM: 8836/1: drivers: amba: Update component matching to use the CoreSight UCI values.
authorMike Leach <mike.leach@linaro.org>
Wed, 13 Feb 2019 13:41:50 +0000 (14:41 +0100)
committerRussell King <rmk+kernel@armlinux.org.uk>
Tue, 26 Feb 2019 11:23:49 +0000 (11:23 +0000)
The patches provide an update of amba_device and matching code to handle
the additional registers required for the Class 0x9 (CoreSight) UCI.

The *data pointer in the amba_id is used by the driver to provide extended
ID register values for matching.

CoreSight components where PID/CID pair is currently sufficient for
unique identification need not provide this additional information.

Signed-off-by: Mike Leach <mike.leach@linaro.org>
Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Tested-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
drivers/amba/bus.c
include/linux/amba/bus.h

index 41b7064..b4dae62 100644 (file)
 
 #define to_amba_driver(d)      container_of(d, struct amba_driver, drv)
 
-static const struct amba_id *
-amba_lookup(const struct amba_id *table, struct amba_device *dev)
+/* called on periphid match and class 0x9 coresight device. */
+static int
+amba_cs_uci_id_match(const struct amba_id *table, struct amba_device *dev)
 {
        int ret = 0;
+       struct amba_cs_uci_id *uci;
+
+       uci = table->data;
 
+       /* no table data or zero mask - return match on periphid */
+       if (!uci || (uci->devarch_mask == 0))
+               return 1;
+
+       /* test against read devtype and masked devarch value */
+       ret = (dev->uci.devtype == uci->devtype) &&
+               ((dev->uci.devarch & uci->devarch_mask) == uci->devarch);
+       return ret;
+}
+
+static const struct amba_id *
+amba_lookup(const struct amba_id *table, struct amba_device *dev)
+{
        while (table->mask) {
-               ret = (dev->periphid & table->mask) == table->id;
-               if (ret)
-                       break;
+               if (((dev->periphid & table->mask) == table->id) &&
+                       ((dev->cid != CORESIGHT_CID) ||
+                        (amba_cs_uci_id_match(table, dev))))
+                       return table;
                table++;
        }
-
-       return ret ? table : NULL;
+       return NULL;
 }
 
 static int amba_match(struct device *dev, struct device_driver *drv)
@@ -399,10 +416,22 @@ static int amba_device_try_add(struct amba_device *dev, struct resource *parent)
                        cid |= (readl(tmp + size - 0x10 + 4 * i) & 255) <<
                                (i * 8);
 
+               if (cid == CORESIGHT_CID) {
+                       /* set the base to the start of the last 4k block */
+                       void __iomem *csbase = tmp + size - 4096;
+
+                       dev->uci.devarch =
+                               readl(csbase + UCI_REG_DEVARCH_OFFSET);
+                       dev->uci.devtype =
+                               readl(csbase + UCI_REG_DEVTYPE_OFFSET) & 0xff;
+               }
+
                amba_put_disable_pclk(dev);
 
-               if (cid == AMBA_CID || cid == CORESIGHT_CID)
+               if (cid == AMBA_CID || cid == CORESIGHT_CID) {
                        dev->periphid = pid;
+                       dev->cid = cid;
+               }
 
                if (!dev->periphid)
                        ret = -ENODEV;
index e3c3622..f99b74a 100644 (file)
@@ -58,6 +58,10 @@ struct amba_cs_uci_id {
        void *data;
 };
 
+/* define offsets for registers used by UCI */
+#define UCI_REG_DEVTYPE_OFFSET 0xFCC
+#define UCI_REG_DEVARCH_OFFSET 0xFBC
+
 struct clk;
 
 struct amba_device {
@@ -65,6 +69,8 @@ struct amba_device {
        struct resource         res;
        struct clk              *pclk;
        unsigned int            periphid;
+       unsigned int            cid;
+       struct amba_cs_uci_id   uci;
        unsigned int            irq[AMBA_NR_IRQS];
        char                    *driver_override;
 };