Skip to contentSkip to conversation

SDM845 System Cache Driver

PATCH Superseded Rishabh Bhatnagar 4 participants 10 messages Apr 23, 2018 – May 8, 2018

Subsystems (3)

v5 of 8 Superseded Latest is v8 →

lore
Share & tools
lore
#0 lore raw

v5 cover SDM845 System Cache Driver

This series implements system cache or LLCC(Last Level Cache Controller) driver for SDM845 SOC. The purpose of the driver is to partition the system cache and program the settings such as priortiy, lines to probe while doing a look up in the system cache, low power related settings etc. The partitions are called cache slices. Each cache slice is associated with size and SCID(System Cache ID). The driver also provides API for clients to query the cache slice details,activate and deactivate them.

The driver can be broadly classified into:
* SOC specific driver: llcc-sdm845.c: Cache partitioning and cache slice properties for usecases on sdm845 that need to use system cache.

* API : llcc-slice.c: Exports APIs to clients to query cache slice details, activate and deactivate cache slices.

Changes since v4:
* Remove null pointer checks as per comments.
* Remove extra blank lines.

Changes since v3:
* Use the regmap_read_poll_timeout function
* Check for regmap read/write errors.
* Remove memory barrier after regmap write
* Derive memory bank offsets using stride macro variable
* Remove debug statements from code
* Remove the qcom_llcc_remove function
* Use if IS_ENABLED in place of ifdef for built-in module
* Change EXPORT_SYMBOL to EXPORT_SYMBOL_GPL
* Remove unnecessary free functions
* Change the variable names as per review comments

Changes since v2:
* Corrected the Makefile to fix compilation.

Changes since v1:
* Added Makefile and Kconfig.

Changes since v0:
* Removed the syscon and simple-mfd approach
* Updated the device tree nodes to mention LLCC as a single HW block
* Moved llcc bank offsets from device tree and handled the offset in the driver.

ckadabi at codeaurora.org (2):
dt-bindings: Documentation for qcom, llcc
drivers: soc: Add LLCC driver

 .../devicetree/bindings/arm/msm/qcom,llcc.txt      |  60 ++++
 drivers/soc/qcom/Kconfig                           |  17 +
 drivers/soc/qcom/Makefile                          |   2 +
 drivers/soc/qcom/llcc-sdm845.c                     | 108 ++++++
 drivers/soc/qcom/llcc-slice.c                      | 380 +++++++++++++++++++++
 include/linux/soc/qcom/llcc-qcom.h                 | 167 +++++++++
 6 files changed, 734 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/msm/qcom,llcc.txt
 create mode 100644 drivers/soc/qcom/llcc-sdm845.c
 create mode 100644 drivers/soc/qcom/llcc-slice.c
 create mode 100644 include/linux/soc/qcom/llcc-qcom.h

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project

#1 lore raw

PATCH v5 1/2 dt-bindings: Documentation for qcom, llcc

Documentation for last level cache controller device tree bindings, client bindings usage examples.

---
 .../devicetree/bindings/arm/msm/qcom,llcc.txt      | 60 ++++++++++++++++++++++
 1 file changed, 60 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/msm/qcom,llcc.txt
Documentation/devicetree/bindings/arm/msm/qcom,llcc.txt new file +60 -0
new file mode 100644
index 0000000..c30d433
@@ -0,0 +1,60 @@
+== Introduction==
+
+LLCC (Last Level Cache Controller) provides last level of cache memory in SOC,
+that can be shared by multiple clients. Clients here are different cores in the
+SOC, the idea is to minimize the local caches at the clients and migrate to
+common pool of memory. Cache memory is divided into partitions called slices
+which are assigned to clients. Clients can query the slice details, activate
+and deactivate them.
+
+Properties:
+- compatible:
+	Usage: required
+	Value type: <string>
+	Definition: must be "qcom,sdm845-llcc"
+
+- reg:
+	Usage: required
+	Value Type: <prop-encoded-array>
+	Definition: Start address and the range of the LLCC registers.
+
+- #cache-cells:
+	Usage: required
+	Value Type: <u32>
+	Definition: Number of cache cells, must be 1
+
+- max-slices:
+	usage: required
+	Value Type: <u32>
+	Definition: Number of cache slices supported by hardware
+
+Example:
+
+	llcc: qcom,llcc at 1100000 {
+		compatible = "qcom,sdm845-llcc";
+		reg = <0x1100000 0x250000>;
+		#cache-cells = <1>;
+		max-slices = <32>;
+	};
+
+== Client ==
+
+Properties:
+- cache-slice-names:
+Usage: required
+	Value type: <stringlist>
+	Definition: A set of names that identify the usecase names of a
+		client that uses cache slice. These strings are
+		used to look up the cache slice entries by name.
+
+- cache-slices:
+	Usage: required
+	Value type: <prop-encoded-array>
+	Definition: The tuple has phandle to llcc device as the first
+			argument and the second argument is the usecase
+			id of the client.
+For Example:
+	venus {
+		cache-slice-names = "vidsc0", "vidsc1";
+		cache-slices = <&llcc VIDSC0_ID>, <&llcc VIDSC1_ID>;
+	};

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project

