8
8
*
9
9
*/
10
10
11
+ #include <linux/cleanup.h>
11
12
#include <linux/pci.h>
12
13
#include <linux/io-64-nonatomic-lo-hi.h>
13
14
21
22
#define SSRAM_IOE_OFFSET 0x68
22
23
#define SSRAM_DEVID_OFFSET 0x70
23
24
25
+ DEFINE_FREE (pmc_core_iounmap , void __iomem * , iounmap (_T ));
26
+
24
27
static const struct pmc_reg_map * pmc_core_find_regmap (struct pmc_info * list , u16 devid )
25
28
{
26
29
for (; list -> map ; ++ list )
@@ -65,44 +68,49 @@ pmc_core_pmc_add(struct pmc_dev *pmcdev, u64 pwrm_base,
65
68
return 0 ;
66
69
}
67
70
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 )
71
73
{
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 ;
73
79
u16 devid ;
74
80
75
- if (pmc_idx != PMC_IDX_SOC ) {
76
- u64 ssram_base = get_base ( ssram , offset ) ;
81
+ if (! pmcdev -> regmap_list )
82
+ return - ENOENT ;
77
83
78
- if (! ssram_base )
79
- return ;
84
+ ssram_base = ssram_pcidev -> resource [ 0 ]. start ;
85
+ tmp_ssram = ioremap ( ssram_base , SSRAM_HDR_SIZE ) ;
80
86
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 );
81
93
ssram = ioremap (ssram_base , SSRAM_HDR_SIZE );
82
94
if (!ssram )
83
- return ;
95
+ return - ENOMEM ;
96
+
97
+ } else {
98
+ ssram = no_free_ptr (tmp_ssram );
84
99
}
85
100
86
101
pwrm_base = get_base (ssram , SSRAM_PWRM_OFFSET );
87
102
devid = readw (ssram + SSRAM_DEVID_OFFSET );
88
103
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 ;
96
107
97
- if (pmc_idx != PMC_IDX_SOC )
98
- iounmap (ssram );
108
+ return pmc_core_pmc_add (pmcdev , pwrm_base , map , PMC_IDX_MAIN );
99
109
}
100
110
101
111
int pmc_core_ssram_init (struct pmc_dev * pmcdev )
102
112
{
103
- void __iomem * ssram ;
104
113
struct pci_dev * pcidev ;
105
- u64 ssram_base ;
106
114
int ret ;
107
115
108
116
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)
113
121
if (ret )
114
122
goto release_dev ;
115
123
116
- ssram_base = pcidev -> resource [0 ].start ;
117
- ssram = ioremap (ssram_base , SSRAM_HDR_SIZE );
118
- if (!ssram )
119
- goto disable_dev ;
120
-
121
124
pmcdev -> ssram_pcidev = pcidev ;
122
125
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 ;
126
129
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 );
128
132
129
133
return 0 ;
130
134
0 commit comments