18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2011 LAPIS Semiconductor Co., Ltd. 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#include <linux/module.h> 78c2ecf20Sopenharmony_ci#include <linux/kernel.h> 88c2ecf20Sopenharmony_ci#include <linux/types.h> 98c2ecf20Sopenharmony_ci#include <linux/fs.h> 108c2ecf20Sopenharmony_ci#include <linux/uaccess.h> 118c2ecf20Sopenharmony_ci#include <linux/string.h> 128c2ecf20Sopenharmony_ci#include <linux/pci.h> 138c2ecf20Sopenharmony_ci#include <linux/io.h> 148c2ecf20Sopenharmony_ci#include <linux/delay.h> 158c2ecf20Sopenharmony_ci#include <linux/mutex.h> 168c2ecf20Sopenharmony_ci#include <linux/if_ether.h> 178c2ecf20Sopenharmony_ci#include <linux/ctype.h> 188c2ecf20Sopenharmony_ci#include <linux/dmi.h> 198c2ecf20Sopenharmony_ci#include <linux/of.h> 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci#define PHUB_STATUS 0x00 /* Status Register offset */ 228c2ecf20Sopenharmony_ci#define PHUB_CONTROL 0x04 /* Control Register offset */ 238c2ecf20Sopenharmony_ci#define PHUB_TIMEOUT 0x05 /* Time out value for Status Register */ 248c2ecf20Sopenharmony_ci#define PCH_PHUB_ROM_WRITE_ENABLE 0x01 /* Enabling for writing ROM */ 258c2ecf20Sopenharmony_ci#define PCH_PHUB_ROM_WRITE_DISABLE 0x00 /* Disabling for writing ROM */ 268c2ecf20Sopenharmony_ci#define PCH_PHUB_MAC_START_ADDR_EG20T 0x14 /* MAC data area start address 278c2ecf20Sopenharmony_ci offset */ 288c2ecf20Sopenharmony_ci#define PCH_PHUB_MAC_START_ADDR_ML7223 0x20C /* MAC data area start address 298c2ecf20Sopenharmony_ci offset */ 308c2ecf20Sopenharmony_ci#define PCH_PHUB_ROM_START_ADDR_EG20T 0x80 /* ROM data area start address offset 318c2ecf20Sopenharmony_ci (Intel EG20T PCH)*/ 328c2ecf20Sopenharmony_ci#define PCH_PHUB_ROM_START_ADDR_ML7213 0x400 /* ROM data area start address 338c2ecf20Sopenharmony_ci offset(LAPIS Semicon ML7213) 348c2ecf20Sopenharmony_ci */ 358c2ecf20Sopenharmony_ci#define PCH_PHUB_ROM_START_ADDR_ML7223 0x400 /* ROM data area start address 368c2ecf20Sopenharmony_ci offset(LAPIS Semicon ML7223) 378c2ecf20Sopenharmony_ci */ 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci/* MAX number of INT_REDUCE_CONTROL registers */ 408c2ecf20Sopenharmony_ci#define MAX_NUM_INT_REDUCE_CONTROL_REG 128 418c2ecf20Sopenharmony_ci#define PCI_DEVICE_ID_PCH1_PHUB 0x8801 428c2ecf20Sopenharmony_ci#define PCH_MINOR_NOS 1 438c2ecf20Sopenharmony_ci#define CLKCFG_CAN_50MHZ 0x12000000 448c2ecf20Sopenharmony_ci#define CLKCFG_CANCLK_MASK 0xFF000000 458c2ecf20Sopenharmony_ci#define CLKCFG_UART_MASK 0xFFFFFF 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci/* CM-iTC */ 488c2ecf20Sopenharmony_ci#define CLKCFG_UART_48MHZ (1 << 16) 498c2ecf20Sopenharmony_ci#define CLKCFG_UART_25MHZ (2 << 16) 508c2ecf20Sopenharmony_ci#define CLKCFG_BAUDDIV (2 << 20) 518c2ecf20Sopenharmony_ci#define CLKCFG_PLL2VCO (8 << 9) 528c2ecf20Sopenharmony_ci#define CLKCFG_UARTCLKSEL (1 << 18) 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci/* Macros for ML7213 */ 558c2ecf20Sopenharmony_ci#define PCI_DEVICE_ID_ROHM_ML7213_PHUB 0x801A 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci/* Macros for ML7223 */ 588c2ecf20Sopenharmony_ci#define PCI_DEVICE_ID_ROHM_ML7223_mPHUB 0x8012 /* for Bus-m */ 598c2ecf20Sopenharmony_ci#define PCI_DEVICE_ID_ROHM_ML7223_nPHUB 0x8002 /* for Bus-n */ 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci/* Macros for ML7831 */ 628c2ecf20Sopenharmony_ci#define PCI_DEVICE_ID_ROHM_ML7831_PHUB 0x8801 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci/* SROM ACCESS Macro */ 658c2ecf20Sopenharmony_ci#define PCH_WORD_ADDR_MASK (~((1 << 2) - 1)) 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci/* Registers address offset */ 688c2ecf20Sopenharmony_ci#define PCH_PHUB_ID_REG 0x0000 698c2ecf20Sopenharmony_ci#define PCH_PHUB_QUEUE_PRI_VAL_REG 0x0004 708c2ecf20Sopenharmony_ci#define PCH_PHUB_RC_QUEUE_MAXSIZE_REG 0x0008 718c2ecf20Sopenharmony_ci#define PCH_PHUB_BRI_QUEUE_MAXSIZE_REG 0x000C 728c2ecf20Sopenharmony_ci#define PCH_PHUB_COMP_RESP_TIMEOUT_REG 0x0010 738c2ecf20Sopenharmony_ci#define PCH_PHUB_BUS_SLAVE_CONTROL_REG 0x0014 748c2ecf20Sopenharmony_ci#define PCH_PHUB_DEADLOCK_AVOID_TYPE_REG 0x0018 758c2ecf20Sopenharmony_ci#define PCH_PHUB_INTPIN_REG_WPERMIT_REG0 0x0020 768c2ecf20Sopenharmony_ci#define PCH_PHUB_INTPIN_REG_WPERMIT_REG1 0x0024 778c2ecf20Sopenharmony_ci#define PCH_PHUB_INTPIN_REG_WPERMIT_REG2 0x0028 788c2ecf20Sopenharmony_ci#define PCH_PHUB_INTPIN_REG_WPERMIT_REG3 0x002C 798c2ecf20Sopenharmony_ci#define PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE 0x0040 808c2ecf20Sopenharmony_ci#define CLKCFG_REG_OFFSET 0x500 818c2ecf20Sopenharmony_ci#define FUNCSEL_REG_OFFSET 0x508 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci#define PCH_PHUB_OROM_SIZE 15360 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci/** 868c2ecf20Sopenharmony_ci * struct pch_phub_reg - PHUB register structure 878c2ecf20Sopenharmony_ci * @phub_id_reg: PHUB_ID register val 888c2ecf20Sopenharmony_ci * @q_pri_val_reg: QUEUE_PRI_VAL register val 898c2ecf20Sopenharmony_ci * @rc_q_maxsize_reg: RC_QUEUE_MAXSIZE register val 908c2ecf20Sopenharmony_ci * @bri_q_maxsize_reg: BRI_QUEUE_MAXSIZE register val 918c2ecf20Sopenharmony_ci * @comp_resp_timeout_reg: COMP_RESP_TIMEOUT register val 928c2ecf20Sopenharmony_ci * @bus_slave_control_reg: BUS_SLAVE_CONTROL_REG register val 938c2ecf20Sopenharmony_ci * @deadlock_avoid_type_reg: DEADLOCK_AVOID_TYPE register val 948c2ecf20Sopenharmony_ci * @intpin_reg_wpermit_reg0: INTPIN_REG_WPERMIT register 0 val 958c2ecf20Sopenharmony_ci * @intpin_reg_wpermit_reg1: INTPIN_REG_WPERMIT register 1 val 968c2ecf20Sopenharmony_ci * @intpin_reg_wpermit_reg2: INTPIN_REG_WPERMIT register 2 val 978c2ecf20Sopenharmony_ci * @intpin_reg_wpermit_reg3: INTPIN_REG_WPERMIT register 3 val 988c2ecf20Sopenharmony_ci * @int_reduce_control_reg: INT_REDUCE_CONTROL registers val 998c2ecf20Sopenharmony_ci * @clkcfg_reg: CLK CFG register val 1008c2ecf20Sopenharmony_ci * @funcsel_reg: Function select register value 1018c2ecf20Sopenharmony_ci * @pch_phub_base_address: Register base address 1028c2ecf20Sopenharmony_ci * @pch_phub_extrom_base_address: external rom base address 1038c2ecf20Sopenharmony_ci * @pch_mac_start_address: MAC address area start address 1048c2ecf20Sopenharmony_ci * @pch_opt_rom_start_address: Option ROM start address 1058c2ecf20Sopenharmony_ci * @ioh_type: Save IOH type 1068c2ecf20Sopenharmony_ci * @pdev: pointer to pci device struct 1078c2ecf20Sopenharmony_ci */ 1088c2ecf20Sopenharmony_cistruct pch_phub_reg { 1098c2ecf20Sopenharmony_ci u32 phub_id_reg; 1108c2ecf20Sopenharmony_ci u32 q_pri_val_reg; 1118c2ecf20Sopenharmony_ci u32 rc_q_maxsize_reg; 1128c2ecf20Sopenharmony_ci u32 bri_q_maxsize_reg; 1138c2ecf20Sopenharmony_ci u32 comp_resp_timeout_reg; 1148c2ecf20Sopenharmony_ci u32 bus_slave_control_reg; 1158c2ecf20Sopenharmony_ci u32 deadlock_avoid_type_reg; 1168c2ecf20Sopenharmony_ci u32 intpin_reg_wpermit_reg0; 1178c2ecf20Sopenharmony_ci u32 intpin_reg_wpermit_reg1; 1188c2ecf20Sopenharmony_ci u32 intpin_reg_wpermit_reg2; 1198c2ecf20Sopenharmony_ci u32 intpin_reg_wpermit_reg3; 1208c2ecf20Sopenharmony_ci u32 int_reduce_control_reg[MAX_NUM_INT_REDUCE_CONTROL_REG]; 1218c2ecf20Sopenharmony_ci u32 clkcfg_reg; 1228c2ecf20Sopenharmony_ci u32 funcsel_reg; 1238c2ecf20Sopenharmony_ci void __iomem *pch_phub_base_address; 1248c2ecf20Sopenharmony_ci void __iomem *pch_phub_extrom_base_address; 1258c2ecf20Sopenharmony_ci u32 pch_mac_start_address; 1268c2ecf20Sopenharmony_ci u32 pch_opt_rom_start_address; 1278c2ecf20Sopenharmony_ci int ioh_type; 1288c2ecf20Sopenharmony_ci struct pci_dev *pdev; 1298c2ecf20Sopenharmony_ci}; 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci/* SROM SPEC for MAC address assignment offset */ 1328c2ecf20Sopenharmony_cistatic const int pch_phub_mac_offset[ETH_ALEN] = {0x3, 0x2, 0x1, 0x0, 0xb, 0xa}; 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_cistatic DEFINE_MUTEX(pch_phub_mutex); 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci/** 1378c2ecf20Sopenharmony_ci * pch_phub_read_modify_write_reg() - Reading modifying and writing register 1388c2ecf20Sopenharmony_ci * @chip: Pointer to the PHUB register structure 1398c2ecf20Sopenharmony_ci * @reg_addr_offset: Register offset address value. 1408c2ecf20Sopenharmony_ci * @data: Writing value. 1418c2ecf20Sopenharmony_ci * @mask: Mask value. 1428c2ecf20Sopenharmony_ci */ 1438c2ecf20Sopenharmony_cistatic void pch_phub_read_modify_write_reg(struct pch_phub_reg *chip, 1448c2ecf20Sopenharmony_ci unsigned int reg_addr_offset, 1458c2ecf20Sopenharmony_ci unsigned int data, unsigned int mask) 1468c2ecf20Sopenharmony_ci{ 1478c2ecf20Sopenharmony_ci void __iomem *reg_addr = chip->pch_phub_base_address + reg_addr_offset; 1488c2ecf20Sopenharmony_ci iowrite32(((ioread32(reg_addr) & ~mask)) | data, reg_addr); 1498c2ecf20Sopenharmony_ci} 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci/* pch_phub_save_reg_conf - saves register configuration */ 1528c2ecf20Sopenharmony_cistatic void __maybe_unused pch_phub_save_reg_conf(struct pci_dev *pdev) 1538c2ecf20Sopenharmony_ci{ 1548c2ecf20Sopenharmony_ci unsigned int i; 1558c2ecf20Sopenharmony_ci struct pch_phub_reg *chip = pci_get_drvdata(pdev); 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci void __iomem *p = chip->pch_phub_base_address; 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci chip->phub_id_reg = ioread32(p + PCH_PHUB_ID_REG); 1608c2ecf20Sopenharmony_ci chip->q_pri_val_reg = ioread32(p + PCH_PHUB_QUEUE_PRI_VAL_REG); 1618c2ecf20Sopenharmony_ci chip->rc_q_maxsize_reg = ioread32(p + PCH_PHUB_RC_QUEUE_MAXSIZE_REG); 1628c2ecf20Sopenharmony_ci chip->bri_q_maxsize_reg = ioread32(p + PCH_PHUB_BRI_QUEUE_MAXSIZE_REG); 1638c2ecf20Sopenharmony_ci chip->comp_resp_timeout_reg = 1648c2ecf20Sopenharmony_ci ioread32(p + PCH_PHUB_COMP_RESP_TIMEOUT_REG); 1658c2ecf20Sopenharmony_ci chip->bus_slave_control_reg = 1668c2ecf20Sopenharmony_ci ioread32(p + PCH_PHUB_BUS_SLAVE_CONTROL_REG); 1678c2ecf20Sopenharmony_ci chip->deadlock_avoid_type_reg = 1688c2ecf20Sopenharmony_ci ioread32(p + PCH_PHUB_DEADLOCK_AVOID_TYPE_REG); 1698c2ecf20Sopenharmony_ci chip->intpin_reg_wpermit_reg0 = 1708c2ecf20Sopenharmony_ci ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG0); 1718c2ecf20Sopenharmony_ci chip->intpin_reg_wpermit_reg1 = 1728c2ecf20Sopenharmony_ci ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG1); 1738c2ecf20Sopenharmony_ci chip->intpin_reg_wpermit_reg2 = 1748c2ecf20Sopenharmony_ci ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG2); 1758c2ecf20Sopenharmony_ci chip->intpin_reg_wpermit_reg3 = 1768c2ecf20Sopenharmony_ci ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG3); 1778c2ecf20Sopenharmony_ci dev_dbg(&pdev->dev, "%s : " 1788c2ecf20Sopenharmony_ci "chip->phub_id_reg=%x, " 1798c2ecf20Sopenharmony_ci "chip->q_pri_val_reg=%x, " 1808c2ecf20Sopenharmony_ci "chip->rc_q_maxsize_reg=%x, " 1818c2ecf20Sopenharmony_ci "chip->bri_q_maxsize_reg=%x, " 1828c2ecf20Sopenharmony_ci "chip->comp_resp_timeout_reg=%x, " 1838c2ecf20Sopenharmony_ci "chip->bus_slave_control_reg=%x, " 1848c2ecf20Sopenharmony_ci "chip->deadlock_avoid_type_reg=%x, " 1858c2ecf20Sopenharmony_ci "chip->intpin_reg_wpermit_reg0=%x, " 1868c2ecf20Sopenharmony_ci "chip->intpin_reg_wpermit_reg1=%x, " 1878c2ecf20Sopenharmony_ci "chip->intpin_reg_wpermit_reg2=%x, " 1888c2ecf20Sopenharmony_ci "chip->intpin_reg_wpermit_reg3=%x\n", __func__, 1898c2ecf20Sopenharmony_ci chip->phub_id_reg, 1908c2ecf20Sopenharmony_ci chip->q_pri_val_reg, 1918c2ecf20Sopenharmony_ci chip->rc_q_maxsize_reg, 1928c2ecf20Sopenharmony_ci chip->bri_q_maxsize_reg, 1938c2ecf20Sopenharmony_ci chip->comp_resp_timeout_reg, 1948c2ecf20Sopenharmony_ci chip->bus_slave_control_reg, 1958c2ecf20Sopenharmony_ci chip->deadlock_avoid_type_reg, 1968c2ecf20Sopenharmony_ci chip->intpin_reg_wpermit_reg0, 1978c2ecf20Sopenharmony_ci chip->intpin_reg_wpermit_reg1, 1988c2ecf20Sopenharmony_ci chip->intpin_reg_wpermit_reg2, 1998c2ecf20Sopenharmony_ci chip->intpin_reg_wpermit_reg3); 2008c2ecf20Sopenharmony_ci for (i = 0; i < MAX_NUM_INT_REDUCE_CONTROL_REG; i++) { 2018c2ecf20Sopenharmony_ci chip->int_reduce_control_reg[i] = 2028c2ecf20Sopenharmony_ci ioread32(p + PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE + 4 * i); 2038c2ecf20Sopenharmony_ci dev_dbg(&pdev->dev, "%s : " 2048c2ecf20Sopenharmony_ci "chip->int_reduce_control_reg[%d]=%x\n", 2058c2ecf20Sopenharmony_ci __func__, i, chip->int_reduce_control_reg[i]); 2068c2ecf20Sopenharmony_ci } 2078c2ecf20Sopenharmony_ci chip->clkcfg_reg = ioread32(p + CLKCFG_REG_OFFSET); 2088c2ecf20Sopenharmony_ci if ((chip->ioh_type == 2) || (chip->ioh_type == 4)) 2098c2ecf20Sopenharmony_ci chip->funcsel_reg = ioread32(p + FUNCSEL_REG_OFFSET); 2108c2ecf20Sopenharmony_ci} 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ci/* pch_phub_restore_reg_conf - restore register configuration */ 2138c2ecf20Sopenharmony_cistatic void __maybe_unused pch_phub_restore_reg_conf(struct pci_dev *pdev) 2148c2ecf20Sopenharmony_ci{ 2158c2ecf20Sopenharmony_ci unsigned int i; 2168c2ecf20Sopenharmony_ci struct pch_phub_reg *chip = pci_get_drvdata(pdev); 2178c2ecf20Sopenharmony_ci void __iomem *p; 2188c2ecf20Sopenharmony_ci p = chip->pch_phub_base_address; 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ci iowrite32(chip->phub_id_reg, p + PCH_PHUB_ID_REG); 2218c2ecf20Sopenharmony_ci iowrite32(chip->q_pri_val_reg, p + PCH_PHUB_QUEUE_PRI_VAL_REG); 2228c2ecf20Sopenharmony_ci iowrite32(chip->rc_q_maxsize_reg, p + PCH_PHUB_RC_QUEUE_MAXSIZE_REG); 2238c2ecf20Sopenharmony_ci iowrite32(chip->bri_q_maxsize_reg, p + PCH_PHUB_BRI_QUEUE_MAXSIZE_REG); 2248c2ecf20Sopenharmony_ci iowrite32(chip->comp_resp_timeout_reg, 2258c2ecf20Sopenharmony_ci p + PCH_PHUB_COMP_RESP_TIMEOUT_REG); 2268c2ecf20Sopenharmony_ci iowrite32(chip->bus_slave_control_reg, 2278c2ecf20Sopenharmony_ci p + PCH_PHUB_BUS_SLAVE_CONTROL_REG); 2288c2ecf20Sopenharmony_ci iowrite32(chip->deadlock_avoid_type_reg, 2298c2ecf20Sopenharmony_ci p + PCH_PHUB_DEADLOCK_AVOID_TYPE_REG); 2308c2ecf20Sopenharmony_ci iowrite32(chip->intpin_reg_wpermit_reg0, 2318c2ecf20Sopenharmony_ci p + PCH_PHUB_INTPIN_REG_WPERMIT_REG0); 2328c2ecf20Sopenharmony_ci iowrite32(chip->intpin_reg_wpermit_reg1, 2338c2ecf20Sopenharmony_ci p + PCH_PHUB_INTPIN_REG_WPERMIT_REG1); 2348c2ecf20Sopenharmony_ci iowrite32(chip->intpin_reg_wpermit_reg2, 2358c2ecf20Sopenharmony_ci p + PCH_PHUB_INTPIN_REG_WPERMIT_REG2); 2368c2ecf20Sopenharmony_ci iowrite32(chip->intpin_reg_wpermit_reg3, 2378c2ecf20Sopenharmony_ci p + PCH_PHUB_INTPIN_REG_WPERMIT_REG3); 2388c2ecf20Sopenharmony_ci dev_dbg(&pdev->dev, "%s : " 2398c2ecf20Sopenharmony_ci "chip->phub_id_reg=%x, " 2408c2ecf20Sopenharmony_ci "chip->q_pri_val_reg=%x, " 2418c2ecf20Sopenharmony_ci "chip->rc_q_maxsize_reg=%x, " 2428c2ecf20Sopenharmony_ci "chip->bri_q_maxsize_reg=%x, " 2438c2ecf20Sopenharmony_ci "chip->comp_resp_timeout_reg=%x, " 2448c2ecf20Sopenharmony_ci "chip->bus_slave_control_reg=%x, " 2458c2ecf20Sopenharmony_ci "chip->deadlock_avoid_type_reg=%x, " 2468c2ecf20Sopenharmony_ci "chip->intpin_reg_wpermit_reg0=%x, " 2478c2ecf20Sopenharmony_ci "chip->intpin_reg_wpermit_reg1=%x, " 2488c2ecf20Sopenharmony_ci "chip->intpin_reg_wpermit_reg2=%x, " 2498c2ecf20Sopenharmony_ci "chip->intpin_reg_wpermit_reg3=%x\n", __func__, 2508c2ecf20Sopenharmony_ci chip->phub_id_reg, 2518c2ecf20Sopenharmony_ci chip->q_pri_val_reg, 2528c2ecf20Sopenharmony_ci chip->rc_q_maxsize_reg, 2538c2ecf20Sopenharmony_ci chip->bri_q_maxsize_reg, 2548c2ecf20Sopenharmony_ci chip->comp_resp_timeout_reg, 2558c2ecf20Sopenharmony_ci chip->bus_slave_control_reg, 2568c2ecf20Sopenharmony_ci chip->deadlock_avoid_type_reg, 2578c2ecf20Sopenharmony_ci chip->intpin_reg_wpermit_reg0, 2588c2ecf20Sopenharmony_ci chip->intpin_reg_wpermit_reg1, 2598c2ecf20Sopenharmony_ci chip->intpin_reg_wpermit_reg2, 2608c2ecf20Sopenharmony_ci chip->intpin_reg_wpermit_reg3); 2618c2ecf20Sopenharmony_ci for (i = 0; i < MAX_NUM_INT_REDUCE_CONTROL_REG; i++) { 2628c2ecf20Sopenharmony_ci iowrite32(chip->int_reduce_control_reg[i], 2638c2ecf20Sopenharmony_ci p + PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE + 4 * i); 2648c2ecf20Sopenharmony_ci dev_dbg(&pdev->dev, "%s : " 2658c2ecf20Sopenharmony_ci "chip->int_reduce_control_reg[%d]=%x\n", 2668c2ecf20Sopenharmony_ci __func__, i, chip->int_reduce_control_reg[i]); 2678c2ecf20Sopenharmony_ci } 2688c2ecf20Sopenharmony_ci 2698c2ecf20Sopenharmony_ci iowrite32(chip->clkcfg_reg, p + CLKCFG_REG_OFFSET); 2708c2ecf20Sopenharmony_ci if ((chip->ioh_type == 2) || (chip->ioh_type == 4)) 2718c2ecf20Sopenharmony_ci iowrite32(chip->funcsel_reg, p + FUNCSEL_REG_OFFSET); 2728c2ecf20Sopenharmony_ci} 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci/** 2758c2ecf20Sopenharmony_ci * pch_phub_read_serial_rom() - Reading Serial ROM 2768c2ecf20Sopenharmony_ci * @chip: Pointer to the PHUB register structure 2778c2ecf20Sopenharmony_ci * @offset_address: Serial ROM offset address to read. 2788c2ecf20Sopenharmony_ci * @data: Read buffer for specified Serial ROM value. 2798c2ecf20Sopenharmony_ci */ 2808c2ecf20Sopenharmony_cistatic void pch_phub_read_serial_rom(struct pch_phub_reg *chip, 2818c2ecf20Sopenharmony_ci unsigned int offset_address, u8 *data) 2828c2ecf20Sopenharmony_ci{ 2838c2ecf20Sopenharmony_ci void __iomem *mem_addr = chip->pch_phub_extrom_base_address + 2848c2ecf20Sopenharmony_ci offset_address; 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_ci *data = ioread8(mem_addr); 2878c2ecf20Sopenharmony_ci} 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_ci/** 2908c2ecf20Sopenharmony_ci * pch_phub_write_serial_rom() - Writing Serial ROM 2918c2ecf20Sopenharmony_ci * @chip: Pointer to the PHUB register structure 2928c2ecf20Sopenharmony_ci * @offset_address: Serial ROM offset address. 2938c2ecf20Sopenharmony_ci * @data: Serial ROM value to write. 2948c2ecf20Sopenharmony_ci */ 2958c2ecf20Sopenharmony_cistatic int pch_phub_write_serial_rom(struct pch_phub_reg *chip, 2968c2ecf20Sopenharmony_ci unsigned int offset_address, u8 data) 2978c2ecf20Sopenharmony_ci{ 2988c2ecf20Sopenharmony_ci void __iomem *mem_addr = chip->pch_phub_extrom_base_address + 2998c2ecf20Sopenharmony_ci (offset_address & PCH_WORD_ADDR_MASK); 3008c2ecf20Sopenharmony_ci int i; 3018c2ecf20Sopenharmony_ci unsigned int word_data; 3028c2ecf20Sopenharmony_ci unsigned int pos; 3038c2ecf20Sopenharmony_ci unsigned int mask; 3048c2ecf20Sopenharmony_ci pos = (offset_address % 4) * 8; 3058c2ecf20Sopenharmony_ci mask = ~(0xFF << pos); 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_ci iowrite32(PCH_PHUB_ROM_WRITE_ENABLE, 3088c2ecf20Sopenharmony_ci chip->pch_phub_extrom_base_address + PHUB_CONTROL); 3098c2ecf20Sopenharmony_ci 3108c2ecf20Sopenharmony_ci word_data = ioread32(mem_addr); 3118c2ecf20Sopenharmony_ci iowrite32((word_data & mask) | (u32)data << pos, mem_addr); 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_ci i = 0; 3148c2ecf20Sopenharmony_ci while (ioread8(chip->pch_phub_extrom_base_address + 3158c2ecf20Sopenharmony_ci PHUB_STATUS) != 0x00) { 3168c2ecf20Sopenharmony_ci msleep(1); 3178c2ecf20Sopenharmony_ci if (i == PHUB_TIMEOUT) 3188c2ecf20Sopenharmony_ci return -ETIMEDOUT; 3198c2ecf20Sopenharmony_ci i++; 3208c2ecf20Sopenharmony_ci } 3218c2ecf20Sopenharmony_ci 3228c2ecf20Sopenharmony_ci iowrite32(PCH_PHUB_ROM_WRITE_DISABLE, 3238c2ecf20Sopenharmony_ci chip->pch_phub_extrom_base_address + PHUB_CONTROL); 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ci return 0; 3268c2ecf20Sopenharmony_ci} 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_ci/** 3298c2ecf20Sopenharmony_ci * pch_phub_read_serial_rom_val() - Read Serial ROM value 3308c2ecf20Sopenharmony_ci * @chip: Pointer to the PHUB register structure 3318c2ecf20Sopenharmony_ci * @offset_address: Serial ROM address offset value. 3328c2ecf20Sopenharmony_ci * @data: Serial ROM value to read. 3338c2ecf20Sopenharmony_ci */ 3348c2ecf20Sopenharmony_cistatic void pch_phub_read_serial_rom_val(struct pch_phub_reg *chip, 3358c2ecf20Sopenharmony_ci unsigned int offset_address, u8 *data) 3368c2ecf20Sopenharmony_ci{ 3378c2ecf20Sopenharmony_ci unsigned int mem_addr; 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci mem_addr = chip->pch_mac_start_address + 3408c2ecf20Sopenharmony_ci pch_phub_mac_offset[offset_address]; 3418c2ecf20Sopenharmony_ci 3428c2ecf20Sopenharmony_ci pch_phub_read_serial_rom(chip, mem_addr, data); 3438c2ecf20Sopenharmony_ci} 3448c2ecf20Sopenharmony_ci 3458c2ecf20Sopenharmony_ci/** 3468c2ecf20Sopenharmony_ci * pch_phub_write_serial_rom_val() - writing Serial ROM value 3478c2ecf20Sopenharmony_ci * @chip: Pointer to the PHUB register structure 3488c2ecf20Sopenharmony_ci * @offset_address: Serial ROM address offset value. 3498c2ecf20Sopenharmony_ci * @data: Serial ROM value. 3508c2ecf20Sopenharmony_ci */ 3518c2ecf20Sopenharmony_cistatic int pch_phub_write_serial_rom_val(struct pch_phub_reg *chip, 3528c2ecf20Sopenharmony_ci unsigned int offset_address, u8 data) 3538c2ecf20Sopenharmony_ci{ 3548c2ecf20Sopenharmony_ci int retval; 3558c2ecf20Sopenharmony_ci unsigned int mem_addr; 3568c2ecf20Sopenharmony_ci 3578c2ecf20Sopenharmony_ci mem_addr = chip->pch_mac_start_address + 3588c2ecf20Sopenharmony_ci pch_phub_mac_offset[offset_address]; 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ci retval = pch_phub_write_serial_rom(chip, mem_addr, data); 3618c2ecf20Sopenharmony_ci 3628c2ecf20Sopenharmony_ci return retval; 3638c2ecf20Sopenharmony_ci} 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_ci/* pch_phub_gbe_serial_rom_conf - makes Serial ROM header format configuration 3668c2ecf20Sopenharmony_ci * for Gigabit Ethernet MAC address 3678c2ecf20Sopenharmony_ci */ 3688c2ecf20Sopenharmony_cistatic int pch_phub_gbe_serial_rom_conf(struct pch_phub_reg *chip) 3698c2ecf20Sopenharmony_ci{ 3708c2ecf20Sopenharmony_ci int retval; 3718c2ecf20Sopenharmony_ci 3728c2ecf20Sopenharmony_ci retval = pch_phub_write_serial_rom(chip, 0x0b, 0xbc); 3738c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x0a, 0x10); 3748c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x09, 0x01); 3758c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x08, 0x02); 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x0f, 0x00); 3788c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x0e, 0x00); 3798c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x0d, 0x00); 3808c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x0c, 0x80); 3818c2ecf20Sopenharmony_ci 3828c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x13, 0xbc); 3838c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x12, 0x10); 3848c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x11, 0x01); 3858c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x10, 0x18); 3868c2ecf20Sopenharmony_ci 3878c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x1b, 0xbc); 3888c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x1a, 0x10); 3898c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x19, 0x01); 3908c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x18, 0x19); 3918c2ecf20Sopenharmony_ci 3928c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x23, 0xbc); 3938c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x22, 0x10); 3948c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x21, 0x01); 3958c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x20, 0x3a); 3968c2ecf20Sopenharmony_ci 3978c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x27, 0x01); 3988c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x26, 0x00); 3998c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x25, 0x00); 4008c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x24, 0x00); 4018c2ecf20Sopenharmony_ci 4028c2ecf20Sopenharmony_ci return retval; 4038c2ecf20Sopenharmony_ci} 4048c2ecf20Sopenharmony_ci 4058c2ecf20Sopenharmony_ci/* pch_phub_gbe_serial_rom_conf_mp - makes SerialROM header format configuration 4068c2ecf20Sopenharmony_ci * for Gigabit Ethernet MAC address 4078c2ecf20Sopenharmony_ci */ 4088c2ecf20Sopenharmony_cistatic int pch_phub_gbe_serial_rom_conf_mp(struct pch_phub_reg *chip) 4098c2ecf20Sopenharmony_ci{ 4108c2ecf20Sopenharmony_ci int retval; 4118c2ecf20Sopenharmony_ci u32 offset_addr; 4128c2ecf20Sopenharmony_ci 4138c2ecf20Sopenharmony_ci offset_addr = 0x200; 4148c2ecf20Sopenharmony_ci retval = pch_phub_write_serial_rom(chip, 0x03 + offset_addr, 0xbc); 4158c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x02 + offset_addr, 0x00); 4168c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x01 + offset_addr, 0x40); 4178c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x00 + offset_addr, 0x02); 4188c2ecf20Sopenharmony_ci 4198c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x07 + offset_addr, 0x00); 4208c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x06 + offset_addr, 0x00); 4218c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x05 + offset_addr, 0x00); 4228c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x04 + offset_addr, 0x80); 4238c2ecf20Sopenharmony_ci 4248c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x0b + offset_addr, 0xbc); 4258c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x0a + offset_addr, 0x00); 4268c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x09 + offset_addr, 0x40); 4278c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x08 + offset_addr, 0x18); 4288c2ecf20Sopenharmony_ci 4298c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x13 + offset_addr, 0xbc); 4308c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x12 + offset_addr, 0x00); 4318c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x11 + offset_addr, 0x40); 4328c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x10 + offset_addr, 0x19); 4338c2ecf20Sopenharmony_ci 4348c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x1b + offset_addr, 0xbc); 4358c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x1a + offset_addr, 0x00); 4368c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x19 + offset_addr, 0x40); 4378c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x18 + offset_addr, 0x3a); 4388c2ecf20Sopenharmony_ci 4398c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x1f + offset_addr, 0x01); 4408c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x1e + offset_addr, 0x00); 4418c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x1d + offset_addr, 0x00); 4428c2ecf20Sopenharmony_ci retval |= pch_phub_write_serial_rom(chip, 0x1c + offset_addr, 0x00); 4438c2ecf20Sopenharmony_ci 4448c2ecf20Sopenharmony_ci return retval; 4458c2ecf20Sopenharmony_ci} 4468c2ecf20Sopenharmony_ci 4478c2ecf20Sopenharmony_ci/** 4488c2ecf20Sopenharmony_ci * pch_phub_read_gbe_mac_addr() - Read Gigabit Ethernet MAC address 4498c2ecf20Sopenharmony_ci * @chip: Pointer to the PHUB register structure 4508c2ecf20Sopenharmony_ci * @data: Buffer of the Gigabit Ethernet MAC address value. 4518c2ecf20Sopenharmony_ci */ 4528c2ecf20Sopenharmony_cistatic void pch_phub_read_gbe_mac_addr(struct pch_phub_reg *chip, u8 *data) 4538c2ecf20Sopenharmony_ci{ 4548c2ecf20Sopenharmony_ci int i; 4558c2ecf20Sopenharmony_ci for (i = 0; i < ETH_ALEN; i++) 4568c2ecf20Sopenharmony_ci pch_phub_read_serial_rom_val(chip, i, &data[i]); 4578c2ecf20Sopenharmony_ci} 4588c2ecf20Sopenharmony_ci 4598c2ecf20Sopenharmony_ci/** 4608c2ecf20Sopenharmony_ci * pch_phub_write_gbe_mac_addr() - Write MAC address 4618c2ecf20Sopenharmony_ci * @chip: Pointer to the PHUB register structure 4628c2ecf20Sopenharmony_ci * @data: Gigabit Ethernet MAC address value. 4638c2ecf20Sopenharmony_ci */ 4648c2ecf20Sopenharmony_cistatic int pch_phub_write_gbe_mac_addr(struct pch_phub_reg *chip, u8 *data) 4658c2ecf20Sopenharmony_ci{ 4668c2ecf20Sopenharmony_ci int retval; 4678c2ecf20Sopenharmony_ci int i; 4688c2ecf20Sopenharmony_ci 4698c2ecf20Sopenharmony_ci if ((chip->ioh_type == 1) || (chip->ioh_type == 5)) /* EG20T or ML7831*/ 4708c2ecf20Sopenharmony_ci retval = pch_phub_gbe_serial_rom_conf(chip); 4718c2ecf20Sopenharmony_ci else /* ML7223 */ 4728c2ecf20Sopenharmony_ci retval = pch_phub_gbe_serial_rom_conf_mp(chip); 4738c2ecf20Sopenharmony_ci if (retval) 4748c2ecf20Sopenharmony_ci return retval; 4758c2ecf20Sopenharmony_ci 4768c2ecf20Sopenharmony_ci for (i = 0; i < ETH_ALEN; i++) { 4778c2ecf20Sopenharmony_ci retval = pch_phub_write_serial_rom_val(chip, i, data[i]); 4788c2ecf20Sopenharmony_ci if (retval) 4798c2ecf20Sopenharmony_ci return retval; 4808c2ecf20Sopenharmony_ci } 4818c2ecf20Sopenharmony_ci 4828c2ecf20Sopenharmony_ci return retval; 4838c2ecf20Sopenharmony_ci} 4848c2ecf20Sopenharmony_ci 4858c2ecf20Sopenharmony_cistatic ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj, 4868c2ecf20Sopenharmony_ci struct bin_attribute *attr, char *buf, 4878c2ecf20Sopenharmony_ci loff_t off, size_t count) 4888c2ecf20Sopenharmony_ci{ 4898c2ecf20Sopenharmony_ci unsigned int rom_signature; 4908c2ecf20Sopenharmony_ci unsigned char rom_length; 4918c2ecf20Sopenharmony_ci unsigned int tmp; 4928c2ecf20Sopenharmony_ci unsigned int addr_offset; 4938c2ecf20Sopenharmony_ci unsigned int orom_size; 4948c2ecf20Sopenharmony_ci int ret; 4958c2ecf20Sopenharmony_ci int err; 4968c2ecf20Sopenharmony_ci ssize_t rom_size; 4978c2ecf20Sopenharmony_ci 4988c2ecf20Sopenharmony_ci struct pch_phub_reg *chip = dev_get_drvdata(kobj_to_dev(kobj)); 4998c2ecf20Sopenharmony_ci 5008c2ecf20Sopenharmony_ci ret = mutex_lock_interruptible(&pch_phub_mutex); 5018c2ecf20Sopenharmony_ci if (ret) { 5028c2ecf20Sopenharmony_ci err = -ERESTARTSYS; 5038c2ecf20Sopenharmony_ci goto return_err_nomutex; 5048c2ecf20Sopenharmony_ci } 5058c2ecf20Sopenharmony_ci 5068c2ecf20Sopenharmony_ci /* Get Rom signature */ 5078c2ecf20Sopenharmony_ci chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size); 5088c2ecf20Sopenharmony_ci if (!chip->pch_phub_extrom_base_address) { 5098c2ecf20Sopenharmony_ci err = -ENODATA; 5108c2ecf20Sopenharmony_ci goto exrom_map_err; 5118c2ecf20Sopenharmony_ci } 5128c2ecf20Sopenharmony_ci 5138c2ecf20Sopenharmony_ci pch_phub_read_serial_rom(chip, chip->pch_opt_rom_start_address, 5148c2ecf20Sopenharmony_ci (unsigned char *)&rom_signature); 5158c2ecf20Sopenharmony_ci rom_signature &= 0xff; 5168c2ecf20Sopenharmony_ci pch_phub_read_serial_rom(chip, chip->pch_opt_rom_start_address + 1, 5178c2ecf20Sopenharmony_ci (unsigned char *)&tmp); 5188c2ecf20Sopenharmony_ci rom_signature |= (tmp & 0xff) << 8; 5198c2ecf20Sopenharmony_ci if (rom_signature == 0xAA55) { 5208c2ecf20Sopenharmony_ci pch_phub_read_serial_rom(chip, 5218c2ecf20Sopenharmony_ci chip->pch_opt_rom_start_address + 2, 5228c2ecf20Sopenharmony_ci &rom_length); 5238c2ecf20Sopenharmony_ci orom_size = rom_length * 512; 5248c2ecf20Sopenharmony_ci if (orom_size < off) { 5258c2ecf20Sopenharmony_ci addr_offset = 0; 5268c2ecf20Sopenharmony_ci goto return_ok; 5278c2ecf20Sopenharmony_ci } 5288c2ecf20Sopenharmony_ci if (orom_size < count) { 5298c2ecf20Sopenharmony_ci addr_offset = 0; 5308c2ecf20Sopenharmony_ci goto return_ok; 5318c2ecf20Sopenharmony_ci } 5328c2ecf20Sopenharmony_ci 5338c2ecf20Sopenharmony_ci for (addr_offset = 0; addr_offset < count; addr_offset++) { 5348c2ecf20Sopenharmony_ci pch_phub_read_serial_rom(chip, 5358c2ecf20Sopenharmony_ci chip->pch_opt_rom_start_address + addr_offset + off, 5368c2ecf20Sopenharmony_ci &buf[addr_offset]); 5378c2ecf20Sopenharmony_ci } 5388c2ecf20Sopenharmony_ci } else { 5398c2ecf20Sopenharmony_ci err = -ENODATA; 5408c2ecf20Sopenharmony_ci goto return_err; 5418c2ecf20Sopenharmony_ci } 5428c2ecf20Sopenharmony_cireturn_ok: 5438c2ecf20Sopenharmony_ci pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); 5448c2ecf20Sopenharmony_ci mutex_unlock(&pch_phub_mutex); 5458c2ecf20Sopenharmony_ci return addr_offset; 5468c2ecf20Sopenharmony_ci 5478c2ecf20Sopenharmony_cireturn_err: 5488c2ecf20Sopenharmony_ci pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); 5498c2ecf20Sopenharmony_ciexrom_map_err: 5508c2ecf20Sopenharmony_ci mutex_unlock(&pch_phub_mutex); 5518c2ecf20Sopenharmony_cireturn_err_nomutex: 5528c2ecf20Sopenharmony_ci return err; 5538c2ecf20Sopenharmony_ci} 5548c2ecf20Sopenharmony_ci 5558c2ecf20Sopenharmony_cistatic ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj, 5568c2ecf20Sopenharmony_ci struct bin_attribute *attr, 5578c2ecf20Sopenharmony_ci char *buf, loff_t off, size_t count) 5588c2ecf20Sopenharmony_ci{ 5598c2ecf20Sopenharmony_ci int err; 5608c2ecf20Sopenharmony_ci unsigned int addr_offset; 5618c2ecf20Sopenharmony_ci int ret; 5628c2ecf20Sopenharmony_ci ssize_t rom_size; 5638c2ecf20Sopenharmony_ci struct pch_phub_reg *chip = dev_get_drvdata(kobj_to_dev(kobj)); 5648c2ecf20Sopenharmony_ci 5658c2ecf20Sopenharmony_ci ret = mutex_lock_interruptible(&pch_phub_mutex); 5668c2ecf20Sopenharmony_ci if (ret) 5678c2ecf20Sopenharmony_ci return -ERESTARTSYS; 5688c2ecf20Sopenharmony_ci 5698c2ecf20Sopenharmony_ci if (off > PCH_PHUB_OROM_SIZE) { 5708c2ecf20Sopenharmony_ci addr_offset = 0; 5718c2ecf20Sopenharmony_ci goto return_ok; 5728c2ecf20Sopenharmony_ci } 5738c2ecf20Sopenharmony_ci if (count > PCH_PHUB_OROM_SIZE) { 5748c2ecf20Sopenharmony_ci addr_offset = 0; 5758c2ecf20Sopenharmony_ci goto return_ok; 5768c2ecf20Sopenharmony_ci } 5778c2ecf20Sopenharmony_ci 5788c2ecf20Sopenharmony_ci chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size); 5798c2ecf20Sopenharmony_ci if (!chip->pch_phub_extrom_base_address) { 5808c2ecf20Sopenharmony_ci err = -ENOMEM; 5818c2ecf20Sopenharmony_ci goto exrom_map_err; 5828c2ecf20Sopenharmony_ci } 5838c2ecf20Sopenharmony_ci 5848c2ecf20Sopenharmony_ci for (addr_offset = 0; addr_offset < count; addr_offset++) { 5858c2ecf20Sopenharmony_ci if (PCH_PHUB_OROM_SIZE < off + addr_offset) 5868c2ecf20Sopenharmony_ci goto return_ok; 5878c2ecf20Sopenharmony_ci 5888c2ecf20Sopenharmony_ci ret = pch_phub_write_serial_rom(chip, 5898c2ecf20Sopenharmony_ci chip->pch_opt_rom_start_address + addr_offset + off, 5908c2ecf20Sopenharmony_ci buf[addr_offset]); 5918c2ecf20Sopenharmony_ci if (ret) { 5928c2ecf20Sopenharmony_ci err = ret; 5938c2ecf20Sopenharmony_ci goto return_err; 5948c2ecf20Sopenharmony_ci } 5958c2ecf20Sopenharmony_ci } 5968c2ecf20Sopenharmony_ci 5978c2ecf20Sopenharmony_cireturn_ok: 5988c2ecf20Sopenharmony_ci pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); 5998c2ecf20Sopenharmony_ci mutex_unlock(&pch_phub_mutex); 6008c2ecf20Sopenharmony_ci return addr_offset; 6018c2ecf20Sopenharmony_ci 6028c2ecf20Sopenharmony_cireturn_err: 6038c2ecf20Sopenharmony_ci pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); 6048c2ecf20Sopenharmony_ci 6058c2ecf20Sopenharmony_ciexrom_map_err: 6068c2ecf20Sopenharmony_ci mutex_unlock(&pch_phub_mutex); 6078c2ecf20Sopenharmony_ci return err; 6088c2ecf20Sopenharmony_ci} 6098c2ecf20Sopenharmony_ci 6108c2ecf20Sopenharmony_cistatic ssize_t show_pch_mac(struct device *dev, struct device_attribute *attr, 6118c2ecf20Sopenharmony_ci char *buf) 6128c2ecf20Sopenharmony_ci{ 6138c2ecf20Sopenharmony_ci u8 mac[8]; 6148c2ecf20Sopenharmony_ci struct pch_phub_reg *chip = dev_get_drvdata(dev); 6158c2ecf20Sopenharmony_ci ssize_t rom_size; 6168c2ecf20Sopenharmony_ci 6178c2ecf20Sopenharmony_ci chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size); 6188c2ecf20Sopenharmony_ci if (!chip->pch_phub_extrom_base_address) 6198c2ecf20Sopenharmony_ci return -ENOMEM; 6208c2ecf20Sopenharmony_ci 6218c2ecf20Sopenharmony_ci pch_phub_read_gbe_mac_addr(chip, mac); 6228c2ecf20Sopenharmony_ci pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); 6238c2ecf20Sopenharmony_ci 6248c2ecf20Sopenharmony_ci return sprintf(buf, "%pM\n", mac); 6258c2ecf20Sopenharmony_ci} 6268c2ecf20Sopenharmony_ci 6278c2ecf20Sopenharmony_cistatic ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr, 6288c2ecf20Sopenharmony_ci const char *buf, size_t count) 6298c2ecf20Sopenharmony_ci{ 6308c2ecf20Sopenharmony_ci u8 mac[ETH_ALEN]; 6318c2ecf20Sopenharmony_ci ssize_t rom_size; 6328c2ecf20Sopenharmony_ci struct pch_phub_reg *chip = dev_get_drvdata(dev); 6338c2ecf20Sopenharmony_ci int ret; 6348c2ecf20Sopenharmony_ci 6358c2ecf20Sopenharmony_ci if (!mac_pton(buf, mac)) 6368c2ecf20Sopenharmony_ci return -EINVAL; 6378c2ecf20Sopenharmony_ci 6388c2ecf20Sopenharmony_ci chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size); 6398c2ecf20Sopenharmony_ci if (!chip->pch_phub_extrom_base_address) 6408c2ecf20Sopenharmony_ci return -ENOMEM; 6418c2ecf20Sopenharmony_ci 6428c2ecf20Sopenharmony_ci ret = pch_phub_write_gbe_mac_addr(chip, mac); 6438c2ecf20Sopenharmony_ci pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); 6448c2ecf20Sopenharmony_ci if (ret) 6458c2ecf20Sopenharmony_ci return ret; 6468c2ecf20Sopenharmony_ci 6478c2ecf20Sopenharmony_ci return count; 6488c2ecf20Sopenharmony_ci} 6498c2ecf20Sopenharmony_ci 6508c2ecf20Sopenharmony_cistatic DEVICE_ATTR(pch_mac, S_IRUGO | S_IWUSR, show_pch_mac, store_pch_mac); 6518c2ecf20Sopenharmony_ci 6528c2ecf20Sopenharmony_cistatic const struct bin_attribute pch_bin_attr = { 6538c2ecf20Sopenharmony_ci .attr = { 6548c2ecf20Sopenharmony_ci .name = "pch_firmware", 6558c2ecf20Sopenharmony_ci .mode = S_IRUGO | S_IWUSR, 6568c2ecf20Sopenharmony_ci }, 6578c2ecf20Sopenharmony_ci .size = PCH_PHUB_OROM_SIZE + 1, 6588c2ecf20Sopenharmony_ci .read = pch_phub_bin_read, 6598c2ecf20Sopenharmony_ci .write = pch_phub_bin_write, 6608c2ecf20Sopenharmony_ci}; 6618c2ecf20Sopenharmony_ci 6628c2ecf20Sopenharmony_cistatic int pch_phub_probe(struct pci_dev *pdev, 6638c2ecf20Sopenharmony_ci const struct pci_device_id *id) 6648c2ecf20Sopenharmony_ci{ 6658c2ecf20Sopenharmony_ci int ret; 6668c2ecf20Sopenharmony_ci struct pch_phub_reg *chip; 6678c2ecf20Sopenharmony_ci 6688c2ecf20Sopenharmony_ci chip = kzalloc(sizeof(struct pch_phub_reg), GFP_KERNEL); 6698c2ecf20Sopenharmony_ci if (chip == NULL) 6708c2ecf20Sopenharmony_ci return -ENOMEM; 6718c2ecf20Sopenharmony_ci 6728c2ecf20Sopenharmony_ci ret = pci_enable_device(pdev); 6738c2ecf20Sopenharmony_ci if (ret) { 6748c2ecf20Sopenharmony_ci dev_err(&pdev->dev, 6758c2ecf20Sopenharmony_ci "%s : pci_enable_device FAILED(ret=%d)", __func__, ret); 6768c2ecf20Sopenharmony_ci goto err_pci_enable_dev; 6778c2ecf20Sopenharmony_ci } 6788c2ecf20Sopenharmony_ci dev_dbg(&pdev->dev, "%s : pci_enable_device returns %d\n", __func__, 6798c2ecf20Sopenharmony_ci ret); 6808c2ecf20Sopenharmony_ci 6818c2ecf20Sopenharmony_ci ret = pci_request_regions(pdev, KBUILD_MODNAME); 6828c2ecf20Sopenharmony_ci if (ret) { 6838c2ecf20Sopenharmony_ci dev_err(&pdev->dev, 6848c2ecf20Sopenharmony_ci "%s : pci_request_regions FAILED(ret=%d)", __func__, ret); 6858c2ecf20Sopenharmony_ci goto err_req_regions; 6868c2ecf20Sopenharmony_ci } 6878c2ecf20Sopenharmony_ci dev_dbg(&pdev->dev, "%s : " 6888c2ecf20Sopenharmony_ci "pci_request_regions returns %d\n", __func__, ret); 6898c2ecf20Sopenharmony_ci 6908c2ecf20Sopenharmony_ci chip->pch_phub_base_address = pci_iomap(pdev, 1, 0); 6918c2ecf20Sopenharmony_ci 6928c2ecf20Sopenharmony_ci 6938c2ecf20Sopenharmony_ci if (chip->pch_phub_base_address == NULL) { 6948c2ecf20Sopenharmony_ci dev_err(&pdev->dev, "%s : pci_iomap FAILED", __func__); 6958c2ecf20Sopenharmony_ci ret = -ENOMEM; 6968c2ecf20Sopenharmony_ci goto err_pci_iomap; 6978c2ecf20Sopenharmony_ci } 6988c2ecf20Sopenharmony_ci dev_dbg(&pdev->dev, "%s : pci_iomap SUCCESS and value " 6998c2ecf20Sopenharmony_ci "in pch_phub_base_address variable is %p\n", __func__, 7008c2ecf20Sopenharmony_ci chip->pch_phub_base_address); 7018c2ecf20Sopenharmony_ci 7028c2ecf20Sopenharmony_ci chip->pdev = pdev; /* Save pci device struct */ 7038c2ecf20Sopenharmony_ci 7048c2ecf20Sopenharmony_ci if (id->driver_data == 1) { /* EG20T PCH */ 7058c2ecf20Sopenharmony_ci const char *board_name; 7068c2ecf20Sopenharmony_ci unsigned int prefetch = 0x000affaa; 7078c2ecf20Sopenharmony_ci 7088c2ecf20Sopenharmony_ci if (pdev->dev.of_node) 7098c2ecf20Sopenharmony_ci of_property_read_u32(pdev->dev.of_node, 7108c2ecf20Sopenharmony_ci "intel,eg20t-prefetch", 7118c2ecf20Sopenharmony_ci &prefetch); 7128c2ecf20Sopenharmony_ci 7138c2ecf20Sopenharmony_ci ret = sysfs_create_file(&pdev->dev.kobj, 7148c2ecf20Sopenharmony_ci &dev_attr_pch_mac.attr); 7158c2ecf20Sopenharmony_ci if (ret) 7168c2ecf20Sopenharmony_ci goto err_sysfs_create; 7178c2ecf20Sopenharmony_ci 7188c2ecf20Sopenharmony_ci ret = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr); 7198c2ecf20Sopenharmony_ci if (ret) 7208c2ecf20Sopenharmony_ci goto exit_bin_attr; 7218c2ecf20Sopenharmony_ci 7228c2ecf20Sopenharmony_ci pch_phub_read_modify_write_reg(chip, 7238c2ecf20Sopenharmony_ci (unsigned int)CLKCFG_REG_OFFSET, 7248c2ecf20Sopenharmony_ci CLKCFG_CAN_50MHZ, 7258c2ecf20Sopenharmony_ci CLKCFG_CANCLK_MASK); 7268c2ecf20Sopenharmony_ci 7278c2ecf20Sopenharmony_ci /* quirk for CM-iTC board */ 7288c2ecf20Sopenharmony_ci board_name = dmi_get_system_info(DMI_BOARD_NAME); 7298c2ecf20Sopenharmony_ci if (board_name && strstr(board_name, "CM-iTC")) 7308c2ecf20Sopenharmony_ci pch_phub_read_modify_write_reg(chip, 7318c2ecf20Sopenharmony_ci (unsigned int)CLKCFG_REG_OFFSET, 7328c2ecf20Sopenharmony_ci CLKCFG_UART_48MHZ | CLKCFG_BAUDDIV | 7338c2ecf20Sopenharmony_ci CLKCFG_PLL2VCO | CLKCFG_UARTCLKSEL, 7348c2ecf20Sopenharmony_ci CLKCFG_UART_MASK); 7358c2ecf20Sopenharmony_ci 7368c2ecf20Sopenharmony_ci /* set the prefech value */ 7378c2ecf20Sopenharmony_ci iowrite32(prefetch, chip->pch_phub_base_address + 0x14); 7388c2ecf20Sopenharmony_ci /* set the interrupt delay value */ 7398c2ecf20Sopenharmony_ci iowrite32(0x25, chip->pch_phub_base_address + 0x44); 7408c2ecf20Sopenharmony_ci chip->pch_opt_rom_start_address = PCH_PHUB_ROM_START_ADDR_EG20T; 7418c2ecf20Sopenharmony_ci chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_EG20T; 7428c2ecf20Sopenharmony_ci 7438c2ecf20Sopenharmony_ci /* quirk for MIPS Boston platform */ 7448c2ecf20Sopenharmony_ci if (pdev->dev.of_node) { 7458c2ecf20Sopenharmony_ci if (of_machine_is_compatible("img,boston")) { 7468c2ecf20Sopenharmony_ci pch_phub_read_modify_write_reg(chip, 7478c2ecf20Sopenharmony_ci (unsigned int)CLKCFG_REG_OFFSET, 7488c2ecf20Sopenharmony_ci CLKCFG_UART_25MHZ, 7498c2ecf20Sopenharmony_ci CLKCFG_UART_MASK); 7508c2ecf20Sopenharmony_ci } 7518c2ecf20Sopenharmony_ci } 7528c2ecf20Sopenharmony_ci } else if (id->driver_data == 2) { /* ML7213 IOH */ 7538c2ecf20Sopenharmony_ci ret = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr); 7548c2ecf20Sopenharmony_ci if (ret) 7558c2ecf20Sopenharmony_ci goto err_sysfs_create; 7568c2ecf20Sopenharmony_ci /* set the prefech value 7578c2ecf20Sopenharmony_ci * Device2(USB OHCI #1/ USB EHCI #1/ USB Device):a 7588c2ecf20Sopenharmony_ci * Device4(SDIO #0,1,2):f 7598c2ecf20Sopenharmony_ci * Device6(SATA 2):f 7608c2ecf20Sopenharmony_ci * Device8(USB OHCI #0/ USB EHCI #0):a 7618c2ecf20Sopenharmony_ci */ 7628c2ecf20Sopenharmony_ci iowrite32(0x000affa0, chip->pch_phub_base_address + 0x14); 7638c2ecf20Sopenharmony_ci chip->pch_opt_rom_start_address =\ 7648c2ecf20Sopenharmony_ci PCH_PHUB_ROM_START_ADDR_ML7213; 7658c2ecf20Sopenharmony_ci } else if (id->driver_data == 3) { /* ML7223 IOH Bus-m*/ 7668c2ecf20Sopenharmony_ci /* set the prefech value 7678c2ecf20Sopenharmony_ci * Device8(GbE) 7688c2ecf20Sopenharmony_ci */ 7698c2ecf20Sopenharmony_ci iowrite32(0x000a0000, chip->pch_phub_base_address + 0x14); 7708c2ecf20Sopenharmony_ci /* set the interrupt delay value */ 7718c2ecf20Sopenharmony_ci iowrite32(0x25, chip->pch_phub_base_address + 0x140); 7728c2ecf20Sopenharmony_ci chip->pch_opt_rom_start_address =\ 7738c2ecf20Sopenharmony_ci PCH_PHUB_ROM_START_ADDR_ML7223; 7748c2ecf20Sopenharmony_ci chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_ML7223; 7758c2ecf20Sopenharmony_ci } else if (id->driver_data == 4) { /* ML7223 IOH Bus-n*/ 7768c2ecf20Sopenharmony_ci ret = sysfs_create_file(&pdev->dev.kobj, 7778c2ecf20Sopenharmony_ci &dev_attr_pch_mac.attr); 7788c2ecf20Sopenharmony_ci if (ret) 7798c2ecf20Sopenharmony_ci goto err_sysfs_create; 7808c2ecf20Sopenharmony_ci ret = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr); 7818c2ecf20Sopenharmony_ci if (ret) 7828c2ecf20Sopenharmony_ci goto exit_bin_attr; 7838c2ecf20Sopenharmony_ci /* set the prefech value 7848c2ecf20Sopenharmony_ci * Device2(USB OHCI #0,1,2,3/ USB EHCI #0):a 7858c2ecf20Sopenharmony_ci * Device4(SDIO #0,1):f 7868c2ecf20Sopenharmony_ci * Device6(SATA 2):f 7878c2ecf20Sopenharmony_ci */ 7888c2ecf20Sopenharmony_ci iowrite32(0x0000ffa0, chip->pch_phub_base_address + 0x14); 7898c2ecf20Sopenharmony_ci chip->pch_opt_rom_start_address =\ 7908c2ecf20Sopenharmony_ci PCH_PHUB_ROM_START_ADDR_ML7223; 7918c2ecf20Sopenharmony_ci chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_ML7223; 7928c2ecf20Sopenharmony_ci } else if (id->driver_data == 5) { /* ML7831 */ 7938c2ecf20Sopenharmony_ci ret = sysfs_create_file(&pdev->dev.kobj, 7948c2ecf20Sopenharmony_ci &dev_attr_pch_mac.attr); 7958c2ecf20Sopenharmony_ci if (ret) 7968c2ecf20Sopenharmony_ci goto err_sysfs_create; 7978c2ecf20Sopenharmony_ci 7988c2ecf20Sopenharmony_ci ret = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr); 7998c2ecf20Sopenharmony_ci if (ret) 8008c2ecf20Sopenharmony_ci goto exit_bin_attr; 8018c2ecf20Sopenharmony_ci 8028c2ecf20Sopenharmony_ci /* set the prefech value */ 8038c2ecf20Sopenharmony_ci iowrite32(0x000affaa, chip->pch_phub_base_address + 0x14); 8048c2ecf20Sopenharmony_ci /* set the interrupt delay value */ 8058c2ecf20Sopenharmony_ci iowrite32(0x25, chip->pch_phub_base_address + 0x44); 8068c2ecf20Sopenharmony_ci chip->pch_opt_rom_start_address = PCH_PHUB_ROM_START_ADDR_EG20T; 8078c2ecf20Sopenharmony_ci chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_EG20T; 8088c2ecf20Sopenharmony_ci } 8098c2ecf20Sopenharmony_ci 8108c2ecf20Sopenharmony_ci chip->ioh_type = id->driver_data; 8118c2ecf20Sopenharmony_ci pci_set_drvdata(pdev, chip); 8128c2ecf20Sopenharmony_ci 8138c2ecf20Sopenharmony_ci return 0; 8148c2ecf20Sopenharmony_ciexit_bin_attr: 8158c2ecf20Sopenharmony_ci sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr); 8168c2ecf20Sopenharmony_ci 8178c2ecf20Sopenharmony_cierr_sysfs_create: 8188c2ecf20Sopenharmony_ci pci_iounmap(pdev, chip->pch_phub_base_address); 8198c2ecf20Sopenharmony_cierr_pci_iomap: 8208c2ecf20Sopenharmony_ci pci_release_regions(pdev); 8218c2ecf20Sopenharmony_cierr_req_regions: 8228c2ecf20Sopenharmony_ci pci_disable_device(pdev); 8238c2ecf20Sopenharmony_cierr_pci_enable_dev: 8248c2ecf20Sopenharmony_ci kfree(chip); 8258c2ecf20Sopenharmony_ci dev_err(&pdev->dev, "%s returns %d\n", __func__, ret); 8268c2ecf20Sopenharmony_ci return ret; 8278c2ecf20Sopenharmony_ci} 8288c2ecf20Sopenharmony_ci 8298c2ecf20Sopenharmony_cistatic void pch_phub_remove(struct pci_dev *pdev) 8308c2ecf20Sopenharmony_ci{ 8318c2ecf20Sopenharmony_ci struct pch_phub_reg *chip = pci_get_drvdata(pdev); 8328c2ecf20Sopenharmony_ci 8338c2ecf20Sopenharmony_ci sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr); 8348c2ecf20Sopenharmony_ci sysfs_remove_bin_file(&pdev->dev.kobj, &pch_bin_attr); 8358c2ecf20Sopenharmony_ci pci_iounmap(pdev, chip->pch_phub_base_address); 8368c2ecf20Sopenharmony_ci pci_release_regions(pdev); 8378c2ecf20Sopenharmony_ci pci_disable_device(pdev); 8388c2ecf20Sopenharmony_ci kfree(chip); 8398c2ecf20Sopenharmony_ci} 8408c2ecf20Sopenharmony_ci 8418c2ecf20Sopenharmony_cistatic int __maybe_unused pch_phub_suspend(struct device *dev_d) 8428c2ecf20Sopenharmony_ci{ 8438c2ecf20Sopenharmony_ci device_wakeup_disable(dev_d); 8448c2ecf20Sopenharmony_ci 8458c2ecf20Sopenharmony_ci return 0; 8468c2ecf20Sopenharmony_ci} 8478c2ecf20Sopenharmony_ci 8488c2ecf20Sopenharmony_cistatic int __maybe_unused pch_phub_resume(struct device *dev_d) 8498c2ecf20Sopenharmony_ci{ 8508c2ecf20Sopenharmony_ci device_wakeup_disable(dev_d); 8518c2ecf20Sopenharmony_ci 8528c2ecf20Sopenharmony_ci return 0; 8538c2ecf20Sopenharmony_ci} 8548c2ecf20Sopenharmony_ci 8558c2ecf20Sopenharmony_cistatic const struct pci_device_id pch_phub_pcidev_id[] = { 8568c2ecf20Sopenharmony_ci { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_PCH1_PHUB), 1, }, 8578c2ecf20Sopenharmony_ci { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7213_PHUB), 2, }, 8588c2ecf20Sopenharmony_ci { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_mPHUB), 3, }, 8598c2ecf20Sopenharmony_ci { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_nPHUB), 4, }, 8608c2ecf20Sopenharmony_ci { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7831_PHUB), 5, }, 8618c2ecf20Sopenharmony_ci { } 8628c2ecf20Sopenharmony_ci}; 8638c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(pci, pch_phub_pcidev_id); 8648c2ecf20Sopenharmony_ci 8658c2ecf20Sopenharmony_cistatic SIMPLE_DEV_PM_OPS(pch_phub_pm_ops, pch_phub_suspend, pch_phub_resume); 8668c2ecf20Sopenharmony_ci 8678c2ecf20Sopenharmony_cistatic struct pci_driver pch_phub_driver = { 8688c2ecf20Sopenharmony_ci .name = "pch_phub", 8698c2ecf20Sopenharmony_ci .id_table = pch_phub_pcidev_id, 8708c2ecf20Sopenharmony_ci .probe = pch_phub_probe, 8718c2ecf20Sopenharmony_ci .remove = pch_phub_remove, 8728c2ecf20Sopenharmony_ci .driver.pm = &pch_phub_pm_ops, 8738c2ecf20Sopenharmony_ci}; 8748c2ecf20Sopenharmony_ci 8758c2ecf20Sopenharmony_cimodule_pci_driver(pch_phub_driver); 8768c2ecf20Sopenharmony_ci 8778c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Intel EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7223) PHUB"); 8788c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 879