aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/platforms/powermac/Makefile3
-rw-r--r--arch/powerpc/platforms/powermac/feature.c46
-rw-r--r--arch/powerpc/platforms/powermac/low_i2c.c294
-rw-r--r--arch/powerpc/platforms/powermac/pfunc_base.c405
-rw-r--r--arch/powerpc/platforms/powermac/pfunc_core.c989
-rw-r--r--arch/powerpc/platforms/powermac/smp.c48
-rw-r--r--drivers/macintosh/via-pmu.c10
-rw-r--r--include/asm-powerpc/pmac_feature.h19
-rw-r--r--include/asm-powerpc/pmac_low_i2c.h3
-rw-r--r--include/asm-powerpc/pmac_pfunc.h253
10 files changed, 2028 insertions, 42 deletions
diff --git a/arch/powerpc/platforms/powermac/Makefile b/arch/powerpc/platforms/powermac/Makefile
index faa1a2c82bcf..78093d7f97af 100644
--- a/arch/powerpc/platforms/powermac/Makefile
+++ b/arch/powerpc/platforms/powermac/Makefile
@@ -1,7 +1,8 @@
1CFLAGS_bootx_init.o += -fPIC 1CFLAGS_bootx_init.o += -fPIC
2 2
3obj-y += pic.o setup.o time.o feature.o pci.o \ 3obj-y += pic.o setup.o time.o feature.o pci.o \
4 sleep.o low_i2c.o cache.o 4 sleep.o low_i2c.o cache.o pfunc_core.o \
5 pfunc_base.o
5obj-$(CONFIG_PMAC_BACKLIGHT) += backlight.o 6obj-$(CONFIG_PMAC_BACKLIGHT) += backlight.o
6obj-$(CONFIG_CPU_FREQ_PMAC) += cpufreq_32.o 7obj-$(CONFIG_CPU_FREQ_PMAC) += cpufreq_32.o
7obj-$(CONFIG_CPU_FREQ_PMAC64) += cpufreq_64.o 8obj-$(CONFIG_CPU_FREQ_PMAC64) += cpufreq_64.o
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c
index b271b11583ac..558dd0692092 100644
--- a/arch/powerpc/platforms/powermac/feature.c
+++ b/arch/powerpc/platforms/powermac/feature.c
@@ -58,12 +58,11 @@ extern int powersave_lowspeed;
58extern int powersave_nap; 58extern int powersave_nap;
59extern struct device_node *k2_skiplist[2]; 59extern struct device_node *k2_skiplist[2];
60 60
61
62/* 61/*
63 * We use a single global lock to protect accesses. Each driver has 62 * We use a single global lock to protect accesses. Each driver has
64 * to take care of its own locking 63 * to take care of its own locking
65 */ 64 */
66static DEFINE_SPINLOCK(feature_lock); 65DEFINE_SPINLOCK(feature_lock);
67 66
68#define LOCK(flags) spin_lock_irqsave(&feature_lock, flags); 67#define LOCK(flags) spin_lock_irqsave(&feature_lock, flags);
69#define UNLOCK(flags) spin_unlock_irqrestore(&feature_lock, flags); 68#define UNLOCK(flags) spin_unlock_irqrestore(&feature_lock, flags);
@@ -106,22 +105,12 @@ static const char *macio_names[] =
106}; 105};
107 106
108 107
108struct device_node *uninorth_node;
109u32 __iomem *uninorth_base;
109 110
110/*
111 * Uninorth reg. access. Note that Uni-N regs are big endian
112 */
113
114#define UN_REG(r) (uninorth_base + ((r) >> 2))
115#define UN_IN(r) (in_be32(UN_REG(r)))
116#define UN_OUT(r,v) (out_be32(UN_REG(r), (v)))
117#define UN_BIS(r,v) (UN_OUT((r), UN_IN(r) | (v)))
118#define UN_BIC(r,v) (UN_OUT((r), UN_IN(r) & ~(v)))
119
120static struct device_node *uninorth_node;
121static u32 __iomem *uninorth_base;
122static u32 uninorth_rev; 111static u32 uninorth_rev;
123static int uninorth_maj; 112static int uninorth_maj;
124static void __iomem *u3_ht; 113static void __iomem *u3_ht_base;
125 114
126/* 115/*
127 * For each motherboard family, we have a table of functions pointers 116 * For each motherboard family, we have a table of functions pointers
@@ -1560,8 +1549,10 @@ void g5_phy_disable_cpu1(void)
1560 1549
1561#ifndef CONFIG_POWER4 1550#ifndef CONFIG_POWER4
1562 1551
1563static void 1552
1564keylargo_shutdown(struct macio_chip *macio, int sleep_mode) 1553#ifdef CONFIG_PM
1554
1555static void keylargo_shutdown(struct macio_chip *macio, int sleep_mode)
1565{ 1556{
1566 u32 temp; 1557 u32 temp;
1567 1558
@@ -1614,8 +1605,7 @@ keylargo_shutdown(struct macio_chip *macio, int sleep_mode)
1614 (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1); 1605 (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1);
1615} 1606}
1616 1607
1617static void 1608static void pangea_shutdown(struct macio_chip *macio, int sleep_mode)
1618pangea_shutdown(struct macio_chip *macio, int sleep_mode)
1619{ 1609{
1620 u32 temp; 1610 u32 temp;
1621 1611
@@ -1648,8 +1638,7 @@ pangea_shutdown(struct macio_chip *macio, int sleep_mode)
1648 (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1); 1638 (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1);
1649} 1639}
1650 1640
1651static void 1641static void intrepid_shutdown(struct macio_chip *macio, int sleep_mode)
1652intrepid_shutdown(struct macio_chip *macio, int sleep_mode)
1653{ 1642{
1654 u32 temp; 1643 u32 temp;
1655 1644
@@ -1833,6 +1822,8 @@ core99_wake_up(void)
1833 return 0; 1822 return 0;
1834} 1823}
1835 1824
1825#endif /* CONFIG_PM */
1826
1836static long 1827static long
1837core99_sleep_state(struct device_node *node, long param, long value) 1828core99_sleep_state(struct device_node *node, long param, long value)
1838{ 1829{
@@ -1854,10 +1845,13 @@ core99_sleep_state(struct device_node *node, long param, long value)
1854 if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0) 1845 if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0)
1855 return -EPERM; 1846 return -EPERM;
1856 1847
1848#ifdef CONFIG_PM
1857 if (value == 1) 1849 if (value == 1)
1858 return core99_sleep(); 1850 return core99_sleep();
1859 else if (value == 0) 1851 else if (value == 0)
1860 return core99_wake_up(); 1852 return core99_wake_up();
1853
1854#endif /* CONFIG_PM */
1861 return 0; 1855 return 0;
1862} 1856}
1863 1857
@@ -1981,7 +1975,9 @@ static struct feature_table_entry core99_features[] = {
1981 { PMAC_FTR_USB_ENABLE, core99_usb_enable }, 1975 { PMAC_FTR_USB_ENABLE, core99_usb_enable },
1982 { PMAC_FTR_1394_ENABLE, core99_firewire_enable }, 1976 { PMAC_FTR_1394_ENABLE, core99_firewire_enable },
1983 { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power }, 1977 { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power },
1978#ifdef CONFIG_PM
1984 { PMAC_FTR_SLEEP_STATE, core99_sleep_state }, 1979 { PMAC_FTR_SLEEP_STATE, core99_sleep_state },
1980#endif
1985#ifdef CONFIG_SMP 1981#ifdef CONFIG_SMP
1986 { PMAC_FTR_RESET_CPU, core99_reset_cpu }, 1982 { PMAC_FTR_RESET_CPU, core99_reset_cpu },
1987#endif /* CONFIG_SMP */ 1983#endif /* CONFIG_SMP */
@@ -2572,7 +2568,7 @@ static void __init probe_uninorth(void)
2572 uninorth_base = ioremap(address, 0x40000); 2568 uninorth_base = ioremap(address, 0x40000);
2573 uninorth_rev = in_be32(UN_REG(UNI_N_VERSION)); 2569 uninorth_rev = in_be32(UN_REG(UNI_N_VERSION));
2574 if (uninorth_maj == 3 || uninorth_maj == 4) 2570 if (uninorth_maj == 3 || uninorth_maj == 4)
2575 u3_ht = ioremap(address + U3_HT_CONFIG_BASE, 0x1000); 2571 u3_ht_base = ioremap(address + U3_HT_CONFIG_BASE, 0x1000);
2576 2572
2577 printk(KERN_INFO "Found %s memory controller & host bridge" 2573 printk(KERN_INFO "Found %s memory controller & host bridge"
2578 " @ 0x%08x revision: 0x%02x\n", uninorth_maj == 3 ? "U3" : 2574 " @ 0x%08x revision: 0x%02x\n", uninorth_maj == 3 ? "U3" :
@@ -2921,9 +2917,9 @@ void __init pmac_check_ht_link(void)
2921 u8 px_bus, px_devfn; 2917 u8 px_bus, px_devfn;
2922 struct pci_controller *px_hose; 2918 struct pci_controller *px_hose;
2923 2919
2924 (void)in_be32(u3_ht + U3_HT_LINK_COMMAND); 2920 (void)in_be32(u3_ht_base + U3_HT_LINK_COMMAND);
2925 ucfg = cfg = in_be32(u3_ht + U3_HT_LINK_CONFIG); 2921 ucfg = cfg = in_be32(u3_ht_base + U3_HT_LINK_CONFIG);
2926 ufreq = freq = in_be32(u3_ht + U3_HT_LINK_FREQ); 2922 ufreq = freq = in_be32(u3_ht_base + U3_HT_LINK_FREQ);
2927 dump_HT_speeds("U3 HyperTransport", cfg, freq); 2923 dump_HT_speeds("U3 HyperTransport", cfg, freq);
2928 2924
2929 pcix_node = of_find_compatible_node(NULL, "pci", "pci-x"); 2925 pcix_node = of_find_compatible_node(NULL, "pci", "pci-x");
diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c
index a25e447f907f..535c802b369f 100644
--- a/arch/powerpc/platforms/powermac/low_i2c.c
+++ b/arch/powerpc/platforms/powermac/low_i2c.c
@@ -49,6 +49,7 @@
49#include <asm/prom.h> 49#include <asm/prom.h>
50#include <asm/machdep.h> 50#include <asm/machdep.h>
51#include <asm/smu.h> 51#include <asm/smu.h>
52#include <asm/pmac_pfunc.h>
52#include <asm/pmac_low_i2c.h> 53#include <asm/pmac_low_i2c.h>
53 54
54#ifdef DEBUG 55#ifdef DEBUG
@@ -1162,9 +1163,291 @@ int pmac_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize,
1162} 1163}
1163EXPORT_SYMBOL_GPL(pmac_i2c_xfer); 1164EXPORT_SYMBOL_GPL(pmac_i2c_xfer);
1164 1165
1166/* some quirks for platform function decoding */
1167enum {
1168 pmac_i2c_quirk_invmask = 0x00000001u,
1169};
1170
1171static void pmac_i2c_devscan(void (*callback)(struct device_node *dev,
1172 int quirks))
1173{
1174 struct pmac_i2c_bus *bus;
1175 struct device_node *np;
1176 static struct whitelist_ent {
1177 char *name;
1178 char *compatible;
1179 int quirks;
1180 } whitelist[] = {
1181 /* XXX Study device-tree's & apple drivers are get the quirks
1182 * right !
1183 */
1184 { "i2c-hwclock", NULL, pmac_i2c_quirk_invmask },
1185 { "i2c-cpu-voltage", NULL, 0},
1186 { "temp-monitor", NULL, 0 },
1187 { "supply-monitor", NULL, 0 },
1188 { NULL, NULL, 0 },
1189 };
1190
1191 /* Only some devices need to have platform functions instanciated
1192 * here. For now, we have a table. Others, like 9554 i2c GPIOs used
1193 * on Xserve, if we ever do a driver for them, will use their own
1194 * platform function instance
1195 */
1196 list_for_each_entry(bus, &pmac_i2c_busses, link) {
1197 for (np = NULL;
1198 (np = of_get_next_child(bus->busnode, np)) != NULL;) {
1199 struct whitelist_ent *p;
1200 /* If multibus, check if device is on that bus */
1201 if (bus->flags & pmac_i2c_multibus)
1202 if (bus != pmac_i2c_find_bus(np))
1203 continue;
1204 for (p = whitelist; p->name != NULL; p++) {
1205 if (strcmp(np->name, p->name))
1206 continue;
1207 if (p->compatible &&
1208 !device_is_compatible(np, p->compatible))
1209 continue;
1210 callback(np, p->quirks);
1211 break;
1212 }
1213 }
1214 }
1215}
1216
1217#define MAX_I2C_DATA 64
1218
1219struct pmac_i2c_pf_inst
1220{
1221 struct pmac_i2c_bus *bus;
1222 u8 addr;
1223 u8 buffer[MAX_I2C_DATA];
1224 u8 scratch[MAX_I2C_DATA];
1225 int bytes;
1226 int quirks;
1227};
1228
1229static void* pmac_i2c_do_begin(struct pmf_function *func, struct pmf_args *args)
1230{
1231 struct pmac_i2c_pf_inst *inst;
1232 struct pmac_i2c_bus *bus;
1233
1234 bus = pmac_i2c_find_bus(func->node);
1235 if (bus == NULL) {
1236 printk(KERN_ERR "low_i2c: Can't find bus for %s (pfunc)\n",
1237 func->node->full_name);
1238 return NULL;
1239 }
1240 if (pmac_i2c_open(bus, 0)) {
1241 printk(KERN_ERR "low_i2c: Can't open i2c bus for %s (pfunc)\n",
1242 func->node->full_name);
1243 return NULL;
1244 }
1245
1246 /* XXX might need GFP_ATOMIC when called during the suspend process,
1247 * but then, there are already lots of issues with suspending when
1248 * near OOM that need to be resolved, the allocator itself should
1249 * probably make GFP_NOIO implicit during suspend
1250 */
1251 inst = kzalloc(sizeof(struct pmac_i2c_pf_inst), GFP_KERNEL);
1252 if (inst == NULL) {
1253 pmac_i2c_close(bus);
1254 return NULL;
1255 }
1256 inst->bus = bus;
1257 inst->addr = pmac_i2c_get_dev_addr(func->node);
1258 inst->quirks = (int)(long)func->driver_data;
1259 return inst;
1260}
1261
1262static void pmac_i2c_do_end(struct pmf_function *func, void *instdata)
1263{
1264 struct pmac_i2c_pf_inst *inst = instdata;
1265
1266 if (inst == NULL)
1267 return;
1268 pmac_i2c_close(inst->bus);
1269 if (inst)
1270 kfree(inst);
1271}
1272
1273static int pmac_i2c_do_read(PMF_STD_ARGS, u32 len)
1274{
1275 struct pmac_i2c_pf_inst *inst = instdata;
1276
1277 inst->bytes = len;
1278 return pmac_i2c_xfer(inst->bus, inst->addr | pmac_i2c_read, 0, 0,
1279 inst->buffer, len);
1280}
1281
1282static int pmac_i2c_do_write(PMF_STD_ARGS, u32 len, const u8 *data)
1283{
1284 struct pmac_i2c_pf_inst *inst = instdata;
1285
1286 return pmac_i2c_xfer(inst->bus, inst->addr | pmac_i2c_write, 0, 0,
1287 (u8 *)data, len);
1288}
1289
1290/* This function is used to do the masking & OR'ing for the "rmw" type
1291 * callbacks. Ze should apply the mask and OR in the values in the
1292 * buffer before writing back. The problem is that it seems that
1293 * various darwin drivers implement the mask/or differently, thus
1294 * we need to check the quirks first
1295 */
1296static void pmac_i2c_do_apply_rmw(struct pmac_i2c_pf_inst *inst,
1297 u32 len, const u8 *mask, const u8 *val)
1298{
1299 int i;
1300
1301 if (inst->quirks & pmac_i2c_quirk_invmask) {
1302 for (i = 0; i < len; i ++)
1303 inst->scratch[i] = (inst->buffer[i] & mask[i]) | val[i];
1304 } else {
1305 for (i = 0; i < len; i ++)
1306 inst->scratch[i] = (inst->buffer[i] & ~mask[i])
1307 | (val[i] & mask[i]);
1308 }
1309}
1310
1311static int pmac_i2c_do_rmw(PMF_STD_ARGS, u32 masklen, u32 valuelen,
1312 u32 totallen, const u8 *maskdata,
1313 const u8 *valuedata)
1314{
1315 struct pmac_i2c_pf_inst *inst = instdata;
1316
1317 if (masklen > inst->bytes || valuelen > inst->bytes ||
1318 totallen > inst->bytes || valuelen > masklen)
1319 return -EINVAL;
1320
1321 pmac_i2c_do_apply_rmw(inst, masklen, maskdata, valuedata);
1322
1323 return pmac_i2c_xfer(inst->bus, inst->addr | pmac_i2c_write, 0, 0,
1324 inst->scratch, totallen);
1325}
1326
1327static int pmac_i2c_do_read_sub(PMF_STD_ARGS, u8 subaddr, u32 len)
1328{
1329 struct pmac_i2c_pf_inst *inst = instdata;
1330
1331 inst->bytes = len;
1332 return pmac_i2c_xfer(inst->bus, inst->addr | pmac_i2c_read, 1, subaddr,
1333 inst->buffer, len);
1334}
1335
1336static int pmac_i2c_do_write_sub(PMF_STD_ARGS, u8 subaddr, u32 len,
1337 const u8 *data)
1338{
1339 struct pmac_i2c_pf_inst *inst = instdata;
1340
1341 return pmac_i2c_xfer(inst->bus, inst->addr | pmac_i2c_write, 1,
1342 subaddr, (u8 *)data, len);
1343}
1344
1345static int pmac_i2c_do_set_mode(PMF_STD_ARGS, int mode)
1346{
1347 struct pmac_i2c_pf_inst *inst = instdata;
1348
1349 return pmac_i2c_setmode(inst->bus, mode);
1350}
1351
1352static int pmac_i2c_do_rmw_sub(PMF_STD_ARGS, u8 subaddr, u32 masklen,
1353 u32 valuelen, u32 totallen, const u8 *maskdata,
1354 const u8 *valuedata)
1355{
1356 struct pmac_i2c_pf_inst *inst = instdata;
1357
1358 if (masklen > inst->bytes || valuelen > inst->bytes ||
1359 totallen > inst->bytes || valuelen > masklen)
1360 return -EINVAL;
1361
1362 pmac_i2c_do_apply_rmw(inst, masklen, maskdata, valuedata);
1363
1364 return pmac_i2c_xfer(inst->bus, inst->addr | pmac_i2c_write, 1,
1365 subaddr, inst->scratch, totallen);
1366}
1367
1368static int pmac_i2c_do_mask_and_comp(PMF_STD_ARGS, u32 len,
1369 const u8 *maskdata,
1370 const u8 *valuedata)
1371{
1372 struct pmac_i2c_pf_inst *inst = instdata;
1373 int i, match;
1374
1375 /* Get return value pointer, it's assumed to be a u32 */
1376 if (!args || !args->count || !args->u[0].p)
1377 return -EINVAL;
1378
1379 /* Check buffer */
1380 if (len > inst->bytes)
1381 return -EINVAL;
1382
1383 for (i = 0, match = 1; match && i < len; i ++)
1384 if ((inst->buffer[i] & maskdata[i]) != valuedata[i])
1385 match = 0;
1386 *args->u[0].p = match;
1387 return 0;
1388}
1389
1390static int pmac_i2c_do_delay(PMF_STD_ARGS, u32 duration)
1391{
1392 msleep((duration + 999) / 1000);
1393 return 0;
1394}
1395
1396
1397static struct pmf_handlers pmac_i2c_pfunc_handlers = {
1398 .begin = pmac_i2c_do_begin,
1399 .end = pmac_i2c_do_end,
1400 .read_i2c = pmac_i2c_do_read,
1401 .write_i2c = pmac_i2c_do_write,
1402 .rmw_i2c = pmac_i2c_do_rmw,
1403 .read_i2c_sub = pmac_i2c_do_read_sub,
1404 .write_i2c_sub = pmac_i2c_do_write_sub,
1405 .rmw_i2c_sub = pmac_i2c_do_rmw_sub,
1406 .set_i2c_mode = pmac_i2c_do_set_mode,
1407 .mask_and_compare = pmac_i2c_do_mask_and_comp,
1408 .delay = pmac_i2c_do_delay,
1409};
1410
1411static void __init pmac_i2c_dev_create(struct device_node *np, int quirks)
1412{
1413 DBG("dev_create(%s)\n", np->full_name);
1414
1415 pmf_register_driver(np, &pmac_i2c_pfunc_handlers,
1416 (void *)(long)quirks);
1417}
1418
1419static void __init pmac_i2c_dev_init(struct device_node *np, int quirks)
1420{
1421 DBG("dev_create(%s)\n", np->full_name);
1422
1423 pmf_do_functions(np, NULL, 0, PMF_FLAGS_ON_INIT, NULL);
1424}
1425
1426static void pmac_i2c_dev_suspend(struct device_node *np, int quirks)
1427{
1428 DBG("dev_suspend(%s)\n", np->full_name);
1429 pmf_do_functions(np, NULL, 0, PMF_FLAGS_ON_SLEEP, NULL);
1430}
1431
1432static void pmac_i2c_dev_resume(struct device_node *np, int quirks)
1433{
1434 DBG("dev_resume(%s)\n", np->full_name);
1435 pmf_do_functions(np, NULL, 0, PMF_FLAGS_ON_WAKE, NULL);
1436}
1437
1438void pmac_pfunc_i2c_suspend(void)
1439{
1440 pmac_i2c_devscan(pmac_i2c_dev_suspend);
1441}
1442
1443void pmac_pfunc_i2c_resume(void)
1444{
1445 pmac_i2c_devscan(pmac_i2c_dev_resume);
1446}
1447
1165/* 1448/*
1166 * Initialize us: probe all i2c busses on the machine and instantiate 1449 * Initialize us: probe all i2c busses on the machine, instantiate
1167 * busses. 1450 * busses and platform functions as needed.
1168 */ 1451 */
1169/* This is non-static as it might be called early by smp code */ 1452/* This is non-static as it might be called early by smp code */
1170int __init pmac_i2c_init(void) 1453int __init pmac_i2c_init(void)
@@ -1187,6 +1470,10 @@ int __init pmac_i2c_init(void)
1187 /* Probe SMU i2c busses */ 1470 /* Probe SMU i2c busses */
1188 smu_i2c_probe(); 1471 smu_i2c_probe();
1189#endif 1472#endif
1473
1474 /* Now add plaform functions for some known devices */
1475 pmac_i2c_devscan(pmac_i2c_dev_create);
1476
1190 return 0; 1477 return 0;
1191} 1478}
1192arch_initcall(pmac_i2c_init); 1479arch_initcall(pmac_i2c_init);
@@ -1216,6 +1503,9 @@ static int __init pmac_i2c_create_platform_devices(void)
1216 platform_device_add(bus->platform_dev); 1503 platform_device_add(bus->platform_dev);
1217 } 1504 }
1218 1505
1506 /* Now call platform "init" functions */
1507 pmac_i2c_devscan(pmac_i2c_dev_init);
1508
1219 return 0; 1509 return 0;
1220} 1510}
1221subsys_initcall(pmac_i2c_create_platform_devices); 1511subsys_initcall(pmac_i2c_create_platform_devices);
diff --git a/arch/powerpc/platforms/powermac/pfunc_base.c b/arch/powerpc/platforms/powermac/pfunc_base.c
new file mode 100644
index 000000000000..4ffd2a9832a0
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/pfunc_base.c
@@ -0,0 +1,405 @@
1#include <linux/config.h>
2#include <linux/types.h>
3#include <linux/init.h>
4#include <linux/delay.h>
5#include <linux/kernel.h>
6#include <linux/interrupt.h>
7#include <linux/spinlock.h>
8
9#include <asm/pmac_feature.h>
10#include <asm/pmac_pfunc.h>
11
12#define DBG(fmt...) printk(fmt)
13
14static irqreturn_t macio_gpio_irq(int irq, void *data, struct pt_regs *regs)
15{
16 pmf_do_irq(data);
17
18 return IRQ_HANDLED;
19}
20
21static int macio_do_gpio_irq_enable(struct pmf_function *func)
22{
23 if (func->node->n_intrs < 1)
24 return -EINVAL;
25
26 return request_irq(func->node->intrs[0].line, macio_gpio_irq, 0,
27 func->node->name, func);
28}
29
30static int macio_do_gpio_irq_disable(struct pmf_function *func)
31{
32 if (func->node->n_intrs < 1)
33 return -EINVAL;
34
35 free_irq(func->node->intrs[0].line, func);
36 return 0;
37}
38
39static int macio_do_gpio_write(PMF_STD_ARGS, u8 value, u8 mask)
40{
41 u8 __iomem *addr = (u8 __iomem *)func->driver_data;
42 unsigned long flags;
43 u8 tmp;
44
45 /* Check polarity */
46 if (args && args->count && !args->u[0].v)
47 value = ~value;
48
49 /* Toggle the GPIO */
50 spin_lock_irqsave(&feature_lock, flags);
51 tmp = readb(addr);
52 tmp = (tmp & ~mask) | (value & mask);
53 DBG("Do write 0x%02x to GPIO %s (%p)\n",
54 tmp, func->node->full_name, addr);
55 writeb(tmp, addr);
56 spin_unlock_irqrestore(&feature_lock, flags);
57
58 return 0;
59}
60
61static int macio_do_gpio_read(PMF_STD_ARGS, u8 mask, int rshift, u8 xor)
62{
63 u8 __iomem *addr = (u8 __iomem *)func->driver_data;
64 u32 value;
65
66 /* Check if we have room for reply */
67 if (args == NULL || args->count == 0 || args->u[0].p == NULL)
68 return -EINVAL;
69
70 value = readb(addr);
71 *args->u[0].p = ((value & mask) >> rshift) ^ xor;
72
73 return 0;
74}
75
76static int macio_do_delay(PMF_STD_ARGS, u32 duration)
77{
78 /* assume we can sleep ! */
79 msleep((duration + 999) / 1000);
80 return 0;
81}
82
83static struct pmf_handlers macio_gpio_handlers = {
84 .irq_enable = macio_do_gpio_irq_enable,
85 .irq_disable = macio_do_gpio_irq_disable,
86 .write_gpio = macio_do_gpio_write,
87 .read_gpio = macio_do_gpio_read,
88 .delay = macio_do_delay,
89};
90
91static void macio_gpio_init_one(struct macio_chip *macio)
92{
93 struct device_node *gparent, *gp;
94
95 /*
96 * Find the "gpio" parent node
97 */
98
99 for (gparent = NULL;
100 (gparent = of_get_next_child(macio->of_node, gparent)) != NULL;)
101 if (strcmp(gparent->name, "gpio") == 0)
102 break;
103 if (gparent == NULL)
104 return;
105
106 DBG("Installing GPIO functions for macio %s\n",
107 macio->of_node->full_name);
108
109 /*
110 * Ok, got one, we dont need anything special to track them down, so
111 * we just create them all
112 */
113 for (gp = NULL; (gp = of_get_next_child(gparent, gp)) != NULL;) {
114 u32 *reg = (u32 *)get_property(gp, "reg", NULL);
115 unsigned long offset;
116 if (reg == NULL)
117 continue;
118 offset = *reg;
119 /* Deal with old style device-tree. We can safely hard code the
120 * offset for now too even if it's a bit gross ...
121 */
122 if (offset < 0x50)
123 offset += 0x50;
124 offset += (unsigned long)macio->base;
125 pmf_register_driver(gp, &macio_gpio_handlers, (void *)offset);
126 }
127
128 DBG("Calling initial GPIO functions for macio %s\n",
129 macio->of_node->full_name);
130
131 /* And now we run all the init ones */
132 for (gp = NULL; (gp = of_get_next_child(gparent, gp)) != NULL;)
133 pmf_do_functions(gp, NULL, 0, PMF_FLAGS_ON_INIT, NULL);
134
135 /* Note: We do not at this point implement the "at sleep" or "at wake"
136 * functions. I yet to find any for GPIOs anyway
137 */
138}
139
140static int macio_do_write_reg32(PMF_STD_ARGS, u32 offset, u32 value, u32 mask)
141{
142 struct macio_chip *macio = func->driver_data;
143 unsigned long flags;
144
145 spin_lock_irqsave(&feature_lock, flags);
146 MACIO_OUT32(offset, (MACIO_IN32(offset) & ~mask) | (value & mask));
147 spin_unlock_irqrestore(&feature_lock, flags);
148 return 0;
149}
150
151static int macio_do_read_reg32(PMF_STD_ARGS, u32 offset)
152{
153 struct macio_chip *macio = func->driver_data;
154
155 /* Check if we have room for reply */
156 if (args == NULL || args->count == 0 || args->u[0].p == NULL)
157 return -EINVAL;
158
159 *args->u[0].p = MACIO_IN32(offset);
160 return 0;
161}
162
163static int macio_do_write_reg8(PMF_STD_ARGS, u32 offset, u8 value, u8 mask)
164{
165 struct macio_chip *macio = func->driver_data;
166 unsigned long flags;
167
168 spin_lock_irqsave(&feature_lock, flags);
169 MACIO_OUT8(offset, (MACIO_IN8(offset) & ~mask) | (value & mask));
170 spin_unlock_irqrestore(&feature_lock, flags);
171 return 0;
172}
173
174static int macio_do_read_reg8(PMF_STD_ARGS, u32 offset)
175{
176 struct macio_chip *macio = func->driver_data;
177
178 /* Check if we have room for reply */
179 if (args == NULL || args->count == 0 || args->u[0].p == NULL)
180 return -EINVAL;
181
182 *((u8 *)(args->u[0].p)) = MACIO_IN8(offset);
183 return 0;
184}
185
186static int macio_do_read_reg32_msrx(PMF_STD_ARGS, u32 offset, u32 mask,
187 u32 shift, u32 xor)
188{
189 struct macio_chip *macio = func->driver_data;
190
191 /* Check if we have room for reply */
192 if (args == NULL || args->count == 0 || args->u[0].p == NULL)
193 return -EINVAL;
194
195 *args->u[0].p = ((MACIO_IN32(offset) & mask) >> shift) ^ xor;
196 return 0;
197}
198
199static int macio_do_read_reg8_msrx(PMF_STD_ARGS, u32 offset, u32 mask,
200 u32 shift, u32 xor)
201{
202 struct macio_chip *macio = func->driver_data;
203
204 /* Check if we have room for reply */
205 if (args == NULL || args->count == 0 || args->u[0].p == NULL)
206 return -EINVAL;
207
208 *((u8 *)(args->u[0].p)) = ((MACIO_IN8(offset) & mask) >> shift) ^ xor;
209 return 0;
210}
211
212static int macio_do_write_reg32_slm(PMF_STD_ARGS, u32 offset, u32 shift,
213 u32 mask)
214{
215 struct macio_chip *macio = func->driver_data;
216 unsigned long flags;
217 u32 tmp, val;
218
219 /* Check args */
220 if (args == NULL || args->count == 0)
221 return -EINVAL;
222
223 spin_lock_irqsave(&feature_lock, flags);
224 tmp = MACIO_IN32(offset);
225 val = args->u[0].v << shift;
226 tmp = (tmp & ~mask) | (val & mask);
227 MACIO_OUT32(offset, tmp);
228 spin_unlock_irqrestore(&feature_lock, flags);
229 return 0;
230}
231
232static int macio_do_write_reg8_slm(PMF_STD_ARGS, u32 offset, u32 shift,
233 u32 mask)
234{
235 struct macio_chip *macio = func->driver_data;
236 unsigned long flags;
237 u32 tmp, val;
238
239 /* Check args */
240 if (args == NULL || args->count == 0)
241 return -EINVAL;
242
243 spin_lock_irqsave(&feature_lock, flags);
244 tmp = MACIO_IN8(offset);
245 val = args->u[0].v << shift;
246 tmp = (tmp & ~mask) | (val & mask);
247 MACIO_OUT8(offset, tmp);
248 spin_unlock_irqrestore(&feature_lock, flags);
249 return 0;
250}
251
252static struct pmf_handlers macio_mmio_handlers = {
253 .write_reg32 = macio_do_write_reg32,
254 .read_reg32 = macio_do_read_reg32,
255 .write_reg8 = macio_do_write_reg8,
256 .read_reg32 = macio_do_read_reg8,
257 .read_reg32_msrx = macio_do_read_reg32_msrx,
258 .read_reg8_msrx = macio_do_read_reg8_msrx,
259 .write_reg32_slm = macio_do_write_reg32_slm,
260 .write_reg8_slm = macio_do_write_reg8_slm,
261 .delay = macio_do_delay,
262};
263
264static void macio_mmio_init_one(struct macio_chip *macio)
265{
266 DBG("Installing MMIO functions for macio %s\n",
267 macio->of_node->full_name);
268
269 pmf_register_driver(macio->of_node, &macio_mmio_handlers, macio);
270}
271
272static struct device_node *unin_hwclock;
273
274static int unin_do_write_reg32(PMF_STD_ARGS, u32 offset, u32 value, u32 mask)
275{
276 unsigned long flags;
277
278 spin_lock_irqsave(&feature_lock, flags);
279 /* This is fairly bogus in darwin, but it should work for our needs
280 * implemeted that way:
281 */
282 UN_OUT(offset, (UN_IN(offset) & ~mask) | (value & mask));
283 spin_unlock_irqrestore(&feature_lock, flags);
284 return 0;
285}
286
287
288static struct pmf_handlers unin_mmio_handlers = {
289 .write_reg32 = unin_do_write_reg32,
290 .delay = macio_do_delay,
291};
292
293static void uninorth_install_pfunc(void)
294{
295 struct device_node *np;
296
297 DBG("Installing functions for UniN %s\n",
298 uninorth_node->full_name);
299
300 /*
301 * Install handlers for the bridge itself
302 */
303 pmf_register_driver(uninorth_node, &unin_mmio_handlers, NULL);
304 pmf_do_functions(uninorth_node, NULL, 0, PMF_FLAGS_ON_INIT, NULL);
305
306
307 /*
308 * Install handlers for the hwclock child if any
309 */
310 for (np = NULL; (np = of_get_next_child(uninorth_node, np)) != NULL;)
311 if (strcmp(np->name, "hw-clock") == 0) {
312 unin_hwclock = np;
313 break;
314 }
315 if (unin_hwclock) {
316 DBG("Installing functions for UniN clock %s\n",
317 unin_hwclock->full_name);
318 pmf_register_driver(unin_hwclock, &unin_mmio_handlers, NULL);
319 pmf_do_functions(unin_hwclock, NULL, 0, PMF_FLAGS_ON_INIT,
320 NULL);
321 }
322}
323
324/* We export this as the SMP code might init us early */
325int __init pmac_pfunc_base_install(void)
326{
327 static int pfbase_inited;
328 int i;
329
330 if (pfbase_inited)
331 return 0;
332 pfbase_inited = 1;
333
334
335 DBG("Installing base platform functions...\n");
336
337 /*
338 * Locate mac-io chips and install handlers
339 */
340 for (i = 0 ; i < MAX_MACIO_CHIPS; i++) {
341 if (macio_chips[i].of_node) {
342 macio_mmio_init_one(&macio_chips[i]);
343 macio_gpio_init_one(&macio_chips[i]);
344 }
345 }
346
347 /*
348 * Install handlers for northbridge and direct mapped hwclock
349 * if any. We do not implement the config space access callback
350 * which is only ever used for functions that we do not call in
351 * the current driver (enabling/disabling cells in U2, mostly used
352 * to restore the PCI settings, we do that differently)
353 */
354 if (uninorth_node && uninorth_base)
355 uninorth_install_pfunc();
356
357 DBG("All base functions installed\n");
358
359 return 0;
360}
361
362arch_initcall(pmac_pfunc_base_install);
363
364#ifdef CONFIG_PM
365
366/* Those can be called by pmac_feature. Ultimately, I should use a sysdev
367 * or a device, but for now, that's good enough until I sort out some
368 * ordering issues. Also, we do not bother with GPIOs, as so far I yet have
369 * to see a case where a GPIO function has the on-suspend or on-resume bit
370 */
371void pmac_pfunc_base_suspend(void)
372{
373 int i;
374
375 for (i = 0 ; i < MAX_MACIO_CHIPS; i++) {
376 if (macio_chips[i].of_node)
377 pmf_do_functions(macio_chips[i].of_node, NULL, 0,
378 PMF_FLAGS_ON_SLEEP, NULL);
379 }
380 if (uninorth_node)
381 pmf_do_functions(uninorth_node, NULL, 0,
382 PMF_FLAGS_ON_SLEEP, NULL);
383 if (unin_hwclock)
384 pmf_do_functions(unin_hwclock, NULL, 0,
385 PMF_FLAGS_ON_SLEEP, NULL);
386}
387
388void pmac_pfunc_base_resume(void)
389{
390 int i;
391
392 if (unin_hwclock)
393 pmf_do_functions(unin_hwclock, NULL, 0,
394 PMF_FLAGS_ON_WAKE, NULL);
395 if (uninorth_node)
396 pmf_do_functions(uninorth_node, NULL, 0,
397 PMF_FLAGS_ON_WAKE, NULL);
398 for (i = 0 ; i < MAX_MACIO_CHIPS; i++) {
399 if (macio_chips[i].of_node)
400 pmf_do_functions(macio_chips[i].of_node, NULL, 0,
401 PMF_FLAGS_ON_WAKE, NULL);
402 }
403}
404
405#endif /* CONFIG_PM */
diff --git a/arch/powerpc/platforms/powermac/pfunc_core.c b/arch/powerpc/platforms/powermac/pfunc_core.c
new file mode 100644
index 000000000000..c32c623001dc
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/pfunc_core.c
@@ -0,0 +1,989 @@
1/*
2 *
3 * FIXME: Properly make this race free with refcounting etc...
4 *
5 * FIXME: LOCKING !!!
6 */
7
8#include <linux/config.h>
9#include <linux/init.h>
10#include <linux/delay.h>
11#include <linux/kernel.h>
12#include <linux/spinlock.h>
13#include <linux/module.h>
14
15#include <asm/semaphore.h>
16#include <asm/prom.h>
17#include <asm/pmac_pfunc.h>
18
19/* Debug */
20#define LOG_PARSE(fmt...)
21#define LOG_ERROR(fmt...) printk(fmt)
22#define LOG_BLOB(t,b,c)
23#define DBG(fmt...) printk(fmt)
24
25/* Command numbers */
26#define PMF_CMD_LIST 0
27#define PMF_CMD_WRITE_GPIO 1
28#define PMF_CMD_READ_GPIO 2
29#define PMF_CMD_WRITE_REG32 3
30#define PMF_CMD_READ_REG32 4
31#define PMF_CMD_WRITE_REG16 5
32#define PMF_CMD_READ_REG16 6
33#define PMF_CMD_WRITE_REG8 7
34#define PMF_CMD_READ_REG8 8
35#define PMF_CMD_DELAY 9
36#define PMF_CMD_WAIT_REG32 10
37#define PMF_CMD_WAIT_REG16 11
38#define PMF_CMD_WAIT_REG8 12
39#define PMF_CMD_READ_I2C 13
40#define PMF_CMD_WRITE_I2C 14
41#define PMF_CMD_RMW_I2C 15
42#define PMF_CMD_GEN_I2C 16
43#define PMF_CMD_SHIFT_BYTES_RIGHT 17
44#define PMF_CMD_SHIFT_BYTES_LEFT 18
45#define PMF_CMD_READ_CFG 19
46#define PMF_CMD_WRITE_CFG 20
47#define PMF_CMD_RMW_CFG 21
48#define PMF_CMD_READ_I2C_SUBADDR 22
49#define PMF_CMD_WRITE_I2C_SUBADDR 23
50#define PMF_CMD_SET_I2C_MODE 24
51#define PMF_CMD_RMW_I2C_SUBADDR 25
52#define PMF_CMD_READ_REG32_MASK_SHR_XOR 26
53#define PMF_CMD_READ_REG16_MASK_SHR_XOR 27
54#define PMF_CMD_READ_REG8_MASK_SHR_XOR 28
55#define PMF_CMD_WRITE_REG32_SHL_MASK 29
56#define PMF_CMD_WRITE_REG16_SHL_MASK 30
57#define PMF_CMD_WRITE_REG8_SHL_MASK 31
58#define PMF_CMD_MASK_AND_COMPARE 32
59#define PMF_CMD_COUNT 33
60
61/* This structure holds the state of the parser while walking through
62 * a function definition
63 */
64struct pmf_cmd {
65 const void *cmdptr;
66 const void *cmdend;
67 struct pmf_function *func;
68 void *instdata;
69 struct pmf_args *args;
70 int error;
71};
72
73#if 0
74/* Debug output */
75static void print_blob(const char *title, const void *blob, int bytes)
76{
77 printk("%s", title);
78 while(bytes--) {
79 printk("%02x ", *((u8 *)blob));
80 blob += 1;
81 }
82 printk("\n");
83}
84#endif
85
86/*
87 * Parser helpers
88 */
89
90static u32 pmf_next32(struct pmf_cmd *cmd)
91{
92 u32 value;
93 if ((cmd->cmdend - cmd->cmdptr) < 4) {
94 cmd->error = 1;
95 return 0;
96 }
97 value = *((u32 *)cmd->cmdptr);
98 cmd->cmdptr += 4;
99 return value;
100}
101
102static const void* pmf_next_blob(struct pmf_cmd *cmd, int count)
103{
104 const void *value;
105 if ((cmd->cmdend - cmd->cmdptr) < count) {
106 cmd->error = 1;
107 return NULL;
108 }
109 value = cmd->cmdptr;
110 cmd->cmdptr += count;
111 return value;
112}
113
114/*
115 * Individual command parsers
116 */
117
118#define PMF_PARSE_CALL(name, cmd, handlers, p...) \
119 do { \
120 if (cmd->error) \
121 return -ENXIO; \
122 if (handlers == NULL) \
123 return 0; \
124 if (handlers->name) \
125 return handlers->name(cmd->func, cmd->instdata, \
126 cmd->args, p); \
127 return -1; \
128 } while(0) \
129
130
131static int pmf_parser_write_gpio(struct pmf_cmd *cmd, struct pmf_handlers *h)
132{
133 u8 value = (u8)pmf_next32(cmd);
134 u8 mask = (u8)pmf_next32(cmd);
135
136 LOG_PARSE("pmf: write_gpio(value: %02x, mask: %02x)\n", value, mask);
137
138 PMF_PARSE_CALL(write_gpio, cmd, h, value, mask);
139}
140
141static int pmf_parser_read_gpio(struct pmf_cmd *cmd, struct pmf_handlers *h)
142{
143 u8 mask = (u8)pmf_next32(cmd);
144 int rshift = (int)pmf_next32(cmd);
145 u8 xor = (u8)pmf_next32(cmd);
146
147 LOG_PARSE("pmf: read_gpio(mask: %02x, rshift: %d, xor: %02x)\n",
148 mask, rshift, xor);
149
150 PMF_PARSE_CALL(read_gpio, cmd, h, mask, rshift, xor);
151}
152
153static int pmf_parser_write_reg32(struct pmf_cmd *cmd, struct pmf_handlers *h)
154{
155 u32 offset = pmf_next32(cmd);
156 u32 value = pmf_next32(cmd);
157 u32 mask = pmf_next32(cmd);
158
159 LOG_PARSE("pmf: write_reg32(offset: %08x, value: %08x, mask: %08x)\n",
160 offset, value, mask);
161
162 PMF_PARSE_CALL(write_reg32, cmd, h, offset, value, mask);
163}
164
165static int pmf_parser_read_reg32(struct pmf_cmd *cmd, struct pmf_handlers *h)
166{
167 u32 offset = pmf_next32(cmd);
168
169 LOG_PARSE("pmf: read_reg32(offset: %08x)\n", offset);
170
171 PMF_PARSE_CALL(read_reg32, cmd, h, offset);
172}
173
174
175static int pmf_parser_write_reg16(struct pmf_cmd *cmd, struct pmf_handlers *h)
176{
177 u32 offset = pmf_next32(cmd);
178 u16 value = (u16)pmf_next32(cmd);
179 u16 mask = (u16)pmf_next32(cmd);
180
181 LOG_PARSE("pmf: write_reg16(offset: %08x, value: %04x, mask: %04x)\n",
182 offset, value, mask);
183
184 PMF_PARSE_CALL(write_reg16, cmd, h, offset, value, mask);
185}
186
187static int pmf_parser_read_reg16(struct pmf_cmd *cmd, struct pmf_handlers *h)
188{
189 u32 offset = pmf_next32(cmd);
190
191 LOG_PARSE("pmf: read_reg16(offset: %08x)\n", offset);
192
193 PMF_PARSE_CALL(read_reg16, cmd, h, offset);
194}
195
196
197static int pmf_parser_write_reg8(struct pmf_cmd *cmd, struct pmf_handlers *h)
198{
199 u32 offset = pmf_next32(cmd);
200 u8 value = (u16)pmf_next32(cmd);
201 u8 mask = (u16)pmf_next32(cmd);
202
203 LOG_PARSE("pmf: write_reg8(offset: %08x, value: %02x, mask: %02x)\n",
204 offset, value, mask);
205
206 PMF_PARSE_CALL(write_reg8, cmd, h, offset, value, mask);
207}
208
209static int pmf_parser_read_reg8(struct pmf_cmd *cmd, struct pmf_handlers *h)
210{
211 u32 offset = pmf_next32(cmd);
212
213 LOG_PARSE("pmf: read_reg8(offset: %08x)\n", offset);
214
215 PMF_PARSE_CALL(read_reg8, cmd, h, offset);
216}
217
218static int pmf_parser_delay(struct pmf_cmd *cmd, struct pmf_handlers *h)
219{
220 u32 duration = pmf_next32(cmd);
221
222 LOG_PARSE("pmf: delay(duration: %d us)\n", duration);
223
224 PMF_PARSE_CALL(delay, cmd, h, duration);
225}
226
227static int pmf_parser_wait_reg32(struct pmf_cmd *cmd, struct pmf_handlers *h)
228{
229 u32 offset = pmf_next32(cmd);
230 u32 value = pmf_next32(cmd);
231 u32 mask = pmf_next32(cmd);
232
233 LOG_PARSE("pmf: wait_reg32(offset: %08x, comp_value: %08x,mask: %08x)\n",
234 offset, value, mask);
235
236 PMF_PARSE_CALL(wait_reg32, cmd, h, offset, value, mask);
237}
238
239static int pmf_parser_wait_reg16(struct pmf_cmd *cmd, struct pmf_handlers *h)
240{
241 u32 offset = pmf_next32(cmd);
242 u16 value = (u16)pmf_next32(cmd);
243 u16 mask = (u16)pmf_next32(cmd);
244
245 LOG_PARSE("pmf: wait_reg16(offset: %08x, comp_value: %04x,mask: %04x)\n",
246 offset, value, mask);
247
248 PMF_PARSE_CALL(wait_reg16, cmd, h, offset, value, mask);
249}
250
251static int pmf_parser_wait_reg8(struct pmf_cmd *cmd, struct pmf_handlers *h)
252{
253 u32 offset = pmf_next32(cmd);
254 u8 value = (u8)pmf_next32(cmd);
255 u8 mask = (u8)pmf_next32(cmd);
256
257 LOG_PARSE("pmf: wait_reg8(offset: %08x, comp_value: %02x,mask: %02x)\n",
258 offset, value, mask);
259
260 PMF_PARSE_CALL(wait_reg8, cmd, h, offset, value, mask);
261}
262
263static int pmf_parser_read_i2c(struct pmf_cmd *cmd, struct pmf_handlers *h)
264{
265 u32 bytes = pmf_next32(cmd);
266
267 LOG_PARSE("pmf: read_i2c(bytes: %ud)\n", bytes);
268
269 PMF_PARSE_CALL(read_i2c, cmd, h, bytes);
270}
271
272static int pmf_parser_write_i2c(struct pmf_cmd *cmd, struct pmf_handlers *h)
273{
274 u32 bytes = pmf_next32(cmd);
275 const void *blob = pmf_next_blob(cmd, bytes);
276
277 LOG_PARSE("pmf: write_i2c(bytes: %ud) ...\n", bytes);
278 LOG_BLOB("pmf: data: \n", blob, bytes);
279
280 PMF_PARSE_CALL(write_i2c, cmd, h, bytes, blob);
281}
282
283
284static int pmf_parser_rmw_i2c(struct pmf_cmd *cmd, struct pmf_handlers *h)
285{
286 u32 maskbytes = pmf_next32(cmd);
287 u32 valuesbytes = pmf_next32(cmd);
288 u32 totalbytes = pmf_next32(cmd);
289 const void *maskblob = pmf_next_blob(cmd, maskbytes);
290 const void *valuesblob = pmf_next_blob(cmd, valuesbytes);
291
292 LOG_PARSE("pmf: rmw_i2c(maskbytes: %ud, valuebytes: %ud, "
293 "totalbytes: %d) ...\n",
294 maskbytes, valuesbytes, totalbytes);
295 LOG_BLOB("pmf: mask data: \n", maskblob, maskbytes);
296 LOG_BLOB("pmf: values data: \n", valuesblob, valuesbytes);
297
298 PMF_PARSE_CALL(rmw_i2c, cmd, h, maskbytes, valuesbytes, totalbytes,
299 maskblob, valuesblob);
300}
301
302static int pmf_parser_read_cfg(struct pmf_cmd *cmd, struct pmf_handlers *h)
303{
304 u32 offset = pmf_next32(cmd);
305 u32 bytes = pmf_next32(cmd);
306
307 LOG_PARSE("pmf: read_cfg(offset: %x, bytes: %ud)\n", offset, bytes);
308
309 PMF_PARSE_CALL(read_cfg, cmd, h, offset, bytes);
310}
311
312
313static int pmf_parser_write_cfg(struct pmf_cmd *cmd, struct pmf_handlers *h)
314{
315 u32 offset = pmf_next32(cmd);
316 u32 bytes = pmf_next32(cmd);
317 const void *blob = pmf_next_blob(cmd, bytes);
318
319 LOG_PARSE("pmf: write_cfg(offset: %x, bytes: %ud)\n", offset, bytes);
320 LOG_BLOB("pmf: data: \n", blob, bytes);
321
322 PMF_PARSE_CALL(write_cfg, cmd, h, offset, bytes, blob);
323}
324
325static int pmf_parser_rmw_cfg(struct pmf_cmd *cmd, struct pmf_handlers *h)
326{
327 u32 offset = pmf_next32(cmd);
328 u32 maskbytes = pmf_next32(cmd);
329 u32 valuesbytes = pmf_next32(cmd);
330 u32 totalbytes = pmf_next32(cmd);
331 const void *maskblob = pmf_next_blob(cmd, maskbytes);
332 const void *valuesblob = pmf_next_blob(cmd, valuesbytes);
333
334 LOG_PARSE("pmf: rmw_cfg(maskbytes: %ud, valuebytes: %ud,"
335 " totalbytes: %d) ...\n",
336 maskbytes, valuesbytes, totalbytes);
337 LOG_BLOB("pmf: mask data: \n", maskblob, maskbytes);
338 LOG_BLOB("pmf: values data: \n", valuesblob, valuesbytes);
339
340 PMF_PARSE_CALL(rmw_cfg, cmd, h, offset, maskbytes, valuesbytes,
341 totalbytes, maskblob, valuesblob);
342}
343
344
345static int pmf_parser_read_i2c_sub(struct pmf_cmd *cmd, struct pmf_handlers *h)
346{
347 u8 subaddr = (u8)pmf_next32(cmd);
348 u32 bytes = pmf_next32(cmd);
349
350 LOG_PARSE("pmf: read_i2c_sub(subaddr: %x, bytes: %ud)\n",
351 subaddr, bytes);
352
353 PMF_PARSE_CALL(read_i2c_sub, cmd, h, subaddr, bytes);
354}
355
356static int pmf_parser_write_i2c_sub(struct pmf_cmd *cmd, struct pmf_handlers *h)
357{
358 u8 subaddr = (u8)pmf_next32(cmd);
359 u32 bytes = pmf_next32(cmd);
360 const void *blob = pmf_next_blob(cmd, bytes);
361
362 LOG_PARSE("pmf: write_i2c_sub(subaddr: %x, bytes: %ud) ...\n",
363 subaddr, bytes);
364 LOG_BLOB("pmf: data: \n", blob, bytes);
365
366 PMF_PARSE_CALL(write_i2c_sub, cmd, h, subaddr, bytes, blob);
367}
368
369static int pmf_parser_set_i2c_mode(struct pmf_cmd *cmd, struct pmf_handlers *h)
370{
371 u32 mode = pmf_next32(cmd);
372
373 LOG_PARSE("pmf: set_i2c_mode(mode: %d)\n", mode);
374
375 PMF_PARSE_CALL(set_i2c_mode, cmd, h, mode);
376}
377
378
379static int pmf_parser_rmw_i2c_sub(struct pmf_cmd *cmd, struct pmf_handlers *h)
380{
381 u8 subaddr = (u8)pmf_next32(cmd);
382 u32 maskbytes = pmf_next32(cmd);
383 u32 valuesbytes = pmf_next32(cmd);
384 u32 totalbytes = pmf_next32(cmd);
385 const void *maskblob = pmf_next_blob(cmd, maskbytes);
386 const void *valuesblob = pmf_next_blob(cmd, valuesbytes);
387
388 LOG_PARSE("pmf: rmw_i2c_sub(subaddr: %x, maskbytes: %ud, valuebytes: %ud"
389 ", totalbytes: %d) ...\n",
390 subaddr, maskbytes, valuesbytes, totalbytes);
391 LOG_BLOB("pmf: mask data: \n", maskblob, maskbytes);
392 LOG_BLOB("pmf: values data: \n", valuesblob, valuesbytes);
393
394 PMF_PARSE_CALL(rmw_i2c_sub, cmd, h, subaddr, maskbytes, valuesbytes,
395 totalbytes, maskblob, valuesblob);
396}
397
398static int pmf_parser_read_reg32_msrx(struct pmf_cmd *cmd,
399 struct pmf_handlers *h)
400{
401 u32 offset = pmf_next32(cmd);
402 u32 mask = pmf_next32(cmd);
403 u32 shift = pmf_next32(cmd);
404 u32 xor = pmf_next32(cmd);
405
406 LOG_PARSE("pmf: read_reg32_msrx(offset: %x, mask: %x, shift: %x,"
407 " xor: %x\n", offset, mask, shift, xor);
408
409 PMF_PARSE_CALL(read_reg32_msrx, cmd, h, offset, mask, shift, xor);
410}
411
412static int pmf_parser_read_reg16_msrx(struct pmf_cmd *cmd,
413 struct pmf_handlers *h)
414{
415 u32 offset = pmf_next32(cmd);
416 u32 mask = pmf_next32(cmd);
417 u32 shift = pmf_next32(cmd);
418 u32 xor = pmf_next32(cmd);
419
420 LOG_PARSE("pmf: read_reg16_msrx(offset: %x, mask: %x, shift: %x,"
421 " xor: %x\n", offset, mask, shift, xor);
422
423 PMF_PARSE_CALL(read_reg16_msrx, cmd, h, offset, mask, shift, xor);
424}
425static int pmf_parser_read_reg8_msrx(struct pmf_cmd *cmd,
426 struct pmf_handlers *h)
427{
428 u32 offset = pmf_next32(cmd);
429 u32 mask = pmf_next32(cmd);
430 u32 shift = pmf_next32(cmd);
431 u32 xor = pmf_next32(cmd);
432
433 LOG_PARSE("pmf: read_reg8_msrx(offset: %x, mask: %x, shift: %x,"
434 " xor: %x\n", offset, mask, shift, xor);
435
436 PMF_PARSE_CALL(read_reg8_msrx, cmd, h, offset, mask, shift, xor);
437}
438
439static int pmf_parser_write_reg32_slm(struct pmf_cmd *cmd,
440 struct pmf_handlers *h)
441{
442 u32 offset = pmf_next32(cmd);
443 u32 shift = pmf_next32(cmd);
444 u32 mask = pmf_next32(cmd);
445
446 LOG_PARSE("pmf: write_reg32_slm(offset: %x, shift: %x, mask: %x\n",
447 offset, shift, mask);
448
449 PMF_PARSE_CALL(write_reg32_slm, cmd, h, offset, shift, mask);
450}
451
452static int pmf_parser_write_reg16_slm(struct pmf_cmd *cmd,
453 struct pmf_handlers *h)
454{
455 u32 offset = pmf_next32(cmd);
456 u32 shift = pmf_next32(cmd);
457 u32 mask = pmf_next32(cmd);
458
459 LOG_PARSE("pmf: write_reg16_slm(offset: %x, shift: %x, mask: %x\n",
460 offset, shift, mask);
461
462 PMF_PARSE_CALL(write_reg16_slm, cmd, h, offset, shift, mask);
463}
464
465static int pmf_parser_write_reg8_slm(struct pmf_cmd *cmd,
466 struct pmf_handlers *h)
467{
468 u32 offset = pmf_next32(cmd);
469 u32 shift = pmf_next32(cmd);
470 u32 mask = pmf_next32(cmd);
471
472 LOG_PARSE("pmf: write_reg8_slm(offset: %x, shift: %x, mask: %x\n",
473 offset, shift, mask);
474
475 PMF_PARSE_CALL(write_reg8_slm, cmd, h, offset, shift, mask);
476}
477
478static int pmf_parser_mask_and_compare(struct pmf_cmd *cmd,
479 struct pmf_handlers *h)
480{
481 u32 bytes = pmf_next32(cmd);
482 const void *maskblob = pmf_next_blob(cmd, bytes);
483 const void *valuesblob = pmf_next_blob(cmd, bytes);
484
485 LOG_PARSE("pmf: mask_and_compare(length: %ud ...\n", bytes);
486 LOG_BLOB("pmf: mask data: \n", maskblob, bytes);
487 LOG_BLOB("pmf: values data: \n", valuesblob, bytes);
488
489 PMF_PARSE_CALL(mask_and_compare, cmd, h,
490 bytes, maskblob, valuesblob);
491}
492
493
494typedef int (*pmf_cmd_parser_t)(struct pmf_cmd *cmd, struct pmf_handlers *h);
495
496static pmf_cmd_parser_t pmf_parsers[PMF_CMD_COUNT] =
497{
498 NULL,
499 pmf_parser_write_gpio,
500 pmf_parser_read_gpio,
501 pmf_parser_write_reg32,
502 pmf_parser_read_reg32,
503 pmf_parser_write_reg16,
504 pmf_parser_read_reg16,
505 pmf_parser_write_reg8,
506 pmf_parser_read_reg8,
507 pmf_parser_delay,
508 pmf_parser_wait_reg32,
509 pmf_parser_wait_reg16,
510 pmf_parser_wait_reg8,
511 pmf_parser_read_i2c,
512 pmf_parser_write_i2c,
513 pmf_parser_rmw_i2c,
514 NULL, /* Bogus command */
515 NULL, /* Shift bytes right: NYI */
516 NULL, /* Shift bytes left: NYI */
517 pmf_parser_read_cfg,
518 pmf_parser_write_cfg,
519 pmf_parser_rmw_cfg,
520 pmf_parser_read_i2c_sub,
521 pmf_parser_write_i2c_sub,
522 pmf_parser_set_i2c_mode,
523 pmf_parser_rmw_i2c_sub,
524 pmf_parser_read_reg32_msrx,
525 pmf_parser_read_reg16_msrx,
526 pmf_parser_read_reg8_msrx,
527 pmf_parser_write_reg32_slm,
528 pmf_parser_write_reg16_slm,
529 pmf_parser_write_reg8_slm,
530 pmf_parser_mask_and_compare,
531};
532
533struct pmf_device {
534 struct list_head link;
535 struct device_node *node;
536 struct pmf_handlers *handlers;
537 struct list_head functions;
538 struct kref ref;
539};
540
541static LIST_HEAD(pmf_devices);
542static spinlock_t pmf_lock = SPIN_LOCK_UNLOCKED;
543
544static void pmf_release_device(struct kref *kref)
545{
546 struct pmf_device *dev = container_of(kref, struct pmf_device, ref);
547 kfree(dev);
548}
549
550static inline void pmf_put_device(struct pmf_device *dev)
551{
552 kref_put(&dev->ref, pmf_release_device);
553}
554
555static inline struct pmf_device *pmf_get_device(struct pmf_device *dev)
556{
557 kref_get(&dev->ref);
558 return dev;
559}
560
561static inline struct pmf_device *pmf_find_device(struct device_node *np)
562{
563 struct pmf_device *dev;
564
565 list_for_each_entry(dev, &pmf_devices, link) {
566 if (dev->node == np)
567 return pmf_get_device(dev);
568 }
569 return NULL;
570}
571
572static int pmf_parse_one(struct pmf_function *func,
573 struct pmf_handlers *handlers,
574 void *instdata, struct pmf_args *args)
575{
576 struct pmf_cmd cmd;
577 u32 ccode;
578 int count, rc;
579
580 cmd.cmdptr = func->data;
581 cmd.cmdend = func->data + func->length;
582 cmd.func = func;
583 cmd.instdata = instdata;
584 cmd.args = args;
585 cmd.error = 0;
586
587 LOG_PARSE("pmf: func %s, %d bytes, %s...\n",
588 func->name, func->length,
589 handlers ? "executing" : "parsing");
590
591 /* One subcommand to parse for now */
592 count = 1;
593
594 while(count-- && cmd.cmdptr < cmd.cmdend) {
595 /* Get opcode */
596 ccode = pmf_next32(&cmd);
597 /* Check if we are hitting a command list, fetch new count */
598 if (ccode == 0) {
599 count = pmf_next32(&cmd) - 1;
600 ccode = pmf_next32(&cmd);
601 }
602 if (cmd.error) {
603 LOG_ERROR("pmf: parse error, not enough data\n");
604 return -ENXIO;
605 }
606 if (ccode >= PMF_CMD_COUNT) {
607 LOG_ERROR("pmf: command code %d unknown !\n", ccode);
608 return -ENXIO;
609 }
610 if (pmf_parsers[ccode] == NULL) {
611 LOG_ERROR("pmf: no parser for command %d !\n", ccode);
612 return -ENXIO;
613 }
614 rc = pmf_parsers[ccode](&cmd, handlers);
615 if (rc != 0) {
616 LOG_ERROR("pmf: parser for command %d returned"
617 " error %d\n", ccode, rc);
618 return rc;
619 }
620 }
621
622 /* We are doing an initial parse pass, we need to adjust the size */
623 if (handlers == NULL)
624 func->length = cmd.cmdptr - func->data;
625
626 return 0;
627}
628
629static int pmf_add_function_prop(struct pmf_device *dev, void *driverdata,
630 const char *name, u32 *data,
631 unsigned int length)
632{
633 int count = 0;
634 struct pmf_function *func = NULL;
635
636 DBG("pmf: Adding functions for platform-do-%s\n", name);
637
638 while (length >= 12) {
639 /* Allocate a structure */
640 func = kzalloc(sizeof(struct pmf_function), GFP_KERNEL);
641 if (func == NULL)
642 goto bail;
643 kref_init(&func->ref);
644 INIT_LIST_HEAD(&func->irq_clients);
645 func->node = dev->node;
646 func->driver_data = driverdata;
647 func->name = name;
648 func->phandle = data[0];
649 func->flags = data[1];
650 data += 2;
651 length -= 8;
652 func->data = data;
653 func->length = length;
654 func->dev = dev;
655 DBG("pmf: idx %d: flags=%08x, phandle=%08x "
656 " %d bytes remaining, parsing...\n",
657 count+1, func->flags, func->phandle, length);
658 if (pmf_parse_one(func, NULL, NULL, NULL)) {
659 kfree(func);
660 goto bail;
661 }
662 length -= func->length;
663 data = (u32 *)(((u8 *)data) + func->length);
664 list_add(&func->link, &dev->functions);
665 pmf_get_device(dev);
666 count++;
667 }
668 bail:
669 DBG("pmf: Added %d functions\n", count);
670
671 return count;
672}
673
674static int pmf_add_functions(struct pmf_device *dev, void *driverdata)
675{
676 struct property *pp;
677#define PP_PREFIX "platform-do-"
678 const int plen = strlen(PP_PREFIX);
679 int count = 0;
680
681 for (pp = dev->node->properties; pp != 0; pp = pp->next) {
682 char *name;
683 if (strncmp(pp->name, PP_PREFIX, plen) != 0)
684 continue;
685 name = pp->name + plen;
686 if (strlen(name) && pp->length >= 12)
687 count += pmf_add_function_prop(dev, driverdata, name,
688 (u32 *)pp->value,
689 pp->length);
690 }
691 return count;
692}
693
694
695int pmf_register_driver(struct device_node *np,
696 struct pmf_handlers *handlers,
697 void *driverdata)
698{
699 struct pmf_device *dev;
700 unsigned long flags;
701 int rc = 0;
702
703 if (handlers == NULL)
704 return -EINVAL;
705
706 DBG("pmf: registering driver for node %s\n", np->full_name);
707
708 spin_lock_irqsave(&pmf_lock, flags);
709 dev = pmf_find_device(np);
710 spin_unlock_irqrestore(&pmf_lock, flags);
711 if (dev != NULL) {
712 DBG("pmf: already there !\n");
713 pmf_put_device(dev);
714 return -EBUSY;
715 }
716
717 dev = kzalloc(sizeof(struct pmf_device), GFP_KERNEL);
718 if (dev == NULL) {
719 DBG("pmf: no memory !\n");
720 return -ENOMEM;
721 }
722 kref_init(&dev->ref);
723 dev->node = of_node_get(np);
724 dev->handlers = handlers;
725 INIT_LIST_HEAD(&dev->functions);
726
727 rc = pmf_add_functions(dev, driverdata);
728 if (rc == 0) {
729 DBG("pmf: no functions, disposing.. \n");
730 of_node_put(np);
731 kfree(dev);
732 return -ENODEV;
733 }
734
735 spin_lock_irqsave(&pmf_lock, flags);
736 list_add(&dev->link, &pmf_devices);
737 spin_unlock_irqrestore(&pmf_lock, flags);
738
739 return 0;
740}
741EXPORT_SYMBOL_GPL(pmf_register_driver);
742
743struct pmf_function *pmf_get_function(struct pmf_function *func)
744{
745 if (!try_module_get(func->dev->handlers->owner))
746 return NULL;
747 kref_get(&func->ref);
748 return func;
749}
750EXPORT_SYMBOL_GPL(pmf_get_function);
751
752static void pmf_release_function(struct kref *kref)
753{
754 struct pmf_function *func =
755 container_of(kref, struct pmf_function, ref);
756 pmf_put_device(func->dev);
757 kfree(func);
758}
759
760static inline void __pmf_put_function(struct pmf_function *func)
761{
762 kref_put(&func->ref, pmf_release_function);
763}
764
765void pmf_put_function(struct pmf_function *func)
766{
767 if (func == NULL)
768 return;
769 module_put(func->dev->handlers->owner);
770 __pmf_put_function(func);
771}
772EXPORT_SYMBOL_GPL(pmf_put_function);
773
774void pmf_unregister_driver(struct device_node *np)
775{
776 struct pmf_device *dev;
777 unsigned long flags;
778
779 DBG("pmf: unregistering driver for node %s\n", np->full_name);
780
781 spin_lock_irqsave(&pmf_lock, flags);
782 dev = pmf_find_device(np);
783 if (dev == NULL) {
784 DBG("pmf: not such driver !\n");
785 spin_unlock_irqrestore(&pmf_lock, flags);
786 return;
787 }
788 list_del(&dev->link);
789
790 while(!list_empty(&dev->functions)) {
791 struct pmf_function *func =
792 list_entry(dev->functions.next, typeof(*func), link);
793 list_del(&func->link);
794 __pmf_put_function(func);
795 }
796
797 pmf_put_device(dev);
798 spin_unlock_irqrestore(&pmf_lock, flags);
799}
800EXPORT_SYMBOL_GPL(pmf_unregister_driver);
801
802struct pmf_function *__pmf_find_function(struct device_node *target,
803 const char *name, u32 flags)
804{
805 struct device_node *actor = of_node_get(target);
806 struct pmf_device *dev;
807 struct pmf_function *func, *result = NULL;
808 char fname[64];
809 u32 *prop, ph;
810
811 /*
812 * Look for a "platform-*" function reference. If we can't find
813 * one, then we fallback to a direct call attempt
814 */
815 snprintf(fname, 63, "platform-%s", name);
816 prop = (u32 *)get_property(target, fname, NULL);
817 if (prop == NULL)
818 goto find_it;
819 ph = *prop;
820 if (ph == 0)
821 goto find_it;
822
823 /*
824 * Ok, now try to find the actor. If we can't find it, we fail,
825 * there is no point in falling back there
826 */
827 of_node_put(actor);
828 actor = of_find_node_by_phandle(ph);
829 if (actor == NULL)
830 return NULL;
831 find_it:
832 dev = pmf_find_device(actor);
833 if (dev == NULL)
834 return NULL;
835
836 list_for_each_entry(func, &dev->functions, link) {
837 if (name && strcmp(name, func->name))
838 continue;
839 if (func->phandle && target->node != func->phandle)
840 continue;
841 if ((func->flags & flags) == 0)
842 continue;
843 result = func;
844 break;
845 }
846 of_node_put(actor);
847 pmf_put_device(dev);
848 return result;
849}
850
851
852int pmf_register_irq_client(struct device_node *target,
853 const char *name,
854 struct pmf_irq_client *client)
855{
856 struct pmf_function *func;
857 unsigned long flags;
858
859 spin_lock_irqsave(&pmf_lock, flags);
860 func = __pmf_find_function(target, name, PMF_FLAGS_INT_GEN);
861 if (func == NULL) {
862 spin_unlock_irqrestore(&pmf_lock, flags);
863 return -ENODEV;
864 }
865 list_add(&client->link, &func->irq_clients);
866 spin_unlock_irqrestore(&pmf_lock, flags);
867
868 return 0;
869}
870EXPORT_SYMBOL_GPL(pmf_register_irq_client);
871
872void pmf_unregister_irq_client(struct device_node *np,
873 const char *name,
874 struct pmf_irq_client *client)
875{
876 unsigned long flags;
877
878 spin_lock_irqsave(&pmf_lock, flags);
879 list_del(&client->link);
880 spin_unlock_irqrestore(&pmf_lock, flags);
881}
882EXPORT_SYMBOL_GPL(pmf_unregister_irq_client);
883
884
885void pmf_do_irq(struct pmf_function *func)
886{
887 unsigned long flags;
888 struct pmf_irq_client *client;
889
890 /* For now, using a spinlock over the whole function. Can be made
891 * to drop the lock using 2 lists if necessary
892 */
893 spin_lock_irqsave(&pmf_lock, flags);
894 list_for_each_entry(client, &func->irq_clients, link) {
895 if (!try_module_get(client->owner))
896 continue;
897 client->handler(client->data);
898 module_put(client->owner);
899 }
900 spin_unlock_irqrestore(&pmf_lock, flags);
901}
902EXPORT_SYMBOL_GPL(pmf_do_irq);
903
904
905int pmf_call_one(struct pmf_function *func, struct pmf_args *args)
906{
907 struct pmf_device *dev = func->dev;
908 void *instdata = NULL;
909 int rc = 0;
910
911 DBG(" ** pmf_call_one(%s/%s) **\n", dev->node->full_name, func->name);
912
913 if (dev->handlers->begin)
914 instdata = dev->handlers->begin(func, args);
915 rc = pmf_parse_one(func, dev->handlers, instdata, args);
916 if (dev->handlers->end)
917 dev->handlers->end(func, instdata);
918
919 return rc;
920}
921EXPORT_SYMBOL_GPL(pmf_call_one);
922
923int pmf_do_functions(struct device_node *np, const char *name,
924 u32 phandle, u32 fflags, struct pmf_args *args)
925{
926 struct pmf_device *dev;
927 struct pmf_function *func, *tmp;
928 unsigned long flags;
929 int rc = -ENODEV;
930
931 spin_lock_irqsave(&pmf_lock, flags);
932
933 dev = pmf_find_device(np);
934 if (dev == NULL) {
935 spin_unlock_irqrestore(&pmf_lock, flags);
936 return -ENODEV;
937 }
938 list_for_each_entry_safe(func, tmp, &dev->functions, link) {
939 if (name && strcmp(name, func->name))
940 continue;
941 if (phandle && func->phandle && phandle != func->phandle)
942 continue;
943 if ((func->flags & fflags) == 0)
944 continue;
945 if (pmf_get_function(func) == NULL)
946 continue;
947 spin_unlock_irqrestore(&pmf_lock, flags);
948 rc = pmf_call_one(func, args);
949 pmf_put_function(func);
950 spin_lock_irqsave(&pmf_lock, flags);
951 }
952 pmf_put_device(dev);
953 spin_unlock_irqrestore(&pmf_lock, flags);
954
955 return rc;
956}
957EXPORT_SYMBOL_GPL(pmf_do_functions);
958
959
960struct pmf_function *pmf_find_function(struct device_node *target,
961 const char *name)
962{
963 struct pmf_function *func;
964 unsigned long flags;
965
966 spin_lock_irqsave(&pmf_lock, flags);
967 func = __pmf_find_function(target, name, PMF_FLAGS_ON_DEMAND);
968 if (func)
969 func = pmf_get_function(func);
970 spin_unlock_irqrestore(&pmf_lock, flags);
971 return func;
972}
973EXPORT_SYMBOL_GPL(pmf_find_function);
974
975int pmf_call_function(struct device_node *target, const char *name,
976 struct pmf_args *args)
977{
978 struct pmf_function *func = pmf_find_function(target, name);
979 int rc;
980
981 if (func == NULL)
982 return -ENODEV;
983
984 rc = pmf_call_one(func, args);
985 pmf_put_function(func);
986 return rc;
987}
988EXPORT_SYMBOL_GPL(pmf_call_function);
989
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index ab72ba86be1e..0df2cdcd805c 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -52,8 +52,9 @@
52#include <asm/cacheflush.h> 52#include <asm/cacheflush.h>
53#include <asm/keylargo.h> 53#include <asm/keylargo.h>
54#include <asm/pmac_low_i2c.h> 54#include <asm/pmac_low_i2c.h>
55#include <asm/pmac_pfunc.h>
55 56
56#undef DEBUG 57#define DEBUG
57 58
58#ifdef DEBUG 59#ifdef DEBUG
59#define DBG(fmt...) udbg_printf(fmt) 60#define DBG(fmt...) udbg_printf(fmt)
@@ -62,6 +63,7 @@
62#endif 63#endif
63 64
64extern void __secondary_start_pmac_0(void); 65extern void __secondary_start_pmac_0(void);
66extern int pmac_pfunc_base_install(void);
65 67
66#ifdef CONFIG_PPC32 68#ifdef CONFIG_PPC32
67 69
@@ -602,11 +604,29 @@ static void __init smp_core99_setup_i2c_hwsync(int ncpus)
602 pmac_tb_clock_chip_host = NULL; 604 pmac_tb_clock_chip_host = NULL;
603} 605}
604 606
605#endif /* CONFIG_PPC64 */
606 607
607 608
608/* 609/*
609 * SMP G4 and newer G5 use a GPIO to enable/disable the timebase. 610 * Newer G5s uses a platform function
611 */
612
613static void smp_core99_pfunc_tb_freeze(int freeze)
614{
615 struct device_node *cpus;
616 struct pmf_args args;
617
618 cpus = of_find_node_by_path("/cpus");
619 BUG_ON(cpus == NULL);
620 args.count = 1;
621 args.u[0].v = !freeze;
622 pmf_call_function(cpus, "cpu-timebase", &args);
623 of_node_put(cpus);
624}
625
626#else /* CONFIG_PPC64 */
627
628/*
629 * SMP G4 use a GPIO to enable/disable the timebase.
610 */ 630 */
611 631
612static unsigned int core99_tb_gpio; /* Timebase freeze GPIO */ 632static unsigned int core99_tb_gpio; /* Timebase freeze GPIO */
@@ -620,6 +640,9 @@ static void smp_core99_gpio_tb_freeze(int freeze)
620 pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0); 640 pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0);
621} 641}
622 642
643
644#endif /* !CONFIG_PPC64 */
645
623/* L2 and L3 cache settings to pass from CPU0 to CPU1 on G4 cpus */ 646/* L2 and L3 cache settings to pass from CPU0 to CPU1 on G4 cpus */
624volatile static long int core99_l2_cache; 647volatile static long int core99_l2_cache;
625volatile static long int core99_l3_cache; 648volatile static long int core99_l3_cache;
@@ -665,19 +688,15 @@ static void __init smp_core99_setup(int ncpus)
665 machine_is_compatible("RackMac3,1")) 688 machine_is_compatible("RackMac3,1"))
666 smp_core99_setup_i2c_hwsync(ncpus); 689 smp_core99_setup_i2c_hwsync(ncpus);
667 690
668 /* GPIO based HW sync on recent G5s */ 691 /* pfunc based HW sync on recent G5s */
669 if (pmac_tb_freeze == NULL) { 692 if (pmac_tb_freeze == NULL) {
670 struct device_node *np = 693 struct device_node *cpus =
671 of_find_node_by_name(NULL, "timebase-enable"); 694 of_find_node_by_path("/cpus");
672 u32 *reg = (u32 *)get_property(np, "reg", NULL); 695 if (cpus &&
673 696 get_property(cpus, "platform-cpu-timebase", NULL)) {
674 if (np && reg && !strcmp(np->type, "gpio")) { 697 pmac_tb_freeze = smp_core99_pfunc_tb_freeze;
675 core99_tb_gpio = *reg;
676 if (core99_tb_gpio < 0x50)
677 core99_tb_gpio += 0x50;
678 pmac_tb_freeze = smp_core99_gpio_tb_freeze;
679 printk(KERN_INFO "Processor timebase sync using" 698 printk(KERN_INFO "Processor timebase sync using"
680 " GPIO 0x%02x\n", core99_tb_gpio); 699 " platform function\n");
681 } 700 }
682 } 701 }
683 702
@@ -746,6 +765,7 @@ static int __init smp_core99_probe(void)
746 /* We need to perform some early initialisations before we can start 765 /* We need to perform some early initialisations before we can start
747 * setting up SMP as we are running before initcalls 766 * setting up SMP as we are running before initcalls
748 */ 767 */
768 pmac_pfunc_base_install();
749 pmac_i2c_init(); 769 pmac_i2c_init();
750 770
751 /* Setup various bits like timebase sync method, ability to nap, ... */ 771 /* Setup various bits like timebase sync method, ability to nap, ... */
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index aa481a88ccab..6eb93e45fcd3 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -55,6 +55,8 @@
55#include <asm/sections.h> 55#include <asm/sections.h>
56#include <asm/irq.h> 56#include <asm/irq.h>
57#include <asm/pmac_feature.h> 57#include <asm/pmac_feature.h>
58#include <asm/pmac_pfunc.h>
59#include <asm/pmac_low_i2c.h>
58#include <asm/uaccess.h> 60#include <asm/uaccess.h>
59#include <asm/mmu_context.h> 61#include <asm/mmu_context.h>
60#include <asm/cputable.h> 62#include <asm/cputable.h>
@@ -2105,6 +2107,10 @@ pmac_suspend_devices(void)
2105 return -EBUSY; 2107 return -EBUSY;
2106 } 2108 }
2107 2109
2110 /* Call platform functions marked "on sleep" */
2111 pmac_pfunc_i2c_suspend();
2112 pmac_pfunc_base_suspend();
2113
2108 /* Stop preemption */ 2114 /* Stop preemption */
2109 preempt_disable(); 2115 preempt_disable();
2110 2116
@@ -2175,6 +2181,10 @@ pmac_wakeup_devices(void)
2175 mdelay(10); 2181 mdelay(10);
2176 preempt_enable(); 2182 preempt_enable();
2177 2183
2184 /* Call platform functions marked "on wake" */
2185 pmac_pfunc_base_resume();
2186 pmac_pfunc_i2c_resume();
2187
2178 /* Resume devices */ 2188 /* Resume devices */
2179 device_resume(); 2189 device_resume();
2180 2190
diff --git a/include/asm-powerpc/pmac_feature.h b/include/asm-powerpc/pmac_feature.h
index e654ad0e5b42..3221628130c4 100644
--- a/include/asm-powerpc/pmac_feature.h
+++ b/include/asm-powerpc/pmac_feature.h
@@ -374,5 +374,24 @@ extern struct macio_chip* macio_find(struct device_node* child, int type);
374#define MACIO_IN8(r) (in_8(MACIO_FCR8(macio,r))) 374#define MACIO_IN8(r) (in_8(MACIO_FCR8(macio,r)))
375#define MACIO_OUT8(r,v) (out_8(MACIO_FCR8(macio,r), (v))) 375#define MACIO_OUT8(r,v) (out_8(MACIO_FCR8(macio,r), (v)))
376 376
377/*
378 * Those are exported by pmac feature for internal use by arch code
379 * only like the platform function callbacks, do not use directly in drivers
380 */
381extern spinlock_t feature_lock;
382extern struct device_node *uninorth_node;
383extern u32 __iomem *uninorth_base;
384
385/*
386 * Uninorth reg. access. Note that Uni-N regs are big endian
387 */
388
389#define UN_REG(r) (uninorth_base + ((r) >> 2))
390#define UN_IN(r) (in_be32(UN_REG(r)))
391#define UN_OUT(r,v) (out_be32(UN_REG(r), (v)))
392#define UN_BIS(r,v) (UN_OUT((r), UN_IN(r) | (v)))
393#define UN_BIC(r,v) (UN_OUT((r), UN_IN(r) & ~(v)))
394
395
377#endif /* __PPC_ASM_PMAC_FEATURE_H */ 396#endif /* __PPC_ASM_PMAC_FEATURE_H */
378#endif /* __KERNEL__ */ 397#endif /* __KERNEL__ */
diff --git a/include/asm-powerpc/pmac_low_i2c.h b/include/asm-powerpc/pmac_low_i2c.h
index 480018f41e1a..131011bd7e76 100644
--- a/include/asm-powerpc/pmac_low_i2c.h
+++ b/include/asm-powerpc/pmac_low_i2c.h
@@ -99,6 +99,9 @@ extern int pmac_i2c_setmode(struct pmac_i2c_bus *bus, int mode);
99extern int pmac_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize, 99extern int pmac_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize,
100 u32 subaddr, u8 *data, int len); 100 u32 subaddr, u8 *data, int len);
101 101
102/* Suspend/resume code called by via-pmu directly for now */
103extern void pmac_pfunc_i2c_suspend(void);
104extern void pmac_pfunc_i2c_resume(void);
102 105
103#endif /* __KERNEL__ */ 106#endif /* __KERNEL__ */
104#endif /* __PMAC_LOW_I2C_H__ */ 107#endif /* __PMAC_LOW_I2C_H__ */
diff --git a/include/asm-powerpc/pmac_pfunc.h b/include/asm-powerpc/pmac_pfunc.h
new file mode 100644
index 000000000000..d9728c80f86d
--- /dev/null
+++ b/include/asm-powerpc/pmac_pfunc.h
@@ -0,0 +1,253 @@
1#ifndef __PMAC_PFUNC_H__
2#define __PMAC_PFUNC_H__
3
4#include <linux/types.h>
5#include <linux/list.h>
6
7/* Flags in command lists */
8#define PMF_FLAGS_ON_INIT 0x80000000u
9#define PMF_FLGAS_ON_TERM 0x40000000u
10#define PMF_FLAGS_ON_SLEEP 0x20000000u
11#define PMF_FLAGS_ON_WAKE 0x10000000u
12#define PMF_FLAGS_ON_DEMAND 0x08000000u
13#define PMF_FLAGS_INT_GEN 0x04000000u
14#define PMF_FLAGS_HIGH_SPEED 0x02000000u
15#define PMF_FLAGS_LOW_SPEED 0x01000000u
16#define PMF_FLAGS_SIDE_EFFECTS 0x00800000u
17
18/*
19 * Arguments to a platform function call.
20 *
21 * NOTE: By convention, pointer arguments point to an u32
22 */
23struct pmf_args {
24 union {
25 u32 v;
26 u32 *p;
27 } u[4];
28 unsigned int count;
29};
30
31/*
32 * A driver capable of interpreting commands provides a handlers
33 * structure filled with whatever handlers are implemented by this
34 * driver. Non implemented handlers are left NULL.
35 *
36 * PMF_STD_ARGS are the same arguments that are passed to the parser
37 * and that gets passed back to the various handlers.
38 *
39 * Interpreting a given function always start with a begin() call which
40 * returns an instance data to be passed around subsequent calls, and
41 * ends with an end() call. This allows the low level driver to implement
42 * locking policy or per-function instance data.
43 *
44 * For interrupt capable functions, irq_enable() is called when a client
45 * registers, and irq_disable() is called when the last client unregisters
46 * Note that irq_enable & irq_disable are called within a semaphore held
47 * by the core, thus you should not try to register yourself to some other
48 * pmf interrupt during those calls.
49 */
50
51#define PMF_STD_ARGS struct pmf_function *func, void *instdata, \
52 struct pmf_args *args
53
54struct pmf_function;
55
56struct pmf_handlers {
57 void * (*begin)(struct pmf_function *func, struct pmf_args *args);
58 void (*end)(struct pmf_function *func, void *instdata);
59
60 int (*irq_enable)(struct pmf_function *func);
61 int (*irq_disable)(struct pmf_function *func);
62
63 int (*write_gpio)(PMF_STD_ARGS, u8 value, u8 mask);
64 int (*read_gpio)(PMF_STD_ARGS, u8 mask, int rshift, u8 xor);
65
66 int (*write_reg32)(PMF_STD_ARGS, u32 offset, u32 value, u32 mask);
67 int (*read_reg32)(PMF_STD_ARGS, u32 offset);
68 int (*write_reg16)(PMF_STD_ARGS, u32 offset, u16 value, u16 mask);
69 int (*read_reg16)(PMF_STD_ARGS, u32 offset);
70 int (*write_reg8)(PMF_STD_ARGS, u32 offset, u8 value, u8 mask);
71 int (*read_reg8)(PMF_STD_ARGS, u32 offset);
72
73 int (*delay)(PMF_STD_ARGS, u32 duration);
74
75 int (*wait_reg32)(PMF_STD_ARGS, u32 offset, u32 value, u32 mask);
76 int (*wait_reg16)(PMF_STD_ARGS, u32 offset, u16 value, u16 mask);
77 int (*wait_reg8)(PMF_STD_ARGS, u32 offset, u8 value, u8 mask);
78
79 int (*read_i2c)(PMF_STD_ARGS, u32 len);
80 int (*write_i2c)(PMF_STD_ARGS, u32 len, const u8 *data);
81 int (*rmw_i2c)(PMF_STD_ARGS, u32 masklen, u32 valuelen, u32 totallen,
82 const u8 *maskdata, const u8 *valuedata);
83
84 int (*read_cfg)(PMF_STD_ARGS, u32 offset, u32 len);
85 int (*write_cfg)(PMF_STD_ARGS, u32 offset, u32 len, const u8 *data);
86 int (*rmw_cfg)(PMF_STD_ARGS, u32 offset, u32 masklen, u32 valuelen,
87 u32 totallen, const u8 *maskdata, const u8 *valuedata);
88
89 int (*read_i2c_sub)(PMF_STD_ARGS, u8 subaddr, u32 len);
90 int (*write_i2c_sub)(PMF_STD_ARGS, u8 subaddr, u32 len, const u8 *data);
91 int (*set_i2c_mode)(PMF_STD_ARGS, int mode);
92 int (*rmw_i2c_sub)(PMF_STD_ARGS, u8 subaddr, u32 masklen, u32 valuelen,
93 u32 totallen, const u8 *maskdata,
94 const u8 *valuedata);
95
96 int (*read_reg32_msrx)(PMF_STD_ARGS, u32 offset, u32 mask, u32 shift,
97 u32 xor);
98 int (*read_reg16_msrx)(PMF_STD_ARGS, u32 offset, u32 mask, u32 shift,
99 u32 xor);
100 int (*read_reg8_msrx)(PMF_STD_ARGS, u32 offset, u32 mask, u32 shift,
101 u32 xor);
102
103 int (*write_reg32_slm)(PMF_STD_ARGS, u32 offset, u32 shift, u32 mask);
104 int (*write_reg16_slm)(PMF_STD_ARGS, u32 offset, u32 shift, u32 mask);
105 int (*write_reg8_slm)(PMF_STD_ARGS, u32 offset, u32 shift, u32 mask);
106
107 int (*mask_and_compare)(PMF_STD_ARGS, u32 len, const u8 *maskdata,
108 const u8 *valuedata);
109
110 struct module *owner;
111};
112
113
114/*
115 * Drivers who expose platform functions register at init time, this
116 * causes the platform functions for that device node to be parsed in
117 * advance and associated with the device. The data structures are
118 * partially public so a driver can walk the list of platform functions
119 * and eventually inspect the flags
120 */
121struct pmf_device;
122
123struct pmf_function {
124 /* All functions for a given driver are linked */
125 struct list_head link;
126
127 /* Function node & driver data */
128 struct device_node *node;
129 void *driver_data;
130
131 /* For internal use by core */
132 struct pmf_device *dev;
133
134 /* The name is the "xxx" in "platform-do-xxx", this is how
135 * platform functions are identified by this code. Some functions
136 * only operate for a given target, in which case the phandle is
137 * here (or 0 if the filter doesn't apply)
138 */
139 const char *name;
140 u32 phandle;
141
142 /* The flags for that function. You can have several functions
143 * with the same name and different flag
144 */
145 u32 flags;
146
147 /* The actual tokenized function blob */
148 const void *data;
149 unsigned int length;
150
151 /* Interrupt clients */
152 struct list_head irq_clients;
153
154 /* Refcounting */
155 struct kref ref;
156};
157
158/*
159 * For platform functions that are interrupts, one can register
160 * irq_client structures. You canNOT use the same structure twice
161 * as it contains a link member. Also, the callback is called with
162 * a spinlock held, you must not call back into any of the pmf_* functions
163 * from within that callback
164 */
165struct pmf_irq_client {
166 void (*handler)(void *data);
167 void *data;
168 struct module *owner;
169 struct list_head link;
170};
171
172
173/*
174 * Register/Unregister a function-capable driver and its handlers
175 */
176extern int pmf_register_driver(struct device_node *np,
177 struct pmf_handlers *handlers,
178 void *driverdata);
179
180extern void pmf_unregister_driver(struct device_node *np);
181
182
183/*
184 * Register/Unregister interrupt clients
185 */
186extern int pmf_register_irq_client(struct device_node *np,
187 const char *name,
188 struct pmf_irq_client *client);
189
190extern void pmf_unregister_irq_client(struct device_node *np,
191 const char *name,
192 struct pmf_irq_client *client);
193
194/*
195 * Called by the handlers when an irq happens
196 */
197extern void pmf_do_irq(struct pmf_function *func);
198
199
200/*
201 * Low level call to platform functions.
202 *
203 * The phandle can filter on the target object for functions that have
204 * multiple targets, the flags allow you to restrict the call to a given
205 * combination of flags.
206 *
207 * The args array contains as many arguments as is required by the function,
208 * this is dependent on the function you are calling, unfortunately Apple
209 * mecanism provides no way to encode that so you have to get it right at
210 * the call site. Some functions require no args, in which case, you can
211 * pass NULL.
212 *
213 * You can also pass NULL to the name. This will match any function that has
214 * the appropriate combination of flags & phandle or you can pass 0 to the
215 * phandle to match any
216 */
217extern int pmf_do_functions(struct device_node *np, const char *name,
218 u32 phandle, u32 flags, struct pmf_args *args);
219
220
221
222/*
223 * High level call to a platform function.
224 *
225 * This one looks for the platform-xxx first so you should call it to the
226 * actual target if any. It will fallback to platform-do-xxx if it can't
227 * find one. It will also exclusively target functions that have
228 * the "OnDemand" flag.
229 */
230
231extern int pmf_call_function(struct device_node *target, const char *name,
232 struct pmf_args *args);
233
234
235/*
236 * For low latency interrupt usage, you can lookup for on-demand functions
237 * using the functions below
238 */
239
240extern struct pmf_function *pmf_find_function(struct device_node *target,
241 const char *name);
242
243extern struct pmf_function * pmf_get_function(struct pmf_function *func);
244extern void pmf_put_function(struct pmf_function *func);
245
246extern int pmf_call_one(struct pmf_function *func, struct pmf_args *args);
247
248
249/* Suspend/resume code called by via-pmu directly for now */
250extern void pmac_pfunc_base_suspend(void);
251extern void pmac_pfunc_base_resume(void);
252
253#endif /* __PMAC_PFUNC_H__ */