Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Intel Low Power Subsystem PWM controller PCI driver
0004  *
0005  * Copyright (C) 2014, Intel Corporation
0006  *
0007  * Derived from the original pwm-lpss.c
0008  */
0009 
0010 #include <linux/kernel.h>
0011 #include <linux/module.h>
0012 #include <linux/pci.h>
0013 #include <linux/pm_runtime.h>
0014 
0015 #include "pwm-lpss.h"
0016 
0017 /* BayTrail */
0018 static const struct pwm_lpss_boardinfo pwm_lpss_byt_info = {
0019     .clk_rate = 25000000,
0020     .npwm = 1,
0021     .base_unit_bits = 16,
0022 };
0023 
0024 /* Braswell */
0025 static const struct pwm_lpss_boardinfo pwm_lpss_bsw_info = {
0026     .clk_rate = 19200000,
0027     .npwm = 1,
0028     .base_unit_bits = 16,
0029 };
0030 
0031 /* Broxton */
0032 static const struct pwm_lpss_boardinfo pwm_lpss_bxt_info = {
0033     .clk_rate = 19200000,
0034     .npwm = 4,
0035     .base_unit_bits = 22,
0036     .bypass = true,
0037 };
0038 
0039 /* Tangier */
0040 static const struct pwm_lpss_boardinfo pwm_lpss_tng_info = {
0041     .clk_rate = 19200000,
0042     .npwm = 4,
0043     .base_unit_bits = 22,
0044 };
0045 
0046 static int pwm_lpss_probe_pci(struct pci_dev *pdev,
0047                   const struct pci_device_id *id)
0048 {
0049     const struct pwm_lpss_boardinfo *info;
0050     struct pwm_lpss_chip *lpwm;
0051     int err;
0052 
0053     err = pcim_enable_device(pdev);
0054     if (err < 0)
0055         return err;
0056 
0057     info = (struct pwm_lpss_boardinfo *)id->driver_data;
0058     lpwm = pwm_lpss_probe(&pdev->dev, &pdev->resource[0], info);
0059     if (IS_ERR(lpwm))
0060         return PTR_ERR(lpwm);
0061 
0062     pci_set_drvdata(pdev, lpwm);
0063 
0064     pm_runtime_put(&pdev->dev);
0065     pm_runtime_allow(&pdev->dev);
0066 
0067     return 0;
0068 }
0069 
0070 static void pwm_lpss_remove_pci(struct pci_dev *pdev)
0071 {
0072     pm_runtime_forbid(&pdev->dev);
0073     pm_runtime_get_sync(&pdev->dev);
0074 }
0075 
0076 #ifdef CONFIG_PM
0077 static int pwm_lpss_runtime_suspend_pci(struct device *dev)
0078 {
0079     /*
0080      * The PCI core will handle transition to D3 automatically. We only
0081      * need to provide runtime PM hooks for that to happen.
0082      */
0083     return 0;
0084 }
0085 
0086 static int pwm_lpss_runtime_resume_pci(struct device *dev)
0087 {
0088     return 0;
0089 }
0090 #endif
0091 
0092 static const struct dev_pm_ops pwm_lpss_pci_pm = {
0093     SET_RUNTIME_PM_OPS(pwm_lpss_runtime_suspend_pci,
0094                pwm_lpss_runtime_resume_pci, NULL)
0095 };
0096 
0097 static const struct pci_device_id pwm_lpss_pci_ids[] = {
0098     { PCI_VDEVICE(INTEL, 0x0ac8), (unsigned long)&pwm_lpss_bxt_info},
0099     { PCI_VDEVICE(INTEL, 0x0f08), (unsigned long)&pwm_lpss_byt_info},
0100     { PCI_VDEVICE(INTEL, 0x0f09), (unsigned long)&pwm_lpss_byt_info},
0101     { PCI_VDEVICE(INTEL, 0x11a5), (unsigned long)&pwm_lpss_tng_info},
0102     { PCI_VDEVICE(INTEL, 0x1ac8), (unsigned long)&pwm_lpss_bxt_info},
0103     { PCI_VDEVICE(INTEL, 0x2288), (unsigned long)&pwm_lpss_bsw_info},
0104     { PCI_VDEVICE(INTEL, 0x2289), (unsigned long)&pwm_lpss_bsw_info},
0105     { PCI_VDEVICE(INTEL, 0x31c8), (unsigned long)&pwm_lpss_bxt_info},
0106     { PCI_VDEVICE(INTEL, 0x5ac8), (unsigned long)&pwm_lpss_bxt_info},
0107     { },
0108 };
0109 MODULE_DEVICE_TABLE(pci, pwm_lpss_pci_ids);
0110 
0111 static struct pci_driver pwm_lpss_driver_pci = {
0112     .name = "pwm-lpss",
0113     .id_table = pwm_lpss_pci_ids,
0114     .probe = pwm_lpss_probe_pci,
0115     .remove = pwm_lpss_remove_pci,
0116     .driver = {
0117         .pm = &pwm_lpss_pci_pm,
0118     },
0119 };
0120 module_pci_driver(pwm_lpss_driver_pci);
0121 
0122 MODULE_DESCRIPTION("PWM PCI driver for Intel LPSS");
0123 MODULE_LICENSE("GPL v2");