diff options
author | Robin Murphy <robin.murphy@arm.com> | 2016-09-12 12:13:52 -0400 |
---|---|---|
committer | Will Deacon <will.deacon@arm.com> | 2016-09-16 04:34:19 -0400 |
commit | d6fc5d977671d16535de66645f83a1bd07e1317d (patch) | |
tree | 608fa34ecbda7ecac83972491c621b295e835896 /drivers/iommu/arm-smmu.c | |
parent | f80cd885fcdd05dff769d62a116313927a03d480 (diff) |
iommu/arm-smmu: Streamline SMMU data lookups
Simplify things somewhat by stashing our arm_smmu_device instance in
drvdata, so that it's readily available to our driver model callbacks.
Then we can excise the private list entirely, since the driver core
already has a perfectly good list of SMMU devices we can use in the one
instance we actually need to. Finally, make a further modest code saving
with the relatively new of_device_get_match_data() helper.
Tested-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'drivers/iommu/arm-smmu.c')
-rw-r--r-- | drivers/iommu/arm-smmu.c | 44 |
1 files changed, 11 insertions, 33 deletions
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 2023a77015a0..b6e26dba2dec 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/module.h> | 41 | #include <linux/module.h> |
42 | #include <linux/of.h> | 42 | #include <linux/of.h> |
43 | #include <linux/of_address.h> | 43 | #include <linux/of_address.h> |
44 | #include <linux/of_device.h> | ||
44 | #include <linux/pci.h> | 45 | #include <linux/pci.h> |
45 | #include <linux/platform_device.h> | 46 | #include <linux/platform_device.h> |
46 | #include <linux/slab.h> | 47 | #include <linux/slab.h> |
@@ -370,8 +371,6 @@ struct arm_smmu_device { | |||
370 | u32 num_context_irqs; | 371 | u32 num_context_irqs; |
371 | unsigned int *irqs; | 372 | unsigned int *irqs; |
372 | 373 | ||
373 | struct list_head list; | ||
374 | |||
375 | u32 cavium_id_base; /* Specific to Cavium */ | 374 | u32 cavium_id_base; /* Specific to Cavium */ |
376 | }; | 375 | }; |
377 | 376 | ||
@@ -409,9 +408,6 @@ struct arm_smmu_domain { | |||
409 | struct iommu_domain domain; | 408 | struct iommu_domain domain; |
410 | }; | 409 | }; |
411 | 410 | ||
412 | static DEFINE_SPINLOCK(arm_smmu_devices_lock); | ||
413 | static LIST_HEAD(arm_smmu_devices); | ||
414 | |||
415 | struct arm_smmu_option_prop { | 411 | struct arm_smmu_option_prop { |
416 | u32 opt; | 412 | u32 opt; |
417 | const char *prop; | 413 | const char *prop; |
@@ -478,6 +474,8 @@ static int __find_legacy_master_phandle(struct device *dev, void *data) | |||
478 | return err == -ENOENT ? 0 : err; | 474 | return err == -ENOENT ? 0 : err; |
479 | } | 475 | } |
480 | 476 | ||
477 | static struct platform_driver arm_smmu_driver; | ||
478 | |||
481 | static int arm_smmu_register_legacy_master(struct device *dev) | 479 | static int arm_smmu_register_legacy_master(struct device *dev) |
482 | { | 480 | { |
483 | struct arm_smmu_device *smmu; | 481 | struct arm_smmu_device *smmu; |
@@ -495,19 +493,16 @@ static int arm_smmu_register_legacy_master(struct device *dev) | |||
495 | } | 493 | } |
496 | 494 | ||
497 | it.node = np; | 495 | it.node = np; |
498 | spin_lock(&arm_smmu_devices_lock); | 496 | err = driver_for_each_device(&arm_smmu_driver.driver, NULL, &data, |
499 | list_for_each_entry(smmu, &arm_smmu_devices, list) { | 497 | __find_legacy_master_phandle); |
500 | err = __find_legacy_master_phandle(smmu->dev, &data); | ||
501 | if (err) | ||
502 | break; | ||
503 | } | ||
504 | spin_unlock(&arm_smmu_devices_lock); | ||
505 | of_node_put(np); | 498 | of_node_put(np); |
506 | if (err == 0) | 499 | if (err == 0) |
507 | return -ENODEV; | 500 | return -ENODEV; |
508 | if (err < 0) | 501 | if (err < 0) |
509 | return err; | 502 | return err; |
510 | 503 | ||
504 | smmu = dev_get_drvdata(data); | ||
505 | |||
511 | if (it.cur_count > MAX_MASTER_STREAMIDS) { | 506 | if (it.cur_count > MAX_MASTER_STREAMIDS) { |
512 | dev_err(smmu->dev, | 507 | dev_err(smmu->dev, |
513 | "reached maximum number (%d) of stream IDs for master device %s\n", | 508 | "reached maximum number (%d) of stream IDs for master device %s\n", |
@@ -1816,7 +1811,6 @@ MODULE_DEVICE_TABLE(of, arm_smmu_of_match); | |||
1816 | 1811 | ||
1817 | static int arm_smmu_device_dt_probe(struct platform_device *pdev) | 1812 | static int arm_smmu_device_dt_probe(struct platform_device *pdev) |
1818 | { | 1813 | { |
1819 | const struct of_device_id *of_id; | ||
1820 | const struct arm_smmu_match_data *data; | 1814 | const struct arm_smmu_match_data *data; |
1821 | struct resource *res; | 1815 | struct resource *res; |
1822 | struct arm_smmu_device *smmu; | 1816 | struct arm_smmu_device *smmu; |
@@ -1830,8 +1824,7 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev) | |||
1830 | } | 1824 | } |
1831 | smmu->dev = dev; | 1825 | smmu->dev = dev; |
1832 | 1826 | ||
1833 | of_id = of_match_node(arm_smmu_of_match, dev->of_node); | 1827 | data = of_device_get_match_data(dev); |
1834 | data = of_id->data; | ||
1835 | smmu->version = data->version; | 1828 | smmu->version = data->version; |
1836 | smmu->model = data->model; | 1829 | smmu->model = data->model; |
1837 | 1830 | ||
@@ -1904,35 +1897,20 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev) | |||
1904 | } | 1897 | } |
1905 | } | 1898 | } |
1906 | 1899 | ||
1907 | INIT_LIST_HEAD(&smmu->list); | 1900 | platform_set_drvdata(pdev, smmu); |
1908 | spin_lock(&arm_smmu_devices_lock); | ||
1909 | list_add(&smmu->list, &arm_smmu_devices); | ||
1910 | spin_unlock(&arm_smmu_devices_lock); | ||
1911 | |||
1912 | arm_smmu_device_reset(smmu); | 1901 | arm_smmu_device_reset(smmu); |
1913 | return 0; | 1902 | return 0; |
1914 | } | 1903 | } |
1915 | 1904 | ||
1916 | static int arm_smmu_device_remove(struct platform_device *pdev) | 1905 | static int arm_smmu_device_remove(struct platform_device *pdev) |
1917 | { | 1906 | { |
1918 | struct device *dev = &pdev->dev; | 1907 | struct arm_smmu_device *smmu = platform_get_drvdata(pdev); |
1919 | struct arm_smmu_device *curr, *smmu = NULL; | ||
1920 | |||
1921 | spin_lock(&arm_smmu_devices_lock); | ||
1922 | list_for_each_entry(curr, &arm_smmu_devices, list) { | ||
1923 | if (curr->dev == dev) { | ||
1924 | smmu = curr; | ||
1925 | list_del(&smmu->list); | ||
1926 | break; | ||
1927 | } | ||
1928 | } | ||
1929 | spin_unlock(&arm_smmu_devices_lock); | ||
1930 | 1908 | ||
1931 | if (!smmu) | 1909 | if (!smmu) |
1932 | return -ENODEV; | 1910 | return -ENODEV; |
1933 | 1911 | ||
1934 | if (!bitmap_empty(smmu->context_map, ARM_SMMU_MAX_CBS)) | 1912 | if (!bitmap_empty(smmu->context_map, ARM_SMMU_MAX_CBS)) |
1935 | dev_err(dev, "removing device with active domains!\n"); | 1913 | dev_err(&pdev->dev, "removing device with active domains!\n"); |
1936 | 1914 | ||
1937 | /* Turn the thing off */ | 1915 | /* Turn the thing off */ |
1938 | writel(sCR0_CLIENTPD, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0); | 1916 | writel(sCR0_CLIENTPD, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0); |