aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu/arm-smmu.c
diff options
context:
space:
mode:
authorRobin Murphy <robin.murphy@arm.com>2016-09-12 12:13:52 -0400
committerWill Deacon <will.deacon@arm.com>2016-09-16 04:34:19 -0400
commitd6fc5d977671d16535de66645f83a1bd07e1317d (patch)
tree608fa34ecbda7ecac83972491c621b295e835896 /drivers/iommu/arm-smmu.c
parentf80cd885fcdd05dff769d62a116313927a03d480 (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.c44
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
412static DEFINE_SPINLOCK(arm_smmu_devices_lock);
413static LIST_HEAD(arm_smmu_devices);
414
415struct arm_smmu_option_prop { 411struct 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
477static struct platform_driver arm_smmu_driver;
478
481static int arm_smmu_register_legacy_master(struct device *dev) 479static 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
1817static int arm_smmu_device_dt_probe(struct platform_device *pdev) 1812static 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
1916static int arm_smmu_device_remove(struct platform_device *pdev) 1905static 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);