maintainer
#2 lore raw

Re: [PATCH v5 1/2] dt-bindings: Documentation for qcom, llcc

Quoted 9 lines · Rishabh Bhatnagar

Documentation for last level cache controller device tree bindings, client bindings usage examples.

---
 .../devicetree/bindings/arm/msm/qcom,llcc.txt      | 60 ++++++++++++++++++++++
 1 file changed, 60 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/msm/qcom,llcc.txt

My comments on v4 still apply.

Rob

#3 lore raw

Re: [PATCH v5 1/2] dt-bindings: Documentation for qcom, llcc

Quoted 13 lines · Rob Herring
Quoted 11 lines · Rishabh Bhatnagar

Documentation for last level cache controller device tree bindings, client bindings usage examples.

---
 .../devicetree/bindings/arm/msm/qcom,llcc.txt      | 60 
++++++++++++++++++++++
 1 file changed, 60 insertions(+)
 create mode 100644 

Documentation/devicetree/bindings/arm/msm/qcom,llcc.txt

Quoted 3 lines

My comments on v4 still apply.

Rob

Hi Rob,
Reposting our replies to your comments on v4:

This is partially true, a bunch of SoCs would support this design but clients IDs are not expected to change. So Ideally client drivers could hard code these IDs.

However I have other concerns of moving the client Ids in the driver. The way the APIs implemented today are as follows:
#1. Client calls into system cache driver to get cache slice handle with the usecase Id as input.
#2. System cache driver gets the phandle of system cache instance from the client device to obtain the private data.
#3. Based on the usecase Id perform look up in the private data to get cache slice handle.
#4. Return the cache slice handle to client

If we don't have the connection between client & system cache then the
private data needs to declared as static global in the system cache
driver,
that limits us to have just once instance of system cache block.

Please let us know what you think.

maintainer
#4 lore raw

Re: [PATCH v5 1/2] dt-bindings: Documentation for qcom, llcc

Quoted 39 lines · On Fri, Apr 27, 2018 at 5:57 PM, <[email protected]> wrote:
Quoted 16 lines · Rob Herring
Quoted 4 lines · Rishabh Bhatnagar

Documentation for last level cache controller device tree bindings, client bindings usage examples.

Quoted 8 lines
---
 .../devicetree/bindings/arm/msm/qcom,llcc.txt      | 60
++++++++++++++++++++++
 1 file changed, 60 insertions(+)
 create mode 100644

Documentation/devicetree/bindings/arm/msm/qcom,llcc.txt

Quoted 3 lines

My comments on v4 still apply.

Rob

Hi Rob,
Reposting our replies to your comments on v4:

This is partially true, a bunch of SoCs would support this design but clients IDs are not expected to change. So Ideally client drivers could hard code these IDs.

However I have other concerns of moving the client Ids in the driver. The way the APIs implemented today are as follows:
#1. Client calls into system cache driver to get cache slice handle with the usecase Id as input.
#2. System cache driver gets the phandle of system cache instance from the client device to obtain the private data.
#3. Based on the usecase Id perform look up in the private data to get cache slice handle.
#4. Return the cache slice handle to client

Quoted 3 lines

If we don't have the connection between client & system cache then the
private data needs to declared as static global in the system cache driver,
that limits us to have just once instance of system cache block.

How many instances do you have?

It is easier to put the data into the kernel and move it to DT later than vice-versa. I don't think it is a good idea to do a custom binding here and one that only addresses caches and nothing else in the interconnect. So either we define an extensible and future-proof binding or put the data into the kernel for now.

