diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2006-01-06 19:41:02 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-01-08 23:47:18 -0500 |
commit | 5b9ca526917b7bc7d1da3beaccb2251a8f0b5fe2 (patch) | |
tree | f345cbb73a4c5bb4c5645d53df2653c916e54172 /arch/powerpc/platforms/powermac/feature.c | |
parent | a28d3af2a26c89aaa6470ca36edb212e05143d67 (diff) |
[PATCH] 3/5 powerpc: Add platform functions interpreter
This is the platform function interpreter itself along with the backends
for UniN/U3/U4, mac-io, GPIOs and i2c. It adds the ability to execute
those do-platform-* scripts in the device-tree (at least for most
devices for which a backend is provided). This should replace the clock
spreading hacks properly. It might also have an impact on all sort of
machines since some of the scripts marked "at init" will now be executed
on boot (or some other on sleep/wakeup), those will possibly do things
that the kernel didn't do at all, like setting some values into some i2c
devices (changing thermal sensor calibration or conversion rate) etc...
Thus regression testing is MUCH welcome. Also loook for errors in dmesg.
That's also why I've left rather verbose debugging enabled in this
version of the patch.
(I do expect some Windtunnel G4s to show some errors as they have an i2c
clock chip on the PMU bus that uses some primitives that the i2c backend
doesn't implement yet. I really need users that have one of those
machine to come back to me so we can get that done right, though the
errors themselves should be harmless, I suspect the machine might not
run at full speed).
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/platforms/powermac/feature.c')
-rw-r--r-- | arch/powerpc/platforms/powermac/feature.c | 46 |
1 files changed, 21 insertions, 25 deletions
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; | |||
58 | extern int powersave_nap; | 58 | extern int powersave_nap; |
59 | extern struct device_node *k2_skiplist[2]; | 59 | extern 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 | */ |
66 | static DEFINE_SPINLOCK(feature_lock); | 65 | DEFINE_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 | ||
108 | struct device_node *uninorth_node; | ||
109 | u32 __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 | |||
120 | static struct device_node *uninorth_node; | ||
121 | static u32 __iomem *uninorth_base; | ||
122 | static u32 uninorth_rev; | 111 | static u32 uninorth_rev; |
123 | static int uninorth_maj; | 112 | static int uninorth_maj; |
124 | static void __iomem *u3_ht; | 113 | static 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 | ||
1563 | static void | 1552 | |
1564 | keylargo_shutdown(struct macio_chip *macio, int sleep_mode) | 1553 | #ifdef CONFIG_PM |
1554 | |||
1555 | static 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 | ||
1617 | static void | 1608 | static void pangea_shutdown(struct macio_chip *macio, int sleep_mode) |
1618 | pangea_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 | ||
1651 | static void | 1641 | static void intrepid_shutdown(struct macio_chip *macio, int sleep_mode) |
1652 | intrepid_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 | |||
1836 | static long | 1827 | static long |
1837 | core99_sleep_state(struct device_node *node, long param, long value) | 1828 | core99_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"); |