linux/drivers/acpi/x86/lpss.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * ACPI support for Intel Lynxpoint LPSS.
 *
 * Copyright (C) 2013, Intel Corporation
 * Authors: Mika Westerberg <[email protected]>
 *          Rafael J. Wysocki <[email protected]>
 */

#include <linux/acpi.h>
#include <linux/clkdev.h>
#include <linux/clk-provider.h>
#include <linux/dmi.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/mutex.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/platform_data/x86/clk-lpss.h>
#include <linux/platform_data/x86/pmc_atom.h>
#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>
#include <linux/pwm.h>
#include <linux/pxa2xx_ssp.h>
#include <linux/suspend.h>
#include <linux/delay.h>

#include "../internal.h"

#ifdef CONFIG_X86_INTEL_LPSS

#include <asm/cpu_device_id.h>
#include <asm/intel-family.h>
#include <asm/iosf_mbi.h>

#define LPSS_ADDR(desc)

#define LPSS_CLK_SIZE
#define LPSS_LTR_SIZE

/* Offsets relative to LPSS_PRIVATE_OFFSET */
#define LPSS_CLK_DIVIDER_DEF_MASK
#define LPSS_RESETS
#define LPSS_RESETS_RESET_FUNC
#define LPSS_RESETS_RESET_APB
#define LPSS_GENERAL
#define LPSS_GENERAL_LTR_MODE_SW
#define LPSS_GENERAL_UART_RTS_OVRD
#define LPSS_SW_LTR
#define LPSS_AUTO_LTR
#define LPSS_LTR_SNOOP_REQ
#define LPSS_LTR_SNOOP_MASK
#define LPSS_LTR_SNOOP_LAT_1US
#define LPSS_LTR_SNOOP_LAT_32US
#define LPSS_LTR_SNOOP_LAT_SHIFT
#define LPSS_LTR_SNOOP_LAT_CUTOFF
#define LPSS_LTR_MAX_VAL
#define LPSS_TX_INT
#define LPSS_TX_INT_MASK

#define LPSS_PRV_REG_COUNT

/* LPSS Flags */
#define LPSS_CLK
#define LPSS_CLK_GATE
#define LPSS_CLK_DIVIDER
#define LPSS_LTR
#define LPSS_SAVE_CTX
/*
 * For some devices the DSDT AML code for another device turns off the device
 * before our suspend handler runs, causing us to read/save all 1-s (0xffffffff)
 * as ctx register values.
 * Luckily these devices always use the same ctx register values, so we can
 * work around this by saving the ctx registers once on activation.
 */
#define LPSS_SAVE_CTX_ONCE
#define LPSS_NO_D3_DELAY

struct lpss_private_data;

struct lpss_device_desc {};

static const struct lpss_device_desc lpss_dma_desc =;

struct lpss_private_data {};

/* Devices which need to be in D3 before lpss_iosf_enter_d3_state() proceeds */
static u32 pmc_atom_d3_mask =;

/* LPSS run time quirks */
static unsigned int lpss_quirks;

/*
 * LPSS_QUIRK_ALWAYS_POWER_ON: override power state for LPSS DMA device.
 *
 * The LPSS DMA controller has neither _PS0 nor _PS3 method. Moreover
 * it can be powered off automatically whenever the last LPSS device goes down.
 * In case of no power any access to the DMA controller will hang the system.
 * The behaviour is reproduced on some HP laptops based on Intel BayTrail as
 * well as on ASuS T100TA transformer.
 *
 * This quirk overrides power state of entire LPSS island to keep DMA powered
 * on whenever we have at least one other device in use.
 */
#define LPSS_QUIRK_ALWAYS_POWER_ON

/* UART Component Parameter Register */
#define LPSS_UART_CPR
#define LPSS_UART_CPR_AFCE

static void lpss_uart_setup(struct lpss_private_data *pdata)
{}

static void lpss_deassert_reset(struct lpss_private_data *pdata)
{}

/*
 * BYT PWM used for backlight control by the i915 driver on systems without
 * the Crystal Cove PMIC.
 */
static struct pwm_lookup byt_pwm_lookup[] =;

static void byt_pwm_setup(struct lpss_private_data *pdata)
{}

#define LPSS_I2C_ENABLE

static void byt_i2c_setup(struct lpss_private_data *pdata)
{}