Rob

#5 lore raw

Re: [PATCH v5 1/2] dt-bindings: Documentation for qcom, llcc

Quoted 48 lines · Rob Herring
Quoted 40 lines · On Fri, Apr 27, 2018 at 5:57 PM, <[email protected]> wrote:
Quoted 16 lines · Rob Herring
Quoted 4 lines · Rishabh Bhatnagar

Documentation for last level cache controller device tree bindings, client bindings usage examples.

Quoted 8 lines
---
 .../devicetree/bindings/arm/msm/qcom,llcc.txt      | 60
++++++++++++++++++++++
 1 file changed, 60 insertions(+)
 create mode 100644

Documentation/devicetree/bindings/arm/msm/qcom,llcc.txt

Quoted 3 lines

My comments on v4 still apply.

Rob

Hi Rob,
Reposting our replies to your comments on v4:

This is partially true, a bunch of SoCs would support this design but clients IDs are not expected to change. So Ideally client drivers could
hard code these IDs.

However I have other concerns of moving the client Ids in the driver. The way the APIs implemented today are as follows:
#1. Client calls into system cache driver to get cache slice handle with the usecase Id as input.
#2. System cache driver gets the phandle of system cache instance from the client device to obtain the private data.
#3. Based on the usecase Id perform look up in the private data to get cache slice handle.
#4. Return the cache slice handle to client

Quoted 4 lines

If we don't have the connection between client & system cache then the
private data needs to declared as static global in the system cache
driver,
that limits us to have just once instance of system cache block.

How many instances do you have?

Quoted 7 lines

It is easier to put the data into the kernel and move it to DT later than vice-versa. I don't think it is a good idea to do a custom binding here and one that only addresses caches and nothing else in the interconnect. So either we define an extensible and future-proof binding or put the data into the kernel for now.

Rob

Hi rob,
Currently we have only instance but how do you propose we handle multiple
instances in future?
Currently we do a lookup in the private data of the driver to get the slice
handle but, if we were to remove the client connection we will have to make
lookup table as global and we can't have more than one instance. Also, can you suggest any extensible interconnect binding that we can refer
to?

maintainer
#6 lore raw

Re: [PATCH v5 1/2] dt-bindings: Documentation for qcom, llcc

Quoted 55 lines · rishabhb at codeaurora.org
Quoted 54 lines · Rob Herring
Quoted 40 lines · On Fri, Apr 27, 2018 at 5:57 PM, <[email protected]> wrote:
Quoted 16 lines · Rob Herring
Quoted 4 lines · Rishabh Bhatnagar

Documentation for last level cache controller device tree bindings, client bindings usage examples.

Quoted 8 lines
---
 .../devicetree/bindings/arm/msm/qcom,llcc.txt      | 60
++++++++++++++++++++++
 1 file changed, 60 insertions(+)
 create mode 100644

Documentation/devicetree/bindings/arm/msm/qcom,llcc.txt

Quoted 3 lines

My comments on v4 still apply.

Rob

Hi Rob,
Reposting our replies to your comments on v4:

This is partially true, a bunch of SoCs would support this design but clients IDs are not expected to change. So Ideally client drivers could
hard code these IDs.

However I have other concerns of moving the client Ids in the driver. The way the APIs implemented today are as follows:
#1. Client calls into system cache driver to get cache slice handle with the usecase Id as input.
#2. System cache driver gets the phandle of system cache instance from the client device to obtain the private data.
#3. Based on the usecase Id perform look up in the private data to get cache slice handle.
#4. Return the cache slice handle to client

Quoted 4 lines

If we don't have the connection between client & system cache then the
private data needs to declared as static global in the system cache
driver,
that limits us to have just once instance of system cache block.

How many instances do you have?

It is easier to put the data into the kernel and move it to DT later than vice-versa. I don't think it is a good idea to do a custom binding here and one that only addresses caches and nothing else in the interconnect. So either we define an extensible and future-proof binding or put the data into the kernel for now.

Quoted 4 lines
Quoted 1 line

Rob

Hi rob,
Currently we have only instance but how do you propose we handle multiple instances in future?

Worry about that when you have more that one. If it's only a theoretical possibility then it can wait.

Quoted 5 lines

