LCOV - code coverage report
Current view: top level - drivers/platform/x86 - pmc_atom.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 6 86 7.0 %
Date: 2022-03-28 13:20:08 Functions: 1 12 8.3 %
Branches: 3 18 16.7 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0-only
       2                 :            : /*
       3                 :            :  * Intel Atom SOC Power Management Controller Driver
       4                 :            :  * Copyright (c) 2014, Intel Corporation.
       5                 :            :  */
       6                 :            : 
       7                 :            : #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
       8                 :            : 
       9                 :            : #include <linux/debugfs.h>
      10                 :            : #include <linux/device.h>
      11                 :            : #include <linux/dmi.h>
      12                 :            : #include <linux/init.h>
      13                 :            : #include <linux/io.h>
      14                 :            : #include <linux/platform_data/x86/clk-pmc-atom.h>
      15                 :            : #include <linux/platform_data/x86/pmc_atom.h>
      16                 :            : #include <linux/platform_device.h>
      17                 :            : #include <linux/pci.h>
      18                 :            : #include <linux/seq_file.h>
      19                 :            : 
      20                 :            : struct pmc_bit_map {
      21                 :            :         const char *name;
      22                 :            :         u32 bit_mask;
      23                 :            : };
      24                 :            : 
      25                 :            : struct pmc_reg_map {
      26                 :            :         const struct pmc_bit_map *d3_sts_0;
      27                 :            :         const struct pmc_bit_map *d3_sts_1;
      28                 :            :         const struct pmc_bit_map *func_dis;
      29                 :            :         const struct pmc_bit_map *func_dis_2;
      30                 :            :         const struct pmc_bit_map *pss;
      31                 :            : };
      32                 :            : 
      33                 :            : struct pmc_data {
      34                 :            :         const struct pmc_reg_map *map;
      35                 :            :         const struct pmc_clk *clks;
      36                 :            : };
      37                 :            : 
      38                 :            : struct pmc_dev {
      39                 :            :         u32 base_addr;
      40                 :            :         void __iomem *regmap;
      41                 :            :         const struct pmc_reg_map *map;
      42                 :            : #ifdef CONFIG_DEBUG_FS
      43                 :            :         struct dentry *dbgfs_dir;
      44                 :            : #endif /* CONFIG_DEBUG_FS */
      45                 :            :         bool init;
      46                 :            : };
      47                 :            : 
      48                 :            : static struct pmc_dev pmc_device;
      49                 :            : static u32 acpi_base_addr;
      50                 :            : 
      51                 :            : static const struct pmc_clk byt_clks[] = {
      52                 :            :         {
      53                 :            :                 .name = "xtal",
      54                 :            :                 .freq = 25000000,
      55                 :            :                 .parent_name = NULL,
      56                 :            :         },
      57                 :            :         {
      58                 :            :                 .name = "pll",
      59                 :            :                 .freq = 19200000,
      60                 :            :                 .parent_name = "xtal",
      61                 :            :         },
      62                 :            :         {},
      63                 :            : };
      64                 :            : 
      65                 :            : static const struct pmc_clk cht_clks[] = {
      66                 :            :         {
      67                 :            :                 .name = "xtal",
      68                 :            :                 .freq = 19200000,
      69                 :            :                 .parent_name = NULL,
      70                 :            :         },
      71                 :            :         {},
      72                 :            : };
      73                 :            : 
      74                 :            : static const struct pmc_bit_map d3_sts_0_map[] = {
      75                 :            :         {"LPSS1_F0_DMA",      BIT_LPSS1_F0_DMA},
      76                 :            :         {"LPSS1_F1_PWM1",     BIT_LPSS1_F1_PWM1},
      77                 :            :         {"LPSS1_F2_PWM2",     BIT_LPSS1_F2_PWM2},
      78                 :            :         {"LPSS1_F3_HSUART1",  BIT_LPSS1_F3_HSUART1},
      79                 :            :         {"LPSS1_F4_HSUART2",  BIT_LPSS1_F4_HSUART2},
      80                 :            :         {"LPSS1_F5_SPI",      BIT_LPSS1_F5_SPI},
      81                 :            :         {"LPSS1_F6_Reserved", BIT_LPSS1_F6_XXX},
      82                 :            :         {"LPSS1_F7_Reserved", BIT_LPSS1_F7_XXX},
      83                 :            :         {"SCC_EMMC",          BIT_SCC_EMMC},
      84                 :            :         {"SCC_SDIO",          BIT_SCC_SDIO},
      85                 :            :         {"SCC_SDCARD",                BIT_SCC_SDCARD},
      86                 :            :         {"SCC_MIPI",          BIT_SCC_MIPI},
      87                 :            :         {"HDA",                       BIT_HDA},
      88                 :            :         {"LPE",                       BIT_LPE},
      89                 :            :         {"OTG",                       BIT_OTG},
      90                 :            :         {"USH",                       BIT_USH},
      91                 :            :         {"GBE",                       BIT_GBE},
      92                 :            :         {"SATA",              BIT_SATA},
      93                 :            :         {"USB_EHCI",          BIT_USB_EHCI},
      94                 :            :         {"SEC",                       BIT_SEC},
      95                 :            :         {"PCIE_PORT0",                BIT_PCIE_PORT0},
      96                 :            :         {"PCIE_PORT1",                BIT_PCIE_PORT1},
      97                 :            :         {"PCIE_PORT2",                BIT_PCIE_PORT2},
      98                 :            :         {"PCIE_PORT3",                BIT_PCIE_PORT3},
      99                 :            :         {"LPSS2_F0_DMA",      BIT_LPSS2_F0_DMA},
     100                 :            :         {"LPSS2_F1_I2C1",     BIT_LPSS2_F1_I2C1},
     101                 :            :         {"LPSS2_F2_I2C2",     BIT_LPSS2_F2_I2C2},
     102                 :            :         {"LPSS2_F3_I2C3",     BIT_LPSS2_F3_I2C3},
     103                 :            :         {"LPSS2_F3_I2C4",     BIT_LPSS2_F4_I2C4},
     104                 :            :         {"LPSS2_F5_I2C5",     BIT_LPSS2_F5_I2C5},
     105                 :            :         {"LPSS2_F6_I2C6",     BIT_LPSS2_F6_I2C6},
     106                 :            :         {"LPSS2_F7_I2C7",     BIT_LPSS2_F7_I2C7},
     107                 :            :         {},
     108                 :            : };
     109                 :            : 
     110                 :            : static struct pmc_bit_map byt_d3_sts_1_map[] = {
     111                 :            :         {"SMB",                       BIT_SMB},
     112                 :            :         {"OTG_SS_PHY",                BIT_OTG_SS_PHY},
     113                 :            :         {"USH_SS_PHY",                BIT_USH_SS_PHY},
     114                 :            :         {"DFX",                       BIT_DFX},
     115                 :            :         {},
     116                 :            : };
     117                 :            : 
     118                 :            : static struct pmc_bit_map cht_d3_sts_1_map[] = {
     119                 :            :         {"SMB",                       BIT_SMB},
     120                 :            :         {"GMM",                       BIT_STS_GMM},
     121                 :            :         {"ISH",                       BIT_STS_ISH},
     122                 :            :         {},
     123                 :            : };
     124                 :            : 
     125                 :            : static struct pmc_bit_map cht_func_dis_2_map[] = {
     126                 :            :         {"SMB",                       BIT_SMB},
     127                 :            :         {"GMM",                       BIT_FD_GMM},
     128                 :            :         {"ISH",                       BIT_FD_ISH},
     129                 :            :         {},
     130                 :            : };
     131                 :            : 
     132                 :            : static const struct pmc_bit_map byt_pss_map[] = {
     133                 :            :         {"GBE",                       PMC_PSS_BIT_GBE},
     134                 :            :         {"SATA",              PMC_PSS_BIT_SATA},
     135                 :            :         {"HDA",                       PMC_PSS_BIT_HDA},
     136                 :            :         {"SEC",                       PMC_PSS_BIT_SEC},
     137                 :            :         {"PCIE",              PMC_PSS_BIT_PCIE},
     138                 :            :         {"LPSS",              PMC_PSS_BIT_LPSS},
     139                 :            :         {"LPE",                       PMC_PSS_BIT_LPE},
     140                 :            :         {"DFX",                       PMC_PSS_BIT_DFX},
     141                 :            :         {"USH_CTRL",          PMC_PSS_BIT_USH_CTRL},
     142                 :            :         {"USH_SUS",           PMC_PSS_BIT_USH_SUS},
     143                 :            :         {"USH_VCCS",          PMC_PSS_BIT_USH_VCCS},
     144                 :            :         {"USH_VCCA",          PMC_PSS_BIT_USH_VCCA},
     145                 :            :         {"OTG_CTRL",          PMC_PSS_BIT_OTG_CTRL},
     146                 :            :         {"OTG_VCCS",          PMC_PSS_BIT_OTG_VCCS},
     147                 :            :         {"OTG_VCCA_CLK",      PMC_PSS_BIT_OTG_VCCA_CLK},
     148                 :            :         {"OTG_VCCA",          PMC_PSS_BIT_OTG_VCCA},
     149                 :            :         {"USB",                       PMC_PSS_BIT_USB},
     150                 :            :         {"USB_SUS",           PMC_PSS_BIT_USB_SUS},
     151                 :            :         {},
     152                 :            : };
     153                 :            : 
     154                 :            : static const struct pmc_bit_map cht_pss_map[] = {
     155                 :            :         {"SATA",              PMC_PSS_BIT_SATA},
     156                 :            :         {"HDA",                       PMC_PSS_BIT_HDA},
     157                 :            :         {"SEC",                       PMC_PSS_BIT_SEC},
     158                 :            :         {"PCIE",              PMC_PSS_BIT_PCIE},
     159                 :            :         {"LPSS",              PMC_PSS_BIT_LPSS},
     160                 :            :         {"LPE",                       PMC_PSS_BIT_LPE},
     161                 :            :         {"UFS",                       PMC_PSS_BIT_CHT_UFS},
     162                 :            :         {"UXD",                       PMC_PSS_BIT_CHT_UXD},
     163                 :            :         {"UXD_FD",            PMC_PSS_BIT_CHT_UXD_FD},
     164                 :            :         {"UX_ENG",            PMC_PSS_BIT_CHT_UX_ENG},
     165                 :            :         {"USB_SUS",           PMC_PSS_BIT_CHT_USB_SUS},
     166                 :            :         {"GMM",                       PMC_PSS_BIT_CHT_GMM},
     167                 :            :         {"ISH",                       PMC_PSS_BIT_CHT_ISH},
     168                 :            :         {"DFX_MASTER",                PMC_PSS_BIT_CHT_DFX_MASTER},
     169                 :            :         {"DFX_CLUSTER1",      PMC_PSS_BIT_CHT_DFX_CLUSTER1},
     170                 :            :         {"DFX_CLUSTER2",      PMC_PSS_BIT_CHT_DFX_CLUSTER2},
     171                 :            :         {"DFX_CLUSTER3",      PMC_PSS_BIT_CHT_DFX_CLUSTER3},
     172                 :            :         {"DFX_CLUSTER4",      PMC_PSS_BIT_CHT_DFX_CLUSTER4},
     173                 :            :         {"DFX_CLUSTER5",      PMC_PSS_BIT_CHT_DFX_CLUSTER5},
     174                 :            :         {},
     175                 :            : };
     176                 :            : 
     177                 :            : static const struct pmc_reg_map byt_reg_map = {
     178                 :            :         .d3_sts_0       = d3_sts_0_map,
     179                 :            :         .d3_sts_1       = byt_d3_sts_1_map,
     180                 :            :         .func_dis       = d3_sts_0_map,
     181                 :            :         .func_dis_2     = byt_d3_sts_1_map,
     182                 :            :         .pss            = byt_pss_map,
     183                 :            : };
     184                 :            : 
     185                 :            : static const struct pmc_reg_map cht_reg_map = {
     186                 :            :         .d3_sts_0       = d3_sts_0_map,
     187                 :            :         .d3_sts_1       = cht_d3_sts_1_map,
     188                 :            :         .func_dis       = d3_sts_0_map,
     189                 :            :         .func_dis_2     = cht_func_dis_2_map,
     190                 :            :         .pss            = cht_pss_map,
     191                 :            : };
     192                 :            : 
     193                 :            : static const struct pmc_data byt_data = {
     194                 :            :         .map = &byt_reg_map,
     195                 :            :         .clks = byt_clks,
     196                 :            : };
     197                 :            : 
     198                 :            : static const struct pmc_data cht_data = {
     199                 :            :         .map = &cht_reg_map,
     200                 :            :         .clks = cht_clks,
     201                 :            : };
     202                 :            : 
     203                 :          0 : static inline u32 pmc_reg_read(struct pmc_dev *pmc, int reg_offset)
     204                 :            : {
     205                 :          0 :         return readl(pmc->regmap + reg_offset);
     206                 :            : }
     207                 :            : 
     208                 :          0 : static inline void pmc_reg_write(struct pmc_dev *pmc, int reg_offset, u32 val)
     209                 :            : {
     210                 :          0 :         writel(val, pmc->regmap + reg_offset);
     211                 :            : }
     212                 :            : 
     213                 :          0 : int pmc_atom_read(int offset, u32 *value)
     214                 :            : {
     215                 :          0 :         struct pmc_dev *pmc = &pmc_device;
     216                 :            : 
     217         [ #  # ]:          0 :         if (!pmc->init)
     218                 :            :                 return -ENODEV;
     219                 :            : 
     220                 :          0 :         *value = pmc_reg_read(pmc, offset);
     221                 :          0 :         return 0;
     222                 :            : }
     223                 :            : EXPORT_SYMBOL_GPL(pmc_atom_read);
     224                 :            : 
     225                 :          0 : int pmc_atom_write(int offset, u32 value)
     226                 :            : {
     227                 :          0 :         struct pmc_dev *pmc = &pmc_device;
     228                 :            : 
     229         [ #  # ]:          0 :         if (!pmc->init)
     230                 :            :                 return -ENODEV;
     231                 :            : 
     232                 :          0 :         pmc_reg_write(pmc, offset, value);
     233                 :          0 :         return 0;
     234                 :            : }
     235                 :            : EXPORT_SYMBOL_GPL(pmc_atom_write);
     236                 :            : 
     237                 :          0 : static void pmc_power_off(void)
     238                 :            : {
     239                 :          0 :         u16     pm1_cnt_port;
     240                 :          0 :         u32     pm1_cnt_value;
     241                 :            : 
     242                 :          0 :         pr_info("Preparing to enter system sleep state S5\n");
     243                 :            : 
     244                 :          0 :         pm1_cnt_port = acpi_base_addr + PM1_CNT;
     245                 :            : 
     246                 :          0 :         pm1_cnt_value = inl(pm1_cnt_port);
     247                 :          0 :         pm1_cnt_value &= SLEEP_TYPE_MASK;
     248                 :          0 :         pm1_cnt_value |= SLEEP_TYPE_S5;
     249                 :          0 :         pm1_cnt_value |= SLEEP_ENABLE;
     250                 :            : 
     251                 :          0 :         outl(pm1_cnt_value, pm1_cnt_port);
     252                 :          0 : }
     253                 :            : 
     254                 :            : static void pmc_hw_reg_setup(struct pmc_dev *pmc)
     255                 :            : {
     256                 :            :         /*
     257                 :            :          * Disable PMC S0IX_WAKE_EN events coming from:
     258                 :            :          * - LPC clock run
     259                 :            :          * - GPIO_SUS ored dedicated IRQs
     260                 :            :          * - GPIO_SCORE ored dedicated IRQs
     261                 :            :          * - GPIO_SUS shared IRQ
     262                 :            :          * - GPIO_SCORE shared IRQ
     263                 :            :          */
     264                 :            :         pmc_reg_write(pmc, PMC_S0IX_WAKE_EN, (u32)PMC_WAKE_EN_SETTING);
     265                 :            : }
     266                 :            : 
     267                 :            : #ifdef CONFIG_DEBUG_FS
     268                 :          0 : static void pmc_dev_state_print(struct seq_file *s, int reg_index,
     269                 :            :                                 u32 sts, const struct pmc_bit_map *sts_map,
     270                 :            :                                 u32 fd, const struct pmc_bit_map *fd_map)
     271                 :            : {
     272                 :          0 :         int offset = PMC_REG_BIT_WIDTH * reg_index;
     273                 :          0 :         int index;
     274                 :            : 
     275         [ #  # ]:          0 :         for (index = 0; sts_map[index].name; index++) {
     276                 :          0 :                 seq_printf(s, "Dev: %-2d - %-32s\tState: %s [%s]\n",
     277                 :            :                         offset + index, sts_map[index].name,
     278         [ #  # ]:          0 :                         fd_map[index].bit_mask & fd ?  "Disabled" : "Enabled ",
     279         [ #  # ]:          0 :                         sts_map[index].bit_mask & sts ?  "D3" : "D0");
     280                 :            :         }
     281                 :          0 : }
     282                 :            : 
     283                 :          0 : static int pmc_dev_state_show(struct seq_file *s, void *unused)
     284                 :            : {
     285                 :          0 :         struct pmc_dev *pmc = s->private;
     286                 :          0 :         const struct pmc_reg_map *m = pmc->map;
     287                 :          0 :         u32 func_dis, func_dis_2;
     288                 :          0 :         u32 d3_sts_0, d3_sts_1;
     289                 :            : 
     290                 :          0 :         func_dis = pmc_reg_read(pmc, PMC_FUNC_DIS);
     291                 :          0 :         func_dis_2 = pmc_reg_read(pmc, PMC_FUNC_DIS_2);
     292                 :          0 :         d3_sts_0 = pmc_reg_read(pmc, PMC_D3_STS_0);
     293                 :          0 :         d3_sts_1 = pmc_reg_read(pmc, PMC_D3_STS_1);
     294                 :            : 
     295                 :            :         /* Low part */
     296                 :          0 :         pmc_dev_state_print(s, 0, d3_sts_0, m->d3_sts_0, func_dis, m->func_dis);
     297                 :            : 
     298                 :            :         /* High part */
     299                 :          0 :         pmc_dev_state_print(s, 1, d3_sts_1, m->d3_sts_1, func_dis_2, m->func_dis_2);
     300                 :            : 
     301                 :          0 :         return 0;
     302                 :            : }
     303                 :            : 
     304                 :          0 : DEFINE_SHOW_ATTRIBUTE(pmc_dev_state);
     305                 :            : 
     306                 :          0 : static int pmc_pss_state_show(struct seq_file *s, void *unused)
     307                 :            : {
     308                 :          0 :         struct pmc_dev *pmc = s->private;
     309                 :          0 :         const struct pmc_bit_map *map = pmc->map->pss;
     310                 :          0 :         u32 pss = pmc_reg_read(pmc, PMC_PSS);
     311                 :          0 :         int index;
     312                 :            : 
     313         [ #  # ]:          0 :         for (index = 0; map[index].name; index++) {
     314                 :          0 :                 seq_printf(s, "Island: %-2d - %-32s\tState: %s\n",
     315                 :            :                         index, map[index].name,
     316         [ #  # ]:          0 :                         map[index].bit_mask & pss ? "Off" : "On");
     317                 :            :         }
     318                 :          0 :         return 0;
     319                 :            : }
     320                 :            : 
     321                 :          0 : DEFINE_SHOW_ATTRIBUTE(pmc_pss_state);
     322                 :            : 
     323                 :          0 : static int pmc_sleep_tmr_show(struct seq_file *s, void *unused)
     324                 :            : {
     325                 :          0 :         struct pmc_dev *pmc = s->private;
     326                 :          0 :         u64 s0ir_tmr, s0i1_tmr, s0i2_tmr, s0i3_tmr, s0_tmr;
     327                 :            : 
     328                 :          0 :         s0ir_tmr = (u64)pmc_reg_read(pmc, PMC_S0IR_TMR) << PMC_TMR_SHIFT;
     329                 :          0 :         s0i1_tmr = (u64)pmc_reg_read(pmc, PMC_S0I1_TMR) << PMC_TMR_SHIFT;
     330                 :          0 :         s0i2_tmr = (u64)pmc_reg_read(pmc, PMC_S0I2_TMR) << PMC_TMR_SHIFT;
     331                 :          0 :         s0i3_tmr = (u64)pmc_reg_read(pmc, PMC_S0I3_TMR) << PMC_TMR_SHIFT;
     332                 :          0 :         s0_tmr = (u64)pmc_reg_read(pmc, PMC_S0_TMR) << PMC_TMR_SHIFT;
     333                 :            : 
     334                 :          0 :         seq_printf(s, "S0IR Residency:\t%lldus\n", s0ir_tmr);
     335                 :          0 :         seq_printf(s, "S0I1 Residency:\t%lldus\n", s0i1_tmr);
     336                 :          0 :         seq_printf(s, "S0I2 Residency:\t%lldus\n", s0i2_tmr);
     337                 :          0 :         seq_printf(s, "S0I3 Residency:\t%lldus\n", s0i3_tmr);
     338                 :          0 :         seq_printf(s, "S0   Residency:\t%lldus\n", s0_tmr);
     339                 :          0 :         return 0;
     340                 :            : }
     341                 :            : 
     342                 :          0 : DEFINE_SHOW_ATTRIBUTE(pmc_sleep_tmr);
     343                 :            : 
     344                 :          0 : static void pmc_dbgfs_register(struct pmc_dev *pmc)
     345                 :            : {
     346                 :          0 :         struct dentry *dir;
     347                 :            : 
     348                 :          0 :         dir = debugfs_create_dir("pmc_atom", NULL);
     349                 :            : 
     350                 :          0 :         pmc->dbgfs_dir = dir;
     351                 :            : 
     352                 :          0 :         debugfs_create_file("dev_state", S_IFREG | S_IRUGO, dir, pmc,
     353                 :            :                             &pmc_dev_state_fops);
     354                 :          0 :         debugfs_create_file("pss_state", S_IFREG | S_IRUGO, dir, pmc,
     355                 :            :                             &pmc_pss_state_fops);
     356                 :          0 :         debugfs_create_file("sleep_state", S_IFREG | S_IRUGO, dir, pmc,
     357                 :            :                             &pmc_sleep_tmr_fops);
     358                 :          0 : }
     359                 :            : #else
     360                 :            : static void pmc_dbgfs_register(struct pmc_dev *pmc)
     361                 :            : {
     362                 :            : }
     363                 :            : #endif /* CONFIG_DEBUG_FS */
     364                 :            : 
     365                 :            : /*
     366                 :            :  * Some systems need one or more of their pmc_plt_clks to be
     367                 :            :  * marked as critical.
     368                 :            :  */
     369                 :            : static const struct dmi_system_id critclk_systems[] = {
     370                 :            :         {
     371                 :            :                 /* pmc_plt_clk0 is used for an external HSIC USB HUB */
     372                 :            :                 .ident = "MPL CEC1x",
     373                 :            :                 .matches = {
     374                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "MPL AG"),
     375                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "CEC10 Family"),
     376                 :            :                 },
     377                 :            :         },
     378                 :            :         {
     379                 :            :                 /* pmc_plt_clk0 - 3 are used for the 4 ethernet controllers */
     380                 :            :                 .ident = "Lex 3I380D",
     381                 :            :                 .matches = {
     382                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "Lex BayTrail"),
     383                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "3I380D"),
     384                 :            :                 },
     385                 :            :         },
     386                 :            :         {
     387                 :            :                 /* pmc_plt_clk* - are used for ethernet controllers */
     388                 :            :                 .ident = "Beckhoff CB3163",
     389                 :            :                 .matches = {
     390                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "Beckhoff Automation"),
     391                 :            :                         DMI_MATCH(DMI_BOARD_NAME, "CB3163"),
     392                 :            :                 },
     393                 :            :         },
     394                 :            :         {
     395                 :            :                 /* pmc_plt_clk* - are used for ethernet controllers */
     396                 :            :                 .ident = "Beckhoff CB4063",
     397                 :            :                 .matches = {
     398                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "Beckhoff Automation"),
     399                 :            :                         DMI_MATCH(DMI_BOARD_NAME, "CB4063"),
     400                 :            :                 },
     401                 :            :         },
     402                 :            :         {
     403                 :            :                 /* pmc_plt_clk* - are used for ethernet controllers */
     404                 :            :                 .ident = "Beckhoff CB6263",
     405                 :            :                 .matches = {
     406                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "Beckhoff Automation"),
     407                 :            :                         DMI_MATCH(DMI_BOARD_NAME, "CB6263"),
     408                 :            :                 },
     409                 :            :         },
     410                 :            :         {
     411                 :            :                 /* pmc_plt_clk* - are used for ethernet controllers */
     412                 :            :                 .ident = "Beckhoff CB6363",
     413                 :            :                 .matches = {
     414                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "Beckhoff Automation"),
     415                 :            :                         DMI_MATCH(DMI_BOARD_NAME, "CB6363"),
     416                 :            :                 },
     417                 :            :         },
     418                 :            :         {
     419                 :            :                 .ident = "SIMATIC IPC227E",
     420                 :            :                 .matches = {
     421                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "SIEMENS AG"),
     422                 :            :                         DMI_MATCH(DMI_PRODUCT_VERSION, "6ES7647-8B"),
     423                 :            :                 },
     424                 :            :         },
     425                 :            :         {
     426                 :            :                 .ident = "SIMATIC IPC277E",
     427                 :            :                 .matches = {
     428                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "SIEMENS AG"),
     429                 :            :                         DMI_MATCH(DMI_PRODUCT_VERSION, "6AV7882-0"),
     430                 :            :                 },
     431                 :            :         },
     432                 :            :         {
     433                 :            :                 .ident = "CONNECT X300",
     434                 :            :                 .matches = {
     435                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "SIEMENS AG"),
     436                 :            :                         DMI_MATCH(DMI_PRODUCT_VERSION, "A5E45074588"),
     437                 :            :                 },
     438                 :            :         },
     439                 :            : 
     440                 :            :         { /*sentinel*/ }
     441                 :            : };
     442                 :            : 
     443                 :            : static int pmc_setup_clks(struct pci_dev *pdev, void __iomem *pmc_regmap,
     444                 :            :                           const struct pmc_data *pmc_data)
     445                 :            : {
     446                 :            :         struct platform_device *clkdev;
     447                 :            :         struct pmc_clk_data *clk_data;
     448                 :            :         const struct dmi_system_id *d = dmi_first_match(critclk_systems);
     449                 :            : 
     450                 :            :         clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
     451                 :            :         if (!clk_data)
     452                 :            :                 return -ENOMEM;
     453                 :            : 
     454                 :            :         clk_data->base = pmc_regmap; /* offset is added by client */
     455                 :            :         clk_data->clks = pmc_data->clks;
     456                 :            :         if (d) {
     457                 :            :                 clk_data->critical = true;
     458                 :            :                 pr_info("%s critclks quirk enabled\n", d->ident);
     459                 :            :         }
     460                 :            : 
     461                 :            :         clkdev = platform_device_register_data(&pdev->dev, "clk-pmc-atom",
     462                 :            :                                                PLATFORM_DEVID_NONE,
     463                 :            :                                                clk_data, sizeof(*clk_data));
     464                 :            :         if (IS_ERR(clkdev)) {
     465                 :            :                 kfree(clk_data);
     466                 :            :                 return PTR_ERR(clkdev);
     467                 :            :         }
     468                 :            : 
     469                 :            :         kfree(clk_data);
     470                 :            : 
     471                 :            :         return 0;
     472                 :            : }
     473                 :            : 
     474                 :            : static int pmc_setup_dev(struct pci_dev *pdev, const struct pci_device_id *ent)
     475                 :            : {
     476                 :            :         struct pmc_dev *pmc = &pmc_device;
     477                 :            :         const struct pmc_data *data = (struct pmc_data *)ent->driver_data;
     478                 :            :         const struct pmc_reg_map *map = data->map;
     479                 :            :         int ret;
     480                 :            : 
     481                 :            :         /* Obtain ACPI base address */
     482                 :            :         pci_read_config_dword(pdev, ACPI_BASE_ADDR_OFFSET, &acpi_base_addr);
     483                 :            :         acpi_base_addr &= ACPI_BASE_ADDR_MASK;
     484                 :            : 
     485                 :            :         /* Install power off function */
     486                 :            :         if (acpi_base_addr != 0 && pm_power_off == NULL)
     487                 :            :                 pm_power_off = pmc_power_off;
     488                 :            : 
     489                 :            :         pci_read_config_dword(pdev, PMC_BASE_ADDR_OFFSET, &pmc->base_addr);
     490                 :            :         pmc->base_addr &= PMC_BASE_ADDR_MASK;
     491                 :            : 
     492                 :            :         pmc->regmap = ioremap(pmc->base_addr, PMC_MMIO_REG_LEN);
     493                 :            :         if (!pmc->regmap) {
     494                 :            :                 dev_err(&pdev->dev, "error: ioremap failed\n");
     495                 :            :                 return -ENOMEM;
     496                 :            :         }
     497                 :            : 
     498                 :            :         pmc->map = map;
     499                 :            : 
     500                 :            :         /* PMC hardware registers setup */
     501                 :            :         pmc_hw_reg_setup(pmc);
     502                 :            : 
     503                 :            :         pmc_dbgfs_register(pmc);
     504                 :            : 
     505                 :            :         /* Register platform clocks - PMC_PLT_CLK [0..5] */
     506                 :            :         ret = pmc_setup_clks(pdev, pmc->regmap, data);
     507                 :            :         if (ret)
     508                 :            :                 dev_warn(&pdev->dev, "platform clocks register failed: %d\n",
     509                 :            :                          ret);
     510                 :            : 
     511                 :            :         pmc->init = true;
     512                 :            :         return ret;
     513                 :            : }
     514                 :            : 
     515                 :            : /*
     516                 :            :  * Data for PCI driver interface
     517                 :            :  *
     518                 :            :  * used by pci_match_id() call below.
     519                 :            :  */
     520                 :            : static const struct pci_device_id pmc_pci_ids[] = {
     521                 :            :         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_VLV_PMC), (kernel_ulong_t)&byt_data },
     522                 :            :         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_CHT_PMC), (kernel_ulong_t)&cht_data },
     523                 :            :         { 0, },
     524                 :            : };
     525                 :            : 
     526                 :         30 : static int __init pmc_atom_init(void)
     527                 :            : {
     528                 :         30 :         struct pci_dev *pdev = NULL;
     529                 :         30 :         const struct pci_device_id *ent;
     530                 :            : 
     531                 :            :         /* We look for our device - PCU PMC
     532                 :            :          * we assume that there is max. one device.
     533                 :            :          *
     534                 :            :          * We can't use plain pci_driver mechanism,
     535                 :            :          * as the device is really a multiple function device,
     536                 :            :          * main driver that binds to the pci_device is lpc_ich
     537                 :            :          * and have to find & bind to the device this way.
     538                 :            :          */
     539         [ +  + ]:        240 :         for_each_pci_dev(pdev) {
     540                 :        210 :                 ent = pci_match_id(pmc_pci_ids, pdev);
     541         [ -  + ]:        210 :                 if (ent)
     542                 :          0 :                         return pmc_setup_dev(pdev, ent);
     543                 :            :         }
     544                 :            :         /* Device not found. */
     545                 :            :         return -ENODEV;
     546                 :            : }
     547                 :            : 
     548                 :            : device_initcall(pmc_atom_init);
     549                 :            : 
     550                 :            : /*
     551                 :            : MODULE_AUTHOR("Aubrey Li <aubrey.li@linux.intel.com>");
     552                 :            : MODULE_DESCRIPTION("Intel Atom SOC Power Management Controller Interface");
     553                 :            : MODULE_LICENSE("GPL v2");
     554                 :            : */

Generated by: LCOV version 1.14