Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6: ACPI / PM: Move ACPI video resume to a PM notifier ACPI: Reduce ACPI resource conflict message to KERN_WARNING, printk cleanup ACPI: battery drivers should call power_supply_changed() ACPI: battery: Fix CONFIG_ACPI_SYSFS_POWER=n PNPACPI: truncate _CRS windows with _LEN > _MAX - _MIN + 1 ACPI: Don't send KEY_UNKNOWN for random video notifications ACPI: NUMA: map pxms to low node ids ACPI: use _HID when supplied by root-level devices ACPI / ACPICA: Do not check reference counters in acpi_ev_enable_gpe() ACPI: fixes a false alarm from lockdep ACPI dock: support multiple ACPI dock devices ACPI: EC: Allow multibyte access to EC
This commit is contained in:
commit
0a2851b9a8
@ -117,19 +117,14 @@ acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
|
||||
if (ACPI_FAILURE(status))
|
||||
return_ACPI_STATUS(status);
|
||||
|
||||
/* Mark wake-enabled or HW enable, or both */
|
||||
/* Clear the GPE (of stale events), then enable it */
|
||||
status = acpi_hw_clear_gpe(gpe_event_info);
|
||||
if (ACPI_FAILURE(status))
|
||||
return_ACPI_STATUS(status);
|
||||
|
||||
if (gpe_event_info->runtime_count) {
|
||||
/* Clear the GPE (of stale events), then enable it */
|
||||
status = acpi_hw_clear_gpe(gpe_event_info);
|
||||
if (ACPI_FAILURE(status))
|
||||
return_ACPI_STATUS(status);
|
||||
|
||||
/* Enable the requested runtime GPE */
|
||||
status = acpi_hw_write_gpe_enable_reg(gpe_event_info);
|
||||
}
|
||||
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
/* Enable the requested GPE */
|
||||
status = acpi_hw_write_gpe_enable_reg(gpe_event_info);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -468,6 +468,18 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
|
||||
|
||||
acpi_ut_add_reference(obj_desc->field.region_obj);
|
||||
|
||||
/* allow full data read from EC address space */
|
||||
if (obj_desc->field.region_obj->region.space_id ==
|
||||
ACPI_ADR_SPACE_EC) {
|
||||
if (obj_desc->common_field.bit_length > 8)
|
||||
obj_desc->common_field.access_bit_width =
|
||||
ACPI_ROUND_UP(obj_desc->common_field.
|
||||
bit_length, 8);
|
||||
obj_desc->common_field.access_byte_width =
|
||||
ACPI_DIV_8(obj_desc->common_field.
|
||||
access_bit_width);
|
||||
}
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
|
||||
"RegionField: BitOff %X, Off %X, Gran %X, Region %p\n",
|
||||
obj_desc->field.start_field_bit_offset,
|
||||
|
@ -568,13 +568,13 @@ static int acpi_battery_update(struct acpi_battery *battery)
|
||||
result = acpi_battery_get_status(battery);
|
||||
if (result)
|
||||
return result;
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
if (!acpi_battery_present(battery)) {
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
sysfs_remove_battery(battery);
|
||||
#endif
|
||||
battery->update_time = 0;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if (!battery->update_time ||
|
||||
old_present != acpi_battery_present(battery)) {
|
||||
result = acpi_battery_get_info(battery);
|
||||
@ -880,7 +880,7 @@ static void acpi_battery_notify(struct acpi_device *device, u32 event)
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
/* acpi_battery_update could remove power_supply object */
|
||||
if (battery->bat.dev)
|
||||
kobject_uevent(&battery->bat.dev->kobj, KOBJ_CHANGE);
|
||||
power_supply_changed(&battery->bat);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1026,13 +1026,10 @@ static int dock_remove(struct dock_station *ds)
|
||||
static acpi_status
|
||||
find_dock(acpi_handle handle, u32 lvl, void *context, void **rv)
|
||||
{
|
||||
acpi_status status = AE_OK;
|
||||
|
||||
if (is_dock(handle))
|
||||
if (dock_add(handle) >= 0)
|
||||
status = AE_CTRL_TERMINATE;
|
||||
dock_add(handle);
|
||||
|
||||
return status;
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
static acpi_status
|
||||
|
@ -629,12 +629,12 @@ static u32 acpi_ec_gpe_handler(void *data)
|
||||
|
||||
static acpi_status
|
||||
acpi_ec_space_handler(u32 function, acpi_physical_address address,
|
||||
u32 bits, u64 *value,
|
||||
u32 bits, u64 *value64,
|
||||
void *handler_context, void *region_context)
|
||||
{
|
||||
struct acpi_ec *ec = handler_context;
|
||||
int result = 0, i;
|
||||
u8 temp = 0;
|
||||
int result = 0, i, bytes = bits / 8;
|
||||
u8 *value = (u8 *)value64;
|
||||
|
||||
if ((address > 0xFF) || !value || !handler_context)
|
||||
return AE_BAD_PARAMETER;
|
||||
@ -642,32 +642,15 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
|
||||
if (function != ACPI_READ && function != ACPI_WRITE)
|
||||
return AE_BAD_PARAMETER;
|
||||
|
||||
if (bits != 8 && acpi_strict)
|
||||
return AE_BAD_PARAMETER;
|
||||
|
||||
if (EC_FLAGS_MSI)
|
||||
if (EC_FLAGS_MSI || bits > 8)
|
||||
acpi_ec_burst_enable(ec);
|
||||
|
||||
if (function == ACPI_READ) {
|
||||
result = acpi_ec_read(ec, address, &temp);
|
||||
*value = temp;
|
||||
} else {
|
||||
temp = 0xff & (*value);
|
||||
result = acpi_ec_write(ec, address, temp);
|
||||
}
|
||||
for (i = 0; i < bytes; ++i, ++address, ++value)
|
||||
result = (function == ACPI_READ) ?
|
||||
acpi_ec_read(ec, address, value) :
|
||||
acpi_ec_write(ec, address, *value);
|
||||
|
||||
for (i = 8; unlikely(bits - i > 0); i += 8) {
|
||||
++address;
|
||||
if (function == ACPI_READ) {
|
||||
result = acpi_ec_read(ec, address, &temp);
|
||||
(*value) |= ((u64)temp) << i;
|
||||
} else {
|
||||
temp = 0xff & ((*value) >> i);
|
||||
result = acpi_ec_write(ec, address, temp);
|
||||
}
|
||||
}
|
||||
|
||||
if (EC_FLAGS_MSI)
|
||||
if (EC_FLAGS_MSI || bits > 8)
|
||||
acpi_ec_burst_disable(ec);
|
||||
|
||||
switch (result) {
|
||||
|
@ -61,8 +61,10 @@ int node_to_pxm(int node)
|
||||
|
||||
void __acpi_map_pxm_to_node(int pxm, int node)
|
||||
{
|
||||
pxm_to_node_map[pxm] = node;
|
||||
node_to_pxm_map[node] = pxm;
|
||||
if (pxm_to_node_map[pxm] == NUMA_NO_NODE || node < pxm_to_node_map[pxm])
|
||||
pxm_to_node_map[pxm] = node;
|
||||
if (node_to_pxm_map[node] == PXM_INVAL || pxm < node_to_pxm_map[node])
|
||||
node_to_pxm_map[node] = pxm;
|
||||
}
|
||||
|
||||
int acpi_map_pxm_to_node(int pxm)
|
||||
|
@ -758,7 +758,14 @@ static acpi_status __acpi_os_execute(acpi_execute_type type,
|
||||
queue = hp ? kacpi_hotplug_wq :
|
||||
(type == OSL_NOTIFY_HANDLER ? kacpi_notify_wq : kacpid_wq);
|
||||
dpc->wait = hp ? 1 : 0;
|
||||
INIT_WORK(&dpc->work, acpi_os_execute_deferred);
|
||||
|
||||
if (queue == kacpi_hotplug_wq)
|
||||
INIT_WORK(&dpc->work, acpi_os_execute_deferred);
|
||||
else if (queue == kacpi_notify_wq)
|
||||
INIT_WORK(&dpc->work, acpi_os_execute_deferred);
|
||||
else
|
||||
INIT_WORK(&dpc->work, acpi_os_execute_deferred);
|
||||
|
||||
ret = queue_work(queue, &dpc->work);
|
||||
|
||||
if (!ret) {
|
||||
@ -1151,16 +1158,10 @@ int acpi_check_resource_conflict(const struct resource *res)
|
||||
|
||||
if (clash) {
|
||||
if (acpi_enforce_resources != ENFORCE_RESOURCES_NO) {
|
||||
printk("%sACPI: %s resource %s [0x%llx-0x%llx]"
|
||||
" conflicts with ACPI region %s"
|
||||
" [0x%llx-0x%llx]\n",
|
||||
acpi_enforce_resources == ENFORCE_RESOURCES_LAX
|
||||
? KERN_WARNING : KERN_ERR,
|
||||
ioport ? "I/O" : "Memory", res->name,
|
||||
(long long) res->start, (long long) res->end,
|
||||
res_list_elem->name,
|
||||
(long long) res_list_elem->start,
|
||||
(long long) res_list_elem->end);
|
||||
printk(KERN_WARNING "ACPI: resource %s %pR"
|
||||
" conflicts with ACPI region %s %pR\n",
|
||||
res->name, res, res_list_elem->name,
|
||||
res_list_elem);
|
||||
if (acpi_enforce_resources == ENFORCE_RESOURCES_LAX)
|
||||
printk(KERN_NOTICE "ACPI: This conflict may"
|
||||
" cause random problems and system"
|
||||
|
@ -1081,12 +1081,6 @@ static void acpi_device_set_id(struct acpi_device *device)
|
||||
if (ACPI_IS_ROOT_DEVICE(device)) {
|
||||
acpi_add_id(device, ACPI_SYSTEM_HID);
|
||||
break;
|
||||
} else if (ACPI_IS_ROOT_DEVICE(device->parent)) {
|
||||
/* \_SB_, the only root-level namespace device */
|
||||
acpi_add_id(device, ACPI_BUS_HID);
|
||||
strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME);
|
||||
strcpy(device->pnp.device_class, ACPI_BUS_CLASS);
|
||||
break;
|
||||
}
|
||||
|
||||
status = acpi_get_object_info(device->handle, &info);
|
||||
@ -1121,6 +1115,12 @@ static void acpi_device_set_id(struct acpi_device *device)
|
||||
acpi_add_id(device, ACPI_DOCK_HID);
|
||||
else if (!acpi_ibm_smbus_match(device))
|
||||
acpi_add_id(device, ACPI_SMBUS_IBM_HID);
|
||||
else if (!acpi_device_hid(device) &&
|
||||
ACPI_IS_ROOT_DEVICE(device->parent)) {
|
||||
acpi_add_id(device, ACPI_BUS_HID); /* \_SB, LNXSYBUS */
|
||||
strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME);
|
||||
strcpy(device->pnp.device_class, ACPI_BUS_CLASS);
|
||||
}
|
||||
|
||||
break;
|
||||
case ACPI_BUS_TYPE_POWER:
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include <linux/dmi.h>
|
||||
#include <acpi/acpi_bus.h>
|
||||
#include <acpi/acpi_drivers.h>
|
||||
#include <linux/suspend.h>
|
||||
|
||||
#define PREFIX "ACPI: "
|
||||
|
||||
@ -89,7 +90,6 @@ module_param(allow_duplicates, bool, 0644);
|
||||
static int register_count = 0;
|
||||
static int acpi_video_bus_add(struct acpi_device *device);
|
||||
static int acpi_video_bus_remove(struct acpi_device *device, int type);
|
||||
static int acpi_video_resume(struct acpi_device *device);
|
||||
static void acpi_video_bus_notify(struct acpi_device *device, u32 event);
|
||||
|
||||
static const struct acpi_device_id video_device_ids[] = {
|
||||
@ -105,7 +105,6 @@ static struct acpi_driver acpi_video_bus = {
|
||||
.ops = {
|
||||
.add = acpi_video_bus_add,
|
||||
.remove = acpi_video_bus_remove,
|
||||
.resume = acpi_video_resume,
|
||||
.notify = acpi_video_bus_notify,
|
||||
},
|
||||
};
|
||||
@ -160,6 +159,7 @@ struct acpi_video_bus {
|
||||
struct proc_dir_entry *dir;
|
||||
struct input_dev *input;
|
||||
char phys[32]; /* for input device */
|
||||
struct notifier_block pm_nb;
|
||||
};
|
||||
|
||||
struct acpi_video_device_flags {
|
||||
@ -1021,6 +1021,13 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
|
||||
if (IS_ERR(device->backlight))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Save current brightness level in case we have to restore it
|
||||
* before acpi_video_device_lcd_set_level() is called next time.
|
||||
*/
|
||||
device->backlight->props.brightness =
|
||||
acpi_video_get_brightness(device->backlight);
|
||||
|
||||
result = sysfs_create_link(&device->backlight->dev.kobj,
|
||||
&device->dev->dev.kobj, "device");
|
||||
if (result)
|
||||
@ -2123,7 +2130,7 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
|
||||
{
|
||||
struct acpi_video_bus *video = acpi_driver_data(device);
|
||||
struct input_dev *input;
|
||||
int keycode;
|
||||
int keycode = 0;
|
||||
|
||||
if (!video)
|
||||
return;
|
||||
@ -2159,17 +2166,19 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
|
||||
break;
|
||||
|
||||
default:
|
||||
keycode = KEY_UNKNOWN;
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"Unsupported event [0x%x]\n", event));
|
||||
break;
|
||||
}
|
||||
|
||||
acpi_notifier_call_chain(device, event, 0);
|
||||
input_report_key(input, keycode, 1);
|
||||
input_sync(input);
|
||||
input_report_key(input, keycode, 0);
|
||||
input_sync(input);
|
||||
|
||||
if (keycode) {
|
||||
input_report_key(input, keycode, 1);
|
||||
input_sync(input);
|
||||
input_report_key(input, keycode, 0);
|
||||
input_sync(input);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@ -2180,7 +2189,7 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
|
||||
struct acpi_device *device = NULL;
|
||||
struct acpi_video_bus *bus;
|
||||
struct input_dev *input;
|
||||
int keycode;
|
||||
int keycode = 0;
|
||||
|
||||
if (!video_device)
|
||||
return;
|
||||
@ -2221,39 +2230,48 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
|
||||
keycode = KEY_DISPLAY_OFF;
|
||||
break;
|
||||
default:
|
||||
keycode = KEY_UNKNOWN;
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"Unsupported event [0x%x]\n", event));
|
||||
break;
|
||||
}
|
||||
|
||||
acpi_notifier_call_chain(device, event, 0);
|
||||
input_report_key(input, keycode, 1);
|
||||
input_sync(input);
|
||||
input_report_key(input, keycode, 0);
|
||||
input_sync(input);
|
||||
|
||||
if (keycode) {
|
||||
input_report_key(input, keycode, 1);
|
||||
input_sync(input);
|
||||
input_report_key(input, keycode, 0);
|
||||
input_sync(input);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int instance;
|
||||
static int acpi_video_resume(struct acpi_device *device)
|
||||
static int acpi_video_resume(struct notifier_block *nb,
|
||||
unsigned long val, void *ign)
|
||||
{
|
||||
struct acpi_video_bus *video;
|
||||
struct acpi_video_device *video_device;
|
||||
int i;
|
||||
|
||||
if (!device || !acpi_driver_data(device))
|
||||
return -EINVAL;
|
||||
switch (val) {
|
||||
case PM_HIBERNATION_PREPARE:
|
||||
case PM_SUSPEND_PREPARE:
|
||||
case PM_RESTORE_PREPARE:
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
video = acpi_driver_data(device);
|
||||
video = container_of(nb, struct acpi_video_bus, pm_nb);
|
||||
|
||||
dev_info(&video->device->dev, "Restoring backlight state\n");
|
||||
|
||||
for (i = 0; i < video->attached_count; i++) {
|
||||
video_device = video->attached_array[i].bind_info;
|
||||
if (video_device && video_device->backlight)
|
||||
acpi_video_set_brightness(video_device->backlight);
|
||||
}
|
||||
return AE_OK;
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static acpi_status
|
||||
@ -2277,6 +2295,8 @@ acpi_video_bus_match(acpi_handle handle, u32 level, void *context,
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
static int instance;
|
||||
|
||||
static int acpi_video_bus_add(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_video_bus *video;
|
||||
@ -2358,7 +2378,6 @@ static int acpi_video_bus_add(struct acpi_device *device)
|
||||
set_bit(KEY_BRIGHTNESSDOWN, input->keybit);
|
||||
set_bit(KEY_BRIGHTNESS_ZERO, input->keybit);
|
||||
set_bit(KEY_DISPLAY_OFF, input->keybit);
|
||||
set_bit(KEY_UNKNOWN, input->keybit);
|
||||
|
||||
error = input_register_device(input);
|
||||
if (error)
|
||||
@ -2370,6 +2389,10 @@ static int acpi_video_bus_add(struct acpi_device *device)
|
||||
video->flags.rom ? "yes" : "no",
|
||||
video->flags.post ? "yes" : "no");
|
||||
|
||||
video->pm_nb.notifier_call = acpi_video_resume;
|
||||
video->pm_nb.priority = 0;
|
||||
register_pm_notifier(&video->pm_nb);
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_input_dev:
|
||||
@ -2396,6 +2419,8 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type)
|
||||
|
||||
video = acpi_driver_data(device);
|
||||
|
||||
unregister_pm_notifier(&video->pm_nb);
|
||||
|
||||
acpi_video_bus_stop_devices(video);
|
||||
acpi_video_bus_put_devices(video);
|
||||
acpi_video_bus_remove_fs(device);
|
||||
|
@ -274,12 +274,33 @@ static void pnpacpi_parse_allocated_busresource(struct pnp_dev *dev,
|
||||
pnp_add_bus_resource(dev, start, end);
|
||||
}
|
||||
|
||||
static u64 addr_space_length(struct pnp_dev *dev, u64 min, u64 max, u64 len)
|
||||
{
|
||||
u64 max_len;
|
||||
|
||||
max_len = max - min + 1;
|
||||
if (len <= max_len)
|
||||
return len;
|
||||
|
||||
/*
|
||||
* Per 6.4.3.5, _LEN cannot exceed _MAX - _MIN + 1, but some BIOSes
|
||||
* don't do this correctly, e.g.,
|
||||
* https://bugzilla.kernel.org/show_bug.cgi?id=15480
|
||||
*/
|
||||
dev_info(&dev->dev,
|
||||
"resource length %#llx doesn't fit in %#llx-%#llx, trimming\n",
|
||||
(unsigned long long) len, (unsigned long long) min,
|
||||
(unsigned long long) max);
|
||||
return max_len;
|
||||
}
|
||||
|
||||
static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev,
|
||||
struct acpi_resource *res)
|
||||
{
|
||||
struct acpi_resource_address64 addr, *p = &addr;
|
||||
acpi_status status;
|
||||
int window;
|
||||
u64 len;
|
||||
|
||||
status = acpi_resource_to_address64(res, p);
|
||||
if (!ACPI_SUCCESS(status)) {
|
||||
@ -288,20 +309,18 @@ static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev,
|
||||
return;
|
||||
}
|
||||
|
||||
len = addr_space_length(dev, p->minimum, p->maximum, p->address_length);
|
||||
window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0;
|
||||
|
||||
if (p->resource_type == ACPI_MEMORY_RANGE)
|
||||
pnpacpi_parse_allocated_memresource(dev,
|
||||
p->minimum, p->address_length,
|
||||
pnpacpi_parse_allocated_memresource(dev, p->minimum, len,
|
||||
p->info.mem.write_protect, window);
|
||||
else if (p->resource_type == ACPI_IO_RANGE)
|
||||
pnpacpi_parse_allocated_ioresource(dev,
|
||||
p->minimum, p->address_length,
|
||||
pnpacpi_parse_allocated_ioresource(dev, p->minimum, len,
|
||||
p->granularity == 0xfff ? ACPI_DECODE_10 :
|
||||
ACPI_DECODE_16, window);
|
||||
else if (p->resource_type == ACPI_BUS_NUMBER_RANGE)
|
||||
pnpacpi_parse_allocated_busresource(dev, p->minimum,
|
||||
p->address_length);
|
||||
pnpacpi_parse_allocated_busresource(dev, p->minimum, len);
|
||||
}
|
||||
|
||||
static void pnpacpi_parse_allocated_ext_address_space(struct pnp_dev *dev,
|
||||
@ -309,21 +328,20 @@ static void pnpacpi_parse_allocated_ext_address_space(struct pnp_dev *dev,
|
||||
{
|
||||
struct acpi_resource_extended_address64 *p = &res->data.ext_address64;
|
||||
int window;
|
||||
u64 len;
|
||||
|
||||
len = addr_space_length(dev, p->minimum, p->maximum, p->address_length);
|
||||
window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0;
|
||||
|
||||
if (p->resource_type == ACPI_MEMORY_RANGE)
|
||||
pnpacpi_parse_allocated_memresource(dev,
|
||||
p->minimum, p->address_length,
|
||||
pnpacpi_parse_allocated_memresource(dev, p->minimum, len,
|
||||
p->info.mem.write_protect, window);
|
||||
else if (p->resource_type == ACPI_IO_RANGE)
|
||||
pnpacpi_parse_allocated_ioresource(dev,
|
||||
p->minimum, p->address_length,
|
||||
pnpacpi_parse_allocated_ioresource(dev, p->minimum, len,
|
||||
p->granularity == 0xfff ? ACPI_DECODE_10 :
|
||||
ACPI_DECODE_16, window);
|
||||
else if (p->resource_type == ACPI_BUS_NUMBER_RANGE)
|
||||
pnpacpi_parse_allocated_busresource(dev, p->minimum,
|
||||
p->address_length);
|
||||
pnpacpi_parse_allocated_busresource(dev, p->minimum, len);
|
||||
}
|
||||
|
||||
static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
|
||||
|
Loading…
Reference in New Issue
Block a user