1873e65bcSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2cf4ece53SMasayuki Ohtak /*
37f2732c8STomoya MORINAGA * Copyright (C) 2011 LAPIS Semiconductor Co., Ltd.
4cf4ece53SMasayuki Ohtak */
5cf4ece53SMasayuki Ohtak
6cf4ece53SMasayuki Ohtak #include <linux/module.h>
7cf4ece53SMasayuki Ohtak #include <linux/kernel.h>
8cf4ece53SMasayuki Ohtak #include <linux/types.h>
9cf4ece53SMasayuki Ohtak #include <linux/fs.h>
10cf4ece53SMasayuki Ohtak #include <linux/uaccess.h>
11cf4ece53SMasayuki Ohtak #include <linux/string.h>
12cf4ece53SMasayuki Ohtak #include <linux/pci.h>
13cf4ece53SMasayuki Ohtak #include <linux/io.h>
14cf4ece53SMasayuki Ohtak #include <linux/delay.h>
15cf4ece53SMasayuki Ohtak #include <linux/mutex.h>
16cf4ece53SMasayuki Ohtak #include <linux/if_ether.h>
17cf4ece53SMasayuki Ohtak #include <linux/ctype.h>
186ae705b2SDenis Turischev #include <linux/dmi.h>
19549ce8f1SZubair Lutfullah Kakakhel #include <linux/of.h>
20cf4ece53SMasayuki Ohtak
21cf4ece53SMasayuki Ohtak #define PHUB_STATUS 0x00 /* Status Register offset */
22cf4ece53SMasayuki Ohtak #define PHUB_CONTROL 0x04 /* Control Register offset */
23cf4ece53SMasayuki Ohtak #define PHUB_TIMEOUT 0x05 /* Time out value for Status Register */
24cf4ece53SMasayuki Ohtak #define PCH_PHUB_ROM_WRITE_ENABLE 0x01 /* Enabling for writing ROM */
25cf4ece53SMasayuki Ohtak #define PCH_PHUB_ROM_WRITE_DISABLE 0x00 /* Disabling for writing ROM */
26275640b0STomoya MORINAGA #define PCH_PHUB_MAC_START_ADDR_EG20T 0x14 /* MAC data area start address
27275640b0STomoya MORINAGA offset */
28275640b0STomoya MORINAGA #define PCH_PHUB_MAC_START_ADDR_ML7223 0x20C /* MAC data area start address
29275640b0STomoya MORINAGA offset */
30275640b0STomoya MORINAGA #define PCH_PHUB_ROM_START_ADDR_EG20T 0x80 /* ROM data area start address offset
31c47dda7dSTomoya MORINAGA (Intel EG20T PCH)*/
32c47dda7dSTomoya MORINAGA #define PCH_PHUB_ROM_START_ADDR_ML7213 0x400 /* ROM data area start address
337f2732c8STomoya MORINAGA offset(LAPIS Semicon ML7213)
34c47dda7dSTomoya MORINAGA */
35275640b0STomoya MORINAGA #define PCH_PHUB_ROM_START_ADDR_ML7223 0x400 /* ROM data area start address
367f2732c8STomoya MORINAGA offset(LAPIS Semicon ML7223)
37275640b0STomoya MORINAGA */
38cf4ece53SMasayuki Ohtak
39cf4ece53SMasayuki Ohtak /* MAX number of INT_REDUCE_CONTROL registers */
40cf4ece53SMasayuki Ohtak #define MAX_NUM_INT_REDUCE_CONTROL_REG 128
41cf4ece53SMasayuki Ohtak #define PCI_DEVICE_ID_PCH1_PHUB 0x8801
42cf4ece53SMasayuki Ohtak #define PCH_MINOR_NOS 1
43cf4ece53SMasayuki Ohtak #define CLKCFG_CAN_50MHZ 0x12000000
44cf4ece53SMasayuki Ohtak #define CLKCFG_CANCLK_MASK 0xFF000000
456ae705b2SDenis Turischev #define CLKCFG_UART_MASK 0xFFFFFF
466ae705b2SDenis Turischev
476ae705b2SDenis Turischev /* CM-iTC */
486ae705b2SDenis Turischev #define CLKCFG_UART_48MHZ (1 << 16)
49bed3d7baSZubair Lutfullah Kakakhel #define CLKCFG_UART_25MHZ (2 << 16)
506ae705b2SDenis Turischev #define CLKCFG_BAUDDIV (2 << 20)
516ae705b2SDenis Turischev #define CLKCFG_PLL2VCO (8 << 9)
526ae705b2SDenis Turischev #define CLKCFG_UARTCLKSEL (1 << 18)
53cf4ece53SMasayuki Ohtak
541a738dcfSTomoya MORINAGA /* Macros for ML7213 */
551a738dcfSTomoya MORINAGA #define PCI_DEVICE_ID_ROHM_ML7213_PHUB 0x801A
56cf4ece53SMasayuki Ohtak
57275640b0STomoya MORINAGA /* Macros for ML7223 */
58275640b0STomoya MORINAGA #define PCI_DEVICE_ID_ROHM_ML7223_mPHUB 0x8012 /* for Bus-m */
59275640b0STomoya MORINAGA #define PCI_DEVICE_ID_ROHM_ML7223_nPHUB 0x8002 /* for Bus-n */
60275640b0STomoya MORINAGA
61584ad00cSTomoya MORINAGA /* Macros for ML7831 */
62584ad00cSTomoya MORINAGA #define PCI_DEVICE_ID_ROHM_ML7831_PHUB 0x8801
63584ad00cSTomoya MORINAGA
64cf4ece53SMasayuki Ohtak /* SROM ACCESS Macro */
65cf4ece53SMasayuki Ohtak #define PCH_WORD_ADDR_MASK (~((1 << 2) - 1))
66cf4ece53SMasayuki Ohtak
67cf4ece53SMasayuki Ohtak /* Registers address offset */
68cf4ece53SMasayuki Ohtak #define PCH_PHUB_ID_REG 0x0000
69cf4ece53SMasayuki Ohtak #define PCH_PHUB_QUEUE_PRI_VAL_REG 0x0004
70cf4ece53SMasayuki Ohtak #define PCH_PHUB_RC_QUEUE_MAXSIZE_REG 0x0008
71cf4ece53SMasayuki Ohtak #define PCH_PHUB_BRI_QUEUE_MAXSIZE_REG 0x000C
72cf4ece53SMasayuki Ohtak #define PCH_PHUB_COMP_RESP_TIMEOUT_REG 0x0010
73cf4ece53SMasayuki Ohtak #define PCH_PHUB_BUS_SLAVE_CONTROL_REG 0x0014
74cf4ece53SMasayuki Ohtak #define PCH_PHUB_DEADLOCK_AVOID_TYPE_REG 0x0018
75cf4ece53SMasayuki Ohtak #define PCH_PHUB_INTPIN_REG_WPERMIT_REG0 0x0020
76cf4ece53SMasayuki Ohtak #define PCH_PHUB_INTPIN_REG_WPERMIT_REG1 0x0024
77cf4ece53SMasayuki Ohtak #define PCH_PHUB_INTPIN_REG_WPERMIT_REG2 0x0028
78cf4ece53SMasayuki Ohtak #define PCH_PHUB_INTPIN_REG_WPERMIT_REG3 0x002C
79cf4ece53SMasayuki Ohtak #define PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE 0x0040
80cf4ece53SMasayuki Ohtak #define CLKCFG_REG_OFFSET 0x500
81dd7d7feaSTomoya MORINAGA #define FUNCSEL_REG_OFFSET 0x508
82cf4ece53SMasayuki Ohtak
83cf4ece53SMasayuki Ohtak #define PCH_PHUB_OROM_SIZE 15360
84cf4ece53SMasayuki Ohtak
85cf4ece53SMasayuki Ohtak /**
86cf4ece53SMasayuki Ohtak * struct pch_phub_reg - PHUB register structure
87cf4ece53SMasayuki Ohtak * @phub_id_reg: PHUB_ID register val
88cf4ece53SMasayuki Ohtak * @q_pri_val_reg: QUEUE_PRI_VAL register val
89cf4ece53SMasayuki Ohtak * @rc_q_maxsize_reg: RC_QUEUE_MAXSIZE register val
90cf4ece53SMasayuki Ohtak * @bri_q_maxsize_reg: BRI_QUEUE_MAXSIZE register val
91cf4ece53SMasayuki Ohtak * @comp_resp_timeout_reg: COMP_RESP_TIMEOUT register val
92cf4ece53SMasayuki Ohtak * @bus_slave_control_reg: BUS_SLAVE_CONTROL_REG register val
93cf4ece53SMasayuki Ohtak * @deadlock_avoid_type_reg: DEADLOCK_AVOID_TYPE register val
94cf4ece53SMasayuki Ohtak * @intpin_reg_wpermit_reg0: INTPIN_REG_WPERMIT register 0 val
95cf4ece53SMasayuki Ohtak * @intpin_reg_wpermit_reg1: INTPIN_REG_WPERMIT register 1 val
96cf4ece53SMasayuki Ohtak * @intpin_reg_wpermit_reg2: INTPIN_REG_WPERMIT register 2 val
97cf4ece53SMasayuki Ohtak * @intpin_reg_wpermit_reg3: INTPIN_REG_WPERMIT register 3 val
98cf4ece53SMasayuki Ohtak * @int_reduce_control_reg: INT_REDUCE_CONTROL registers val
99cf4ece53SMasayuki Ohtak * @clkcfg_reg: CLK CFG register val
100dd7d7feaSTomoya MORINAGA * @funcsel_reg: Function select register value
101cf4ece53SMasayuki Ohtak * @pch_phub_base_address: Register base address
102cf4ece53SMasayuki Ohtak * @pch_phub_extrom_base_address: external rom base address
103275640b0STomoya MORINAGA * @pch_mac_start_address: MAC address area start address
104275640b0STomoya MORINAGA * @pch_opt_rom_start_address: Option ROM start address
105275640b0STomoya MORINAGA * @ioh_type: Save IOH type
1069914a0deSTomoya MORINAGA * @pdev: pointer to pci device struct
107cf4ece53SMasayuki Ohtak */
108cf4ece53SMasayuki Ohtak struct pch_phub_reg {
109cf4ece53SMasayuki Ohtak u32 phub_id_reg;
110cf4ece53SMasayuki Ohtak u32 q_pri_val_reg;
111cf4ece53SMasayuki Ohtak u32 rc_q_maxsize_reg;
112cf4ece53SMasayuki Ohtak u32 bri_q_maxsize_reg;
113cf4ece53SMasayuki Ohtak u32 comp_resp_timeout_reg;
114cf4ece53SMasayuki Ohtak u32 bus_slave_control_reg;
115cf4ece53SMasayuki Ohtak u32 deadlock_avoid_type_reg;
116cf4ece53SMasayuki Ohtak u32 intpin_reg_wpermit_reg0;
117cf4ece53SMasayuki Ohtak u32 intpin_reg_wpermit_reg1;
118cf4ece53SMasayuki Ohtak u32 intpin_reg_wpermit_reg2;
119cf4ece53SMasayuki Ohtak u32 intpin_reg_wpermit_reg3;
120cf4ece53SMasayuki Ohtak u32 int_reduce_control_reg[MAX_NUM_INT_REDUCE_CONTROL_REG];
121cf4ece53SMasayuki Ohtak u32 clkcfg_reg;
122dd7d7feaSTomoya MORINAGA u32 funcsel_reg;
123cf4ece53SMasayuki Ohtak void __iomem *pch_phub_base_address;
124cf4ece53SMasayuki Ohtak void __iomem *pch_phub_extrom_base_address;
125275640b0STomoya MORINAGA u32 pch_mac_start_address;
126275640b0STomoya MORINAGA u32 pch_opt_rom_start_address;
127275640b0STomoya MORINAGA int ioh_type;
1289914a0deSTomoya MORINAGA struct pci_dev *pdev;
129cf4ece53SMasayuki Ohtak };
130cf4ece53SMasayuki Ohtak
131cf4ece53SMasayuki Ohtak /* SROM SPEC for MAC address assignment offset */
132cf4ece53SMasayuki Ohtak static const int pch_phub_mac_offset[ETH_ALEN] = {0x3, 0x2, 0x1, 0x0, 0xb, 0xa};
133cf4ece53SMasayuki Ohtak
134cf4ece53SMasayuki Ohtak static DEFINE_MUTEX(pch_phub_mutex);
135cf4ece53SMasayuki Ohtak
136cf4ece53SMasayuki Ohtak /**
137cf4ece53SMasayuki Ohtak * pch_phub_read_modify_write_reg() - Reading modifying and writing register
138*0f8ab9bdSLee Jones * @chip: Pointer to the PHUB register structure
139cf4ece53SMasayuki Ohtak * @reg_addr_offset: Register offset address value.
140cf4ece53SMasayuki Ohtak * @data: Writing value.
141cf4ece53SMasayuki Ohtak * @mask: Mask value.
142cf4ece53SMasayuki Ohtak */
pch_phub_read_modify_write_reg(struct pch_phub_reg * chip,unsigned int reg_addr_offset,unsigned int data,unsigned int mask)143cf4ece53SMasayuki Ohtak static void pch_phub_read_modify_write_reg(struct pch_phub_reg *chip,
144cf4ece53SMasayuki Ohtak unsigned int reg_addr_offset,
145cf4ece53SMasayuki Ohtak unsigned int data, unsigned int mask)
146cf4ece53SMasayuki Ohtak {
147cf4ece53SMasayuki Ohtak void __iomem *reg_addr = chip->pch_phub_base_address + reg_addr_offset;
148cf4ece53SMasayuki Ohtak iowrite32(((ioread32(reg_addr) & ~mask)) | data, reg_addr);
149cf4ece53SMasayuki Ohtak }
150cf4ece53SMasayuki Ohtak
151cf4ece53SMasayuki Ohtak /* pch_phub_save_reg_conf - saves register configuration */
pch_phub_save_reg_conf(struct pci_dev * pdev)15234afa1d6SVaibhav Gupta static void __maybe_unused pch_phub_save_reg_conf(struct pci_dev *pdev)
153cf4ece53SMasayuki Ohtak {
154cf4ece53SMasayuki Ohtak unsigned int i;
155cf4ece53SMasayuki Ohtak struct pch_phub_reg *chip = pci_get_drvdata(pdev);
156cf4ece53SMasayuki Ohtak
157cf4ece53SMasayuki Ohtak void __iomem *p = chip->pch_phub_base_address;
158cf4ece53SMasayuki Ohtak
159cf4ece53SMasayuki Ohtak chip->phub_id_reg = ioread32(p + PCH_PHUB_ID_REG);
160cf4ece53SMasayuki Ohtak chip->q_pri_val_reg = ioread32(p + PCH_PHUB_QUEUE_PRI_VAL_REG);
161cf4ece53SMasayuki Ohtak chip->rc_q_maxsize_reg = ioread32(p + PCH_PHUB_RC_QUEUE_MAXSIZE_REG);
162cf4ece53SMasayuki Ohtak chip->bri_q_maxsize_reg = ioread32(p + PCH_PHUB_BRI_QUEUE_MAXSIZE_REG);
163cf4ece53SMasayuki Ohtak chip->comp_resp_timeout_reg =
164cf4ece53SMasayuki Ohtak ioread32(p + PCH_PHUB_COMP_RESP_TIMEOUT_REG);
165cf4ece53SMasayuki Ohtak chip->bus_slave_control_reg =
166cf4ece53SMasayuki Ohtak ioread32(p + PCH_PHUB_BUS_SLAVE_CONTROL_REG);
167cf4ece53SMasayuki Ohtak chip->deadlock_avoid_type_reg =
168cf4ece53SMasayuki Ohtak ioread32(p + PCH_PHUB_DEADLOCK_AVOID_TYPE_REG);
169cf4ece53SMasayuki Ohtak chip->intpin_reg_wpermit_reg0 =
170cf4ece53SMasayuki Ohtak ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG0);
171cf4ece53SMasayuki Ohtak chip->intpin_reg_wpermit_reg1 =
172cf4ece53SMasayuki Ohtak ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG1);
173cf4ece53SMasayuki Ohtak chip->intpin_reg_wpermit_reg2 =
174cf4ece53SMasayuki Ohtak ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG2);
175cf4ece53SMasayuki Ohtak chip->intpin_reg_wpermit_reg3 =
176cf4ece53SMasayuki Ohtak ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG3);
177cf4ece53SMasayuki Ohtak dev_dbg(&pdev->dev, "%s : "
178cf4ece53SMasayuki Ohtak "chip->phub_id_reg=%x, "
179cf4ece53SMasayuki Ohtak "chip->q_pri_val_reg=%x, "
180cf4ece53SMasayuki Ohtak "chip->rc_q_maxsize_reg=%x, "
181cf4ece53SMasayuki Ohtak "chip->bri_q_maxsize_reg=%x, "
182cf4ece53SMasayuki Ohtak "chip->comp_resp_timeout_reg=%x, "
183cf4ece53SMasayuki Ohtak "chip->bus_slave_control_reg=%x, "
184cf4ece53SMasayuki Ohtak "chip->deadlock_avoid_type_reg=%x, "
185cf4ece53SMasayuki Ohtak "chip->intpin_reg_wpermit_reg0=%x, "
186cf4ece53SMasayuki Ohtak "chip->intpin_reg_wpermit_reg1=%x, "
187cf4ece53SMasayuki Ohtak "chip->intpin_reg_wpermit_reg2=%x, "
188cf4ece53SMasayuki Ohtak "chip->intpin_reg_wpermit_reg3=%x\n", __func__,
189cf4ece53SMasayuki Ohtak chip->phub_id_reg,
190cf4ece53SMasayuki Ohtak chip->q_pri_val_reg,
191cf4ece53SMasayuki Ohtak chip->rc_q_maxsize_reg,
192cf4ece53SMasayuki Ohtak chip->bri_q_maxsize_reg,
193cf4ece53SMasayuki Ohtak chip->comp_resp_timeout_reg,
194cf4ece53SMasayuki Ohtak chip->bus_slave_control_reg,
195cf4ece53SMasayuki Ohtak chip->deadlock_avoid_type_reg,
196cf4ece53SMasayuki Ohtak chip->intpin_reg_wpermit_reg0,
197cf4ece53SMasayuki Ohtak chip->intpin_reg_wpermit_reg1,
198cf4ece53SMasayuki Ohtak chip->intpin_reg_wpermit_reg2,
199cf4ece53SMasayuki Ohtak chip->intpin_reg_wpermit_reg3);
200cf4ece53SMasayuki Ohtak for (i = 0; i < MAX_NUM_INT_REDUCE_CONTROL_REG; i++) {
201cf4ece53SMasayuki Ohtak chip->int_reduce_control_reg[i] =
202cf4ece53SMasayuki Ohtak ioread32(p + PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE + 4 * i);
203cf4ece53SMasayuki Ohtak dev_dbg(&pdev->dev, "%s : "
204cf4ece53SMasayuki Ohtak "chip->int_reduce_control_reg[%d]=%x\n",
205cf4ece53SMasayuki Ohtak __func__, i, chip->int_reduce_control_reg[i]);
206cf4ece53SMasayuki Ohtak }
207cf4ece53SMasayuki Ohtak chip->clkcfg_reg = ioread32(p + CLKCFG_REG_OFFSET);
208dd7d7feaSTomoya MORINAGA if ((chip->ioh_type == 2) || (chip->ioh_type == 4))
209dd7d7feaSTomoya MORINAGA chip->funcsel_reg = ioread32(p + FUNCSEL_REG_OFFSET);
210cf4ece53SMasayuki Ohtak }
211cf4ece53SMasayuki Ohtak
212cf4ece53SMasayuki Ohtak /* pch_phub_restore_reg_conf - restore register configuration */
pch_phub_restore_reg_conf(struct pci_dev * pdev)21334afa1d6SVaibhav Gupta static void __maybe_unused pch_phub_restore_reg_conf(struct pci_dev *pdev)
214cf4ece53SMasayuki Ohtak {
215cf4ece53SMasayuki Ohtak unsigned int i;
216cf4ece53SMasayuki Ohtak struct pch_phub_reg *chip = pci_get_drvdata(pdev);
217cf4ece53SMasayuki Ohtak void __iomem *p;
218cf4ece53SMasayuki Ohtak p = chip->pch_phub_base_address;
219cf4ece53SMasayuki Ohtak
220cf4ece53SMasayuki Ohtak iowrite32(chip->phub_id_reg, p + PCH_PHUB_ID_REG);
221cf4ece53SMasayuki Ohtak iowrite32(chip->q_pri_val_reg, p + PCH_PHUB_QUEUE_PRI_VAL_REG);
222cf4ece53SMasayuki Ohtak iowrite32(chip->rc_q_maxsize_reg, p + PCH_PHUB_RC_QUEUE_MAXSIZE_REG);
223cf4ece53SMasayuki Ohtak iowrite32(chip->bri_q_maxsize_reg, p + PCH_PHUB_BRI_QUEUE_MAXSIZE_REG);
224cf4ece53SMasayuki Ohtak iowrite32(chip->comp_resp_timeout_reg,
225cf4ece53SMasayuki Ohtak p + PCH_PHUB_COMP_RESP_TIMEOUT_REG);
226cf4ece53SMasayuki Ohtak iowrite32(chip->bus_slave_control_reg,
227cf4ece53SMasayuki Ohtak p + PCH_PHUB_BUS_SLAVE_CONTROL_REG);
228cf4ece53SMasayuki Ohtak iowrite32(chip->deadlock_avoid_type_reg,
229cf4ece53SMasayuki Ohtak p + PCH_PHUB_DEADLOCK_AVOID_TYPE_REG);
230cf4ece53SMasayuki Ohtak iowrite32(chip->intpin_reg_wpermit_reg0,
231cf4ece53SMasayuki Ohtak p + PCH_PHUB_INTPIN_REG_WPERMIT_REG0);
232cf4ece53SMasayuki Ohtak iowrite32(chip->intpin_reg_wpermit_reg1,
233cf4ece53SMasayuki Ohtak p + PCH_PHUB_INTPIN_REG_WPERMIT_REG1);
234cf4ece53SMasayuki Ohtak iowrite32(chip->intpin_reg_wpermit_reg2,
235cf4ece53SMasayuki Ohtak p + PCH_PHUB_INTPIN_REG_WPERMIT_REG2);
236cf4ece53SMasayuki Ohtak iowrite32(chip->intpin_reg_wpermit_reg3,
237cf4ece53SMasayuki Ohtak p + PCH_PHUB_INTPIN_REG_WPERMIT_REG3);
238cf4ece53SMasayuki Ohtak dev_dbg(&pdev->dev, "%s : "
239cf4ece53SMasayuki Ohtak "chip->phub_id_reg=%x, "
240cf4ece53SMasayuki Ohtak "chip->q_pri_val_reg=%x, "
241cf4ece53SMasayuki Ohtak "chip->rc_q_maxsize_reg=%x, "
242cf4ece53SMasayuki Ohtak "chip->bri_q_maxsize_reg=%x, "
243cf4ece53SMasayuki Ohtak "chip->comp_resp_timeout_reg=%x, "
244cf4ece53SMasayuki Ohtak "chip->bus_slave_control_reg=%x, "
245cf4ece53SMasayuki Ohtak "chip->deadlock_avoid_type_reg=%x, "
246cf4ece53SMasayuki Ohtak "chip->intpin_reg_wpermit_reg0=%x, "
247cf4ece53SMasayuki Ohtak "chip->intpin_reg_wpermit_reg1=%x, "
248cf4ece53SMasayuki Ohtak "chip->intpin_reg_wpermit_reg2=%x, "
249cf4ece53SMasayuki Ohtak "chip->intpin_reg_wpermit_reg3=%x\n", __func__,
250cf4ece53SMasayuki Ohtak chip->phub_id_reg,
251cf4ece53SMasayuki Ohtak chip->q_pri_val_reg,
252cf4ece53SMasayuki Ohtak chip->rc_q_maxsize_reg,
253cf4ece53SMasayuki Ohtak chip->bri_q_maxsize_reg,
254cf4ece53SMasayuki Ohtak chip->comp_resp_timeout_reg,
255cf4ece53SMasayuki Ohtak chip->bus_slave_control_reg,
256cf4ece53SMasayuki Ohtak chip->deadlock_avoid_type_reg,
257cf4ece53SMasayuki Ohtak chip->intpin_reg_wpermit_reg0,
258cf4ece53SMasayuki Ohtak chip->intpin_reg_wpermit_reg1,
259cf4ece53SMasayuki Ohtak chip->intpin_reg_wpermit_reg2,
260cf4ece53SMasayuki Ohtak chip->intpin_reg_wpermit_reg3);
261cf4ece53SMasayuki Ohtak for (i = 0; i < MAX_NUM_INT_REDUCE_CONTROL_REG; i++) {
262cf4ece53SMasayuki Ohtak iowrite32(chip->int_reduce_control_reg[i],
263cf4ece53SMasayuki Ohtak p + PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE + 4 * i);
264cf4ece53SMasayuki Ohtak dev_dbg(&pdev->dev, "%s : "
265cf4ece53SMasayuki Ohtak "chip->int_reduce_control_reg[%d]=%x\n",
266cf4ece53SMasayuki Ohtak __func__, i, chip->int_reduce_control_reg[i]);
267cf4ece53SMasayuki Ohtak }
268cf4ece53SMasayuki Ohtak
269cf4ece53SMasayuki Ohtak iowrite32(chip->clkcfg_reg, p + CLKCFG_REG_OFFSET);
270dd7d7feaSTomoya MORINAGA if ((chip->ioh_type == 2) || (chip->ioh_type == 4))
271dd7d7feaSTomoya MORINAGA iowrite32(chip->funcsel_reg, p + FUNCSEL_REG_OFFSET);
272cf4ece53SMasayuki Ohtak }
273cf4ece53SMasayuki Ohtak
274cf4ece53SMasayuki Ohtak /**
275cf4ece53SMasayuki Ohtak * pch_phub_read_serial_rom() - Reading Serial ROM
276*0f8ab9bdSLee Jones * @chip: Pointer to the PHUB register structure
277cf4ece53SMasayuki Ohtak * @offset_address: Serial ROM offset address to read.
278cf4ece53SMasayuki Ohtak * @data: Read buffer for specified Serial ROM value.
279cf4ece53SMasayuki Ohtak */
pch_phub_read_serial_rom(struct pch_phub_reg * chip,unsigned int offset_address,u8 * data)280cf4ece53SMasayuki Ohtak static void pch_phub_read_serial_rom(struct pch_phub_reg *chip,
281cf4ece53SMasayuki Ohtak unsigned int offset_address, u8 *data)
282cf4ece53SMasayuki Ohtak {
283cf4ece53SMasayuki Ohtak void __iomem *mem_addr = chip->pch_phub_extrom_base_address +
284cf4ece53SMasayuki Ohtak offset_address;
285cf4ece53SMasayuki Ohtak
286cf4ece53SMasayuki Ohtak *data = ioread8(mem_addr);
287cf4ece53SMasayuki Ohtak }
288cf4ece53SMasayuki Ohtak
289cf4ece53SMasayuki Ohtak /**
290cf4ece53SMasayuki Ohtak * pch_phub_write_serial_rom() - Writing Serial ROM
291*0f8ab9bdSLee Jones * @chip: Pointer to the PHUB register structure
292cf4ece53SMasayuki Ohtak * @offset_address: Serial ROM offset address.
293cf4ece53SMasayuki Ohtak * @data: Serial ROM value to write.
294cf4ece53SMasayuki Ohtak */
pch_phub_write_serial_rom(struct pch_phub_reg * chip,unsigned int offset_address,u8 data)295cf4ece53SMasayuki Ohtak static int pch_phub_write_serial_rom(struct pch_phub_reg *chip,
296cf4ece53SMasayuki Ohtak unsigned int offset_address, u8 data)
297cf4ece53SMasayuki Ohtak {
298cf4ece53SMasayuki Ohtak void __iomem *mem_addr = chip->pch_phub_extrom_base_address +
299cf4ece53SMasayuki Ohtak (offset_address & PCH_WORD_ADDR_MASK);
300cf4ece53SMasayuki Ohtak int i;
301cf4ece53SMasayuki Ohtak unsigned int word_data;
302cf4ece53SMasayuki Ohtak unsigned int pos;
303cf4ece53SMasayuki Ohtak unsigned int mask;
304cf4ece53SMasayuki Ohtak pos = (offset_address % 4) * 8;
305cf4ece53SMasayuki Ohtak mask = ~(0xFF << pos);
306cf4ece53SMasayuki Ohtak
307cf4ece53SMasayuki Ohtak iowrite32(PCH_PHUB_ROM_WRITE_ENABLE,
308cf4ece53SMasayuki Ohtak chip->pch_phub_extrom_base_address + PHUB_CONTROL);
309cf4ece53SMasayuki Ohtak
310cf4ece53SMasayuki Ohtak word_data = ioread32(mem_addr);
311cf4ece53SMasayuki Ohtak iowrite32((word_data & mask) | (u32)data << pos, mem_addr);
312cf4ece53SMasayuki Ohtak
313cf4ece53SMasayuki Ohtak i = 0;
314cf4ece53SMasayuki Ohtak while (ioread8(chip->pch_phub_extrom_base_address +
315cf4ece53SMasayuki Ohtak PHUB_STATUS) != 0x00) {
316cf4ece53SMasayuki Ohtak msleep(1);
317cf4ece53SMasayuki Ohtak if (i == PHUB_TIMEOUT)
318cf4ece53SMasayuki Ohtak return -ETIMEDOUT;
319cf4ece53SMasayuki Ohtak i++;
320cf4ece53SMasayuki Ohtak }
321cf4ece53SMasayuki Ohtak
322cf4ece53SMasayuki Ohtak iowrite32(PCH_PHUB_ROM_WRITE_DISABLE,
323cf4ece53SMasayuki Ohtak chip->pch_phub_extrom_base_address + PHUB_CONTROL);
324cf4ece53SMasayuki Ohtak
325cf4ece53SMasayuki Ohtak return 0;
326cf4ece53SMasayuki Ohtak }
327cf4ece53SMasayuki Ohtak
328cf4ece53SMasayuki Ohtak /**
329cf4ece53SMasayuki Ohtak * pch_phub_read_serial_rom_val() - Read Serial ROM value
330*0f8ab9bdSLee Jones * @chip: Pointer to the PHUB register structure
331cf4ece53SMasayuki Ohtak * @offset_address: Serial ROM address offset value.
332cf4ece53SMasayuki Ohtak * @data: Serial ROM value to read.
333cf4ece53SMasayuki Ohtak */
pch_phub_read_serial_rom_val(struct pch_phub_reg * chip,unsigned int offset_address,u8 * data)334cf4ece53SMasayuki Ohtak static void pch_phub_read_serial_rom_val(struct pch_phub_reg *chip,
335cf4ece53SMasayuki Ohtak unsigned int offset_address, u8 *data)
336cf4ece53SMasayuki Ohtak {
337cf4ece53SMasayuki Ohtak unsigned int mem_addr;
338cf4ece53SMasayuki Ohtak
339275640b0STomoya MORINAGA mem_addr = chip->pch_mac_start_address +
340cf4ece53SMasayuki Ohtak pch_phub_mac_offset[offset_address];
341cf4ece53SMasayuki Ohtak
342cf4ece53SMasayuki Ohtak pch_phub_read_serial_rom(chip, mem_addr, data);
343cf4ece53SMasayuki Ohtak }
344cf4ece53SMasayuki Ohtak
345cf4ece53SMasayuki Ohtak /**
346cf4ece53SMasayuki Ohtak * pch_phub_write_serial_rom_val() - writing Serial ROM value
347*0f8ab9bdSLee Jones * @chip: Pointer to the PHUB register structure
348cf4ece53SMasayuki Ohtak * @offset_address: Serial ROM address offset value.
349cf4ece53SMasayuki Ohtak * @data: Serial ROM value.
350cf4ece53SMasayuki Ohtak */
pch_phub_write_serial_rom_val(struct pch_phub_reg * chip,unsigned int offset_address,u8 data)351cf4ece53SMasayuki Ohtak static int pch_phub_write_serial_rom_val(struct pch_phub_reg *chip,
352cf4ece53SMasayuki Ohtak unsigned int offset_address, u8 data)
353cf4ece53SMasayuki Ohtak {
354cf4ece53SMasayuki Ohtak int retval;
355cf4ece53SMasayuki Ohtak unsigned int mem_addr;
356cf4ece53SMasayuki Ohtak
357275640b0STomoya MORINAGA mem_addr = chip->pch_mac_start_address +
358cf4ece53SMasayuki Ohtak pch_phub_mac_offset[offset_address];
359cf4ece53SMasayuki Ohtak
360cf4ece53SMasayuki Ohtak retval = pch_phub_write_serial_rom(chip, mem_addr, data);
361cf4ece53SMasayuki Ohtak
362cf4ece53SMasayuki Ohtak return retval;
363cf4ece53SMasayuki Ohtak }
364cf4ece53SMasayuki Ohtak
365cf4ece53SMasayuki Ohtak /* pch_phub_gbe_serial_rom_conf - makes Serial ROM header format configuration
366cf4ece53SMasayuki Ohtak * for Gigabit Ethernet MAC address
367cf4ece53SMasayuki Ohtak */
pch_phub_gbe_serial_rom_conf(struct pch_phub_reg * chip)368cf4ece53SMasayuki Ohtak static int pch_phub_gbe_serial_rom_conf(struct pch_phub_reg *chip)
369cf4ece53SMasayuki Ohtak {
370cf4ece53SMasayuki Ohtak int retval;
371cf4ece53SMasayuki Ohtak
372cf4ece53SMasayuki Ohtak retval = pch_phub_write_serial_rom(chip, 0x0b, 0xbc);
373cf4ece53SMasayuki Ohtak retval |= pch_phub_write_serial_rom(chip, 0x0a, 0x10);
374cf4ece53SMasayuki Ohtak retval |= pch_phub_write_serial_rom(chip, 0x09, 0x01);
375cf4ece53SMasayuki Ohtak retval |= pch_phub_write_serial_rom(chip, 0x08, 0x02);
376cf4ece53SMasayuki Ohtak
377cf4ece53SMasayuki Ohtak retval |= pch_phub_write_serial_rom(chip, 0x0f, 0x00);
378cf4ece53SMasayuki Ohtak retval |= pch_phub_write_serial_rom(chip, 0x0e, 0x00);
379cf4ece53SMasayuki Ohtak retval |= pch_phub_write_serial_rom(chip, 0x0d, 0x00);
380cf4ece53SMasayuki Ohtak retval |= pch_phub_write_serial_rom(chip, 0x0c, 0x80);
381cf4ece53SMasayuki Ohtak
382cf4ece53SMasayuki Ohtak retval |= pch_phub_write_serial_rom(chip, 0x13, 0xbc);
383cf4ece53SMasayuki Ohtak retval |= pch_phub_write_serial_rom(chip, 0x12, 0x10);
384cf4ece53SMasayuki Ohtak retval |= pch_phub_write_serial_rom(chip, 0x11, 0x01);
385cf4ece53SMasayuki Ohtak retval |= pch_phub_write_serial_rom(chip, 0x10, 0x18);
386cf4ece53SMasayuki Ohtak
387cf4ece53SMasayuki Ohtak retval |= pch_phub_write_serial_rom(chip, 0x1b, 0xbc);
388cf4ece53SMasayuki Ohtak retval |= pch_phub_write_serial_rom(chip, 0x1a, 0x10);
389cf4ece53SMasayuki Ohtak retval |= pch_phub_write_serial_rom(chip, 0x19, 0x01);
390cf4ece53SMasayuki Ohtak retval |= pch_phub_write_serial_rom(chip, 0x18, 0x19);
391cf4ece53SMasayuki Ohtak
392cf4ece53SMasayuki Ohtak retval |= pch_phub_write_serial_rom(chip, 0x23, 0xbc);
393cf4ece53SMasayuki Ohtak retval |= pch_phub_write_serial_rom(chip, 0x22, 0x10);
394cf4ece53SMasayuki Ohtak retval |= pch_phub_write_serial_rom(chip, 0x21, 0x01);
395cf4ece53SMasayuki Ohtak retval |= pch_phub_write_serial_rom(chip, 0x20, 0x3a);
396cf4ece53SMasayuki Ohtak
397cf4ece53SMasayuki Ohtak retval |= pch_phub_write_serial_rom(chip, 0x27, 0x01);
398cf4ece53SMasayuki Ohtak retval |= pch_phub_write_serial_rom(chip, 0x26, 0x00);
399cf4ece53SMasayuki Ohtak retval |= pch_phub_write_serial_rom(chip, 0x25, 0x00);
400cf4ece53SMasayuki Ohtak retval |= pch_phub_write_serial_rom(chip, 0x24, 0x00);
401cf4ece53SMasayuki Ohtak
402cf4ece53SMasayuki Ohtak return retval;
403cf4ece53SMasayuki Ohtak }
404cf4ece53SMasayuki Ohtak
405275640b0STomoya MORINAGA /* pch_phub_gbe_serial_rom_conf_mp - makes SerialROM header format configuration
406275640b0STomoya MORINAGA * for Gigabit Ethernet MAC address
407275640b0STomoya MORINAGA */
pch_phub_gbe_serial_rom_conf_mp(struct pch_phub_reg * chip)408275640b0STomoya MORINAGA static int pch_phub_gbe_serial_rom_conf_mp(struct pch_phub_reg *chip)
409275640b0STomoya MORINAGA {
410275640b0STomoya MORINAGA int retval;
411275640b0STomoya MORINAGA u32 offset_addr;
412275640b0STomoya MORINAGA
413275640b0STomoya MORINAGA offset_addr = 0x200;
414275640b0STomoya MORINAGA retval = pch_phub_write_serial_rom(chip, 0x03 + offset_addr, 0xbc);
415275640b0STomoya MORINAGA retval |= pch_phub_write_serial_rom(chip, 0x02 + offset_addr, 0x00);
416275640b0STomoya MORINAGA retval |= pch_phub_write_serial_rom(chip, 0x01 + offset_addr, 0x40);
417275640b0STomoya MORINAGA retval |= pch_phub_write_serial_rom(chip, 0x00 + offset_addr, 0x02);
418275640b0STomoya MORINAGA
419275640b0STomoya MORINAGA retval |= pch_phub_write_serial_rom(chip, 0x07 + offset_addr, 0x00);
420275640b0STomoya MORINAGA retval |= pch_phub_write_serial_rom(chip, 0x06 + offset_addr, 0x00);
421275640b0STomoya MORINAGA retval |= pch_phub_write_serial_rom(chip, 0x05 + offset_addr, 0x00);
422275640b0STomoya MORINAGA retval |= pch_phub_write_serial_rom(chip, 0x04 + offset_addr, 0x80);
423275640b0STomoya MORINAGA
424275640b0STomoya MORINAGA retval |= pch_phub_write_serial_rom(chip, 0x0b + offset_addr, 0xbc);
425275640b0STomoya MORINAGA retval |= pch_phub_write_serial_rom(chip, 0x0a + offset_addr, 0x00);
426275640b0STomoya MORINAGA retval |= pch_phub_write_serial_rom(chip, 0x09 + offset_addr, 0x40);
427275640b0STomoya MORINAGA retval |= pch_phub_write_serial_rom(chip, 0x08 + offset_addr, 0x18);
428275640b0STomoya MORINAGA
429275640b0STomoya MORINAGA retval |= pch_phub_write_serial_rom(chip, 0x13 + offset_addr, 0xbc);
430275640b0STomoya MORINAGA retval |= pch_phub_write_serial_rom(chip, 0x12 + offset_addr, 0x00);
431275640b0STomoya MORINAGA retval |= pch_phub_write_serial_rom(chip, 0x11 + offset_addr, 0x40);
432275640b0STomoya MORINAGA retval |= pch_phub_write_serial_rom(chip, 0x10 + offset_addr, 0x19);
433275640b0STomoya MORINAGA
434275640b0STomoya MORINAGA retval |= pch_phub_write_serial_rom(chip, 0x1b + offset_addr, 0xbc);
435275640b0STomoya MORINAGA retval |= pch_phub_write_serial_rom(chip, 0x1a + offset_addr, 0x00);
436275640b0STomoya MORINAGA retval |= pch_phub_write_serial_rom(chip, 0x19 + offset_addr, 0x40);
437275640b0STomoya MORINAGA retval |= pch_phub_write_serial_rom(chip, 0x18 + offset_addr, 0x3a);
438275640b0STomoya MORINAGA
439275640b0STomoya MORINAGA retval |= pch_phub_write_serial_rom(chip, 0x1f + offset_addr, 0x01);
440275640b0STomoya MORINAGA retval |= pch_phub_write_serial_rom(chip, 0x1e + offset_addr, 0x00);
441275640b0STomoya MORINAGA retval |= pch_phub_write_serial_rom(chip, 0x1d + offset_addr, 0x00);
442275640b0STomoya MORINAGA retval |= pch_phub_write_serial_rom(chip, 0x1c + offset_addr, 0x00);
443275640b0STomoya MORINAGA
444275640b0STomoya MORINAGA return retval;
445275640b0STomoya MORINAGA }
446275640b0STomoya MORINAGA
447cf4ece53SMasayuki Ohtak /**
448cf4ece53SMasayuki Ohtak * pch_phub_read_gbe_mac_addr() - Read Gigabit Ethernet MAC address
449*0f8ab9bdSLee Jones * @chip: Pointer to the PHUB register structure
450cf4ece53SMasayuki Ohtak * @data: Buffer of the Gigabit Ethernet MAC address value.
451cf4ece53SMasayuki Ohtak */
pch_phub_read_gbe_mac_addr(struct pch_phub_reg * chip,u8 * data)452cf4ece53SMasayuki Ohtak static void pch_phub_read_gbe_mac_addr(struct pch_phub_reg *chip, u8 *data)
453cf4ece53SMasayuki Ohtak {
454cf4ece53SMasayuki Ohtak int i;
455cf4ece53SMasayuki Ohtak for (i = 0; i < ETH_ALEN; i++)
456cf4ece53SMasayuki Ohtak pch_phub_read_serial_rom_val(chip, i, &data[i]);
457cf4ece53SMasayuki Ohtak }
458cf4ece53SMasayuki Ohtak
459cf4ece53SMasayuki Ohtak /**
460cf4ece53SMasayuki Ohtak * pch_phub_write_gbe_mac_addr() - Write MAC address
461*0f8ab9bdSLee Jones * @chip: Pointer to the PHUB register structure
462cf4ece53SMasayuki Ohtak * @data: Gigabit Ethernet MAC address value.
463cf4ece53SMasayuki Ohtak */
pch_phub_write_gbe_mac_addr(struct pch_phub_reg * chip,u8 * data)464cf4ece53SMasayuki Ohtak static int pch_phub_write_gbe_mac_addr(struct pch_phub_reg *chip, u8 *data)
465cf4ece53SMasayuki Ohtak {
466cf4ece53SMasayuki Ohtak int retval;
467cf4ece53SMasayuki Ohtak int i;
468cf4ece53SMasayuki Ohtak
4692a988791STomoya MORINAGA if ((chip->ioh_type == 1) || (chip->ioh_type == 5)) /* EG20T or ML7831*/
470cf4ece53SMasayuki Ohtak retval = pch_phub_gbe_serial_rom_conf(chip);
471275640b0STomoya MORINAGA else /* ML7223 */
472275640b0STomoya MORINAGA retval = pch_phub_gbe_serial_rom_conf_mp(chip);
473cf4ece53SMasayuki Ohtak if (retval)
474cf4ece53SMasayuki Ohtak return retval;
475cf4ece53SMasayuki Ohtak
476cf4ece53SMasayuki Ohtak for (i = 0; i < ETH_ALEN; i++) {
477cf4ece53SMasayuki Ohtak retval = pch_phub_write_serial_rom_val(chip, i, data[i]);
478cf4ece53SMasayuki Ohtak if (retval)
479cf4ece53SMasayuki Ohtak return retval;
480cf4ece53SMasayuki Ohtak }
481cf4ece53SMasayuki Ohtak
482cf4ece53SMasayuki Ohtak return retval;
483cf4ece53SMasayuki Ohtak }
484cf4ece53SMasayuki Ohtak
pch_phub_bin_read(struct file * filp,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t off,size_t count)485cf4ece53SMasayuki Ohtak static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj,
486cf4ece53SMasayuki Ohtak struct bin_attribute *attr, char *buf,
487cf4ece53SMasayuki Ohtak loff_t off, size_t count)
488cf4ece53SMasayuki Ohtak {
489cf4ece53SMasayuki Ohtak unsigned int rom_signature;
490cf4ece53SMasayuki Ohtak unsigned char rom_length;
491cf4ece53SMasayuki Ohtak unsigned int tmp;
492cf4ece53SMasayuki Ohtak unsigned int addr_offset;
493cf4ece53SMasayuki Ohtak unsigned int orom_size;
494cf4ece53SMasayuki Ohtak int ret;
495cf4ece53SMasayuki Ohtak int err;
4969914a0deSTomoya MORINAGA ssize_t rom_size;
497cf4ece53SMasayuki Ohtak
49885f4f39cSGeliang Tang struct pch_phub_reg *chip = dev_get_drvdata(kobj_to_dev(kobj));
499cf4ece53SMasayuki Ohtak
500cf4ece53SMasayuki Ohtak ret = mutex_lock_interruptible(&pch_phub_mutex);
501cf4ece53SMasayuki Ohtak if (ret) {
502cf4ece53SMasayuki Ohtak err = -ERESTARTSYS;
503cf4ece53SMasayuki Ohtak goto return_err_nomutex;
504cf4ece53SMasayuki Ohtak }
505cf4ece53SMasayuki Ohtak
506cf4ece53SMasayuki Ohtak /* Get Rom signature */
5079914a0deSTomoya MORINAGA chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size);
508a75fa128SColin Ian King if (!chip->pch_phub_extrom_base_address) {
509a75fa128SColin Ian King err = -ENODATA;
5109914a0deSTomoya MORINAGA goto exrom_map_err;
511a75fa128SColin Ian King }
5129914a0deSTomoya MORINAGA
513275640b0STomoya MORINAGA pch_phub_read_serial_rom(chip, chip->pch_opt_rom_start_address,
514275640b0STomoya MORINAGA (unsigned char *)&rom_signature);
515cf4ece53SMasayuki Ohtak rom_signature &= 0xff;
516275640b0STomoya MORINAGA pch_phub_read_serial_rom(chip, chip->pch_opt_rom_start_address + 1,
517275640b0STomoya MORINAGA (unsigned char *)&tmp);
518cf4ece53SMasayuki Ohtak rom_signature |= (tmp & 0xff) << 8;
519cf4ece53SMasayuki Ohtak if (rom_signature == 0xAA55) {
520275640b0STomoya MORINAGA pch_phub_read_serial_rom(chip,
521275640b0STomoya MORINAGA chip->pch_opt_rom_start_address + 2,
522275640b0STomoya MORINAGA &rom_length);
523cf4ece53SMasayuki Ohtak orom_size = rom_length * 512;
524cf4ece53SMasayuki Ohtak if (orom_size < off) {
525cf4ece53SMasayuki Ohtak addr_offset = 0;
526cf4ece53SMasayuki Ohtak goto return_ok;
527cf4ece53SMasayuki Ohtak }
528cf4ece53SMasayuki Ohtak if (orom_size < count) {
529cf4ece53SMasayuki Ohtak addr_offset = 0;
530cf4ece53SMasayuki Ohtak goto return_ok;
531cf4ece53SMasayuki Ohtak }
532cf4ece53SMasayuki Ohtak
533cf4ece53SMasayuki Ohtak for (addr_offset = 0; addr_offset < count; addr_offset++) {
534275640b0STomoya MORINAGA pch_phub_read_serial_rom(chip,
535275640b0STomoya MORINAGA chip->pch_opt_rom_start_address + addr_offset + off,
536cf4ece53SMasayuki Ohtak &buf[addr_offset]);
537cf4ece53SMasayuki Ohtak }
538cf4ece53SMasayuki Ohtak } else {
539cf4ece53SMasayuki Ohtak err = -ENODATA;
540cf4ece53SMasayuki Ohtak goto return_err;
541cf4ece53SMasayuki Ohtak }
542cf4ece53SMasayuki Ohtak return_ok:
5439914a0deSTomoya MORINAGA pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
544cf4ece53SMasayuki Ohtak mutex_unlock(&pch_phub_mutex);
545cf4ece53SMasayuki Ohtak return addr_offset;
546cf4ece53SMasayuki Ohtak
547cf4ece53SMasayuki Ohtak return_err:
5489914a0deSTomoya MORINAGA pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
5499914a0deSTomoya MORINAGA exrom_map_err:
550cf4ece53SMasayuki Ohtak mutex_unlock(&pch_phub_mutex);
551cf4ece53SMasayuki Ohtak return_err_nomutex:
552cf4ece53SMasayuki Ohtak return err;
553cf4ece53SMasayuki Ohtak }
554cf4ece53SMasayuki Ohtak
pch_phub_bin_write(struct file * filp,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t off,size_t count)555cf4ece53SMasayuki Ohtak static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj,
556cf4ece53SMasayuki Ohtak struct bin_attribute *attr,
557cf4ece53SMasayuki Ohtak char *buf, loff_t off, size_t count)
558cf4ece53SMasayuki Ohtak {
559cf4ece53SMasayuki Ohtak int err;
560cf4ece53SMasayuki Ohtak unsigned int addr_offset;
561cf4ece53SMasayuki Ohtak int ret;
5629914a0deSTomoya MORINAGA ssize_t rom_size;
56385f4f39cSGeliang Tang struct pch_phub_reg *chip = dev_get_drvdata(kobj_to_dev(kobj));
564cf4ece53SMasayuki Ohtak
565cf4ece53SMasayuki Ohtak ret = mutex_lock_interruptible(&pch_phub_mutex);
566cf4ece53SMasayuki Ohtak if (ret)
567cf4ece53SMasayuki Ohtak return -ERESTARTSYS;
568cf4ece53SMasayuki Ohtak
569cf4ece53SMasayuki Ohtak if (off > PCH_PHUB_OROM_SIZE) {
570cf4ece53SMasayuki Ohtak addr_offset = 0;
571cf4ece53SMasayuki Ohtak goto return_ok;
572cf4ece53SMasayuki Ohtak }
573cf4ece53SMasayuki Ohtak if (count > PCH_PHUB_OROM_SIZE) {
574cf4ece53SMasayuki Ohtak addr_offset = 0;
575cf4ece53SMasayuki Ohtak goto return_ok;
576cf4ece53SMasayuki Ohtak }
577cf4ece53SMasayuki Ohtak
5789914a0deSTomoya MORINAGA chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size);
5799914a0deSTomoya MORINAGA if (!chip->pch_phub_extrom_base_address) {
5809914a0deSTomoya MORINAGA err = -ENOMEM;
5819914a0deSTomoya MORINAGA goto exrom_map_err;
5829914a0deSTomoya MORINAGA }
5839914a0deSTomoya MORINAGA
584cf4ece53SMasayuki Ohtak for (addr_offset = 0; addr_offset < count; addr_offset++) {
585cf4ece53SMasayuki Ohtak if (PCH_PHUB_OROM_SIZE < off + addr_offset)
586cf4ece53SMasayuki Ohtak goto return_ok;
587cf4ece53SMasayuki Ohtak
588275640b0STomoya MORINAGA ret = pch_phub_write_serial_rom(chip,
589275640b0STomoya MORINAGA chip->pch_opt_rom_start_address + addr_offset + off,
590cf4ece53SMasayuki Ohtak buf[addr_offset]);
591cf4ece53SMasayuki Ohtak if (ret) {
592cf4ece53SMasayuki Ohtak err = ret;
593cf4ece53SMasayuki Ohtak goto return_err;
594cf4ece53SMasayuki Ohtak }
595cf4ece53SMasayuki Ohtak }
596cf4ece53SMasayuki Ohtak
597cf4ece53SMasayuki Ohtak return_ok:
5989914a0deSTomoya MORINAGA pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
599cf4ece53SMasayuki Ohtak mutex_unlock(&pch_phub_mutex);
600cf4ece53SMasayuki Ohtak return addr_offset;
601cf4ece53SMasayuki Ohtak
602cf4ece53SMasayuki Ohtak return_err:
6039914a0deSTomoya MORINAGA pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
6049914a0deSTomoya MORINAGA
6059914a0deSTomoya MORINAGA exrom_map_err:
606cf4ece53SMasayuki Ohtak mutex_unlock(&pch_phub_mutex);
607cf4ece53SMasayuki Ohtak return err;
608cf4ece53SMasayuki Ohtak }
609cf4ece53SMasayuki Ohtak
show_pch_mac(struct device * dev,struct device_attribute * attr,char * buf)610cf4ece53SMasayuki Ohtak static ssize_t show_pch_mac(struct device *dev, struct device_attribute *attr,
611cf4ece53SMasayuki Ohtak char *buf)
612cf4ece53SMasayuki Ohtak {
613cf4ece53SMasayuki Ohtak u8 mac[8];
614cf4ece53SMasayuki Ohtak struct pch_phub_reg *chip = dev_get_drvdata(dev);
6159914a0deSTomoya MORINAGA ssize_t rom_size;
6169914a0deSTomoya MORINAGA
6179914a0deSTomoya MORINAGA chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size);
6189914a0deSTomoya MORINAGA if (!chip->pch_phub_extrom_base_address)
6199914a0deSTomoya MORINAGA return -ENOMEM;
620cf4ece53SMasayuki Ohtak
621cf4ece53SMasayuki Ohtak pch_phub_read_gbe_mac_addr(chip, mac);
6229914a0deSTomoya MORINAGA pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
623cf4ece53SMasayuki Ohtak
62425b8a88cSAndy Shevchenko return sprintf(buf, "%pM\n", mac);
625cf4ece53SMasayuki Ohtak }
626cf4ece53SMasayuki Ohtak
store_pch_mac(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)627cf4ece53SMasayuki Ohtak static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr,
628cf4ece53SMasayuki Ohtak const char *buf, size_t count)
629cf4ece53SMasayuki Ohtak {
630143e9c76SAndy Shevchenko u8 mac[ETH_ALEN];
6319914a0deSTomoya MORINAGA ssize_t rom_size;
632cf4ece53SMasayuki Ohtak struct pch_phub_reg *chip = dev_get_drvdata(dev);
633a246b973SAlexander Stein int ret;
634cf4ece53SMasayuki Ohtak
635143e9c76SAndy Shevchenko if (!mac_pton(buf, mac))
636cf4ece53SMasayuki Ohtak return -EINVAL;
637cf4ece53SMasayuki Ohtak
6389914a0deSTomoya MORINAGA chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size);
6399914a0deSTomoya MORINAGA if (!chip->pch_phub_extrom_base_address)
6409914a0deSTomoya MORINAGA return -ENOMEM;
6419914a0deSTomoya MORINAGA
642a246b973SAlexander Stein ret = pch_phub_write_gbe_mac_addr(chip, mac);
6439914a0deSTomoya MORINAGA pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
644a246b973SAlexander Stein if (ret)
645a246b973SAlexander Stein return ret;
646cf4ece53SMasayuki Ohtak
647cf4ece53SMasayuki Ohtak return count;
648cf4ece53SMasayuki Ohtak }
649cf4ece53SMasayuki Ohtak
650cf4ece53SMasayuki Ohtak static DEVICE_ATTR(pch_mac, S_IRUGO | S_IWUSR, show_pch_mac, store_pch_mac);
651cf4ece53SMasayuki Ohtak
65257daedf8SBhumika Goyal static const struct bin_attribute pch_bin_attr = {
653cf4ece53SMasayuki Ohtak .attr = {
654cf4ece53SMasayuki Ohtak .name = "pch_firmware",
655cf4ece53SMasayuki Ohtak .mode = S_IRUGO | S_IWUSR,
656cf4ece53SMasayuki Ohtak },
657cf4ece53SMasayuki Ohtak .size = PCH_PHUB_OROM_SIZE + 1,
658cf4ece53SMasayuki Ohtak .read = pch_phub_bin_read,
659cf4ece53SMasayuki Ohtak .write = pch_phub_bin_write,
660cf4ece53SMasayuki Ohtak };
661cf4ece53SMasayuki Ohtak
pch_phub_probe(struct pci_dev * pdev,const struct pci_device_id * id)66280c8ae28SBill Pemberton static int pch_phub_probe(struct pci_dev *pdev,
663cf4ece53SMasayuki Ohtak const struct pci_device_id *id)
664cf4ece53SMasayuki Ohtak {
665cf4ece53SMasayuki Ohtak int ret;
666cf4ece53SMasayuki Ohtak struct pch_phub_reg *chip;
667cf4ece53SMasayuki Ohtak
668cf4ece53SMasayuki Ohtak chip = kzalloc(sizeof(struct pch_phub_reg), GFP_KERNEL);
669cf4ece53SMasayuki Ohtak if (chip == NULL)
670cf4ece53SMasayuki Ohtak return -ENOMEM;
671cf4ece53SMasayuki Ohtak
672cf4ece53SMasayuki Ohtak ret = pci_enable_device(pdev);
673cf4ece53SMasayuki Ohtak if (ret) {
674cf4ece53SMasayuki Ohtak dev_err(&pdev->dev,
675cf4ece53SMasayuki Ohtak "%s : pci_enable_device FAILED(ret=%d)", __func__, ret);
676cf4ece53SMasayuki Ohtak goto err_pci_enable_dev;
677cf4ece53SMasayuki Ohtak }
678cf4ece53SMasayuki Ohtak dev_dbg(&pdev->dev, "%s : pci_enable_device returns %d\n", __func__,
679cf4ece53SMasayuki Ohtak ret);
680cf4ece53SMasayuki Ohtak
681cf4ece53SMasayuki Ohtak ret = pci_request_regions(pdev, KBUILD_MODNAME);
682cf4ece53SMasayuki Ohtak if (ret) {
683cf4ece53SMasayuki Ohtak dev_err(&pdev->dev,
684cf4ece53SMasayuki Ohtak "%s : pci_request_regions FAILED(ret=%d)", __func__, ret);
685cf4ece53SMasayuki Ohtak goto err_req_regions;
686cf4ece53SMasayuki Ohtak }
687cf4ece53SMasayuki Ohtak dev_dbg(&pdev->dev, "%s : "
688cf4ece53SMasayuki Ohtak "pci_request_regions returns %d\n", __func__, ret);
689cf4ece53SMasayuki Ohtak
690cf4ece53SMasayuki Ohtak chip->pch_phub_base_address = pci_iomap(pdev, 1, 0);
691cf4ece53SMasayuki Ohtak
692cf4ece53SMasayuki Ohtak
69373ac0e9eSDevendra Naga if (chip->pch_phub_base_address == NULL) {
694cf4ece53SMasayuki Ohtak dev_err(&pdev->dev, "%s : pci_iomap FAILED", __func__);
695cf4ece53SMasayuki Ohtak ret = -ENOMEM;
696cf4ece53SMasayuki Ohtak goto err_pci_iomap;
697cf4ece53SMasayuki Ohtak }
698cf4ece53SMasayuki Ohtak dev_dbg(&pdev->dev, "%s : pci_iomap SUCCESS and value "
699da0d7f98SGreg Kroah-Hartman "in pch_phub_base_address variable is %p\n", __func__,
700da0d7f98SGreg Kroah-Hartman chip->pch_phub_base_address);
701cf4ece53SMasayuki Ohtak
7029914a0deSTomoya MORINAGA chip->pdev = pdev; /* Save pci device struct */
703cf4ece53SMasayuki Ohtak
704275640b0STomoya MORINAGA if (id->driver_data == 1) { /* EG20T PCH */
7052b934c62SAlexander Stein const char *board_name;
706549ce8f1SZubair Lutfullah Kakakhel unsigned int prefetch = 0x000affaa;
707549ce8f1SZubair Lutfullah Kakakhel
708549ce8f1SZubair Lutfullah Kakakhel if (pdev->dev.of_node)
709549ce8f1SZubair Lutfullah Kakakhel of_property_read_u32(pdev->dev.of_node,
710549ce8f1SZubair Lutfullah Kakakhel "intel,eg20t-prefetch",
711549ce8f1SZubair Lutfullah Kakakhel &prefetch);
7122b934c62SAlexander Stein
71329ddae2aSWei Yongjun ret = sysfs_create_file(&pdev->dev.kobj,
714c47dda7dSTomoya MORINAGA &dev_attr_pch_mac.attr);
71529ddae2aSWei Yongjun if (ret)
716cf4ece53SMasayuki Ohtak goto err_sysfs_create;
717cf4ece53SMasayuki Ohtak
71829ddae2aSWei Yongjun ret = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
71929ddae2aSWei Yongjun if (ret)
720cf4ece53SMasayuki Ohtak goto exit_bin_attr;
721cf4ece53SMasayuki Ohtak
722c47dda7dSTomoya MORINAGA pch_phub_read_modify_write_reg(chip,
723c47dda7dSTomoya MORINAGA (unsigned int)CLKCFG_REG_OFFSET,
724c47dda7dSTomoya MORINAGA CLKCFG_CAN_50MHZ,
725c47dda7dSTomoya MORINAGA CLKCFG_CANCLK_MASK);
726cf4ece53SMasayuki Ohtak
7276ae705b2SDenis Turischev /* quirk for CM-iTC board */
7282b934c62SAlexander Stein board_name = dmi_get_system_info(DMI_BOARD_NAME);
7292b934c62SAlexander Stein if (board_name && strstr(board_name, "CM-iTC"))
7306ae705b2SDenis Turischev pch_phub_read_modify_write_reg(chip,
7316ae705b2SDenis Turischev (unsigned int)CLKCFG_REG_OFFSET,
7326ae705b2SDenis Turischev CLKCFG_UART_48MHZ | CLKCFG_BAUDDIV |
7336ae705b2SDenis Turischev CLKCFG_PLL2VCO | CLKCFG_UARTCLKSEL,
7346ae705b2SDenis Turischev CLKCFG_UART_MASK);
7356ae705b2SDenis Turischev
736cf4ece53SMasayuki Ohtak /* set the prefech value */
737549ce8f1SZubair Lutfullah Kakakhel iowrite32(prefetch, chip->pch_phub_base_address + 0x14);
738cf4ece53SMasayuki Ohtak /* set the interrupt delay value */
739cf4ece53SMasayuki Ohtak iowrite32(0x25, chip->pch_phub_base_address + 0x44);
740275640b0STomoya MORINAGA chip->pch_opt_rom_start_address = PCH_PHUB_ROM_START_ADDR_EG20T;
741275640b0STomoya MORINAGA chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_EG20T;
742bed3d7baSZubair Lutfullah Kakakhel
743bed3d7baSZubair Lutfullah Kakakhel /* quirk for MIPS Boston platform */
744bed3d7baSZubair Lutfullah Kakakhel if (pdev->dev.of_node) {
745bed3d7baSZubair Lutfullah Kakakhel if (of_machine_is_compatible("img,boston")) {
746bed3d7baSZubair Lutfullah Kakakhel pch_phub_read_modify_write_reg(chip,
747bed3d7baSZubair Lutfullah Kakakhel (unsigned int)CLKCFG_REG_OFFSET,
748bed3d7baSZubair Lutfullah Kakakhel CLKCFG_UART_25MHZ,
749bed3d7baSZubair Lutfullah Kakakhel CLKCFG_UART_MASK);
750bed3d7baSZubair Lutfullah Kakakhel }
751bed3d7baSZubair Lutfullah Kakakhel }
752275640b0STomoya MORINAGA } else if (id->driver_data == 2) { /* ML7213 IOH */
75329ddae2aSWei Yongjun ret = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
75429ddae2aSWei Yongjun if (ret)
755c47dda7dSTomoya MORINAGA goto err_sysfs_create;
756c47dda7dSTomoya MORINAGA /* set the prefech value
757c47dda7dSTomoya MORINAGA * Device2(USB OHCI #1/ USB EHCI #1/ USB Device):a
758c47dda7dSTomoya MORINAGA * Device4(SDIO #0,1,2):f
759c47dda7dSTomoya MORINAGA * Device6(SATA 2):f
760c47dda7dSTomoya MORINAGA * Device8(USB OHCI #0/ USB EHCI #0):a
761c47dda7dSTomoya MORINAGA */
762c47dda7dSTomoya MORINAGA iowrite32(0x000affa0, chip->pch_phub_base_address + 0x14);
763275640b0STomoya MORINAGA chip->pch_opt_rom_start_address =\
764275640b0STomoya MORINAGA PCH_PHUB_ROM_START_ADDR_ML7213;
765275640b0STomoya MORINAGA } else if (id->driver_data == 3) { /* ML7223 IOH Bus-m*/
766275640b0STomoya MORINAGA /* set the prefech value
767275640b0STomoya MORINAGA * Device8(GbE)
768275640b0STomoya MORINAGA */
769275640b0STomoya MORINAGA iowrite32(0x000a0000, chip->pch_phub_base_address + 0x14);
77020ae6d0bSTomoya MORINAGA /* set the interrupt delay value */
77120ae6d0bSTomoya MORINAGA iowrite32(0x25, chip->pch_phub_base_address + 0x140);
772275640b0STomoya MORINAGA chip->pch_opt_rom_start_address =\
773275640b0STomoya MORINAGA PCH_PHUB_ROM_START_ADDR_ML7223;
774275640b0STomoya MORINAGA chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_ML7223;
775275640b0STomoya MORINAGA } else if (id->driver_data == 4) { /* ML7223 IOH Bus-n*/
77629ddae2aSWei Yongjun ret = sysfs_create_file(&pdev->dev.kobj,
777275640b0STomoya MORINAGA &dev_attr_pch_mac.attr);
77829ddae2aSWei Yongjun if (ret)
779275640b0STomoya MORINAGA goto err_sysfs_create;
78029ddae2aSWei Yongjun ret = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
78129ddae2aSWei Yongjun if (ret)
782275640b0STomoya MORINAGA goto exit_bin_attr;
783275640b0STomoya MORINAGA /* set the prefech value
784275640b0STomoya MORINAGA * Device2(USB OHCI #0,1,2,3/ USB EHCI #0):a
785275640b0STomoya MORINAGA * Device4(SDIO #0,1):f
786275640b0STomoya MORINAGA * Device6(SATA 2):f
787275640b0STomoya MORINAGA */
788275640b0STomoya MORINAGA iowrite32(0x0000ffa0, chip->pch_phub_base_address + 0x14);
789275640b0STomoya MORINAGA chip->pch_opt_rom_start_address =\
790275640b0STomoya MORINAGA PCH_PHUB_ROM_START_ADDR_ML7223;
791275640b0STomoya MORINAGA chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_ML7223;
792584ad00cSTomoya MORINAGA } else if (id->driver_data == 5) { /* ML7831 */
79329ddae2aSWei Yongjun ret = sysfs_create_file(&pdev->dev.kobj,
794584ad00cSTomoya MORINAGA &dev_attr_pch_mac.attr);
79529ddae2aSWei Yongjun if (ret)
796584ad00cSTomoya MORINAGA goto err_sysfs_create;
797584ad00cSTomoya MORINAGA
79829ddae2aSWei Yongjun ret = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
79929ddae2aSWei Yongjun if (ret)
800584ad00cSTomoya MORINAGA goto exit_bin_attr;
801584ad00cSTomoya MORINAGA
802584ad00cSTomoya MORINAGA /* set the prefech value */
803584ad00cSTomoya MORINAGA iowrite32(0x000affaa, chip->pch_phub_base_address + 0x14);
804584ad00cSTomoya MORINAGA /* set the interrupt delay value */
805584ad00cSTomoya MORINAGA iowrite32(0x25, chip->pch_phub_base_address + 0x44);
806584ad00cSTomoya MORINAGA chip->pch_opt_rom_start_address = PCH_PHUB_ROM_START_ADDR_EG20T;
807584ad00cSTomoya MORINAGA chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_EG20T;
808c47dda7dSTomoya MORINAGA }
809275640b0STomoya MORINAGA
810275640b0STomoya MORINAGA chip->ioh_type = id->driver_data;
811c47dda7dSTomoya MORINAGA pci_set_drvdata(pdev, chip);
812cf4ece53SMasayuki Ohtak
813cf4ece53SMasayuki Ohtak return 0;
814cf4ece53SMasayuki Ohtak exit_bin_attr:
815cf4ece53SMasayuki Ohtak sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr);
816cf4ece53SMasayuki Ohtak
817cf4ece53SMasayuki Ohtak err_sysfs_create:
818cf4ece53SMasayuki Ohtak pci_iounmap(pdev, chip->pch_phub_base_address);
819cf4ece53SMasayuki Ohtak err_pci_iomap:
820cf4ece53SMasayuki Ohtak pci_release_regions(pdev);
821cf4ece53SMasayuki Ohtak err_req_regions:
822cf4ece53SMasayuki Ohtak pci_disable_device(pdev);
823cf4ece53SMasayuki Ohtak err_pci_enable_dev:
824cf4ece53SMasayuki Ohtak kfree(chip);
825cf4ece53SMasayuki Ohtak dev_err(&pdev->dev, "%s returns %d\n", __func__, ret);
826cf4ece53SMasayuki Ohtak return ret;
827cf4ece53SMasayuki Ohtak }
828cf4ece53SMasayuki Ohtak
pch_phub_remove(struct pci_dev * pdev)829486a5c28SBill Pemberton static void pch_phub_remove(struct pci_dev *pdev)
830cf4ece53SMasayuki Ohtak {
831cf4ece53SMasayuki Ohtak struct pch_phub_reg *chip = pci_get_drvdata(pdev);
832cf4ece53SMasayuki Ohtak
833cf4ece53SMasayuki Ohtak sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr);
834cf4ece53SMasayuki Ohtak sysfs_remove_bin_file(&pdev->dev.kobj, &pch_bin_attr);
835cf4ece53SMasayuki Ohtak pci_iounmap(pdev, chip->pch_phub_base_address);
836cf4ece53SMasayuki Ohtak pci_release_regions(pdev);
837cf4ece53SMasayuki Ohtak pci_disable_device(pdev);
838cf4ece53SMasayuki Ohtak kfree(chip);
839cf4ece53SMasayuki Ohtak }
840cf4ece53SMasayuki Ohtak
pch_phub_suspend(struct device * dev_d)84134afa1d6SVaibhav Gupta static int __maybe_unused pch_phub_suspend(struct device *dev_d)
842cf4ece53SMasayuki Ohtak {
84334afa1d6SVaibhav Gupta device_wakeup_disable(dev_d);
844cf4ece53SMasayuki Ohtak
845cf4ece53SMasayuki Ohtak return 0;
846cf4ece53SMasayuki Ohtak }
847cf4ece53SMasayuki Ohtak
pch_phub_resume(struct device * dev_d)84834afa1d6SVaibhav Gupta static int __maybe_unused pch_phub_resume(struct device *dev_d)
849cf4ece53SMasayuki Ohtak {
85034afa1d6SVaibhav Gupta device_wakeup_disable(dev_d);
851cf4ece53SMasayuki Ohtak
852cf4ece53SMasayuki Ohtak return 0;
853cf4ece53SMasayuki Ohtak }
854cf4ece53SMasayuki Ohtak
855e3b9c5ceSArvind Yadav static const struct pci_device_id pch_phub_pcidev_id[] = {
856c47dda7dSTomoya MORINAGA { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_PCH1_PHUB), 1, },
857c47dda7dSTomoya MORINAGA { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7213_PHUB), 2, },
858275640b0STomoya MORINAGA { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_mPHUB), 3, },
859275640b0STomoya MORINAGA { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_nPHUB), 4, },
860584ad00cSTomoya MORINAGA { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7831_PHUB), 5, },
861c47dda7dSTomoya MORINAGA { }
862cf4ece53SMasayuki Ohtak };
863b2595142SAxel Lin MODULE_DEVICE_TABLE(pci, pch_phub_pcidev_id);
864cf4ece53SMasayuki Ohtak
86534afa1d6SVaibhav Gupta static SIMPLE_DEV_PM_OPS(pch_phub_pm_ops, pch_phub_suspend, pch_phub_resume);
86634afa1d6SVaibhav Gupta
867cf4ece53SMasayuki Ohtak static struct pci_driver pch_phub_driver = {
868cf4ece53SMasayuki Ohtak .name = "pch_phub",
869cf4ece53SMasayuki Ohtak .id_table = pch_phub_pcidev_id,
870cf4ece53SMasayuki Ohtak .probe = pch_phub_probe,
8712d6bed9cSBill Pemberton .remove = pch_phub_remove,
87234afa1d6SVaibhav Gupta .driver.pm = &pch_phub_pm_ops,
873cf4ece53SMasayuki Ohtak };
874cf4ece53SMasayuki Ohtak
875cfeb2852SDevendra Naga module_pci_driver(pch_phub_driver);
876cf4ece53SMasayuki Ohtak
8777f2732c8STomoya MORINAGA MODULE_DESCRIPTION("Intel EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7223) PHUB");
878cf4ece53SMasayuki Ohtak MODULE_LICENSE("GPL");
879