mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
Merge branches 'pm-qos', 'pm-domains' and 'pm-drivers'
* pm-qos: PM / QoS: Add type to dev_pm_qos_add_ancestor_request() arguments ACPI / LPSS: Support for device latency tolerance PM QoS ACPI / scan: Add bind/unbind callbacks to struct acpi_scan_handler PM / QoS: Introcuce latency tolerance device PM QoS type PM / QoS: Add no_constraints_value field to struct pm_qos_constraints PM / QoS: Rename device resume latency QoS items * pm-domains: PM / domains: Turn latency warning into debug message * pm-drivers: PM: Add pm_runtime_suspend|resume_force functions PM / runtime: Fetch runtime PM callbacks using a macro
This commit is contained in:
commit
165f5fd04a
20 changed files with 591 additions and 168 deletions
|
|
@ -33,6 +33,13 @@ ACPI_MODULE_NAME("acpi_lpss");
|
|||
#define LPSS_GENERAL_UART_RTS_OVRD BIT(3)
|
||||
#define LPSS_SW_LTR 0x10
|
||||
#define LPSS_AUTO_LTR 0x14
|
||||
#define LPSS_LTR_SNOOP_REQ BIT(15)
|
||||
#define LPSS_LTR_SNOOP_MASK 0x0000FFFF
|
||||
#define LPSS_LTR_SNOOP_LAT_1US 0x800
|
||||
#define LPSS_LTR_SNOOP_LAT_32US 0xC00
|
||||
#define LPSS_LTR_SNOOP_LAT_SHIFT 5
|
||||
#define LPSS_LTR_SNOOP_LAT_CUTOFF 3000
|
||||
#define LPSS_LTR_MAX_VAL 0x3FF
|
||||
#define LPSS_TX_INT 0x20
|
||||
#define LPSS_TX_INT_MASK BIT(1)
|
||||
|
||||
|
|
@ -326,6 +333,17 @@ static int acpi_lpss_create_device(struct acpi_device *adev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static u32 __lpss_reg_read(struct lpss_private_data *pdata, unsigned int reg)
|
||||
{
|
||||
return readl(pdata->mmio_base + pdata->dev_desc->prv_offset + reg);
|
||||
}
|
||||
|
||||
static void __lpss_reg_write(u32 val, struct lpss_private_data *pdata,
|
||||
unsigned int reg)
|
||||
{
|
||||
writel(val, pdata->mmio_base + pdata->dev_desc->prv_offset + reg);
|
||||
}
|
||||
|
||||
static int lpss_reg_read(struct device *dev, unsigned int reg, u32 *val)
|
||||
{
|
||||
struct acpi_device *adev;
|
||||
|
|
@ -347,7 +365,7 @@ static int lpss_reg_read(struct device *dev, unsigned int reg, u32 *val)
|
|||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
*val = readl(pdata->mmio_base + pdata->dev_desc->prv_offset + reg);
|
||||
*val = __lpss_reg_read(pdata, reg);
|
||||
|
||||
out:
|
||||
spin_unlock_irqrestore(&dev->power.lock, flags);
|
||||
|
|
@ -400,6 +418,37 @@ static struct attribute_group lpss_attr_group = {
|
|||
.name = "lpss_ltr",
|
||||
};
|
||||
|
||||
static void acpi_lpss_set_ltr(struct device *dev, s32 val)
|
||||
{
|
||||
struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
|
||||
u32 ltr_mode, ltr_val;
|
||||
|
||||
ltr_mode = __lpss_reg_read(pdata, LPSS_GENERAL);
|
||||
if (val < 0) {
|
||||
if (ltr_mode & LPSS_GENERAL_LTR_MODE_SW) {
|
||||
ltr_mode &= ~LPSS_GENERAL_LTR_MODE_SW;
|
||||
__lpss_reg_write(ltr_mode, pdata, LPSS_GENERAL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
ltr_val = __lpss_reg_read(pdata, LPSS_SW_LTR) & ~LPSS_LTR_SNOOP_MASK;
|
||||
if (val >= LPSS_LTR_SNOOP_LAT_CUTOFF) {
|
||||
ltr_val |= LPSS_LTR_SNOOP_LAT_32US;
|
||||
val = LPSS_LTR_MAX_VAL;
|
||||
} else if (val > LPSS_LTR_MAX_VAL) {
|
||||
ltr_val |= LPSS_LTR_SNOOP_LAT_32US | LPSS_LTR_SNOOP_REQ;
|
||||
val >>= LPSS_LTR_SNOOP_LAT_SHIFT;
|
||||
} else {
|
||||
ltr_val |= LPSS_LTR_SNOOP_LAT_1US | LPSS_LTR_SNOOP_REQ;
|
||||
}
|
||||
ltr_val |= val;
|
||||
__lpss_reg_write(ltr_val, pdata, LPSS_SW_LTR);
|
||||
if (!(ltr_mode & LPSS_GENERAL_LTR_MODE_SW)) {
|
||||
ltr_mode |= LPSS_GENERAL_LTR_MODE_SW;
|
||||
__lpss_reg_write(ltr_mode, pdata, LPSS_GENERAL);
|
||||
}
|
||||
}
|
||||
|
||||
static int acpi_lpss_platform_notify(struct notifier_block *nb,
|
||||
unsigned long action, void *data)
|
||||
{
|
||||
|
|
@ -437,9 +486,29 @@ static struct notifier_block acpi_lpss_nb = {
|
|||
.notifier_call = acpi_lpss_platform_notify,
|
||||
};
|
||||
|
||||
static void acpi_lpss_bind(struct device *dev)
|
||||
{
|
||||
struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
|
||||
|
||||
if (!pdata || !pdata->mmio_base || !pdata->dev_desc->ltr_required)
|
||||
return;
|
||||
|
||||
if (pdata->mmio_size >= pdata->dev_desc->prv_offset + LPSS_LTR_SIZE)
|
||||
dev->power.set_latency_tolerance = acpi_lpss_set_ltr;
|
||||
else
|
||||
dev_err(dev, "MMIO size insufficient to access LTR\n");
|
||||
}
|
||||
|
||||
static void acpi_lpss_unbind(struct device *dev)
|
||||
{
|
||||
dev->power.set_latency_tolerance = NULL;
|
||||
}
|
||||
|
||||
static struct acpi_scan_handler lpss_handler = {
|
||||
.ids = acpi_lpss_device_ids,
|
||||
.attach = acpi_lpss_create_device,
|
||||
.bind = acpi_lpss_bind,
|
||||
.unbind = acpi_lpss_unbind,
|
||||
};
|
||||
|
||||
void __init acpi_lpss_init(void)
|
||||
|
|
|
|||
|
|
@ -287,6 +287,7 @@ EXPORT_SYMBOL_GPL(acpi_unbind_one);
|
|||
static int acpi_platform_notify(struct device *dev)
|
||||
{
|
||||
struct acpi_bus_type *type = acpi_get_bus_type(dev);
|
||||
struct acpi_device *adev;
|
||||
int ret;
|
||||
|
||||
ret = acpi_bind_one(dev, NULL);
|
||||
|
|
@ -303,9 +304,14 @@ static int acpi_platform_notify(struct device *dev)
|
|||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
adev = ACPI_COMPANION(dev);
|
||||
if (!adev)
|
||||
goto out;
|
||||
|
||||
if (type && type->setup)
|
||||
type->setup(dev);
|
||||
else if (adev->handler && adev->handler->bind)
|
||||
adev->handler->bind(dev);
|
||||
|
||||
out:
|
||||
#if ACPI_GLUE_DEBUG
|
||||
|
|
@ -324,11 +330,17 @@ static int acpi_platform_notify(struct device *dev)
|
|||
|
||||
static int acpi_platform_notify_remove(struct device *dev)
|
||||
{
|
||||
struct acpi_device *adev = ACPI_COMPANION(dev);
|
||||
struct acpi_bus_type *type;
|
||||
|
||||
if (!adev)
|
||||
return 0;
|
||||
|
||||
type = acpi_get_bus_type(dev);
|
||||
if (type && type->cleanup)
|
||||
type->cleanup(dev);
|
||||
else if (adev->handler && adev->handler->unbind)
|
||||
adev->handler->unbind(dev);
|
||||
|
||||
acpi_unbind_one(dev);
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -2072,13 +2072,14 @@ static int acpi_scan_attach_handler(struct acpi_device *device)
|
|||
|
||||
handler = acpi_scan_match_handler(hwid->id, &devid);
|
||||
if (handler) {
|
||||
device->handler = handler;
|
||||
ret = handler->attach(device, devid);
|
||||
if (ret > 0) {
|
||||
device->handler = handler;
|
||||
if (ret > 0)
|
||||
break;
|
||||
} else if (ret < 0) {
|
||||
|
||||
device->handler = NULL;
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
|
|
|||
Loading…
Reference in a new issue