^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Intel LPSS ACPI support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2015, Intel Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Mika Westerberg <mika.westerberg@linux.intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/property.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "intel-lpss.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) static const struct intel_lpss_platform_info spt_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) .clk_rate = 120000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) static struct property_entry spt_i2c_properties[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 230),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static const struct intel_lpss_platform_info spt_i2c_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) .clk_rate = 120000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) .properties = spt_i2c_properties,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static struct property_entry uart_properties[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) PROPERTY_ENTRY_U32("reg-io-width", 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) PROPERTY_ENTRY_U32("reg-shift", 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) PROPERTY_ENTRY_BOOL("snps,uart-16550-compatible"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static const struct intel_lpss_platform_info spt_uart_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) .clk_rate = 120000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) .clk_con_id = "baudclk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) .properties = uart_properties,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) static const struct intel_lpss_platform_info bxt_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) .clk_rate = 100000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static struct property_entry bxt_i2c_properties[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 42),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) PROPERTY_ENTRY_U32("i2c-sda-falling-time-ns", 171),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) PROPERTY_ENTRY_U32("i2c-scl-falling-time-ns", 208),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static const struct intel_lpss_platform_info bxt_i2c_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) .clk_rate = 133000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) .properties = bxt_i2c_properties,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static struct property_entry apl_i2c_properties[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 207),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) PROPERTY_ENTRY_U32("i2c-sda-falling-time-ns", 171),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) PROPERTY_ENTRY_U32("i2c-scl-falling-time-ns", 208),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static const struct intel_lpss_platform_info apl_i2c_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) .clk_rate = 133000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) .properties = apl_i2c_properties,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static const struct acpi_device_id intel_lpss_acpi_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* SPT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) { "INT3440", (kernel_ulong_t)&spt_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) { "INT3441", (kernel_ulong_t)&spt_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) { "INT3442", (kernel_ulong_t)&spt_i2c_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) { "INT3443", (kernel_ulong_t)&spt_i2c_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) { "INT3444", (kernel_ulong_t)&spt_i2c_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) { "INT3445", (kernel_ulong_t)&spt_i2c_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) { "INT3446", (kernel_ulong_t)&spt_i2c_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) { "INT3447", (kernel_ulong_t)&spt_i2c_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) { "INT3448", (kernel_ulong_t)&spt_uart_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) { "INT3449", (kernel_ulong_t)&spt_uart_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) { "INT344A", (kernel_ulong_t)&spt_uart_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /* BXT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) { "80860AAC", (kernel_ulong_t)&bxt_i2c_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) { "80860ABC", (kernel_ulong_t)&bxt_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) { "80860AC2", (kernel_ulong_t)&bxt_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /* APL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) { "80865AAC", (kernel_ulong_t)&apl_i2c_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) { "80865ABC", (kernel_ulong_t)&bxt_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) { "80865AC2", (kernel_ulong_t)&bxt_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) MODULE_DEVICE_TABLE(acpi, intel_lpss_acpi_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static int intel_lpss_acpi_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct intel_lpss_platform_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) const struct acpi_device_id *id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) id = acpi_match_device(intel_lpss_acpi_ids, &pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (!id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) info = devm_kmemdup(&pdev->dev, (void *)id->driver_data, sizeof(*info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) info->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) info->irq = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) ret = intel_lpss_probe(&pdev->dev, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) pm_runtime_set_active(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) pm_runtime_enable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static int intel_lpss_acpi_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) intel_lpss_remove(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) pm_runtime_disable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static INTEL_LPSS_PM_OPS(intel_lpss_acpi_pm_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) static struct platform_driver intel_lpss_acpi_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) .probe = intel_lpss_acpi_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) .remove = intel_lpss_acpi_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) .name = "intel-lpss",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) .acpi_match_table = intel_lpss_acpi_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) .pm = &intel_lpss_acpi_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) module_platform_driver(intel_lpss_acpi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) MODULE_DESCRIPTION("Intel LPSS ACPI driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) MODULE_LICENSE("GPL v2");