Re: PowerPC radeon KMS - is it possible?
On Mit, 2012-04-18 at 18:23 +0200, Gerhard Pircher wrote: Von: Michel Dänzer mic...@daenzer.net On Mit, 2012-04-18 at 17:49 +0200, Gerhard Pircher wrote: Von: Michel Dänzer mic...@daenzer.net On Mit, 2012-04-18 at 16:55 +0200, Andreas Schwab wrote: Michel Dänzer mic...@daenzer.net writes: On Mit, 2012-04-18 at 16:28 +0200, Andreas Schwab wrote: Michel Dänzer mic...@daenzer.net writes: Have you tried smaller aperture sizes (uninorth_agp.aperture) and/or radeon.test=1? (See commit 52f072cb084bbb460d3a4ae09f0b6efc3e7e8a8c) Neither changes anything. How small aperture sizes have you tried? 32M. With the old UMS driver 3D once worked fine ... That doesn't necessarily mean much per se, as with UMS memory is only statically mapped into the AGP GART once (so most of those 32M are wasted at least most of the time), whereas with KMS it's dynamically (un)mapped on demand. That may be a stupid question, but is it allowed (for a DRM client or whatever does the mapping) to change the content of a page mapped into the AGP GART or is it necessary to explicitly unmap the page, change its content and map it again? The former. I know that the uninorth AGPGART driver does a cache flushing for newly mapped pages, Ah, right, that probably explains why the map_page_into_agp change doesn't make any difference. but is there any code in the driver that handles the former case (or isn't this necessary on PPC Macs)? If by 'former case' you mean userspace modifying memory mapped into the AGP GART, then no, this generally doesn't require special treatment on PowerMacs. (Ignoring the potential issue mentioned by Ben in this thread) I would say it's necessary to unmap the page first (sounds more like the pci_[un]map_page() approach) - at least when it should work with non-coherent architectures, too. I'm afraid non-coherent platforms haven't really been a concern yet for KMS, and always doing the above dance would probably have a significant performance impact on coherent platforms. Are there any plans for a page flushing API? I suppose that wouldn't have such a big performance impact on coherent platforms (but probably an impact on the userspace API). Not that I know of. Note that this isn't necessarily the only possible approach for addressing this problem. The driver knows which memory buffers are used by a GPU command stream sequence, so it should be able to take any measures necessary to ensure the device sees their contents as of when the command stream was submitted. -- Earthling Michel Dänzer | http://www.amd.com Libre software enthusiast | Debian, X and DRI developer ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc: fix build when CONFIG_BOOKE_WDT is enabled
Commit ae3a197e (Disintegrate asm/system.h for PowerPC) broke build of assembly files when CONFIG_BOOKE_WDT is enabled as follows: AS arch/powerpc/lib/string.o /home/baruch/git/stable/arch/powerpc/include/asm/reg_booke.h: Assembler messages: /home/baruch/git/stable/arch/powerpc/include/asm/reg_booke.h:19: Error: Unrecognized opcode: `extern' /home/baruch/git/stable/arch/powerpc/include/asm/reg_booke.h:20: Error: Unrecognized opcode: `extern' Since setup_32.c is the only user of the booke_wdt configuration variables, move the declarations there. Cc: David Howells dhowe...@redhat.com Signed-off-by: Baruch Siach bar...@tkos.co.il --- arch/powerpc/include/asm/reg_booke.h |5 - arch/powerpc/kernel/setup_32.c |5 + 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h index b86faa9..8a97aa7 100644 --- a/arch/powerpc/include/asm/reg_booke.h +++ b/arch/powerpc/include/asm/reg_booke.h @@ -15,11 +15,6 @@ #ifndef __ASM_POWERPC_REG_BOOKE_H__ #define __ASM_POWERPC_REG_BOOKE_H__ -#ifdef CONFIG_BOOKE_WDT -extern u32 booke_wdt_enabled; -extern u32 booke_wdt_period; -#endif /* CONFIG_BOOKE_WDT */ - /* Machine State Register (MSR) Fields */ #define MSR_GS (128) /* Guest state */ #define MSR_UCLE (126) /* User-mode cache lock enable */ diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 9825f29..a9b8be5 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -61,6 +61,11 @@ unsigned long vgacon_remap_base; EXPORT_SYMBOL(vgacon_remap_base); #endif +#ifdef CONFIG_BOOKE_WDT +extern u32 booke_wdt_enabled; +extern u32 booke_wdt_period; +#endif /* CONFIG_BOOKE_WDT */ + /* * These are used in binfmt_elf.c to put aux entries on the stack * for each elf executable being started. -- 1.7.9.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 09/15] powerpc/windfarm: Improve display of fan speeds in sysfs
Controls registered as RPM and PWM fans are now displayed with the RPM or % suffix respectively to make it clearer to the user what the value actually means since the fan type isn't otherwise obvious. Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org --- drivers/macintosh/windfarm_core.c | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c index ce88979..ebafc25 100644 --- a/drivers/macintosh/windfarm_core.c +++ b/drivers/macintosh/windfarm_core.c @@ -164,13 +164,24 @@ static ssize_t wf_show_control(struct device *dev, struct device_attribute *attr, char *buf) { struct wf_control *ctrl = container_of(attr, struct wf_control, attr); + const char *typestr; s32 val = 0; int err; err = ctrl-ops-get_value(ctrl, val); if (err 0) return err; - return sprintf(buf, %d\n, val); + switch(ctrl-type) { + case WF_CONTROL_RPM_FAN: + typestr = RPM; + break; + case WF_CONTROL_PWM_FAN: + typestr = %; + break; + default: + typestr = ; + } + return sprintf(buf, %d%s\n, val, typestr); } /* This is really only for debugging... */ -- 1.7.9.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 03/15] powerpc/pmac: Convert windfarm_lm75 to new i2c probing
This simplifies the driver to stop using the deprecated attach interface Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org --- drivers/macintosh/windfarm_lm75_sensor.c | 124 -- 1 file changed, 30 insertions(+), 94 deletions(-) diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c index 4d6a90a..4cc3f93 100644 --- a/drivers/macintosh/windfarm_lm75_sensor.c +++ b/drivers/macintosh/windfarm_lm75_sensor.c @@ -23,7 +23,7 @@ #include windfarm.h -#define VERSION 0.2 +#define VERSION 1.0 #undef DEBUG @@ -36,8 +36,8 @@ struct wf_lm75_sensor { int ds1775 : 1; int inited : 1; - struct i2c_client *i2c; - struct wf_sensor sens; + struct i2c_client *i2c; + struct wf_sensorsens; }; #define wf_to_lm75(c) container_of(c, struct wf_lm75_sensor, sens) @@ -90,40 +90,19 @@ static struct wf_sensor_ops wf_lm75_ops = { static int wf_lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) -{ +{ struct wf_lm75_sensor *lm; - int rc; - - lm = kzalloc(sizeof(struct wf_lm75_sensor), GFP_KERNEL); - if (lm == NULL) - return -ENODEV; - - lm-inited = 0; - lm-ds1775 = id-driver_data; - lm-i2c = client; - lm-sens.name = client-dev.platform_data; - lm-sens.ops = wf_lm75_ops; - i2c_set_clientdata(client, lm); - - rc = wf_register_sensor(lm-sens); - if (rc) - kfree(lm); - - return rc; -} - -static struct i2c_driver wf_lm75_driver; - -static struct i2c_client *wf_lm75_create(struct i2c_adapter *adapter, -u8 addr, int ds1775, -const char *loc) -{ - struct i2c_board_info info; - struct i2c_client *client; - char *name; + int rc, ds1775 = id-driver_data; + const char *name, *loc; DBG(wf_lm75: creating %s device at address 0x%02x\n, - ds1775 ? ds1775 : lm75, addr); + ds1775 ? ds1775 : lm75, client-addr); + + loc = of_get_property(client-dev.of_node, hwsensor-location, NULL); + if (!loc) { + dev_warn(client-dev, Missing hwsensor-location property!\n); + return -ENXIO; + } /* Usual rant about sensor names not beeing very consistent in * the device-tree, oh well ... @@ -138,67 +117,24 @@ static struct i2c_client *wf_lm75_create(struct i2c_adapter *adapter, else if (!strcmp(loc, HD Temp)) name = hard-drive-temp; else - goto fail; - - memset(info, 0, sizeof(struct i2c_board_info)); - info.addr = (addr 1) 0x7f; - info.platform_data = name; - strlcpy(info.type, ds1775 ? wf_ds1775 : wf_lm75, I2C_NAME_SIZE); - - client = i2c_new_device(adapter, info); - if (client == NULL) { - printk(KERN_ERR windfarm: failed to attach %s %s to i2c\n, - ds1775 ? ds1775 : lm75, name); - goto fail; - } - - /* -* Let i2c-core delete that device on driver removal. -* This is safe because i2c-core holds the core_lock mutex for us. -*/ - list_add_tail(client-detected, wf_lm75_driver.clients); - return client; - fail: - return NULL; -} - -static int wf_lm75_attach(struct i2c_adapter *adapter) -{ - struct device_node *busnode, *dev; - struct pmac_i2c_bus *bus; + return -ENXIO; + - DBG(wf_lm75: adapter %s detected\n, adapter-name); - - bus = pmac_i2c_adapter_to_bus(adapter); - if (bus == NULL) + lm = kzalloc(sizeof(struct wf_lm75_sensor), GFP_KERNEL); + if (lm == NULL) return -ENODEV; - busnode = pmac_i2c_get_bus_node(bus); - DBG(wf_lm75: bus found, looking for device...\n); - - /* Now look for lm75(s) in there */ - for (dev = NULL; -(dev = of_get_next_child(busnode, dev)) != NULL;) { - const char *loc = - of_get_property(dev, hwsensor-location, NULL); - u8 addr; + lm-inited = 0; + lm-ds1775 = ds1775; + lm-i2c = client; + lm-sens.name = (char *)name; /* XXX fix constness in structure */ + lm-sens.ops = wf_lm75_ops; + i2c_set_clientdata(client, lm); - /* We must re-match the adapter in order to properly check -* the channel on multibus setups -*/ - if (!pmac_i2c_match_adapter(dev, adapter)) - continue; - addr = pmac_i2c_get_dev_addr(dev); - if (loc == NULL || addr == 0) - continue; - /* real lm75 */ - if (of_device_is_compatible(dev, lm75)) -
[PATCH 06/15] powerpc/windfarm: const'ify and add priv field to controls sensors
const'ify the sensor ops and name and add a void* for use by the control and sensor drivers to point back to their private data, avoiding the need to create a wrapper data structure per sensor or control instance. Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org --- drivers/macintosh/windfarm.h | 23 --- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/macintosh/windfarm.h b/drivers/macintosh/windfarm.h index 7a2482c..3ef192a 100644 --- a/drivers/macintosh/windfarm.h +++ b/drivers/macintosh/windfarm.h @@ -35,12 +35,12 @@ struct wf_control_ops { }; struct wf_control { - struct list_headlink; - struct wf_control_ops *ops; - char*name; - int type; - struct kref ref; - struct device_attribute attr; + struct list_headlink; + const struct wf_control_ops *ops; + const char *name; + int type; + struct kref ref; + struct device_attribute attr; }; #define WF_CONTROL_TYPE_GENERIC0 @@ -85,11 +85,12 @@ struct wf_sensor_ops { }; struct wf_sensor { - struct list_headlink; - struct wf_sensor_ops*ops; - char*name; - struct kref ref; - struct device_attribute attr; + struct list_headlink; + const struct wf_sensor_ops *ops; + const char *name; + struct kref ref; + struct device_attribute attr; + void*priv; }; /* Same lifetime rules as controls */ -- 1.7.9.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 15/15] powerpc/powermac: New windfarm driver for PowerMac G5 (AGP) and Xserve G5
This replaces the old therm_pm72 using the same windfarm infrastructure that was used for other PowerMac G5 models. The fan speeds and sensors should now be visible in the same location in sysfs. The driver is split into separate core modules for PowerMac7,2 (and 7,3) and RackMac3,1, with a lot of the shared code now in the separate sensor and control modules. Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org --- drivers/macintosh/Kconfig | 23 +- drivers/macintosh/Makefile | 14 + drivers/macintosh/windfarm.h |3 +- drivers/macintosh/windfarm_core.c | 10 +- drivers/macintosh/windfarm_cpufreq_clamp.c |6 - drivers/macintosh/windfarm_mpu.h | 105 drivers/macintosh/windfarm_pm72.c | 872 drivers/macintosh/windfarm_rm31.c | 765 8 files changed, 1783 insertions(+), 15 deletions(-) create mode 100644 drivers/macintosh/windfarm_mpu.h create mode 100644 drivers/macintosh/windfarm_pm72.c create mode 100644 drivers/macintosh/windfarm_rm31.c diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig index fa51af1..a555da6 100644 --- a/drivers/macintosh/Kconfig +++ b/drivers/macintosh/Kconfig @@ -204,11 +204,14 @@ config THERM_ADT746X better fan behaviour by default, and some manual control. config THERM_PM72 - tristate Support for thermal management on PowerMac G5 + tristate Support for thermal management on PowerMac G5 (AGP) depends on I2C I2C_POWERMAC PPC_PMAC64 + default n help This driver provides thermostat and fan control for the desktop - G5 machines. + G5 machines. + + This is deprecated, use windfarm instead. config WINDFARM tristate New PowerMac thermal control infrastructure @@ -221,6 +224,22 @@ config WINDFARM_PM81 help This driver provides thermal control for the iMacG5 +config WINDFARM_PM72 + tristate Support for thermal management on PowerMac G5 (AGP) + depends on WINDFARM I2C CPU_FREQ_PMAC64 ADB_PMU + select I2C_POWERMAC + help + This driver provides thermal control for the PowerMac G5 + AGP variants (PowerMac 7,2 and 7,3) + +config WINDFARM_RM31 + tristate Support for thermal management on Xserve G5 + depends on WINDFARM I2C CPU_FREQ_PMAC64 ADB_PMU + select I2C_POWERMAC + help + This driver provides thermal control for the Xserve G5 + (RackMac3,1) + config WINDFARM_PM91 tristate Support for thermal management on PowerMac9,1 depends on WINDFARM I2C CPU_FREQ_PMAC64 PMAC_SMU diff --git a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile index 6652a6e..6753b65 100644 --- a/drivers/macintosh/Makefile +++ b/drivers/macintosh/Makefile @@ -29,6 +29,20 @@ obj-$(CONFIG_THERM_PM72) += therm_pm72.o obj-$(CONFIG_THERM_WINDTUNNEL) += therm_windtunnel.o obj-$(CONFIG_THERM_ADT746X)+= therm_adt746x.o obj-$(CONFIG_WINDFARM) += windfarm_core.o +obj-$(CONFIG_WINDFARM_PM72) += windfarm_fcu_controls.o \ + windfarm_ad7417_sensor.o \ + windfarm_lm75_sensor.o \ + windfarm_max6690_sensor.o \ + windfarm_pid.o \ + windfarm_cpufreq_clamp.o \ + windfarm_pm72.o +obj-$(CONFIG_WINDFARM_RM31) += windfarm_fcu_controls.o \ + windfarm_ad7417_sensor.o \ + windfarm_lm75_sensor.o \ + windfarm_lm87_sensor.o \ + windfarm_pid.o \ + windfarm_cpufreq_clamp.o \ + windfarm_rm31.o obj-$(CONFIG_WINDFARM_PM81) += windfarm_smu_controls.o \ windfarm_smu_sensors.o \ windfarm_lm75_sensor.o windfarm_pid.o \ diff --git a/drivers/macintosh/windfarm.h b/drivers/macintosh/windfarm.h index a9e385e..028cdac 100644 --- a/drivers/macintosh/windfarm.h +++ b/drivers/macintosh/windfarm.h @@ -17,7 +17,7 @@ #include linux/device.h /* Display a 16.16 fixed point value */ -#define FIX32TOPRINT(f)((f) 16),f) 0x) * 1000) 16) +#define FIX32TOPRINT(f)(((s32)(f)) 16),(s32)(f)) 0x) * 1000) 16) /* * Control objects @@ -41,6 +41,7 @@ struct wf_control { int type; struct kref ref; struct device_attribute attr; + void*priv; }; #define WF_CONTROL_TYPE_GENERIC0 diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c index ebafc25..3ee198b 100644 ---
[PATCH 04/15] powerpc/pmac: Convert windfarm_max6690 to new i2c probing
This simplifies the driver to stop using the deprecated attach interface Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org --- drivers/macintosh/windfarm_max6690_sensor.c | 100 ++- 1 file changed, 21 insertions(+), 79 deletions(-) diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c index 8204113..f4902f4 100644 --- a/drivers/macintosh/windfarm_max6690_sensor.c +++ b/drivers/macintosh/windfarm_max6690_sensor.c @@ -16,7 +16,7 @@ #include windfarm.h -#define VERSION 0.2 +#define VERSION 1.0 /* This currently only exports the external temperature sensor, since that's all the control loops need. */ @@ -64,9 +64,25 @@ static struct wf_sensor_ops wf_max6690_ops = { static int wf_max6690_probe(struct i2c_client *client, const struct i2c_device_id *id) { + const char *name, *loc; struct wf_6690_sensor *max; int rc; + loc = of_get_property(client-dev.of_node, hwsensor-location, NULL); + if (!loc) { + dev_warn(client-dev, Missing hwsensor-location property!\n); + return -ENXIO; + } + + if (!strcmp(loc, BACKSIDE)) + name = backside-temp; + else if (!strcmp(loc, NB Ambient)) + name = north-bridge-temp; + else if (!strcmp(loc, GPU Ambient)) + name = gpu-temp; + else + return -ENXIO; + max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL); if (max == NULL) { printk(KERN_ERR windfarm: Couldn't create MAX6690 sensor: @@ -75,90 +91,16 @@ static int wf_max6690_probe(struct i2c_client *client, } max-i2c = client; - max-sens.name = client-dev.platform_data; + max-sens.name = (char *)name; /* XXX fix constness in structure */ max-sens.ops = wf_max6690_ops; i2c_set_clientdata(client, max); rc = wf_register_sensor(max-sens); - if (rc) { + if (rc) kfree(max); - } - return rc; } -static struct i2c_driver wf_max6690_driver; - -static struct i2c_client *wf_max6690_create(struct i2c_adapter *adapter, - u8 addr, const char *loc) -{ - struct i2c_board_info info; - struct i2c_client *client; - char *name; - - if (!strcmp(loc, BACKSIDE)) - name = backside-temp; - else if (!strcmp(loc, NB Ambient)) - name = north-bridge-temp; - else if (!strcmp(loc, GPU Ambient)) - name = gpu-temp; - else - goto fail; - - memset(info, 0, sizeof(struct i2c_board_info)); - info.addr = addr 1; - info.platform_data = name; - strlcpy(info.type, wf_max6690, I2C_NAME_SIZE); - - client = i2c_new_device(adapter, info); - if (client == NULL) { - printk(KERN_ERR windfarm: failed to attach MAX6690 sensor\n); - goto fail; - } - - /* -* Let i2c-core delete that device on driver removal. -* This is safe because i2c-core holds the core_lock mutex for us. -*/ - list_add_tail(client-detected, wf_max6690_driver.clients); - return client; - - fail: - return NULL; -} - -static int wf_max6690_attach(struct i2c_adapter *adapter) -{ - struct device_node *busnode, *dev = NULL; - struct pmac_i2c_bus *bus; - const char *loc; - - bus = pmac_i2c_adapter_to_bus(adapter); - if (bus == NULL) - return -ENODEV; - busnode = pmac_i2c_get_bus_node(bus); - - while ((dev = of_get_next_child(busnode, dev)) != NULL) { - u8 addr; - - /* We must re-match the adapter in order to properly check -* the channel on multibus setups -*/ - if (!pmac_i2c_match_adapter(dev, adapter)) - continue; - if (!of_device_is_compatible(dev, max6690)) - continue; - addr = pmac_i2c_get_dev_addr(dev); - loc = of_get_property(dev, hwsensor-location, NULL); - if (loc == NULL || addr == 0) - continue; - printk(found max6690, loc=%s addr=0x%02x\n, loc, addr); - wf_max6690_create(adapter, addr, loc); - } - - return 0; -} - static int wf_max6690_remove(struct i2c_client *client) { struct wf_6690_sensor *max = i2c_get_clientdata(client); @@ -170,15 +112,15 @@ static int wf_max6690_remove(struct i2c_client *client) } static const struct i2c_device_id wf_max6690_id[] = { - { wf_max6690, 0 }, + { MAC,max6690, 0 }, { } }; +MODULE_DEVICE_TABLE(i2c, wf_max6690_id); static struct i2c_driver wf_max6690_driver = { .driver = { .name = wf_max6690, }, - .attach_adapter = wf_max6690_attach,
[PATCH 05/15] powerpc/pmac: Convert windfarm_smu_sat to new i2c probing
This simplifies the driver to stop using the deprecated attach interface. While at it we also implement teardown properly and fix the refcounting by using a kref. Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org --- drivers/macintosh/windfarm_smu_sat.c | 126 +- 1 file changed, 47 insertions(+), 79 deletions(-) diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c index 65a8ff3..72dfe19 100644 --- a/drivers/macintosh/windfarm_smu_sat.c +++ b/drivers/macintosh/windfarm_smu_sat.c @@ -20,7 +20,7 @@ #include windfarm.h -#define VERSION 0.2 +#define VERSION 1.0 #define DEBUG @@ -34,11 +34,12 @@ #define MAX_AGEmsecs_to_jiffies(800) struct wf_sat { + struct kref ref; int nr; - atomic_trefcnt; struct mutexmutex; unsigned long last_read; /* jiffies when cache last updated */ u8 cache[16]; + struct list_headsensors; struct i2c_client *i2c; struct device_node *node; }; @@ -46,11 +47,12 @@ struct wf_sat { static struct wf_sat *sats[2]; struct wf_sat_sensor { - int index; - int index2; /* used for power sensors */ - int shift; - struct wf_sat *sat; - struct wf_sensor sens; + struct list_headlink; + int index; + int index2; /* used for power sensors */ + int shift; + struct wf_sat *sat; + struct wf_sensorsens; }; #define wf_to_sat(c) container_of(c, struct wf_sat_sensor, sens) @@ -142,7 +144,7 @@ static int wf_sat_read_cache(struct wf_sat *sat) return 0; } -static int wf_sat_get(struct wf_sensor *sr, s32 *value) +static int wf_sat_sensor_get(struct wf_sensor *sr, s32 *value) { struct wf_sat_sensor *sens = wf_to_sat(sr); struct wf_sat *sat = sens-sat; @@ -175,58 +177,30 @@ static int wf_sat_get(struct wf_sensor *sr, s32 *value) return err; } -static void wf_sat_release(struct wf_sensor *sr) +static void wf_sat_release(struct kref *ref) +{ + struct wf_sat *sat = container_of(ref, struct wf_sat, ref); + + if (sat-nr = 0) + sats[sat-nr] = NULL; + kfree(sat); +} + +static void wf_sat_sensor_release(struct wf_sensor *sr) { struct wf_sat_sensor *sens = wf_to_sat(sr); struct wf_sat *sat = sens-sat; - if (atomic_dec_and_test(sat-refcnt)) { - if (sat-nr = 0) - sats[sat-nr] = NULL; - kfree(sat); - } kfree(sens); + kref_put(sat-ref, wf_sat_release); } static struct wf_sensor_ops wf_sat_ops = { - .get_value = wf_sat_get, - .release= wf_sat_release, + .get_value = wf_sat_sensor_get, + .release= wf_sat_sensor_release, .owner = THIS_MODULE, }; -static struct i2c_driver wf_sat_driver; - -static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev) -{ - struct i2c_board_info info; - struct i2c_client *client; - const u32 *reg; - u8 addr; - - reg = of_get_property(dev, reg, NULL); - if (reg == NULL) - return; - addr = *reg; - DBG(KERN_DEBUG wf_sat: creating sat at address %x\n, addr); - - memset(info, 0, sizeof(struct i2c_board_info)); - info.addr = (addr 1) 0x7f; - info.platform_data = dev; - strlcpy(info.type, wf_sat, I2C_NAME_SIZE); - - client = i2c_new_device(adapter, info); - if (client == NULL) { - printk(KERN_ERR windfarm: failed to attach smu-sat to i2c\n); - return; - } - - /* -* Let i2c-core delete that device on driver removal. -* This is safe because i2c-core holds the core_lock mutex for us. -*/ - list_add_tail(client-detected, wf_sat_driver.clients); -} - static int wf_sat_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -246,9 +220,10 @@ static int wf_sat_probe(struct i2c_client *client, return -ENOMEM; sat-nr = -1; sat-node = of_node_get(dev); - atomic_set(sat-refcnt, 0); + kref_init(sat-ref); mutex_init(sat-mutex); sat-i2c = client; + INIT_LIST_HEAD(sat-sensors); i2c_set_clientdata(client, sat); vsens[0] = vsens[1] = -1; @@ -310,14 +285,15 @@ static int wf_sat_probe(struct i2c_client *client, sens-index2 = -1; sens-shift = shift; sens-sat = sat; - atomic_inc(sat-refcnt); sens-sens.ops = wf_sat_ops; sens-sens.name = (char *) (sens + 1); snprintf(sens-sens.name, 16,
[PATCH 12/15] powerpc/windfarm: Add lm87 sensor
For use by the upcoming windfarm_rm31 Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org --- drivers/macintosh/windfarm_lm87_sensor.c | 201 ++ 1 file changed, 201 insertions(+) create mode 100644 drivers/macintosh/windfarm_lm87_sensor.c diff --git a/drivers/macintosh/windfarm_lm87_sensor.c b/drivers/macintosh/windfarm_lm87_sensor.c new file mode 100644 index 000..c071aab --- /dev/null +++ b/drivers/macintosh/windfarm_lm87_sensor.c @@ -0,0 +1,201 @@ +/* + * Windfarm PowerMac thermal control. LM87 sensor + * + * Copyright 2012 Benjamin Herrenschmidt, IBM Corp. + * + * Released under the term of the GNU GPL v2. + * + */ + +#include linux/types.h +#include linux/errno.h +#include linux/kernel.h +#include linux/delay.h +#include linux/slab.h +#include linux/init.h +#include linux/wait.h +#include linux/i2c.h +#include asm/prom.h +#include asm/machdep.h +#include asm/io.h +#include asm/sections.h +#include asm/pmac_low_i2c.h + +#include windfarm.h + +#define VERSION 1.0 + +#undef DEBUG + +#ifdef DEBUG +#define DBG(args...) printk(args) +#else +#define DBG(args...) do { } while(0) +#endif + +struct wf_lm87_sensor { + struct i2c_client *i2c; + struct wf_sensorsens; +}; +#define wf_to_lm87(c) container_of(c, struct wf_lm87_sensor, sens) + + +static int wf_lm87_read_reg(struct i2c_client *chip, int reg) +{ + int rc, tries = 0; + u8 buf; + + for (;;) { + /* Set address */ + buf = (u8)reg; + rc = i2c_master_send(chip, buf, 1); + if (rc = 0) + goto error; + rc = i2c_master_recv(chip, buf, 1); + if (rc = 0) + goto error; + return (int)buf; + error: + DBG(wf_lm87: Error reading LM87, retrying...\n); + if (++tries 10) { + printk(KERN_ERR wf_lm87: Error reading LM87 !\n); + return -EIO; + } + msleep(10); + } +} + +static int wf_lm87_get(struct wf_sensor *sr, s32 *value) +{ + struct wf_lm87_sensor *lm = sr-priv; + s32 temp; + + if (lm-i2c == NULL) + return -ENODEV; + +#define LM87_INT_TEMP 0x27 + + /* Read temperature register */ + temp = wf_lm87_read_reg(lm-i2c, LM87_INT_TEMP); + if (temp 0) + return temp; + *value = temp 16; + + return 0; +} + +static void wf_lm87_release(struct wf_sensor *sr) +{ + struct wf_lm87_sensor *lm = wf_to_lm87(sr); + + kfree(lm); +} + +static struct wf_sensor_ops wf_lm87_ops = { + .get_value = wf_lm87_get, + .release= wf_lm87_release, + .owner = THIS_MODULE, +}; + +static int wf_lm87_probe(struct i2c_client *client, +const struct i2c_device_id *id) +{ + struct wf_lm87_sensor *lm; + const char *name = NULL, *loc; + struct device_node *np = NULL; + int rc; + + /* +* The lm87 contains a whole pile of sensors, additionally, +* the Xserve G5 has several lm87's. However, for now we only +* care about the internal temperature sensor +*/ + while ((np = of_get_next_child(client-dev.of_node, np)) != NULL) { + if (strcmp(np-name, int-temp)) + continue; + loc = of_get_property(np, location, NULL); + if (!loc) + continue; + if (strstr(loc, DIMM)) + name = dimms-temp; + else if (strstr(loc, Processors)) + name = between-cpus-temp; + if (name) { + of_node_put(np); + break; + } + } + if (!name) { + pr_warning(wf_lm87: Unsupported sensor %s\n, + client-dev.of_node-full_name); + return -ENODEV; + } + + lm = kzalloc(sizeof(struct wf_lm87_sensor), GFP_KERNEL); + if (lm == NULL) + return -ENODEV; + + lm-i2c = client; + lm-sens.name = name; + lm-sens.ops = wf_lm87_ops; + lm-sens.priv = lm; + i2c_set_clientdata(client, lm); + + rc = wf_register_sensor(lm-sens); + if (rc) + kfree(lm); + return rc; +} + +static int wf_lm87_remove(struct i2c_client *client) +{ + struct wf_lm87_sensor *lm = i2c_get_clientdata(client); + + DBG(wf_lm87: i2c detatch called for %s\n, lm-sens.name); + + /* Mark client detached */ + lm-i2c = NULL; + + /* release sensor */ + wf_unregister_sensor(lm-sens); + + return 0; +} + +static const struct i2c_device_id wf_lm87_id[] = { + { MAC,lm87cimt, 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, wf_lm87_id); + +static struct i2c_driver wf_lm87_driver = { + .driver = { +
[PATCH 14/15] powerpc/windfarm: Add Fan Control Unit controls for G5s
The FCU operates the fans on the earlier generation G5 machines, this module will be used by upcoming windfarm drivers. Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org --- drivers/macintosh/windfarm_fcu_controls.c | 617 + 1 file changed, 617 insertions(+) create mode 100644 drivers/macintosh/windfarm_fcu_controls.c diff --git a/drivers/macintosh/windfarm_fcu_controls.c b/drivers/macintosh/windfarm_fcu_controls.c new file mode 100644 index 000..871f8b4 --- /dev/null +++ b/drivers/macintosh/windfarm_fcu_controls.c @@ -0,0 +1,617 @@ +/* + * Windfarm PowerMac thermal control. FCU fan control + * + * Copyright 2012 Benjamin Herrenschmidt, IBM Corp. + * + * Released under the term of the GNU GPL v2. + */ +#undef DEBUG + +#include linux/types.h +#include linux/errno.h +#include linux/kernel.h +#include linux/delay.h +#include linux/slab.h +#include linux/init.h +#include linux/wait.h +#include linux/i2c.h +#include asm/prom.h +#include asm/machdep.h +#include asm/io.h +#include asm/sections.h + +#include windfarm.h +#include windfarm_mpu.h + +#define VERSION 1.0 + +#ifdef DEBUG +#define DBG(args...) printk(args) +#else +#define DBG(args...) do { } while(0) +#endif + +/* + * This option is weird :) Basically, if you define this to 1 + * the control loop for the RPMs fans (not PWMs) will apply the + * correction factor obtained from the PID to the actual RPM + * speed read from the FCU. + * + * If you define the below constant to 0, then it will be + * applied to the setpoint RPM speed, that is basically the + * speed we proviously asked for. + * + * I'm not sure which of these Apple's algorithm is supposed + * to use + */ +#define RPM_PID_USE_ACTUAL_SPEED 1 + +/* Default min/max for pumps */ +#define CPU_PUMP_OUTPUT_MAX3200 +#define CPU_PUMP_OUTPUT_MIN1250 + +#define FCU_FAN_RPM0 +#define FCU_FAN_PWM1 + +struct wf_fcu_priv { + struct kref ref; + struct i2c_client *i2c; + struct mutexlock; + struct list_headfan_list; + int rpm_shift; +}; + +struct wf_fcu_fan { + struct list_headlink; + int id; + s32 min, max, target; + struct wf_fcu_priv *fcu_priv; + struct wf_control ctrl; +}; + +static void wf_fcu_release(struct kref *ref) +{ + struct wf_fcu_priv *pv = container_of(ref, struct wf_fcu_priv, ref); + + kfree(pv); +} + +static void wf_fcu_fan_release(struct wf_control *ct) +{ + struct wf_fcu_fan *fan = ct-priv; + + kref_put(fan-fcu_priv-ref, wf_fcu_release); + kfree(fan); +} + +static int wf_fcu_read_reg(struct wf_fcu_priv *pv, int reg, + unsigned char *buf, int nb) +{ + int tries, nr, nw; + + mutex_lock(pv-lock); + + buf[0] = reg; + tries = 0; + for (;;) { + nw = i2c_master_send(pv-i2c, buf, 1); + if (nw 0 || (nw 0 nw != -EIO) || tries = 100) + break; + msleep(10); + ++tries; + } + if (nw = 0) { + pr_err(Failure writing address to FCU: %d, nw); + nr = nw; + goto bail; + } + tries = 0; + for (;;) { + nr = i2c_master_recv(pv-i2c, buf, nb); + if (nr 0 || (nr 0 nr != -ENODEV) || tries = 100) + break; + msleep(10); + ++tries; + } + if (nr = 0) + pr_err(wf_fcu: Failure reading data from FCU: %d, nw); + bail: + mutex_unlock(pv-lock); + return nr; +} + +static int wf_fcu_write_reg(struct wf_fcu_priv *pv, int reg, + const unsigned char *ptr, int nb) +{ + int tries, nw; + unsigned char buf[16]; + + buf[0] = reg; + memcpy(buf+1, ptr, nb); + ++nb; + tries = 0; + for (;;) { + nw = i2c_master_send(pv-i2c, buf, nb); + if (nw 0 || (nw 0 nw != -EIO) || tries = 100) + break; + msleep(10); + ++tries; + } + if (nw 0) + pr_err(wf_fcu: Failure writing to FCU: %d, nw); + return nw; +} + +static int wf_fcu_fan_set_rpm(struct wf_control *ct, s32 value) +{ + struct wf_fcu_fan *fan = ct-priv; + struct wf_fcu_priv *pv = fan-fcu_priv; + int rc, shift = pv-rpm_shift; + unsigned char buf[2]; + + if (value fan-min) + value = fan-min; + if (value fan-max) + value = fan-max; + + if (fan-target fan-target == value) + return 0; + fan-target = value; + + buf[0] = value (8 - shift); + buf[1] = value shift; + rc = wf_fcu_write_reg(pv, 0x10 + (fan-id * 2), buf, 2); + if (rc 0) + return -EIO; + return 0;
[PATCH 11/15] powerpc/windfarm: Add ad7417 sensor
For user by the upcoming windfarm_pm72 and windfarm_rm31 Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org --- drivers/macintosh/windfarm_ad7417_sensor.c | 347 1 file changed, 347 insertions(+) create mode 100644 drivers/macintosh/windfarm_ad7417_sensor.c diff --git a/drivers/macintosh/windfarm_ad7417_sensor.c b/drivers/macintosh/windfarm_ad7417_sensor.c new file mode 100644 index 000..ac3f243 --- /dev/null +++ b/drivers/macintosh/windfarm_ad7417_sensor.c @@ -0,0 +1,347 @@ +/* + * Windfarm PowerMac thermal control. AD7417 sensors + * + * Copyright 2012 Benjamin Herrenschmidt, IBM Corp. + * + * Released under the term of the GNU GPL v2. + */ + +#include linux/types.h +#include linux/errno.h +#include linux/kernel.h +#include linux/delay.h +#include linux/slab.h +#include linux/init.h +#include linux/wait.h +#include linux/i2c.h +#include asm/prom.h +#include asm/machdep.h +#include asm/io.h +#include asm/sections.h + +#include windfarm.h +#include windfarm_mpu.h + +#define VERSION 1.0 + +struct wf_ad7417_priv { + struct kref ref; + struct i2c_client *i2c; + u8 config; + u8 cpu; + const struct mpu_data *mpu; + struct wf_sensorsensors[5]; + struct mutexlock; +}; + +static int wf_ad7417_temp_get(struct wf_sensor *sr, s32 *value) +{ + struct wf_ad7417_priv *pv = sr-priv; + u8 buf[2]; + s16 raw; + int rc; + + *value = 0; + mutex_lock(pv-lock); + + /* Read temp register */ + buf[0] = 0; + rc = i2c_master_send(pv-i2c, buf, 1); + if (rc 0) + goto error; + rc = i2c_master_recv(pv-i2c, buf, 2); + if (rc 0) + goto error; + + /* Read a a 16-bit signed value */ + raw = be16_to_cpup((__le16 *)buf); + + /* Convert 8.8-bit to 16.16 fixed point */ + *value = ((s32)raw) 8; + + mutex_unlock(pv-lock); + return 0; + +error: + mutex_unlock(pv-lock); + return -1; +} + +/* + * Scaling factors for the AD7417 ADC converters (except + * for the CPU diode which is obtained from the EEPROM). + * Those values are obtained from the property list of + * the darwin driver + */ +#define ADC_12V_CURRENT_SCALE 0x0320 /* _AD2 */ +#define ADC_CPU_VOLTAGE_SCALE 0x00a0 /* _AD3 */ +#define ADC_CPU_CURRENT_SCALE 0x1f40 /* _AD4 */ + +static void wf_ad7417_adc_convert(struct wf_ad7417_priv *pv, + int chan, s32 raw, s32 *value) +{ + switch(chan) { + case 1: /* Diode */ + *value = (raw * (s32)pv-mpu-mdiode + + ((s32)pv-mpu-bdiode 12)) 2; + break; + case 2: /* 12v current */ + *value = raw * ADC_12V_CURRENT_SCALE; + break; + case 3: /* core voltage */ + *value = raw * ADC_CPU_VOLTAGE_SCALE; + break; + case 4: /* core current */ + *value = raw * ADC_CPU_CURRENT_SCALE; + break; + } +} + +static int wf_ad7417_adc_get(struct wf_sensor *sr, s32 *value) +{ + struct wf_ad7417_priv *pv = sr-priv; + int chan = sr - pv-sensors; + int i, rc; + u8 buf[2]; + u16 raw; + + *value = 0; + mutex_lock(pv-lock); + for (i = 0; i 10; i++) { + /* Set channel */ + buf[0] = 1; + buf[1] = (pv-config 0x1f) | (chan 5); + rc = i2c_master_send(pv-i2c, buf, 2); + if (rc 0) + goto error; + + /* Wait for conversion */ + msleep(1); + + /* Switch to data register */ + buf[0] = 4; + rc = i2c_master_send(pv-i2c, buf, 1); + if (rc 0) + goto error; + + /* Read result */ + rc = i2c_master_recv(pv-i2c, buf, 2); + if (rc 0) + goto error; + + /* Read a a 16-bit signed value */ + raw = be16_to_cpup((__le16 *)buf) 6; + wf_ad7417_adc_convert(pv, chan, raw, value); + + dev_vdbg(pv-i2c-dev, ADC chan %d [%s] + raw value: 0x%x, conv to: 0x%08x\n, +chan, sr-name, raw, *value); + + mutex_unlock(pv-lock); + return 0; + + error: + dev_dbg(pv-i2c-dev, + Error reading ADC, try %d...\n, i); + if (i 9) + msleep(10); + } + mutex_unlock(pv-lock); + return -1; +} + +static void wf_ad7417_release(struct kref *ref) +{ + struct wf_ad7417_priv *pv = container_of(ref, +struct wf_ad7417_priv, ref); + kfree(pv); +} + +static void wf_ad7417_sensor_release(struct wf_sensor *sr) +{ + struct
[PATCH 02/15] powerpc/pmac: Convert therm_adt746x to new i2c probing
This simplifies the driver to stop using the deprecated attach interface, Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org --- drivers/macintosh/therm_adt746x.c | 480 - 1 file changed, 204 insertions(+), 276 deletions(-) diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c index fc71723..f433521 100644 --- a/drivers/macintosh/therm_adt746x.c +++ b/drivers/macintosh/therm_adt746x.c @@ -47,7 +47,7 @@ static u8 FAN_SPD_SET[2] = {0x30, 0x31}; static u8 default_limits_local[3] = {70, 50, 70};/* local, sensor1, sensor2 */ static u8 default_limits_chip[3] = {80, 65, 80};/* local, sensor1, sensor2 */ -static const char *sensor_location[3]; +static const char *sensor_location[3] = { ?, ?, ? }; static int limit_adjust; static int fan_speed = -1; @@ -79,18 +79,16 @@ struct thermostat { int last_speed[2]; int last_var[2]; int pwm_inv[2]; + struct task_struct *thread; + struct platform_device *pdev; + enum { + ADT7460, + ADT7467 + } type; }; -static enum {ADT7460, ADT7467} therm_type; -static int therm_bus, therm_address; -static struct platform_device * of_dev; -static struct thermostat* thermostat; -static struct task_struct *thread_therm = NULL; - static void write_both_fan_speed(struct thermostat *th, int speed); static void write_fan_speed(struct thermostat *th, int speed, int fan); -static void thermostat_create_files(void); -static void thermostat_remove_files(void); static int write_reg(struct thermostat* th, int reg, u8 data) @@ -126,66 +124,6 @@ read_reg(struct thermostat* th, int reg) return data; } -static struct i2c_driver thermostat_driver; - -static int -attach_thermostat(struct i2c_adapter *adapter) -{ - unsigned long bus_no; - struct i2c_board_info info; - struct i2c_client *client; - - if (strncmp(adapter-name, uni-n, 5)) - return -ENODEV; - bus_no = simple_strtoul(adapter-name + 6, NULL, 10); - if (bus_no != therm_bus) - return -ENODEV; - - memset(info, 0, sizeof(struct i2c_board_info)); - strlcpy(info.type, therm_adt746x, I2C_NAME_SIZE); - info.addr = therm_address; - client = i2c_new_device(adapter, info); - if (!client) - return -ENODEV; - - /* -* Let i2c-core delete that device on driver removal. -* This is safe because i2c-core holds the core_lock mutex for us. -*/ - list_add_tail(client-detected, thermostat_driver.clients); - return 0; -} - -static int -remove_thermostat(struct i2c_client *client) -{ - struct thermostat *th = i2c_get_clientdata(client); - int i; - - thermostat_remove_files(); - - if (thread_therm != NULL) { - kthread_stop(thread_therm); - } - - printk(KERN_INFO adt746x: Putting max temperatures back from -%d, %d, %d to %d, %d, %d\n, - th-limits[0], th-limits[1], th-limits[2], - th-initial_limits[0], th-initial_limits[1], - th-initial_limits[2]); - - for (i = 0; i 3; i++) - write_reg(th, LIMIT_REG[i], th-initial_limits[i]); - - write_both_fan_speed(th, -1); - - thermostat = NULL; - - kfree(th); - - return 0; -} - static int read_fan_speed(struct thermostat *th, u8 addr) { u8 tmp[2]; @@ -203,7 +141,7 @@ static int read_fan_speed(struct thermostat *th, u8 addr) static void write_both_fan_speed(struct thermostat *th, int speed) { write_fan_speed(th, speed, 0); - if (therm_type == ADT7460) + if (th-type == ADT7460) write_fan_speed(th, speed, 1); } @@ -216,7 +154,7 @@ static void write_fan_speed(struct thermostat *th, int speed, int fan) else if (speed -1) speed = 0; - if (therm_type == ADT7467 fan == 1) + if (th-type == ADT7467 fan == 1) return; if (th-last_speed[fan] != speed) { @@ -239,7 +177,7 @@ static void write_fan_speed(struct thermostat *th, int speed, int fan) write_reg(th, FAN_SPD_SET[fan], speed); } else { /* back to automatic */ - if(therm_type == ADT7460) { + if(th-type == ADT7460) { manual = read_reg(th, MANUAL_MODE[fan]) (~MANUAL_MASK); manual = ~INVERT_MASK; @@ -293,7 +231,7 @@ static void update_fans_speed (struct thermostat *th) /* we don't care about local sensor, so we start at sensor 1 */ for (i = 1; i 3; i++) { int started = 0; - int fan_number = (therm_type == ADT7460 i == 2); + int fan_number = (th-type == ADT7460 i == 2);
[PATCH 08/15] powerpc/windfarm: Remove spurrious sysfs_attr_init()
The windfarm core will do it, so this is a duplicate. Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org --- drivers/macintosh/windfarm_smu_controls.c |1 - 1 file changed, 1 deletion(-) diff --git a/drivers/macintosh/windfarm_smu_controls.c b/drivers/macintosh/windfarm_smu_controls.c index 3c2be51..c155a54 100644 --- a/drivers/macintosh/windfarm_smu_controls.c +++ b/drivers/macintosh/windfarm_smu_controls.c @@ -172,7 +172,6 @@ static struct smu_fan_control *smu_fan_create(struct device_node *node, fct-fan_type = pwm_fan; fct-ctrl.type = pwm_fan ? WF_CONTROL_PWM_FAN : WF_CONTROL_RPM_FAN; - sysfs_attr_init(fct-ctrl.attr.attr); /* We use the name location here the same way we do for SMU sensors, * see the comment in windfarm_smu_sensors.c. The locations are a bit -- 1.7.9.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 10/15] powerpc/windfarm: Add useful accessors
Makes the code more readable Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org --- drivers/macintosh/windfarm.h | 25 + drivers/macintosh/windfarm_pm81.c | 25 - drivers/macintosh/windfarm_pm91.c | 33 +++-- 3 files changed, 52 insertions(+), 31 deletions(-) diff --git a/drivers/macintosh/windfarm.h b/drivers/macintosh/windfarm.h index 3ef192a..a9e385e 100644 --- a/drivers/macintosh/windfarm.h +++ b/drivers/macintosh/windfarm.h @@ -72,6 +72,26 @@ static inline int wf_control_set_min(struct wf_control *ct) return ct-ops-set_value(ct, vmin); } +static inline int wf_control_set(struct wf_control *ct, s32 val) +{ + return ct-ops-set_value(ct, val); +} + +static inline int wf_control_get(struct wf_control *ct, s32 *val) +{ + return ct-ops-get_value(ct, val); +} + +static inline s32 wf_control_get_min(struct wf_control *ct) +{ + return ct-ops-get_min(ct); +} + +static inline s32 wf_control_get_max(struct wf_control *ct) +{ + return ct-ops-get_max(ct); +} + /* * Sensor objects */ @@ -100,6 +120,11 @@ extern struct wf_sensor * wf_find_sensor(const char *name); extern int wf_get_sensor(struct wf_sensor *sr); extern void wf_put_sensor(struct wf_sensor *sr); +static inline int wf_sensor_get(struct wf_sensor *sr, s32 *val) +{ + return sr-ops-get_value(sr, val); +} + /* For use by clients. Note that we are a bit racy here since * notifier_block doesn't have a module owner field. I may fix * it one day ... diff --git a/drivers/macintosh/windfarm_pm81.c b/drivers/macintosh/windfarm_pm81.c index fc13d0f..990c876 100644 --- a/drivers/macintosh/windfarm_pm81.c +++ b/drivers/macintosh/windfarm_pm81.c @@ -302,13 +302,13 @@ static void wf_smu_create_sys_fans(void) pid_param.interval = WF_SMU_SYS_FANS_INTERVAL; pid_param.history_len = WF_SMU_SYS_FANS_HISTORY_SIZE; pid_param.itarget = param-itarget; - pid_param.min = fan_system-ops-get_min(fan_system); - pid_param.max = fan_system-ops-get_max(fan_system); + pid_param.min = wf_control_get_min(fan_system); + pid_param.max = wf_control_get_max(fan_system); if (fan_hd) { pid_param.min = - max(pid_param.min,fan_hd-ops-get_min(fan_hd)); + max(pid_param.min, wf_control_get_min(fan_hd)); pid_param.max = - min(pid_param.max,fan_hd-ops-get_max(fan_hd)); + min(pid_param.max, wf_control_get_max(fan_hd)); } wf_pid_init(wf_smu_sys_fans-pid, pid_param); @@ -337,7 +337,7 @@ static void wf_smu_sys_fans_tick(struct wf_smu_sys_fans_state *st) } st-ticks = WF_SMU_SYS_FANS_INTERVAL; - rc = sensor_hd_temp-ops-get_value(sensor_hd_temp, temp); + rc = wf_sensor_get(sensor_hd_temp, temp); if (rc) { printk(KERN_WARNING windfarm: HD temp sensor error %d\n, rc); @@ -373,7 +373,7 @@ static void wf_smu_sys_fans_tick(struct wf_smu_sys_fans_state *st) st-hd_setpoint = new_setpoint; readjust: if (fan_system wf_smu_failure_state == 0) { - rc = fan_system-ops-set_value(fan_system, st-sys_setpoint); + rc = wf_control_set(fan_system, st-sys_setpoint); if (rc) { printk(KERN_WARNING windfarm: Sys fan error %d\n, rc); @@ -381,7 +381,7 @@ static void wf_smu_sys_fans_tick(struct wf_smu_sys_fans_state *st) } } if (fan_hd wf_smu_failure_state == 0) { - rc = fan_hd-ops-set_value(fan_hd, st-hd_setpoint); + rc = wf_control_set(fan_hd, st-hd_setpoint); if (rc) { printk(KERN_WARNING windfarm: HD fan error %d\n, rc); @@ -447,8 +447,8 @@ static void wf_smu_create_cpu_fans(void) pid_param.ttarget = tmax - tdelta; pid_param.pmaxadj = maxpow - powadj; - pid_param.min = fan_cpu_main-ops-get_min(fan_cpu_main); - pid_param.max = fan_cpu_main-ops-get_max(fan_cpu_main); + pid_param.min = wf_control_get_min(fan_cpu_main); + pid_param.max = wf_control_get_max(fan_cpu_main); wf_cpu_pid_init(wf_smu_cpu_fans-pid, pid_param); @@ -481,7 +481,7 @@ static void wf_smu_cpu_fans_tick(struct wf_smu_cpu_fans_state *st) } st-ticks = WF_SMU_CPU_FANS_INTERVAL; - rc = sensor_cpu_temp-ops-get_value(sensor_cpu_temp, temp); + rc = wf_sensor_get(sensor_cpu_temp, temp); if (rc) { printk(KERN_WARNING windfarm: CPU temp sensor error %d\n, rc); @@ -489,7 +489,7 @@ static void wf_smu_cpu_fans_tick(struct wf_smu_cpu_fans_state *st) return; } - rc = sensor_cpu_power-ops-get_value(sensor_cpu_power, power); + rc =
[PATCH 00/15] PowerMac i2c API conversions windfarm updates
The goal of this series is to convert a bulk of PowerMac i2c drivers to the new proper i2c driver registration model. This series is not complete in that there are still a few drivers to do but it goes through the bulk of thermal control and some of the nastiest. The biggest change is that windfarm is ported to generally use the new model, and I've written a new set of windfarm modules to take over from the old therm_pm72 (which was mostly unfixable) on the PowerMac G5 AGP and Xserve G5 machines. This had a bit of testing on a couple of PowerMac G5 AGP variants but none at all on Xserve G5 since the one I have is unfortunately dead. If you want to help me test this, don't forget to disable therm_pm72, and instead load windfarm_pm72 or windfarm_rm31 depending on your machine (you can load or build-in the whole lot as well). As usual windfarm don't properly auto-load yet, I still need to fix that. So please test ! Especially if you have an XServe G5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 07/15] powerpc/pmac: Don't add_timer() twice
If the interrupt and the timeout happen roughly at the same time, we can get into a situation where the timer function is run while the interrupt has already been processed. In this case, the timer function might end up doing an add_timer on an already pending timer, causing a BUG_ON() to trigger. Instead, just skip the whole timeout operation if we see that the timer is pending. The spinlock ensures that the only way that happens is if we already started a new operation and thus the timeout can be ignored. Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org --- arch/powerpc/platforms/powermac/low_i2c.c |9 + 1 file changed, 9 insertions(+) diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c index f991dbb..fc536f2 100644 --- a/arch/powerpc/platforms/powermac/low_i2c.c +++ b/arch/powerpc/platforms/powermac/low_i2c.c @@ -366,11 +366,20 @@ static void kw_i2c_timeout(unsigned long data) unsigned long flags; spin_lock_irqsave(host-lock, flags); + + /* +* If the timer is pending, that means we raced with the +* irq, in which case we just return +*/ + if (timer_pending(host-timeout_timer)) + goto skip; + kw_i2c_handle_interrupt(host, kw_read_reg(reg_isr)); if (host-state != state_idle) { host-timeout_timer.expires = jiffies + KW_POLL_TIMEOUT; add_timer(host-timeout_timer); } + skip: spin_unlock_irqrestore(host-lock, flags); } -- 1.7.9.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 13/15] powerpc/windfarm: Updates to lm75 and max6690 sensors
This allows those modules to load on PowerMac7,2 PowerMac7,3 and RackMac3,1 and add the sensor name conversion for those machines. This will be used by the corresponding new windfarm modules for those machines. Note that since therm_pm72 is linked first, it will still take priority on those i2c devices if built-in. If using modules it will depend which is loaded first, but you should avoid building therm_pm72 if you are using the new windfarm drivers Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org --- drivers/macintosh/windfarm_lm75_sensor.c| 11 ++- drivers/macintosh/windfarm_max6690_sensor.c | 11 +-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c index 4cc3f93..b0c2d36 100644 --- a/drivers/macintosh/windfarm_lm75_sensor.c +++ b/drivers/macintosh/windfarm_lm75_sensor.c @@ -116,6 +116,12 @@ static int wf_lm75_probe(struct i2c_client *client, name = optical-drive-temp; else if (!strcmp(loc, HD Temp)) name = hard-drive-temp; + else if (!strcmp(loc, PCI SLOTS)) + name = slots-temp; + else if (!strcmp(loc, CPU A INLET)) + name = cpu-inlet-temp-0; + else if (!strcmp(loc, CPU B INLET)) + name = cpu-inlet-temp-1; else return -ENXIO; @@ -170,11 +176,6 @@ static struct i2c_driver wf_lm75_driver = { static int __init wf_lm75_sensor_init(void) { - /* Don't register on old machines that use therm_pm72 for now */ - if (of_machine_is_compatible(PowerMac7,2) || - of_machine_is_compatible(PowerMac7,3) || - of_machine_is_compatible(RackMac3,1)) - return -ENODEV; return i2c_add_driver(wf_lm75_driver); } diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c index f4902f4..371b058 100644 --- a/drivers/macintosh/windfarm_max6690_sensor.c +++ b/drivers/macintosh/windfarm_max6690_sensor.c @@ -74,7 +74,11 @@ static int wf_max6690_probe(struct i2c_client *client, return -ENXIO; } - if (!strcmp(loc, BACKSIDE)) + /* +* We only expose the external temperature register for +* now as this is all we need for our control loops +*/ + if (!strcmp(loc, BACKSIDE) || !strcmp(loc, SYS CTRLR AMBIENT)) name = backside-temp; else if (!strcmp(loc, NB Ambient)) name = north-bridge-temp; @@ -128,11 +132,6 @@ static struct i2c_driver wf_max6690_driver = { static int __init wf_max6690_sensor_init(void) { - /* Don't register on old machines that use therm_pm72 for now */ - if (of_machine_is_compatible(PowerMac7,2) || - of_machine_is_compatible(PowerMac7,3) || - of_machine_is_compatible(RackMac3,1)) - return -ENODEV; return i2c_add_driver(wf_max6690_driver); } -- 1.7.9.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 01/15] i2c/powermac: Register i2c devices from device-tree
This causes i2c-powermac to register i2c devices exposed in the device-tree, enabling new-style probing of devices. Note that we prefix the IDs with MAC, in order to prevent the generic drivers from matching. This is done on purpose as we only want drivers specifically tested/designed to operate on powermacs to match. This removes the special case we had for the AMS driver, and updates the driver's match table instead. Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org --- arch/powerpc/platforms/powermac/low_i2c.c |1 + drivers/i2c/busses/i2c-powermac.c | 98 + drivers/macintosh/ams/ams-i2c.c |2 +- 3 files changed, 73 insertions(+), 28 deletions(-) diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c index 996c5ff..f991dbb 100644 --- a/arch/powerpc/platforms/powermac/low_i2c.c +++ b/arch/powerpc/platforms/powermac/low_i2c.c @@ -1494,6 +1494,7 @@ static int __init pmac_i2c_create_platform_devices(void) if (bus-platform_dev == NULL) return -ENOMEM; bus-platform_dev-dev.platform_data = bus; + bus-platform_dev-dev.of_node = bus-busnode; platform_device_add(bus-platform_dev); } diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c index 7b397c6..31c47e1 100644 --- a/drivers/i2c/busses/i2c-powermac.c +++ b/drivers/i2c/busses/i2c-powermac.c @@ -227,6 +227,72 @@ static int __devexit i2c_powermac_remove(struct platform_device *dev) return 0; } +static void __devinit i2c_powermac_register_devices(struct i2c_adapter *adap, + struct pmac_i2c_bus *bus) +{ + struct i2c_client *newdev; + struct device_node *node; + + for_each_child_of_node(adap-dev.of_node, node) { + struct i2c_board_info info = {}; + struct dev_archdata dev_ad = {}; + const __be32 *reg; + char tmp[16]; + u32 addr; + int len; + + /* Get address channel */ + reg = of_get_property(node, reg, len); + if (!reg || (len sizeof(int))) { + dev_err(adap-dev, i2c-powermac: invalid reg on %s\n, + node-full_name); + continue; + } + addr = be32_to_cpup(reg); + + /* Multibus setup, check channel */ + if (!pmac_i2c_match_adapter(node, adap)) + continue; + + dev_dbg(adap-dev, i2c-powermac: register %s\n, + node-full_name); + + /* Make up a modalias. Note: we to _NOT_ want the standard +* i2c drivers to match with any of our powermac stuff +* unless they have been specifically modified to handle +* it on a case by case basis. For example, for thermal +* control, things like lm75 etc... shall match with their +* corresponding windfarm drivers, _NOT_ the generic ones, +* so we force a prefix of AAPL, onto the modalias to +* make that happen +*/ + if (of_modalias_node(node, tmp, sizeof(tmp)) 0) { + dev_err(adap-dev, i2c-powermac: modalias failure +on %s\n, node-full_name); + continue; + } + snprintf(info.type, sizeof(info.type), MAC,%s, tmp); + + /* Fill out the rest of the info structure */ + info.addr = (addr 0xff) 1; + info.irq = irq_of_parse_and_map(node, 0); + info.of_node = of_node_get(node); + info.archdata = dev_ad; + + newdev = i2c_new_device(adap, info); + if (!newdev) { + dev_err(adap-dev, i2c-powermac: Failure to register +%s\n, node-full_name); + of_node_put(node); + /* We do not dispose of the interrupt mapping on +* purpose. It's not necessary (interrupt cannot be +* re-used) and somebody else might have grabbed it +* via direct DT lookup so let's not bother +*/ + continue; + } + } +} static int __devinit i2c_powermac_probe(struct platform_device *dev) { @@ -272,6 +338,7 @@ static int __devinit i2c_powermac_probe(struct platform_device *dev) adapter-algo = i2c_powermac_algorithm; i2c_set_adapdata(adapter, bus); adapter-dev.parent = dev-dev; + adapter-dev.of_node = dev-dev.of_node; rc = i2c_add_adapter(adapter); if (rc) { printk(KERN_ERR i2c-powermac: Adapter %s registration
Re: [PATCH 01/15] i2c/powermac: Register i2c devices from device-tree
Benjamin Herrenschmidt b...@kernel.crashing.org writes: + /* Make up a modalias. Note: we to _NOT_ want the standard + * i2c drivers to match with any of our powermac stuff + * unless they have been specifically modified to handle + * it on a case by case basis. For example, for thermal + * control, things like lm75 etc... shall match with their + * corresponding windfarm drivers, _NOT_ the generic ones, + * so we force a prefix of AAPL, onto the modalias to s/AAPL,/MAC,/ Andreas. -- Andreas Schwab, sch...@linux-m68k.org GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 And now for something completely different. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 00/15] PowerMac i2c API conversions windfarm updates
On Thu, 19 Apr 2012 18:16:41 +1000, Benjamin Herrenschmidt wrote: The goal of this series is to convert a bulk of PowerMac i2c drivers to the new proper i2c driver registration model. This series is not complete in that there are still a few drivers to do but it goes through the bulk of thermal control and some of the nastiest. The biggest change is that windfarm is ported to generally use the new model, and I've written a new set of windfarm modules to take over from the old therm_pm72 (which was mostly unfixable) on the PowerMac G5 AGP and Xserve G5 machines. This had a bit of testing on a couple of PowerMac G5 AGP variants but none at all on Xserve G5 since the one I have is unfortunately dead. If you want to help me test this, don't forget to disable therm_pm72, and instead load windfarm_pm72 or windfarm_rm31 depending on your machine (you can load or build-in the whole lot as well). As usual windfarm don't properly auto-load yet, I still need to fix that. So please test ! Especially if you have an XServe G5 Benjamin, thanks a lot for doing this! These drivers were the last ones blocking the removal of the legacy binding model in i2c-core. Testers are very welcome. The earliest we can get these changes upstream, the better. Christian, can you please test this series? I'm sure Benjamin can send the patches to you directly if needed. -- Jean Delvare ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 00/15] PowerMac i2c API conversions windfarm updates
Jean Delvare kh...@linux-fr.org writes: These drivers were the last ones blocking the removal of the legacy binding model in i2c-core. There are also still some uses in snd-aoa. Andreas. -- Andreas Schwab, sch...@linux-m68k.org GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 And now for something completely different. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 00/15] PowerMac i2c API conversions windfarm updates
Jean Delvare kh...@linux-fr.org wrote: On Thu, 19 Apr 2012 18:16:41 +1000, Benjamin Herrenschmidt wrote: The goal of this series is to convert a bulk of PowerMac i2c drivers to the new proper i2c driver registration model. This series is not complete in that there are still a few drivers to do but it goes through the bulk of thermal control and some of the nastiest. The biggest change is that windfarm is ported to generally use the new model, and I've written a new set of windfarm modules to take over from the old therm_pm72 (which was mostly unfixable) on the PowerMac G5 AGP and Xserve G5 machines. This had a bit of testing on a couple of PowerMac G5 AGP variants but none at all on Xserve G5 since the one I have is unfortunately dead. If you want to help me test this, don't forget to disable therm_pm72, and instead load windfarm_pm72 or windfarm_rm31 depending on your machine (you can load or build-in the whole lot as well). As usual windfarm don't properly auto-load yet, I still need to fix that. So please test ! Especially if you have an XServe G5 Benjamin, thanks a lot for doing this! These drivers were the last ones blocking the removal of the legacy binding model in i2c-core. Testers are very welcome. The earliest we can get these changes upstream, the better. Christian, can you please test this series? I'm sure Benjamin can send the patches to you directly if needed. -- Jean Delvare I may need a day or two to get to it, but I'll test it. Thanks, C. -- make bzImage, not war ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 00/15] PowerMac i2c API conversions windfarm updates
Andreas Schwab sch...@linux-m68k.org writes: Jean Delvare kh...@linux-fr.org writes: These drivers were the last ones blocking the removal of the legacy binding model in i2c-core. There are also still some uses in snd-aoa. Never mind, I just found the commit in tiwai/sound.git. Andreas. -- Andreas Schwab, sch...@linux-m68k.org GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 And now for something completely different. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 00/15] PowerMac i2c API conversions windfarm updates
Andreas Schwab sch...@linux-m68k.org writes: Andreas Schwab sch...@linux-m68k.org writes: Jean Delvare kh...@linux-fr.org writes: These drivers were the last ones blocking the removal of the legacy binding model in i2c-core. There are also still some uses in snd-aoa. Never mind, I just found the commit in tiwai/sound.git. Confused this was some old one which has nothing to do with the legacy binding model conversion. Andreas. -- Andreas Schwab, sch...@linux-m68k.org GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 And now for something completely different. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 00/15] PowerMac i2c API conversions windfarm updates
Hallo Andreas, On Thu, 19 Apr 2012 12:11:25 +0200, Andreas Schwab wrote: Jean Delvare kh...@linux-fr.org writes: These drivers were the last ones blocking the removal of the legacy binding model in i2c-core. There are also still some uses in snd-aoa. You're right, there are still 3 sound drivers which need to be converted (aoa/onyx, aoa/tas and ppc/keywest.) I believe Benjamin will take care of the latter when he is done with the thermal management drivers. Not sure who can work on and/or test the aoa sound drivers. -- Jean Delvare ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: PowerPC radeon KMS - is it possible?
Original-Nachricht Datum: Thu, 19 Apr 2012 08:32:51 +0200 Von: Michel Dänzer mic...@daenzer.net An: Gerhard Pircher gerhard_pirc...@gmx.net CC: ojordan12...@hotmail.co.uk, sch...@linux-m68k.org, linuxppc-dev@lists.ozlabs.org Betreff: Re: PowerPC radeon KMS - is it possible? On Mit, 2012-04-18 at 18:23 +0200, Gerhard Pircher wrote: Von: Michel Dänzer mic...@daenzer.net On Mit, 2012-04-18 at 17:49 +0200, Gerhard Pircher wrote: Von: Michel Dänzer mic...@daenzer.net On Mit, 2012-04-18 at 16:55 +0200, Andreas Schwab wrote: Michel Dänzer mic...@daenzer.net writes: On Mit, 2012-04-18 at 16:28 +0200, Andreas Schwab wrote: Michel Dänzer mic...@daenzer.net writes: Have you tried smaller aperture sizes (uninorth_agp.aperture) and/or radeon.test=1? (See commit 52f072cb084bbb460d3a4ae09f0b6efc3e7e8a8c) Neither changes anything. How small aperture sizes have you tried? 32M. With the old UMS driver 3D once worked fine ... That doesn't necessarily mean much per se, as with UMS memory is only statically mapped into the AGP GART once (so most of those 32M are wasted at least most of the time), whereas with KMS it's dynamically (un)mapped on demand. That may be a stupid question, but is it allowed (for a DRM client or whatever does the mapping) to change the content of a page mapped into the AGP GART or is it necessary to explicitly unmap the page, change its content and map it again? The former. I know that the uninorth AGPGART driver does a cache flushing for newly mapped pages, Ah, right, that probably explains why the map_page_into_agp change doesn't make any difference. but is there any code in the driver that handles the former case (or isn't this necessary on PPC Macs)? If by 'former case' you mean userspace modifying memory mapped into the AGP GART, then no, this generally doesn't require special treatment on PowerMacs. (Ignoring the potential issue mentioned by Ben in this thread) I guess you refer to the ordering issue here. The former case is an explanation, why I see data corruption with my AGPGART driver (more or less a copy of the uninorth driver) on my non-coherent platform. There are no cache flushes done for writes to already mapped pages. I tested this with radeon.test=1, but I'm not even sure if this code changes already mapped pages (all of this makes it hard to tell for me whether I stumble over a severe hardware error and/or a simple coherency problem). I would say it's necessary to unmap the page first (sounds more like the pci_[un]map_page() approach) - at least when it should work with non-coherent architectures, too. I'm afraid non-coherent platforms haven't really been a concern yet for KMS, and always doing the above dance would probably have a significant performance impact on coherent platforms. Are there any plans for a page flushing API? I suppose that wouldn't have such a big performance impact on coherent platforms (but probably an impact on the userspace API). Not that I know of. Note that this isn't necessarily the only possible approach for addressing this problem. The driver knows which memory buffers are used by a GPU command stream sequence, so it should be able to take any measures necessary to ensure the device sees their contents as of when the command stream was submitted. Good to hear! Anyway the TTM backend and the KMS drivers are a way too complex for me so that I can only hope there will be a solution for non-coherent platforms someday. :-) Thanks for the clarification! Gerhard -- NEU: FreePhone 3-fach-Flat mit kostenlosem Smartphone! Jetzt informieren: http://mobile.1und1.de/?ac=OM.PW.PW003K20328T7073a ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: PowerPC radeon KMS - is it possible?
On Don, 2012-04-19 at 13:48 +0200, Gerhard Pircher wrote: Von: Michel Dänzer mic...@daenzer.net On Mit, 2012-04-18 at 18:23 +0200, Gerhard Pircher wrote: Von: Michel Dänzer mic...@daenzer.net On Mit, 2012-04-18 at 17:49 +0200, Gerhard Pircher wrote: That may be a stupid question, but is it allowed (for a DRM client or whatever does the mapping) to change the content of a page mapped into the AGP GART or is it necessary to explicitly unmap the page, change its content and map it again? The former. I know that the uninorth AGPGART driver does a cache flushing for newly mapped pages, but is there any code in the driver that handles the former case (or isn't this necessary on PPC Macs)? If by 'former case' you mean userspace modifying memory mapped into the AGP GART, then no, this generally doesn't require special treatment on PowerMacs. (Ignoring the potential issue mentioned by Ben in this thread) I guess you refer to the ordering issue here. Yeah. The former case is an explanation, why I see data corruption with my AGPGART driver (more or less a copy of the uninorth driver) on my non-coherent platform. There are no cache flushes done for writes to already mapped pages. As I said, the radeon driver always maps AGP memory uncacheable for the CPU, so no such CPU cache flushes should be necessary. I tested this with radeon.test=1, but I'm not even sure if this code changes already mapped pages [...] It does. radeon_bo_pin(..., RADEON_GEM_DOMAIN_GTT, ...) binds the buffer memory into the AGP GART, and the test only maps it to the CPU after that. I take it the test fails for you? How exactly? -- Earthling Michel Dänzer | http://www.amd.com Libre software enthusiast | Debian, X and DRI developer ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 02/15] powerpc/pmac: Convert therm_adt746x to new i2c probing
Tested on iBook G4 (PowerBook6,7). Andreas. -- Andreas Schwab, sch...@linux-m68k.org GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 And now for something completely different. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [EDAC ABI v13 24/25] edac: change the mem allocation scheme to make Documentation/kobject.txt happy
Hi Joe, Em 17-04-2012 18:17, Joe Perches escreveu: On Mon, 2012-04-16 at 17:38 -0300, Mauro Carvalho Chehab wrote: Kernel kobjects have rigid rules: each container object should be dynamically allocated, and can't be allocated into a single kmalloc. EDAC never obeyed this rule: it has a single malloc function that allocates all needed data into a single kzalloc. As this is not accepted anymore, change the allocation schema of the EDAC *_info structs to enforce this Kernel standard. [] diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c [] @@ -2228,9 +2228,9 @@ static int init_csrows(struct mem_ctl_info *mci) edac_mode = EDAC_NONE; for (j = 0; j pvt-channel_count; j++) { -csrow-channels[j].dimm-mtype = mtype; -csrow-channels[j].dimm-edac_mode = edac_mode; -csrow-channels[j].dimm-nr_pages = nr_pages; +csrow-channels[j]-dimm-mtype = mtype; +csrow-channels[j]-dimm-edac_mode = edac_mode; +csrow-channels[j]-dimm-nr_pages = nr_pages; It might be better to use an automatic for typeof foo dimm = csrow-channels[j]-dimm; dimm-mtype = mtype; etc... [] @@ -293,39 +286,56 @@ struct mem_ctl_info *edac_mc_alloc(unsigned edac_index, mci-mem_is_per_rank = per_rank; /* - * Fills the csrow struct + * Alocate and fill the csrow/channels structs */ +mci-csrows = kzalloc(sizeof(*mci-csrows) * tot_csrows, GFP_KERNEL); kcalloc [] +csr-channels = kzalloc(sizeof(*csr-channels) * tot_cschannels, +GFP_KERNEL); here too @@ -391,7 +401,31 @@ struct mem_ctl_info *edac_mc_alloc(unsigned edac_index, trace_hw_event_init(edac, (unsigned)edac_index); +debugf1(EDAC MCI allocated\n); return mci; Agreed with all above. Fixed. + +error: +debugf1(Failed to allocate one or more EDAC MCI structs\n); Generally, it's not necessary to have specific OOM messages as allocations without GFP_NOWARN do dump_stack()s There is one error condition on the error path that might potentially happen that it is not related directly to the kalloc stuff: if, there GET_POS() tries to access something out of the allocated range, it bails out. I added this debug printk due to that, while testing the allocation changes. The check could potentially be using a BUG_ON() call, but, as failing here, the edac drivers will not load, I opted to not use BUG_ON, and, instead use the standard error path for it. That's said, it seems better to remove this debugf1 from this place, and add some printk(KERN_ERR, ...) at this specific condition. -- To unsubscribe from this list: send the line unsubscribe linux-edac in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html I'm folding the enclosed patch on this one, in order to address the comments on your review. Thanks! Mauro - diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 16510a3..08af66c 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -2180,6 +2180,7 @@ static u32 amd64_csrow_nr_pages(struct amd64_pvt *pvt, u8 dct, int csrow_nr) static int init_csrows(struct mem_ctl_info *mci) { struct csrow_info *csrow; + struct dimm_info *dimm; struct amd64_pvt *pvt = mci-pvt_info; u64 base, mask; u32 val; @@ -2228,9 +2229,10 @@ static int init_csrows(struct mem_ctl_info *mci) edac_mode = EDAC_NONE; for (j = 0; j pvt-channel_count; j++) { - csrow-channels[j]-dimm-mtype = mtype; - csrow-channels[j]-dimm-edac_mode = edac_mode; - csrow-channels[j]-dimm-nr_pages = nr_pages; + dimm = csrow-channels[j]-dimm; + dimm-mtype = mtype; + dimm-edac_mode = edac_mode; + dimm-nr_pages = nr_pages; } } diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index fe57684..16f2d3b 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c @@ -296,7 +296,7 @@ struct mem_ctl_info *edac_mc_alloc(unsigned edac_index, /* * Alocate and fill the csrow/channels structs */ - mci-csrows = kzalloc(sizeof(*mci-csrows) * tot_csrows, GFP_KERNEL); + mci-csrows = kcalloc(sizeof(*mci-csrows), tot_csrows, GFP_KERNEL); if (!mci-csrows) goto error; for (row = 0; row tot_csrows; row++) { @@ -307,7 +307,7 @@ struct mem_ctl_info *edac_mc_alloc(unsigned edac_index, csr-csrow_idx = row; csr-mci = mci; csr-nr_channels = tot_cschannels; - csr-channels = kzalloc(sizeof(*csr-channels) * tot_cschannels, +
[PATCH] edac: change the mem allocation scheme to make Documentation/kobject.txt happy
Kernel kobjects have rigid rules: each container object should be dynamically allocated, and can't be allocated into a single kmalloc. EDAC never obeyed this rule: it has a single malloc function that allocates all needed data into a single kzalloc. As this is not accepted anymore, change the allocation schema of the EDAC *_info structs to enforce this Kernel standard. Reviewed-by: Joe Perches j...@perches.com Cc: Aristeu Rozanski aroza...@redhat.com Cc: Doug Thompson nor...@yahoo.com Cc: Greg K H gre...@linuxfoundation.org Cc: Borislav Petkov borislav.pet...@amd.com Cc: Mark Gross mark.gr...@intel.com Cc: Tim Small t...@buttersideup.com Cc: Ranganathan Desikan r...@jetztechnologies.com Cc: Arvind R. arvin...@gmail.com Cc: Olof Johansson o...@lixom.net Cc: Egor Martovetsky e...@pasemi.com Cc: Chris Metcalf cmetc...@tilera.com Cc: Michal Marek mma...@suse.cz Cc: Jiri Kosina jkos...@suse.cz Cc: Dmitry Eremin-Solenikov dbarysh...@gmail.com Cc: Benjamin Herrenschmidt b...@kernel.crashing.org Cc: Hitoshi Mitake h.mit...@gmail.com Cc: Andrew Morton a...@linux-foundation.org Cc: Shaohui Xie shaohui@freescale.com Cc: linuxppc-dev@lists.ozlabs.org Signed-off-by: Mauro Carvalho Chehab mche...@redhat.com --- drivers/edac/amd64_edac.c | 10 ++- drivers/edac/amd76x_edac.c |8 +- drivers/edac/cell_edac.c |8 +- drivers/edac/cpc925_edac.c |8 +- drivers/edac/e752x_edac.c |4 +- drivers/edac/e7xxx_edac.c |4 +- drivers/edac/edac_mc.c | 105 + drivers/edac/edac_mc_sysfs.c | 126 +++- drivers/edac/i3000_edac.c |6 +- drivers/edac/i3200_edac.c |4 +- drivers/edac/i5400_edac.c |6 +- drivers/edac/i82443bxgx_edac.c |4 +- drivers/edac/i82860_edac.c |6 +- drivers/edac/i82875p_edac.c|6 +- drivers/edac/i82975x_edac.c| 10 ++-- drivers/edac/mpc85xx_edac.c|6 +- drivers/edac/mv64x60_edac.c|4 +- drivers/edac/pasemi_edac.c |8 +- drivers/edac/r82600_edac.c |4 +- drivers/edac/tile_edac.c |4 +- drivers/edac/x38_edac.c|4 +- include/linux/edac.h | 31 ++ 22 files changed, 218 insertions(+), 158 deletions(-) diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 5eda2cd..08af66c 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -2180,6 +2180,7 @@ static u32 amd64_csrow_nr_pages(struct amd64_pvt *pvt, u8 dct, int csrow_nr) static int init_csrows(struct mem_ctl_info *mci) { struct csrow_info *csrow; + struct dimm_info *dimm; struct amd64_pvt *pvt = mci-pvt_info; u64 base, mask; u32 val; @@ -2197,7 +2198,7 @@ static int init_csrows(struct mem_ctl_info *mci) !!(val NBCFG_CHIPKILL), !!(val NBCFG_ECC_ENABLE)); for_each_chip_select(i, 0, pvt) { - csrow = mci-csrows[i]; + csrow = mci-csrows[i]; if (!csrow_enabled(i, 0, pvt)) { debugf1(CSROW %d EMPTY for node %d\n, i, @@ -2228,9 +2229,10 @@ static int init_csrows(struct mem_ctl_info *mci) edac_mode = EDAC_NONE; for (j = 0; j pvt-channel_count; j++) { - csrow-channels[j].dimm-mtype = mtype; - csrow-channels[j].dimm-edac_mode = edac_mode; - csrow-channels[j].dimm-nr_pages = nr_pages; + dimm = csrow-channels[j]-dimm; + dimm-mtype = mtype; + dimm-edac_mode = edac_mode; + dimm-nr_pages = nr_pages; } } diff --git a/drivers/edac/amd76x_edac.c b/drivers/edac/amd76x_edac.c index 9a34c5f..99d8d56 100644 --- a/drivers/edac/amd76x_edac.c +++ b/drivers/edac/amd76x_edac.c @@ -146,7 +146,7 @@ static int amd76x_process_error_info(struct mem_ctl_info *mci, if (handle_errors) { row = (info-ecc_mode_status 4) 0xf; edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, -mci-csrows[row].first_page, 0, 0, +mci-csrows[row]-first_page, 0, 0, row, 0, -1, mci-ctl_name, , NULL); } @@ -161,7 +161,7 @@ static int amd76x_process_error_info(struct mem_ctl_info *mci, if (handle_errors) { row = info-ecc_mode_status 0xf; edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, -mci-csrows[row].first_page, 0, 0, +mci-csrows[row]-first_page, 0, 0, row, 0, -1, mci-ctl_name, ,
Re: [PATCH] edac: change the mem allocation scheme to make Documentation/kobject.txt happy
On Thu, Apr 19, 2012 at 10:21:30AM -0300, Mauro Carvalho Chehab wrote: Kernel kobjects have rigid rules: each container object should be dynamically allocated, and can't be allocated into a single kmalloc. EDAC never obeyed this rule: it has a single malloc function that allocates all needed data into a single kzalloc. As this is not accepted anymore, change the allocation schema of the EDAC *_info structs to enforce this Kernel standard. Very nice work, thanks for doing this: Acked-by: Greg Kroah-Hartman gre...@linuxfoundation.org ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 2/2] irqdomain/powerpc: Fix broken NR_IRQ references
On Thu, 19 Apr 2012 10:45:01 +1000, Michael Ellerman mich...@ellerman.id.au wrote: On Mon, 2012-04-16 at 14:13 -0600, Grant Likely wrote: diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c index d09f3e8..fc9df1a 100644 --- a/arch/powerpc/platforms/cell/axon_msi.c +++ b/arch/powerpc/platforms/cell/axon_msi.c @@ -276,9 +276,6 @@ static int axon_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) if (rc) return rc; - /* We rely on being able to stash a virq in a u16 */ Would be nice to move the comment to the hunk below rather than just deleting it. Otherwise the 65536 looks a bit random. Done. g. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 1/2] powerpc/8xx: Fix NR_IRQ bugs and refactor 8xx interrupt controller
On Tue, 17 Apr 2012 09:03:02 +1000, Benjamin Herrenschmidt b...@kernel.crashing.org wrote: On Mon, 2012-04-16 at 14:13 -0600, Grant Likely wrote: The mpc8xx driver uses a reference to NR_IRQS that is buggy. It uses NR_IRQs for the array size of the ppc_cached_irq_mask bitmap, but NR_IRQs could be smaller than the number of hardware irqs that ppc_cached_irq_mask tracks. Also, while fixing that problem, it became apparent that the interrupt controller only supports 32 interrupt numbers, but it is written as if it supports multiple register banks which is more complicated. This patch pulls out the buggy reference to NR_IRQs and fixes the size of the ppc_cached_irq_mask to match the number of HW irqs. It also drops the now-unnecessary code since ppc_cached_irq_mask is no longer an array. Can you rename ppc_cached_irq_mask while at it ? I think it was written that way because it was all copy/pasted from powermac/pic.c which -does- need it to be an array (and has the same bugs btw) :-) Done; and I think I fixed the pic.c bugs in patch 2. g. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v5 06/27] irq_domain/powerpc: eliminate irq_map; use irq_alloc_desc() instead
On Thu, 12 Apr 2012 07:37:28 +1000, Benjamin Herrenschmidt b...@kernel.crashing.org wrote: On Wed, 2012-04-11 at 14:57 -0600, Grant Likely wrote: Yeah, I've got a different way to fix it though. There is exactly one user of irq_virq_count in-tree right now: PS3. Also, irq_virq_count is only useful for the NOMAP mapping. So, instead of having a single global irq_virq_count values, I've dropped it entirely and added a max_irq argument to irq_domain_add_nomap(). That makes it a property of an individual nomap irq domain instead of a global system settting. Hopefully I'll have a draft patch ready today. That works for me. I'll send patches for cleanup MPIC as well. Okay, I'll wait on these. The MPIC fixes will need to be applied before I can apply the automatic revmapping and hint removal patches. Those patches will also need testing before I apply to linux-next. g. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] powerpc/85xx: don't call of_platform_bus_probe() twice
On Nov 30, 2011, at 10:19 AM, Timur Tabi wrote: Commit 46d026ac (powerpc/85xx: consolidate of_platform_bus_probe calls) replaced platform-specific of_device_id tables with a single function that probes the most of the busses in 85xx device trees. If a specific platform needed additional busses probed, then it could call of_platform_bus_probe() again. Typically, the additional platform-specific busses are children of existing busses that have already been probed. of_platform_bus_probe() does not handle those child busses automatically. Unfortunately, this doesn't actually work. The second (platform-specific) call to of_platform_bus_probe() never finds any of the busses it's asked to find. To remedy this, the platform-specific of_device_id tables are eliminated, and their entries are merged into mpc85xx_common_ids[], so that all busses are probed at once. Signed-off-by: Timur Tabi ti...@freescale.com --- arch/powerpc/platforms/85xx/common.c |6 ++ arch/powerpc/platforms/85xx/mpc85xx_mds.c | 11 +-- arch/powerpc/platforms/85xx/p1022_ds.c| 13 + 3 files changed, 8 insertions(+), 22 deletions(-) applied to merge - k ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] powerpc: fix build when CONFIG_BOOKE_WDT is enabled
On Apr 19, 2012, at 1:32 AM, Baruch Siach wrote: Commit ae3a197e (Disintegrate asm/system.h for PowerPC) broke build of assembly files when CONFIG_BOOKE_WDT is enabled as follows: AS arch/powerpc/lib/string.o /home/baruch/git/stable/arch/powerpc/include/asm/reg_booke.h: Assembler messages: /home/baruch/git/stable/arch/powerpc/include/asm/reg_booke.h:19: Error: Unrecognized opcode: `extern' /home/baruch/git/stable/arch/powerpc/include/asm/reg_booke.h:20: Error: Unrecognized opcode: `extern' Since setup_32.c is the only user of the booke_wdt configuration variables, move the declarations there. Cc: David Howells dhowe...@redhat.com Signed-off-by: Baruch Siach bar...@tkos.co.il --- arch/powerpc/include/asm/reg_booke.h |5 - arch/powerpc/kernel/setup_32.c |5 + 2 files changed, 5 insertions(+), 5 deletions(-) applied to merge, minor moving of the externs to be in same ifdef in setup_32.c - k ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 1/4] powerpc/mpic_msgr: fix compile error when SMP disabled
On Apr 15, 2012, at 9:05 PM, Mingkai Hu wrote: In file included from arch/powerpc/sysdev/mpic_msgr.c:20:0: ~/arch/powerpc/include/asm/mpic_msgr.h: In function 'mpic_msgr_set_destination': ~/arch/powerpc/include/asm/mpic_msgr.h:117:2: error: implicit declaration of function 'get_hard_smp_processor_id' make[1]: *** [arch/powerpc/sysdev/mpic_msgr.o] Error 1 Signed-off-by: Mingkai Hu mingkai...@freescale.com --- arch/powerpc/include/asm/mpic_msgr.h |1 + 1 files changed, 1 insertions(+), 0 deletions(-) applied to merge - k ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 2/4] powerpc/mpic_msgr: add lock for MPIC message global variable
On Apr 15, 2012, at 9:05 PM, Mingkai Hu wrote: Also fix issue of accessing invalid msgr pointer issue. The local msgr pointer in fucntion mpic_msgr_get will be accessed before getting a valid address which will cause kernel crash. Signed-off-by: Mingkai Hu mingkai...@freescale.com --- arch/powerpc/sysdev/mpic_msgr.c | 10 +- 1 files changed, 5 insertions(+), 5 deletions(-) applied to merge - k ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 3/4] powerpc/mpic_msgr: fix offset error when setting mer register
On Apr 15, 2012, at 9:05 PM, Mingkai Hu wrote: Signed-off-by: Mingkai Hu mingkai...@freescale.com --- arch/powerpc/sysdev/mpic_msgr.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) applied to merge - k ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 4/4] powerpc/mpc85xx: add MPIC message dts node
On Apr 15, 2012, at 9:05 PM, Mingkai Hu wrote: Signed-off-by: Mingkai Hu mingkai...@freescale.com --- arch/powerpc/boot/dts/fsl/pq3-mpic-message-B.dtsi | 43 + arch/powerpc/boot/dts/fsl/pq3-mpic.dtsi | 10 + 2 files changed, 53 insertions(+), 0 deletions(-) create mode 100644 arch/powerpc/boot/dts/fsl/pq3-mpic-message-B.dtsi applied to merge - k ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 00/15] PowerMac i2c API conversions windfarm updates
On Thu, 2012-04-19 at 11:37 +0200, Jean Delvare wrote: Benjamin, thanks a lot for doing this! These drivers were the last ones blocking the removal of the legacy binding model in i2c-core. There's a couple left :-) I haven't done therm_windtunnel.c (here too, I need testers when I'm done) and our sound drivers are still using the old API afaik, that's next on my list. Testers are very welcome. The earliest we can get these changes upstream, the better. Christian, can you please test this series? I'm sure Benjamin can send the patches to you directly if needed. The main problem is that I don't have a Xserve G5 anymore to test, that's one driver that largely rewritten and totally untested... Cheers, Ben. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[git pull] Please pull powerpc.git merge branch
Ben, Some bug fix patches for v3.4. - k The following changes since commit fae2e0fb24c61ca68c98d854a34732549ebc1854: powerpc: Fix typo in runlatch code (2012-04-11 10:42:15 +1000) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/galak/powerpc.git merge Baruch Siach (1): powerpc: fix build when CONFIG_BOOKE_WDT is enabled Mingkai Hu (4): powerpc/mpic_msgr: fix compile error when SMP disabled powerpc/mpic_msgr: add lock for MPIC message global variable powerpc/mpic_msgr: fix offset error when setting mer register powerpc/mpc85xx: add MPIC message dts node Timur Tabi (1): powerpc/85xx: don't call of_platform_bus_probe() twice arch/powerpc/boot/dts/fsl/pq3-mpic-message-B.dtsi | 43 + arch/powerpc/boot/dts/fsl/pq3-mpic.dtsi | 10 + arch/powerpc/include/asm/mpic_msgr.h |1 + arch/powerpc/include/asm/reg_booke.h |5 -- arch/powerpc/kernel/setup_32.c|3 + arch/powerpc/platforms/85xx/common.c |6 +++ arch/powerpc/platforms/85xx/mpc85xx_mds.c | 11 +- arch/powerpc/platforms/85xx/p1022_ds.c| 13 +-- arch/powerpc/sysdev/mpic_msgr.c | 12 +++--- 9 files changed, 71 insertions(+), 33 deletions(-) create mode 100644 arch/powerpc/boot/dts/fsl/pq3-mpic-message-B.dtsi ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 1/3] powerpc/mpic: Fix confusion between hw_irq and virq
mpic_is_ipi() takes a virq and immediately converts it to a hw_irq. However, one of the two call sites calls it with a ... hw_irq. The other call site also happens to have the hw_irq at hand, so let's change it to just take that as an argument. Also change mpic_is_tm() for consistency. Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org --- arch/powerpc/sysdev/mpic.c | 12 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 9ac71eb..665b0f8 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -604,18 +604,14 @@ static struct mpic *mpic_find(unsigned int irq) } /* Determine if the linux irq is an IPI */ -static unsigned int mpic_is_ipi(struct mpic *mpic, unsigned int irq) +static unsigned int mpic_is_ipi(struct mpic *mpic, unsigned int src) { - unsigned int src = virq_to_hw(irq); - return (src = mpic-ipi_vecs[0] src = mpic-ipi_vecs[3]); } /* Determine if the linux irq is a timer */ -static unsigned int mpic_is_tm(struct mpic *mpic, unsigned int irq) +static unsigned int mpic_is_tm(struct mpic *mpic, unsigned int src) { - unsigned int src = virq_to_hw(irq); - return (src = mpic-timer_vecs[0] src = mpic-timer_vecs[7]); } @@ -1555,12 +1551,12 @@ void mpic_irq_set_priority(unsigned int irq, unsigned int pri) return; raw_spin_lock_irqsave(mpic_lock, flags); - if (mpic_is_ipi(mpic, irq)) { + if (mpic_is_ipi(mpic, src)) { reg = mpic_ipi_read(src - mpic-ipi_vecs[0]) ~MPIC_VECPRI_PRIORITY_MASK; mpic_ipi_write(src - mpic-ipi_vecs[0], reg | (pri MPIC_VECPRI_PRIORITY_SHIFT)); - } else if (mpic_is_tm(mpic, irq)) { + } else if (mpic_is_tm(mpic, src)) { reg = mpic_tm_read(src - mpic-timer_vecs[0]) ~MPIC_VECPRI_PRIORITY_MASK; mpic_tm_write(src - mpic-timer_vecs[0], ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 1/3] powerpc/mpic: Fix confusion between hw_irq and virq
mpic_is_ipi() takes a virq and immediately converts it to a hw_irq. However, one of the two call sites calls it with a ... hw_irq. The other call site also happens to have the hw_irq at hand, so let's change it to just take that as an argument. Also change mpic_is_tm() for consistency. Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org --- arch/powerpc/sysdev/mpic.c | 12 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 9ac71eb..665b0f8 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -604,18 +604,14 @@ static struct mpic *mpic_find(unsigned int irq) } /* Determine if the linux irq is an IPI */ -static unsigned int mpic_is_ipi(struct mpic *mpic, unsigned int irq) +static unsigned int mpic_is_ipi(struct mpic *mpic, unsigned int src) { - unsigned int src = virq_to_hw(irq); - return (src = mpic-ipi_vecs[0] src = mpic-ipi_vecs[3]); } /* Determine if the linux irq is a timer */ -static unsigned int mpic_is_tm(struct mpic *mpic, unsigned int irq) +static unsigned int mpic_is_tm(struct mpic *mpic, unsigned int src) { - unsigned int src = virq_to_hw(irq); - return (src = mpic-timer_vecs[0] src = mpic-timer_vecs[7]); } @@ -1555,12 +1551,12 @@ void mpic_irq_set_priority(unsigned int irq, unsigned int pri) return; raw_spin_lock_irqsave(mpic_lock, flags); - if (mpic_is_ipi(mpic, irq)) { + if (mpic_is_ipi(mpic, src)) { reg = mpic_ipi_read(src - mpic-ipi_vecs[0]) ~MPIC_VECPRI_PRIORITY_MASK; mpic_ipi_write(src - mpic-ipi_vecs[0], reg | (pri MPIC_VECPRI_PRIORITY_SHIFT)); - } else if (mpic_is_tm(mpic, irq)) { + } else if (mpic_is_tm(mpic, src)) { reg = mpic_tm_read(src - mpic-timer_vecs[0]) ~MPIC_VECPRI_PRIORITY_MASK; mpic_tm_write(src - mpic-timer_vecs[0], ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 2/3] irq: Add IRQ_TYPE_DEFAULT for use by PIC drivers
This is meant typically to allow a PIC driver's irq domain map() callback to establish sane defaults for the interrupt (and make sure that the HW and the irq_desc are in sync as far as the trigger is concerned). The irq core may not call the set_trigger callback if it thinks the trigger is already set to the right setting, so we need to ensure new descriptors are properly synchronized with the hardware. Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org --- include/linux/irq.h |7 +++ 1 file changed, 7 insertions(+) diff --git a/include/linux/irq.h b/include/linux/irq.h index 7810406..b27cfcf 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -49,6 +49,12 @@ typedef void (*irq_preflow_handler_t)(struct irq_data *data); * IRQ_TYPE_LEVEL_LOW - low level triggered * IRQ_TYPE_LEVEL_MASK - Mask to filter out the level bits * IRQ_TYPE_SENSE_MASK - Mask for all the above bits + * IRQ_TYPE_DEFAULT- For use by some PICs to ask irq_set_type + * to setup the HW to a sane default (used + *by irqdomain map() callbacks to synchronize + *the HW state and SW flags for a newly + *allocated descriptor). + * * IRQ_TYPE_PROBE - Special flag for probing in progress * * Bits which can be modified via irq_set/clear/modify_status_flags() @@ -77,6 +83,7 @@ enum { IRQ_TYPE_LEVEL_LOW = 0x0008, IRQ_TYPE_LEVEL_MASK = (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH), IRQ_TYPE_SENSE_MASK = 0x000f, + IRQ_TYPE_DEFAULT= IRQ_TYPE_SENSE_MASK, IRQ_TYPE_PROBE = 0x0010, ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 3/3] powerpc/mpic: Properly set default triggers
This gets rid of the unused default senses array, and replaces the incorrect use of IRQ_TYPE_NONE with the new IRQ_TYPE_DEFAULT for the initial set_trigger() call when mapping an interrupt. This in turn makes us read the HW state and update the irq desc accordingly. Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org --- arch/powerpc/include/asm/mpic.h | 18 - arch/powerpc/sysdev/mpic.c | 42 --- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h index c65b929..c9f698a 100644 --- a/arch/powerpc/include/asm/mpic.h +++ b/arch/powerpc/include/asm/mpic.h @@ -275,9 +275,6 @@ struct mpic unsigned intisu_mask; /* Number of sources */ unsigned intnum_sources; - /* default senses array */ - unsigned char *senses; - unsigned intsenses_count; /* vector numbers used for internal sources (ipi/timers) */ unsigned intipi_vecs[4]; @@ -415,21 +412,6 @@ extern struct mpic *mpic_alloc(struct device_node *node, extern void mpic_assign_isu(struct mpic *mpic, unsigned int isu_num, phys_addr_t phys_addr); -/* Set default sense codes - * - * @mpic: controller - * @senses:array of sense codes - * @count: size of above array - * - * Optionally provide an array (indexed on hardware interrupt numbers - * for this MPIC) of default sense codes for the chip. Those are linux - * sense codes IRQ_TYPE_* - * - * The driver gets ownership of the pointer, don't dispose of it or - * anything like that. __init only. - */ -extern void mpic_set_default_senses(struct mpic *mpic, u8 *senses, int count); - /* Initialize the controller. After this has been called, none of the above * should be called again for this mpic diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 665b0f8..395af13 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -872,21 +872,45 @@ int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type) if (src = mpic-num_sources) return -EINVAL; + vold = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)); + + /* We don't support none type */ if (flow_type == IRQ_TYPE_NONE) - if (mpic-senses src mpic-senses_count) - flow_type = mpic-senses[src]; - if (flow_type == IRQ_TYPE_NONE) - flow_type = IRQ_TYPE_LEVEL_LOW; + flow_type = IRQ_TYPE_DEFAULT; + + /* Default: read HW settings */ + if (flow_type == IRQ_TYPE_DEFAULT) { + switch(vold (MPIC_INFO(VECPRI_POLARITY_MASK) | + MPIC_INFO(VECPRI_SENSE_MASK))) { + case MPIC_INFO(VECPRI_SENSE_EDGE) | +MPIC_INFO(VECPRI_POLARITY_POSITIVE): + flow_type = IRQ_TYPE_EDGE_RISING; + break; + case MPIC_INFO(VECPRI_SENSE_EDGE) | +MPIC_INFO(VECPRI_POLARITY_NEGATIVE): + flow_type = IRQ_TYPE_EDGE_FALLING; + break; + case MPIC_INFO(VECPRI_SENSE_LEVEL) | +MPIC_INFO(VECPRI_POLARITY_POSITIVE): + flow_type = IRQ_TYPE_LEVEL_HIGH; + break; + case MPIC_INFO(VECPRI_SENSE_LEVEL) | +MPIC_INFO(VECPRI_POLARITY_NEGATIVE): + flow_type = IRQ_TYPE_LEVEL_LOW; + break; + } + } + /* Apply to irq desc */ irqd_set_trigger_type(d, flow_type); + /* Apply to HW */ if (mpic_is_ht_interrupt(mpic, src)) vecpri = MPIC_VECPRI_POLARITY_POSITIVE | MPIC_VECPRI_SENSE_EDGE; else vecpri = mpic_type_to_vecpri(mpic, flow_type); - vold = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)); vnew = vold ~(MPIC_INFO(VECPRI_POLARITY_MASK) | MPIC_INFO(VECPRI_SENSE_MASK)); vnew |= vecpri; @@ -1022,7 +1046,7 @@ static int mpic_host_map(struct irq_domain *h, unsigned int virq, irq_set_chip_and_handler(virq, chip, handle_fasteoi_irq); /* Set default irq type */ - irq_set_irq_type(virq, IRQ_TYPE_NONE); + irq_set_irq_type(virq, IRQ_TYPE_DEFAULT); /* If the MPIC was reset, then all vectors have already been * initialized. Otherwise, a per source lazy initialization @@ -1413,12 +1437,6 @@ void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num, mpic-num_sources = isu_first + mpic-isu_size; } -void __init mpic_set_default_senses(struct mpic *mpic, u8 *senses,