Currently we do a lookup in the private data of the driver to get the slice handle but, if we were to remove the client connection we will have to make lookup table as global and we can't have more than one instance. Also, can you suggest any extensible interconnect binding that we can refer to?

There's been some work to add interconnect support for QCom chips. ATM, there is no binding for it and it is just a kernel driver and subsystem. I'm sure you can Google that to find as easily as me.

Rob

#7 lore raw

PATCH v5 2/2 drivers: soc: Add LLCC driver

In reply to Rishabh Bhatnagar

LLCC (Last Level Cache Controller) provides additional cache memory in the system. LLCC is partitioned into multiple slices and each slice gets its own priority, size, ID and other config parameters. LLCC driver programs these parameters for each slice. Clients that are assigned to use LLCC need to get information such size & ID of the slice they get and activate or deactivate the slice as needed. LLCC driver provides API for the clients to perform these operations.

---
 drivers/soc/qcom/Kconfig           |  17 ++
 drivers/soc/qcom/Makefile          |   2 +
 drivers/soc/qcom/llcc-sdm845.c     | 108 +++++++++++
 drivers/soc/qcom/llcc-slice.c      | 380 +++++++++++++++++++++++++++++++++++++
 include/linux/soc/qcom/llcc-qcom.h | 167 ++++++++++++++++
 5 files changed, 674 insertions(+)
 create mode 100644 drivers/soc/qcom/llcc-sdm845.c
 create mode 100644 drivers/soc/qcom/llcc-slice.c
 create mode 100644 include/linux/soc/qcom/llcc-qcom.h
drivers/soc/qcom/Kconfig +17 -0
index e050eb8..2b09321 100644
@@ -21,6 +21,23 @@ config QCOM_GSBI
           functions for connecting the underlying serial UART, SPI, and I2C
           devices to the output pins.
 
+config QCOM_LLCC
+	tristate "Qualcomm Technologies, Inc. LLCC driver"
+	depends on ARCH_QCOM
+	help
+	  Qualcomm Technologies, Inc. platform specific
+	  Last Level Cache Controller(LLCC) driver. This provides interfaces
+	  to client's that use the LLCC. Say yes here to enable LLCC slice
+	  driver.
+
+config QCOM_SDM845_LLCC
+	tristate "Qualcomm Technologies, Inc. SDM845 LLCC driver"
+	depends on QCOM_LLCC
+	help
+	  Say yes here to enable the LLCC driver for SDM845. This provides
+	  data required to configure LLCC so that clients can start using the
+	  LLCC slices.
+
 config QCOM_MDT_LOADER
 	tristate
 	select QCOM_SCM
drivers/soc/qcom/Makefile +2 -0
index dcebf28..e16d6a2 100644
@@ -12,3 +12,5 @@ obj-$(CONFIG_QCOM_SMEM_STATE) += smem_state.o
 obj-$(CONFIG_QCOM_SMP2P)	+= smp2p.o
 obj-$(CONFIG_QCOM_SMSM)	+= smsm.o
 obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o
+obj-$(CONFIG_QCOM_LLCC) += llcc-slice.o
+obj-$(CONFIG_QCOM_SDM845_LLCC) += llcc-sdm845.o
drivers/soc/qcom/llcc-sdm845.c new file +108 -0

108 lines not on this page · raw message

drivers/soc/qcom/llcc-slice.c new file +380 -0

380 lines not on this page · raw message

include/linux/soc/qcom/llcc-qcom.h new file +167 -0

167 lines not on this page · raw message

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project

#8 lore raw

Re: [PATCH v5 2/2] drivers: soc: Add LLCC driver

Quoted 5 lines · Rishabh Bhatnagar
drivers/soc/qcom/Kconfig +0 -0
index e050eb8..2b09321 100644

drivers/soc/qcom/Kconfig config QCOM_GSBI · line 30

Quoted 10 lines
drivers/soc/qcom/Kconfig +7 -0
@@ -21,6 +21,23 @@ config QCOM_GSBI
           functions for connecting the underlying serial UART, SPI, and I2C
           devices to the output pins.
 
+config QCOM_LLCC
+	tristate "Qualcomm Technologies, Inc. LLCC driver"
+	depends on ARCH_QCOM
+	help
+	  Qualcomm Technologies, Inc. platform specific
+	  Last Level Cache Controller(LLCC) driver. This provides interfaces
+	  to client's that use the LLCC. Say yes here to enable LLCC slice

