2525#define FLAG_CFG1 BIT(1)
2626#define FLAG_DEV_FIX BIT(2)
2727
28+ struct loongson_pci_data {
29+ u32 flags ;
30+ struct pci_ops * ops ;
31+ };
32+
2833struct loongson_pci {
2934 void __iomem * cfg0_base ;
3035 void __iomem * cfg1_base ;
3136 struct platform_device * pdev ;
32- u32 flags ;
37+ const struct loongson_pci_data * data ;
3338};
3439
3540/* Fixup wrong class code in PCIe bridges */
@@ -126,8 +131,8 @@ static void __iomem *pci_loongson_map_bus(struct pci_bus *bus, unsigned int devf
126131 * Do not read more than one device on the bus other than
127132 * the host bus. For our hardware the root bus is always bus 0.
128133 */
129- if (priv -> flags & FLAG_DEV_FIX && busnum != 0 &&
130- PCI_SLOT (devfn ) > 0 )
134+ if (priv -> data -> flags & FLAG_DEV_FIX &&
135+ ! pci_is_root_bus ( bus ) && PCI_SLOT (devfn ) > 0 )
131136 return NULL ;
132137
133138 /* CFG0 can only access standard space */
@@ -159,20 +164,42 @@ static int loongson_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
159164 return val ;
160165}
161166
162- /* H/w only accept 32-bit PCI operations */
167+ /* LS2K/LS7A accept 8/16/ 32-bit PCI config operations */
163168static struct pci_ops loongson_pci_ops = {
169+ .map_bus = pci_loongson_map_bus ,
170+ .read = pci_generic_config_read ,
171+ .write = pci_generic_config_write ,
172+ };
173+
174+ /* RS780/SR5690 only accept 32-bit PCI config operations */
175+ static struct pci_ops loongson_pci_ops32 = {
164176 .map_bus = pci_loongson_map_bus ,
165177 .read = pci_generic_config_read32 ,
166178 .write = pci_generic_config_write32 ,
167179};
168180
181+ static const struct loongson_pci_data ls2k_pci_data = {
182+ .flags = FLAG_CFG1 | FLAG_DEV_FIX ,
183+ .ops = & loongson_pci_ops ,
184+ };
185+
186+ static const struct loongson_pci_data ls7a_pci_data = {
187+ .flags = FLAG_CFG1 | FLAG_DEV_FIX ,
188+ .ops = & loongson_pci_ops ,
189+ };
190+
191+ static const struct loongson_pci_data rs780e_pci_data = {
192+ .flags = FLAG_CFG0 ,
193+ .ops = & loongson_pci_ops32 ,
194+ };
195+
169196static const struct of_device_id loongson_pci_of_match [] = {
170197 { .compatible = "loongson,ls2k-pci" ,
171- .data = ( void * )( FLAG_CFG0 | FLAG_CFG1 | FLAG_DEV_FIX ) , },
198+ .data = & ls2k_pci_data , },
172199 { .compatible = "loongson,ls7a-pci" ,
173- .data = ( void * )( FLAG_CFG0 | FLAG_CFG1 | FLAG_DEV_FIX ) , },
200+ .data = & ls7a_pci_data , },
174201 { .compatible = "loongson,rs780e-pci" ,
175- .data = ( void * )( FLAG_CFG0 ) , },
202+ .data = & rs780e_pci_data , },
176203 {}
177204};
178205
@@ -193,20 +220,20 @@ static int loongson_pci_probe(struct platform_device *pdev)
193220
194221 priv = pci_host_bridge_priv (bridge );
195222 priv -> pdev = pdev ;
196- priv -> flags = ( unsigned long ) of_device_get_match_data (dev );
223+ priv -> data = of_device_get_match_data (dev );
197224
198- regs = platform_get_resource (pdev , IORESOURCE_MEM , 0 );
199- if (!regs ) {
200- dev_err (dev , "missing mem resources for cfg0\n" );
201- return - EINVAL ;
225+ if (priv -> data -> flags & FLAG_CFG0 ) {
226+ regs = platform_get_resource (pdev , IORESOURCE_MEM , 0 );
227+ if (!regs )
228+ dev_err (dev , "missing mem resources for cfg0\n" );
229+ else {
230+ priv -> cfg0_base = devm_pci_remap_cfg_resource (dev , regs );
231+ if (IS_ERR (priv -> cfg0_base ))
232+ return PTR_ERR (priv -> cfg0_base );
233+ }
202234 }
203235
204- priv -> cfg0_base = devm_pci_remap_cfg_resource (dev , regs );
205- if (IS_ERR (priv -> cfg0_base ))
206- return PTR_ERR (priv -> cfg0_base );
207-
208- /* CFG1 is optional */
209- if (priv -> flags & FLAG_CFG1 ) {
236+ if (priv -> data -> flags & FLAG_CFG1 ) {
210237 regs = platform_get_resource (pdev , IORESOURCE_MEM , 1 );
211238 if (!regs )
212239 dev_info (dev , "missing mem resource for cfg1\n" );
@@ -218,7 +245,7 @@ static int loongson_pci_probe(struct platform_device *pdev)
218245 }
219246
220247 bridge -> sysdata = priv ;
221- bridge -> ops = & loongson_pci_ops ;
248+ bridge -> ops = priv -> data -> ops ;
222249 bridge -> map_irq = loongson_map_irq ;
223250
224251 return pci_host_probe (bridge );
0 commit comments