88 *
99 */
1010
11+ #include <linux/cleanup.h>
1112#include <linux/pci.h>
1213#include <linux/io-64-nonatomic-lo-hi.h>
1314
2122#define SSRAM_IOE_OFFSET 0x68
2223#define SSRAM_DEVID_OFFSET 0x70
2324
25+ DEFINE_FREE (pmc_core_iounmap , void __iomem * , iounmap (_T ));
26+
2427static const struct pmc_reg_map * pmc_core_find_regmap (struct pmc_info * list , u16 devid )
2528{
2629 for (; list -> map ; ++ list )
@@ -65,44 +68,49 @@ pmc_core_pmc_add(struct pmc_dev *pmcdev, u64 pwrm_base,
6568 return 0 ;
6669}
6770
68- static void
69- pmc_core_ssram_get_pmc (struct pmc_dev * pmcdev , void __iomem * ssram , u32 offset ,
70- int pmc_idx )
71+ static int
72+ pmc_core_ssram_get_pmc (struct pmc_dev * pmcdev , int pmc_idx , u32 offset )
7173{
72- u64 pwrm_base ;
74+ struct pci_dev * ssram_pcidev = pmcdev -> ssram_pcidev ;
75+ void __iomem __free (pmc_core_iounmap ) * tmp_ssram = NULL ;
76+ void __iomem __free (pmc_core_iounmap ) * ssram = NULL ;
77+ const struct pmc_reg_map * map ;
78+ u64 ssram_base , pwrm_base ;
7379 u16 devid ;
7480
75- if (pmc_idx != PMC_IDX_SOC ) {
76- u64 ssram_base = get_base ( ssram , offset ) ;
81+ if (! pmcdev -> regmap_list )
82+ return - ENOENT ;
7783
78- if (! ssram_base )
79- return ;
84+ ssram_base = ssram_pcidev -> resource [ 0 ]. start ;
85+ tmp_ssram = ioremap ( ssram_base , SSRAM_HDR_SIZE ) ;
8086
87+ if (pmc_idx != PMC_IDX_MAIN ) {
88+ /*
89+ * The secondary PMC BARS (which are behind hidden PCI devices)
90+ * are read from fixed offsets in MMIO of the primary PMC BAR.
91+ */
92+ ssram_base = get_base (tmp_ssram , offset );
8193 ssram = ioremap (ssram_base , SSRAM_HDR_SIZE );
8294 if (!ssram )
83- return ;
95+ return - ENOMEM ;
96+
97+ } else {
98+ ssram = no_free_ptr (tmp_ssram );
8499 }
85100
86101 pwrm_base = get_base (ssram , SSRAM_PWRM_OFFSET );
87102 devid = readw (ssram + SSRAM_DEVID_OFFSET );
88103
89- if (pmcdev -> regmap_list ) {
90- const struct pmc_reg_map * map ;
91-
92- map = pmc_core_find_regmap (pmcdev -> regmap_list , devid );
93- if (map )
94- pmc_core_pmc_add (pmcdev , pwrm_base , map , pmc_idx );
95- }
104+ map = pmc_core_find_regmap (pmcdev -> regmap_list , devid );
105+ if (!map )
106+ return - ENODEV ;
96107
97- if (pmc_idx != PMC_IDX_SOC )
98- iounmap (ssram );
108+ return pmc_core_pmc_add (pmcdev , pwrm_base , map , PMC_IDX_MAIN );
99109}
100110
101111int pmc_core_ssram_init (struct pmc_dev * pmcdev )
102112{
103- void __iomem * ssram ;
104113 struct pci_dev * pcidev ;
105- u64 ssram_base ;
106114 int ret ;
107115
108116 pcidev = pci_get_domain_bus_and_slot (0 , 0 , PCI_DEVFN (20 , 2 ));
@@ -113,18 +121,14 @@ int pmc_core_ssram_init(struct pmc_dev *pmcdev)
113121 if (ret )
114122 goto release_dev ;
115123
116- ssram_base = pcidev -> resource [0 ].start ;
117- ssram = ioremap (ssram_base , SSRAM_HDR_SIZE );
118- if (!ssram )
119- goto disable_dev ;
120-
121124 pmcdev -> ssram_pcidev = pcidev ;
122125
123- pmc_core_ssram_get_pmc (pmcdev , ssram , 0 , PMC_IDX_SOC );
124- pmc_core_ssram_get_pmc ( pmcdev , ssram , SSRAM_IOE_OFFSET , PMC_IDX_IOE );
125- pmc_core_ssram_get_pmc ( pmcdev , ssram , SSRAM_PCH_OFFSET , PMC_IDX_PCH ) ;
126+ ret = pmc_core_ssram_get_pmc (pmcdev , PMC_IDX_MAIN , 0 );
127+ if ( ret )
128+ goto disable_dev ;
126129
127- iounmap (ssram );
130+ pmc_core_ssram_get_pmc (pmcdev , PMC_IDX_IOE , SSRAM_IOE_OFFSET );
131+ pmc_core_ssram_get_pmc (pmcdev , PMC_IDX_PCH , SSRAM_PCH_OFFSET );
128132
129133 return 0 ;
130134
0 commit comments