forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-11 297b60346df8beafee954a0fd7c2d64f33f3b9bc
kernel/drivers/mfd/lpc_ich.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * lpc_ich.c - LPC interface for Intel ICH
34 *
....@@ -10,15 +11,6 @@
1011
1112 * Copyright (c) 2011 Extreme Engineering Solution, Inc.
1213 * Author: Aaron Sierra <asierra@xes-inc.com>
13
- *
14
- * This program is free software; you can redistribute it and/or modify
15
- * it under the terms of the GNU General Public License 2 as published
16
- * by the Free Software Foundation.
17
- *
18
- * This program is distributed in the hope that it will be useful,
19
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
- * GNU General Public License for more details.
2214 *
2315 * This driver supports the following I/O Controller hubs:
2416 * (See the intel documentation on http://developer.intel.com.)
....@@ -71,6 +63,8 @@
7163 #define SPIBASE_BYT 0x54
7264 #define SPIBASE_BYT_SZ 512
7365 #define SPIBASE_BYT_EN BIT(1)
66
+#define BYT_BCR 0xfc
67
+#define BYT_BCR_WPD BIT(0)
7468
7569 #define SPIBASE_LPT 0x3800
7670 #define SPIBASE_LPT_SZ 512
....@@ -1091,12 +1085,57 @@
10911085 return ret;
10921086 }
10931087
1088
+static bool lpc_ich_byt_set_writeable(void __iomem *base, void *data)
1089
+{
1090
+ u32 val;
1091
+
1092
+ val = readl(base + BYT_BCR);
1093
+ if (!(val & BYT_BCR_WPD)) {
1094
+ val |= BYT_BCR_WPD;
1095
+ writel(val, base + BYT_BCR);
1096
+ val = readl(base + BYT_BCR);
1097
+ }
1098
+
1099
+ return val & BYT_BCR_WPD;
1100
+}
1101
+
1102
+static bool lpc_ich_lpt_set_writeable(void __iomem *base, void *data)
1103
+{
1104
+ struct pci_dev *pdev = data;
1105
+ u32 bcr;
1106
+
1107
+ pci_read_config_dword(pdev, BCR, &bcr);
1108
+ if (!(bcr & BCR_WPD)) {
1109
+ bcr |= BCR_WPD;
1110
+ pci_write_config_dword(pdev, BCR, bcr);
1111
+ pci_read_config_dword(pdev, BCR, &bcr);
1112
+ }
1113
+
1114
+ return bcr & BCR_WPD;
1115
+}
1116
+
1117
+static bool lpc_ich_bxt_set_writeable(void __iomem *base, void *data)
1118
+{
1119
+ unsigned int spi = PCI_DEVFN(13, 2);
1120
+ struct pci_bus *bus = data;
1121
+ u32 bcr;
1122
+
1123
+ pci_bus_read_config_dword(bus, spi, BCR, &bcr);
1124
+ if (!(bcr & BCR_WPD)) {
1125
+ bcr |= BCR_WPD;
1126
+ pci_bus_write_config_dword(bus, spi, BCR, bcr);
1127
+ pci_bus_read_config_dword(bus, spi, BCR, &bcr);
1128
+ }
1129
+
1130
+ return bcr & BCR_WPD;
1131
+}
1132
+
10941133 static int lpc_ich_init_spi(struct pci_dev *dev)
10951134 {
10961135 struct lpc_ich_priv *priv = pci_get_drvdata(dev);
10971136 struct resource *res = &intel_spi_res[0];
10981137 struct intel_spi_boardinfo *info;
1099
- u32 spi_base, rcba, bcr;
1138
+ u32 spi_base, rcba;
11001139
11011140 info = devm_kzalloc(&dev->dev, sizeof(*info), GFP_KERNEL);
11021141 if (!info)
....@@ -1110,6 +1149,8 @@
11101149 if (spi_base & SPIBASE_BYT_EN) {
11111150 res->start = spi_base & ~(SPIBASE_BYT_SZ - 1);
11121151 res->end = res->start + SPIBASE_BYT_SZ - 1;
1152
+
1153
+ info->set_writeable = lpc_ich_byt_set_writeable;
11131154 }
11141155 break;
11151156
....@@ -1120,8 +1161,8 @@
11201161 res->start = spi_base + SPIBASE_LPT;
11211162 res->end = res->start + SPIBASE_LPT_SZ - 1;
11221163
1123
- pci_read_config_dword(dev, BCR, &bcr);
1124
- info->writeable = !!(bcr & BCR_WPD);
1164
+ info->set_writeable = lpc_ich_lpt_set_writeable;
1165
+ info->data = dev;
11251166 }
11261167 break;
11271168
....@@ -1142,8 +1183,8 @@
11421183 res->start = spi_base & 0xfffffff0;
11431184 res->end = res->start + SPIBASE_APL_SZ - 1;
11441185
1145
- pci_bus_read_config_dword(bus, spi, BCR, &bcr);
1146
- info->writeable = !!(bcr & BCR_WPD);
1186
+ info->set_writeable = lpc_ich_bxt_set_writeable;
1187
+ info->data = bus;
11471188 }
11481189
11491190 pci_bus_write_config_byte(bus, p2sb, 0xe1, 0x1);