to clients

Quoted 13 lines
drivers/soc/qcom/Kconfig +10 -0
+	  driver.
+
+config QCOM_SDM845_LLCC
+	tristate "Qualcomm Technologies, Inc. SDM845 LLCC driver"
+	depends on QCOM_LLCC
+	help
+	  Say yes here to enable the LLCC driver for SDM845. This provides
+	  data required to configure LLCC so that clients can start using the
+	  LLCC slices.
+
 config QCOM_MDT_LOADER
 	tristate
 	select QCOM_SCM
Signature · 1 line
~Randy
#9 lore raw

Re: [PATCH v5 2/2] drivers: soc: Add LLCC driver

In reply to Rishabh Bhatnagar

Hi Rishabh,

Quoted 8 lines · Rishabh Bhatnagar

LLCC (Last Level Cache Controller) provides additional cache memory in the system. LLCC is partitioned into multiple slices and each slice gets its own priority, size, ID and other config parameters. LLCC driver programs these parameters for each slice. Clients that are assigned to use LLCC need to get information such size & ID of the slice they get and activate or deactivate the slice as needed. LLCC driver provides API for the clients to perform these operations.

Quoted 7 lines
---
  drivers/soc/qcom/Kconfig           |  17 ++
  drivers/soc/qcom/Makefile          |   2 +
  drivers/soc/qcom/llcc-sdm845.c     | 108 +++++++++++
  drivers/soc/qcom/llcc-slice.c      | 380

+++++++++++++++++++++++++++++++++++++

Quoted 5 lines
  include/linux/soc/qcom/llcc-qcom.h | 167 ++++++++++++++++
  5 files changed, 674 insertions(+)

create mode 100644 drivers/soc/qcom/llcc-sdm845.c create mode 100644 drivers/soc/qcom/llcc-slice.c create mode 100644 include/linux/soc/qcom/llcc-qcom.h

...

Quoted 25 lines
drivers/soc/qcom/llcc-slice.c new file +19 -0
new file mode 100644
index 0000000..fd2b607
@@ -0,0 +1,380 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ *
+ */
+
+#include <linux/bitmap.h>
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/soc/qcom/llcc-qcom.h>
+
+#define ACTIVATE                      0x1
+#define DEACTIVATE                    0x2

drivers/soc/qcom/llcc-slice.c line 29

Quoted 10 lines
drivers/soc/qcom/llcc-slice.c new file +10 -0
+#define ACT_CTRL_OPCODE_ACTIVATE      0x1
+#define ACT_CTRL_OPCODE_DEACTIVATE    0x2
+#define ACT_CTRL_ACT_TRIG             0x1
+#define ACT_CTRL_OPCODE_SHIFT         0x1
+#define ATTR1_PROBE_TARGET_WAYS_SHIFT 0x2
+#define ATTR1_FIXED_SIZE_SHIFT        0x3
+#define ATTR1_PRIORITY_SHIFT          0x4
+#define ATTR1_MAX_CAP_SHIFT           0x10
+#define ATTR0_RES_WAYS_MASK           0x00000fff
+#define ATR0_BONUS_WAYS_MASK          0x0fff0000

This looks like it's missing a t, eg ATTR0_BONUS_WAYS_MASK.

Quoted 16 lines
drivers/soc/qcom/llcc-slice.c new file +16 -0
+#define ATTR0_BONUS_WAYS_SHIFT        0x10
+#define LLCC_STATUS_READ_DELAY 100
+
+#define CACHE_LINE_SIZE_SHIFT 6
+
+#define LLCC_COMMON_STATUS0            0x0003000c
+#define LLCC_LB_CNT_MASK               0xf0000000
+#define LLCC_LB_CNT_SHIFT              28
+
+#define MAX_CAP_TO_BYTES(n) (n * 1024)
+#define LLCC_TRP_ACT_CTRLn(n) (n * 0x1000)
+#define LLCC_TRP_STATUSn(n)   (4 + n * 0x1000)
+#define LLCC_TRP_ATTR0_CFGn(n) (0x21000 + 0x8 * n)
+#define LLCC_TRP_ATTR1_CFGn(n) (0x21004 + 0x8 * n)
+
+#define BANK_OFFSET_STRIDE     0x80000

drivers/soc/qcom/llcc-slice.c

