LCOV - code coverage report
Current view: top level - drivers/base - platform.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 193 472 40.9 %
Date: 2022-04-01 14:35:51 Functions: 18 48 37.5 %
Branches: 71 285 24.9 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0
       2                 :            : /*
       3                 :            :  * platform.c - platform 'pseudo' bus for legacy devices
       4                 :            :  *
       5                 :            :  * Copyright (c) 2002-3 Patrick Mochel
       6                 :            :  * Copyright (c) 2002-3 Open Source Development Labs
       7                 :            :  *
       8                 :            :  * Please see Documentation/driver-api/driver-model/platform.rst for more
       9                 :            :  * information.
      10                 :            :  */
      11                 :            : 
      12                 :            : #include <linux/string.h>
      13                 :            : #include <linux/platform_device.h>
      14                 :            : #include <linux/of_device.h>
      15                 :            : #include <linux/of_irq.h>
      16                 :            : #include <linux/module.h>
      17                 :            : #include <linux/init.h>
      18                 :            : #include <linux/dma-mapping.h>
      19                 :            : #include <linux/memblock.h>
      20                 :            : #include <linux/err.h>
      21                 :            : #include <linux/slab.h>
      22                 :            : #include <linux/pm_runtime.h>
      23                 :            : #include <linux/pm_domain.h>
      24                 :            : #include <linux/idr.h>
      25                 :            : #include <linux/acpi.h>
      26                 :            : #include <linux/clk/clk-conf.h>
      27                 :            : #include <linux/limits.h>
      28                 :            : #include <linux/property.h>
      29                 :            : #include <linux/kmemleak.h>
      30                 :            : #include <linux/types.h>
      31                 :            : 
      32                 :            : #include "base.h"
      33                 :            : #include "power/power.h"
      34                 :            : 
      35                 :            : /* For automatically allocated device IDs */
      36                 :            : static DEFINE_IDA(platform_devid_ida);
      37                 :            : 
      38                 :            : struct device platform_bus = {
      39                 :            :         .init_name      = "platform",
      40                 :            : };
      41                 :            : EXPORT_SYMBOL_GPL(platform_bus);
      42                 :            : 
      43                 :            : /**
      44                 :            :  * platform_get_resource - get a resource for a device
      45                 :            :  * @dev: platform device
      46                 :            :  * @type: resource type
      47                 :            :  * @num: resource index
      48                 :            :  */
      49                 :          0 : struct resource *platform_get_resource(struct platform_device *dev,
      50                 :            :                                        unsigned int type, unsigned int num)
      51                 :            : {
      52                 :          0 :         u32 i;
      53                 :            : 
      54   [ #  #  #  #  :          0 :         for (i = 0; i < dev->num_resources; i++) {
             #  #  #  # ]
      55                 :          0 :                 struct resource *r = &dev->resource[i];
      56                 :            : 
      57   [ #  #  #  #  :          0 :                 if (type == resource_type(r) && num-- == 0)
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
      58                 :          0 :                         return r;
      59                 :            :         }
      60                 :            :         return NULL;
      61                 :            : }
      62                 :            : EXPORT_SYMBOL_GPL(platform_get_resource);
      63                 :            : 
      64                 :            : #ifdef CONFIG_HAS_IOMEM
      65                 :            : /**
      66                 :            :  * devm_platform_ioremap_resource - call devm_ioremap_resource() for a platform
      67                 :            :  *                                  device
      68                 :            :  *
      69                 :            :  * @pdev: platform device to use both for memory resource lookup as well as
      70                 :            :  *        resource management
      71                 :            :  * @index: resource index
      72                 :            :  */
      73                 :          0 : void __iomem *devm_platform_ioremap_resource(struct platform_device *pdev,
      74                 :            :                                              unsigned int index)
      75                 :            : {
      76                 :          0 :         struct resource *res;
      77                 :            : 
      78                 :          0 :         res = platform_get_resource(pdev, IORESOURCE_MEM, index);
      79                 :          0 :         return devm_ioremap_resource(&pdev->dev, res);
      80                 :            : }
      81                 :            : EXPORT_SYMBOL_GPL(devm_platform_ioremap_resource);
      82                 :            : 
      83                 :            : /**
      84                 :            :  * devm_platform_ioremap_resource_wc - write-combined variant of
      85                 :            :  *                                     devm_platform_ioremap_resource()
      86                 :            :  *
      87                 :            :  * @pdev: platform device to use both for memory resource lookup as well as
      88                 :            :  *        resource management
      89                 :            :  * @index: resource index
      90                 :            :  */
      91                 :          0 : void __iomem *devm_platform_ioremap_resource_wc(struct platform_device *pdev,
      92                 :            :                                                 unsigned int index)
      93                 :            : {
      94                 :          0 :         struct resource *res;
      95                 :            : 
      96                 :          0 :         res = platform_get_resource(pdev, IORESOURCE_MEM, index);
      97                 :          0 :         return devm_ioremap_resource_wc(&pdev->dev, res);
      98                 :            : }
      99                 :            : 
     100                 :            : /**
     101                 :            :  * devm_platform_ioremap_resource_byname - call devm_ioremap_resource for
     102                 :            :  *                                         a platform device, retrieve the
     103                 :            :  *                                         resource by name
     104                 :            :  *
     105                 :            :  * @pdev: platform device to use both for memory resource lookup as well as
     106                 :            :  *        resource management
     107                 :            :  * @name: name of the resource
     108                 :            :  */
     109                 :            : void __iomem *
     110                 :          0 : devm_platform_ioremap_resource_byname(struct platform_device *pdev,
     111                 :            :                                       const char *name)
     112                 :            : {
     113                 :          0 :         struct resource *res;
     114                 :            : 
     115                 :          0 :         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
     116                 :          0 :         return devm_ioremap_resource(&pdev->dev, res);
     117                 :            : }
     118                 :            : EXPORT_SYMBOL_GPL(devm_platform_ioremap_resource_byname);
     119                 :            : #endif /* CONFIG_HAS_IOMEM */
     120                 :            : 
     121                 :            : /**
     122                 :            :  * platform_get_irq_optional - get an optional IRQ for a device
     123                 :            :  * @dev: platform device
     124                 :            :  * @num: IRQ number index
     125                 :            :  *
     126                 :            :  * Gets an IRQ for a platform device. Device drivers should check the return
     127                 :            :  * value for errors so as to not pass a negative integer value to the
     128                 :            :  * request_irq() APIs. This is the same as platform_get_irq(), except that it
     129                 :            :  * does not print an error message if an IRQ can not be obtained.
     130                 :            :  *
     131                 :            :  * Example:
     132                 :            :  *              int irq = platform_get_irq_optional(pdev, 0);
     133                 :            :  *              if (irq < 0)
     134                 :            :  *                      return irq;
     135                 :            :  *
     136                 :            :  * Return: IRQ number on success, negative error number on failure.
     137                 :            :  */
     138                 :          0 : int platform_get_irq_optional(struct platform_device *dev, unsigned int num)
     139                 :            : {
     140                 :            : #ifdef CONFIG_SPARC
     141                 :            :         /* sparc does not have irqs represented as IORESOURCE_IRQ resources */
     142                 :            :         if (!dev || num >= dev->archdata.num_irqs)
     143                 :            :                 return -ENXIO;
     144                 :            :         return dev->archdata.irqs[num];
     145                 :            : #else
     146                 :          0 :         struct resource *r;
     147                 :          0 :         int ret;
     148                 :            : 
     149                 :          0 :         if (IS_ENABLED(CONFIG_OF_IRQ) && dev->dev.of_node) {
     150                 :            :                 ret = of_irq_get(dev->dev.of_node, num);
     151                 :            :                 if (ret > 0 || ret == -EPROBE_DEFER)
     152                 :            :                         return ret;
     153                 :            :         }
     154                 :            : 
     155                 :          0 :         r = platform_get_resource(dev, IORESOURCE_IRQ, num);
     156         [ #  # ]:          0 :         if (has_acpi_companion(&dev->dev)) {
     157   [ #  #  #  # ]:          0 :                 if (r && r->flags & IORESOURCE_DISABLED) {
     158                 :          0 :                         ret = acpi_irq_get(ACPI_HANDLE(&dev->dev), num, r);
     159                 :          0 :                         if (ret)
     160                 :          0 :                                 return ret;
     161                 :            :                 }
     162                 :            :         }
     163                 :            : 
     164                 :            :         /*
     165                 :            :          * The resources may pass trigger flags to the irqs that need
     166                 :            :          * to be set up. It so happens that the trigger flags for
     167                 :            :          * IORESOURCE_BITS correspond 1-to-1 to the IRQF_TRIGGER*
     168                 :            :          * settings.
     169                 :            :          */
     170   [ #  #  #  # ]:          0 :         if (r && r->flags & IORESOURCE_BITS) {
     171                 :          0 :                 struct irq_data *irqd;
     172                 :            : 
     173                 :          0 :                 irqd = irq_get_irq_data(r->start);
     174         [ #  # ]:          0 :                 if (!irqd)
     175                 :            :                         return -ENXIO;
     176                 :          0 :                 irqd_set_trigger_type(irqd, r->flags & IORESOURCE_BITS);
     177                 :            :         }
     178                 :            : 
     179         [ #  # ]:          0 :         if (r)
     180                 :          0 :                 return r->start;
     181                 :            : 
     182                 :            :         /*
     183                 :            :          * For the index 0 interrupt, allow falling back to GpioInt
     184                 :            :          * resources. While a device could have both Interrupt and GpioInt
     185                 :            :          * resources, making this fallback ambiguous, in many common cases
     186                 :            :          * the device will only expose one IRQ, and this fallback
     187                 :            :          * allows a common code path across either kind of resource.
     188                 :            :          */
     189   [ #  #  #  # ]:          0 :         if (num == 0 && has_acpi_companion(&dev->dev)) {
     190                 :          0 :                 ret = acpi_dev_gpio_irq_get(ACPI_COMPANION(&dev->dev), num);
     191                 :            :                 /* Our callers expect -ENXIO for missing IRQs. */
     192                 :            :                 if (ret >= 0 || ret == -EPROBE_DEFER)
     193                 :            :                         return ret;
     194                 :            :         }
     195                 :            : 
     196                 :            :         return -ENXIO;
     197                 :            : #endif
     198                 :            : }
     199                 :            : EXPORT_SYMBOL_GPL(platform_get_irq_optional);
     200                 :            : 
     201                 :            : /**
     202                 :            :  * platform_get_irq - get an IRQ for a device
     203                 :            :  * @dev: platform device
     204                 :            :  * @num: IRQ number index
     205                 :            :  *
     206                 :            :  * Gets an IRQ for a platform device and prints an error message if finding the
     207                 :            :  * IRQ fails. Device drivers should check the return value for errors so as to
     208                 :            :  * not pass a negative integer value to the request_irq() APIs.
     209                 :            :  *
     210                 :            :  * Example:
     211                 :            :  *              int irq = platform_get_irq(pdev, 0);
     212                 :            :  *              if (irq < 0)
     213                 :            :  *                      return irq;
     214                 :            :  *
     215                 :            :  * Return: IRQ number on success, negative error number on failure.
     216                 :            :  */
     217                 :          0 : int platform_get_irq(struct platform_device *dev, unsigned int num)
     218                 :            : {
     219                 :          0 :         int ret;
     220                 :            : 
     221                 :          0 :         ret = platform_get_irq_optional(dev, num);
     222         [ #  # ]:          0 :         if (ret < 0 && ret != -EPROBE_DEFER)
     223                 :          0 :                 dev_err(&dev->dev, "IRQ index %u not found\n", num);
     224                 :            : 
     225                 :          0 :         return ret;
     226                 :            : }
     227                 :            : EXPORT_SYMBOL_GPL(platform_get_irq);
     228                 :            : 
     229                 :            : /**
     230                 :            :  * platform_irq_count - Count the number of IRQs a platform device uses
     231                 :            :  * @dev: platform device
     232                 :            :  *
     233                 :            :  * Return: Number of IRQs a platform device uses or EPROBE_DEFER
     234                 :            :  */
     235                 :          0 : int platform_irq_count(struct platform_device *dev)
     236                 :            : {
     237                 :          0 :         int ret, nr = 0;
     238                 :            : 
     239         [ #  # ]:          0 :         while ((ret = platform_get_irq_optional(dev, nr)) >= 0)
     240                 :          0 :                 nr++;
     241                 :            : 
     242         [ #  # ]:          0 :         if (ret == -EPROBE_DEFER)
     243                 :          0 :                 return ret;
     244                 :            : 
     245                 :            :         return nr;
     246                 :            : }
     247                 :            : EXPORT_SYMBOL_GPL(platform_irq_count);
     248                 :            : 
     249                 :            : /**
     250                 :            :  * platform_get_resource_byname - get a resource for a device by name
     251                 :            :  * @dev: platform device
     252                 :            :  * @type: resource type
     253                 :            :  * @name: resource name
     254                 :            :  */
     255                 :          0 : struct resource *platform_get_resource_byname(struct platform_device *dev,
     256                 :            :                                               unsigned int type,
     257                 :            :                                               const char *name)
     258                 :            : {
     259                 :          0 :         u32 i;
     260                 :            : 
     261         [ #  # ]:          0 :         for (i = 0; i < dev->num_resources; i++) {
     262                 :          0 :                 struct resource *r = &dev->resource[i];
     263                 :            : 
     264         [ #  # ]:          0 :                 if (unlikely(!r->name))
     265                 :          0 :                         continue;
     266                 :            : 
     267   [ #  #  #  # ]:          0 :                 if (type == resource_type(r) && !strcmp(r->name, name))
     268                 :          0 :                         return r;
     269                 :            :         }
     270                 :            :         return NULL;
     271                 :            : }
     272                 :            : EXPORT_SYMBOL_GPL(platform_get_resource_byname);
     273                 :            : 
     274                 :          0 : static int __platform_get_irq_byname(struct platform_device *dev,
     275                 :            :                                      const char *name)
     276                 :            : {
     277                 :          0 :         struct resource *r;
     278                 :          0 :         int ret;
     279                 :            : 
     280                 :          0 :         if (IS_ENABLED(CONFIG_OF_IRQ) && dev->dev.of_node) {
     281                 :            :                 ret = of_irq_get_byname(dev->dev.of_node, name);
     282                 :            :                 if (ret > 0 || ret == -EPROBE_DEFER)
     283                 :            :                         return ret;
     284                 :            :         }
     285                 :            : 
     286                 :          0 :         r = platform_get_resource_byname(dev, IORESOURCE_IRQ, name);
     287   [ #  #  #  # ]:          0 :         if (r)
     288                 :          0 :                 return r->start;
     289                 :            : 
     290                 :            :         return -ENXIO;
     291                 :            : }
     292                 :            : 
     293                 :            : /**
     294                 :            :  * platform_get_irq_byname - get an IRQ for a device by name
     295                 :            :  * @dev: platform device
     296                 :            :  * @name: IRQ name
     297                 :            :  *
     298                 :            :  * Get an IRQ like platform_get_irq(), but then by name rather then by index.
     299                 :            :  *
     300                 :            :  * Return: IRQ number on success, negative error number on failure.
     301                 :            :  */
     302                 :          0 : int platform_get_irq_byname(struct platform_device *dev, const char *name)
     303                 :            : {
     304                 :          0 :         int ret;
     305                 :            : 
     306                 :          0 :         ret = __platform_get_irq_byname(dev, name);
     307         [ #  # ]:          0 :         if (ret < 0 && ret != -EPROBE_DEFER)
     308                 :          0 :                 dev_err(&dev->dev, "IRQ %s not found\n", name);
     309                 :            : 
     310                 :          0 :         return ret;
     311                 :            : }
     312                 :            : EXPORT_SYMBOL_GPL(platform_get_irq_byname);
     313                 :            : 
     314                 :            : /**
     315                 :            :  * platform_get_irq_byname_optional - get an optional IRQ for a device by name
     316                 :            :  * @dev: platform device
     317                 :            :  * @name: IRQ name
     318                 :            :  *
     319                 :            :  * Get an optional IRQ by name like platform_get_irq_byname(). Except that it
     320                 :            :  * does not print an error message if an IRQ can not be obtained.
     321                 :            :  *
     322                 :            :  * Return: IRQ number on success, negative error number on failure.
     323                 :            :  */
     324                 :          0 : int platform_get_irq_byname_optional(struct platform_device *dev,
     325                 :            :                                      const char *name)
     326                 :            : {
     327                 :          0 :         return __platform_get_irq_byname(dev, name);
     328                 :            : }
     329                 :            : EXPORT_SYMBOL_GPL(platform_get_irq_byname_optional);
     330                 :            : 
     331                 :            : /**
     332                 :            :  * platform_add_devices - add a numbers of platform devices
     333                 :            :  * @devs: array of platform devices to add
     334                 :            :  * @num: number of platform devices in array
     335                 :            :  */
     336                 :          0 : int platform_add_devices(struct platform_device **devs, int num)
     337                 :            : {
     338                 :          0 :         int i, ret = 0;
     339                 :            : 
     340         [ #  # ]:          0 :         for (i = 0; i < num; i++) {
     341                 :          0 :                 ret = platform_device_register(devs[i]);
     342         [ #  # ]:          0 :                 if (ret) {
     343         [ #  # ]:          0 :                         while (--i >= 0)
     344                 :          0 :                                 platform_device_unregister(devs[i]);
     345                 :            :                         break;
     346                 :            :                 }
     347                 :            :         }
     348                 :            : 
     349                 :          0 :         return ret;
     350                 :            : }
     351                 :            : EXPORT_SYMBOL_GPL(platform_add_devices);
     352                 :            : 
     353                 :            : struct platform_object {
     354                 :            :         struct platform_device pdev;
     355                 :            :         char name[];
     356                 :            : };
     357                 :            : 
     358                 :            : /*
     359                 :            :  * Set up default DMA mask for platform devices if the they weren't
     360                 :            :  * previously set by the architecture / DT.
     361                 :            :  */
     362                 :        168 : static void setup_pdev_dma_masks(struct platform_device *pdev)
     363                 :            : {
     364                 :        168 :         if (!pdev->dev.coherent_dma_mask)
     365                 :        168 :                 pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
     366   [ -  -  +  - ]:        168 :         if (!pdev->dev.dma_mask) {
     367                 :        168 :                 pdev->platform_dma_mask = DMA_BIT_MASK(32);
     368                 :        168 :                 pdev->dev.dma_mask = &pdev->platform_dma_mask;
     369                 :            :         }
     370                 :            : };
     371                 :            : 
     372                 :            : /**
     373                 :            :  * platform_device_put - destroy a platform device
     374                 :            :  * @pdev: platform device to free
     375                 :            :  *
     376                 :            :  * Free all memory associated with a platform device.  This function must
     377                 :            :  * _only_ be externally called in error cases.  All other usage is a bug.
     378                 :            :  */
     379                 :         21 : void platform_device_put(struct platform_device *pdev)
     380                 :            : {
     381   [ -  -  -  -  :         21 :         if (!IS_ERR_OR_NULL(pdev))
          -  +  -  -  -  
                      - ]
     382                 :          0 :                 put_device(&pdev->dev);
     383                 :          0 : }
     384                 :            : EXPORT_SYMBOL_GPL(platform_device_put);
     385                 :            : 
     386                 :          0 : static void platform_device_release(struct device *dev)
     387                 :            : {
     388                 :          0 :         struct platform_object *pa = container_of(dev, struct platform_object,
     389                 :            :                                                   pdev.dev);
     390                 :            : 
     391                 :          0 :         of_device_node_put(&pa->pdev.dev);
     392                 :          0 :         kfree(pa->pdev.dev.platform_data);
     393                 :          0 :         kfree(pa->pdev.mfd_cell);
     394                 :          0 :         kfree(pa->pdev.resource);
     395                 :          0 :         kfree(pa->pdev.driver_override);
     396                 :          0 :         kfree(pa);
     397                 :          0 : }
     398                 :            : 
     399                 :            : /**
     400                 :            :  * platform_device_alloc - create a platform device
     401                 :            :  * @name: base name of the device we're adding
     402                 :            :  * @id: instance id
     403                 :            :  *
     404                 :            :  * Create a platform device object which can have other objects attached
     405                 :            :  * to it, and which will have attached objects freed when it is released.
     406                 :            :  */
     407                 :        168 : struct platform_device *platform_device_alloc(const char *name, int id)
     408                 :            : {
     409                 :        168 :         struct platform_object *pa;
     410                 :            : 
     411                 :        168 :         pa = kzalloc(sizeof(*pa) + strlen(name) + 1, GFP_KERNEL);
     412         [ +  - ]:        168 :         if (pa) {
     413                 :        168 :                 strcpy(pa->name, name);
     414                 :        168 :                 pa->pdev.name = pa->name;
     415                 :        168 :                 pa->pdev.id = id;
     416                 :        168 :                 device_initialize(&pa->pdev.dev);
     417                 :        168 :                 pa->pdev.dev.release = platform_device_release;
     418         [ +  - ]:        168 :                 setup_pdev_dma_masks(&pa->pdev);
     419                 :            :         }
     420                 :            : 
     421         [ +  - ]:        168 :         return pa ? &pa->pdev : NULL;
     422                 :            : }
     423                 :            : EXPORT_SYMBOL_GPL(platform_device_alloc);
     424                 :            : 
     425                 :            : /**
     426                 :            :  * platform_device_add_resources - add resources to a platform device
     427                 :            :  * @pdev: platform device allocated by platform_device_alloc to add resources to
     428                 :            :  * @res: set of resources that needs to be allocated for the device
     429                 :            :  * @num: number of resources
     430                 :            :  *
     431                 :            :  * Add a copy of the resources to the platform device.  The memory
     432                 :            :  * associated with the resources will be freed when the platform device is
     433                 :            :  * released.
     434                 :            :  */
     435                 :        147 : int platform_device_add_resources(struct platform_device *pdev,
     436                 :            :                                   const struct resource *res, unsigned int num)
     437                 :            : {
     438                 :        147 :         struct resource *r = NULL;
     439                 :            : 
     440         [ +  + ]:        147 :         if (res) {
     441                 :         42 :                 r = kmemdup(res, sizeof(struct resource) * num, GFP_KERNEL);
     442         [ +  - ]:         42 :                 if (!r)
     443                 :            :                         return -ENOMEM;
     444                 :            :         }
     445                 :            : 
     446                 :        147 :         kfree(pdev->resource);
     447                 :        147 :         pdev->resource = r;
     448                 :        147 :         pdev->num_resources = num;
     449                 :        147 :         return 0;
     450                 :            : }
     451                 :            : EXPORT_SYMBOL_GPL(platform_device_add_resources);
     452                 :            : 
     453                 :            : /**
     454                 :            :  * platform_device_add_data - add platform-specific data to a platform device
     455                 :            :  * @pdev: platform device allocated by platform_device_alloc to add resources to
     456                 :            :  * @data: platform specific data for this platform device
     457                 :            :  * @size: size of platform specific data
     458                 :            :  *
     459                 :            :  * Add a copy of platform specific data to the platform device's
     460                 :            :  * platform_data pointer.  The memory associated with the platform data
     461                 :            :  * will be freed when the platform device is released.
     462                 :            :  */
     463                 :        147 : int platform_device_add_data(struct platform_device *pdev, const void *data,
     464                 :            :                              size_t size)
     465                 :            : {
     466                 :        147 :         void *d = NULL;
     467                 :            : 
     468         [ +  + ]:        147 :         if (data) {
     469                 :         21 :                 d = kmemdup(data, size, GFP_KERNEL);
     470         [ +  - ]:         21 :                 if (!d)
     471                 :            :                         return -ENOMEM;
     472                 :            :         }
     473                 :            : 
     474                 :        147 :         kfree(pdev->dev.platform_data);
     475                 :        147 :         pdev->dev.platform_data = d;
     476                 :        147 :         return 0;
     477                 :            : }
     478                 :            : EXPORT_SYMBOL_GPL(platform_device_add_data);
     479                 :            : 
     480                 :            : /**
     481                 :            :  * platform_device_add_properties - add built-in properties to a platform device
     482                 :            :  * @pdev: platform device to add properties to
     483                 :            :  * @properties: null terminated array of properties to add
     484                 :            :  *
     485                 :            :  * The function will take deep copy of @properties and attach the copy to the
     486                 :            :  * platform device. The memory associated with properties will be freed when the
     487                 :            :  * platform device is released.
     488                 :            :  */
     489                 :          0 : int platform_device_add_properties(struct platform_device *pdev,
     490                 :            :                                    const struct property_entry *properties)
     491                 :            : {
     492                 :          0 :         return device_add_properties(&pdev->dev, properties);
     493                 :            : }
     494                 :            : EXPORT_SYMBOL_GPL(platform_device_add_properties);
     495                 :            : 
     496                 :            : /**
     497                 :            :  * platform_device_add - add a platform device to device hierarchy
     498                 :            :  * @pdev: platform device we're adding
     499                 :            :  *
     500                 :            :  * This is part 2 of platform_device_register(), though may be called
     501                 :            :  * separately _iff_ pdev was allocated by platform_device_alloc().
     502                 :            :  */
     503                 :        168 : int platform_device_add(struct platform_device *pdev)
     504                 :            : {
     505                 :        168 :         u32 i;
     506                 :        168 :         int ret;
     507                 :            : 
     508         [ +  - ]:        168 :         if (!pdev)
     509                 :            :                 return -EINVAL;
     510                 :            : 
     511         [ +  + ]:        168 :         if (!pdev->dev.parent)
     512                 :        126 :                 pdev->dev.parent = &platform_bus;
     513                 :            : 
     514                 :        168 :         pdev->dev.bus = &platform_bus_type;
     515                 :            : 
     516      [ +  +  + ]:        168 :         switch (pdev->id) {
     517                 :         42 :         default:
     518                 :         42 :                 dev_set_name(&pdev->dev, "%s.%d", pdev->name,  pdev->id);
     519                 :         42 :                 break;
     520                 :        105 :         case PLATFORM_DEVID_NONE:
     521                 :        105 :                 dev_set_name(&pdev->dev, "%s", pdev->name);
     522                 :        105 :                 break;
     523                 :         21 :         case PLATFORM_DEVID_AUTO:
     524                 :            :                 /*
     525                 :            :                  * Automatically allocated device ID. We mark it as such so
     526                 :            :                  * that we remember it must be freed, and we append a suffix
     527                 :            :                  * to avoid namespace collision with explicit IDs.
     528                 :            :                  */
     529                 :         21 :                 ret = ida_simple_get(&platform_devid_ida, 0, 0, GFP_KERNEL);
     530         [ -  + ]:         21 :                 if (ret < 0)
     531                 :          0 :                         goto err_out;
     532                 :         21 :                 pdev->id = ret;
     533                 :         21 :                 pdev->id_auto = true;
     534                 :         21 :                 dev_set_name(&pdev->dev, "%s.%d.auto", pdev->name, pdev->id);
     535                 :         21 :                 break;
     536                 :            :         }
     537                 :            : 
     538         [ +  + ]:        210 :         for (i = 0; i < pdev->num_resources; i++) {
     539                 :         42 :                 struct resource *p, *r = &pdev->resource[i];
     540                 :            : 
     541         [ +  - ]:         42 :                 if (r->name == NULL)
     542         [ +  - ]:         84 :                         r->name = dev_name(&pdev->dev);
     543                 :            : 
     544                 :         42 :                 p = r->parent;
     545         [ +  - ]:         42 :                 if (!p) {
     546         [ +  + ]:         42 :                         if (resource_type(r) == IORESOURCE_MEM)
     547                 :            :                                 p = &iomem_resource;
     548         [ +  - ]:         21 :                         else if (resource_type(r) == IORESOURCE_IO)
     549                 :         21 :                                 p = &ioport_resource;
     550                 :            :                 }
     551                 :            : 
     552         [ +  - ]:         42 :                 if (p) {
     553                 :         42 :                         ret = insert_resource(p, r);
     554         [ -  + ]:         42 :                         if (ret) {
     555                 :          0 :                                 dev_err(&pdev->dev, "failed to claim resource %d: %pR\n", i, r);
     556                 :          0 :                                 goto failed;
     557                 :            :                         }
     558                 :            :                 }
     559                 :            :         }
     560                 :            : 
     561                 :        168 :         pr_debug("Registering platform device '%s'. Parent at %s\n",
     562                 :            :                  dev_name(&pdev->dev), dev_name(pdev->dev.parent));
     563                 :            : 
     564                 :        168 :         ret = device_add(&pdev->dev);
     565         [ -  + ]:        168 :         if (ret == 0)
     566                 :            :                 return ret;
     567                 :            : 
     568                 :          0 :  failed:
     569         [ #  # ]:          0 :         if (pdev->id_auto) {
     570                 :          0 :                 ida_simple_remove(&platform_devid_ida, pdev->id);
     571                 :          0 :                 pdev->id = PLATFORM_DEVID_AUTO;
     572                 :            :         }
     573                 :            : 
     574         [ #  # ]:          0 :         while (i--) {
     575                 :          0 :                 struct resource *r = &pdev->resource[i];
     576         [ #  # ]:          0 :                 if (r->parent)
     577                 :          0 :                         release_resource(r);
     578                 :            :         }
     579                 :            : 
     580                 :          0 :  err_out:
     581                 :            :         return ret;
     582                 :            : }
     583                 :            : EXPORT_SYMBOL_GPL(platform_device_add);
     584                 :            : 
     585                 :            : /**
     586                 :            :  * platform_device_del - remove a platform-level device
     587                 :            :  * @pdev: platform device we're removing
     588                 :            :  *
     589                 :            :  * Note that this function will also release all memory- and port-based
     590                 :            :  * resources owned by the device (@dev->resource).  This function must
     591                 :            :  * _only_ be externally called in error cases.  All other usage is a bug.
     592                 :            :  */
     593                 :         21 : void platform_device_del(struct platform_device *pdev)
     594                 :            : {
     595                 :         21 :         u32 i;
     596                 :            : 
     597   [ -  +  -  + ]:         21 :         if (!IS_ERR_OR_NULL(pdev)) {
     598                 :          0 :                 device_del(&pdev->dev);
     599                 :            : 
     600         [ #  # ]:          0 :                 if (pdev->id_auto) {
     601                 :          0 :                         ida_simple_remove(&platform_devid_ida, pdev->id);
     602                 :          0 :                         pdev->id = PLATFORM_DEVID_AUTO;
     603                 :            :                 }
     604                 :            : 
     605         [ #  # ]:          0 :                 for (i = 0; i < pdev->num_resources; i++) {
     606                 :          0 :                         struct resource *r = &pdev->resource[i];
     607         [ #  # ]:          0 :                         if (r->parent)
     608                 :          0 :                                 release_resource(r);
     609                 :            :                 }
     610                 :            :         }
     611                 :         21 : }
     612                 :            : EXPORT_SYMBOL_GPL(platform_device_del);
     613                 :            : 
     614                 :            : /**
     615                 :            :  * platform_device_register - add a platform-level device
     616                 :            :  * @pdev: platform device we're adding
     617                 :            :  */
     618                 :          0 : int platform_device_register(struct platform_device *pdev)
     619                 :            : {
     620                 :          0 :         device_initialize(&pdev->dev);
     621         [ #  # ]:          0 :         setup_pdev_dma_masks(pdev);
     622                 :          0 :         return platform_device_add(pdev);
     623                 :            : }
     624                 :            : EXPORT_SYMBOL_GPL(platform_device_register);
     625                 :            : 
     626                 :            : /**
     627                 :            :  * platform_device_unregister - unregister a platform-level device
     628                 :            :  * @pdev: platform device we're unregistering
     629                 :            :  *
     630                 :            :  * Unregistration is done in 2 steps. First we release all resources
     631                 :            :  * and remove it from the subsystem, then we drop reference count by
     632                 :            :  * calling platform_device_put().
     633                 :            :  */
     634                 :         21 : void platform_device_unregister(struct platform_device *pdev)
     635                 :            : {
     636                 :         21 :         platform_device_del(pdev);
     637         [ -  + ]:         21 :         platform_device_put(pdev);
     638                 :         21 : }
     639                 :            : EXPORT_SYMBOL_GPL(platform_device_unregister);
     640                 :            : 
     641                 :            : /**
     642                 :            :  * platform_device_register_full - add a platform-level device with
     643                 :            :  * resources and platform-specific data
     644                 :            :  *
     645                 :            :  * @pdevinfo: data used to create device
     646                 :            :  *
     647                 :            :  * Returns &struct platform_device pointer on success, or ERR_PTR() on error.
     648                 :            :  */
     649                 :        126 : struct platform_device *platform_device_register_full(
     650                 :            :                 const struct platform_device_info *pdevinfo)
     651                 :            : {
     652                 :        126 :         int ret = -ENOMEM;
     653                 :        126 :         struct platform_device *pdev;
     654                 :            : 
     655                 :        126 :         pdev = platform_device_alloc(pdevinfo->name, pdevinfo->id);
     656         [ +  - ]:        126 :         if (!pdev)
     657                 :            :                 return ERR_PTR(-ENOMEM);
     658                 :            : 
     659                 :        126 :         pdev->dev.parent = pdevinfo->parent;
     660                 :        126 :         pdev->dev.fwnode = pdevinfo->fwnode;
     661         [ +  + ]:        126 :         pdev->dev.of_node = of_node_get(to_of_node(pdev->dev.fwnode));
     662                 :        126 :         pdev->dev.of_node_reused = pdevinfo->of_node_reused;
     663                 :            : 
     664         [ +  + ]:        126 :         if (pdevinfo->dma_mask) {
     665                 :         42 :                 pdev->platform_dma_mask = pdevinfo->dma_mask;
     666                 :         42 :                 pdev->dev.dma_mask = &pdev->platform_dma_mask;
     667                 :         42 :                 pdev->dev.coherent_dma_mask = pdevinfo->dma_mask;
     668                 :            :         }
     669                 :            : 
     670                 :        126 :         ret = platform_device_add_resources(pdev,
     671                 :            :                         pdevinfo->res, pdevinfo->num_res);
     672         [ -  + ]:        126 :         if (ret)
     673                 :          0 :                 goto err;
     674                 :            : 
     675                 :        126 :         ret = platform_device_add_data(pdev,
     676                 :            :                         pdevinfo->data, pdevinfo->size_data);
     677         [ -  + ]:        126 :         if (ret)
     678                 :          0 :                 goto err;
     679                 :            : 
     680         [ -  + ]:        126 :         if (pdevinfo->properties) {
     681                 :          0 :                 ret = platform_device_add_properties(pdev,
     682                 :            :                                                      pdevinfo->properties);
     683         [ #  # ]:          0 :                 if (ret)
     684                 :          0 :                         goto err;
     685                 :            :         }
     686                 :            : 
     687                 :        126 :         ret = platform_device_add(pdev);
     688         [ -  + ]:        126 :         if (ret) {
     689                 :          0 : err:
     690                 :          0 :                 ACPI_COMPANION_SET(&pdev->dev, NULL);
     691         [ #  # ]:          0 :                 platform_device_put(pdev);
     692                 :          0 :                 return ERR_PTR(ret);
     693                 :            :         }
     694                 :            : 
     695                 :            :         return pdev;
     696                 :            : }
     697                 :            : EXPORT_SYMBOL_GPL(platform_device_register_full);
     698                 :            : 
     699                 :         63 : static int platform_drv_probe(struct device *_dev)
     700                 :            : {
     701                 :         63 :         struct platform_driver *drv = to_platform_driver(_dev->driver);
     702                 :         63 :         struct platform_device *dev = to_platform_device(_dev);
     703                 :         63 :         int ret;
     704                 :            : 
     705                 :         63 :         ret = of_clk_set_defaults(_dev->of_node, false);
     706                 :         63 :         if (ret < 0)
     707                 :            :                 return ret;
     708                 :            : 
     709                 :         63 :         ret = dev_pm_domain_attach(_dev, true);
     710         [ -  + ]:         63 :         if (ret)
     711                 :          0 :                 goto out;
     712                 :            : 
     713         [ +  + ]:         63 :         if (drv->probe) {
     714                 :         42 :                 ret = drv->probe(dev);
     715         [ +  - ]:         42 :                 if (ret)
     716                 :          0 :                         dev_pm_domain_detach(_dev, true);
     717                 :            :         }
     718                 :            : 
     719                 :         63 : out:
     720   [ +  +  -  + ]:         63 :         if (drv->prevent_deferred_probe && ret == -EPROBE_DEFER) {
     721                 :          0 :                 dev_warn(_dev, "probe deferral not supported\n");
     722                 :          0 :                 ret = -ENXIO;
     723                 :            :         }
     724                 :            : 
     725                 :         63 :         return ret;
     726                 :            : }
     727                 :            : 
     728                 :          0 : static int platform_drv_probe_fail(struct device *_dev)
     729                 :            : {
     730                 :          0 :         return -ENXIO;
     731                 :            : }
     732                 :            : 
     733                 :          0 : static int platform_drv_remove(struct device *_dev)
     734                 :            : {
     735                 :          0 :         struct platform_driver *drv = to_platform_driver(_dev->driver);
     736                 :          0 :         struct platform_device *dev = to_platform_device(_dev);
     737                 :          0 :         int ret = 0;
     738                 :            : 
     739         [ #  # ]:          0 :         if (drv->remove)
     740                 :          0 :                 ret = drv->remove(dev);
     741                 :          0 :         dev_pm_domain_detach(_dev, true);
     742                 :            : 
     743                 :          0 :         return ret;
     744                 :            : }
     745                 :            : 
     746                 :          0 : static void platform_drv_shutdown(struct device *_dev)
     747                 :            : {
     748                 :          0 :         struct platform_driver *drv = to_platform_driver(_dev->driver);
     749                 :          0 :         struct platform_device *dev = to_platform_device(_dev);
     750                 :            : 
     751         [ #  # ]:          0 :         if (drv->shutdown)
     752                 :          0 :                 drv->shutdown(dev);
     753                 :          0 : }
     754                 :            : 
     755                 :            : /**
     756                 :            :  * __platform_driver_register - register a driver for platform-level devices
     757                 :            :  * @drv: platform driver structure
     758                 :            :  * @owner: owning module/driver
     759                 :            :  */
     760                 :        231 : int __platform_driver_register(struct platform_driver *drv,
     761                 :            :                                 struct module *owner)
     762                 :            : {
     763                 :        231 :         drv->driver.owner = owner;
     764                 :        231 :         drv->driver.bus = &platform_bus_type;
     765                 :        231 :         drv->driver.probe = platform_drv_probe;
     766                 :        231 :         drv->driver.remove = platform_drv_remove;
     767                 :        231 :         drv->driver.shutdown = platform_drv_shutdown;
     768                 :            : 
     769                 :        210 :         return driver_register(&drv->driver);
     770                 :            : }
     771                 :            : EXPORT_SYMBOL_GPL(__platform_driver_register);
     772                 :            : 
     773                 :            : /**
     774                 :            :  * platform_driver_unregister - unregister a driver for platform-level devices
     775                 :            :  * @drv: platform driver structure
     776                 :            :  */
     777                 :         21 : void platform_driver_unregister(struct platform_driver *drv)
     778                 :            : {
     779                 :         21 :         driver_unregister(&drv->driver);
     780                 :          0 : }
     781                 :            : EXPORT_SYMBOL_GPL(platform_driver_unregister);
     782                 :            : 
     783                 :            : /**
     784                 :            :  * __platform_driver_probe - register driver for non-hotpluggable device
     785                 :            :  * @drv: platform driver structure
     786                 :            :  * @probe: the driver probe routine, probably from an __init section
     787                 :            :  * @module: module which will be the owner of the driver
     788                 :            :  *
     789                 :            :  * Use this instead of platform_driver_register() when you know the device
     790                 :            :  * is not hotpluggable and has already been registered, and you want to
     791                 :            :  * remove its run-once probe() infrastructure from memory after the driver
     792                 :            :  * has bound to the device.
     793                 :            :  *
     794                 :            :  * One typical use for this would be with drivers for controllers integrated
     795                 :            :  * into system-on-chip processors, where the controller devices have been
     796                 :            :  * configured as part of board setup.
     797                 :            :  *
     798                 :            :  * Note that this is incompatible with deferred probing.
     799                 :            :  *
     800                 :            :  * Returns zero if the driver registered and bound to a device, else returns
     801                 :            :  * a negative error code and with the driver not registered.
     802                 :            :  */
     803                 :         21 : int __init_or_module __platform_driver_probe(struct platform_driver *drv,
     804                 :            :                 int (*probe)(struct platform_device *), struct module *module)
     805                 :            : {
     806                 :         21 :         int retval, code;
     807                 :            : 
     808         [ -  + ]:         21 :         if (drv->driver.probe_type == PROBE_PREFER_ASYNCHRONOUS) {
     809                 :          0 :                 pr_err("%s: drivers registered with %s can not be probed asynchronously\n",
     810                 :            :                          drv->driver.name, __func__);
     811                 :          0 :                 return -EINVAL;
     812                 :            :         }
     813                 :            : 
     814                 :            :         /*
     815                 :            :          * We have to run our probes synchronously because we check if
     816                 :            :          * we find any devices to bind to and exit with error if there
     817                 :            :          * are any.
     818                 :            :          */
     819                 :         21 :         drv->driver.probe_type = PROBE_FORCE_SYNCHRONOUS;
     820                 :            : 
     821                 :            :         /*
     822                 :            :          * Prevent driver from requesting probe deferral to avoid further
     823                 :            :          * futile probe attempts.
     824                 :            :          */
     825                 :         21 :         drv->prevent_deferred_probe = true;
     826                 :            : 
     827                 :            :         /* make sure driver won't have bind/unbind attributes */
     828                 :         21 :         drv->driver.suppress_bind_attrs = true;
     829                 :            : 
     830                 :            :         /* temporary section violation during probe() */
     831                 :         21 :         drv->probe = probe;
     832                 :         21 :         retval = code = __platform_driver_register(drv, module);
     833                 :            : 
     834                 :            :         /*
     835                 :            :          * Fixup that section violation, being paranoid about code scanning
     836                 :            :          * the list of drivers in order to probe new devices.  Check to see
     837                 :            :          * if the probe was successful, and make sure any forced probes of
     838                 :            :          * new devices fail.
     839                 :            :          */
     840                 :         21 :         spin_lock(&drv->driver.bus->p->klist_drivers.k_lock);
     841                 :         21 :         drv->probe = NULL;
     842   [ +  -  -  + ]:         21 :         if (code == 0 && list_empty(&drv->driver.p->klist_devices.k_list))
     843                 :          0 :                 retval = -ENODEV;
     844                 :         21 :         drv->driver.probe = platform_drv_probe_fail;
     845                 :         21 :         spin_unlock(&drv->driver.bus->p->klist_drivers.k_lock);
     846                 :            : 
     847         [ -  + ]:         21 :         if (code != retval)
     848                 :          0 :                 platform_driver_unregister(drv);
     849                 :            :         return retval;
     850                 :            : }
     851                 :            : EXPORT_SYMBOL_GPL(__platform_driver_probe);
     852                 :            : 
     853                 :            : /**
     854                 :            :  * __platform_create_bundle - register driver and create corresponding device
     855                 :            :  * @driver: platform driver structure
     856                 :            :  * @probe: the driver probe routine, probably from an __init section
     857                 :            :  * @res: set of resources that needs to be allocated for the device
     858                 :            :  * @n_res: number of resources
     859                 :            :  * @data: platform specific data for this platform device
     860                 :            :  * @size: size of platform specific data
     861                 :            :  * @module: module which will be the owner of the driver
     862                 :            :  *
     863                 :            :  * Use this in legacy-style modules that probe hardware directly and
     864                 :            :  * register a single platform device and corresponding platform driver.
     865                 :            :  *
     866                 :            :  * Returns &struct platform_device pointer on success, or ERR_PTR() on error.
     867                 :            :  */
     868                 :         21 : struct platform_device * __init_or_module __platform_create_bundle(
     869                 :            :                         struct platform_driver *driver,
     870                 :            :                         int (*probe)(struct platform_device *),
     871                 :            :                         struct resource *res, unsigned int n_res,
     872                 :            :                         const void *data, size_t size, struct module *module)
     873                 :            : {
     874                 :         21 :         struct platform_device *pdev;
     875                 :         21 :         int error;
     876                 :            : 
     877                 :         21 :         pdev = platform_device_alloc(driver->driver.name, -1);
     878         [ -  + ]:         21 :         if (!pdev) {
     879                 :          0 :                 error = -ENOMEM;
     880                 :          0 :                 goto err_out;
     881                 :            :         }
     882                 :            : 
     883                 :         21 :         error = platform_device_add_resources(pdev, res, n_res);
     884         [ -  + ]:         21 :         if (error)
     885                 :          0 :                 goto err_pdev_put;
     886                 :            : 
     887                 :         21 :         error = platform_device_add_data(pdev, data, size);
     888         [ -  + ]:         21 :         if (error)
     889                 :          0 :                 goto err_pdev_put;
     890                 :            : 
     891                 :         21 :         error = platform_device_add(pdev);
     892         [ -  + ]:         21 :         if (error)
     893                 :          0 :                 goto err_pdev_put;
     894                 :            : 
     895                 :         21 :         error = __platform_driver_probe(driver, probe, module);
     896         [ -  + ]:         21 :         if (error)
     897                 :          0 :                 goto err_pdev_del;
     898                 :            : 
     899                 :            :         return pdev;
     900                 :            : 
     901                 :            : err_pdev_del:
     902                 :          0 :         platform_device_del(pdev);
     903                 :          0 : err_pdev_put:
     904         [ #  # ]:          0 :         platform_device_put(pdev);
     905                 :          0 : err_out:
     906                 :          0 :         return ERR_PTR(error);
     907                 :            : }
     908                 :            : EXPORT_SYMBOL_GPL(__platform_create_bundle);
     909                 :            : 
     910                 :            : /**
     911                 :            :  * __platform_register_drivers - register an array of platform drivers
     912                 :            :  * @drivers: an array of drivers to register
     913                 :            :  * @count: the number of drivers to register
     914                 :            :  * @owner: module owning the drivers
     915                 :            :  *
     916                 :            :  * Registers platform drivers specified by an array. On failure to register a
     917                 :            :  * driver, all previously registered drivers will be unregistered. Callers of
     918                 :            :  * this API should use platform_unregister_drivers() to unregister drivers in
     919                 :            :  * the reverse order.
     920                 :            :  *
     921                 :            :  * Returns: 0 on success or a negative error code on failure.
     922                 :            :  */
     923                 :          0 : int __platform_register_drivers(struct platform_driver * const *drivers,
     924                 :            :                                 unsigned int count, struct module *owner)
     925                 :            : {
     926                 :          0 :         unsigned int i;
     927                 :          0 :         int err;
     928                 :            : 
     929         [ #  # ]:          0 :         for (i = 0; i < count; i++) {
     930                 :          0 :                 pr_debug("registering platform driver %ps\n", drivers[i]);
     931                 :            : 
     932                 :          0 :                 err = __platform_driver_register(drivers[i], owner);
     933         [ #  # ]:          0 :                 if (err < 0) {
     934                 :          0 :                         pr_err("failed to register platform driver %ps: %d\n",
     935                 :            :                                drivers[i], err);
     936                 :          0 :                         goto error;
     937                 :            :                 }
     938                 :            :         }
     939                 :            : 
     940                 :            :         return 0;
     941                 :            : 
     942                 :            : error:
     943         [ #  # ]:          0 :         while (i--) {
     944                 :          0 :                 pr_debug("unregistering platform driver %ps\n", drivers[i]);
     945                 :          0 :                 platform_driver_unregister(drivers[i]);
     946                 :            :         }
     947                 :            : 
     948                 :            :         return err;
     949                 :            : }
     950                 :            : EXPORT_SYMBOL_GPL(__platform_register_drivers);
     951                 :            : 
     952                 :            : /**
     953                 :            :  * platform_unregister_drivers - unregister an array of platform drivers
     954                 :            :  * @drivers: an array of drivers to unregister
     955                 :            :  * @count: the number of drivers to unregister
     956                 :            :  *
     957                 :            :  * Unegisters platform drivers specified by an array. This is typically used
     958                 :            :  * to complement an earlier call to platform_register_drivers(). Drivers are
     959                 :            :  * unregistered in the reverse order in which they were registered.
     960                 :            :  */
     961                 :          0 : void platform_unregister_drivers(struct platform_driver * const *drivers,
     962                 :            :                                  unsigned int count)
     963                 :            : {
     964         [ #  # ]:          0 :         while (count--) {
     965                 :          0 :                 pr_debug("unregistering platform driver %ps\n", drivers[count]);
     966                 :          0 :                 platform_driver_unregister(drivers[count]);
     967                 :            :         }
     968                 :          0 : }
     969                 :            : EXPORT_SYMBOL_GPL(platform_unregister_drivers);
     970                 :            : 
     971                 :            : /* modalias support enables more hands-off userspace setup:
     972                 :            :  * (a) environment variable lets new-style hotplug events work once system is
     973                 :            :  *     fully running:  "modprobe $MODALIAS"
     974                 :            :  * (b) sysfs attribute lets new-style coldplug recover from hotplug events
     975                 :            :  *     mishandled before system is fully running:  "modprobe $(cat modalias)"
     976                 :            :  */
     977                 :         21 : static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
     978                 :            :                              char *buf)
     979                 :            : {
     980                 :         21 :         struct platform_device  *pdev = to_platform_device(dev);
     981                 :         21 :         int len;
     982                 :            : 
     983                 :         21 :         len = of_device_modalias(dev, buf, PAGE_SIZE);
     984                 :         21 :         if (len != -ENODEV)
     985                 :            :                 return len;
     986                 :            : 
     987                 :         21 :         len = acpi_device_modalias(dev, buf, PAGE_SIZE -1);
     988         [ +  - ]:         21 :         if (len != -ENODEV)
     989                 :         21 :                 return len;
     990                 :            : 
     991                 :          0 :         len = snprintf(buf, PAGE_SIZE, "platform:%s\n", pdev->name);
     992                 :            : 
     993         [ #  # ]:          0 :         return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
     994                 :            : }
     995                 :            : static DEVICE_ATTR_RO(modalias);
     996                 :            : 
     997                 :          0 : static ssize_t driver_override_store(struct device *dev,
     998                 :            :                                      struct device_attribute *attr,
     999                 :            :                                      const char *buf, size_t count)
    1000                 :            : {
    1001                 :          0 :         struct platform_device *pdev = to_platform_device(dev);
    1002                 :          0 :         char *driver_override, *old, *cp;
    1003                 :            : 
    1004                 :            :         /* We need to keep extra room for a newline */
    1005         [ #  # ]:          0 :         if (count >= (PAGE_SIZE - 1))
    1006                 :            :                 return -EINVAL;
    1007                 :            : 
    1008                 :          0 :         driver_override = kstrndup(buf, count, GFP_KERNEL);
    1009         [ #  # ]:          0 :         if (!driver_override)
    1010                 :            :                 return -ENOMEM;
    1011                 :            : 
    1012                 :          0 :         cp = strchr(driver_override, '\n');
    1013         [ #  # ]:          0 :         if (cp)
    1014                 :          0 :                 *cp = '\0';
    1015                 :            : 
    1016                 :          0 :         device_lock(dev);
    1017                 :          0 :         old = pdev->driver_override;
    1018         [ #  # ]:          0 :         if (strlen(driver_override)) {
    1019                 :          0 :                 pdev->driver_override = driver_override;
    1020                 :            :         } else {
    1021                 :          0 :                 kfree(driver_override);
    1022                 :          0 :                 pdev->driver_override = NULL;
    1023                 :            :         }
    1024                 :          0 :         device_unlock(dev);
    1025                 :            : 
    1026                 :          0 :         kfree(old);
    1027                 :            : 
    1028                 :          0 :         return count;
    1029                 :            : }
    1030                 :            : 
    1031                 :          0 : static ssize_t driver_override_show(struct device *dev,
    1032                 :            :                                     struct device_attribute *attr, char *buf)
    1033                 :            : {
    1034                 :          0 :         struct platform_device *pdev = to_platform_device(dev);
    1035                 :          0 :         ssize_t len;
    1036                 :            : 
    1037                 :          0 :         device_lock(dev);
    1038                 :          0 :         len = sprintf(buf, "%s\n", pdev->driver_override);
    1039                 :          0 :         device_unlock(dev);
    1040                 :          0 :         return len;
    1041                 :            : }
    1042                 :            : static DEVICE_ATTR_RW(driver_override);
    1043                 :            : 
    1044                 :            : 
    1045                 :            : static struct attribute *platform_dev_attrs[] = {
    1046                 :            :         &dev_attr_modalias.attr,
    1047                 :            :         &dev_attr_driver_override.attr,
    1048                 :            :         NULL,
    1049                 :            : };
    1050                 :            : ATTRIBUTE_GROUPS(platform_dev);
    1051                 :            : 
    1052                 :        945 : static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
    1053                 :            : {
    1054                 :        945 :         struct platform_device  *pdev = to_platform_device(dev);
    1055                 :        945 :         int rc;
    1056                 :            : 
    1057                 :            :         /* Some devices have extra OF data and an OF-style MODALIAS */
    1058                 :        945 :         rc = of_device_uevent_modalias(dev, env);
    1059                 :        945 :         if (rc != -ENODEV)
    1060                 :            :                 return rc;
    1061                 :            : 
    1062                 :        945 :         rc = acpi_device_uevent_modalias(dev, env);
    1063         [ +  + ]:        945 :         if (rc != -ENODEV)
    1064                 :            :                 return rc;
    1065                 :            : 
    1066                 :        777 :         add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX,
    1067                 :            :                         pdev->name);
    1068                 :        777 :         return 0;
    1069                 :            : }
    1070                 :            : 
    1071                 :            : static const struct platform_device_id *platform_match_id(
    1072                 :            :                         const struct platform_device_id *id,
    1073                 :            :                         struct platform_device *pdev)
    1074                 :            : {
    1075         [ +  + ]:        336 :         while (id->name[0]) {
    1076         [ -  + ]:        168 :                 if (strcmp(pdev->name, id->name) == 0) {
    1077                 :          0 :                         pdev->id_entry = id;
    1078                 :          0 :                         return id;
    1079                 :            :                 }
    1080                 :        168 :                 id++;
    1081                 :            :         }
    1082                 :            :         return NULL;
    1083                 :            : }
    1084                 :            : 
    1085                 :            : /**
    1086                 :            :  * platform_match - bind platform device to platform driver.
    1087                 :            :  * @dev: device.
    1088                 :            :  * @drv: driver.
    1089                 :            :  *
    1090                 :            :  * Platform device IDs are assumed to be encoded like this:
    1091                 :            :  * "<name><instance>", where <name> is a short description of the type of
    1092                 :            :  * device, like "pci" or "floppy", and <instance> is the enumerated
    1093                 :            :  * instance of the device, like '0' or '42'.  Driver IDs are simply
    1094                 :            :  * "<name>".  So, extract the <name> from the platform_device structure,
    1095                 :            :  * and compare it against the name of the driver. Return whether they match
    1096                 :            :  * or not.
    1097                 :            :  */
    1098                 :       1680 : static int platform_match(struct device *dev, struct device_driver *drv)
    1099                 :            : {
    1100                 :       1680 :         struct platform_device *pdev = to_platform_device(dev);
    1101                 :       1680 :         struct platform_driver *pdrv = to_platform_driver(drv);
    1102                 :            : 
    1103                 :            :         /* When driver_override is set, only bind to the matching driver */
    1104         [ -  + ]:       1680 :         if (pdev->driver_override)
    1105                 :          0 :                 return !strcmp(pdev->driver_override, drv->name);
    1106                 :            : 
    1107                 :            :         /* Attempt an OF style match first */
    1108                 :       1680 :         if (of_driver_match_device(dev, drv))
    1109                 :            :                 return 1;
    1110                 :            : 
    1111                 :            :         /* Then try ACPI style match */
    1112         [ +  - ]:       1680 :         if (acpi_driver_match_device(dev, drv))
    1113                 :            :                 return 1;
    1114                 :            : 
    1115                 :            :         /* Then try to match against the id table */
    1116         [ +  + ]:       1680 :         if (pdrv->id_table)
    1117                 :        168 :                 return platform_match_id(pdrv->id_table, pdev) != NULL;
    1118                 :            : 
    1119                 :            :         /* fall-back to driver name match */
    1120                 :       1512 :         return (strcmp(pdev->name, drv->name) == 0);
    1121                 :            : }
    1122                 :            : 
    1123                 :            : #ifdef CONFIG_PM_SLEEP
    1124                 :            : 
    1125                 :          0 : static int platform_legacy_suspend(struct device *dev, pm_message_t mesg)
    1126                 :            : {
    1127                 :          0 :         struct platform_driver *pdrv = to_platform_driver(dev->driver);
    1128                 :          0 :         struct platform_device *pdev = to_platform_device(dev);
    1129                 :          0 :         int ret = 0;
    1130                 :            : 
    1131                 :          0 :         if (dev->driver && pdrv->suspend)
    1132                 :          0 :                 ret = pdrv->suspend(pdev, mesg);
    1133                 :            : 
    1134                 :          0 :         return ret;
    1135                 :            : }
    1136                 :            : 
    1137                 :          0 : static int platform_legacy_resume(struct device *dev)
    1138                 :            : {
    1139                 :          0 :         struct platform_driver *pdrv = to_platform_driver(dev->driver);
    1140                 :          0 :         struct platform_device *pdev = to_platform_device(dev);
    1141                 :          0 :         int ret = 0;
    1142                 :            : 
    1143                 :          0 :         if (dev->driver && pdrv->resume)
    1144                 :          0 :                 ret = pdrv->resume(pdev);
    1145                 :            : 
    1146                 :            :         return ret;
    1147                 :            : }
    1148                 :            : 
    1149                 :            : #endif /* CONFIG_PM_SLEEP */
    1150                 :            : 
    1151                 :            : #ifdef CONFIG_SUSPEND
    1152                 :            : 
    1153                 :          0 : int platform_pm_suspend(struct device *dev)
    1154                 :            : {
    1155                 :          0 :         struct device_driver *drv = dev->driver;
    1156                 :          0 :         int ret = 0;
    1157                 :            : 
    1158         [ #  # ]:          0 :         if (!drv)
    1159                 :            :                 return 0;
    1160                 :            : 
    1161         [ #  # ]:          0 :         if (drv->pm) {
    1162         [ #  # ]:          0 :                 if (drv->pm->suspend)
    1163                 :          0 :                         ret = drv->pm->suspend(dev);
    1164                 :            :         } else {
    1165         [ #  # ]:          0 :                 ret = platform_legacy_suspend(dev, PMSG_SUSPEND);
    1166                 :            :         }
    1167                 :            : 
    1168                 :            :         return ret;
    1169                 :            : }
    1170                 :            : 
    1171                 :          0 : int platform_pm_resume(struct device *dev)
    1172                 :            : {
    1173                 :          0 :         struct device_driver *drv = dev->driver;
    1174                 :          0 :         int ret = 0;
    1175                 :            : 
    1176         [ #  # ]:          0 :         if (!drv)
    1177                 :            :                 return 0;
    1178                 :            : 
    1179         [ #  # ]:          0 :         if (drv->pm) {
    1180         [ #  # ]:          0 :                 if (drv->pm->resume)
    1181                 :          0 :                         ret = drv->pm->resume(dev);
    1182                 :            :         } else {
    1183         [ #  # ]:          0 :                 ret = platform_legacy_resume(dev);
    1184                 :            :         }
    1185                 :            : 
    1186                 :            :         return ret;
    1187                 :            : }
    1188                 :            : 
    1189                 :            : #endif /* CONFIG_SUSPEND */
    1190                 :            : 
    1191                 :            : #ifdef CONFIG_HIBERNATE_CALLBACKS
    1192                 :            : 
    1193                 :          0 : int platform_pm_freeze(struct device *dev)
    1194                 :            : {
    1195                 :          0 :         struct device_driver *drv = dev->driver;
    1196                 :          0 :         int ret = 0;
    1197                 :            : 
    1198         [ #  # ]:          0 :         if (!drv)
    1199                 :            :                 return 0;
    1200                 :            : 
    1201         [ #  # ]:          0 :         if (drv->pm) {
    1202         [ #  # ]:          0 :                 if (drv->pm->freeze)
    1203                 :          0 :                         ret = drv->pm->freeze(dev);
    1204                 :            :         } else {
    1205         [ #  # ]:          0 :                 ret = platform_legacy_suspend(dev, PMSG_FREEZE);
    1206                 :            :         }
    1207                 :            : 
    1208                 :            :         return ret;
    1209                 :            : }
    1210                 :            : 
    1211                 :          0 : int platform_pm_thaw(struct device *dev)
    1212                 :            : {
    1213                 :          0 :         struct device_driver *drv = dev->driver;
    1214                 :          0 :         int ret = 0;
    1215                 :            : 
    1216         [ #  # ]:          0 :         if (!drv)
    1217                 :            :                 return 0;
    1218                 :            : 
    1219         [ #  # ]:          0 :         if (drv->pm) {
    1220         [ #  # ]:          0 :                 if (drv->pm->thaw)
    1221                 :          0 :                         ret = drv->pm->thaw(dev);
    1222                 :            :         } else {
    1223         [ #  # ]:          0 :                 ret = platform_legacy_resume(dev);
    1224                 :            :         }
    1225                 :            : 
    1226                 :            :         return ret;
    1227                 :            : }
    1228                 :            : 
    1229                 :          0 : int platform_pm_poweroff(struct device *dev)
    1230                 :            : {
    1231                 :          0 :         struct device_driver *drv = dev->driver;
    1232                 :          0 :         int ret = 0;
    1233                 :            : 
    1234         [ #  # ]:          0 :         if (!drv)
    1235                 :            :                 return 0;
    1236                 :            : 
    1237         [ #  # ]:          0 :         if (drv->pm) {
    1238         [ #  # ]:          0 :                 if (drv->pm->poweroff)
    1239                 :          0 :                         ret = drv->pm->poweroff(dev);
    1240                 :            :         } else {
    1241         [ #  # ]:          0 :                 ret = platform_legacy_suspend(dev, PMSG_HIBERNATE);
    1242                 :            :         }
    1243                 :            : 
    1244                 :            :         return ret;
    1245                 :            : }
    1246                 :            : 
    1247                 :          0 : int platform_pm_restore(struct device *dev)
    1248                 :            : {
    1249                 :          0 :         struct device_driver *drv = dev->driver;
    1250                 :          0 :         int ret = 0;
    1251                 :            : 
    1252         [ #  # ]:          0 :         if (!drv)
    1253                 :            :                 return 0;
    1254                 :            : 
    1255         [ #  # ]:          0 :         if (drv->pm) {
    1256         [ #  # ]:          0 :                 if (drv->pm->restore)
    1257                 :          0 :                         ret = drv->pm->restore(dev);
    1258                 :            :         } else {
    1259         [ #  # ]:          0 :                 ret = platform_legacy_resume(dev);
    1260                 :            :         }
    1261                 :            : 
    1262                 :            :         return ret;
    1263                 :            : }
    1264                 :            : 
    1265                 :            : #endif /* CONFIG_HIBERNATE_CALLBACKS */
    1266                 :            : 
    1267                 :         63 : int platform_dma_configure(struct device *dev)
    1268                 :            : {
    1269                 :         63 :         enum dev_dma_attr attr;
    1270                 :         63 :         int ret = 0;
    1271                 :            : 
    1272         [ +  - ]:         63 :         if (dev->of_node) {
    1273                 :            :                 ret = of_dma_configure(dev, dev->of_node, true);
    1274         [ -  + ]:         63 :         } else if (has_acpi_companion(dev)) {
    1275         [ #  # ]:          0 :                 attr = acpi_get_dma_attr(to_acpi_device_node(dev->fwnode));
    1276                 :          0 :                 ret = acpi_dma_configure(dev, attr);
    1277                 :            :         }
    1278                 :            : 
    1279                 :         63 :         return ret;
    1280                 :            : }
    1281                 :            : 
    1282                 :            : static const struct dev_pm_ops platform_dev_pm_ops = {
    1283                 :            :         .runtime_suspend = pm_generic_runtime_suspend,
    1284                 :            :         .runtime_resume = pm_generic_runtime_resume,
    1285                 :            :         USE_PLATFORM_PM_SLEEP_OPS
    1286                 :            : };
    1287                 :            : 
    1288                 :            : struct bus_type platform_bus_type = {
    1289                 :            :         .name           = "platform",
    1290                 :            :         .dev_groups     = platform_dev_groups,
    1291                 :            :         .match          = platform_match,
    1292                 :            :         .uevent         = platform_uevent,
    1293                 :            :         .dma_configure  = platform_dma_configure,
    1294                 :            :         .pm             = &platform_dev_pm_ops,
    1295                 :            : };
    1296                 :            : EXPORT_SYMBOL_GPL(platform_bus_type);
    1297                 :            : 
    1298                 :          0 : static inline int __platform_match(struct device *dev, const void *drv)
    1299                 :            : {
    1300                 :          0 :         return platform_match(dev, (struct device_driver *)drv);
    1301                 :            : }
    1302                 :            : 
    1303                 :            : /**
    1304                 :            :  * platform_find_device_by_driver - Find a platform device with a given
    1305                 :            :  * driver.
    1306                 :            :  * @start: The device to start the search from.
    1307                 :            :  * @drv: The device driver to look for.
    1308                 :            :  */
    1309                 :          0 : struct device *platform_find_device_by_driver(struct device *start,
    1310                 :            :                                               const struct device_driver *drv)
    1311                 :            : {
    1312                 :          0 :         return bus_find_device(&platform_bus_type, start, drv,
    1313                 :            :                                __platform_match);
    1314                 :            : }
    1315                 :            : EXPORT_SYMBOL_GPL(platform_find_device_by_driver);
    1316                 :            : 
    1317                 :         21 : void __weak __init early_platform_cleanup(void) { }
    1318                 :            : 
    1319                 :         21 : int __init platform_bus_init(void)
    1320                 :            : {
    1321                 :         21 :         int error;
    1322                 :            : 
    1323                 :         21 :         early_platform_cleanup();
    1324                 :            : 
    1325                 :         21 :         error = device_register(&platform_bus);
    1326         [ -  + ]:         21 :         if (error) {
    1327                 :          0 :                 put_device(&platform_bus);
    1328                 :          0 :                 return error;
    1329                 :            :         }
    1330                 :         21 :         error =  bus_register(&platform_bus_type);
    1331         [ -  + ]:         21 :         if (error)
    1332                 :          0 :                 device_unregister(&platform_bus);
    1333                 :            :         of_platform_register_reconfig_notifier();
    1334                 :            :         return error;
    1335                 :            : }

Generated by: LCOV version 1.14