1320 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Driver for the HiSilicon SEC units found on Hip06 Hip074 *5 * Copyright (c) 2016-2017 HiSilicon Limited.6 */7#include <linux/acpi.h>8#include <linux/atomic.h>9#include <linux/delay.h>10#include <linux/dma-direction.h>11#include <linux/dma-mapping.h>12#include <linux/dmapool.h>13#include <linux/io.h>14#include <linux/iommu.h>15#include <linux/interrupt.h>16#include <linux/irq.h>17#include <linux/irqreturn.h>18#include <linux/mm.h>19#include <linux/module.h>20#include <linux/of.h>21#include <linux/platform_device.h>22#include <linux/slab.h>23 24#include "sec_drv.h"25 26#define SEC_QUEUE_AR_FROCE_ALLOC 027#define SEC_QUEUE_AR_FROCE_NOALLOC 128#define SEC_QUEUE_AR_FROCE_DIS 229 30#define SEC_QUEUE_AW_FROCE_ALLOC 031#define SEC_QUEUE_AW_FROCE_NOALLOC 132#define SEC_QUEUE_AW_FROCE_DIS 233 34/* SEC_ALGSUB registers */35#define SEC_ALGSUB_CLK_EN_REG 0x03b836#define SEC_ALGSUB_CLK_DIS_REG 0x03bc37#define SEC_ALGSUB_CLK_ST_REG 0x535c38#define SEC_ALGSUB_RST_REQ_REG 0x0aa839#define SEC_ALGSUB_RST_DREQ_REG 0x0aac40#define SEC_ALGSUB_RST_ST_REG 0x5a5441#define SEC_ALGSUB_RST_ST_IS_RST BIT(0)42 43#define SEC_ALGSUB_BUILD_RST_REQ_REG 0x0ab844#define SEC_ALGSUB_BUILD_RST_DREQ_REG 0x0abc45#define SEC_ALGSUB_BUILD_RST_ST_REG 0x5a5c46#define SEC_ALGSUB_BUILD_RST_ST_IS_RST BIT(0)47 48#define SEC_SAA_BASE 0x00001000UL49 50/* SEC_SAA registers */51#define SEC_SAA_CTRL_REG(x) ((x) * SEC_SAA_ADDR_SIZE)52#define SEC_SAA_CTRL_GET_QM_EN BIT(0)53 54#define SEC_ST_INTMSK1_REG 0x020055#define SEC_ST_RINT1_REG 0x040056#define SEC_ST_INTSTS1_REG 0x060057#define SEC_BD_MNG_STAT_REG 0x080058#define SEC_PARSING_STAT_REG 0x080459#define SEC_LOAD_TIME_OUT_CNT_REG 0x080860#define SEC_CORE_WORK_TIME_OUT_CNT_REG 0x080c61#define SEC_BACK_TIME_OUT_CNT_REG 0x081062#define SEC_BD1_PARSING_RD_TIME_OUT_CNT_REG 0x081463#define SEC_BD1_PARSING_WR_TIME_OUT_CNT_REG 0x081864#define SEC_BD2_PARSING_RD_TIME_OUT_CNT_REG 0x081c65#define SEC_BD2_PARSING_WR_TIME_OUT_CNT_REG 0x082066#define SEC_SAA_ACC_REG 0x083c67#define SEC_BD_NUM_CNT_IN_SEC_REG 0x085868#define SEC_LOAD_WORK_TIME_CNT_REG 0x086069#define SEC_CORE_WORK_WORK_TIME_CNT_REG 0x086470#define SEC_BACK_WORK_TIME_CNT_REG 0x086871#define SEC_SAA_IDLE_TIME_CNT_REG 0x086c72#define SEC_SAA_CLK_CNT_REG 0x087073 74/* SEC_COMMON registers */75#define SEC_CLK_EN_REG 0x000076#define SEC_CTRL_REG 0x000477 78#define SEC_COMMON_CNT_CLR_CE_REG 0x000879#define SEC_COMMON_CNT_CLR_CE_CLEAR BIT(0)80#define SEC_COMMON_CNT_CLR_CE_SNAP_EN BIT(1)81 82#define SEC_SECURE_CTRL_REG 0x000c83#define SEC_AXI_CACHE_CFG_REG 0x001084#define SEC_AXI_QOS_CFG_REG 0x001485#define SEC_IPV4_MASK_TABLE_REG 0x002086#define SEC_IPV6_MASK_TABLE_X_REG(x) (0x0024 + (x) * 4)87#define SEC_FSM_MAX_CNT_REG 0x006488 89#define SEC_CTRL2_REG 0x006890#define SEC_CTRL2_DATA_AXI_RD_OTSD_CFG_M GENMASK(3, 0)91#define SEC_CTRL2_DATA_AXI_RD_OTSD_CFG_S 092#define SEC_CTRL2_DATA_AXI_WR_OTSD_CFG_M GENMASK(6, 4)93#define SEC_CTRL2_DATA_AXI_WR_OTSD_CFG_S 494#define SEC_CTRL2_CLK_GATE_EN BIT(7)95#define SEC_CTRL2_ENDIAN_BD BIT(8)96#define SEC_CTRL2_ENDIAN_BD_TYPE BIT(9)97 98#define SEC_CNT_PRECISION_CFG_REG 0x006c99#define SEC_DEBUG_BD_CFG_REG 0x0070100#define SEC_DEBUG_BD_CFG_WB_NORMAL BIT(0)101#define SEC_DEBUG_BD_CFG_WB_EN BIT(1)102 103#define SEC_Q_SIGHT_SEL 0x0074104#define SEC_Q_SIGHT_HIS_CLR 0x0078105#define SEC_Q_VMID_CFG_REG(q) (0x0100 + (q) * 4)106#define SEC_Q_WEIGHT_CFG_REG(q) (0x200 + (q) * 4)107#define SEC_STAT_CLR_REG 0x0a00108#define SEC_SAA_IDLE_CNT_CLR_REG 0x0a04109#define SEC_QM_CPL_Q_IDBUF_DFX_CFG_REG 0x0b00110#define SEC_QM_CPL_Q_IDBUF_DFX_RESULT_REG 0x0b04111#define SEC_QM_BD_DFX_CFG_REG 0x0b08112#define SEC_QM_BD_DFX_RESULT_REG 0x0b0c113#define SEC_QM_BDID_DFX_RESULT_REG 0x0b10114#define SEC_QM_BD_DFIFO_STATUS_REG 0x0b14115#define SEC_QM_BD_DFX_CFG2_REG 0x0b1c116#define SEC_QM_BD_DFX_RESULT2_REG 0x0b20117#define SEC_QM_BD_IDFIFO_STATUS_REG 0x0b18118#define SEC_QM_BD_DFIFO_STATUS2_REG 0x0b28119#define SEC_QM_BD_IDFIFO_STATUS2_REG 0x0b2c120 121#define SEC_HASH_IPV4_MASK 0xfff00000122#define SEC_MAX_SAA_NUM 0xa123#define SEC_SAA_ADDR_SIZE 0x1000124 125#define SEC_Q_INIT_REG 0x0126#define SEC_Q_INIT_WO_STAT_CLEAR 0x2127#define SEC_Q_INIT_AND_STAT_CLEAR 0x3128 129#define SEC_Q_CFG_REG 0x8130#define SEC_Q_CFG_REORDER BIT(0)131 132#define SEC_Q_PROC_NUM_CFG_REG 0x10133#define SEC_QUEUE_ENB_REG 0x18134 135#define SEC_Q_DEPTH_CFG_REG 0x50136#define SEC_Q_DEPTH_CFG_DEPTH_M GENMASK(11, 0)137#define SEC_Q_DEPTH_CFG_DEPTH_S 0138 139#define SEC_Q_BASE_HADDR_REG 0x54140#define SEC_Q_BASE_LADDR_REG 0x58141#define SEC_Q_WR_PTR_REG 0x5c142#define SEC_Q_OUTORDER_BASE_HADDR_REG 0x60143#define SEC_Q_OUTORDER_BASE_LADDR_REG 0x64144#define SEC_Q_OUTORDER_RD_PTR_REG 0x68145#define SEC_Q_OT_TH_REG 0x6c146 147#define SEC_Q_ARUSER_CFG_REG 0x70148#define SEC_Q_ARUSER_CFG_FA BIT(0)149#define SEC_Q_ARUSER_CFG_FNA BIT(1)150#define SEC_Q_ARUSER_CFG_RINVLD BIT(2)151#define SEC_Q_ARUSER_CFG_PKG BIT(3)152 153#define SEC_Q_AWUSER_CFG_REG 0x74154#define SEC_Q_AWUSER_CFG_FA BIT(0)155#define SEC_Q_AWUSER_CFG_FNA BIT(1)156#define SEC_Q_AWUSER_CFG_PKG BIT(2)157 158#define SEC_Q_ERR_BASE_HADDR_REG 0x7c159#define SEC_Q_ERR_BASE_LADDR_REG 0x80160#define SEC_Q_CFG_VF_NUM_REG 0x84161#define SEC_Q_SOFT_PROC_PTR_REG 0x88162#define SEC_Q_FAIL_INT_MSK_REG 0x300163#define SEC_Q_FLOW_INT_MKS_REG 0x304164#define SEC_Q_FAIL_RINT_REG 0x400165#define SEC_Q_FLOW_RINT_REG 0x404166#define SEC_Q_FAIL_INT_STATUS_REG 0x500167#define SEC_Q_FLOW_INT_STATUS_REG 0x504168#define SEC_Q_STATUS_REG 0x600169#define SEC_Q_RD_PTR_REG 0x604170#define SEC_Q_PRO_PTR_REG 0x608171#define SEC_Q_OUTORDER_WR_PTR_REG 0x60c172#define SEC_Q_OT_CNT_STATUS_REG 0x610173#define SEC_Q_INORDER_BD_NUM_ST_REG 0x650174#define SEC_Q_INORDER_GET_FLAG_ST_REG 0x654175#define SEC_Q_INORDER_ADD_FLAG_ST_REG 0x658176#define SEC_Q_INORDER_TASK_INT_NUM_LEFT_ST_REG 0x65c177#define SEC_Q_RD_DONE_PTR_REG 0x660178#define SEC_Q_CPL_Q_BD_NUM_ST_REG 0x700179#define SEC_Q_CPL_Q_PTR_ST_REG 0x704180#define SEC_Q_CPL_Q_H_ADDR_ST_REG 0x708181#define SEC_Q_CPL_Q_L_ADDR_ST_REG 0x70c182#define SEC_Q_CPL_TASK_INT_NUM_LEFT_ST_REG 0x710183#define SEC_Q_WRR_ID_CHECK_REG 0x714184#define SEC_Q_CPLQ_FULL_CHECK_REG 0x718185#define SEC_Q_SUCCESS_BD_CNT_REG 0x800186#define SEC_Q_FAIL_BD_CNT_REG 0x804187#define SEC_Q_GET_BD_CNT_REG 0x808188#define SEC_Q_IVLD_CNT_REG 0x80c189#define SEC_Q_BD_PROC_GET_CNT_REG 0x810190#define SEC_Q_BD_PROC_DONE_CNT_REG 0x814191#define SEC_Q_LAT_CLR_REG 0x850192#define SEC_Q_PKT_LAT_MAX_REG 0x854193#define SEC_Q_PKT_LAT_AVG_REG 0x858194#define SEC_Q_PKT_LAT_MIN_REG 0x85c195#define SEC_Q_ID_CLR_CFG_REG 0x900196#define SEC_Q_1ST_BD_ERR_ID_REG 0x904197#define SEC_Q_1ST_AUTH_FAIL_ID_REG 0x908198#define SEC_Q_1ST_RD_ERR_ID_REG 0x90c199#define SEC_Q_1ST_ECC2_ERR_ID_REG 0x910200#define SEC_Q_1ST_IVLD_ID_REG 0x914201#define SEC_Q_1ST_BD_WR_ERR_ID_REG 0x918202#define SEC_Q_1ST_ERR_BD_WR_ERR_ID_REG 0x91c203#define SEC_Q_1ST_BD_MAC_WR_ERR_ID_REG 0x920204 205struct sec_debug_bd_info {206#define SEC_DEBUG_BD_INFO_SOFT_ERR_CHECK_M GENMASK(22, 0)207 u32 soft_err_check;208#define SEC_DEBUG_BD_INFO_HARD_ERR_CHECK_M GENMASK(9, 0)209 u32 hard_err_check;210 u32 icv_mac1st_word;211#define SEC_DEBUG_BD_INFO_GET_ID_M GENMASK(19, 0)212 u32 sec_get_id;213 /* W4---W15 */214 u32 reserv_left[12];215};216 217struct sec_out_bd_info {218#define SEC_OUT_BD_INFO_Q_ID_M GENMASK(11, 0)219#define SEC_OUT_BD_INFO_ECC_2BIT_ERR BIT(14)220 u16 data;221};222 223#define SEC_MAX_DEVICES 8224static struct sec_dev_info *sec_devices[SEC_MAX_DEVICES];225static DEFINE_MUTEX(sec_id_lock);226 227static int sec_queue_map_io(struct sec_queue *queue)228{229 struct device *dev = queue->dev_info->dev;230 struct resource *res;231 232 res = platform_get_resource(to_platform_device(dev),233 IORESOURCE_MEM,234 2 + queue->queue_id);235 if (!res) {236 dev_err(dev, "Failed to get queue %u memory resource\n",237 queue->queue_id);238 return -ENOMEM;239 }240 queue->regs = ioremap(res->start, resource_size(res));241 if (!queue->regs)242 return -ENOMEM;243 244 return 0;245}246 247static void sec_queue_unmap_io(struct sec_queue *queue)248{249 iounmap(queue->regs);250}251 252static int sec_queue_ar_pkgattr(struct sec_queue *queue, u32 ar_pkg)253{254 void __iomem *addr = queue->regs + SEC_Q_ARUSER_CFG_REG;255 u32 regval;256 257 regval = readl_relaxed(addr);258 if (ar_pkg)259 regval |= SEC_Q_ARUSER_CFG_PKG;260 else261 regval &= ~SEC_Q_ARUSER_CFG_PKG;262 writel_relaxed(regval, addr);263 264 return 0;265}266 267static int sec_queue_aw_pkgattr(struct sec_queue *queue, u32 aw_pkg)268{269 void __iomem *addr = queue->regs + SEC_Q_AWUSER_CFG_REG;270 u32 regval;271 272 regval = readl_relaxed(addr);273 regval |= SEC_Q_AWUSER_CFG_PKG;274 writel_relaxed(regval, addr);275 276 return 0;277}278 279static int sec_clk_en(struct sec_dev_info *info)280{281 void __iomem *base = info->regs[SEC_COMMON];282 u32 i = 0;283 284 writel_relaxed(0x7, base + SEC_ALGSUB_CLK_EN_REG);285 do {286 usleep_range(1000, 10000);287 if ((readl_relaxed(base + SEC_ALGSUB_CLK_ST_REG) & 0x7) == 0x7)288 return 0;289 i++;290 } while (i < 10);291 dev_err(info->dev, "sec clock enable fail!\n");292 293 return -EIO;294}295 296static int sec_clk_dis(struct sec_dev_info *info)297{298 void __iomem *base = info->regs[SEC_COMMON];299 u32 i = 0;300 301 writel_relaxed(0x7, base + SEC_ALGSUB_CLK_DIS_REG);302 do {303 usleep_range(1000, 10000);304 if ((readl_relaxed(base + SEC_ALGSUB_CLK_ST_REG) & 0x7) == 0)305 return 0;306 i++;307 } while (i < 10);308 dev_err(info->dev, "sec clock disable fail!\n");309 310 return -EIO;311}312 313static int sec_reset_whole_module(struct sec_dev_info *info)314{315 void __iomem *base = info->regs[SEC_COMMON];316 bool is_reset, b_is_reset;317 u32 i = 0;318 319 writel_relaxed(1, base + SEC_ALGSUB_RST_REQ_REG);320 writel_relaxed(1, base + SEC_ALGSUB_BUILD_RST_REQ_REG);321 while (1) {322 usleep_range(1000, 10000);323 is_reset = readl_relaxed(base + SEC_ALGSUB_RST_ST_REG) &324 SEC_ALGSUB_RST_ST_IS_RST;325 b_is_reset = readl_relaxed(base + SEC_ALGSUB_BUILD_RST_ST_REG) &326 SEC_ALGSUB_BUILD_RST_ST_IS_RST;327 if (is_reset && b_is_reset)328 break;329 i++;330 if (i > 10) {331 dev_err(info->dev, "Reset req failed\n");332 return -EIO;333 }334 }335 336 i = 0;337 writel_relaxed(1, base + SEC_ALGSUB_RST_DREQ_REG);338 writel_relaxed(1, base + SEC_ALGSUB_BUILD_RST_DREQ_REG);339 while (1) {340 usleep_range(1000, 10000);341 is_reset = readl_relaxed(base + SEC_ALGSUB_RST_ST_REG) &342 SEC_ALGSUB_RST_ST_IS_RST;343 b_is_reset = readl_relaxed(base + SEC_ALGSUB_BUILD_RST_ST_REG) &344 SEC_ALGSUB_BUILD_RST_ST_IS_RST;345 if (!is_reset && !b_is_reset)346 break;347 348 i++;349 if (i > 10) {350 dev_err(info->dev, "Reset dreq failed\n");351 return -EIO;352 }353 }354 355 return 0;356}357 358static void sec_bd_endian_little(struct sec_dev_info *info)359{360 void __iomem *addr = info->regs[SEC_SAA] + SEC_CTRL2_REG;361 u32 regval;362 363 regval = readl_relaxed(addr);364 regval &= ~(SEC_CTRL2_ENDIAN_BD | SEC_CTRL2_ENDIAN_BD_TYPE);365 writel_relaxed(regval, addr);366}367 368/*369 * sec_cache_config - configure optimum cache placement370 */371static void sec_cache_config(struct sec_dev_info *info)372{373 struct iommu_domain *domain;374 void __iomem *addr = info->regs[SEC_SAA] + SEC_CTRL_REG;375 376 domain = iommu_get_domain_for_dev(info->dev);377 378 /* Check that translation is occurring */379 if (domain && (domain->type & __IOMMU_DOMAIN_PAGING))380 writel_relaxed(0x44cf9e, addr);381 else382 writel_relaxed(0x4cfd9, addr);383}384 385static void sec_data_axiwr_otsd_cfg(struct sec_dev_info *info, u32 cfg)386{387 void __iomem *addr = info->regs[SEC_SAA] + SEC_CTRL2_REG;388 u32 regval;389 390 regval = readl_relaxed(addr);391 regval &= ~SEC_CTRL2_DATA_AXI_WR_OTSD_CFG_M;392 regval |= (cfg << SEC_CTRL2_DATA_AXI_WR_OTSD_CFG_S) &393 SEC_CTRL2_DATA_AXI_WR_OTSD_CFG_M;394 writel_relaxed(regval, addr);395}396 397static void sec_data_axird_otsd_cfg(struct sec_dev_info *info, u32 cfg)398{399 void __iomem *addr = info->regs[SEC_SAA] + SEC_CTRL2_REG;400 u32 regval;401 402 regval = readl_relaxed(addr);403 regval &= ~SEC_CTRL2_DATA_AXI_RD_OTSD_CFG_M;404 regval |= (cfg << SEC_CTRL2_DATA_AXI_RD_OTSD_CFG_S) &405 SEC_CTRL2_DATA_AXI_RD_OTSD_CFG_M;406 writel_relaxed(regval, addr);407}408 409static void sec_clk_gate_en(struct sec_dev_info *info, bool clkgate)410{411 void __iomem *addr = info->regs[SEC_SAA] + SEC_CTRL2_REG;412 u32 regval;413 414 regval = readl_relaxed(addr);415 if (clkgate)416 regval |= SEC_CTRL2_CLK_GATE_EN;417 else418 regval &= ~SEC_CTRL2_CLK_GATE_EN;419 writel_relaxed(regval, addr);420}421 422static void sec_comm_cnt_cfg(struct sec_dev_info *info, bool clr_ce)423{424 void __iomem *addr = info->regs[SEC_SAA] + SEC_COMMON_CNT_CLR_CE_REG;425 u32 regval;426 427 regval = readl_relaxed(addr);428 if (clr_ce)429 regval |= SEC_COMMON_CNT_CLR_CE_CLEAR;430 else431 regval &= ~SEC_COMMON_CNT_CLR_CE_CLEAR;432 writel_relaxed(regval, addr);433}434 435static void sec_commsnap_en(struct sec_dev_info *info, bool snap_en)436{437 void __iomem *addr = info->regs[SEC_SAA] + SEC_COMMON_CNT_CLR_CE_REG;438 u32 regval;439 440 regval = readl_relaxed(addr);441 if (snap_en)442 regval |= SEC_COMMON_CNT_CLR_CE_SNAP_EN;443 else444 regval &= ~SEC_COMMON_CNT_CLR_CE_SNAP_EN;445 writel_relaxed(regval, addr);446}447 448static void sec_ipv6_hashmask(struct sec_dev_info *info, u32 hash_mask[])449{450 void __iomem *base = info->regs[SEC_SAA];451 int i;452 453 for (i = 0; i < 10; i++)454 writel_relaxed(hash_mask[0],455 base + SEC_IPV6_MASK_TABLE_X_REG(i));456}457 458static int sec_ipv4_hashmask(struct sec_dev_info *info, u32 hash_mask)459{460 if (hash_mask & SEC_HASH_IPV4_MASK) {461 dev_err(info->dev, "Sec Ipv4 Hash Mask Input Error!\n");462 return -EINVAL;463 }464 465 writel_relaxed(hash_mask,466 info->regs[SEC_SAA] + SEC_IPV4_MASK_TABLE_REG);467 468 return 0;469}470 471static void sec_set_dbg_bd_cfg(struct sec_dev_info *info, u32 cfg)472{473 void __iomem *addr = info->regs[SEC_SAA] + SEC_DEBUG_BD_CFG_REG;474 u32 regval;475 476 regval = readl_relaxed(addr);477 /* Always disable write back of normal bd */478 regval &= ~SEC_DEBUG_BD_CFG_WB_NORMAL;479 480 if (cfg)481 regval &= ~SEC_DEBUG_BD_CFG_WB_EN;482 else483 regval |= SEC_DEBUG_BD_CFG_WB_EN;484 485 writel_relaxed(regval, addr);486}487 488static void sec_saa_getqm_en(struct sec_dev_info *info, u32 saa_indx, u32 en)489{490 void __iomem *addr = info->regs[SEC_SAA] + SEC_SAA_BASE +491 SEC_SAA_CTRL_REG(saa_indx);492 u32 regval;493 494 regval = readl_relaxed(addr);495 if (en)496 regval |= SEC_SAA_CTRL_GET_QM_EN;497 else498 regval &= ~SEC_SAA_CTRL_GET_QM_EN;499 writel_relaxed(regval, addr);500}501 502static void sec_saa_int_mask(struct sec_dev_info *info, u32 saa_indx,503 u32 saa_int_mask)504{505 writel_relaxed(saa_int_mask,506 info->regs[SEC_SAA] + SEC_SAA_BASE + SEC_ST_INTMSK1_REG +507 saa_indx * SEC_SAA_ADDR_SIZE);508}509 510static void sec_streamid(struct sec_dev_info *info, int i)511{512 #define SEC_SID 0x600513 #define SEC_VMID 0514 515 writel_relaxed((SEC_VMID | ((SEC_SID & 0xffff) << 8)),516 info->regs[SEC_SAA] + SEC_Q_VMID_CFG_REG(i));517}518 519static void sec_queue_ar_alloc(struct sec_queue *queue, u32 alloc)520{521 void __iomem *addr = queue->regs + SEC_Q_ARUSER_CFG_REG;522 u32 regval;523 524 regval = readl_relaxed(addr);525 if (alloc == SEC_QUEUE_AR_FROCE_ALLOC) {526 regval |= SEC_Q_ARUSER_CFG_FA;527 regval &= ~SEC_Q_ARUSER_CFG_FNA;528 } else {529 regval &= ~SEC_Q_ARUSER_CFG_FA;530 regval |= SEC_Q_ARUSER_CFG_FNA;531 }532 533 writel_relaxed(regval, addr);534}535 536static void sec_queue_aw_alloc(struct sec_queue *queue, u32 alloc)537{538 void __iomem *addr = queue->regs + SEC_Q_AWUSER_CFG_REG;539 u32 regval;540 541 regval = readl_relaxed(addr);542 if (alloc == SEC_QUEUE_AW_FROCE_ALLOC) {543 regval |= SEC_Q_AWUSER_CFG_FA;544 regval &= ~SEC_Q_AWUSER_CFG_FNA;545 } else {546 regval &= ~SEC_Q_AWUSER_CFG_FA;547 regval |= SEC_Q_AWUSER_CFG_FNA;548 }549 550 writel_relaxed(regval, addr);551}552 553static void sec_queue_reorder(struct sec_queue *queue, bool reorder)554{555 void __iomem *base = queue->regs;556 u32 regval;557 558 regval = readl_relaxed(base + SEC_Q_CFG_REG);559 if (reorder)560 regval |= SEC_Q_CFG_REORDER;561 else562 regval &= ~SEC_Q_CFG_REORDER;563 writel_relaxed(regval, base + SEC_Q_CFG_REG);564}565 566static void sec_queue_depth(struct sec_queue *queue, u32 depth)567{568 void __iomem *addr = queue->regs + SEC_Q_DEPTH_CFG_REG;569 u32 regval;570 571 regval = readl_relaxed(addr);572 regval &= ~SEC_Q_DEPTH_CFG_DEPTH_M;573 regval |= (depth << SEC_Q_DEPTH_CFG_DEPTH_S) & SEC_Q_DEPTH_CFG_DEPTH_M;574 575 writel_relaxed(regval, addr);576}577 578static void sec_queue_cmdbase_addr(struct sec_queue *queue, u64 addr)579{580 writel_relaxed(upper_32_bits(addr), queue->regs + SEC_Q_BASE_HADDR_REG);581 writel_relaxed(lower_32_bits(addr), queue->regs + SEC_Q_BASE_LADDR_REG);582}583 584static void sec_queue_outorder_addr(struct sec_queue *queue, u64 addr)585{586 writel_relaxed(upper_32_bits(addr),587 queue->regs + SEC_Q_OUTORDER_BASE_HADDR_REG);588 writel_relaxed(lower_32_bits(addr),589 queue->regs + SEC_Q_OUTORDER_BASE_LADDR_REG);590}591 592static void sec_queue_errbase_addr(struct sec_queue *queue, u64 addr)593{594 writel_relaxed(upper_32_bits(addr),595 queue->regs + SEC_Q_ERR_BASE_HADDR_REG);596 writel_relaxed(lower_32_bits(addr),597 queue->regs + SEC_Q_ERR_BASE_LADDR_REG);598}599 600static void sec_queue_irq_disable(struct sec_queue *queue)601{602 writel_relaxed((u32)~0, queue->regs + SEC_Q_FLOW_INT_MKS_REG);603}604 605static void sec_queue_irq_enable(struct sec_queue *queue)606{607 writel_relaxed(0, queue->regs + SEC_Q_FLOW_INT_MKS_REG);608}609 610static void sec_queue_abn_irq_disable(struct sec_queue *queue)611{612 writel_relaxed((u32)~0, queue->regs + SEC_Q_FAIL_INT_MSK_REG);613}614 615static void sec_queue_stop(struct sec_queue *queue)616{617 disable_irq(queue->task_irq);618 sec_queue_irq_disable(queue);619 writel_relaxed(0x0, queue->regs + SEC_QUEUE_ENB_REG);620}621 622static void sec_queue_start(struct sec_queue *queue)623{624 sec_queue_irq_enable(queue);625 enable_irq(queue->task_irq);626 queue->expected = 0;627 writel_relaxed(SEC_Q_INIT_AND_STAT_CLEAR, queue->regs + SEC_Q_INIT_REG);628 writel_relaxed(0x1, queue->regs + SEC_QUEUE_ENB_REG);629}630 631static struct sec_queue *sec_alloc_queue(struct sec_dev_info *info)632{633 int i;634 635 mutex_lock(&info->dev_lock);636 637 /* Get the first idle queue in SEC device */638 for (i = 0; i < SEC_Q_NUM; i++)639 if (!info->queues[i].in_use) {640 info->queues[i].in_use = true;641 info->queues_in_use++;642 mutex_unlock(&info->dev_lock);643 644 return &info->queues[i];645 }646 mutex_unlock(&info->dev_lock);647 648 return ERR_PTR(-ENODEV);649}650 651static int sec_queue_free(struct sec_queue *queue)652{653 struct sec_dev_info *info = queue->dev_info;654 655 if (queue->queue_id >= SEC_Q_NUM) {656 dev_err(info->dev, "No queue %u\n", queue->queue_id);657 return -ENODEV;658 }659 660 if (!queue->in_use) {661 dev_err(info->dev, "Queue %u is idle\n", queue->queue_id);662 return -ENODEV;663 }664 665 mutex_lock(&info->dev_lock);666 queue->in_use = false;667 info->queues_in_use--;668 mutex_unlock(&info->dev_lock);669 670 return 0;671}672 673static irqreturn_t sec_isr_handle_th(int irq, void *q)674{675 sec_queue_irq_disable(q);676 return IRQ_WAKE_THREAD;677}678 679static irqreturn_t sec_isr_handle(int irq, void *q)680{681 struct sec_queue *queue = q;682 struct sec_queue_ring_cmd *msg_ring = &queue->ring_cmd;683 struct sec_queue_ring_cq *cq_ring = &queue->ring_cq;684 struct sec_out_bd_info *outorder_msg;685 struct sec_bd_info *msg;686 u32 ooo_read, ooo_write;687 void __iomem *base = queue->regs;688 int q_id;689 690 ooo_read = readl(base + SEC_Q_OUTORDER_RD_PTR_REG);691 ooo_write = readl(base + SEC_Q_OUTORDER_WR_PTR_REG);692 outorder_msg = cq_ring->vaddr + ooo_read;693 q_id = outorder_msg->data & SEC_OUT_BD_INFO_Q_ID_M;694 msg = msg_ring->vaddr + q_id;695 696 while ((ooo_write != ooo_read) && msg->w0 & SEC_BD_W0_DONE) {697 /*698 * Must be before callback otherwise blocks adding other chained699 * elements700 */701 set_bit(q_id, queue->unprocessed);702 if (q_id == queue->expected)703 while (test_bit(queue->expected, queue->unprocessed)) {704 clear_bit(queue->expected, queue->unprocessed);705 msg = msg_ring->vaddr + queue->expected;706 msg->w0 &= ~SEC_BD_W0_DONE;707 msg_ring->callback(msg,708 queue->shadow[queue->expected]);709 queue->shadow[queue->expected] = NULL;710 queue->expected = (queue->expected + 1) %711 SEC_QUEUE_LEN;712 atomic_dec(&msg_ring->used);713 }714 715 ooo_read = (ooo_read + 1) % SEC_QUEUE_LEN;716 writel(ooo_read, base + SEC_Q_OUTORDER_RD_PTR_REG);717 ooo_write = readl(base + SEC_Q_OUTORDER_WR_PTR_REG);718 outorder_msg = cq_ring->vaddr + ooo_read;719 q_id = outorder_msg->data & SEC_OUT_BD_INFO_Q_ID_M;720 msg = msg_ring->vaddr + q_id;721 }722 723 sec_queue_irq_enable(queue);724 725 return IRQ_HANDLED;726}727 728static int sec_queue_irq_init(struct sec_queue *queue)729{730 struct sec_dev_info *info = queue->dev_info;731 int irq = queue->task_irq;732 int ret;733 734 ret = request_threaded_irq(irq, sec_isr_handle_th, sec_isr_handle,735 IRQF_TRIGGER_RISING, queue->name, queue);736 if (ret) {737 dev_err(info->dev, "request irq(%d) failed %d\n", irq, ret);738 return ret;739 }740 disable_irq(irq);741 742 return 0;743}744 745static int sec_queue_irq_uninit(struct sec_queue *queue)746{747 free_irq(queue->task_irq, queue);748 749 return 0;750}751 752static struct sec_dev_info *sec_device_get(void)753{754 struct sec_dev_info *sec_dev = NULL;755 struct sec_dev_info *this_sec_dev;756 int least_busy_n = SEC_Q_NUM + 1;757 int i;758 759 /* Find which one is least busy and use that first */760 for (i = 0; i < SEC_MAX_DEVICES; i++) {761 this_sec_dev = sec_devices[i];762 if (this_sec_dev &&763 this_sec_dev->queues_in_use < least_busy_n) {764 least_busy_n = this_sec_dev->queues_in_use;765 sec_dev = this_sec_dev;766 }767 }768 769 return sec_dev;770}771 772static struct sec_queue *sec_queue_alloc_start(struct sec_dev_info *info)773{774 struct sec_queue *queue;775 776 queue = sec_alloc_queue(info);777 if (IS_ERR(queue)) {778 dev_err(info->dev, "alloc sec queue failed! %ld\n",779 PTR_ERR(queue));780 return queue;781 }782 783 sec_queue_start(queue);784 785 return queue;786}787 788/**789 * sec_queue_alloc_start_safe - get a hw queue from appropriate instance790 *791 * This function does extremely simplistic load balancing. It does not take into792 * account NUMA locality of the accelerator, or which cpu has requested the793 * queue. Future work may focus on optimizing this in order to improve full794 * machine throughput.795 */796struct sec_queue *sec_queue_alloc_start_safe(void)797{798 struct sec_dev_info *info;799 struct sec_queue *queue = ERR_PTR(-ENODEV);800 801 mutex_lock(&sec_id_lock);802 info = sec_device_get();803 if (!info)804 goto unlock;805 806 queue = sec_queue_alloc_start(info);807 808unlock:809 mutex_unlock(&sec_id_lock);810 811 return queue;812}813 814/**815 * sec_queue_stop_release() - free up a hw queue for reuse816 * @queue: The queue we are done with.817 *818 * This will stop the current queue, terminanting any transactions819 * that are inflight an return it to the pool of available hw queuess820 */821int sec_queue_stop_release(struct sec_queue *queue)822{823 struct device *dev = queue->dev_info->dev;824 int ret;825 826 sec_queue_stop(queue);827 828 ret = sec_queue_free(queue);829 if (ret)830 dev_err(dev, "Releasing queue failed %d\n", ret);831 832 return ret;833}834 835/**836 * sec_queue_empty() - Is this hardware queue currently empty.837 * @queue: The queue to test838 *839 * We need to know if we have an empty queue for some of the chaining modes840 * as if it is not empty we may need to hold the message in a software queue841 * until the hw queue is drained.842 */843bool sec_queue_empty(struct sec_queue *queue)844{845 struct sec_queue_ring_cmd *msg_ring = &queue->ring_cmd;846 847 return !atomic_read(&msg_ring->used);848}849 850/**851 * sec_queue_send() - queue up a single operation in the hw queue852 * @queue: The queue in which to put the message853 * @msg: The message854 * @ctx: Context to be put in the shadow array and passed back to cb on result.855 *856 * This function will return -EAGAIN if the queue is currently full.857 */858int sec_queue_send(struct sec_queue *queue, struct sec_bd_info *msg, void *ctx)859{860 struct sec_queue_ring_cmd *msg_ring = &queue->ring_cmd;861 void __iomem *base = queue->regs;862 u32 write, read;863 864 mutex_lock(&msg_ring->lock);865 read = readl(base + SEC_Q_RD_PTR_REG);866 write = readl(base + SEC_Q_WR_PTR_REG);867 if (write == read && atomic_read(&msg_ring->used) == SEC_QUEUE_LEN) {868 mutex_unlock(&msg_ring->lock);869 return -EAGAIN;870 }871 memcpy(msg_ring->vaddr + write, msg, sizeof(*msg));872 queue->shadow[write] = ctx;873 write = (write + 1) % SEC_QUEUE_LEN;874 875 /* Ensure content updated before queue advance */876 wmb();877 writel(write, base + SEC_Q_WR_PTR_REG);878 879 atomic_inc(&msg_ring->used);880 mutex_unlock(&msg_ring->lock);881 882 return 0;883}884 885bool sec_queue_can_enqueue(struct sec_queue *queue, int num)886{887 struct sec_queue_ring_cmd *msg_ring = &queue->ring_cmd;888 889 return SEC_QUEUE_LEN - atomic_read(&msg_ring->used) >= num;890}891 892static void sec_queue_hw_init(struct sec_queue *queue)893{894 sec_queue_ar_alloc(queue, SEC_QUEUE_AR_FROCE_NOALLOC);895 sec_queue_aw_alloc(queue, SEC_QUEUE_AW_FROCE_NOALLOC);896 sec_queue_ar_pkgattr(queue, 1);897 sec_queue_aw_pkgattr(queue, 1);898 899 /* Enable out of order queue */900 sec_queue_reorder(queue, true);901 902 /* Interrupt after a single complete element */903 writel_relaxed(1, queue->regs + SEC_Q_PROC_NUM_CFG_REG);904 905 sec_queue_depth(queue, SEC_QUEUE_LEN - 1);906 907 sec_queue_cmdbase_addr(queue, queue->ring_cmd.paddr);908 909 sec_queue_outorder_addr(queue, queue->ring_cq.paddr);910 911 sec_queue_errbase_addr(queue, queue->ring_db.paddr);912 913 writel_relaxed(0x100, queue->regs + SEC_Q_OT_TH_REG);914 915 sec_queue_abn_irq_disable(queue);916 sec_queue_irq_disable(queue);917 writel_relaxed(SEC_Q_INIT_AND_STAT_CLEAR, queue->regs + SEC_Q_INIT_REG);918}919 920static int sec_hw_init(struct sec_dev_info *info)921{922 struct iommu_domain *domain;923 u32 sec_ipv4_mask = 0;924 u32 sec_ipv6_mask[10] = {};925 u32 i, ret;926 927 domain = iommu_get_domain_for_dev(info->dev);928 929 /*930 * Enable all available processing unit clocks.931 * Only the first cluster is usable with translations.932 */933 if (domain && (domain->type & __IOMMU_DOMAIN_PAGING))934 info->num_saas = 5;935 936 else937 info->num_saas = 10;938 939 writel_relaxed(GENMASK(info->num_saas - 1, 0),940 info->regs[SEC_SAA] + SEC_CLK_EN_REG);941 942 /* 32 bit little endian */943 sec_bd_endian_little(info);944 945 sec_cache_config(info);946 947 /* Data axi port write and read outstanding config as per datasheet */948 sec_data_axiwr_otsd_cfg(info, 0x7);949 sec_data_axird_otsd_cfg(info, 0x7);950 951 /* Enable clock gating */952 sec_clk_gate_en(info, true);953 954 /* Set CNT_CYC register not read clear */955 sec_comm_cnt_cfg(info, false);956 957 /* Enable CNT_CYC */958 sec_commsnap_en(info, false);959 960 writel_relaxed((u32)~0, info->regs[SEC_SAA] + SEC_FSM_MAX_CNT_REG);961 962 ret = sec_ipv4_hashmask(info, sec_ipv4_mask);963 if (ret) {964 dev_err(info->dev, "Failed to set ipv4 hashmask %d\n", ret);965 return -EIO;966 }967 968 sec_ipv6_hashmask(info, sec_ipv6_mask);969 970 /* do not use debug bd */971 sec_set_dbg_bd_cfg(info, 0);972 973 if (domain && (domain->type & __IOMMU_DOMAIN_PAGING)) {974 for (i = 0; i < SEC_Q_NUM; i++) {975 sec_streamid(info, i);976 /* Same QoS for all queues */977 writel_relaxed(0x3f,978 info->regs[SEC_SAA] +979 SEC_Q_WEIGHT_CFG_REG(i));980 }981 }982 983 for (i = 0; i < info->num_saas; i++) {984 sec_saa_getqm_en(info, i, 1);985 sec_saa_int_mask(info, i, 0);986 }987 988 return 0;989}990 991static void sec_hw_exit(struct sec_dev_info *info)992{993 int i;994 995 for (i = 0; i < SEC_MAX_SAA_NUM; i++) {996 sec_saa_int_mask(info, i, (u32)~0);997 sec_saa_getqm_en(info, i, 0);998 }999}1000 1001static void sec_queue_base_init(struct sec_dev_info *info,1002 struct sec_queue *queue, int queue_id)1003{1004 queue->dev_info = info;1005 queue->queue_id = queue_id;1006 snprintf(queue->name, sizeof(queue->name),1007 "%s_%d", dev_name(info->dev), queue->queue_id);1008}1009 1010static int sec_map_io(struct sec_dev_info *info, struct platform_device *pdev)1011{1012 struct resource *res;1013 int i;1014 1015 for (i = 0; i < SEC_NUM_ADDR_REGIONS; i++) {1016 res = platform_get_resource(pdev, IORESOURCE_MEM, i);1017 1018 if (!res) {1019 dev_err(info->dev, "Memory resource %d not found\n", i);1020 return -EINVAL;1021 }1022 1023 info->regs[i] = devm_ioremap(info->dev, res->start,1024 resource_size(res));1025 if (!info->regs[i]) {1026 dev_err(info->dev,1027 "Memory resource %d could not be remapped\n",1028 i);1029 return -EINVAL;1030 }1031 }1032 1033 return 0;1034}1035 1036static int sec_base_init(struct sec_dev_info *info,1037 struct platform_device *pdev)1038{1039 int ret;1040 1041 ret = sec_map_io(info, pdev);1042 if (ret)1043 return ret;1044 1045 ret = sec_clk_en(info);1046 if (ret)1047 return ret;1048 1049 ret = sec_reset_whole_module(info);1050 if (ret)1051 goto sec_clk_disable;1052 1053 ret = sec_hw_init(info);1054 if (ret)1055 goto sec_clk_disable;1056 1057 return 0;1058 1059sec_clk_disable:1060 sec_clk_dis(info);1061 1062 return ret;1063}1064 1065static void sec_base_exit(struct sec_dev_info *info)1066{1067 sec_hw_exit(info);1068 sec_clk_dis(info);1069}1070 1071#define SEC_Q_CMD_SIZE \1072 round_up(SEC_QUEUE_LEN * sizeof(struct sec_bd_info), PAGE_SIZE)1073#define SEC_Q_CQ_SIZE \1074 round_up(SEC_QUEUE_LEN * sizeof(struct sec_out_bd_info), PAGE_SIZE)1075#define SEC_Q_DB_SIZE \1076 round_up(SEC_QUEUE_LEN * sizeof(struct sec_debug_bd_info), PAGE_SIZE)1077 1078static int sec_queue_res_cfg(struct sec_queue *queue)1079{1080 struct device *dev = queue->dev_info->dev;1081 struct sec_queue_ring_cmd *ring_cmd = &queue->ring_cmd;1082 struct sec_queue_ring_cq *ring_cq = &queue->ring_cq;1083 struct sec_queue_ring_db *ring_db = &queue->ring_db;1084 int ret;1085 1086 ring_cmd->vaddr = dma_alloc_coherent(dev, SEC_Q_CMD_SIZE,1087 &ring_cmd->paddr, GFP_KERNEL);1088 if (!ring_cmd->vaddr)1089 return -ENOMEM;1090 1091 atomic_set(&ring_cmd->used, 0);1092 mutex_init(&ring_cmd->lock);1093 ring_cmd->callback = sec_alg_callback;1094 1095 ring_cq->vaddr = dma_alloc_coherent(dev, SEC_Q_CQ_SIZE,1096 &ring_cq->paddr, GFP_KERNEL);1097 if (!ring_cq->vaddr) {1098 ret = -ENOMEM;1099 goto err_free_ring_cmd;1100 }1101 1102 ring_db->vaddr = dma_alloc_coherent(dev, SEC_Q_DB_SIZE,1103 &ring_db->paddr, GFP_KERNEL);1104 if (!ring_db->vaddr) {1105 ret = -ENOMEM;1106 goto err_free_ring_cq;1107 }1108 queue->task_irq = platform_get_irq(to_platform_device(dev),1109 queue->queue_id * 2 + 1);1110 if (queue->task_irq < 0) {1111 ret = queue->task_irq;1112 goto err_free_ring_db;1113 }1114 1115 return 0;1116 1117err_free_ring_db:1118 dma_free_coherent(dev, SEC_Q_DB_SIZE, queue->ring_db.vaddr,1119 queue->ring_db.paddr);1120err_free_ring_cq:1121 dma_free_coherent(dev, SEC_Q_CQ_SIZE, queue->ring_cq.vaddr,1122 queue->ring_cq.paddr);1123err_free_ring_cmd:1124 dma_free_coherent(dev, SEC_Q_CMD_SIZE, queue->ring_cmd.vaddr,1125 queue->ring_cmd.paddr);1126 1127 return ret;1128}1129 1130static void sec_queue_free_ring_pages(struct sec_queue *queue)1131{1132 struct device *dev = queue->dev_info->dev;1133 1134 dma_free_coherent(dev, SEC_Q_DB_SIZE, queue->ring_db.vaddr,1135 queue->ring_db.paddr);1136 dma_free_coherent(dev, SEC_Q_CQ_SIZE, queue->ring_cq.vaddr,1137 queue->ring_cq.paddr);1138 dma_free_coherent(dev, SEC_Q_CMD_SIZE, queue->ring_cmd.vaddr,1139 queue->ring_cmd.paddr);1140}1141 1142static int sec_queue_config(struct sec_dev_info *info, struct sec_queue *queue,1143 int queue_id)1144{1145 int ret;1146 1147 sec_queue_base_init(info, queue, queue_id);1148 1149 ret = sec_queue_res_cfg(queue);1150 if (ret)1151 return ret;1152 1153 ret = sec_queue_map_io(queue);1154 if (ret) {1155 dev_err(info->dev, "Queue map failed %d\n", ret);1156 sec_queue_free_ring_pages(queue);1157 return ret;1158 }1159 1160 sec_queue_hw_init(queue);1161 1162 return 0;1163}1164 1165static void sec_queue_unconfig(struct sec_dev_info *info,1166 struct sec_queue *queue)1167{1168 sec_queue_unmap_io(queue);1169 sec_queue_free_ring_pages(queue);1170}1171 1172static int sec_id_alloc(struct sec_dev_info *info)1173{1174 int ret = 0;1175 int i;1176 1177 mutex_lock(&sec_id_lock);1178 1179 for (i = 0; i < SEC_MAX_DEVICES; i++)1180 if (!sec_devices[i])1181 break;1182 if (i == SEC_MAX_DEVICES) {1183 ret = -ENOMEM;1184 goto unlock;1185 }1186 info->sec_id = i;1187 sec_devices[info->sec_id] = info;1188 1189unlock:1190 mutex_unlock(&sec_id_lock);1191 1192 return ret;1193}1194 1195static void sec_id_free(struct sec_dev_info *info)1196{1197 mutex_lock(&sec_id_lock);1198 sec_devices[info->sec_id] = NULL;1199 mutex_unlock(&sec_id_lock);1200}1201 1202static int sec_probe(struct platform_device *pdev)1203{1204 struct sec_dev_info *info;1205 struct device *dev = &pdev->dev;1206 int i, j;1207 int ret;1208 1209 ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));1210 if (ret) {1211 dev_err(dev, "Failed to set 64 bit dma mask %d", ret);1212 return -ENODEV;1213 }1214 1215 info = devm_kzalloc(dev, (sizeof(*info)), GFP_KERNEL);1216 if (!info)1217 return -ENOMEM;1218 1219 info->dev = dev;1220 mutex_init(&info->dev_lock);1221 1222 info->hw_sgl_pool = dmam_pool_create("sgl", dev,1223 sizeof(struct sec_hw_sgl), 64, 0);1224 if (!info->hw_sgl_pool) {1225 dev_err(dev, "Failed to create sec sgl dma pool\n");1226 return -ENOMEM;1227 }1228 1229 ret = sec_base_init(info, pdev);1230 if (ret) {1231 dev_err(dev, "Base initialization fail! %d\n", ret);1232 return ret;1233 }1234 1235 for (i = 0; i < SEC_Q_NUM; i++) {1236 ret = sec_queue_config(info, &info->queues[i], i);1237 if (ret)1238 goto queues_unconfig;1239 1240 ret = sec_queue_irq_init(&info->queues[i]);1241 if (ret) {1242 sec_queue_unconfig(info, &info->queues[i]);1243 goto queues_unconfig;1244 }1245 }1246 1247 ret = sec_algs_register();1248 if (ret) {1249 dev_err(dev, "Failed to register algorithms with crypto %d\n",1250 ret);1251 goto queues_unconfig;1252 }1253 1254 platform_set_drvdata(pdev, info);1255 1256 ret = sec_id_alloc(info);1257 if (ret)1258 goto algs_unregister;1259 1260 return 0;1261 1262algs_unregister:1263 sec_algs_unregister();1264queues_unconfig:1265 for (j = i - 1; j >= 0; j--) {1266 sec_queue_irq_uninit(&info->queues[j]);1267 sec_queue_unconfig(info, &info->queues[j]);1268 }1269 sec_base_exit(info);1270 1271 return ret;1272}1273 1274static void sec_remove(struct platform_device *pdev)1275{1276 struct sec_dev_info *info = platform_get_drvdata(pdev);1277 int i;1278 1279 /* Unexpose as soon as possible, reuse during remove is fine */1280 sec_id_free(info);1281 1282 sec_algs_unregister();1283 1284 for (i = 0; i < SEC_Q_NUM; i++) {1285 sec_queue_irq_uninit(&info->queues[i]);1286 sec_queue_unconfig(info, &info->queues[i]);1287 }1288 1289 sec_base_exit(info);1290}1291 1292static const __maybe_unused struct of_device_id sec_match[] = {1293 { .compatible = "hisilicon,hip06-sec" },1294 { .compatible = "hisilicon,hip07-sec" },1295 {}1296};1297MODULE_DEVICE_TABLE(of, sec_match);1298 1299static const __maybe_unused struct acpi_device_id sec_acpi_match[] = {1300 { "HISI02C1", 0 },1301 { }1302};1303MODULE_DEVICE_TABLE(acpi, sec_acpi_match);1304 1305static struct platform_driver sec_driver = {1306 .probe = sec_probe,1307 .remove_new = sec_remove,1308 .driver = {1309 .name = "hisi_sec_platform_driver",1310 .of_match_table = sec_match,1311 .acpi_match_table = ACPI_PTR(sec_acpi_match),1312 },1313};1314module_platform_driver(sec_driver);1315 1316MODULE_LICENSE("GPL");1317MODULE_DESCRIPTION("HiSilicon Security Accelerators");1318MODULE_AUTHOR("Zaibo Xu <xuzaibo@huawei.com");1319MODULE_AUTHOR("Jonathan Cameron <jonathan.cameron@huawei.com>");1320