Merge branches 'pm-devfreq' and 'pm-tools'
* pm-devfreq: PM / devfreq: rk3399_dmc: Remove unneeded semicolon PM / devfreq: Replace devfreq->dev.parent as dev in devfreq_add_device PM / devfreq: Correct spelling in a comment * pm-tools: cpupower: Add cpuid cap flag for MSR_AMD_HWCR support cpupower: Remove family arg to decode_pstates() cpupower: Condense pstate enabled bit checks in decode_pstates() cpupower: Update family checks when decoding HW pstates cpupower: Remove unused pscur variable. cpupower: Add CPUPOWER_CAP_AMD_HW_PSTATE cpuid caps flag cpupower: Correct macro name for CPB caps flag cpupower: Update msr_pstate union struct naming cpupower: add Makefile dependencies for install targets
This commit is contained in:
commit
332fd9005b
@ -900,13 +900,13 @@ struct devfreq *devfreq_add_device(struct device *dev,
|
|||||||
goto err_devfreq;
|
goto err_devfreq;
|
||||||
|
|
||||||
devfreq->nb_min.notifier_call = qos_min_notifier_call;
|
devfreq->nb_min.notifier_call = qos_min_notifier_call;
|
||||||
err = dev_pm_qos_add_notifier(devfreq->dev.parent, &devfreq->nb_min,
|
err = dev_pm_qos_add_notifier(dev, &devfreq->nb_min,
|
||||||
DEV_PM_QOS_MIN_FREQUENCY);
|
DEV_PM_QOS_MIN_FREQUENCY);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_devfreq;
|
goto err_devfreq;
|
||||||
|
|
||||||
devfreq->nb_max.notifier_call = qos_max_notifier_call;
|
devfreq->nb_max.notifier_call = qos_max_notifier_call;
|
||||||
err = dev_pm_qos_add_notifier(devfreq->dev.parent, &devfreq->nb_max,
|
err = dev_pm_qos_add_notifier(dev, &devfreq->nb_max,
|
||||||
DEV_PM_QOS_MAX_FREQUENCY);
|
DEV_PM_QOS_MAX_FREQUENCY);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_devfreq;
|
goto err_devfreq;
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
/*
|
/*
|
||||||
* Definition of governor attribute flags except for common sysfs attributes
|
* Definition of governor attribute flags except for common sysfs attributes
|
||||||
* - DEVFREQ_GOV_ATTR_POLLING_INTERVAL
|
* - DEVFREQ_GOV_ATTR_POLLING_INTERVAL
|
||||||
* : Indicate polling_interal sysfs attribute
|
* : Indicate polling_interval sysfs attribute
|
||||||
* - DEVFREQ_GOV_ATTR_TIMER
|
* - DEVFREQ_GOV_ATTR_TIMER
|
||||||
* : Indicate timer sysfs attribute
|
* : Indicate timer sysfs attribute
|
||||||
*/
|
*/
|
||||||
|
@ -400,7 +400,7 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
|
|||||||
default:
|
default:
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto err_edev;
|
goto err_edev;
|
||||||
};
|
}
|
||||||
|
|
||||||
no_pmu:
|
no_pmu:
|
||||||
arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, 0, 0,
|
arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, 0, 0,
|
||||||
|
@ -270,14 +270,14 @@ clean:
|
|||||||
$(MAKE) -C bench O=$(OUTPUT) clean
|
$(MAKE) -C bench O=$(OUTPUT) clean
|
||||||
|
|
||||||
|
|
||||||
install-lib:
|
install-lib: libcpupower
|
||||||
$(INSTALL) -d $(DESTDIR)${libdir}
|
$(INSTALL) -d $(DESTDIR)${libdir}
|
||||||
$(CP) $(OUTPUT)libcpupower.so* $(DESTDIR)${libdir}/
|
$(CP) $(OUTPUT)libcpupower.so* $(DESTDIR)${libdir}/
|
||||||
$(INSTALL) -d $(DESTDIR)${includedir}
|
$(INSTALL) -d $(DESTDIR)${includedir}
|
||||||
$(INSTALL_DATA) lib/cpufreq.h $(DESTDIR)${includedir}/cpufreq.h
|
$(INSTALL_DATA) lib/cpufreq.h $(DESTDIR)${includedir}/cpufreq.h
|
||||||
$(INSTALL_DATA) lib/cpuidle.h $(DESTDIR)${includedir}/cpuidle.h
|
$(INSTALL_DATA) lib/cpuidle.h $(DESTDIR)${includedir}/cpuidle.h
|
||||||
|
|
||||||
install-tools:
|
install-tools: $(OUTPUT)cpupower
|
||||||
$(INSTALL) -d $(DESTDIR)${bindir}
|
$(INSTALL) -d $(DESTDIR)${bindir}
|
||||||
$(INSTALL_PROGRAM) $(OUTPUT)cpupower $(DESTDIR)${bindir}
|
$(INSTALL_PROGRAM) $(OUTPUT)cpupower $(DESTDIR)${bindir}
|
||||||
$(INSTALL) -d $(DESTDIR)${bash_completion_dir}
|
$(INSTALL) -d $(DESTDIR)${bash_completion_dir}
|
||||||
@ -293,14 +293,14 @@ install-man:
|
|||||||
$(INSTALL_DATA) -D man/cpupower-info.1 $(DESTDIR)${mandir}/man1/cpupower-info.1
|
$(INSTALL_DATA) -D man/cpupower-info.1 $(DESTDIR)${mandir}/man1/cpupower-info.1
|
||||||
$(INSTALL_DATA) -D man/cpupower-monitor.1 $(DESTDIR)${mandir}/man1/cpupower-monitor.1
|
$(INSTALL_DATA) -D man/cpupower-monitor.1 $(DESTDIR)${mandir}/man1/cpupower-monitor.1
|
||||||
|
|
||||||
install-gmo:
|
install-gmo: create-gmo
|
||||||
$(INSTALL) -d $(DESTDIR)${localedir}
|
$(INSTALL) -d $(DESTDIR)${localedir}
|
||||||
for HLANG in $(LANGUAGES); do \
|
for HLANG in $(LANGUAGES); do \
|
||||||
echo '$(INSTALL_DATA) -D $(OUTPUT)po/$$HLANG.gmo $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo'; \
|
echo '$(INSTALL_DATA) -D $(OUTPUT)po/$$HLANG.gmo $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo'; \
|
||||||
$(INSTALL_DATA) -D $(OUTPUT)po/$$HLANG.gmo $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo; \
|
$(INSTALL_DATA) -D $(OUTPUT)po/$$HLANG.gmo $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo; \
|
||||||
done;
|
done;
|
||||||
|
|
||||||
install-bench:
|
install-bench: compile-bench
|
||||||
@#DESTDIR must be set from outside to survive
|
@#DESTDIR must be set from outside to survive
|
||||||
@sbindir=$(sbindir) bindir=$(bindir) docdir=$(docdir) confdir=$(confdir) $(MAKE) -C bench O=$(OUTPUT) install
|
@sbindir=$(sbindir) bindir=$(bindir) docdir=$(docdir) confdir=$(confdir) $(MAKE) -C bench O=$(OUTPUT) install
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ $(OUTPUT)cpufreq-bench: $(OBJS)
|
|||||||
|
|
||||||
all: $(OUTPUT)cpufreq-bench
|
all: $(OUTPUT)cpufreq-bench
|
||||||
|
|
||||||
install:
|
install: $(OUTPUT)cpufreq-bench
|
||||||
mkdir -p $(DESTDIR)/$(sbindir)
|
mkdir -p $(DESTDIR)/$(sbindir)
|
||||||
mkdir -p $(DESTDIR)/$(bindir)
|
mkdir -p $(DESTDIR)/$(bindir)
|
||||||
mkdir -p $(DESTDIR)/$(docdir)
|
mkdir -p $(DESTDIR)/$(docdir)
|
||||||
|
@ -186,8 +186,7 @@ static int get_boost_mode_x86(unsigned int cpu)
|
|||||||
if ((cpupower_cpu_info.vendor == X86_VENDOR_AMD &&
|
if ((cpupower_cpu_info.vendor == X86_VENDOR_AMD &&
|
||||||
cpupower_cpu_info.family >= 0x10) ||
|
cpupower_cpu_info.family >= 0x10) ||
|
||||||
cpupower_cpu_info.vendor == X86_VENDOR_HYGON) {
|
cpupower_cpu_info.vendor == X86_VENDOR_HYGON) {
|
||||||
ret = decode_pstates(cpu, cpupower_cpu_info.family, b_states,
|
ret = decode_pstates(cpu, b_states, pstates, &pstate_no);
|
||||||
pstates, &pstate_no);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -13,7 +13,8 @@
|
|||||||
#define MSR_AMD_PSTATE 0xc0010064
|
#define MSR_AMD_PSTATE 0xc0010064
|
||||||
#define MSR_AMD_PSTATE_LIMIT 0xc0010061
|
#define MSR_AMD_PSTATE_LIMIT 0xc0010061
|
||||||
|
|
||||||
union msr_pstate {
|
union core_pstate {
|
||||||
|
/* pre fam 17h: */
|
||||||
struct {
|
struct {
|
||||||
unsigned fid:6;
|
unsigned fid:6;
|
||||||
unsigned did:3;
|
unsigned did:3;
|
||||||
@ -26,7 +27,8 @@ union msr_pstate {
|
|||||||
unsigned idddiv:2;
|
unsigned idddiv:2;
|
||||||
unsigned res3:21;
|
unsigned res3:21;
|
||||||
unsigned en:1;
|
unsigned en:1;
|
||||||
} bits;
|
} pstate;
|
||||||
|
/* since fam 17h: */
|
||||||
struct {
|
struct {
|
||||||
unsigned fid:8;
|
unsigned fid:8;
|
||||||
unsigned did:6;
|
unsigned did:6;
|
||||||
@ -35,37 +37,37 @@ union msr_pstate {
|
|||||||
unsigned idddiv:2;
|
unsigned idddiv:2;
|
||||||
unsigned res1:31;
|
unsigned res1:31;
|
||||||
unsigned en:1;
|
unsigned en:1;
|
||||||
} fam17h_bits;
|
} pstatedef;
|
||||||
unsigned long long val;
|
unsigned long long val;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int get_did(int family, union msr_pstate pstate)
|
static int get_did(union core_pstate pstate)
|
||||||
{
|
{
|
||||||
int t;
|
int t;
|
||||||
|
|
||||||
if (family == 0x12)
|
if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_PSTATEDEF)
|
||||||
|
t = pstate.pstatedef.did;
|
||||||
|
else if (cpupower_cpu_info.family == 0x12)
|
||||||
t = pstate.val & 0xf;
|
t = pstate.val & 0xf;
|
||||||
else if (family == 0x17 || family == 0x18)
|
|
||||||
t = pstate.fam17h_bits.did;
|
|
||||||
else
|
else
|
||||||
t = pstate.bits.did;
|
t = pstate.pstate.did;
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_cof(int family, union msr_pstate pstate)
|
static int get_cof(union core_pstate pstate)
|
||||||
{
|
{
|
||||||
int t;
|
int t;
|
||||||
int fid, did, cof;
|
int fid, did, cof;
|
||||||
|
|
||||||
did = get_did(family, pstate);
|
did = get_did(pstate);
|
||||||
if (family == 0x17 || family == 0x18) {
|
if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_PSTATEDEF) {
|
||||||
fid = pstate.fam17h_bits.fid;
|
fid = pstate.pstatedef.fid;
|
||||||
cof = 200 * fid / did;
|
cof = 200 * fid / did;
|
||||||
} else {
|
} else {
|
||||||
t = 0x10;
|
t = 0x10;
|
||||||
fid = pstate.bits.fid;
|
fid = pstate.pstate.fid;
|
||||||
if (family == 0x11)
|
if (cpupower_cpu_info.family == 0x11)
|
||||||
t = 0x8;
|
t = 0x8;
|
||||||
cof = (100 * (fid + t)) >> did;
|
cof = (100 * (fid + t)) >> did;
|
||||||
}
|
}
|
||||||
@ -74,8 +76,7 @@ static int get_cof(int family, union msr_pstate pstate)
|
|||||||
|
|
||||||
/* Needs:
|
/* Needs:
|
||||||
* cpu -> the cpu that gets evaluated
|
* cpu -> the cpu that gets evaluated
|
||||||
* cpu_family -> The cpu's family (0x10, 0x12,...)
|
* boost_states -> how much boost states the machines support
|
||||||
* boots_states -> how much boost states the machines support
|
|
||||||
*
|
*
|
||||||
* Fills up:
|
* Fills up:
|
||||||
* pstates -> a pointer to an array of size MAX_HW_PSTATES
|
* pstates -> a pointer to an array of size MAX_HW_PSTATES
|
||||||
@ -85,31 +86,23 @@ static int get_cof(int family, union msr_pstate pstate)
|
|||||||
*
|
*
|
||||||
* returns zero on success, -1 on failure
|
* returns zero on success, -1 on failure
|
||||||
*/
|
*/
|
||||||
int decode_pstates(unsigned int cpu, unsigned int cpu_family,
|
int decode_pstates(unsigned int cpu, int boost_states,
|
||||||
int boost_states, unsigned long *pstates, int *no)
|
unsigned long *pstates, int *no)
|
||||||
{
|
{
|
||||||
int i, psmax, pscur;
|
int i, psmax;
|
||||||
union msr_pstate pstate;
|
union core_pstate pstate;
|
||||||
unsigned long long val;
|
unsigned long long val;
|
||||||
|
|
||||||
/* Only read out frequencies from HW when CPU might be boostable
|
/* Only read out frequencies from HW if HW Pstate is supported,
|
||||||
to keep the code as short and clean as possible.
|
* otherwise frequencies are exported via ACPI tables.
|
||||||
Otherwise frequencies are exported via ACPI tables.
|
*/
|
||||||
*/
|
if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_HW_PSTATE))
|
||||||
if (cpu_family < 0x10 || cpu_family == 0x14)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (read_msr(cpu, MSR_AMD_PSTATE_LIMIT, &val))
|
if (read_msr(cpu, MSR_AMD_PSTATE_LIMIT, &val))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
psmax = (val >> 4) & 0x7;
|
psmax = (val >> 4) & 0x7;
|
||||||
|
|
||||||
if (read_msr(cpu, MSR_AMD_PSTATE_STATUS, &val))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
pscur = val & 0x7;
|
|
||||||
|
|
||||||
pscur += boost_states;
|
|
||||||
psmax += boost_states;
|
psmax += boost_states;
|
||||||
for (i = 0; i <= psmax; i++) {
|
for (i = 0; i <= psmax; i++) {
|
||||||
if (i >= MAX_HW_PSTATES) {
|
if (i >= MAX_HW_PSTATES) {
|
||||||
@ -119,12 +112,12 @@ int decode_pstates(unsigned int cpu, unsigned int cpu_family,
|
|||||||
}
|
}
|
||||||
if (read_msr(cpu, MSR_AMD_PSTATE + i, &pstate.val))
|
if (read_msr(cpu, MSR_AMD_PSTATE + i, &pstate.val))
|
||||||
return -1;
|
return -1;
|
||||||
if ((cpu_family == 0x17) && (!pstate.fam17h_bits.en))
|
|
||||||
continue;
|
/* The enabled bit (bit 63) is common for all families */
|
||||||
else if (!pstate.bits.en)
|
if (!pstate.pstatedef.en)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
pstates[i] = get_cof(cpu_family, pstate);
|
pstates[i] = get_cof(pstate);
|
||||||
}
|
}
|
||||||
*no = i;
|
*no = i;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -128,9 +128,23 @@ out:
|
|||||||
/* AMD or Hygon Boost state enable/disable register */
|
/* AMD or Hygon Boost state enable/disable register */
|
||||||
if (cpu_info->vendor == X86_VENDOR_AMD ||
|
if (cpu_info->vendor == X86_VENDOR_AMD ||
|
||||||
cpu_info->vendor == X86_VENDOR_HYGON) {
|
cpu_info->vendor == X86_VENDOR_HYGON) {
|
||||||
if (ext_cpuid_level >= 0x80000007 &&
|
if (ext_cpuid_level >= 0x80000007) {
|
||||||
(cpuid_edx(0x80000007) & (1 << 9)))
|
if (cpuid_edx(0x80000007) & (1 << 9)) {
|
||||||
cpu_info->caps |= CPUPOWER_CAP_AMD_CBP;
|
cpu_info->caps |= CPUPOWER_CAP_AMD_CPB;
|
||||||
|
|
||||||
|
if (cpu_info->family >= 0x17)
|
||||||
|
cpu_info->caps |= CPUPOWER_CAP_AMD_CPB_MSR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((cpuid_edx(0x80000007) & (1 << 7)) &&
|
||||||
|
cpu_info->family != 0x14) {
|
||||||
|
/* HW pstate was not implemented in family 0x14 */
|
||||||
|
cpu_info->caps |= CPUPOWER_CAP_AMD_HW_PSTATE;
|
||||||
|
|
||||||
|
if (cpu_info->family >= 0x17)
|
||||||
|
cpu_info->caps |= CPUPOWER_CAP_AMD_PSTATEDEF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ext_cpuid_level >= 0x80000008 &&
|
if (ext_cpuid_level >= 0x80000008 &&
|
||||||
cpuid_ebx(0x80000008) & (1 << 4))
|
cpuid_ebx(0x80000008) & (1 << 4))
|
||||||
|
@ -64,12 +64,15 @@ enum cpupower_cpu_vendor {X86_VENDOR_UNKNOWN = 0, X86_VENDOR_INTEL,
|
|||||||
|
|
||||||
#define CPUPOWER_CAP_INV_TSC 0x00000001
|
#define CPUPOWER_CAP_INV_TSC 0x00000001
|
||||||
#define CPUPOWER_CAP_APERF 0x00000002
|
#define CPUPOWER_CAP_APERF 0x00000002
|
||||||
#define CPUPOWER_CAP_AMD_CBP 0x00000004
|
#define CPUPOWER_CAP_AMD_CPB 0x00000004
|
||||||
#define CPUPOWER_CAP_PERF_BIAS 0x00000008
|
#define CPUPOWER_CAP_PERF_BIAS 0x00000008
|
||||||
#define CPUPOWER_CAP_HAS_TURBO_RATIO 0x00000010
|
#define CPUPOWER_CAP_HAS_TURBO_RATIO 0x00000010
|
||||||
#define CPUPOWER_CAP_IS_SNB 0x00000020
|
#define CPUPOWER_CAP_IS_SNB 0x00000020
|
||||||
#define CPUPOWER_CAP_INTEL_IDA 0x00000040
|
#define CPUPOWER_CAP_INTEL_IDA 0x00000040
|
||||||
#define CPUPOWER_CAP_AMD_RDPRU 0x00000080
|
#define CPUPOWER_CAP_AMD_RDPRU 0x00000080
|
||||||
|
#define CPUPOWER_CAP_AMD_HW_PSTATE 0x00000100
|
||||||
|
#define CPUPOWER_CAP_AMD_PSTATEDEF 0x00000200
|
||||||
|
#define CPUPOWER_CAP_AMD_CPB_MSR 0x00000400
|
||||||
|
|
||||||
#define CPUPOWER_AMD_CPBDIS 0x02000000
|
#define CPUPOWER_AMD_CPBDIS 0x02000000
|
||||||
|
|
||||||
@ -125,8 +128,8 @@ extern struct pci_dev *pci_slot_func_init(struct pci_access **pacc,
|
|||||||
|
|
||||||
/* AMD HW pstate decoding **************************/
|
/* AMD HW pstate decoding **************************/
|
||||||
|
|
||||||
extern int decode_pstates(unsigned int cpu, unsigned int cpu_family,
|
extern int decode_pstates(unsigned int cpu, int boost_states,
|
||||||
int boost_states, unsigned long *pstates, int *no);
|
unsigned long *pstates, int *no);
|
||||||
|
|
||||||
/* AMD HW pstate decoding **************************/
|
/* AMD HW pstate decoding **************************/
|
||||||
|
|
||||||
@ -143,9 +146,8 @@ unsigned int cpuid_edx(unsigned int op);
|
|||||||
/* cpuid and cpuinfo helpers **************************/
|
/* cpuid and cpuinfo helpers **************************/
|
||||||
/* X86 ONLY ********************************************/
|
/* X86 ONLY ********************************************/
|
||||||
#else
|
#else
|
||||||
static inline int decode_pstates(unsigned int cpu, unsigned int cpu_family,
|
static inline int decode_pstates(unsigned int cpu, int boost_states,
|
||||||
int boost_states, unsigned long *pstates,
|
unsigned long *pstates, int *no)
|
||||||
int *no)
|
|
||||||
{ return -1; };
|
{ return -1; };
|
||||||
|
|
||||||
static inline int read_msr(int cpu, unsigned int idx, unsigned long long *val)
|
static inline int read_msr(int cpu, unsigned int idx, unsigned long long *val)
|
||||||
|
@ -16,17 +16,12 @@
|
|||||||
int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active,
|
int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active,
|
||||||
int *states)
|
int *states)
|
||||||
{
|
{
|
||||||
struct cpupower_cpu_info cpu_info;
|
|
||||||
int ret;
|
int ret;
|
||||||
unsigned long long val;
|
unsigned long long val;
|
||||||
|
|
||||||
*support = *active = *states = 0;
|
*support = *active = *states = 0;
|
||||||
|
|
||||||
ret = get_cpu_info(&cpu_info);
|
if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_CPB) {
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_CBP) {
|
|
||||||
*support = 1;
|
*support = 1;
|
||||||
|
|
||||||
/* AMD Family 0x17 does not utilize PCI D18F4 like prior
|
/* AMD Family 0x17 does not utilize PCI D18F4 like prior
|
||||||
@ -34,7 +29,7 @@ int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active,
|
|||||||
* has Hardware determined variable increments instead.
|
* has Hardware determined variable increments instead.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (cpu_info.family == 0x17 || cpu_info.family == 0x18) {
|
if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_CPB_MSR) {
|
||||||
if (!read_msr(cpu, MSR_AMD_HWCR, &val)) {
|
if (!read_msr(cpu, MSR_AMD_HWCR, &val)) {
|
||||||
if (!(val & CPUPOWER_AMD_CPBDIS))
|
if (!(val & CPUPOWER_AMD_CPBDIS))
|
||||||
*active = 1;
|
*active = 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user