Quoted 10 lines
drivers/soc/qcom/llcc-slice.c new file +10 -0
+
+static const struct regmap_config llcc_regmap_config = {
+       .reg_bits = 32,
+       .reg_stride = 4,
+       .val_bits = 32,
+       .fast_io = true,
+};
+
+/* Get the slice entry by index */
+static struct llcc_slice_desc *llcc_slice_get_entry(struct device *dev,

int n)

Quoted 9 lines
drivers/soc/qcom/llcc-slice.c new file +9 -0
+{
+       struct of_phandle_args phargs;
+       struct llcc_drv_data *drv;
+       const struct llcc_slice_config *llcc_data_ptr;
+       struct llcc_slice_desc *desc;
+       struct platform_device *pdev;
+       u32 sz, count;
+
+       if (of_parse_phandle_with_args(dev->of_node, "cache-slices",

drivers/soc/qcom/llcc-slice.c line 74

Quoted 10 lines
drivers/soc/qcom/llcc-slice.c new file +10 -0
+                                      "#cache-cells", n, &phargs))
+               return ERR_PTR(-ENODEV);
+
+       pdev = of_find_device_by_node(phargs.np);
+       if (!pdev)
+               return ERR_PTR(-ENODEV);
+
+       drv = platform_get_drvdata(pdev);
+       if (!drv)
+               return ERR_PTR(-EFAULT);

EFAULT is a little weird here, right? Maybe EINVAL or ENODEV?

Quoted 25 lines
drivers/soc/qcom/llcc-slice.c new file +25 -0
+
+       llcc_data_ptr = drv->cfg;
+       sz = drv->cfg_size;
+       count = 0;
+
+       while (llcc_data_ptr && count < sz) {
+               if (llcc_data_ptr->usecase_id == phargs.args[0])
+                       break;
+               llcc_data_ptr++;
+               count++;
+       }
+
+       if (llcc_data_ptr == NULL || count == sz)
+               return ERR_PTR(-ENODEV);
+
+       desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
+       if (!desc)
+               return ERR_PTR(-ENOMEM);
+
+       desc->slice_id = llcc_data_ptr->slice_id;
+       desc->slice_size = llcc_data_ptr->max_cap;
+       desc->dev = &pdev->dev;
+
+       return desc;
+}

drivers/soc/qcom/llcc-slice.c

Quoted 10 lines
drivers/soc/qcom/llcc-slice.c new file +10 -0
+
+/**
+ * llcc_slice_getd - get llcc slice descriptor
+ * @dev: Device pointer of the client
+ * @name: Name of the use case
+ *
+ * A pointer to llcc slice descriptor will be returned on success and
+ * and error pointer is returned on failure
+ */
+struct llcc_slice_desc *llcc_slice_getd(struct device *dev, const char

*name)

drivers/soc/qcom/llcc-slice.c

