/* * Copyright (c) 2018 Samsung Electronics Co., Ltd. * http://www.samsung.com * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License Version 2 as publised * by the Free Software Foundation. * * BTS Bus Traffic Shaper device driver operation functions set * */ #include #include #include "regs-bts2100.h" #include "bts.h" /**************************************************************** * init ops functions * ****************************************************************/ static void init_trexbts(void __iomem *base) { unsigned int w1; if (!base) return; /* high [27:24] mid [19:16] threshold */ w1 = __raw_readl(base + SCI_CTRL); w1 |= (0xB << HIGH_THRESHOLD_SHIFT) | (0x7 << MID_THRESHOLD_SHIFT); __raw_writel(w1, base + SCI_CTRL); __raw_writel(0x10101010, base + TH_IMM_R_0); __raw_writel(0x18181818, base + TH_IMM_W_0); __raw_writel(0x10101010, base + TH_HIGH_R_0); __raw_writel(0x18181818, base + TH_HIGH_W_0); } static void init_sciqfull(void __iomem *base) { } static void init_smcqbusy(void __iomem *base) { unsigned int threshold = DEFAULT_QBUSY_TH; unsigned int tmp_reg = 0; if (!base) return; if (threshold > 0x3F) threshold = 0x3F; tmp_reg = __raw_readl(base + SMC_SCHEDCTL_BUNDLE_CTRL4); tmp_reg &= ~(0x3F << 16); tmp_reg &= ~(0x3F << 24); tmp_reg |= (threshold << 16); //W tmp_reg |= (threshold << 24); //R __raw_writel(tmp_reg, base + SMC_SCHEDCTL_BUNDLE_CTRL4); } static void init_qmax(void __iomem *base) { unsigned int threshold = 0; unsigned int tmp_reg; if (!base) return; /* Read threshold set */ threshold = DEFAULT_QMAX_RD_TH; if (threshold > 0xFFFF) threshold = 0xFFFF; tmp_reg = __raw_readl(base + QMAX_THRESHOLD_R); tmp_reg &= ~(0xFFFF << 0); tmp_reg |= (threshold << 0); __raw_writel(tmp_reg, base + QMAX_THRESHOLD_R); /* Write threshold set */ threshold = DEFAULT_QMAX_WR_TH; if (threshold > 0xFFFF) threshold = 0xFFFF; tmp_reg = __raw_readl(base + QMAX_THRESHOLD_W); tmp_reg &= ~(0xFFFF << 0); tmp_reg |= (threshold << 0); __raw_writel(tmp_reg, base + QMAX_THRESHOLD_W); } /**************************************************************** * ip bts ops functions * ****************************************************************/ static int set_ipbts_qos(void __iomem *base, struct bts_stat *stat) { unsigned int tmp_reg_r = 0; unsigned int tmp_reg_w = 0; unsigned int tmp_reg = 0; if (!base || !stat) return -ENODATA; /* xCON[8] = AxQoS override *1:override, 0:bypass */ if (stat->bypass) { tmp_reg_r = __raw_readl(base + RCON); tmp_reg_r = tmp_reg_r & ~(0x1 << AXQOS_BYPASS); tmp_reg_w = __raw_readl(base + WCON); tmp_reg_w = tmp_reg_w & ~(0x1 << AXQOS_BYPASS); __raw_writel(tmp_reg_r, base + RCON); __raw_writel(tmp_reg_w, base + WCON); return 0; } if (stat->arqos > MAX_QOS) stat->arqos = MAX_QOS; /* xCON[15:12] = AxQoS value */ tmp_reg_r = __raw_readl(base + RCON); tmp_reg_r = tmp_reg_r & ~((0x1 << AXQOS_BYPASS) | (MAX_QOS << AXQOS_VAL)); tmp_reg_r = tmp_reg_r | (0x1 << AXQOS_BYPASS) | (stat->arqos << AXQOS_VAL); if (stat->awqos > MAX_QOS) stat->awqos = MAX_QOS; /* xCON[15:12] = AxQoS_value */ tmp_reg_w = __raw_readl(base + WCON); tmp_reg_w = tmp_reg_w & ~((0x1 << AXQOS_BYPASS) | (MAX_QOS << AXQOS_VAL)); tmp_reg_w = tmp_reg_w | (0x1 << AXQOS_BYPASS) | (stat->awqos << AXQOS_VAL); __raw_writel(tmp_reg_r, base + RCON); __raw_writel(tmp_reg_w, base + WCON); /* CONTROL[0] = QoS on/off */ tmp_reg = __raw_readl(base + CON); tmp_reg = tmp_reg & ~(0x1 << AXQOS_ONOFF); tmp_reg = tmp_reg | (0x1 << AXQOS_ONOFF); __raw_writel(tmp_reg, base + CON); return 0; } static int get_ipbts_qos(void __iomem *base, struct bts_stat *stat) { unsigned int tmp_reg_r = 0; unsigned int tmp_reg_w = 0; if (!base || !stat) return -ENODATA; tmp_reg_r = __raw_readl(base + RCON); tmp_reg_r = (tmp_reg_r & (0x1 << AXQOS_BYPASS)) >> AXQOS_BYPASS; tmp_reg_w = __raw_readl(base + WCON); tmp_reg_w = (tmp_reg_w & (0x1 << AXQOS_BYPASS)) >> AXQOS_BYPASS; if (!tmp_reg_r || !tmp_reg_w) stat->bypass = true; else stat->bypass = false; tmp_reg_r = __raw_readl(base + RCON); tmp_reg_r = (tmp_reg_r & (MAX_QOS << AXQOS_VAL)) >> AXQOS_VAL; tmp_reg_w = __raw_readl(base + WCON); tmp_reg_w = (tmp_reg_w & (MAX_QOS << AXQOS_VAL)) >> AXQOS_VAL; stat->arqos = tmp_reg_r; stat->awqos = tmp_reg_w; return 0; } static int set_ipbts_mo(void __iomem *base, struct bts_stat *stat) { unsigned int tmp_reg_r = 0; unsigned int tmp_reg_w = 0; if (!base || !stat) return -ENODATA; if (stat->rmo > MAX_MO || !stat->rmo) stat->rmo = MAX_MO; tmp_reg_r = __raw_readl(base + RBLK_UPPER); tmp_reg_r = tmp_reg_r & ~(MAX_MO << BLOCK_UPPER); tmp_reg_r = tmp_reg_r | (stat->rmo << BLOCK_UPPER); if (stat->wmo > MAX_MO || !stat->wmo) stat->wmo = MAX_MO; tmp_reg_w = __raw_readl(base + WBLK_UPPER); tmp_reg_w = tmp_reg_w & ~(MAX_MO << BLOCK_UPPER); tmp_reg_w = tmp_reg_w | (stat->wmo << BLOCK_UPPER); __raw_writel(tmp_reg_r, base + RBLK_UPPER); __raw_writel(tmp_reg_w, base + WBLK_UPPER); return 0; } static int get_ipbts_mo(void __iomem *base, struct bts_stat *stat) { unsigned int tmp_reg_r = 0; unsigned int tmp_reg_w = 0; if (!base || !stat) return -ENODATA; tmp_reg_r = __raw_readl(base + RBLK_UPPER); tmp_reg_r = (tmp_reg_r & (MAX_MO << BLOCK_UPPER)) >> BLOCK_UPPER; tmp_reg_w = __raw_readl(base + WBLK_UPPER); tmp_reg_w = (tmp_reg_w & (MAX_MO << BLOCK_UPPER)) >> BLOCK_UPPER; stat->rmo = tmp_reg_r; stat->wmo = tmp_reg_w; return 0; } static void vc_cfg_setting(void __iomem *base) { __raw_writel(0xf, base + VC_CFG_USER_MASK_LOW_0); __raw_writel(0xf, base + VC_CFG_USER_MASK_LOW_1); __raw_writel(0x1f, base + VC_CFG_USER_MASK_LOW_2); __raw_writel(0x1f, base + VC_CFG_USER_MASK_LOW_3); __raw_writel(0x4, base + VC_CFG_USER_VAL_0); __raw_writel(0x8, base + VC_CFG_USER_VAL_1); __raw_writel(0xC, base + VC_CFG_USER_VAL_2); __raw_writel(0x10, base + VC_CFG_USER_VAL_3); __raw_writel(0x13, base + VC_CFG_DOMAIN_0); __raw_writel(0x13, base + VC_CFG_DOMAIN_1); __raw_writel(0x13, base + VC_CFG_DOMAIN_2); __raw_writel(0x13, base + VC_CFG_DOMAIN_3); __raw_writel(0x4111, base + VC_CFG_VC_VAL_0); __raw_writel(0x4111, base + VC_CFG_VC_VAL_1); __raw_writel(0x4111, base + VC_CFG_VC_VAL_2); __raw_writel(0x4111, base + VC_CFG_VC_VAL_3); } static int set_ipbts_urgent(void __iomem *base, struct bts_stat *stat) { unsigned int tmp_reg = 0; if (!base || !stat) return -ENODATA; if (stat->qurgent_th_r > MAX_QUTH) stat->qurgent_th_r = MAX_QUTH; if (stat->qurgent_th_w > MAX_QUTH) stat->qurgent_th_w = MAX_QUTH; /* Read QUrgent */ tmp_reg = __raw_readl(base + TIMEOUT_R0); tmp_reg = tmp_reg & ~((MAX_QUTH << TIMEOUT_CNT_VC0) | (MAX_QUTH << TIMEOUT_CNT_VC1) | (MAX_QUTH << TIMEOUT_CNT_VC2) | (MAX_QUTH << TIMEOUT_CNT_VC3)); tmp_reg = tmp_reg | (stat->qurgent_th_r << TIMEOUT_CNT_VC0) | (stat->qurgent_th_r << TIMEOUT_CNT_VC1) | (stat->qurgent_th_r << TIMEOUT_CNT_VC2) | (stat->qurgent_th_r << TIMEOUT_CNT_VC3); __raw_writel(tmp_reg, base + TIMEOUT_R0); /* Write QUrgent */ tmp_reg = __raw_readl(base + TIMEOUT_W0); tmp_reg = tmp_reg & ~((MAX_QUTH << TIMEOUT_CNT_VC0) | (MAX_QUTH << TIMEOUT_CNT_VC1) | (MAX_QUTH << TIMEOUT_CNT_VC2) | (MAX_QUTH << TIMEOUT_CNT_VC3)); tmp_reg = tmp_reg | (stat->qurgent_th_w << TIMEOUT_CNT_VC0) | (stat->qurgent_th_w << TIMEOUT_CNT_VC1) | (stat->qurgent_th_w << TIMEOUT_CNT_VC2) | (stat->qurgent_th_w << TIMEOUT_CNT_VC3); __raw_writel(tmp_reg, base + TIMEOUT_W0); tmp_reg = __raw_readl(base + CON); tmp_reg = tmp_reg & ~(0xFF << QURGENT_EN); if (stat->qurgent_on) tmp_reg = tmp_reg | (stat->qurgent_on << QURGENT_EN); if (stat->vc_cfg) vc_cfg_setting(base); __raw_writel(tmp_reg, base + CON); return 0; } static int get_ipbts_urgent(void __iomem *base, struct bts_stat *stat) { unsigned int tmp_reg = 0; if (!base || !stat) return -ENODATA; tmp_reg = __raw_readl(base + TIMEOUT_R0); stat->qurgent_th_r = (tmp_reg & (MAX_QUTH << TIMEOUT_CNT_VC0)) >> TIMEOUT_CNT_VC0; tmp_reg = __raw_readl(base + TIMEOUT_W0); stat->qurgent_th_w = (tmp_reg & (MAX_QUTH << TIMEOUT_CNT_VC0)) >> TIMEOUT_CNT_VC0; tmp_reg = __raw_readl(base + CON); stat->qurgent_on = (tmp_reg & (0xFF << QURGENT_EN)) >> QURGENT_EN; return 0; } static int set_ipbts_blocking(void __iomem *base, struct bts_stat *stat) { unsigned int tmp_reg_r = 0; unsigned int tmp_reg_w = 0; if (!base || !stat) return -ENODATA; if (stat->blocking_on) { if (stat->qfull_limit_r > MAX_MO) stat->qfull_limit_r = MAX_MO; if (stat->qfull_limit_w > MAX_MO) stat->qfull_limit_w = MAX_MO; tmp_reg_r = __raw_readl(base + RBLK_UPPER_FULL); tmp_reg_r = tmp_reg_r & ~(MAX_MO << BLOCK_UPPER); tmp_reg_r = tmp_reg_r | (stat->qfull_limit_r << BLOCK_UPPER); tmp_reg_w = __raw_readl(base + WBLK_UPPER_FULL); tmp_reg_w = tmp_reg_w & ~(MAX_MO << BLOCK_UPPER); tmp_reg_w = tmp_reg_w | (stat->qfull_limit_w << BLOCK_UPPER); __raw_writel(tmp_reg_r, base + RBLK_UPPER_FULL); __raw_writel(tmp_reg_w, base + WBLK_UPPER_FULL); if (stat->qbusy_limit_r > MAX_MO) stat->qbusy_limit_r = MAX_MO; if (stat->qbusy_limit_w > MAX_MO) stat->qbusy_limit_w = MAX_MO; tmp_reg_r = __raw_readl(base + RBLK_UPPER_BUSY); tmp_reg_r = tmp_reg_r & ~(MAX_MO << BLOCK_UPPER); tmp_reg_r = tmp_reg_r | (stat->qbusy_limit_r << BLOCK_UPPER); tmp_reg_w = __raw_readl(base + WBLK_UPPER_BUSY); tmp_reg_w = tmp_reg_w & ~(MAX_MO << BLOCK_UPPER); tmp_reg_w = tmp_reg_w | (stat->qbusy_limit_w << BLOCK_UPPER); __raw_writel(tmp_reg_r, base + RBLK_UPPER_BUSY); __raw_writel(tmp_reg_w, base + WBLK_UPPER_BUSY); if (stat->qmax0_limit_r > MAX_MO) stat->qmax0_limit_r = MAX_MO; if (stat->qmax0_limit_w > MAX_MO) stat->qmax0_limit_w = MAX_MO; if (stat->qmax1_limit_r > MAX_MO) stat->qmax1_limit_r = MAX_MO; if (stat->qmax1_limit_w > MAX_MO) stat->qmax1_limit_w = MAX_MO; tmp_reg_r = __raw_readl(base + RBLK_UPPER_MAX); tmp_reg_r &= ~((MAX_MO << BLOCK_UPPER1) | (MAX_MO << BLOCK_UPPER0)); tmp_reg_r |= ((stat->qmax1_limit_r << BLOCK_UPPER1) | (stat->qmax0_limit_r << BLOCK_UPPER0)); tmp_reg_w = __raw_readl(base + WBLK_UPPER_MAX); tmp_reg_w &= ~((MAX_MO << BLOCK_UPPER1) | (MAX_MO << BLOCK_UPPER0)); tmp_reg_w |= ((stat->qmax1_limit_w << BLOCK_UPPER1) | (stat->qmax0_limit_w << BLOCK_UPPER0)); __raw_writel(tmp_reg_r, base + RBLK_UPPER_MAX); __raw_writel(tmp_reg_w, base + WBLK_UPPER_MAX); tmp_reg_r = __raw_readl(base + RCON); tmp_reg_r = tmp_reg_r & ~(0x1 << BLOCKING_EN); tmp_reg_r = tmp_reg_r | (0x1 << BLOCKING_EN); __raw_writel(tmp_reg_r, base + RCON); tmp_reg_w = __raw_readl(base + WCON); tmp_reg_w = tmp_reg_w & ~(0x1 << BLOCKING_EN); tmp_reg_w = tmp_reg_w | (0x1 << BLOCKING_EN); __raw_writel(tmp_reg_w, base + WCON); } else { tmp_reg_r = __raw_readl(base + RCON); tmp_reg_r = tmp_reg_r & ~(0x1 << BLOCKING_EN); __raw_writel(tmp_reg_r, base + RCON); tmp_reg_w = __raw_readl(base + WCON); tmp_reg_w = tmp_reg_w & ~(0x1 << BLOCKING_EN); __raw_writel(tmp_reg_w, base + WCON); } return 0; } static int get_ipbts_blocking(void __iomem *base, struct bts_stat *stat) { unsigned int tmp_reg = 0; tmp_reg = __raw_readl(base + RCON); stat->blocking_on = (tmp_reg & (0x1 << BLOCKING_EN)) ? true : false; if (!stat->blocking_on) return 0; tmp_reg = __raw_readl(base + RBLK_UPPER_FULL); stat->qfull_limit_r = (tmp_reg & (MAX_MO << BLOCK_UPPER)) >> BLOCK_UPPER; tmp_reg = __raw_readl(base + WBLK_UPPER_FULL); stat->qfull_limit_w = (tmp_reg & (MAX_MO << BLOCK_UPPER)) >> BLOCK_UPPER; tmp_reg = __raw_readl(base + RBLK_UPPER_BUSY); stat->qbusy_limit_r = (tmp_reg & (MAX_MO << BLOCK_UPPER)) >> BLOCK_UPPER; tmp_reg = __raw_readl(base + WBLK_UPPER_BUSY); stat->qbusy_limit_w = (tmp_reg & (MAX_MO << BLOCK_UPPER)) >> BLOCK_UPPER; tmp_reg = __raw_readl(base + RBLK_UPPER_MAX); stat->qmax0_limit_r = (tmp_reg & (MAX_MO << BLOCK_UPPER0)) >> BLOCK_UPPER0; stat->qmax1_limit_r = (tmp_reg & (MAX_MO << BLOCK_UPPER1)) >> BLOCK_UPPER1; tmp_reg = __raw_readl(base + WBLK_UPPER_MAX); stat->qmax0_limit_w = (tmp_reg & (MAX_MO << BLOCK_UPPER0)) >> BLOCK_UPPER0; stat->qmax1_limit_w = (tmp_reg & (MAX_MO << BLOCK_UPPER1)) >> BLOCK_UPPER1; return 0; } static int set_ipbts(void __iomem *base, struct bts_stat *stat) { int ret = 0; if (!base || !stat) return -ENODATA; if (!stat->stat_on) return 0; ret = set_ipbts_qos(base, stat); if (ret) { pr_err("set_ipbts_qos failed! ret=%d\n", ret); return ret; } ret = set_ipbts_mo(base, stat); if (ret) { pr_err("set_ipbts_mo failed! ret=%d\n", ret); return ret; } ret = set_ipbts_urgent(base, stat); if (ret) { pr_err("set_ipbts_urgent failed! ret=%d\n", ret); return ret; } ret = set_ipbts_blocking(base, stat); if (ret) { pr_err("set_ipbts_blocking failed! ret=%d\n", ret); return ret; } return ret; } static int get_ipbts(void __iomem *base, struct bts_stat *stat) { int ret = 0; if (!base || !stat) return -ENODATA; ret = get_ipbts_qos(base, stat); if (ret) { pr_err("get_ipbts_qos failed! ret=%d\n", ret); return ret; } ret = get_ipbts_mo(base, stat); if (ret) { pr_err("get_ipbts_mo failed! ret=%d\n", ret); return ret; } ret = get_ipbts_urgent(base, stat); if (ret) { pr_err("get_ipbts_urgent failed! ret=%d\n", ret); return ret; } ret = get_ipbts_blocking(base, stat); if (ret) { pr_err("get_ipbts_blocking failed! ret=%d\n", ret); return ret; } return 0; } /**************************************************************** * sci bts ops functions * ****************************************************************/ static int set_scibts_mo(void __iomem *base, struct bts_stat *stat) { unsigned int tmp_reg = 0; if (!base || !stat) return -ENODATA; if (stat->rmo > MAX_MO || !stat->rmo) stat->rmo = MAX_MO; if (stat->wmo > MAX_MO || !stat->wmo) stat->wmo = MAX_MO; /* * CRP_CTL3_X (Olympus 0~3) * MaxOutstandingPort0Rd [7:0] (Olympus cpu use 0/3, not use 1/2) * MaxOutstandingPort0Wr [15:8] (Olympus cpu use 0/3, not use 1/2) * MaxOutstandingPort1Rd [23:16] (Olympus gpu use 0/1/2/3) * MaxOutstandingPort1Wr [31:24] (Olympus gpu use 0/1/2/3) */ tmp_reg = stat->rmo << RMO_PORT_1 | stat->wmo << WMO_PORT_1; __raw_writel(tmp_reg, base); return 0; } static int get_scibts_mo(void __iomem *base, struct bts_stat *stat) { unsigned int tmp_reg = 0; unsigned int tmp_reg_r = 0; unsigned int tmp_reg_w = 0; if (!base || !stat) return -ENODATA; tmp_reg = __raw_readl(base); tmp_reg_r = (tmp_reg & (0xFF << RMO_PORT_1)) >> RMO_PORT_1; tmp_reg_w = (tmp_reg & (0xFF << WMO_PORT_1)) >> WMO_PORT_1; stat->rmo = tmp_reg_r; stat->wmo = tmp_reg_w; return 0; } static int set_scibts_qos(void __iomem *base, struct bts_stat *stat) { unsigned int tmp_reg = 0; void __iomem *qos_base = NULL; if (!stat) return -ENODATA; qos_base = stat->qos_va_base; if (!qos_base) return 0; /* QoS on */ if (stat->arqos || stat->awqos) { /* on */ tmp_reg = __raw_readl(qos_base + CORE_QOS_EN); tmp_reg = tmp_reg | (0x1 << SCIQOS_EN); __raw_writel(tmp_reg, qos_base + CORE_QOS_EN); } else { /* QoS off */ tmp_reg = __raw_readl(qos_base + CORE_QOS_EN); tmp_reg = tmp_reg & ~(0x1 << SCIQOS_EN); __raw_writel(tmp_reg, qos_base + CORE_QOS_EN); } if (stat->arqos > SCIMAX_QOS) stat->arqos = SCIMAX_QOS; if (stat->awqos > SCIMAX_QOS) stat->awqos = SCIMAX_QOS; /* AxQoS value */ tmp_reg = __raw_readl(qos_base); tmp_reg = tmp_reg & ~((SCIMAX_QOS << SCIQOS_W)| (SCIMAX_QOS << SCIQOS_R)); tmp_reg = tmp_reg | (stat->arqos << SCIQOS_R) | (stat->awqos << SCIQOS_W); __raw_writel(tmp_reg, qos_base); return 0; } static int get_scibts_qos(void __iomem *base, struct bts_stat *stat) { unsigned int tmp_reg = 0; unsigned int tmp_reg_r = 0; unsigned int tmp_reg_w = 0; void __iomem *qos_base = NULL; if (!stat) return -ENODATA; qos_base = stat->qos_va_base; if (!qos_base) return 0; tmp_reg = __raw_readl(qos_base + CORE_QOS_EN); tmp_reg = (tmp_reg & (0x1 << SCIQOS_EN)) >> SCIQOS_EN; if (tmp_reg) stat->bypass = false; else stat->bypass = true; tmp_reg_w = __raw_readl(qos_base); tmp_reg_w = (tmp_reg_w & (SCIMAX_QOS << SCIQOS_W)) >> SCIQOS_W; tmp_reg_r = __raw_readl(qos_base); tmp_reg_r = (tmp_reg_r & (SCIMAX_QOS << SCIQOS_R)) >> SCIQOS_R; stat->arqos = tmp_reg_r; stat->awqos = tmp_reg_w; return 0; } static int set_scibts(void __iomem *base, struct bts_stat *stat) { int ret = 0; if (!base || !stat) return -ENODATA; if (!stat->stat_on) return 0; ret = set_scibts_qos(base, stat); if (ret) { pr_err("set_scibts_qos failed! ret=%d\n", ret); return ret; } ret = set_scibts_mo(base, stat); if (ret) { pr_err("set_scibts_mo failed! ret=%d\n", ret); return ret; } return ret; } static int get_scibts(void __iomem *base, struct bts_stat *stat) { int ret = 0; if (!base || !stat) return -ENODATA; ret = get_scibts_qos(base, stat); if (ret) { pr_err("get_scibts_qos failed! ret=%d\n", ret); return ret; } ret = get_scibts_mo(base, stat); if (ret) { pr_err("get_scibts_mo failed! ret=%d\n", ret); return ret; } return 0; } /**************************************************************** * register ops functions * ****************************************************************/ int register_btsops(struct bts_info *info) { unsigned int type = info->type; info->ops = kmalloc(sizeof(struct bts_ops), GFP_KERNEL); if (info->ops == NULL) return -ENOMEM; switch (type) { case IP_BTS: info->ops->init_bts = NULL; info->ops->set_bts = set_ipbts; info->ops->get_bts = get_ipbts; info->ops->set_qos = set_ipbts_qos; info->ops->get_qos = get_ipbts_qos; info->ops->set_mo = set_ipbts_mo; info->ops->get_mo = get_ipbts_mo; info->ops->set_urgent = set_ipbts_urgent; info->ops->get_urgent = get_ipbts_urgent; info->ops->set_blocking = set_ipbts_blocking; info->ops->get_blocking = get_ipbts_blocking; break; case TREX_BTS: info->ops->init_bts = init_trexbts; info->ops->set_bts = NULL; info->ops->get_bts = NULL; info->ops->set_qos = NULL; info->ops->get_qos = NULL; info->ops->set_mo = NULL; info->ops->get_mo = NULL; info->ops->set_urgent = NULL; info->ops->get_urgent = NULL; info->ops->set_blocking = NULL; info->ops->get_blocking = NULL; break; case SCI_BTS: info->ops->init_bts = init_sciqfull; info->ops->set_bts = set_scibts; info->ops->get_bts = get_scibts; info->ops->set_qos = set_scibts_qos; info->ops->get_qos = get_scibts_qos; info->ops->set_mo = set_scibts_mo; info->ops->get_mo = get_scibts_mo; info->ops->set_urgent = NULL; info->ops->get_urgent = NULL; info->ops->set_blocking = NULL; info->ops->get_blocking = NULL; break; case SMC_BTS: info->ops->init_bts = init_smcqbusy; info->ops->set_bts = NULL; info->ops->get_bts = NULL; info->ops->set_qos = NULL; info->ops->get_qos = NULL; info->ops->set_mo = NULL; info->ops->get_mo = NULL; info->ops->set_urgent = NULL; info->ops->get_urgent = NULL; info->ops->set_blocking = NULL; info->ops->get_blocking = NULL; break; case BUSC_BTS: info->ops->init_bts = init_qmax; info->ops->set_bts = NULL; info->ops->get_bts = NULL; info->ops->set_qos = NULL; info->ops->get_qos = NULL; info->ops->set_mo = NULL; info->ops->get_mo = NULL; info->ops->set_urgent = NULL; info->ops->get_urgent = NULL; info->ops->set_blocking = NULL; info->ops->get_blocking = NULL; break; case DREX_BTS: info->ops->init_bts = NULL; info->ops->set_bts = NULL; info->ops->get_bts = NULL; info->ops->set_qos = NULL; info->ops->get_qos = NULL; info->ops->set_mo = NULL; info->ops->get_mo = NULL; info->ops->set_urgent = NULL; info->ops->get_urgent = NULL; info->ops->set_blocking = NULL; info->ops->get_blocking = NULL; break; case INTERNAL_BTS: info->ops->init_bts = NULL; info->ops->set_bts = NULL; info->ops->get_bts = NULL; info->ops->set_qos = NULL; info->ops->get_qos = NULL; info->ops->set_mo = NULL; info->ops->get_mo = NULL; info->ops->set_urgent = NULL; info->ops->get_urgent = NULL; info->ops->set_blocking = NULL; info->ops->get_blocking = NULL; break; default: break; } return 0; } EXPORT_SYMBOL(register_btsops); MODULE_LICENSE("GPL");