4242#include <linux/of.h>
4343#include <linux/of_address.h>
4444#include <linux/of_device.h>
45+ #include <linux/of_iommu.h>
4546#include <linux/pci.h>
4647#include <linux/platform_device.h>
4748#include <linux/slab.h>
5152
5253#include "io-pgtable.h"
5354
54- /* Maximum number of stream IDs assigned to a single device */
55- #define MAX_MASTER_STREAMIDS 128
56-
5755/* Maximum number of context banks per SMMU */
5856#define ARM_SMMU_MAX_CBS 128
5957
@@ -321,13 +319,13 @@ struct arm_smmu_smr {
321319
322320struct arm_smmu_master_cfg {
323321 struct arm_smmu_device * smmu ;
324- int num_streamids ;
325- u16 streamids [MAX_MASTER_STREAMIDS ];
326- s16 smendx [MAX_MASTER_STREAMIDS ];
322+ s16 smendx [];
327323};
328324#define INVALID_SMENDX -1
329- #define for_each_cfg_sme (cfg , i , idx ) \
330- for (i = 0; idx = cfg->smendx[i], i < cfg->num_streamids; ++i)
325+ #define __fwspec_cfg (fw ) ((struct arm_smmu_master_cfg *)fw->iommu_priv)
326+ #define fwspec_smmu (fw ) (__fwspec_cfg(fw)->smmu)
327+ #define for_each_cfg_sme (fw , i , idx ) \
328+ for (i = 0; idx = __fwspec_cfg(fw)->smendx[i], i < fw->num_ids; ++i)
331329
332330struct arm_smmu_device {
333331 struct device * dev ;
@@ -480,14 +478,16 @@ static int __find_legacy_master_phandle(struct device *dev, void *data)
480478}
481479
482480static struct platform_driver arm_smmu_driver ;
481+ static struct iommu_ops arm_smmu_ops ;
483482
484- static int arm_smmu_register_legacy_master (struct device * dev )
483+ static int arm_smmu_register_legacy_master (struct device * dev ,
484+ struct arm_smmu_device * * smmu )
485485{
486- struct arm_smmu_device * smmu ;
487- struct arm_smmu_master_cfg * cfg ;
486+ struct device * smmu_dev ;
488487 struct device_node * np ;
489488 struct of_phandle_iterator it ;
490489 void * data = & it ;
490+ u32 * sids ;
491491 __be32 pci_sid ;
492492 int err ;
493493
@@ -500,20 +500,13 @@ static int arm_smmu_register_legacy_master(struct device *dev)
500500 it .node = np ;
501501 err = driver_for_each_device (& arm_smmu_driver .driver , NULL , & data ,
502502 __find_legacy_master_phandle );
503+ smmu_dev = data ;
503504 of_node_put (np );
504505 if (err == 0 )
505506 return - ENODEV ;
506507 if (err < 0 )
507508 return err ;
508509
509- smmu = dev_get_drvdata (data );
510-
511- if (it .cur_count > MAX_MASTER_STREAMIDS ) {
512- dev_err (smmu -> dev ,
513- "reached maximum number (%d) of stream IDs for master device %s\n" ,
514- MAX_MASTER_STREAMIDS , dev_name (dev ));
515- return - ENOSPC ;
516- }
517510 if (dev_is_pci (dev )) {
518511 /* "mmu-masters" assumes Stream ID == Requester ID */
519512 pci_for_each_dma_alias (to_pci_dev (dev ), __arm_smmu_get_pci_sid ,
@@ -522,17 +515,20 @@ static int arm_smmu_register_legacy_master(struct device *dev)
522515 it .cur_count = 1 ;
523516 }
524517
525- cfg = kzalloc (sizeof (* cfg ), GFP_KERNEL );
526- if (!cfg )
527- return - ENOMEM ;
528-
529- cfg -> smmu = smmu ;
530- dev -> archdata .iommu = cfg ;
518+ err = iommu_fwspec_init (dev , & smmu_dev -> of_node -> fwnode ,
519+ & arm_smmu_ops );
520+ if (err )
521+ return err ;
531522
532- while (it .cur_count -- )
533- cfg -> streamids [cfg -> num_streamids ++ ] = be32_to_cpup (it .cur ++ );
523+ sids = kcalloc (it .cur_count , sizeof (* sids ), GFP_KERNEL );
524+ if (!sids )
525+ return - ENOMEM ;
534526
535- return 0 ;
527+ * smmu = dev_get_drvdata (smmu_dev );
528+ of_phandle_iterator_args (& it , sids , it .cur_count );
529+ err = iommu_fwspec_add_ids (dev , sids , it .cur_count );
530+ kfree (sids );
531+ return err ;
536532}
537533
538534static int __arm_smmu_alloc_bitmap (unsigned long * map , int start , int end )
@@ -1127,27 +1123,28 @@ static bool arm_smmu_free_sme(struct arm_smmu_device *smmu, int idx)
11271123
11281124static int arm_smmu_master_alloc_smes (struct device * dev )
11291125{
1130- struct arm_smmu_master_cfg * cfg = dev -> archdata .iommu ;
1126+ struct iommu_fwspec * fwspec = dev -> iommu_fwspec ;
1127+ struct arm_smmu_master_cfg * cfg = fwspec -> iommu_priv ;
11311128 struct arm_smmu_device * smmu = cfg -> smmu ;
11321129 struct arm_smmu_smr * smrs = smmu -> smrs ;
11331130 struct iommu_group * group ;
11341131 int i , idx , ret ;
11351132
11361133 mutex_lock (& smmu -> stream_map_mutex );
11371134 /* Figure out a viable stream map entry allocation */
1138- for_each_cfg_sme (cfg , i , idx ) {
1135+ for_each_cfg_sme (fwspec , i , idx ) {
11391136 if (idx != INVALID_SMENDX ) {
11401137 ret = - EEXIST ;
11411138 goto out_err ;
11421139 }
11431140
1144- ret = arm_smmu_find_sme (smmu , cfg -> streamids [i ], 0 );
1141+ ret = arm_smmu_find_sme (smmu , fwspec -> ids [i ], 0 );
11451142 if (ret < 0 )
11461143 goto out_err ;
11471144
11481145 idx = ret ;
11491146 if (smrs && smmu -> s2crs [idx ].count == 0 ) {
1150- smrs [idx ].id = cfg -> streamids [i ];
1147+ smrs [idx ].id = fwspec -> ids [i ];
11511148 smrs [idx ].mask = 0 ; /* We don't currently share SMRs */
11521149 smrs [idx ].valid = true;
11531150 }
@@ -1165,7 +1162,7 @@ static int arm_smmu_master_alloc_smes(struct device *dev)
11651162 iommu_group_put (group );
11661163
11671164 /* It worked! Now, poke the actual hardware */
1168- for_each_cfg_sme (cfg , i , idx ) {
1165+ for_each_cfg_sme (fwspec , i , idx ) {
11691166 arm_smmu_write_sme (smmu , idx );
11701167 smmu -> s2crs [idx ].group = group ;
11711168 }
@@ -1182,13 +1179,14 @@ static int arm_smmu_master_alloc_smes(struct device *dev)
11821179 return ret ;
11831180}
11841181
1185- static void arm_smmu_master_free_smes (struct arm_smmu_master_cfg * cfg )
1182+ static void arm_smmu_master_free_smes (struct iommu_fwspec * fwspec )
11861183{
1187- struct arm_smmu_device * smmu = cfg -> smmu ;
1184+ struct arm_smmu_device * smmu = fwspec_smmu (fwspec );
1185+ struct arm_smmu_master_cfg * cfg = fwspec -> iommu_priv ;
11881186 int i , idx ;
11891187
11901188 mutex_lock (& smmu -> stream_map_mutex );
1191- for_each_cfg_sme (cfg , i , idx ) {
1189+ for_each_cfg_sme (fwspec , i , idx ) {
11921190 if (arm_smmu_free_sme (smmu , idx ))
11931191 arm_smmu_write_sme (smmu , idx );
11941192 cfg -> smendx [i ] = INVALID_SMENDX ;
@@ -1197,7 +1195,7 @@ static void arm_smmu_master_free_smes(struct arm_smmu_master_cfg *cfg)
11971195}
11981196
11991197static int arm_smmu_domain_add_master (struct arm_smmu_domain * smmu_domain ,
1200- struct arm_smmu_master_cfg * cfg )
1198+ struct iommu_fwspec * fwspec )
12011199{
12021200 struct arm_smmu_device * smmu = smmu_domain -> smmu ;
12031201 struct arm_smmu_s2cr * s2cr = smmu -> s2crs ;
@@ -1214,7 +1212,7 @@ static int arm_smmu_domain_add_master(struct arm_smmu_domain *smmu_domain,
12141212 if (smmu_domain -> domain .type == IOMMU_DOMAIN_DMA )
12151213 type = S2CR_TYPE_BYPASS ;
12161214
1217- for_each_cfg_sme (cfg , i , idx ) {
1215+ for_each_cfg_sme (fwspec , i , idx ) {
12181216 if (type == s2cr [idx ].type && cbndx == s2cr [idx ].cbndx )
12191217 continue ;
12201218
@@ -1229,32 +1227,34 @@ static int arm_smmu_domain_add_master(struct arm_smmu_domain *smmu_domain,
12291227static int arm_smmu_attach_dev (struct iommu_domain * domain , struct device * dev )
12301228{
12311229 int ret ;
1230+ struct iommu_fwspec * fwspec = dev -> iommu_fwspec ;
1231+ struct arm_smmu_device * smmu ;
12321232 struct arm_smmu_domain * smmu_domain = to_smmu_domain (domain );
1233- struct arm_smmu_master_cfg * cfg = dev -> archdata .iommu ;
12341233
1235- if (!cfg ) {
1234+ if (!fwspec || fwspec -> ops != & arm_smmu_ops ) {
12361235 dev_err (dev , "cannot attach to SMMU, is it on the same bus?\n" );
12371236 return - ENXIO ;
12381237 }
12391238
1239+ smmu = fwspec_smmu (fwspec );
12401240 /* Ensure that the domain is finalised */
1241- ret = arm_smmu_init_domain_context (domain , cfg -> smmu );
1241+ ret = arm_smmu_init_domain_context (domain , smmu );
12421242 if (ret < 0 )
12431243 return ret ;
12441244
12451245 /*
12461246 * Sanity check the domain. We don't support domains across
12471247 * different SMMUs.
12481248 */
1249- if (smmu_domain -> smmu != cfg -> smmu ) {
1249+ if (smmu_domain -> smmu != smmu ) {
12501250 dev_err (dev ,
12511251 "cannot attach to SMMU %s whilst already attached to domain on SMMU %s\n" ,
1252- dev_name (smmu_domain -> smmu -> dev ), dev_name (cfg -> smmu -> dev ));
1252+ dev_name (smmu_domain -> smmu -> dev ), dev_name (smmu -> dev ));
12531253 return - EINVAL ;
12541254 }
12551255
12561256 /* Looks ok, so add the device to the domain */
1257- return arm_smmu_domain_add_master (smmu_domain , cfg );
1257+ return arm_smmu_domain_add_master (smmu_domain , fwspec );
12581258}
12591259
12601260static int arm_smmu_map (struct iommu_domain * domain , unsigned long iova ,
@@ -1375,57 +1375,72 @@ static bool arm_smmu_capable(enum iommu_cap cap)
13751375
13761376static int arm_smmu_add_device (struct device * dev )
13771377{
1378+ struct arm_smmu_device * smmu ;
13781379 struct arm_smmu_master_cfg * cfg ;
1380+ struct iommu_fwspec * fwspec ;
13791381 int i , ret ;
13801382
1381- ret = arm_smmu_register_legacy_master (dev );
1382- cfg = dev -> archdata . iommu ;
1383+ ret = arm_smmu_register_legacy_master (dev , & smmu );
1384+ fwspec = dev -> iommu_fwspec ;
13831385 if (ret )
13841386 goto out_free ;
13851387
13861388 ret = - EINVAL ;
1387- for (i = 0 ; i < cfg -> num_streamids ; i ++ ) {
1388- u16 sid = cfg -> streamids [i ];
1389+ for (i = 0 ; i < fwspec -> num_ids ; i ++ ) {
1390+ u16 sid = fwspec -> ids [i ];
13891391
1390- if (sid & ~cfg -> smmu -> streamid_mask ) {
1392+ if (sid & ~smmu -> streamid_mask ) {
13911393 dev_err (dev , "stream ID 0x%x out of range for SMMU (0x%x)\n" ,
13921394 sid , cfg -> smmu -> streamid_mask );
13931395 goto out_free ;
13941396 }
1395- cfg -> smendx [i ] = INVALID_SMENDX ;
13961397 }
13971398
1399+ ret = - ENOMEM ;
1400+ cfg = kzalloc (offsetof(struct arm_smmu_master_cfg , smendx [i ]),
1401+ GFP_KERNEL );
1402+ if (!cfg )
1403+ goto out_free ;
1404+
1405+ cfg -> smmu = smmu ;
1406+ fwspec -> iommu_priv = cfg ;
1407+ while (i -- )
1408+ cfg -> smendx [i ] = INVALID_SMENDX ;
1409+
13981410 ret = arm_smmu_master_alloc_smes (dev );
1399- if (!ret )
1400- return ret ;
1411+ if (ret )
1412+ goto out_free ;
1413+
1414+ return 0 ;
14011415
14021416out_free :
1403- kfree (cfg );
1404- dev -> archdata .iommu = NULL ;
1417+ if (fwspec )
1418+ kfree (fwspec -> iommu_priv );
1419+ iommu_fwspec_free (dev );
14051420 return ret ;
14061421}
14071422
14081423static void arm_smmu_remove_device (struct device * dev )
14091424{
1410- struct arm_smmu_master_cfg * cfg = dev -> archdata . iommu ;
1425+ struct iommu_fwspec * fwspec = dev -> iommu_fwspec ;
14111426
1412- if (!cfg )
1427+ if (!fwspec || fwspec -> ops != & arm_smmu_ops )
14131428 return ;
14141429
1415- arm_smmu_master_free_smes (cfg );
1430+ arm_smmu_master_free_smes (fwspec );
14161431 iommu_group_remove_device (dev );
1417- kfree (cfg );
1418- dev -> archdata . iommu = NULL ;
1432+ kfree (fwspec -> iommu_priv );
1433+ iommu_fwspec_free ( dev ) ;
14191434}
14201435
14211436static struct iommu_group * arm_smmu_device_group (struct device * dev )
14221437{
1423- struct arm_smmu_master_cfg * cfg = dev -> archdata . iommu ;
1424- struct arm_smmu_device * smmu = cfg -> smmu ;
1438+ struct iommu_fwspec * fwspec = dev -> iommu_fwspec ;
1439+ struct arm_smmu_device * smmu = fwspec_smmu ( fwspec ) ;
14251440 struct iommu_group * group = NULL ;
14261441 int i , idx ;
14271442
1428- for_each_cfg_sme (cfg , i , idx ) {
1443+ for_each_cfg_sme (fwspec , i , idx ) {
14291444 if (group && smmu -> s2crs [idx ].group &&
14301445 group != smmu -> s2crs [idx ].group )
14311446 return ERR_PTR (- EINVAL );
@@ -1936,6 +1951,7 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
19361951 }
19371952 }
19381953
1954+ of_iommu_set_ops (dev -> of_node , & arm_smmu_ops );
19391955 platform_set_drvdata (pdev , smmu );
19401956 arm_smmu_device_reset (smmu );
19411957 return 0 ;
0 commit comments