/*
 * BSW PWM1 is used for backlight control by the i915 driver
 * BSW PWM2 is used for backlight control for fixed (etched into the glass)
 * touch controls on some models. These touch-controls have specialized
 * drivers which know they need the "pwm_soc_lpss_2" con-id.
 */
static struct pwm_lookup bsw_pwm_lookup[] =;

static void bsw_pwm_setup(struct lpss_private_data *pdata)
{}

static const struct property_entry lpt_spi_properties[] =;

static const struct lpss_device_desc lpt_spi_dev_desc =;

static const struct lpss_device_desc lpt_i2c_dev_desc =;

static struct property_entry uart_properties[] =;

static const struct lpss_device_desc lpt_uart_dev_desc =;

static const struct lpss_device_desc lpt_sdio_dev_desc =;

static const struct lpss_device_desc byt_pwm_dev_desc =;

static const struct lpss_device_desc bsw_pwm_dev_desc =;

static const struct lpss_device_desc bsw_pwm2_dev_desc =;

static const struct lpss_device_desc byt_uart_dev_desc =;

static const struct lpss_device_desc bsw_uart_dev_desc =;

static const struct property_entry byt_spi_properties[] =;

static const struct lpss_device_desc byt_spi_dev_desc =;

static const struct lpss_device_desc byt_sdio_dev_desc =;

static const struct lpss_device_desc byt_i2c_dev_desc =;

static const struct lpss_device_desc bsw_i2c_dev_desc =;

static const struct property_entry bsw_spi_properties[] =;

static const struct lpss_device_desc bsw_spi_dev_desc =;

static const struct x86_cpu_id lpss_cpu_ids[] =;

#else

#define LPSS_ADDR

#endif /* CONFIG_X86_INTEL_LPSS */

static const struct acpi_device_id acpi_lpss_device_ids[] =;

#ifdef CONFIG_X86_INTEL_LPSS

/* LPSS main clock device. */
static struct platform_device *lpss_clk_dev;

static inline void lpt_register_clock_device(void)
{}

static int register_device_clock(struct acpi_device *adev,
				 struct lpss_private_data *pdata)
{}

struct lpss_device_links {};

/* Please keep this list sorted alphabetically by vendor and model */
static const struct dmi_system_id i2c1_dep_missing_dmi_ids[] =;

/*
 * The _DEP method is used to identify dependencies but instead of creating
 * device links for every handle in _DEP, only links in the following list are
 * created. That is necessary because, in the general case, _DEP can refer to
 * devices that might not have drivers, or that are on different buses, or where
 * the supplier is not enumerated until after the consumer is probed.
 */
static const struct lpss_device_links lpss_device_links[] =;

static bool acpi_lpss_is_supplier(struct acpi_device *adev,
				  const struct lpss_device_links *link)
{}

static bool acpi_lpss_is_consumer(struct acpi_device *adev,
				  const struct lpss_device_links *link)
{}

struct hid_uid {};

static int match_hid_uid(struct device *dev, const void *data)
{}

static struct device *acpi_lpss_find_device(const char *hid, const char *uid)
{}

static void acpi_lpss_link_consumer(struct device *dev1,
				    const struct lpss_device_links *link)
{}

static void acpi_lpss_link_supplier(struct device *dev1,
				    const struct lpss_device_links *link)
{}

static void acpi_lpss_create_device_links(struct acpi_device *adev,
					  struct platform_device *pdev)
{}

static int acpi_lpss_create_device(struct acpi_device *adev,
				   const struct acpi_device_id *id)
{}

static u32 __lpss_reg_read(struct lpss_private_data *pdata, unsigned int reg)
{}

static void __lpss_reg_write(u32 val, struct lpss_private_data *pdata,
			     unsigned int reg)
{}

static int lpss_reg_read(struct device *dev, unsigned int reg, u32 *val)
{}

static ssize_t lpss_ltr_show(struct device *dev, struct device_attribute *attr,
			     char *buf)
{}

static ssize_t lpss_ltr_mode_show(struct device *dev,
				  struct device_attribute *attr, char *buf)
{}

static DEVICE_ATTR(auto_ltr, S_IRUSR, lpss_ltr_show, NULL);
static DEVICE_ATTR(sw_ltr, S_IRUSR, lpss_ltr_show, NULL);
static DEVICE_ATTR(ltr_mode, S_IRUSR, lpss_ltr_mode_show, NULL);

