0001
0002
0003
0004
0005
0006
0007
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},
0024 {"ARMHC500", 0},
0025 {"ARMHC501", 0},
0026 {"ARMHC502", 0},
0027 {"ARMHC503", 0},
0028 {"ARMHC979", 0},
0029 {"ARMHC97C", 0},
0030 {"ARMHC98D", 0},
0031 {"ARMHC9CA", 0},
0032 {"ARMHC9FF", 0},
0033 {"", 0},
0034 };
0035
0036 static void amba_register_dummy_clk(void)
0037 {
0038 static struct clk *amba_dummy_clk;
0039
0040
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
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
0097
0098
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 }