1*4b45efe8SAndy Shevchenko /* 2*4b45efe8SAndy Shevchenko * Intel LPSS PCI support. 3*4b45efe8SAndy Shevchenko * 4*4b45efe8SAndy Shevchenko * Copyright (C) 2015, Intel Corporation 5*4b45efe8SAndy Shevchenko * 6*4b45efe8SAndy Shevchenko * Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com> 7*4b45efe8SAndy Shevchenko * Mika Westerberg <mika.westerberg@linux.intel.com> 8*4b45efe8SAndy Shevchenko * 9*4b45efe8SAndy Shevchenko * This program is free software; you can redistribute it and/or modify 10*4b45efe8SAndy Shevchenko * it under the terms of the GNU General Public License version 2 as 11*4b45efe8SAndy Shevchenko * published by the Free Software Foundation. 12*4b45efe8SAndy Shevchenko */ 13*4b45efe8SAndy Shevchenko 14*4b45efe8SAndy Shevchenko #include <linux/ioport.h> 15*4b45efe8SAndy Shevchenko #include <linux/kernel.h> 16*4b45efe8SAndy Shevchenko #include <linux/module.h> 17*4b45efe8SAndy Shevchenko #include <linux/pci.h> 18*4b45efe8SAndy Shevchenko #include <linux/pm.h> 19*4b45efe8SAndy Shevchenko #include <linux/pm_runtime.h> 20*4b45efe8SAndy Shevchenko 21*4b45efe8SAndy Shevchenko #include "intel-lpss.h" 22*4b45efe8SAndy Shevchenko 23*4b45efe8SAndy Shevchenko static int intel_lpss_pci_probe(struct pci_dev *pdev, 24*4b45efe8SAndy Shevchenko const struct pci_device_id *id) 25*4b45efe8SAndy Shevchenko { 26*4b45efe8SAndy Shevchenko struct intel_lpss_platform_info *info; 27*4b45efe8SAndy Shevchenko int ret; 28*4b45efe8SAndy Shevchenko 29*4b45efe8SAndy Shevchenko ret = pcim_enable_device(pdev); 30*4b45efe8SAndy Shevchenko if (ret) 31*4b45efe8SAndy Shevchenko return ret; 32*4b45efe8SAndy Shevchenko 33*4b45efe8SAndy Shevchenko info = devm_kmemdup(&pdev->dev, (void *)id->driver_data, sizeof(*info), 34*4b45efe8SAndy Shevchenko GFP_KERNEL); 35*4b45efe8SAndy Shevchenko if (!info) 36*4b45efe8SAndy Shevchenko return -ENOMEM; 37*4b45efe8SAndy Shevchenko 38*4b45efe8SAndy Shevchenko info->mem = &pdev->resource[0]; 39*4b45efe8SAndy Shevchenko info->irq = pdev->irq; 40*4b45efe8SAndy Shevchenko 41*4b45efe8SAndy Shevchenko /* Probably it is enough to set this for iDMA capable devices only */ 42*4b45efe8SAndy Shevchenko pci_set_master(pdev); 43*4b45efe8SAndy Shevchenko 44*4b45efe8SAndy Shevchenko ret = intel_lpss_probe(&pdev->dev, info); 45*4b45efe8SAndy Shevchenko if (ret) 46*4b45efe8SAndy Shevchenko return ret; 47*4b45efe8SAndy Shevchenko 48*4b45efe8SAndy Shevchenko pm_runtime_put(&pdev->dev); 49*4b45efe8SAndy Shevchenko pm_runtime_allow(&pdev->dev); 50*4b45efe8SAndy Shevchenko 51*4b45efe8SAndy Shevchenko return 0; 52*4b45efe8SAndy Shevchenko } 53*4b45efe8SAndy Shevchenko 54*4b45efe8SAndy Shevchenko static void intel_lpss_pci_remove(struct pci_dev *pdev) 55*4b45efe8SAndy Shevchenko { 56*4b45efe8SAndy Shevchenko pm_runtime_forbid(&pdev->dev); 57*4b45efe8SAndy Shevchenko pm_runtime_get_sync(&pdev->dev); 58*4b45efe8SAndy Shevchenko 59*4b45efe8SAndy Shevchenko intel_lpss_remove(&pdev->dev); 60*4b45efe8SAndy Shevchenko } 61*4b45efe8SAndy Shevchenko 62*4b45efe8SAndy Shevchenko static INTEL_LPSS_PM_OPS(intel_lpss_pci_pm_ops); 63*4b45efe8SAndy Shevchenko 64*4b45efe8SAndy Shevchenko static const struct intel_lpss_platform_info spt_info = { 65*4b45efe8SAndy Shevchenko .clk_rate = 120000000, 66*4b45efe8SAndy Shevchenko }; 67*4b45efe8SAndy Shevchenko 68*4b45efe8SAndy Shevchenko static const struct intel_lpss_platform_info spt_uart_info = { 69*4b45efe8SAndy Shevchenko .clk_rate = 120000000, 70*4b45efe8SAndy Shevchenko .clk_con_id = "baudclk", 71*4b45efe8SAndy Shevchenko }; 72*4b45efe8SAndy Shevchenko 73*4b45efe8SAndy Shevchenko static const struct pci_device_id intel_lpss_pci_ids[] = { 74*4b45efe8SAndy Shevchenko /* SPT-LP */ 75*4b45efe8SAndy Shevchenko { PCI_VDEVICE(INTEL, 0x9d27), (kernel_ulong_t)&spt_uart_info }, 76*4b45efe8SAndy Shevchenko { PCI_VDEVICE(INTEL, 0x9d28), (kernel_ulong_t)&spt_uart_info }, 77*4b45efe8SAndy Shevchenko { PCI_VDEVICE(INTEL, 0x9d29), (kernel_ulong_t)&spt_info }, 78*4b45efe8SAndy Shevchenko { PCI_VDEVICE(INTEL, 0x9d2a), (kernel_ulong_t)&spt_info }, 79*4b45efe8SAndy Shevchenko { PCI_VDEVICE(INTEL, 0x9d60), (kernel_ulong_t)&spt_info }, 80*4b45efe8SAndy Shevchenko { PCI_VDEVICE(INTEL, 0x9d61), (kernel_ulong_t)&spt_info }, 81*4b45efe8SAndy Shevchenko { PCI_VDEVICE(INTEL, 0x9d62), (kernel_ulong_t)&spt_info }, 82*4b45efe8SAndy Shevchenko { PCI_VDEVICE(INTEL, 0x9d63), (kernel_ulong_t)&spt_info }, 83*4b45efe8SAndy Shevchenko { PCI_VDEVICE(INTEL, 0x9d64), (kernel_ulong_t)&spt_info }, 84*4b45efe8SAndy Shevchenko { PCI_VDEVICE(INTEL, 0x9d65), (kernel_ulong_t)&spt_info }, 85*4b45efe8SAndy Shevchenko { PCI_VDEVICE(INTEL, 0x9d66), (kernel_ulong_t)&spt_uart_info }, 86*4b45efe8SAndy Shevchenko /* SPT-H */ 87*4b45efe8SAndy Shevchenko { PCI_VDEVICE(INTEL, 0xa127), (kernel_ulong_t)&spt_uart_info }, 88*4b45efe8SAndy Shevchenko { PCI_VDEVICE(INTEL, 0xa128), (kernel_ulong_t)&spt_uart_info }, 89*4b45efe8SAndy Shevchenko { PCI_VDEVICE(INTEL, 0xa129), (kernel_ulong_t)&spt_info }, 90*4b45efe8SAndy Shevchenko { PCI_VDEVICE(INTEL, 0xa12a), (kernel_ulong_t)&spt_info }, 91*4b45efe8SAndy Shevchenko { PCI_VDEVICE(INTEL, 0xa160), (kernel_ulong_t)&spt_info }, 92*4b45efe8SAndy Shevchenko { PCI_VDEVICE(INTEL, 0xa161), (kernel_ulong_t)&spt_info }, 93*4b45efe8SAndy Shevchenko { PCI_VDEVICE(INTEL, 0xa166), (kernel_ulong_t)&spt_uart_info }, 94*4b45efe8SAndy Shevchenko { } 95*4b45efe8SAndy Shevchenko }; 96*4b45efe8SAndy Shevchenko MODULE_DEVICE_TABLE(pci, intel_lpss_pci_ids); 97*4b45efe8SAndy Shevchenko 98*4b45efe8SAndy Shevchenko static struct pci_driver intel_lpss_pci_driver = { 99*4b45efe8SAndy Shevchenko .name = "intel-lpss", 100*4b45efe8SAndy Shevchenko .id_table = intel_lpss_pci_ids, 101*4b45efe8SAndy Shevchenko .probe = intel_lpss_pci_probe, 102*4b45efe8SAndy Shevchenko .remove = intel_lpss_pci_remove, 103*4b45efe8SAndy Shevchenko .driver = { 104*4b45efe8SAndy Shevchenko .pm = &intel_lpss_pci_pm_ops, 105*4b45efe8SAndy Shevchenko }, 106*4b45efe8SAndy Shevchenko }; 107*4b45efe8SAndy Shevchenko 108*4b45efe8SAndy Shevchenko module_pci_driver(intel_lpss_pci_driver); 109*4b45efe8SAndy Shevchenko 110*4b45efe8SAndy Shevchenko MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>"); 111*4b45efe8SAndy Shevchenko MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); 112*4b45efe8SAndy Shevchenko MODULE_DESCRIPTION("Intel LPSS PCI driver"); 113*4b45efe8SAndy Shevchenko MODULE_LICENSE("GPL v2"); 114