Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 
0003 /*
0004  * ACPI support for platform bus type.
0005  *
0006  * Copyright (C) 2015, Linaro Ltd
0007  * Author: Graeme Gregory <graeme.gregory@linaro.org>
0008  */
0009 
0010 #include <linux/acpi.h>
0011 #include <linux/amba/bus.h>
0012 #include <linux/clkdev.h>
0013 #include <linux/clk-provider.h>
0014 #include <linux/device.h>
0015 #include <linux/err.h>
0016 #include <linux/ioport.h>
0017 #include <linux/kernel.h>
0018 #include <linux/module.h>
0019 
0020 #include "internal.h"
0021 
0022 static const struct acpi_device_id amba_id_list[] = {
0023     {"ARMH0061", 0}, /* PL061 GPIO Device */
0024     {"ARMHC500", 0}, /* ARM CoreSight ETM4x */
0025     {"ARMHC501", 0}, /* ARM CoreSight ETR */
0026     {"ARMHC502", 0}, /* ARM CoreSight STM */
0027     {"ARMHC503", 0}, /* ARM CoreSight Debug */
0028     {"ARMHC979", 0}, /* ARM CoreSight TPIU */
0029     {"ARMHC97C", 0}, /* ARM CoreSight SoC-400 TMC, SoC-600 ETF/ETB */
0030     {"ARMHC98D", 0}, /* ARM CoreSight Dynamic Replicator */
0031     {"ARMHC9CA", 0}, /* ARM CoreSight CATU */
0032     {"ARMHC9FF", 0}, /* ARM CoreSight Dynamic Funnel */
0033     {"", 0},
0034 };
0035 
0036 static void amba_register_dummy_clk(void)
0037 {
0038     static struct clk *amba_dummy_clk;
0039 
0040     /* If clock already registered */
0041     if (amba_dummy_clk)
0042         return;
0043 
0044     amba_dummy_clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, 0, 0);
0045     clk_register_clkdev(amba_dummy_clk, "apb_pclk", NULL);
0046 }
0047 
0048 static int amba_handler_attach(struct acpi_device *adev,
0049                 const struct acpi_device_id *id)
0050 {
0051     struct amba_device *dev;
0052     struct resource_entry *rentry;
0053     struct list_head resource_list;
0054     bool address_found = false;
0055     int irq_no = 0;
0056     int ret;
0057 
0058     /* If the ACPI node already has a physical device attached, skip it. */
0059     if (adev->physical_node_count)
0060         return 0;
0061 
0062     dev = amba_device_alloc(dev_name(&adev->dev), 0, 0);
0063     if (!dev) {
0064         dev_err(&adev->dev, "%s(): amba_device_alloc() failed\n",
0065             __func__);
0066         return -ENOMEM;
0067     }
0068 
0069     INIT_LIST_HEAD(&resource_list);
0070     ret = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
0071     if (ret < 0)
0072         goto err_free;
0073 
0074     list_for_each_entry(rentry, &resource_list, node) {
0075         switch (resource_type(rentry->res)) {
0076         case IORESOURCE_MEM:
0077             if (!address_found) {
0078                 dev->res = *rentry->res;
0079                 dev->res.name = dev_name(&dev->dev);
0080                 address_found = true;
0081             }
0082             break;
0083         case IORESOURCE_IRQ:
0084             if (irq_no < AMBA_NR_IRQS)
0085                 dev->irq[irq_no++] = rentry->res->start;
0086             break;
0087         default:
0088             dev_warn(&adev->dev, "Invalid resource\n");
0089             break;
0090         }
0091     }
0092 
0093     acpi_dev_free_resource_list(&resource_list);
0094 
0095     /*
0096      * If the ACPI node has a parent and that parent has a physical device
0097      * attached to it, that physical device should be the parent of
0098      * the amba device we are about to create.
0099      */
0100     if (adev->parent)
0101         dev->dev.parent = acpi_get_first_physical_node(adev->parent);
0102 
0103     ACPI_COMPANION_SET(&dev->dev, adev);
0104 
0105     ret = amba_device_add(dev, &iomem_resource);
0106     if (ret) {
0107         dev_err(&adev->dev, "%s(): amba_device_add() failed (%d)\n",
0108                __func__, ret);
0109         goto err_free;
0110     }
0111 
0112     return 1;
0113 
0114 err_free:
0115     amba_device_put(dev);
0116     return ret;
0117 }
0118 
0119 static struct acpi_scan_handler amba_handler = {
0120     .ids = amba_id_list,
0121     .attach = amba_handler_attach,
0122 };
0123 
0124 void __init acpi_amba_init(void)
0125 {
0126     amba_register_dummy_clk();
0127     acpi_scan_add_handler(&amba_handler);
0128 }