1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License.  See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2000, 2001 Keith M Wesolowski
7 */
8#include <linux/kernel.h>
9#include <linux/init.h>
10#include <linux/pci.h>
11#include <linux/types.h>
12#include <asm/pci.h>
13#include <asm/ip32/mace.h>
14
15# define DPRINTK(args...)
16
17/*
18 * O2 has up to 5 PCI devices connected into the MACE bridge.  The device
19 * map looks like this:
20 *
21 * 0  aic7xxx 0
22 * 1  aic7xxx 1
23 * 2  expansion slot
24 * 3  N/C
25 * 4  N/C
26 */
27
28#define chkslot(_bus,_devfn)					\
29do {							        \
30	if ((_bus)->number > 0 || PCI_SLOT (_devfn) < 1	\
31	    || PCI_SLOT (_devfn) > 3)			        \
32		return PCIBIOS_DEVICE_NOT_FOUND;		\
33} while (0)
34
35#define mkaddr(_devfn, _reg) \
36((((_devfn) & 0xffUL) << 8) | ((_reg) & 0xfcUL))
37
38static int
39mace_pci_read_config(struct pci_bus *bus, unsigned int devfn,
40		     int reg, int size, u32 *val)
41{
42	chkslot(bus, devfn);
43	mace->pci.config_addr = mkaddr(devfn, reg);
44	switch (size) {
45	case 1:
46		*val = mace->pci.config_data.b[(reg & 3) ^ 3];
47		break;
48	case 2:
49		*val = mace->pci.config_data.w[((reg >> 1) & 1) ^ 1];
50		break;
51	case 4:
52		*val = mace->pci.config_data.l;
53		break;
54	}
55
56	DPRINTK("read%d: reg=%08x,val=%02x\n", size * 8, reg, *val);
57
58	return PCIBIOS_SUCCESSFUL;
59}
60
61static int
62mace_pci_write_config(struct pci_bus *bus, unsigned int devfn,
63		      int reg, int size, u32 val)
64{
65	chkslot(bus, devfn);
66	mace->pci.config_addr = mkaddr(devfn, reg);
67	switch (size) {
68	case 1:
69		mace->pci.config_data.b[(reg & 3) ^ 3] = val;
70		break;
71	case 2:
72		mace->pci.config_data.w[((reg >> 1) & 1) ^ 1] = val;
73		break;
74	case 4:
75		mace->pci.config_data.l = val;
76		break;
77	}
78
79	DPRINTK("write%d: reg=%08x,val=%02x\n", size * 8, reg, val);
80
81	return PCIBIOS_SUCCESSFUL;
82}
83
84struct pci_ops mace_pci_ops = {
85	.read = mace_pci_read_config,
86	.write = mace_pci_write_config,
87};
88