linux/drivers/mfd/intel-lpss-pci.c
<<
>>
Prefs
   1/*
   2 * Intel LPSS PCI support.
   3 *
   4 * Copyright (C) 2015, Intel Corporation
   5 *
   6 * Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
   7 *          Mika Westerberg <mika.westerberg@linux.intel.com>
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License version 2 as
  11 * published by the Free Software Foundation.
  12 */
  13
  14#include <linux/ioport.h>
  15#include <linux/kernel.h>
  16#include <linux/module.h>
  17#include <linux/pci.h>
  18#include <linux/pm.h>
  19#include <linux/pm_runtime.h>
  20#include <linux/property.h>
  21
  22#include "intel-lpss.h"
  23
  24static int intel_lpss_pci_probe(struct pci_dev *pdev,
  25                                const struct pci_device_id *id)
  26{
  27        struct intel_lpss_platform_info *info;
  28        int ret;
  29
  30        ret = pcim_enable_device(pdev);
  31        if (ret)
  32                return ret;
  33
  34        info = devm_kmemdup(&pdev->dev, (void *)id->driver_data, sizeof(*info),
  35                            GFP_KERNEL);
  36        if (!info)
  37                return -ENOMEM;
  38
  39        info->mem = &pdev->resource[0];
  40        info->irq = pdev->irq;
  41
  42        /* Probably it is enough to set this for iDMA capable devices only */
  43        pci_set_master(pdev);
  44
  45        ret = intel_lpss_probe(&pdev->dev, info);
  46        if (ret)
  47                return ret;
  48
  49        pm_runtime_put(&pdev->dev);
  50        pm_runtime_allow(&pdev->dev);
  51
  52        return 0;
  53}
  54
  55static void intel_lpss_pci_remove(struct pci_dev *pdev)
  56{
  57        pm_runtime_forbid(&pdev->dev);
  58        pm_runtime_get_sync(&pdev->dev);
  59
  60        intel_lpss_remove(&pdev->dev);
  61}
  62
  63static INTEL_LPSS_PM_OPS(intel_lpss_pci_pm_ops);
  64
  65static const struct intel_lpss_platform_info spt_info = {
  66        .clk_rate = 120000000,
  67};
  68
  69static struct property_entry spt_i2c_properties[] = {
  70        PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 230),
  71        { },
  72};
  73
  74static struct property_set spt_i2c_pset = {
  75        .properties = spt_i2c_properties,
  76};
  77
  78static const struct intel_lpss_platform_info spt_i2c_info = {
  79        .clk_rate = 120000000,
  80        .pset = &spt_i2c_pset,
  81};
  82
  83static struct property_entry uart_properties[] = {
  84        PROPERTY_ENTRY_U32("reg-io-width", 4),
  85        PROPERTY_ENTRY_U32("reg-shift", 2),
  86        PROPERTY_ENTRY_BOOL("snps,uart-16550-compatible"),
  87        { },
  88};
  89
  90static struct property_set uart_pset = {
  91        .properties = uart_properties,
  92};
  93
  94static const struct intel_lpss_platform_info spt_uart_info = {
  95        .clk_rate = 120000000,
  96        .clk_con_id = "baudclk",
  97        .pset = &uart_pset,
  98};
  99
 100static const struct intel_lpss_platform_info bxt_info = {
 101        .clk_rate = 100000000,
 102};
 103
 104static const struct intel_lpss_platform_info bxt_uart_info = {
 105        .clk_rate = 100000000,
 106        .clk_con_id = "baudclk",
 107        .pset = &uart_pset,
 108};
 109
 110static struct property_entry bxt_i2c_properties[] = {
 111        PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 42),
 112        PROPERTY_ENTRY_U32("i2c-sda-falling-time-ns", 171),
 113        PROPERTY_ENTRY_U32("i2c-scl-falling-time-ns", 208),
 114        { },
 115};
 116
 117static struct property_set bxt_i2c_pset = {
 118        .properties = bxt_i2c_properties,
 119};
 120
 121static const struct intel_lpss_platform_info bxt_i2c_info = {
 122        .clk_rate = 133000000,
 123        .pset = &bxt_i2c_pset,
 124};
 125
 126static const struct pci_device_id intel_lpss_pci_ids[] = {
 127        /* BXT A-Step */
 128        { PCI_VDEVICE(INTEL, 0x0aac), (kernel_ulong_t)&bxt_i2c_info },
 129        { PCI_VDEVICE(INTEL, 0x0aae), (kernel_ulong_t)&bxt_i2c_info },
 130        { PCI_VDEVICE(INTEL, 0x0ab0), (kernel_ulong_t)&bxt_i2c_info },
 131        { PCI_VDEVICE(INTEL, 0x0ab2), (kernel_ulong_t)&bxt_i2c_info },
 132        { PCI_VDEVICE(INTEL, 0x0ab4), (kernel_ulong_t)&bxt_i2c_info },
 133        { PCI_VDEVICE(INTEL, 0x0ab6), (kernel_ulong_t)&bxt_i2c_info },
 134        { PCI_VDEVICE(INTEL, 0x0ab8), (kernel_ulong_t)&bxt_i2c_info },
 135        { PCI_VDEVICE(INTEL, 0x0aba), (kernel_ulong_t)&bxt_i2c_info },
 136        { PCI_VDEVICE(INTEL, 0x0abc), (kernel_ulong_t)&bxt_uart_info },
 137        { PCI_VDEVICE(INTEL, 0x0abe), (kernel_ulong_t)&bxt_uart_info },
 138        { PCI_VDEVICE(INTEL, 0x0ac0), (kernel_ulong_t)&bxt_uart_info },
 139        { PCI_VDEVICE(INTEL, 0x0ac2), (kernel_ulong_t)&bxt_info },
 140        { PCI_VDEVICE(INTEL, 0x0ac4), (kernel_ulong_t)&bxt_info },
 141        { PCI_VDEVICE(INTEL, 0x0ac6), (kernel_ulong_t)&bxt_info },
 142        { PCI_VDEVICE(INTEL, 0x0aee), (kernel_ulong_t)&bxt_uart_info },
 143        /* BXT B-Step */
 144        { PCI_VDEVICE(INTEL, 0x1aac), (kernel_ulong_t)&bxt_i2c_info },
 145        { PCI_VDEVICE(INTEL, 0x1aae), (kernel_ulong_t)&bxt_i2c_info },
 146        { PCI_VDEVICE(INTEL, 0x1ab0), (kernel_ulong_t)&bxt_i2c_info },
 147        { PCI_VDEVICE(INTEL, 0x1ab2), (kernel_ulong_t)&bxt_i2c_info },
 148        { PCI_VDEVICE(INTEL, 0x1ab4), (kernel_ulong_t)&bxt_i2c_info },
 149        { PCI_VDEVICE(INTEL, 0x1ab6), (kernel_ulong_t)&bxt_i2c_info },
 150        { PCI_VDEVICE(INTEL, 0x1ab8), (kernel_ulong_t)&bxt_i2c_info },
 151        { PCI_VDEVICE(INTEL, 0x1aba), (kernel_ulong_t)&bxt_i2c_info },
 152        { PCI_VDEVICE(INTEL, 0x1abc), (kernel_ulong_t)&bxt_uart_info },
 153        { PCI_VDEVICE(INTEL, 0x1abe), (kernel_ulong_t)&bxt_uart_info },
 154        { PCI_VDEVICE(INTEL, 0x1ac0), (kernel_ulong_t)&bxt_uart_info },
 155        { PCI_VDEVICE(INTEL, 0x1ac2), (kernel_ulong_t)&bxt_info },
 156        { PCI_VDEVICE(INTEL, 0x1ac4), (kernel_ulong_t)&bxt_info },
 157        { PCI_VDEVICE(INTEL, 0x1ac6), (kernel_ulong_t)&bxt_info },
 158        { PCI_VDEVICE(INTEL, 0x1aee), (kernel_ulong_t)&bxt_uart_info },
 159
 160        /* APL */
 161        { PCI_VDEVICE(INTEL, 0x5aac), (kernel_ulong_t)&bxt_i2c_info },
 162        { PCI_VDEVICE(INTEL, 0x5aae), (kernel_ulong_t)&bxt_i2c_info },
 163        { PCI_VDEVICE(INTEL, 0x5ab0), (kernel_ulong_t)&bxt_i2c_info },
 164        { PCI_VDEVICE(INTEL, 0x5ab2), (kernel_ulong_t)&bxt_i2c_info },
 165        { PCI_VDEVICE(INTEL, 0x5ab4), (kernel_ulong_t)&bxt_i2c_info },
 166        { PCI_VDEVICE(INTEL, 0x5ab6), (kernel_ulong_t)&bxt_i2c_info },
 167        { PCI_VDEVICE(INTEL, 0x5ab8), (kernel_ulong_t)&bxt_i2c_info },
 168        { PCI_VDEVICE(INTEL, 0x5aba), (kernel_ulong_t)&bxt_i2c_info },
 169        { PCI_VDEVICE(INTEL, 0x5abc), (kernel_ulong_t)&bxt_uart_info },
 170        { PCI_VDEVICE(INTEL, 0x5abe), (kernel_ulong_t)&bxt_uart_info },
 171        { PCI_VDEVICE(INTEL, 0x5ac0), (kernel_ulong_t)&bxt_uart_info },
 172        { PCI_VDEVICE(INTEL, 0x5ac2), (kernel_ulong_t)&bxt_info },
 173        { PCI_VDEVICE(INTEL, 0x5ac4), (kernel_ulong_t)&bxt_info },
 174        { PCI_VDEVICE(INTEL, 0x5ac6), (kernel_ulong_t)&bxt_info },
 175        { PCI_VDEVICE(INTEL, 0x5aee), (kernel_ulong_t)&bxt_uart_info },
 176        /* SPT-LP */
 177        { PCI_VDEVICE(INTEL, 0x9d27), (kernel_ulong_t)&spt_uart_info },
 178        { PCI_VDEVICE(INTEL, 0x9d28), (kernel_ulong_t)&spt_uart_info },
 179        { PCI_VDEVICE(INTEL, 0x9d29), (kernel_ulong_t)&spt_info },
 180        { PCI_VDEVICE(INTEL, 0x9d2a), (kernel_ulong_t)&spt_info },
 181        { PCI_VDEVICE(INTEL, 0x9d60), (kernel_ulong_t)&spt_i2c_info },
 182        { PCI_VDEVICE(INTEL, 0x9d61), (kernel_ulong_t)&spt_i2c_info },
 183        { PCI_VDEVICE(INTEL, 0x9d62), (kernel_ulong_t)&spt_i2c_info },
 184        { PCI_VDEVICE(INTEL, 0x9d63), (kernel_ulong_t)&spt_i2c_info },
 185        { PCI_VDEVICE(INTEL, 0x9d64), (kernel_ulong_t)&spt_i2c_info },
 186        { PCI_VDEVICE(INTEL, 0x9d65), (kernel_ulong_t)&spt_i2c_info },
 187        { PCI_VDEVICE(INTEL, 0x9d66), (kernel_ulong_t)&spt_uart_info },
 188        /* SPT-H */
 189        { PCI_VDEVICE(INTEL, 0xa127), (kernel_ulong_t)&spt_uart_info },
 190        { PCI_VDEVICE(INTEL, 0xa128), (kernel_ulong_t)&spt_uart_info },
 191        { PCI_VDEVICE(INTEL, 0xa129), (kernel_ulong_t)&spt_info },
 192        { PCI_VDEVICE(INTEL, 0xa12a), (kernel_ulong_t)&spt_info },
 193        { PCI_VDEVICE(INTEL, 0xa160), (kernel_ulong_t)&spt_i2c_info },
 194        { PCI_VDEVICE(INTEL, 0xa161), (kernel_ulong_t)&spt_i2c_info },
 195        { PCI_VDEVICE(INTEL, 0xa166), (kernel_ulong_t)&spt_uart_info },
 196        { }
 197};
 198MODULE_DEVICE_TABLE(pci, intel_lpss_pci_ids);
 199
 200static struct pci_driver intel_lpss_pci_driver = {
 201        .name = "intel-lpss",
 202        .id_table = intel_lpss_pci_ids,
 203        .probe = intel_lpss_pci_probe,
 204        .remove = intel_lpss_pci_remove,
 205        .driver = {
 206                .pm = &intel_lpss_pci_pm_ops,
 207        },
 208};
 209
 210module_pci_driver(intel_lpss_pci_driver);
 211
 212MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>");
 213MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
 214MODULE_DESCRIPTION("Intel LPSS PCI driver");
 215MODULE_LICENSE("GPL v2");
 216