static struct attribute *lpss_attrs[] =;

static const struct attribute_group lpss_attr_group =;

static void acpi_lpss_set_ltr(struct device *dev, s32 val)
{}

#ifdef CONFIG_PM
/**
 * acpi_lpss_save_ctx() - Save the private registers of LPSS device
 * @dev: LPSS device
 * @pdata: pointer to the private data of the LPSS device
 *
 * Most LPSS devices have private registers which may loose their context when
 * the device is powered down. acpi_lpss_save_ctx() saves those registers into
 * prv_reg_ctx array.
 */
static void acpi_lpss_save_ctx(struct device *dev,
			       struct lpss_private_data *pdata)
{}

/**
 * acpi_lpss_restore_ctx() - Restore the private registers of LPSS device
 * @dev: LPSS device
 * @pdata: pointer to the private data of the LPSS device
 *
 * Restores the registers that were previously stored with acpi_lpss_save_ctx().
 */
static void acpi_lpss_restore_ctx(struct device *dev,
				  struct lpss_private_data *pdata)
{}

static void acpi_lpss_d3_to_d0_delay(struct lpss_private_data *pdata)
{}

static int acpi_lpss_activate(struct device *dev)
{}

static void acpi_lpss_dismiss(struct device *dev)
{}

/* IOSF SB for LPSS island */
#define LPSS_IOSF_UNIT_LPIOEP
#define LPSS_IOSF_UNIT_LPIO1
#define LPSS_IOSF_UNIT_LPIO2

#define LPSS_IOSF_PMCSR
#define LPSS_PMCSR_D0
#define LPSS_PMCSR_D3hot
#define LPSS_PMCSR_Dx_MASK

#define LPSS_IOSF_GPIODEF0
#define LPSS_GPIODEF0_DMA1_D3
#define LPSS_GPIODEF0_DMA2_D3
#define LPSS_GPIODEF0_DMA_D3_MASK
#define LPSS_GPIODEF0_DMA_LLP

static DEFINE_MUTEX(lpss_iosf_mutex);
static bool lpss_iosf_d3_entered =;

static void lpss_iosf_enter_d3_state(void)
{}

static void lpss_iosf_exit_d3_state(void)
{}

static int acpi_lpss_suspend(struct device *dev, bool wakeup)
{}

static int acpi_lpss_resume(struct device *dev)
{}

#ifdef CONFIG_PM_SLEEP
static int acpi_lpss_do_suspend_late(struct device *dev)
{}

static int acpi_lpss_suspend_late(struct device *dev)
{}

static int acpi_lpss_suspend_noirq(struct device *dev)
{}

static int acpi_lpss_do_resume_early(struct device *dev)
{}

static int acpi_lpss_resume_early(struct device *dev)
{}

static int acpi_lpss_resume_noirq(struct device *dev)
{}

static int acpi_lpss_do_restore_early(struct device *dev)
{}

static int acpi_lpss_restore_early(struct device *dev)
{}

static int acpi_lpss_restore_noirq(struct device *dev)
{}

static int acpi_lpss_do_poweroff_late(struct device *dev)
{}

static int acpi_lpss_poweroff_late(struct device *dev)
{}

static int acpi_lpss_poweroff_noirq(struct device *dev)
{}
#endif /* CONFIG_PM_SLEEP */

static int acpi_lpss_runtime_suspend(struct device *dev)
{}

static int acpi_lpss_runtime_resume(struct device *dev)
{}
#endif /* CONFIG_PM */

static struct dev_pm_domain acpi_lpss_pm_domain =;

static int acpi_lpss_platform_notify(struct notifier_block *nb,
				     unsigned long action, void *data)
{}

static struct notifier_block acpi_lpss_nb =;

static void acpi_lpss_bind(struct device *dev)
{}

static void acpi_lpss_unbind(struct device *dev)
{}

static struct acpi_scan_handler lpss_handler =;

void __init acpi_lpss_init(void)
{}

#else

static struct acpi_scan_handler lpss_handler = {
	.ids = acpi_lpss_device_ids,
};

void __init acpi_lpss_init(void)
{
	acpi_scan_add_handler(&lpss_handler);
}

#endif /* CONFIG_X86_INTEL_LPSS */