* [PATCH 1/2] i2c: Add support for device alias names
From: Jean Delvare @ 2008-04-28 9:39 UTC (permalink / raw)
To: Linux I2C
Cc: Laurent, Sievers, linuxppc-dev list, Paul Mundt, Scott Wood, Kay
In-Reply-To: <20080428113052.6d024bda@hyperion.delvare>
Based on earlier work by Jon Smirl and Jochen Friedrich.
This patch allows new-style i2c chip drivers to have alias names using
the official kernel aliasing system and MODULE_DEVICE_TABLE(). At this
point, the old i2c driver binding scheme (driver_name/type) is still
supported.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Cc: Jochen Friedrich <jochen@scram.de>
Cc: Jon Smirl <jonsmirl@gmail.com>
Cc: Kay Sievers <kay.sievers@vrfy.org>
---
One thing I am still not happy with is that the aliases created have a
trailing "*":
$ /sbin/modinfo lm90
filename: /lib/modules/2.6.25-git11/kernel/drivers/hwmon/lm90.ko
author: Jean Delvare <khali@linux-fr.org>
description: LM90/ADM1032 driver
license: GPL
vermagic: 2.6.25-git11 mod_unload
depends: hwmon
alias: i2c:lm90*
alias: i2c:adm1032*
alias: i2c:lm99*
alias: i2c:lm86*
alias: i2c:max6657*
alias: i2c:adt7461*
alias: i2c:max6680*
$
This would cause trouble if one I2C chip name matches the beginning of
another I2C chip name and both chips are supported by different
drivers. This has yet to be seen, but still, I'd like to see this
problem fixed quickly.
Documentation/i2c/writing-clients | 3 +
drivers/gpio/pca953x.c | 3 +
drivers/gpio/pcf857x.c | 3 +
drivers/hwmon/f75375s.c | 8 ++--
drivers/i2c/chips/ds1682.c | 3 +
drivers/i2c/chips/menelaus.c | 3 +
drivers/i2c/chips/tps65010.c | 3 +
drivers/i2c/chips/tsl2550.c | 3 +
drivers/i2c/i2c-core.c | 51 +++++++++++++++++++++++-----
drivers/media/video/cs5345.c | 3 +
drivers/media/video/cs53l32a.c | 3 +
drivers/media/video/cx25840/cx25840-core.c | 3 +
drivers/media/video/m52790.c | 3 +
drivers/media/video/msp3400-driver.c | 2 -
drivers/media/video/mt9m001.c | 3 +
drivers/media/video/mt9v022.c | 3 +
drivers/media/video/saa7115.c | 3 +
drivers/media/video/saa7127.c | 3 +
drivers/media/video/saa717x.c | 3 +
drivers/media/video/tcm825x.c | 3 +
drivers/media/video/tlv320aic23b.c | 3 +
drivers/media/video/tuner-core.c | 3 +
drivers/media/video/tvaudio.c | 2 -
drivers/media/video/upd64031a.c | 3 +
drivers/media/video/upd64083.c | 3 +
drivers/media/video/v4l2-common.c | 5 +-
drivers/media/video/vp27smpx.c | 3 +
drivers/media/video/wm8739.c | 3 +
drivers/media/video/wm8775.c | 3 +
drivers/rtc/rtc-ds1307.c | 3 +
drivers/rtc/rtc-ds1374.c | 3 +
drivers/rtc/rtc-m41t80.c | 3 +
drivers/rtc/rtc-rs5c372.c | 3 +
drivers/rtc/rtc-s35390a.c | 3 +
include/linux/i2c.h | 5 +-
include/linux/mod_devicetable.h | 11 ++++++
include/media/v4l2-common.h | 4 +-
include/media/v4l2-i2c-drv-legacy.h | 2 -
include/media/v4l2-i2c-drv.h | 2 -
scripts/mod/file2alias.c | 13 +++++++
40 files changed, 141 insertions(+), 51 deletions(-)
--- linux-2.6.26-rc0.orig/Documentation/i2c/writing-clients 2008-04-27 22:05:00.000000000 +0200
+++ linux-2.6.26-rc0/Documentation/i2c/writing-clients 2008-04-27 22:09:29.000000000 +0200
@@ -164,7 +164,8 @@ I2C device drivers using this binding mo
kind of driver in Linux: they provide a probe() method to bind to
those devices, and a remove() method to unbind.
- static int foo_probe(struct i2c_client *client);
+ static int foo_probe(struct i2c_client *client,
+ const struct i2c_device_id *id);
static int foo_remove(struct i2c_client *client);
Remember that the i2c_driver does not create those client handles. The
--- linux-2.6.26-rc0.orig/drivers/gpio/pca953x.c 2008-04-27 22:05:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/gpio/pca953x.c 2008-04-27 22:09:29.000000000 +0200
@@ -191,7 +191,8 @@ static void pca953x_setup_gpio(struct pc
gc->label = chip->client->name;
}
-static int __devinit pca953x_probe(struct i2c_client *client)
+static int __devinit pca953x_probe(struct i2c_client *client,
+ const struct i2c_device_id *did)
{
struct pca953x_platform_data *pdata;
struct pca953x_chip *chip;
--- linux-2.6.26-rc0.orig/drivers/gpio/pcf857x.c 2008-04-27 22:05:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/gpio/pcf857x.c 2008-04-27 22:09:29.000000000 +0200
@@ -142,7 +142,8 @@ static void pcf857x_set16(struct gpio_ch
/*-------------------------------------------------------------------------*/
-static int pcf857x_probe(struct i2c_client *client)
+static int pcf857x_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct pcf857x_platform_data *pdata;
struct pcf857x *gpio;
--- linux-2.6.26-rc0.orig/drivers/hwmon/f75375s.c 2008-04-27 22:05:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/hwmon/f75375s.c 2008-04-27 22:09:29.000000000 +0200
@@ -117,7 +117,8 @@ struct f75375_data {
static int f75375_attach_adapter(struct i2c_adapter *adapter);
static int f75375_detect(struct i2c_adapter *adapter, int address, int kind);
static int f75375_detach_client(struct i2c_client *client);
-static int f75375_probe(struct i2c_client *client);
+static int f75375_probe(struct i2c_client *client,
+ const struct i2c_device_id *id);
static int f75375_remove(struct i2c_client *client);
static struct i2c_driver f75375_legacy_driver = {
@@ -628,7 +629,8 @@ static void f75375_init(struct i2c_clien
}
-static int f75375_probe(struct i2c_client *client)
+static int f75375_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct f75375_data *data = i2c_get_clientdata(client);
struct f75375s_platform_data *f75375s_pdata = client->dev.platform_data;
@@ -748,7 +750,7 @@ static int f75375_detect(struct i2c_adap
if ((err = i2c_attach_client(client)))
goto exit_free;
- if ((err = f75375_probe(client)) < 0)
+ if ((err = f75375_probe(client, NULL)) < 0)
goto exit_detach;
return 0;
--- linux-2.6.26-rc0.orig/drivers/i2c/chips/ds1682.c 2008-04-27 22:05:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/i2c/chips/ds1682.c 2008-04-27 22:09:29.000000000 +0200
@@ -200,7 +200,8 @@ static struct bin_attribute ds1682_eepro
/*
* Called when a ds1682 device is matched with this driver
*/
-static int ds1682_probe(struct i2c_client *client)
+static int ds1682_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
int rc;
--- linux-2.6.26-rc0.orig/drivers/i2c/chips/menelaus.c 2008-04-27 22:05:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/i2c/chips/menelaus.c 2008-04-27 22:09:29.000000000 +0200
@@ -1149,7 +1149,8 @@ static inline void menelaus_rtc_init(str
static struct i2c_driver menelaus_i2c_driver;
-static int menelaus_probe(struct i2c_client *client)
+static int menelaus_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct menelaus_chip *menelaus;
int rev = 0, val;
--- linux-2.6.26-rc0.orig/drivers/i2c/chips/tps65010.c 2008-04-27 22:08:10.000000000 +0200
+++ linux-2.6.26-rc0/drivers/i2c/chips/tps65010.c 2008-04-27 22:09:29.000000000 +0200
@@ -532,7 +532,8 @@ static int __exit tps65010_remove(struct
return 0;
}
-static int tps65010_probe(struct i2c_client *client)
+static int tps65010_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct tps65010 *tps;
int status;
--- linux-2.6.26-rc0.orig/drivers/i2c/chips/tsl2550.c 2008-04-27 22:05:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/i2c/chips/tsl2550.c 2008-04-27 22:09:29.000000000 +0200
@@ -364,7 +364,8 @@ static int tsl2550_init_client(struct i2
*/
static struct i2c_driver tsl2550_driver;
-static int __devinit tsl2550_probe(struct i2c_client *client)
+static int __devinit tsl2550_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
struct tsl2550_data *data;
--- linux-2.6.26-rc0.orig/drivers/i2c/i2c-core.c 2008-04-27 22:07:17.000000000 +0200
+++ linux-2.6.26-rc0/drivers/i2c/i2c-core.c 2008-04-27 22:09:29.000000000 +0200
@@ -48,6 +48,17 @@ static DEFINE_IDR(i2c_adapter_idr);
/* ------------------------------------------------------------------------- */
+static const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id,
+ const struct i2c_client *client)
+{
+ while (id->name[0]) {
+ if (strcmp(client->name, id->name) == 0)
+ return id;
+ id++;
+ }
+ return NULL;
+}
+
static int i2c_device_match(struct device *dev, struct device_driver *drv)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -59,6 +70,10 @@ static int i2c_device_match(struct devic
if (!is_newstyle_driver(driver))
return 0;
+ /* match on an id table if there is one */
+ if (driver->id_table)
+ return i2c_match_id(driver->id_table, client) != NULL;
+
/* new style drivers use the same kind of driver matching policy
* as platform devices or SPI: compare device and driver IDs.
*/
@@ -73,11 +88,17 @@ static int i2c_device_uevent(struct devi
struct i2c_client *client = to_i2c_client(dev);
/* by definition, legacy drivers can't hotplug */
- if (dev->driver || !client->driver_name)
+ if (dev->driver)
return 0;
- if (add_uevent_var(env, "MODALIAS=%s", client->driver_name))
- return -ENOMEM;
+ if (client->driver_name[0]) {
+ if (add_uevent_var(env, "MODALIAS=%s", client->driver_name))
+ return -ENOMEM;
+ } else {
+ if (add_uevent_var(env, "MODALIAS=%s%s",
+ I2C_MODULE_PREFIX, client->name))
+ return -ENOMEM;
+ }
dev_dbg(dev, "uevent\n");
return 0;
}
@@ -90,13 +111,19 @@ static int i2c_device_probe(struct devic
{
struct i2c_client *client = to_i2c_client(dev);
struct i2c_driver *driver = to_i2c_driver(dev->driver);
+ const struct i2c_device_id *id;
int status;
if (!driver->probe)
return -ENODEV;
client->driver = driver;
dev_dbg(dev, "probe\n");
- status = driver->probe(client);
+
+ if (driver->id_table)
+ id = i2c_match_id(driver->id_table, client);
+ else
+ id = NULL;
+ status = driver->probe(client, id);
if (status)
client->driver = NULL;
return status;
@@ -179,9 +206,9 @@ static ssize_t show_client_name(struct d
static ssize_t show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
{
struct i2c_client *client = to_i2c_client(dev);
- return client->driver_name
+ return client->driver_name[0]
? sprintf(buf, "%s\n", client->driver_name)
- : 0;
+ : sprintf(buf, "%s%s\n", I2C_MODULE_PREFIX, client->name);
}
static struct device_attribute i2c_dev_attrs[] = {
@@ -300,15 +327,21 @@ void i2c_unregister_device(struct i2c_cl
EXPORT_SYMBOL_GPL(i2c_unregister_device);
-static int dummy_nop(struct i2c_client *client)
+static int dummy_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ return 0;
+}
+
+static int dummy_remove(struct i2c_client *client)
{
return 0;
}
static struct i2c_driver dummy_driver = {
.driver.name = "dummy",
- .probe = dummy_nop,
- .remove = dummy_nop,
+ .probe = dummy_probe,
+ .remove = dummy_remove,
};
/**
--- linux-2.6.26-rc0.orig/drivers/media/video/cs5345.c 2008-04-27 22:05:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/cs5345.c 2008-04-27 22:09:29.000000000 +0200
@@ -142,7 +142,8 @@ static int cs5345_command(struct i2c_cli
/* ----------------------------------------------------------------------- */
-static int cs5345_probe(struct i2c_client *client)
+static int cs5345_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
/* Check if the adapter supports the needed features */
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
--- linux-2.6.26-rc0.orig/drivers/media/video/cs53l32a.c 2008-04-27 22:05:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/cs53l32a.c 2008-04-27 22:09:29.000000000 +0200
@@ -135,7 +135,8 @@ static int cs53l32a_command(struct i2c_c
* concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
*/
-static int cs53l32a_probe(struct i2c_client *client)
+static int cs53l32a_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
int i;
--- linux-2.6.26-rc0.orig/drivers/media/video/cx25840/cx25840-core.c 2008-04-27 22:07:20.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/cx25840/cx25840-core.c 2008-04-27 22:09:29.000000000 +0200
@@ -1209,7 +1209,8 @@ static int cx25840_command(struct i2c_cl
/* ----------------------------------------------------------------------- */
-static int cx25840_probe(struct i2c_client *client)
+static int cx25840_probe(struct i2c_client *client,
+ const struct i2c_device_id *did)
{
struct cx25840_state *state;
u32 id;
--- linux-2.6.26-rc0.orig/drivers/media/video/m52790.c 2008-04-27 22:05:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/m52790.c 2008-04-27 22:09:29.000000000 +0200
@@ -126,7 +126,8 @@ static int m52790_command(struct i2c_cli
/* i2c implementation */
-static int m52790_probe(struct i2c_client *client)
+static int m52790_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct m52790_state *state;
--- linux-2.6.26-rc0.orig/drivers/media/video/msp3400-driver.c 2008-04-27 22:07:20.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/msp3400-driver.c 2008-04-27 22:09:29.000000000 +0200
@@ -805,7 +805,7 @@ static int msp_resume(struct i2c_client
/* ----------------------------------------------------------------------- */
-static int msp_probe(struct i2c_client *client)
+static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct msp_state *state;
int (*thread_func)(void *data) = NULL;
--- linux-2.6.26-rc0.orig/drivers/media/video/mt9m001.c 2008-04-27 22:07:20.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/mt9m001.c 2008-04-27 22:09:29.000000000 +0200
@@ -620,7 +620,8 @@ static void mt9m001_video_remove(struct
soc_camera_video_stop(&mt9m001->icd);
}
-static int mt9m001_probe(struct i2c_client *client)
+static int mt9m001_probe(struct i2c_client *client,
+ const struct i2c_device_id *did)
{
struct mt9m001 *mt9m001;
struct soc_camera_device *icd;
--- linux-2.6.26-rc0.orig/drivers/media/video/mt9v022.c 2008-04-27 22:07:20.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/mt9v022.c 2008-04-27 22:09:29.000000000 +0200
@@ -745,7 +745,8 @@ static void mt9v022_video_remove(struct
soc_camera_video_stop(&mt9v022->icd);
}
-static int mt9v022_probe(struct i2c_client *client)
+static int mt9v022_probe(struct i2c_client *client,
+ const struct i2c_device_id *did)
{
struct mt9v022 *mt9v022;
struct soc_camera_device *icd;
--- linux-2.6.26-rc0.orig/drivers/media/video/saa7115.c 2008-04-27 22:07:20.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/saa7115.c 2008-04-27 22:09:29.000000000 +0200
@@ -1450,7 +1450,8 @@ static int saa7115_command(struct i2c_cl
/* ----------------------------------------------------------------------- */
-static int saa7115_probe(struct i2c_client *client)
+static int saa7115_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct saa711x_state *state;
int i;
--- linux-2.6.26-rc0.orig/drivers/media/video/saa7127.c 2008-04-27 22:05:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/saa7127.c 2008-04-27 22:09:29.000000000 +0200
@@ -661,7 +661,8 @@ static int saa7127_command(struct i2c_cl
/* ----------------------------------------------------------------------- */
-static int saa7127_probe(struct i2c_client *client)
+static int saa7127_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct saa7127_state *state;
struct v4l2_sliced_vbi_data vbi = { 0, 0, 0, 0 }; /* set to disabled */
--- linux-2.6.26-rc0.orig/drivers/media/video/saa717x.c 2008-04-27 22:07:20.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/saa717x.c 2008-04-27 22:09:29.000000000 +0200
@@ -1418,7 +1418,8 @@ static int saa717x_command(struct i2c_cl
/* i2c implementation */
/* ----------------------------------------------------------------------- */
-static int saa717x_probe(struct i2c_client *client)
+static int saa717x_probe(struct i2c_client *client,
+ const struct i2c_device_id *did)
{
struct saa717x_state *decoder;
u8 id = 0;
--- linux-2.6.26-rc0.orig/drivers/media/video/tcm825x.c 2008-04-27 22:07:20.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/tcm825x.c 2008-04-27 22:09:29.000000000 +0200
@@ -840,7 +840,8 @@ static struct v4l2_int_device tcm825x_in
},
};
-static int tcm825x_probe(struct i2c_client *client)
+static int tcm825x_probe(struct i2c_client *client,
+ const struct i2c_device_id *did)
{
struct tcm825x_sensor *sensor = &tcm825x;
int rval;
--- linux-2.6.26-rc0.orig/drivers/media/video/tlv320aic23b.c 2008-04-27 22:05:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/tlv320aic23b.c 2008-04-27 22:09:29.000000000 +0200
@@ -125,7 +125,8 @@ static int tlv320aic23b_command(struct i
* concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
*/
-static int tlv320aic23b_probe(struct i2c_client *client)
+static int tlv320aic23b_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct tlv320aic23b_state *state;
--- linux-2.6.26-rc0.orig/drivers/media/video/tuner-core.c 2008-04-27 22:07:20.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/tuner-core.c 2008-04-27 22:09:29.000000000 +0200
@@ -1073,7 +1073,8 @@ static void tuner_lookup(struct i2c_adap
/* During client attach, set_type is called by adapter's attach_inform callback.
set_type must then be completed by tuner_probe.
*/
-static int tuner_probe(struct i2c_client *client)
+static int tuner_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct tuner *t;
struct tuner *radio;
--- linux-2.6.26-rc0.orig/drivers/media/video/tvaudio.c 2008-04-27 22:07:20.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/tvaudio.c 2008-04-27 22:09:29.000000000 +0200
@@ -1461,7 +1461,7 @@ static struct CHIPDESC chiplist[] = {
/* ---------------------------------------------------------------------- */
/* i2c registration */
-static int chip_probe(struct i2c_client *client)
+static int chip_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct CHIPSTATE *chip;
struct CHIPDESC *desc;
--- linux-2.6.26-rc0.orig/drivers/media/video/upd64031a.c 2008-04-27 22:05:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/upd64031a.c 2008-04-27 22:09:29.000000000 +0200
@@ -195,7 +195,8 @@ static int upd64031a_command(struct i2c_
/* i2c implementation */
-static int upd64031a_probe(struct i2c_client *client)
+static int upd64031a_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct upd64031a_state *state;
int i;
--- linux-2.6.26-rc0.orig/drivers/media/video/upd64083.c 2008-04-27 22:05:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/upd64083.c 2008-04-27 22:09:29.000000000 +0200
@@ -172,7 +172,8 @@ static int upd64083_command(struct i2c_c
/* i2c implementation */
-static int upd64083_probe(struct i2c_client *client)
+static int upd64083_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct upd64083_state *state;
int i;
--- linux-2.6.26-rc0.orig/drivers/media/video/v4l2-common.c 2008-04-27 22:05:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/v4l2-common.c 2008-04-27 22:09:29.000000000 +0200
@@ -710,7 +710,8 @@ EXPORT_SYMBOL(v4l2_chip_ident_i2c_client
/* Helper function for I2C legacy drivers */
int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver *driver,
- const char *name, int (*probe)(struct i2c_client *))
+ const char *name,
+ int (*probe)(struct i2c_client *, const struct i2c_device_id *))
{
struct i2c_client *client;
int err;
@@ -724,7 +725,7 @@ int v4l2_i2c_attach(struct i2c_adapter *
client->driver = driver;
strlcpy(client->name, name, sizeof(client->name));
- err = probe(client);
+ err = probe(client, NULL);
if (err == 0) {
i2c_attach_client(client);
} else {
--- linux-2.6.26-rc0.orig/drivers/media/video/vp27smpx.c 2008-04-27 22:05:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/vp27smpx.c 2008-04-27 22:09:29.000000000 +0200
@@ -121,7 +121,8 @@ static int vp27smpx_command(struct i2c_c
* concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
*/
-static int vp27smpx_probe(struct i2c_client *client)
+static int vp27smpx_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct vp27smpx_state *state;
--- linux-2.6.26-rc0.orig/drivers/media/video/wm8739.c 2008-04-27 22:05:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/wm8739.c 2008-04-27 22:09:29.000000000 +0200
@@ -261,7 +261,8 @@ static int wm8739_command(struct i2c_cli
/* i2c implementation */
-static int wm8739_probe(struct i2c_client *client)
+static int wm8739_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct wm8739_state *state;
--- linux-2.6.26-rc0.orig/drivers/media/video/wm8775.c 2008-04-27 22:05:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/wm8775.c 2008-04-27 22:09:29.000000000 +0200
@@ -159,7 +159,8 @@ static int wm8775_command(struct i2c_cli
* concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
*/
-static int wm8775_probe(struct i2c_client *client)
+static int wm8775_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct wm8775_state *state;
--- linux-2.6.26-rc0.orig/drivers/rtc/rtc-ds1307.c 2008-04-27 22:05:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/rtc/rtc-ds1307.c 2008-04-27 22:09:29.000000000 +0200
@@ -326,7 +326,8 @@ static struct bin_attribute nvram = {
static struct i2c_driver ds1307_driver;
-static int __devinit ds1307_probe(struct i2c_client *client)
+static int __devinit ds1307_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct ds1307 *ds1307;
int err = -ENODEV;
--- linux-2.6.26-rc0.orig/drivers/rtc/rtc-ds1374.c 2008-04-27 22:05:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/rtc/rtc-ds1374.c 2008-04-27 22:09:29.000000000 +0200
@@ -355,7 +355,8 @@ static const struct rtc_class_ops ds1374
.ioctl = ds1374_ioctl,
};
-static int ds1374_probe(struct i2c_client *client)
+static int ds1374_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct ds1374 *ds1374;
int ret;
--- linux-2.6.26-rc0.orig/drivers/rtc/rtc-m41t80.c 2008-04-27 22:05:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/rtc/rtc-m41t80.c 2008-04-27 22:09:29.000000000 +0200
@@ -756,7 +756,8 @@ static struct notifier_block wdt_notifie
*
*****************************************************************************
*/
-static int m41t80_probe(struct i2c_client *client)
+static int m41t80_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
int i, rc = 0;
struct rtc_device *rtc = NULL;
--- linux-2.6.26-rc0.orig/drivers/rtc/rtc-rs5c372.c 2008-04-27 22:05:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/rtc/rtc-rs5c372.c 2008-04-27 22:09:29.000000000 +0200
@@ -494,7 +494,8 @@ static void rs5c_sysfs_unregister(struct
static struct i2c_driver rs5c372_driver;
-static int rs5c372_probe(struct i2c_client *client)
+static int rs5c372_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
int err = 0;
struct rs5c372 *rs5c372;
--- linux-2.6.26-rc0.orig/drivers/rtc/rtc-s35390a.c 2008-04-27 22:05:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/rtc/rtc-s35390a.c 2008-04-27 22:09:29.000000000 +0200
@@ -195,7 +195,8 @@ static const struct rtc_class_ops s35390
static struct i2c_driver s35390a_driver;
-static int s35390a_probe(struct i2c_client *client)
+static int s35390a_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
int err;
unsigned int i;
--- linux-2.6.26-rc0.orig/include/linux/i2c.h 2008-04-27 22:05:00.000000000 +0200
+++ linux-2.6.26-rc0/include/linux/i2c.h 2008-04-27 22:09:29.000000000 +0200
@@ -126,7 +126,7 @@ struct i2c_driver {
* With the driver model, device enumeration is NEVER done by drivers;
* it's done by infrastructure. (NEW STYLE DRIVERS ONLY)
*/
- int (*probe)(struct i2c_client *);
+ int (*probe)(struct i2c_client *, const struct i2c_device_id *);
int (*remove)(struct i2c_client *);
/* driver model interfaces that don't relate to enumeration */
@@ -140,11 +140,10 @@ struct i2c_driver {
int (*command)(struct i2c_client *client,unsigned int cmd, void *arg);
struct device_driver driver;
+ const struct i2c_device_id *id_table;
};
#define to_i2c_driver(d) container_of(d, struct i2c_driver, driver)
-#define I2C_NAME_SIZE 20
-
/**
* struct i2c_client - represent an I2C slave device
* @flags: I2C_CLIENT_TEN indicates the device uses a ten bit chip address;
--- linux-2.6.26-rc0.orig/include/linux/mod_devicetable.h 2008-04-27 22:05:00.000000000 +0200
+++ linux-2.6.26-rc0/include/linux/mod_devicetable.h 2008-04-27 22:09:29.000000000 +0200
@@ -368,4 +368,15 @@ struct virtio_device_id {
};
#define VIRTIO_DEV_ANY_ID 0xffffffff
+/* i2c */
+
+#define I2C_NAME_SIZE 20
+#define I2C_MODULE_PREFIX "i2c:"
+
+struct i2c_device_id {
+ char name[I2C_NAME_SIZE];
+ kernel_ulong_t driver_data; /* Data private to the driver */
+};
+
+
#endif /* LINUX_MOD_DEVICETABLE_H */
--- linux-2.6.26-rc0.orig/include/media/v4l2-common.h 2008-04-27 22:05:00.000000000 +0200
+++ linux-2.6.26-rc0/include/media/v4l2-common.h 2008-04-27 22:09:29.000000000 +0200
@@ -107,9 +107,11 @@ int v4l2_chip_match_host(u32 id_type, u3
struct i2c_driver;
struct i2c_adapter;
struct i2c_client;
+struct i2c_device_id;
int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver *driver,
- const char *name, int (*probe)(struct i2c_client *));
+ const char *name,
+ int (*probe)(struct i2c_client *, const struct i2c_device_id *));
/* ------------------------------------------------------------------------- */
--- linux-2.6.26-rc0.orig/include/media/v4l2-i2c-drv-legacy.h 2008-04-27 22:05:00.000000000 +0200
+++ linux-2.6.26-rc0/include/media/v4l2-i2c-drv-legacy.h 2008-04-27 22:09:29.000000000 +0200
@@ -25,7 +25,7 @@ struct v4l2_i2c_driver_data {
const char * const name;
int driverid;
int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);
- int (*probe)(struct i2c_client *client);
+ int (*probe)(struct i2c_client *client, const struct i2c_device_id *id);
int (*remove)(struct i2c_client *client);
int (*suspend)(struct i2c_client *client, pm_message_t state);
int (*resume)(struct i2c_client *client);
--- linux-2.6.26-rc0.orig/include/media/v4l2-i2c-drv.h 2008-04-27 22:05:00.000000000 +0200
+++ linux-2.6.26-rc0/include/media/v4l2-i2c-drv.h 2008-04-27 22:09:29.000000000 +0200
@@ -30,7 +30,7 @@ struct v4l2_i2c_driver_data {
const char * const name;
int driverid;
int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);
- int (*probe)(struct i2c_client *client);
+ int (*probe)(struct i2c_client *client, const struct i2c_device_id *id);
int (*remove)(struct i2c_client *client);
int (*suspend)(struct i2c_client *client, pm_message_t state);
int (*resume)(struct i2c_client *client);
--- linux-2.6.26-rc0.orig/scripts/mod/file2alias.c 2008-04-27 22:07:28.000000000 +0200
+++ linux-2.6.26-rc0/scripts/mod/file2alias.c 2008-04-27 22:09:29.000000000 +0200
@@ -576,6 +576,15 @@ static int do_virtio_entry(const char *f
return 1;
}
+/* Looks like: i2c:S */
+static int do_i2c_entry(const char *filename, struct i2c_device_id *id,
+ char *alias)
+{
+ sprintf(alias, I2C_MODULE_PREFIX "%s", id->name);
+
+ return 1;
+}
+
/* Ignore any prefix, eg. v850 prepends _ */
static inline int sym_is(const char *symbol, const char *name)
{
@@ -704,6 +713,10 @@ void handle_moddevtable(struct module *m
do_table(symval, sym->st_size,
sizeof(struct virtio_device_id), "virtio",
do_virtio_entry, mod);
+ else if (sym_is(symname, "__mod_i2c_device_table"))
+ do_table(symval, sym->st_size,
+ sizeof(struct i2c_device_id), "i2c",
+ do_i2c_entry, mod);
free(zeros);
}
--
Jean Delvare
^ permalink raw reply
* MPC852T Linux Support
From: Ankur Maheshwari @ 2008-04-28 9:22 UTC (permalink / raw)
To: Linux PPC
Hi all,
I am planning to use MPC-852T on my next card. I want to know whether
any Linux support is available for MPC-852T.
I have worked with MPC860-Kernel-2.4.4 (MPC8xx) earlier. Can I use the
same kernel for MPC-852T or do I need to change something.
If MPC852T Evaluation card / linux support is already available, kindly
send me the pointers.
thanks,
Ankur Maheshwari
^ permalink raw reply
* [PATCH 0/2] i2c: Add support for device alias names
From: Jean Delvare @ 2008-04-28 9:30 UTC (permalink / raw)
To: Linux I2C
Cc: Laurent, Sievers, linuxppc-dev list, Paul Mundt, Scott Wood, Kay
Hi all,
This is an updated, minimal patchset to add support for device alias
names to the i2c subsystem. It is based on earlier work by Jon Smirl,
Jochen Friedrich and myself.
For 2.6.26-rc1 I'll only attempt to push the first two patches: the one
adding the support for alias names and the one converting the drivers
to make use of it. I've even excluded most of the video drivers from
this patch, as they are a bit more difficult to deal with and I don't
want to break them for rc1. This will come later, together with the
patch removing the old device/driver matching scheme.
I've fixed a number of bugs since the previous iteration, and added a
few missing chunks as well. I hope I caught all the pieces this time
but that's hard to tell given that much of the changes are in arch code
I can't even build. So I would like everyone interested in these two
patches getting in 2.6.26-rc1 to give them good testing on as many
systems as possible, and report to me, ideally by the end of the day.
Sorry for the short notice, but I did my best with the little spare
time I had.
Note that there are RTC patches pending for upstream merge, which will
conflict with my patches. Andrew Morton should push them to Linus
today, so that I can rebase my patches before I send them to Linus
(tomorrow). The current versions of the patches apply on top of
2.6.26-git11.
Thanks,
--
Jean Delvare
^ permalink raw reply
* Re: cpu_clock confusion
From: Gabriel Paubert @ 2008-04-28 8:46 UTC (permalink / raw)
To: Johannes Berg
Cc: linux-kernel, benh, linuxppc-dev, tglx, arndb, mingo,
David Miller
In-Reply-To: <1209029257.3357.55.camel@johannes.berg>
On Thu, Apr 24, 2008 at 11:27:37AM +0200, Johannes Berg wrote:
> On Thu, 2008-04-24 at 02:24 -0700, David Miller wrote:
> > From: Johannes Berg <johannes@sipsolutions.net>
> > Date: Thu, 24 Apr 2008 11:21:52 +0200
> >
> > > Hmm. Why is that whole cpu_clock stuff in place anyway? powerpc has
> > > perfectly synchronised time across processors with dirt cheap access to
> > > it as well, so why build all this code that only messes it up on top of
> > > it?
> >
> > Same on sparc64. These changes add more bugs than they fix.
>
> I tend to think all this clock business should be done local to those
> arches that aren't capable of providing cheap, useful synchronised and
> accurate clocks themselves. Or be a lib that they can link in if needed.
> As it stands, it seems to me that it all just penalises those
> architectures that have decent clocks.
100% agreed.
Gabriel
^ permalink raw reply
* Linux support MPC7448 L2 ECC errors
From: Assaf Hoffman @ 2008-04-28 7:40 UTC (permalink / raw)
To: linuxppc-embedded
Hi all,
Can you please tell if MPC7448 L2 ECC error handling is implemented in
any of Linux kernels?
Many thanks.
^ permalink raw reply
* Re: [PATCH] powerpc TLF_RESTORE_SIGMASK
From: Roland McGrath @ 2008-04-28 7:30 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, akpm, linux-kernel
In-Reply-To: <18448.10563.385481.904182@cargo.ozlabs.ibm.com>
> Thanks. That can't go in until some generic changes have gone in
> first, right? So are you going to push the lot in one go via Andrew,
> or should I wait until the generic part is upstream and then push the
> powerpc bit?
>From what I can see, the related patches are in -mm now, but the powerpc
patch is not. Linus already said he approved of the patches, so I hope
they can be merged in real soon. That will simplify the juggling for arch
patches. That said, there is really no hurry for this change for powerpc;
it's a small optimization.
> Oh, and could you please also fix the occurrence of
> TIF_RESTORE_SIGMASK in arch/ppc/kernel/entry.S when this stuff goes
> in?
Oh, I didn't realize that file was in use (or existed).
Third time's the charm (or is this the fifth time?).
Thanks,
Roland
---
[PATCH] powerpc TLF_RESTORE_SIGMASK
Replace TIF_RESTORE_SIGMASK with TLF_RESTORE_SIGMASK and define
our own set_restore_sigmask() function. This saves the costly
SMP-safe set_bit operation, which we do not need for the sigmask
flag since TIF_SIGPENDING always has to be set too.
Signed-off-by: Roland McGrath <roland@redhat.com>
---
arch/powerpc/kernel/entry_32.S | 4 ++--
arch/powerpc/kernel/signal.c | 12 ++++++------
arch/powerpc/kernel/signal_32.c | 2 +-
arch/ppc/kernel/entry.S | 4 ++--
include/asm-powerpc/thread_info.h | 17 +++++++++++++----
5 files changed, 24 insertions(+), 15 deletions(-)
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 84c8686..7e2ecf0 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -667,7 +667,7 @@ user_exc_return: /* r10 contains MSR_KERNEL here */
/* Check current_thread_info()->flags */
rlwinm r9,r1,0,0,(31-THREAD_SHIFT)
lwz r9,TI_FLAGS(r9)
- andi. r0,r9,(_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK|_TIF_NEED_RESCHED)
+ andi. r0,r9,_TIF_USER_WORK_MASK
bne do_work
restore_user:
@@ -924,7 +924,7 @@ recheck:
lwz r9,TI_FLAGS(r9)
andi. r0,r9,_TIF_NEED_RESCHED
bne- do_resched
- andi. r0,r9,_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK
+ andi. r0,r9,_TIF_USER_WORK_MASK
beq restore_user
do_user_signal: /* r10 contains MSR_KERNEL here */
ori r10,r10,MSR_EE
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index a65a44f..ad55488 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -120,7 +120,7 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
int ret;
int is32 = is_32bit_task();
- if (test_thread_flag(TIF_RESTORE_SIGMASK))
+ if (current_thread_info()->local_flags & _TLF_RESTORE_SIGMASK)
oldset = ¤t->saved_sigmask;
else if (!oldset)
oldset = ¤t->blocked;
@@ -131,9 +131,10 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
check_syscall_restart(regs, &ka, signr > 0);
if (signr <= 0) {
+ struct thread_info *ti = current_thread_info();
/* No signal to deliver -- put the saved sigmask back */
- if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
- clear_thread_flag(TIF_RESTORE_SIGMASK);
+ if (ti->local_flags & _TLF_RESTORE_SIGMASK) {
+ ti->local_flags &= ~_TLF_RESTORE_SIGMASK;
sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL);
}
return 0; /* no signals delivered */
@@ -169,10 +170,9 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
/*
* A signal was successfully delivered; the saved sigmask is in
- * its frame, and we can clear the TIF_RESTORE_SIGMASK flag.
+ * its frame, and we can clear the TLF_RESTORE_SIGMASK flag.
*/
- if (test_thread_flag(TIF_RESTORE_SIGMASK))
- clear_thread_flag(TIF_RESTORE_SIGMASK);
+ current_thread_info()->local_flags &= ~_TLF_RESTORE_SIGMASK;
}
return ret;
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index ad69434..4ae16d1 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -243,7 +243,7 @@ long sys_sigsuspend(old_sigset_t mask)
current->state = TASK_INTERRUPTIBLE;
schedule();
- set_thread_flag(TIF_RESTORE_SIGMASK);
+ set_restore_sigmask();
return -ERESTARTNOHAND;
}
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S
index 5f3a5d0..fcd830a 100644
--- a/arch/ppc/kernel/entry.S
+++ b/arch/ppc/kernel/entry.S
@@ -647,7 +647,7 @@ user_exc_return: /* r10 contains MSR_KERNEL here */
/* Check current_thread_info()->flags */
rlwinm r9,r1,0,0,18
lwz r9,TI_FLAGS(r9)
- andi. r0,r9,(_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK|_TIF_NEED_RESCHED)
+ andi. r0,r9,_TIF_USER_WORK_MASK
bne do_work
restore_user:
@@ -898,7 +898,7 @@ recheck:
lwz r9,TI_FLAGS(r9)
andi. r0,r9,_TIF_NEED_RESCHED
bne- do_resched
- andi. r0,r9,_TIF_SIGPENDING
+ andi. r0,r9,_TIF_USER_WORK_MASK
beq restore_user
do_user_signal: /* r10 contains MSR_KERNEL here */
ori r10,r10,MSR_EE
diff --git a/include/asm-powerpc/thread_info.h b/include/asm-powerpc/thread_info.h
index d030f5c..e079e81 100644
--- a/include/asm-powerpc/thread_info.h
+++ b/include/asm-powerpc/thread_info.h
@@ -116,7 +116,6 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_SECCOMP 10 /* secure computing */
#define TIF_RESTOREALL 11 /* Restore all regs (implies NOERROR) */
#define TIF_NOERROR 12 /* Force successful syscall return */
-#define TIF_RESTORE_SIGMASK 13 /* Restore signal mask in do_signal */
#define TIF_FREEZE 14 /* Freezing for suspend */
#define TIF_RUNLATCH 15 /* Is the runlatch enabled? */
#define TIF_ABI_PENDING 16 /* 32/64 bit switch needed */
@@ -134,21 +133,31 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_SECCOMP (1<<TIF_SECCOMP)
#define _TIF_RESTOREALL (1<<TIF_RESTOREALL)
#define _TIF_NOERROR (1<<TIF_NOERROR)
-#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
#define _TIF_FREEZE (1<<TIF_FREEZE)
#define _TIF_RUNLATCH (1<<TIF_RUNLATCH)
#define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING)
#define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP)
-#define _TIF_USER_WORK_MASK ( _TIF_SIGPENDING | \
- _TIF_NEED_RESCHED | _TIF_RESTORE_SIGMASK)
+#define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED)
#define _TIF_PERSYSCALL_MASK (_TIF_RESTOREALL|_TIF_NOERROR)
/* Bits in local_flags */
/* Don't move TLF_NAPPING without adjusting the code in entry_32.S */
#define TLF_NAPPING 0 /* idle thread enabled NAP mode */
+#define TLF_RESTORE_SIGMASK 1 /* Restore signal mask in do_signal */
#define _TLF_NAPPING (1 << TLF_NAPPING)
+#define _TLF_RESTORE_SIGMASK (1 << TLF_RESTORE_SIGMASK)
+
+#ifndef __ASSEMBLY__
+#define HAVE_SET_RESTORE_SIGMASK 1
+static inline void set_restore_sigmask(void)
+{
+ struct thread_info *ti = current_thread_info();
+ ti->local_flags |= _TLF_RESTORE_SIGMASK;
+ set_bit(TIF_SIGPENDING, &ti->flags);
+}
+#endif /* !__ASSEMBLY__ */
#endif /* __KERNEL__ */
^ permalink raw reply related
* Re: [PATHC V3] Watchdog on MPC85xx SMP system
From: Kumar Gala @ 2008-04-28 6:28 UTC (permalink / raw)
To: Chen Gong
Cc: linuxppc-dev@ozlabs.org list, Wim Van Sebroeck, lkml Mailing List
In-Reply-To: <1209363637-22739-1-git-send-email-g.chen@freescale.com>
On Apr 28, 2008, at 1:20 AM, Chen Gong wrote:
> On Book-E SMP systems each core has its own private watchdog.
> If only one watchdog is enabled, when the core that doesn't
> enable the watchdog is hung, system can't reset because no
> watchdog is running on it. That's bad. It means we must enable
> watchdogs on both cores.
>
> We can use smp_call_function() to send appropriate messages to all
> the other
> cores to enable and update the watchdog.
>
> Signed-off-by: Chen Gong <g.chen@freescale.com>
In the future Wim should be copied as maintainer of WATCHDOG drivers
in the kernel.
- k
>
> ---
> Tested on MPC8572DS platform.
>
> drivers/char/watchdog/booke_wdt.c | 34 ++++++++++++++++++++++++++
> +-------
> 1 files changed, 27 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/char/watchdog/booke_wdt.c b/drivers/char/
> watchdog/booke_wdt.c
> index d362f5b..b3a37d0 100644
> --- a/drivers/char/watchdog/booke_wdt.c
> +++ b/drivers/char/watchdog/booke_wdt.c
> @@ -6,7 +6,12 @@
> * Author: Matthew McClintock
> * Maintainer: Kumar Gala <galak@kernel.crashing.org>
> *
> - * Copyright 2005 Freescale Semiconductor Inc.
> + * Copyright 2005, 2008 Freescale Semiconductor Inc.
> + *
> + * Changelog:
> + * 2008-04-28 Chen Gong <g.chen@freescale.com>
> + * Add SMP support for MPC85xx system. Tested on
> + * MPC8572DS platform
> *
> * This program is free software; you can redistribute it and/or
> modify it
> * under the terms of the GNU General Public License as published
> by the
> @@ -16,6 +21,7 @@
>
> #include <linux/module.h>
> #include <linux/fs.h>
> +#include <linux/smp.h>
> #include <linux/miscdevice.h>
> #include <linux/notifier.h>
> #include <linux/watchdog.h>
> @@ -47,23 +53,31 @@ u32 booke_wdt_period = WDT_PERIOD_DEFAULT;
> #define WDTP(x) (TCR_WP(x))
> #endif
>
> +static DEFINE_SPINLOCK(booke_wdt_lock);
> +
> +static void __booke_wdt_ping(void *data)
> +{
> + mtspr(SPRN_TSR, TSR_ENW|TSR_WIS);
> +}
> +
> /*
> * booke_wdt_ping:
> */
> static __inline__ void booke_wdt_ping(void)
> {
> - mtspr(SPRN_TSR, TSR_ENW|TSR_WIS);
> + smp_call_function(__booke_wdt_ping, NULL, 0, 0);
> + __booke_wdt_ping(NULL);
> }
>
> /*
> - * booke_wdt_enable:
> + * __booke_wdt_enable:
> */
> -static __inline__ void booke_wdt_enable(void)
> +static __inline__ void __booke_wdt_enable(void *data)
> {
> u32 val;
>
> /* clear status before enabling watchdog */
> - booke_wdt_ping();
> + __booke_wdt_ping(NULL);
> val = mfspr(SPRN_TCR);
> val |= (TCR_WIE|TCR_WRC(WRC_CHIP)|WDTP(booke_wdt_period));
>
> @@ -137,12 +151,15 @@ static int booke_wdt_ioctl (struct inode
> *inode, struct file *file,
> */
> static int booke_wdt_open (struct inode *inode, struct file *file)
> {
> + spin_lock(&booke_wdt_lock);
> if (booke_wdt_enabled == 0) {
> booke_wdt_enabled = 1;
> - booke_wdt_enable();
> + __booke_wdt_enable(NULL);
> + smp_call_function(__booke_wdt_enable, NULL, 0, 0);
> printk (KERN_INFO "PowerPC Book-E Watchdog Timer Enabled
> (wdt_period=%d)\n",
> booke_wdt_period);
> }
> + spin_unlock(&booke_wdt_lock);
>
> return nonseekable_open(inode, file);
> }
> @@ -183,11 +200,14 @@ static int __init booke_wdt_init(void)
> return ret;
> }
>
> + spin_lock(&booke_wdt_lock);
> if (booke_wdt_enabled == 1) {
> printk (KERN_INFO "PowerPC Book-E Watchdog Timer Enabled
> (wdt_period=%d)\n",
> booke_wdt_period);
> - booke_wdt_enable();
> + __booke_wdt_enable(NULL);
> + smp_call_function(__booke_wdt_enable, NULL, 0, 0);
> }
> + spin_unlock(&booke_wdt_lock);
>
> return ret;
> }
> --
> 1.5.4
^ permalink raw reply
* [PATCH v2] [POWERPC] Add IRQSTACKS support on ppc32
From: Kumar Gala @ 2008-04-28 6:21 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
* Added allocation and initialization of the irq stacks. We limit the
stacks to be in lowmem for ppc32.
* Implemented ppc32 versions of call_do_softirq() and call_handle_irq()
to switch the stack pointers
* Reworked how we do stack overflow detection. We now keep around the
limit of the stack in the thread_struct and compare against the limit
to see if we've overflowed. We can now use this on ppc64 if desired.
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
Removed ifdef from init_IRQ since we have a dummy version of irq_ctx_init
in irq.h
arch/powerpc/Kconfig.debug | 1 -
arch/powerpc/kernel/asm-offsets.c | 1 +
arch/powerpc/kernel/entry_32.S | 4 ++--
arch/powerpc/kernel/irq.c | 10 ++++++++--
arch/powerpc/kernel/misc_32.S | 25 +++++++++++++++++++++++++
arch/powerpc/kernel/process.c | 2 ++
arch/powerpc/kernel/setup_32.c | 21 +++++++++++++++++++++
include/asm-powerpc/processor.h | 6 ++++++
8 files changed, 65 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index a86d8d8..2cf72d2 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -118,7 +118,6 @@ config XMON_DISASSEMBLY
config IRQSTACKS
bool "Use separate kernel stacks when processing interrupts"
- depends on PPC64
help
If you say Y here the kernel will use separate kernel stacks
for handling hard and soft interrupts. This can help avoid
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index adf1d09..0ef4d41 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -64,6 +64,7 @@ int main(void)
#endif /* CONFIG_PPC64 */
DEFINE(KSP, offsetof(struct thread_struct, ksp));
+ DEFINE(KSP_LIMIT, offsetof(struct thread_struct, ksp_limit));
DEFINE(PT_REGS, offsetof(struct thread_struct, regs));
DEFINE(THREAD_FPEXC_MODE, offsetof(struct thread_struct, fpexc_mode));
DEFINE(THREAD_FPR0, offsetof(struct thread_struct, fpr[0]));
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 84c8686..f33c1fe 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -137,8 +137,8 @@ transfer_to_handler:
2: /* if from kernel, check interrupted DOZE/NAP mode and
* check for stack overflow
*/
- lwz r9,THREAD_INFO-THREAD(r12)
- cmplw r1,r9 /* if r1 <= current->thread_info */
+ lwz r9,KSP_LIMIT(r12)
+ cmplw r1,r9 /* if r1 <= ksp_limit */
ble- stack_ovf /* then the kernel stack overflowed */
5:
#ifdef CONFIG_6xx
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 425616f..2f73f70 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -307,6 +307,7 @@ void do_IRQ(struct pt_regs *regs)
if (curtp != irqtp) {
struct irq_desc *desc = irq_desc + irq;
void *handler = desc->handle_irq;
+ unsigned long saved_sp_limit = current->thread.ksp_limit;
if (handler == NULL)
handler = &__do_IRQ;
irqtp->task = curtp->task;
@@ -319,7 +320,10 @@ void do_IRQ(struct pt_regs *regs)
(irqtp->preempt_count & ~SOFTIRQ_MASK) |
(curtp->preempt_count & SOFTIRQ_MASK);
+ current->thread.ksp_limit = (unsigned long)irqtp +
+ _ALIGN_UP(sizeof(struct thread_info), 16);
call_handle_irq(irq, desc, irqtp, handler);
+ current->thread.ksp_limit = saved_sp_limit;
irqtp->task = NULL;
@@ -352,9 +356,7 @@ void __init init_IRQ(void)
{
if (ppc_md.init_IRQ)
ppc_md.init_IRQ();
-#ifdef CONFIG_PPC64
irq_ctx_init();
-#endif
}
@@ -383,11 +385,15 @@ void irq_ctx_init(void)
static inline void do_softirq_onstack(void)
{
struct thread_info *curtp, *irqtp;
+ unsigned long saved_sp_limit = current->thread.ksp_limit;
curtp = current_thread_info();
irqtp = softirq_ctx[smp_processor_id()];
irqtp->task = curtp->task;
+ current->thread.ksp_limit = (unsigned long)irqtp +
+ _ALIGN_UP(sizeof(struct thread_info), 16);
call_do_softirq(irqtp);
+ current->thread.ksp_limit = saved_sp_limit;
irqtp->task = NULL;
}
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index 92ccc6f..89aaaa6 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -32,6 +32,31 @@
.text
+#ifdef CONFIG_IRQSTACKS
+_GLOBAL(call_do_softirq)
+ mflr r0
+ stw r0,4(r1)
+ stwu r1,THREAD_SIZE-STACK_FRAME_OVERHEAD(r3)
+ mr r1,r3
+ bl __do_softirq
+ lwz r1,0(r1)
+ lwz r0,4(r1)
+ mtlr r0
+ blr
+
+_GLOBAL(call_handle_irq)
+ mflr r0
+ stw r0,4(r1)
+ mtctr r6
+ stwu r1,THREAD_SIZE-STACK_FRAME_OVERHEAD(r5)
+ mr r1,r5
+ bctrl
+ lwz r1,0(r1)
+ lwz r0,4(r1)
+ mtlr r0
+ blr
+#endif /* CONFIG_IRQSTACKS */
+
/*
* This returns the high 64 bits of the product of two 64-bit numbers.
*/
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 6caad17..7de41c3 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -589,6 +589,8 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
kregs = (struct pt_regs *) sp;
sp -= STACK_FRAME_OVERHEAD;
p->thread.ksp = sp;
+ p->thread.ksp_limit = (unsigned long)task_stack_page(p) +
+ _ALIGN_UP(sizeof(struct thread_info), 16);
#ifdef CONFIG_PPC64
if (cpu_has_feature(CPU_FTR_SLB)) {
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 36f6779..5112a4a 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -16,6 +16,7 @@
#include <linux/root_dev.h>
#include <linux/cpu.h>
#include <linux/console.h>
+#include <linux/lmb.h>
#include <asm/io.h>
#include <asm/prom.h>
@@ -229,6 +230,24 @@ int __init ppc_init(void)
arch_initcall(ppc_init);
+#ifdef CONFIG_IRQSTACKS
+static void __init irqstack_early_init(void)
+{
+ unsigned int i;
+
+ /* interrupt stacks must be in lowmem, we get that for free on ppc32
+ * as the lmb is limited to lowmem by LMB_REAL_LIMIT */
+ for_each_possible_cpu(i) {
+ softirq_ctx[i] = (struct thread_info *)
+ __va(lmb_alloc(THREAD_SIZE, THREAD_SIZE));
+ hardirq_ctx[i] = (struct thread_info *)
+ __va(lmb_alloc(THREAD_SIZE, THREAD_SIZE));
+ }
+}
+#else
+#define irqstack_early_init()
+#endif
+
/* Warning, IO base is not yet inited */
void __init setup_arch(char **cmdline_p)
{
@@ -286,6 +305,8 @@ void __init setup_arch(char **cmdline_p)
init_mm.end_data = (unsigned long) _edata;
init_mm.brk = klimit;
+ irqstack_early_init();
+
/* set up the bootmem stuff with available memory */
do_init_bootmem();
if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab);
diff --git a/include/asm-powerpc/processor.h b/include/asm-powerpc/processor.h
index fd98ca9..cf83f2d 100644
--- a/include/asm-powerpc/processor.h
+++ b/include/asm-powerpc/processor.h
@@ -138,6 +138,8 @@ typedef struct {
struct thread_struct {
unsigned long ksp; /* Kernel stack pointer */
+ unsigned long ksp_limit; /* if ksp <= ksp_limit stack overflow */
+
#ifdef CONFIG_PPC64
unsigned long ksp_vsid;
#endif
@@ -182,11 +184,14 @@ struct thread_struct {
#define ARCH_MIN_TASKALIGN 16
#define INIT_SP (sizeof(init_stack) + (unsigned long) &init_stack)
+#define INIT_SP_LIMIT \
+ (_ALIGN_UP(sizeof(init_thread_info), 16) + (unsigned long) &init_stack)
#ifdef CONFIG_PPC32
#define INIT_THREAD { \
.ksp = INIT_SP, \
+ .ksp_limit = INIT_SP_LIMIT, \
.fs = KERNEL_DS, \
.pgdir = swapper_pg_dir, \
.fpexc_mode = MSR_FE0 | MSR_FE1, \
@@ -194,6 +199,7 @@ struct thread_struct {
#else
#define INIT_THREAD { \
.ksp = INIT_SP, \
+ .ksp_limit = INIT_SP_LIMIT, \
.regs = (struct pt_regs *)INIT_SP - 1, /* XXX bogus, I think */ \
.fs = KERNEL_DS, \
.fpr = {0}, \
--
1.5.4.1
^ permalink raw reply related
* [PATHC V3] Watchdog on MPC85xx SMP system
From: Chen Gong @ 2008-04-28 6:20 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Chen Gong
On Book-E SMP systems each core has its own private watchdog.
If only one watchdog is enabled, when the core that doesn't
enable the watchdog is hung, system can't reset because no
watchdog is running on it. That's bad. It means we must enable
watchdogs on both cores.
We can use smp_call_function() to send appropriate messages to all the other
cores to enable and update the watchdog.
Signed-off-by: Chen Gong <g.chen@freescale.com>
---
Tested on MPC8572DS platform.
drivers/char/watchdog/booke_wdt.c | 34 +++++++++++++++++++++++++++-------
1 files changed, 27 insertions(+), 7 deletions(-)
diff --git a/drivers/char/watchdog/booke_wdt.c b/drivers/char/watchdog/booke_wdt.c
index d362f5b..b3a37d0 100644
--- a/drivers/char/watchdog/booke_wdt.c
+++ b/drivers/char/watchdog/booke_wdt.c
@@ -6,7 +6,12 @@
* Author: Matthew McClintock
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
*
- * Copyright 2005 Freescale Semiconductor Inc.
+ * Copyright 2005, 2008 Freescale Semiconductor Inc.
+ *
+ * Changelog:
+ * 2008-04-28 Chen Gong <g.chen@freescale.com>
+ * Add SMP support for MPC85xx system. Tested on
+ * MPC8572DS platform
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -16,6 +21,7 @@
#include <linux/module.h>
#include <linux/fs.h>
+#include <linux/smp.h>
#include <linux/miscdevice.h>
#include <linux/notifier.h>
#include <linux/watchdog.h>
@@ -47,23 +53,31 @@ u32 booke_wdt_period = WDT_PERIOD_DEFAULT;
#define WDTP(x) (TCR_WP(x))
#endif
+static DEFINE_SPINLOCK(booke_wdt_lock);
+
+static void __booke_wdt_ping(void *data)
+{
+ mtspr(SPRN_TSR, TSR_ENW|TSR_WIS);
+}
+
/*
* booke_wdt_ping:
*/
static __inline__ void booke_wdt_ping(void)
{
- mtspr(SPRN_TSR, TSR_ENW|TSR_WIS);
+ smp_call_function(__booke_wdt_ping, NULL, 0, 0);
+ __booke_wdt_ping(NULL);
}
/*
- * booke_wdt_enable:
+ * __booke_wdt_enable:
*/
-static __inline__ void booke_wdt_enable(void)
+static __inline__ void __booke_wdt_enable(void *data)
{
u32 val;
/* clear status before enabling watchdog */
- booke_wdt_ping();
+ __booke_wdt_ping(NULL);
val = mfspr(SPRN_TCR);
val |= (TCR_WIE|TCR_WRC(WRC_CHIP)|WDTP(booke_wdt_period));
@@ -137,12 +151,15 @@ static int booke_wdt_ioctl (struct inode *inode, struct file *file,
*/
static int booke_wdt_open (struct inode *inode, struct file *file)
{
+ spin_lock(&booke_wdt_lock);
if (booke_wdt_enabled == 0) {
booke_wdt_enabled = 1;
- booke_wdt_enable();
+ __booke_wdt_enable(NULL);
+ smp_call_function(__booke_wdt_enable, NULL, 0, 0);
printk (KERN_INFO "PowerPC Book-E Watchdog Timer Enabled (wdt_period=%d)\n",
booke_wdt_period);
}
+ spin_unlock(&booke_wdt_lock);
return nonseekable_open(inode, file);
}
@@ -183,11 +200,14 @@ static int __init booke_wdt_init(void)
return ret;
}
+ spin_lock(&booke_wdt_lock);
if (booke_wdt_enabled == 1) {
printk (KERN_INFO "PowerPC Book-E Watchdog Timer Enabled (wdt_period=%d)\n",
booke_wdt_period);
- booke_wdt_enable();
+ __booke_wdt_enable(NULL);
+ smp_call_function(__booke_wdt_enable, NULL, 0, 0);
}
+ spin_unlock(&booke_wdt_lock);
return ret;
}
--
1.5.4
^ permalink raw reply related
* Re: [PATCH] [POWERPC] Add IRQSTACKS support on ppc32
From: Kumar Gala @ 2008-04-28 6:10 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <18453.26718.402204.95133@cargo.ozlabs.ibm.com>
On Apr 28, 2008, at 1:02 AM, Paul Mackerras wrote:
> Kumar Gala writes:
>
>>> Mostly looks great. One minor nit is that this ifdef could
>>> disappear
>>> entirely now:
>>
>> How do you figure? If we want to maintain it as a config option (for
>> at least 2.6.26) we either need this ifdef or a dummy
>> irq_ctx_init().
>
> In include/asm-powerpc/irq.h we already have a dummy definition:
>
> #ifdef CONFIG_IRQSTACKS
>
> ...
>
> #else
> #define irq_ctx_init()
>
> #endif /* CONFIG_IRQSTACKS */
Missed that. Will drop the ifdef in irq.c and repost.
- k
^ permalink raw reply
* Re: [PATCH] [POWERPC] Add IRQSTACKS support on ppc32
From: Paul Mackerras @ 2008-04-28 6:02 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <D84B894B-B6E8-47FD-97CE-CACDE7835B78@kernel.crashing.org>
Kumar Gala writes:
> > Mostly looks great. One minor nit is that this ifdef could disappear
> > entirely now:
>
> How do you figure? If we want to maintain it as a config option (for
> at least 2.6.26) we either need this ifdef or a dummy irq_ctx_init().
In include/asm-powerpc/irq.h we already have a dummy definition:
#ifdef CONFIG_IRQSTACKS
...
#else
#define irq_ctx_init()
#endif /* CONFIG_IRQSTACKS */
Paul.
^ permalink raw reply
* [PATCH] celleb_scc_pciex __iomem annotations
From: Al Viro @ 2008-04-28 5:59 UTC (permalink / raw)
To: torvalds; +Cc: linuxppc-dev, linux-kernel
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
arch/powerpc/platforms/cell/celleb_scc_pciex.c | 18 +++++++++---------
1 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/arch/powerpc/platforms/cell/celleb_scc_pciex.c b/arch/powerpc/platforms/cell/celleb_scc_pciex.c
index ab24d94..31da84c 100644
--- a/arch/powerpc/platforms/cell/celleb_scc_pciex.c
+++ b/arch/powerpc/platforms/cell/celleb_scc_pciex.c
@@ -36,8 +36,8 @@
#include "celleb_scc.h"
#include "celleb_pci.h"
-#define PEX_IN(base, off) in_be32((void *)(base) + (off))
-#define PEX_OUT(base, off, data) out_be32((void *)(base) + (off), (data))
+#define PEX_IN(base, off) in_be32((void __iomem *)(base) + (off))
+#define PEX_OUT(base, off, data) out_be32((void __iomem *)(base) + (off), (data))
static void scc_pciex_io_flush(struct iowa_bus *bus)
{
@@ -304,7 +304,7 @@ static int __init scc_pciex_iowa_init(struct iowa_bus *bus, void *data)
((((0x1 << (size))-1) << ((addr) & 0x3)) << PEXDCMND_BYTE_EN_SHIFT)
#define MK_PEXDCMND(cmd, addr, size) ((cmd) | MK_PEXDCMND_BYTE_EN(addr, size))
-static uint32_t config_read_pciex_dev(unsigned int *base,
+static uint32_t config_read_pciex_dev(unsigned int __iomem *base,
uint64_t bus_no, uint64_t dev_no, uint64_t func_no,
uint64_t off, uint64_t size)
{
@@ -320,7 +320,7 @@ static uint32_t config_read_pciex_dev(unsigned int *base,
return ret;
}
-static void config_write_pciex_dev(unsigned int *base, uint64_t bus_no,
+static void config_write_pciex_dev(unsigned int __iomem *base, uint64_t bus_no,
uint64_t dev_no, uint64_t func_no, uint64_t off, uint64_t size,
uint32_t data)
{
@@ -338,7 +338,7 @@ static void config_write_pciex_dev(unsigned int *base, uint64_t bus_no,
((((0x1 << (len)) - 1) << ((off) & 0x3)) << PEXCADRS_BYTE_EN_SHIFT)
#define MK_PEXCADRS(cmd, addr, size) \
((cmd) | MK_PEXCADRS_BYTE_EN(addr, size) | ((addr) & ~0x3))
-static uint32_t config_read_pciex_rc(unsigned int *base,
+static uint32_t config_read_pciex_rc(unsigned int __iomem *base,
uint32_t where, uint32_t size)
{
PEX_OUT(base, PEXCADRS, MK_PEXCADRS(PEXCADRS_CMD_READ, where, size));
@@ -346,7 +346,7 @@ static uint32_t config_read_pciex_rc(unsigned int *base,
>> ((where & (4 - size)) * 8)) & ((0x1 << (size * 8)) - 1);
}
-static void config_write_pciex_rc(unsigned int *base, uint32_t where,
+static void config_write_pciex_rc(unsigned int __iomem *base, uint32_t where,
uint32_t size, uint32_t val)
{
uint32_t data;
@@ -410,7 +410,7 @@ static struct pci_ops scc_pciex_pci_ops = {
scc_pciex_write_config,
};
-static void pciex_clear_intr_all(unsigned int *base)
+static void pciex_clear_intr_all(unsigned int __iomem *base)
{
PEX_OUT(base, PEXAERRSTS, 0xffffffff);
PEX_OUT(base, PEXPRERRSTS, 0xffffffff);
@@ -427,7 +427,7 @@ static void pciex_disable_intr_all(unsigned int *base)
}
#endif
-static void pciex_enable_intr_all(unsigned int *base)
+static void pciex_enable_intr_all(unsigned int __iomem *base)
{
PEX_OUT(base, PEXINTMASK, 0x0000e7f1);
PEX_OUT(base, PEXAERRMASK, 0x03ff01ff);
@@ -435,7 +435,7 @@ static void pciex_enable_intr_all(unsigned int *base)
PEX_OUT(base, PEXVDMASK, 0x00000001);
}
-static void pciex_check_status(unsigned int *base)
+static void pciex_check_status(unsigned int __iomem *base)
{
uint32_t err = 0;
uint32_t intsts, aerr, prerr, rcvcp, lenerr;
--
1.5.3.GIT
^ permalink raw reply related
* Re: [PATCH] [POWERPC] Add IRQSTACKS support on ppc32
From: Kumar Gala @ 2008-04-28 5:50 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <18453.24013.647603.723185@cargo.ozlabs.ibm.com>
On Apr 28, 2008, at 12:17 AM, Paul Mackerras wrote:
> Kumar Gala writes:
>
>> * Added allocation and initialization of the irq stacks. We limit
>> the
>> stacks to be in lowmem for ppc32.
>> * Implemented ppc32 versions of call_do_softirq() and
>> call_handle_irq()
>> to switch the stack pointers
>> * Reworked how we do stack overflow detection. We now keep around
>> the
>> limit of the stack in the thread_struct and compare against the
>> limit
>> to see if we've overflowed. We can now use this on ppc64 if
>> desired.
>
> Mostly looks great. One minor nit is that this ifdef could disappear
> entirely now:
How do you figure? If we want to maintain it as a config option (for
at least 2.6.26) we either need this ifdef or a dummy irq_ctx_init().
>> @@ -352,7 +356,7 @@ void __init init_IRQ(void)
>> {
>> if (ppc_md.init_IRQ)
>> ppc_md.init_IRQ();
>> -#ifdef CONFIG_PPC64
>> +#ifdef CONFIG_IRQSTACKS
>> irq_ctx_init();
>> #endif
>
> Since it looks pretty much exactly like what 64-bit already does, and
> it's under a config option, I withdraw my objection to it going into
> 2.6.26.
:)
- k
^ permalink raw reply
* Re: [PATCH] [POWERPC] Add IRQSTACKS support on ppc32
From: Paul Mackerras @ 2008-04-28 5:17 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <Pine.LNX.4.64.0804240814280.29846@blarg.am.freescale.net>
Kumar Gala writes:
> * Added allocation and initialization of the irq stacks. We limit the
> stacks to be in lowmem for ppc32.
> * Implemented ppc32 versions of call_do_softirq() and call_handle_irq()
> to switch the stack pointers
> * Reworked how we do stack overflow detection. We now keep around the
> limit of the stack in the thread_struct and compare against the limit
> to see if we've overflowed. We can now use this on ppc64 if desired.
Mostly looks great. One minor nit is that this ifdef could disappear
entirely now:
> @@ -352,7 +356,7 @@ void __init init_IRQ(void)
> {
> if (ppc_md.init_IRQ)
> ppc_md.init_IRQ();
> -#ifdef CONFIG_PPC64
> +#ifdef CONFIG_IRQSTACKS
> irq_ctx_init();
> #endif
Since it looks pretty much exactly like what 64-bit already does, and
it's under a config option, I withdraw my objection to it going into
2.6.26.
Paul.
^ permalink raw reply
* Re: [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code to supportRev B boards
From: Grant Likely @ 2008-04-28 4:47 UTC (permalink / raw)
To: Sean MacLennan; +Cc: Stephen Rothwell, linuxppc-dev
In-Reply-To: <20080427222514.1086f2d3@lappy.seanm.ca>
On Sun, Apr 27, 2008 at 8:25 PM, Sean MacLennan <smaclennan@pikatech.com> wrote:
> On Sun, 27 Apr 2008 19:51:57 -0600
> "Grant Likely" <grant.likely@secretlab.ca> wrote:
>
> > Actually, it looks like he's trying to find the second gpio node in
> > the tree.
>
> Correct.
>
>
> > Sean, if that is true, then this is a very fragile way to do it.
> > Really, you should have a phandle somewhere that points to the GPIO
> > node that your LEDs are attached to. Others have been addressing the
> > same problem and the consensus seems to be to add a 'leds' node for
> > each of your leds with a phandle and gpio descriptor to the gpio node.
> >
> > See the documentation added by this patch (section 't'):
> > http://patchwork.ozlabs.org/linuxppc/patch?id=18156
>
> I saw that earlier. I thought that that method relied on the gpio_led
> driver? I want to use the gpio_led driver, but I believe the underlying
> gpio code for the 440EP is not done yet.
Something very important to remember: The device tree is simply a
description of the hardware. Its layout *must* *not* be driven by
device driver design. Driver design can and will change over time;
hardware description conventions should be relatively stable.
If your LEDs are attached to gpio pins, then you should use the
current draft led->gpio bindings as shown in the above patch. Then,
let your platform code extract whatever data it needs from the device
tree to set up the LEDs.
It is irrelevant that the 44EP GPIO driver doesn't support that
binding. Just make sure that the warp platform code doesn't register
warp's linux,gpio-led device tree nodes onto the of_platform bus.
That way your platform code can do whatever it wants to handle the
LEDs itself.
Cheers,
g.
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply
* [POWERPC] Use __always_inline for xchg* and cmpxchg*
From: Paul Mackerras @ 2008-04-28 4:44 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel
This changes the definitions of the xchg and cmpxchg families of
functions in include/asm-powerpc/system.h to be marked __always_inline
rather than __inline__. The reason for doing this is that we rely on
the compiler inlining them in order to eliminate the references to
__xchg_called_with_bad_pointer and __cmpxchg_called_with_bad_pointer,
which are deliberately left undefined. Thus this change will enable
us to make the inline keyword be just a hint rather than a directive.
Signed-off-by: Paul Mackerras <paulus@samba.org>
---
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
index fab1674..2b6559a 100644
--- a/include/asm-powerpc/system.h
+++ b/include/asm-powerpc/system.h
@@ -204,7 +204,7 @@ extern int powersave_nap; /* set if nap mode can be used in idle loop */
* Changes the memory location '*ptr' to be val and returns
* the previous value stored there.
*/
-static __inline__ unsigned long
+static __always_inline unsigned long
__xchg_u32(volatile void *p, unsigned long val)
{
unsigned long prev;
@@ -229,7 +229,7 @@ __xchg_u32(volatile void *p, unsigned long val)
* Changes the memory location '*ptr' to be val and returns
* the previous value stored there.
*/
-static __inline__ unsigned long
+static __always_inline unsigned long
__xchg_u32_local(volatile void *p, unsigned long val)
{
unsigned long prev;
@@ -247,7 +247,7 @@ __xchg_u32_local(volatile void *p, unsigned long val)
}
#ifdef CONFIG_PPC64
-static __inline__ unsigned long
+static __always_inline unsigned long
__xchg_u64(volatile void *p, unsigned long val)
{
unsigned long prev;
@@ -266,7 +266,7 @@ __xchg_u64(volatile void *p, unsigned long val)
return prev;
}
-static __inline__ unsigned long
+static __always_inline unsigned long
__xchg_u64_local(volatile void *p, unsigned long val)
{
unsigned long prev;
@@ -290,7 +290,7 @@ __xchg_u64_local(volatile void *p, unsigned long val)
*/
extern void __xchg_called_with_bad_pointer(void);
-static __inline__ unsigned long
+static __always_inline unsigned long
__xchg(volatile void *ptr, unsigned long x, unsigned int size)
{
switch (size) {
@@ -305,7 +305,7 @@ __xchg(volatile void *ptr, unsigned long x, unsigned int size)
return x;
}
-static __inline__ unsigned long
+static __always_inline unsigned long
__xchg_local(volatile void *ptr, unsigned long x, unsigned int size)
{
switch (size) {
@@ -338,7 +338,7 @@ __xchg_local(volatile void *ptr, unsigned long x, unsigned int size)
*/
#define __HAVE_ARCH_CMPXCHG 1
-static __inline__ unsigned long
+static __always_inline unsigned long
__cmpxchg_u32(volatile unsigned int *p, unsigned long old, unsigned long new)
{
unsigned int prev;
@@ -361,7 +361,7 @@ __cmpxchg_u32(volatile unsigned int *p, unsigned long old, unsigned long new)
return prev;
}
-static __inline__ unsigned long
+static __always_inline unsigned long
__cmpxchg_u32_local(volatile unsigned int *p, unsigned long old,
unsigned long new)
{
@@ -384,7 +384,7 @@ __cmpxchg_u32_local(volatile unsigned int *p, unsigned long old,
}
#ifdef CONFIG_PPC64
-static __inline__ unsigned long
+static __always_inline unsigned long
__cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new)
{
unsigned long prev;
@@ -406,7 +406,7 @@ __cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new)
return prev;
}
-static __inline__ unsigned long
+static __always_inline unsigned long
__cmpxchg_u64_local(volatile unsigned long *p, unsigned long old,
unsigned long new)
{
@@ -432,7 +432,7 @@ __cmpxchg_u64_local(volatile unsigned long *p, unsigned long old,
if something tries to do an invalid cmpxchg(). */
extern void __cmpxchg_called_with_bad_pointer(void);
-static __inline__ unsigned long
+static __always_inline unsigned long
__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new,
unsigned int size)
{
@@ -448,7 +448,7 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new,
return old;
}
-static __inline__ unsigned long
+static __always_inline unsigned long
__cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new,
unsigned int size)
{
^ permalink raw reply related
* Re: get_cycles()
From: Tony Breeds @ 2008-04-28 4:38 UTC (permalink / raw)
To: Kevin Diggs; +Cc: linuxppc-dev
In-Reply-To: <48145709.9020809@hypersurf.com>
On Sun, Apr 27, 2008 at 03:35:54AM -0700, Kevin Diggs wrote:
> I'm working on a cpufreq driver for the 750GX so I don't think I have to
> worry about being to platform specific.
>
> Would a compile time configuration be a good idea (hrtimer or
> get_cycles() assisted timing)?
Save yourself the pain, and use the hrtimers infrastructure.
> In the 2.4 code I just used a timer 2 ticks in the future to be certain
> I did not go under the 100 us PLL lock delay. I was trying to see if I
> could cut the latency down.
>
> What about using OF? Isn't there a timebase property for the cpus?
Sure, If you really don't want to use the infrastructure that's there
feel free to duplicate portions of arch/powerpc/kernel/time.c and
kernel/time/* into your cpufreq driver.
Yours Tony
linux.conf.au http://www.marchsouth.org/
Jan 19 - 24 2009 The Australian Linux Technical Conference!
^ permalink raw reply
* Re: 2.6.25: pmac_newworld undefined
From: Tony Breeds @ 2008-04-28 4:20 UTC (permalink / raw)
To: Christian Kujau, Sam Ravnborg; +Cc: linuxppc-dev, LKML
In-Reply-To: <alpine.DEB.1.10.0804271951190.11017@sheep.housecafe.de>
On Sun, Apr 27, 2008 at 08:03:46PM +0200, Christian Kujau wrote:
> Hi,
>
> the build failure reported[0] by Kamalesh back in 01/2008 is still
> present in today's 2.6.25-git with CONFIG_NVRAM=m (instead of =y):
>
> Building modules, stage 2.
> MODPOST 72 modules
> ERROR: "pmac_newworld" [arch/powerpc/platforms/powermac/nvram.ko] undefined!
> ERROR: "__alloc_bootmem" [arch/powerpc/platforms/powermac/nvram.ko]
> undefined!
> make[1]: *** [__modpost] Error 1
Yeah that isn't really surprising. Essentially
arch/powerpc/platforms/powermac/nvram.c must be builtin (not modular)
but CONFIG_NVRAM is tristate, and your .config has CONFIG_NVRAM=m.
We can probably "fix" this by adding another config config symbol and
"selecting" that from CONFIG_NVRAM. Then using this new symbol in
arch/powerpc/platforms/powermac/*
so I think with we need is:
config NVRAM
bool "..." if PPC32
tristate "..." if !PPC32
...
...
Sam is there some way to achieve that or should we just create an
secondary symbol?
Yours Tony
linux.conf.au http://www.marchsouth.org/
Jan 19 - 24 2009 The Australian Linux Technical Conference!
^ permalink raw reply
* [PATCH] Add fast little-endian switch system call
From: Paul Mackerras @ 2008-04-28 3:52 UTC (permalink / raw)
To: linuxppc-dev
This adds a system call on 64-bit platforms for switching between
little-endian and big-endian modes that is much faster than doing a
prctl call. This system call is handled as a special case right at
the start of the system call entry code, and because it is a special
case, it uses a system call number which is out of the range of
normal system calls, namely 0x1ebe.
Measurements with lmbench on a 4.2GHz POWER6 showed no measurable
change in the speed of normal system calls with this patch.
Switching endianness with this new system call takes around 60ns on a
4.2GHz POWER6, compared with around 300ns to switch endian mode with a
prctl. This can provide a significant performance advantage for
emulators for little-endian architectures that want to switch between
big-endian and little-endian mode frequently, e.g. because they are
generating instructions sequences on the fly and they want to run
those sequences in little-endian mode.
Signed-off-by: Paul Mackerras <paulus@samba.org>
---
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 215973a..2eb49a7 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -239,6 +239,10 @@ instruction_access_slb_pSeries:
.globl system_call_pSeries
system_call_pSeries:
HMT_MEDIUM
+BEGIN_FTR_SECTION
+ cmpdi r0,0x1ebe
+ beq- 1f
+END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
mr r9,r13
mfmsr r10
mfspr r13,SPRN_SPRG3
@@ -253,6 +257,13 @@ system_call_pSeries:
rfid
b . /* prevent speculative execution */
+/* Fast LE/BE switch system call */
+1: mfspr r12,SPRN_SRR1
+ xori r12,r12,MSR_LE
+ mtspr SPRN_SRR1,r12
+ rfid /* return to userspace */
+ b .
+
STD_EXCEPTION_PSERIES(0xd00, single_step)
STD_EXCEPTION_PSERIES(0xe00, trap_0e)
^ permalink raw reply related
* Re: [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code to supportRev B boards
From: Sean MacLennan @ 2008-04-28 2:31 UTC (permalink / raw)
To: Stephen Rothwell; +Cc: linuxppc-dev
In-Reply-To: <20080428105859.daef4d71.sfr@canb.auug.org.au>
On Mon, 28 Apr 2008 10:58:59 +1000
"Stephen Rothwell" <sfr@canb.auug.org.au> wrote:
> You really want linux.of.h (unless there was some preexisting reason
> to require of_platform.h).
You are correct. That was a cut and paste from warp.c which
specifically needs of_platform.h.
Cheers,
Sean
^ permalink raw reply
* Re: [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code to supportRev B boards
From: Sean MacLennan @ 2008-04-28 2:25 UTC (permalink / raw)
To: Grant Likely; +Cc: Stephen Rothwell, linuxppc-dev
In-Reply-To: <fa686aa40804271851t6d762a1et76fa3cc02c2205fe@mail.gmail.com>
On Sun, 27 Apr 2008 19:51:57 -0600
"Grant Likely" <grant.likely@secretlab.ca> wrote:
> Actually, it looks like he's trying to find the second gpio node in
> the tree.
Correct.
> Sean, if that is true, then this is a very fragile way to do it.
> Really, you should have a phandle somewhere that points to the GPIO
> node that your LEDs are attached to. Others have been addressing the
> same problem and the consensus seems to be to add a 'leds' node for
> each of your leds with a phandle and gpio descriptor to the gpio node.
>
> See the documentation added by this patch (section 't'):
> http://patchwork.ozlabs.org/linuxppc/patch?id=18156
I saw that earlier. I thought that that method relied on the gpio_led
driver? I want to use the gpio_led driver, but I believe the underlying
gpio code for the 440EP is not done yet.
If *either* assumption is wrong, let me know! It would be one less
driver (the warp_led driver) that I would have to support outside the
mainline kernel.
I believe, if the platform update gets accepted, that in 2.6.26 the
Warp will be usable with the the mainline kernel. You will just lose
some functionally, such as the SD driver which has already been
rejected.
Cheers,
Sean
^ permalink raw reply
* Re: [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code to supportRev B boards
From: Grant Likely @ 2008-04-28 1:51 UTC (permalink / raw)
To: Stephen Rothwell; +Cc: linuxppc-dev, Sean MacLennan
In-Reply-To: <20080428105859.daef4d71.sfr@canb.auug.org.au>
On Sun, Apr 27, 2008 at 6:58 PM, Stephen Rothwell <sfr@canb.auug.org.au> wrote:
> Hi Sean,
>
>
> On Sun, 27 Apr 2008 15:25:46 -0400 Sean MacLennan <smaclennan@pikatech.com> wrote:
> >
> > +++ b/arch/powerpc/platforms/44x/warp-nand.c
> > @@ -11,8 +11,10 @@
> > #include <linux/mtd/partitions.h>
> > #include <linux/mtd/nand.h>
> > #include <linux/mtd/ndfc.h>
> > +#include <linux/of_platform.h>
>
> You really want linux.of.h (unless there was some preexisting reason to
> require of_platform.h).
>
>
> > +static void pika_setup_critical_temp(struct i2c_client *client)
> > +{
> > + struct device_node *np;
> > + int irq, rc;
> > +
> > + /* Setup power LEDS for possible critical temp */
> > + np = of_find_compatible_node(NULL, NULL, "ibm,gpio-440EP");
> > + if (np)
> > + np = of_find_compatible_node(np, NULL, "ibm,gpio-440EP");
>
> Did you really mean to test if (!np) above instead?
Actually, it looks like he's trying to find the second gpio node in the tree.
Sean, if that is true, then this is a very fragile way to do it.
Really, you should have a phandle somewhere that points to the GPIO
node that your LEDs are attached to. Others have been addressing the
same problem and the consensus seems to be to add a 'leds' node for
each of your leds with a phandle and gpio descriptor to the gpio node.
See the documentation added by this patch (section 't'):
http://patchwork.ozlabs.org/linuxppc/patch?id=18156
Cheers,
g.
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply
* Re: [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code to supportRev B boards
From: Stephen Rothwell @ 2008-04-28 0:58 UTC (permalink / raw)
To: Sean MacLennan; +Cc: linuxppc-dev
In-Reply-To: <20080427152546.1e26b145@lappy.seanm.ca>
[-- Attachment #1: Type: text/plain, Size: 895 bytes --]
Hi Sean,
On Sun, 27 Apr 2008 15:25:46 -0400 Sean MacLennan <smaclennan@pikatech.com> wrote:
>
> +++ b/arch/powerpc/platforms/44x/warp-nand.c
> @@ -11,8 +11,10 @@
> #include <linux/mtd/partitions.h>
> #include <linux/mtd/nand.h>
> #include <linux/mtd/ndfc.h>
> +#include <linux/of_platform.h>
You really want linux.of.h (unless there was some preexisting reason to
require of_platform.h).
> +static void pika_setup_critical_temp(struct i2c_client *client)
> +{
> + struct device_node *np;
> + int irq, rc;
> +
> + /* Setup power LEDS for possible critical temp */
> + np = of_find_compatible_node(NULL, NULL, "ibm,gpio-440EP");
> + if (np)
> + np = of_find_compatible_node(np, NULL, "ibm,gpio-440EP");
Did you really mean to test if (!np) above instead?
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: EABI
From: Ron Sass @ 2008-04-27 20:36 UTC (permalink / raw)
To: Brian Silverman; +Cc: linuxppc-embedded
In-Reply-To: <4810B196.7000300@conceptxdesign.com>
Unfortunately, it is not that easy. The Xilinx tool chain use
newlib but your Linux kernel (and rootfs) is probably built
around glibc. When we've wanted to do a quick-and-dirty test of
something that relies on Xilinx's patches to gcc, we have used
powerpc-eabi-gcc to compile to assembler and then used our own
crosstools compilers to link and load.
That doesn't solve your problem but hopefully it explains the
issue.
Ron
> Is it possible to compile a Linux application using an EABI compiler
> (specfically, Xilinx's EDK powerpc-eabi-gcc.exe)?
>
> The issue at hand is that we'd like for our customers to be able to use
> the Xilinx EDK toolchain (which we know they will have) to compile Linx
> apps without having to install another toolchain (crosstool, ELDK, etc).
>
> So, what I'm hoping is that the EDK toolchain can be configured to be
> Linux compatible binaries, or that there is some kind of wrapper that
> will handle the incompatible interfaces. Searching around, I've seen
> some mention of Linux EABI compatibility (for Debian ARM releases), but
> I haven't found any clear concensus...
>
> P.S. My apologies if this message appears on the mailing list twice...
>
> --
> Brian Silverman
> Concept X, LLC
^ permalink raw reply
* Re: ARCH=ppc strncmp undefined
From: Grant Likely @ 2008-04-27 20:24 UTC (permalink / raw)
To: dhlii; +Cc: linuxppc-embedded
In-Reply-To: <4814D35C.9070608@dlasys.net>
On Sun, Apr 27, 2008 at 1:26 PM, David H. Lynch Jr. <dhlii@dlasys.net> wrote:
> After pulling and rebasing to 2.6.25, I get strncmp is undefined
> when I try to link the kernel.
>
> I have not chased this down as just added strncmp into
> arch/ppc/lib/string.S
>
> But I would guess this is a side effect of changes to accomidate
> migration to ARCH=powerpc.
> There appear to be a number of remaining arch/ppc BSP's that need
> strncmp and therefore
> will not build in 2.6.25.
There is a patch to fix this bug:
http://ozlabs.org/pipermail/linuxppc-dev/2008-April/055094.html
Cheers,
g.
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox