LCOV - code coverage report
Current view: top level - drivers/acpi - acpi_apd.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 3 27 11.1 %
Date: 2022-04-01 14:35:51 Functions: 1 2 50.0 %
Branches: 0 16 0.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0-only
       2                 :            : /*
       3                 :            :  * AMD ACPI support for ACPI2platform device.
       4                 :            :  *
       5                 :            :  * Copyright (c) 2014,2015 AMD Corporation.
       6                 :            :  * Authors: Ken Xue <Ken.Xue@amd.com>
       7                 :            :  *      Wu, Jeff <Jeff.Wu@amd.com>
       8                 :            :  */
       9                 :            : 
      10                 :            : #include <linux/clk-provider.h>
      11                 :            : #include <linux/platform_data/clk-st.h>
      12                 :            : #include <linux/platform_device.h>
      13                 :            : #include <linux/pm_domain.h>
      14                 :            : #include <linux/clkdev.h>
      15                 :            : #include <linux/acpi.h>
      16                 :            : #include <linux/err.h>
      17                 :            : #include <linux/io.h>
      18                 :            : #include <linux/pm.h>
      19                 :            : 
      20                 :            : #include "internal.h"
      21                 :            : 
      22                 :            : ACPI_MODULE_NAME("acpi_apd");
      23                 :            : struct apd_private_data;
      24                 :            : 
      25                 :            : /**
      26                 :            :  * ACPI_APD_SYSFS : add device attributes in sysfs
      27                 :            :  * ACPI_APD_PM : attach power domain to device
      28                 :            :  */
      29                 :            : #define ACPI_APD_SYSFS  BIT(0)
      30                 :            : #define ACPI_APD_PM     BIT(1)
      31                 :            : 
      32                 :            : /**
      33                 :            :  * struct apd_device_desc - a descriptor for apd device
      34                 :            :  * @flags: device flags like %ACPI_APD_SYSFS, %ACPI_APD_PM
      35                 :            :  * @fixed_clk_rate: fixed rate input clock source for acpi device;
      36                 :            :  *                      0 means no fixed rate input clock source
      37                 :            :  * @setup: a hook routine to set device resource during create platform device
      38                 :            :  *
      39                 :            :  * Device description defined as acpi_device_id.driver_data
      40                 :            :  */
      41                 :            : struct apd_device_desc {
      42                 :            :         unsigned int flags;
      43                 :            :         unsigned int fixed_clk_rate;
      44                 :            :         struct property_entry *properties;
      45                 :            :         int (*setup)(struct apd_private_data *pdata);
      46                 :            : };
      47                 :            : 
      48                 :            : struct apd_private_data {
      49                 :            :         struct clk *clk;
      50                 :            :         struct acpi_device *adev;
      51                 :            :         const struct apd_device_desc *dev_desc;
      52                 :            : };
      53                 :            : 
      54                 :            : #if defined(CONFIG_X86_AMD_PLATFORM_DEVICE) || defined(CONFIG_ARM64)
      55                 :            : #define APD_ADDR(desc)  ((unsigned long)&desc)
      56                 :            : 
      57                 :            : static int acpi_apd_setup(struct apd_private_data *pdata)
      58                 :            : {
      59                 :            :         const struct apd_device_desc *dev_desc = pdata->dev_desc;
      60                 :            :         struct clk *clk;
      61                 :            : 
      62                 :            :         if (dev_desc->fixed_clk_rate) {
      63                 :            :                 clk = clk_register_fixed_rate(&pdata->adev->dev,
      64                 :            :                                         dev_name(&pdata->adev->dev),
      65                 :            :                                         NULL, 0, dev_desc->fixed_clk_rate);
      66                 :            :                 clk_register_clkdev(clk, NULL, dev_name(&pdata->adev->dev));
      67                 :            :                 pdata->clk = clk;
      68                 :            :         }
      69                 :            : 
      70                 :            :         return 0;
      71                 :            : }
      72                 :            : 
      73                 :            : #ifdef CONFIG_X86_AMD_PLATFORM_DEVICE
      74                 :            : 
      75                 :            : static int misc_check_res(struct acpi_resource *ares, void *data)
      76                 :            : {
      77                 :            :         struct resource res;
      78                 :            : 
      79                 :            :         return !acpi_dev_resource_memory(ares, &res);
      80                 :            : }
      81                 :            : 
      82                 :            : static int st_misc_setup(struct apd_private_data *pdata)
      83                 :            : {
      84                 :            :         struct acpi_device *adev = pdata->adev;
      85                 :            :         struct platform_device *clkdev;
      86                 :            :         struct st_clk_data *clk_data;
      87                 :            :         struct resource_entry *rentry;
      88                 :            :         struct list_head resource_list;
      89                 :            :         int ret;
      90                 :            : 
      91                 :            :         clk_data = devm_kzalloc(&adev->dev, sizeof(*clk_data), GFP_KERNEL);
      92                 :            :         if (!clk_data)
      93                 :            :                 return -ENOMEM;
      94                 :            : 
      95                 :            :         INIT_LIST_HEAD(&resource_list);
      96                 :            :         ret = acpi_dev_get_resources(adev, &resource_list, misc_check_res,
      97                 :            :                                      NULL);
      98                 :            :         if (ret < 0)
      99                 :            :                 return -ENOENT;
     100                 :            : 
     101                 :            :         list_for_each_entry(rentry, &resource_list, node) {
     102                 :            :                 clk_data->base = devm_ioremap(&adev->dev, rentry->res->start,
     103                 :            :                                               resource_size(rentry->res));
     104                 :            :                 break;
     105                 :            :         }
     106                 :            : 
     107                 :            :         acpi_dev_free_resource_list(&resource_list);
     108                 :            : 
     109                 :            :         clkdev = platform_device_register_data(&adev->dev, "clk-st",
     110                 :            :                                                PLATFORM_DEVID_NONE, clk_data,
     111                 :            :                                                sizeof(*clk_data));
     112                 :            :         return PTR_ERR_OR_ZERO(clkdev);
     113                 :            : }
     114                 :            : 
     115                 :            : static const struct apd_device_desc cz_i2c_desc = {
     116                 :            :         .setup = acpi_apd_setup,
     117                 :            :         .fixed_clk_rate = 133000000,
     118                 :            : };
     119                 :            : 
     120                 :            : static const struct apd_device_desc wt_i2c_desc = {
     121                 :            :         .setup = acpi_apd_setup,
     122                 :            :         .fixed_clk_rate = 150000000,
     123                 :            : };
     124                 :            : 
     125                 :            : static struct property_entry uart_properties[] = {
     126                 :            :         PROPERTY_ENTRY_U32("reg-io-width", 4),
     127                 :            :         PROPERTY_ENTRY_U32("reg-shift", 2),
     128                 :            :         PROPERTY_ENTRY_BOOL("snps,uart-16550-compatible"),
     129                 :            :         { },
     130                 :            : };
     131                 :            : 
     132                 :            : static const struct apd_device_desc cz_uart_desc = {
     133                 :            :         .setup = acpi_apd_setup,
     134                 :            :         .fixed_clk_rate = 48000000,
     135                 :            :         .properties = uart_properties,
     136                 :            : };
     137                 :            : 
     138                 :            : static const struct apd_device_desc st_misc_desc = {
     139                 :            :         .setup = st_misc_setup,
     140                 :            : };
     141                 :            : #endif
     142                 :            : 
     143                 :            : #ifdef CONFIG_ARM64
     144                 :            : static const struct apd_device_desc xgene_i2c_desc = {
     145                 :            :         .setup = acpi_apd_setup,
     146                 :            :         .fixed_clk_rate = 100000000,
     147                 :            : };
     148                 :            : 
     149                 :            : static const struct apd_device_desc vulcan_spi_desc = {
     150                 :            :         .setup = acpi_apd_setup,
     151                 :            :         .fixed_clk_rate = 133000000,
     152                 :            : };
     153                 :            : 
     154                 :            : static const struct apd_device_desc hip07_i2c_desc = {
     155                 :            :         .setup = acpi_apd_setup,
     156                 :            :         .fixed_clk_rate = 200000000,
     157                 :            : };
     158                 :            : 
     159                 :            : static const struct apd_device_desc hip08_i2c_desc = {
     160                 :            :         .setup = acpi_apd_setup,
     161                 :            :         .fixed_clk_rate = 250000000,
     162                 :            : };
     163                 :            : 
     164                 :            : static const struct apd_device_desc hip08_lite_i2c_desc = {
     165                 :            :         .setup = acpi_apd_setup,
     166                 :            :         .fixed_clk_rate = 125000000,
     167                 :            : };
     168                 :            : 
     169                 :            : static const struct apd_device_desc thunderx2_i2c_desc = {
     170                 :            :         .setup = acpi_apd_setup,
     171                 :            :         .fixed_clk_rate = 125000000,
     172                 :            : };
     173                 :            : 
     174                 :            : static const struct apd_device_desc nxp_i2c_desc = {
     175                 :            :         .setup = acpi_apd_setup,
     176                 :            :         .fixed_clk_rate = 350000000,
     177                 :            : };
     178                 :            : 
     179                 :            : static const struct apd_device_desc hip08_spi_desc = {
     180                 :            :         .setup = acpi_apd_setup,
     181                 :            :         .fixed_clk_rate = 250000000,
     182                 :            : };
     183                 :            : #endif
     184                 :            : 
     185                 :            : #else
     186                 :            : 
     187                 :            : #define APD_ADDR(desc) (0UL)
     188                 :            : 
     189                 :            : #endif /* CONFIG_X86_AMD_PLATFORM_DEVICE */
     190                 :            : 
     191                 :            : /**
     192                 :            : * Create platform device during acpi scan attach handle.
     193                 :            : * Return value > 0 on success of creating device.
     194                 :            : */
     195                 :          0 : static int acpi_apd_create_device(struct acpi_device *adev,
     196                 :            :                                    const struct acpi_device_id *id)
     197                 :            : {
     198                 :          0 :         const struct apd_device_desc *dev_desc = (void *)id->driver_data;
     199                 :          0 :         struct apd_private_data *pdata;
     200                 :          0 :         struct platform_device *pdev;
     201                 :          0 :         int ret;
     202                 :            : 
     203         [ #  # ]:          0 :         if (!dev_desc) {
     204                 :          0 :                 pdev = acpi_create_platform_device(adev, NULL);
     205   [ #  #  #  # ]:          0 :                 return IS_ERR_OR_NULL(pdev) ? PTR_ERR(pdev) : 1;
     206                 :            :         }
     207                 :            : 
     208                 :          0 :         pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
     209         [ #  # ]:          0 :         if (!pdata)
     210                 :            :                 return -ENOMEM;
     211                 :            : 
     212                 :          0 :         pdata->adev = adev;
     213                 :          0 :         pdata->dev_desc = dev_desc;
     214                 :            : 
     215         [ #  # ]:          0 :         if (dev_desc->setup) {
     216                 :          0 :                 ret = dev_desc->setup(pdata);
     217         [ #  # ]:          0 :                 if (ret)
     218                 :          0 :                         goto err_out;
     219                 :            :         }
     220                 :            : 
     221                 :          0 :         adev->driver_data = pdata;
     222                 :          0 :         pdev = acpi_create_platform_device(adev, dev_desc->properties);
     223   [ #  #  #  # ]:          0 :         if (!IS_ERR_OR_NULL(pdev))
     224                 :            :                 return 1;
     225                 :            : 
     226                 :          0 :         ret = PTR_ERR(pdev);
     227                 :          0 :         adev->driver_data = NULL;
     228                 :            : 
     229                 :          0 :  err_out:
     230                 :          0 :         kfree(pdata);
     231                 :          0 :         return ret;
     232                 :            : }
     233                 :            : 
     234                 :            : static const struct acpi_device_id acpi_apd_device_ids[] = {
     235                 :            :         /* Generic apd devices */
     236                 :            : #ifdef CONFIG_X86_AMD_PLATFORM_DEVICE
     237                 :            :         { "AMD0010", APD_ADDR(cz_i2c_desc) },
     238                 :            :         { "AMDI0010", APD_ADDR(wt_i2c_desc) },
     239                 :            :         { "AMD0020", APD_ADDR(cz_uart_desc) },
     240                 :            :         { "AMDI0020", APD_ADDR(cz_uart_desc) },
     241                 :            :         { "AMD0030", },
     242                 :            :         { "AMD0040", APD_ADDR(st_misc_desc)},
     243                 :            : #endif
     244                 :            : #ifdef CONFIG_ARM64
     245                 :            :         { "APMC0D0F", APD_ADDR(xgene_i2c_desc) },
     246                 :            :         { "BRCM900D", APD_ADDR(vulcan_spi_desc) },
     247                 :            :         { "CAV900D",  APD_ADDR(vulcan_spi_desc) },
     248                 :            :         { "CAV9007",  APD_ADDR(thunderx2_i2c_desc) },
     249                 :            :         { "HISI02A1", APD_ADDR(hip07_i2c_desc) },
     250                 :            :         { "HISI02A2", APD_ADDR(hip08_i2c_desc) },
     251                 :            :         { "HISI02A3", APD_ADDR(hip08_lite_i2c_desc) },
     252                 :            :         { "HISI0173", APD_ADDR(hip08_spi_desc) },
     253                 :            :         { "NXP0001", APD_ADDR(nxp_i2c_desc) },
     254                 :            : #endif
     255                 :            :         { }
     256                 :            : };
     257                 :            : 
     258                 :            : static struct acpi_scan_handler apd_handler = {
     259                 :            :         .ids = acpi_apd_device_ids,
     260                 :            :         .attach = acpi_apd_create_device,
     261                 :            : };
     262                 :            : 
     263                 :         21 : void __init acpi_apd_init(void)
     264                 :            : {
     265                 :         21 :         acpi_scan_add_handler(&apd_handler);
     266                 :         21 : }

Generated by: LCOV version 1.14