Quoted 10 lines
drivers/soc/qcom/llcc-slice.c new file +10 -0
+{
+       struct device_node *np = dev->of_node;
+       int index = 0;
+       const char *slice_name;
+       struct property *prop;
+
+       if (!of_get_property(np, "cache-slice-names", NULL))
+               return ERR_PTR(-ENOENT);
+
+       of_property_for_each_string(np, "cache-slice-names", prop,

slice_name) {

Quoted 32 lines
drivers/soc/qcom/llcc-slice.c new file +32 -0
+               if (!strcmp(name, slice_name))
+                       break;
+               index++;
+       }
+       return llcc_slice_get_entry(dev, index);
+}
+EXPORT_SYMBOL_GPL(llcc_slice_getd);
+
+/**
+ * llcc_slice_putd - llcc slice descritpor
+ * @desc: Pointer to llcc slice descriptor
+ */
+void llcc_slice_putd(struct llcc_slice_desc *desc)
+{
+       devm_kfree(desc->dev, desc);
+}
+EXPORT_SYMBOL_GPL(llcc_slice_putd);
+
+static int llcc_update_act_ctrl(struct llcc_drv_data *drv, u32 sid,
+                               u32 act_ctrl_reg_val, u32 status)
+{
+       u32 act_ctrl_reg;
+       u32 status_reg;
+       u32 slice_status;
+       int ret = 0;
+
+       act_ctrl_reg = drv->bcast_off + LLCC_TRP_ACT_CTRLn(sid);
+       status_reg = drv->bcast_off + LLCC_TRP_STATUSn(sid);
+
+       /* Set the ACTIVE trigger */
+       act_ctrl_reg_val |= ACT_CTRL_ACT_TRIG;
+       ret = regmap_write(drv->regmap, act_ctrl_reg, act_ctrl_reg_val);

drivers/soc/qcom/llcc-slice.c

Quoted 10 lines
drivers/soc/qcom/llcc-slice.c new file +10 -0
+       if (ret)
+               return ret;
+
+       /* Clear the ACTIVE trigger */
+       act_ctrl_reg_val &= ~ACT_CTRL_ACT_TRIG;
+       ret = regmap_write(drv->regmap, act_ctrl_reg, act_ctrl_reg_val);
+       if (ret)
+               return ret;
+
+       ret = regmap_read_poll_timeout(drv->regmap, status_reg,

slice_status,

drivers/soc/qcom/llcc-slice.c line 162

Quoted 1 line
drivers/soc/qcom/llcc-slice.c new file +1 -0
+                       !(slice_status & status), 0,

LLCC_STATUS_READ_DELAY);

Quoted 22 lines
drivers/soc/qcom/llcc-slice.c new file +22 -0
+       return ret;
+}
+
+/**
+ * llcc_slice_activate - Activate the llcc slice
+ * @desc: Pointer to llcc slice descriptor
+ *
+ * A value of zero will be returned on success and a negative errno will
+ * be returned in error cases
+ */
+int llcc_slice_activate(struct llcc_slice_desc *desc)
+{
+       int ret;
+       u32 act_ctrl_val;
+       struct llcc_drv_data *drv;
+
+       drv = dev_get_drvdata(desc->dev);
+       if (!drv)
+               return -EINVAL;
+
+       mutex_lock(&drv->lock);
+       if (test_bit(desc->slice_id, drv->bitmap)) {

drivers/soc/qcom/llcc-slice.c line 194

Quoted 10 lines
drivers/soc/qcom/llcc-slice.c new file +10 -0
+               mutex_unlock(&drv->lock);
+               return 0;
+       }
+
+       act_ctrl_val = ACT_CTRL_OPCODE_ACTIVATE << ACT_CTRL_OPCODE_SHIFT;
+
+       ret = llcc_update_act_ctrl(drv, desc->slice_id, act_ctrl_val,
+                                 DEACTIVATE);
+
+       __set_bit(desc->slice_id, drv->bitmap);

If llcc_update_act_ctrl fails, your bitmap will become out of sync with reality, and future calls to llcc_slice activate will return immediately. Perhaps you should only set the bit if ret is zero.

Quoted 19 lines
drivers/soc/qcom/llcc-slice.c new file +19 -0
+       mutex_unlock(&drv->lock);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(llcc_slice_activate);
+
+/**
+ * llcc_slice_deactivate - Deactivate the llcc slice
+ * @desc: Pointer to llcc slice descriptor
+ *
+ * A value of zero will be returned on success and a negative errno will
+ * be returned in error cases
+ */
+int llcc_slice_deactivate(struct llcc_slice_desc *desc)
+{
+       u32 act_ctrl_val;
+       int ret;
+       struct llcc_drv_data *drv;
+

drivers/soc/qcom/llcc-slice.c

Quoted 10 lines
drivers/soc/qcom/llcc-slice.c new file +10 -0
+       drv = dev_get_drvdata(desc->dev);
+       if (!drv)
+               return -EINVAL;
+
+       mutex_lock(&drv->lock);
+       if (!test_bit(desc->slice_id, drv->bitmap)) {
+               mutex_unlock(&drv->lock);
+               return 0;
+       }
+       act_ctrl_val = ACT_CTRL_OPCODE_DEACTIVATE <<

ACT_CTRL_OPCODE_SHIFT;

drivers/soc/qcom/llcc-slice.c line 228

Quoted 5 lines
drivers/soc/qcom/llcc-slice.c new file +5 -0
+
+       ret = llcc_update_act_ctrl(drv, desc->slice_id, act_ctrl_val,
+                                 ACTIVATE);
+
+       __clear_bit(desc->slice_id, drv->bitmap);

Conversely, only clear the bit if ret was zero.

If you fix these issues, then feel free to add my Reviewed-by to the next spin of this patch.
-Evan