Hi all,
The following 2 patches do the following to bq2415x_charger:
- first patch fixes pre-existing coding style issues reported by checkpatch.pl
- second patch adds ACPI enumeration support
Thanks,
Anda
Anda-Maria Nicolae (2):
power_supply: bq2415x_charger: Fix coding style issues
power_supply: bq2415x_charger: Add ACPI support
drivers/power/bq2415x_charger.c | 94 +++++++++++++++++++++++++++------------
1 file changed, 66 insertions(+), 28 deletions(-)
--
1.7.9.5
This patch fixes the following issues reported by checkpatch.pl:
- use -EINVAL instead of -ENOSYS, to fix warning message:
"ENOSYS means 'invalid syscall nr' and nothing else"
- remove unnecessary log message
- split lines whose length is greater than 80 characters
- if an arm statement uses braces, add braces to the other arms of the
respective statement, too
- match alignment with open parenthesis
Signed-off-by: Anda-Maria Nicolae <[email protected]>
---
drivers/power/bq2415x_charger.c | 35 ++++++++++++++++++-----------------
1 file changed, 18 insertions(+), 17 deletions(-)
diff --git a/drivers/power/bq2415x_charger.c b/drivers/power/bq2415x_charger.c
index 6c534dc..2cf8ec7 100644
--- a/drivers/power/bq2415x_charger.c
+++ b/drivers/power/bq2415x_charger.c
@@ -631,7 +631,7 @@ static int bq2415x_set_charge_current(struct bq2415x_device *bq, int mA)
int val;
if (bq->init_data.resistor_sense <= 0)
- return -ENOSYS;
+ return -EINVAL;
val = (mA * bq->init_data.resistor_sense - 37400) / 6800;
if (val < 0)
@@ -650,7 +650,7 @@ static int bq2415x_get_charge_current(struct bq2415x_device *bq)
int ret;
if (bq->init_data.resistor_sense <= 0)
- return -ENOSYS;
+ return -EINVAL;
ret = bq2415x_i2c_read_mask(bq, BQ2415X_REG_CURRENT,
BQ2415X_MASK_VI_CHRG, BQ2415X_SHIFT_VI_CHRG);
@@ -665,7 +665,7 @@ static int bq2415x_set_termination_current(struct bq2415x_device *bq, int mA)
int val;
if (bq->init_data.resistor_sense <= 0)
- return -ENOSYS;
+ return -EINVAL;
val = (mA * bq->init_data.resistor_sense - 3400) / 3400;
if (val < 0)
@@ -684,7 +684,7 @@ static int bq2415x_get_termination_current(struct bq2415x_device *bq)
int ret;
if (bq->init_data.resistor_sense <= 0)
- return -ENOSYS;
+ return -EINVAL;
ret = bq2415x_i2c_read_mask(bq, BQ2415X_REG_CURRENT,
BQ2415X_MASK_VI_TERM, BQ2415X_SHIFT_VI_TERM);
@@ -1166,7 +1166,7 @@ static ssize_t bq2415x_sysfs_set_mode(struct device *dev,
if (strncmp(buf, "auto", 4) == 0) {
if (bq->automode < 0)
- return -ENOSYS;
+ return -EINVAL;
bq->automode = 1;
mode = bq->reported_mode;
} else if (strncmp(buf, "off", 3) == 0) {
@@ -1556,28 +1556,28 @@ static int bq2415x_probe(struct i2c_client *client,
bq = devm_kzalloc(&client->dev, sizeof(*bq), GFP_KERNEL);
if (!bq) {
- dev_err(&client->dev, "failed to allocate device data\n");
ret = -ENOMEM;
goto error_2;
}
if (np) {
- bq->notify_psy = power_supply_get_by_phandle(np, "ti,usb-charger-detection");
+ bq->notify_psy = power_supply_get_by_phandle(np,
+ "ti,usb-charger-detection");
if (IS_ERR(bq->notify_psy)) {
dev_info(&client->dev,
- "no 'ti,usb-charger-detection' property (err=%ld)\n",
+ "no 'ti,usb-charger-detection' property (err=%ld)\n",
PTR_ERR(bq->notify_psy));
bq->notify_psy = NULL;
} else if (!bq->notify_psy) {
ret = -EPROBE_DEFER;
goto error_2;
}
- }
- else if (pdata->notify_device)
+ } else if (pdata->notify_device) {
bq->notify_psy = power_supply_get_by_name(pdata->notify_device);
- else
+ } else {
bq->notify_psy = NULL;
+ }
i2c_set_clientdata(client, bq);
@@ -1592,11 +1592,11 @@ static int bq2415x_probe(struct i2c_client *client,
if (np) {
ret = of_property_read_u32(np, "ti,current-limit",
- &bq->init_data.current_limit);
+ &bq->init_data.current_limit);
if (ret)
goto error_3;
ret = of_property_read_u32(np, "ti,weak-battery-voltage",
- &bq->init_data.weak_battery_voltage);
+ &bq->init_data.weak_battery_voltage);
if (ret)
goto error_3;
ret = of_property_read_u32(np, "ti,battery-regulation-voltage",
@@ -1604,15 +1604,15 @@ static int bq2415x_probe(struct i2c_client *client,
if (ret)
goto error_3;
ret = of_property_read_u32(np, "ti,charge-current",
- &bq->init_data.charge_current);
+ &bq->init_data.charge_current);
if (ret)
goto error_3;
ret = of_property_read_u32(np, "ti,termination-current",
- &bq->init_data.termination_current);
+ &bq->init_data.termination_current);
if (ret)
goto error_3;
ret = of_property_read_u32(np, "ti,resistor-sense",
- &bq->init_data.resistor_sense);
+ &bq->init_data.resistor_sense);
if (ret)
goto error_3;
} else {
@@ -1648,7 +1648,8 @@ static int bq2415x_probe(struct i2c_client *client,
}
/* Query for initial reported_mode and set it */
- bq2415x_notifier_call(&bq->nb, PSY_EVENT_PROP_CHANGED, bq->notify_psy);
+ bq2415x_notifier_call(&bq->nb, PSY_EVENT_PROP_CHANGED,
+ bq->notify_psy);
bq2415x_set_mode(bq, bq->reported_mode);
bq->automode = 1;
--
1.7.9.5
Replace of_property_read_u32() with device_property_read_u32(), which is a
wrapper over ACPI and device tree enumeration methods.
When ACPI enumeration is used, automode is not supported. Therefore,
bq2415x_charger does not update its input current automatically, depending
on the USB port type that is connected to. Input current may be updated via
sysfs.
Signed-off-by: Anda-Maria Nicolae <[email protected]>
---
drivers/power/bq2415x_charger.c | 73 +++++++++++++++++++++++++++++----------
1 file changed, 55 insertions(+), 18 deletions(-)
diff --git a/drivers/power/bq2415x_charger.c b/drivers/power/bq2415x_charger.c
index 2cf8ec7..e98dcb6 100644
--- a/drivers/power/bq2415x_charger.c
+++ b/drivers/power/bq2415x_charger.c
@@ -35,6 +35,7 @@
#include <linux/idr.h>
#include <linux/i2c.h>
#include <linux/slab.h>
+#include <linux/acpi.h>
#include <linux/power/bq2415x_charger.h>
@@ -1530,13 +1531,14 @@ static int bq2415x_probe(struct i2c_client *client,
{
int ret;
int num;
- char *name;
+ char *name = NULL;
struct bq2415x_device *bq;
struct device_node *np = client->dev.of_node;
struct bq2415x_platform_data *pdata = client->dev.platform_data;
+ const struct acpi_device_id *acpi_id = NULL;
- if (!np && !pdata) {
- dev_err(&client->dev, "platform data missing\n");
+ if (!np && !pdata && !ACPI_HANDLE(&client->dev)) {
+ dev_err(&client->dev, "Neither devicetree, nor platform data, nor ACPI support\n");
return -ENODEV;
}
@@ -1547,7 +1549,14 @@ static int bq2415x_probe(struct i2c_client *client,
if (num < 0)
return num;
- name = kasprintf(GFP_KERNEL, "%s-%d", id->name, num);
+ if (id) {
+ name = kasprintf(GFP_KERNEL, "%s-%d", id->name, num);
+ } else if (ACPI_HANDLE(&client->dev)) {
+ acpi_id =
+ acpi_match_device(client->dev.driver->acpi_match_table,
+ &client->dev);
+ name = kasprintf(GFP_KERNEL, "%s-%d", acpi_id->id, num);
+ }
if (!name) {
dev_err(&client->dev, "failed to allocate device name\n");
ret = -ENOMEM;
@@ -1573,7 +1582,7 @@ static int bq2415x_probe(struct i2c_client *client,
ret = -EPROBE_DEFER;
goto error_2;
}
- } else if (pdata->notify_device) {
+ } else if (pdata && pdata->notify_device) {
bq->notify_psy = power_supply_get_by_name(pdata->notify_device);
} else {
bq->notify_psy = NULL;
@@ -1583,36 +1592,45 @@ static int bq2415x_probe(struct i2c_client *client,
bq->id = num;
bq->dev = &client->dev;
- bq->chip = id->driver_data;
+ if (id)
+ bq->chip = id->driver_data;
+ else if (ACPI_HANDLE(bq->dev))
+ bq->chip = acpi_id->driver_data;
bq->name = name;
bq->mode = BQ2415X_MODE_OFF;
bq->reported_mode = BQ2415X_MODE_OFF;
bq->autotimer = 0;
bq->automode = 0;
- if (np) {
- ret = of_property_read_u32(np, "ti,current-limit",
- &bq->init_data.current_limit);
+ if (np || ACPI_HANDLE(bq->dev)) {
+ ret = device_property_read_u32(bq->dev,
+ "ti,current-limit",
+ &bq->init_data.current_limit);
if (ret)
goto error_3;
- ret = of_property_read_u32(np, "ti,weak-battery-voltage",
- &bq->init_data.weak_battery_voltage);
+ ret = device_property_read_u32(bq->dev,
+ "ti,weak-battery-voltage",
+ &bq->init_data.weak_battery_voltage);
if (ret)
goto error_3;
- ret = of_property_read_u32(np, "ti,battery-regulation-voltage",
+ ret = device_property_read_u32(bq->dev,
+ "ti,battery-regulation-voltage",
&bq->init_data.battery_regulation_voltage);
if (ret)
goto error_3;
- ret = of_property_read_u32(np, "ti,charge-current",
- &bq->init_data.charge_current);
+ ret = device_property_read_u32(bq->dev,
+ "ti,charge-current",
+ &bq->init_data.charge_current);
if (ret)
goto error_3;
- ret = of_property_read_u32(np, "ti,termination-current",
- &bq->init_data.termination_current);
+ ret = device_property_read_u32(bq->dev,
+ "ti,termination-current",
+ &bq->init_data.termination_current);
if (ret)
goto error_3;
- ret = of_property_read_u32(np, "ti,resistor-sense",
- &bq->init_data.resistor_sense);
+ ret = device_property_read_u32(bq->dev,
+ "ti,resistor-sense",
+ &bq->init_data.resistor_sense);
if (ret)
goto error_3;
} else {
@@ -1728,9 +1746,28 @@ static const struct i2c_device_id bq2415x_i2c_id_table[] = {
};
MODULE_DEVICE_TABLE(i2c, bq2415x_i2c_id_table);
+static const struct acpi_device_id bq2415x_i2c_acpi_match[] = {
+ { "BQ2415X", BQUNKNOWN },
+ { "BQ241500", BQ24150 },
+ { "BQA24150", BQ24150A },
+ { "BQ241510", BQ24151 },
+ { "BQA24151", BQ24151A },
+ { "BQ241520", BQ24152 },
+ { "BQ241530", BQ24153 },
+ { "BQA24153", BQ24153A },
+ { "BQ241550", BQ24155 },
+ { "BQ241560", BQ24156 },
+ { "BQA24156", BQ24156A },
+ { "BQS24157", BQ24157S },
+ { "BQ241580", BQ24158 },
+ {},
+};
+MODULE_DEVICE_TABLE(acpi, bq2415x_i2c_acpi_match);
+
static struct i2c_driver bq2415x_driver = {
.driver = {
.name = "bq2415x-charger",
+ .acpi_match_table = ACPI_PTR(bq2415x_i2c_acpi_match),
},
.probe = bq2415x_probe,
.remove = bq2415x_remove,
--
1.7.9.5
Hi,
On Tue, May 12, 2015 at 12:11:31PM +0300, Anda-Maria Nicolae wrote:
> The following 2 patches do the following to bq2415x_charger:
> - first patch fixes pre-existing coding style issues reported by checkpatch.pl
> - second patch adds ACPI enumeration support
Thanks, queued.
-- Sebastian
On Tue 2015-05-12 12:11:32, Anda-Maria Nicolae wrote:
> This patch fixes the following issues reported by checkpatch.pl:
> - use -EINVAL instead of -ENOSYS, to fix warning message:
> "ENOSYS means 'invalid syscall nr' and nothing else"
So you change the ABI? Just like that? With changelog saying "cleanup checkpatch"?
Maybe it is ok to change the ABI... but you should say so clearly in the changelog...
Pavel
> diff --git a/drivers/power/bq2415x_charger.c b/drivers/power/bq2415x_charger.c
> index 6c534dc..2cf8ec7 100644
> --- a/drivers/power/bq2415x_charger.c
> +++ b/drivers/power/bq2415x_charger.c
> @@ -631,7 +631,7 @@ static int bq2415x_set_charge_current(struct bq2415x_device *bq, int mA)
> int val;
>
> if (bq->init_data.resistor_sense <= 0)
> - return -ENOSYS;
> + return -EINVAL;
>
> val = (mA * bq->init_data.resistor_sense - 37400) / 6800;
> if (val < 0)
> @@ -650,7 +650,7 @@ static int bq2415x_get_charge_current(struct bq2415x_device *bq)
> int ret;
>
> if (bq->init_data.resistor_sense <= 0)
> - return -ENOSYS;
> + return -EINVAL;
>
> ret = bq2415x_i2c_read_mask(bq, BQ2415X_REG_CURRENT,
> BQ2415X_MASK_VI_CHRG, BQ2415X_SHIFT_VI_CHRG);
> @@ -665,7 +665,7 @@ static int bq2415x_set_termination_current(struct bq2415x_device *bq, int mA)
> int val;
>
> if (bq->init_data.resistor_sense <= 0)
> - return -ENOSYS;
> + return -EINVAL;
>
> val = (mA * bq->init_data.resistor_sense - 3400) / 3400;
> if (val < 0)
> @@ -684,7 +684,7 @@ static int bq2415x_get_termination_current(struct bq2415x_device *bq)
> int ret;
>
> if (bq->init_data.resistor_sense <= 0)
> - return -ENOSYS;
> + return -EINVAL;
>
> ret = bq2415x_i2c_read_mask(bq, BQ2415X_REG_CURRENT,
> BQ2415X_MASK_VI_TERM, BQ2415X_SHIFT_VI_TERM);
> @@ -1166,7 +1166,7 @@ static ssize_t bq2415x_sysfs_set_mode(struct device *dev,
>
> if (strncmp(buf, "auto", 4) == 0) {
> if (bq->automode < 0)
> - return -ENOSYS;
> + return -EINVAL;
> bq->automode = 1;
> mode = bq->reported_mode;
> } else if (strncmp(buf, "off", 3) == 0) {
> @@ -1556,28 +1556,28 @@ static int bq2415x_probe(struct i2c_client *client,
>
> bq = devm_kzalloc(&client->dev, sizeof(*bq), GFP_KERNEL);
> if (!bq) {
> - dev_err(&client->dev, "failed to allocate device data\n");
> ret = -ENOMEM;
> goto error_2;
> }
>
> if (np) {
> - bq->notify_psy = power_supply_get_by_phandle(np, "ti,usb-charger-detection");
> + bq->notify_psy = power_supply_get_by_phandle(np,
> + "ti,usb-charger-detection");
>
> if (IS_ERR(bq->notify_psy)) {
> dev_info(&client->dev,
> - "no 'ti,usb-charger-detection' property (err=%ld)\n",
> + "no 'ti,usb-charger-detection' property (err=%ld)\n",
> PTR_ERR(bq->notify_psy));
> bq->notify_psy = NULL;
> } else if (!bq->notify_psy) {
> ret = -EPROBE_DEFER;
> goto error_2;
> }
> - }
> - else if (pdata->notify_device)
> + } else if (pdata->notify_device) {
> bq->notify_psy = power_supply_get_by_name(pdata->notify_device);
> - else
> + } else {
> bq->notify_psy = NULL;
> + }
>
> i2c_set_clientdata(client, bq);
>
> @@ -1592,11 +1592,11 @@ static int bq2415x_probe(struct i2c_client *client,
>
> if (np) {
> ret = of_property_read_u32(np, "ti,current-limit",
> - &bq->init_data.current_limit);
> + &bq->init_data.current_limit);
> if (ret)
> goto error_3;
> ret = of_property_read_u32(np, "ti,weak-battery-voltage",
> - &bq->init_data.weak_battery_voltage);
> + &bq->init_data.weak_battery_voltage);
> if (ret)
> goto error_3;
> ret = of_property_read_u32(np, "ti,battery-regulation-voltage",
> @@ -1604,15 +1604,15 @@ static int bq2415x_probe(struct i2c_client *client,
> if (ret)
> goto error_3;
> ret = of_property_read_u32(np, "ti,charge-current",
> - &bq->init_data.charge_current);
> + &bq->init_data.charge_current);
> if (ret)
> goto error_3;
> ret = of_property_read_u32(np, "ti,termination-current",
> - &bq->init_data.termination_current);
> + &bq->init_data.termination_current);
> if (ret)
> goto error_3;
> ret = of_property_read_u32(np, "ti,resistor-sense",
> - &bq->init_data.resistor_sense);
> + &bq->init_data.resistor_sense);
> if (ret)
> goto error_3;
> } else {
> @@ -1648,7 +1648,8 @@ static int bq2415x_probe(struct i2c_client *client,
> }
>
> /* Query for initial reported_mode and set it */
> - bq2415x_notifier_call(&bq->nb, PSY_EVENT_PROP_CHANGED, bq->notify_psy);
> + bq2415x_notifier_call(&bq->nb, PSY_EVENT_PROP_CHANGED,
> + bq->notify_psy);
> bq2415x_set_mode(bq, bq->reported_mode);
>
> bq->automode = 1;
> --
> 1.7.9.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
On Tue 2015-05-12 12:11:33, Anda-Maria Nicolae wrote:
> Replace of_property_read_u32() with device_property_read_u32(), which is a
> wrapper over ACPI and device tree enumeration methods.
> When ACPI enumeration is used, automode is not supported. Therefore,
> bq2415x_charger does not update its input current automatically, depending
> on the USB port type that is connected to. Input current may be updated via
> sysfs.
>
> Signed-off-by: Anda-Maria Nicolae <[email protected]>
> ---
> drivers/power/bq2415x_charger.c | 73 +++++++++++++++++++++++++++++----------
> 1 file changed, 55 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/power/bq2415x_charger.c b/drivers/power/bq2415x_charger.c
> index 2cf8ec7..e98dcb6 100644
> --- a/drivers/power/bq2415x_charger.c
> +++ b/drivers/power/bq2415x_charger.c
> @@ -35,6 +35,7 @@
> #include <linux/idr.h>
> #include <linux/i2c.h>
> #include <linux/slab.h>
> +#include <linux/acpi.h>
>
> #include <linux/power/bq2415x_charger.h>
>
> @@ -1530,13 +1531,14 @@ static int bq2415x_probe(struct i2c_client *client,
> {
> int ret;
> int num;
> - char *name;
> + char *name = NULL;
> struct bq2415x_device *bq;
Why?
> @@ -1547,7 +1549,14 @@ static int bq2415x_probe(struct i2c_client *client,
> if (num < 0)
> return num;
>
> - name = kasprintf(GFP_KERNEL, "%s-%d", id->name, num);
> + if (id) {
> + name = kasprintf(GFP_KERNEL, "%s-%d", id->name, num);
> + } else if (ACPI_HANDLE(&client->dev)) {
> + acpi_id =
> + acpi_match_device(client->dev.driver->acpi_match_table,
> + &client->dev);
> + name = kasprintf(GFP_KERNEL, "%s-%d", acpi_id->id, num);
> + }
You have both branches covered.
Pavel
> if (!name) {
> dev_err(&client->dev, "failed to allocate device name\n");
> ret = -ENOMEM;
> @@ -1573,7 +1582,7 @@ static int bq2415x_probe(struct i2c_client *client,
> ret = -EPROBE_DEFER;
> goto error_2;
> }
> - } else if (pdata->notify_device) {
> + } else if (pdata && pdata->notify_device) {
> bq->notify_psy = power_supply_get_by_name(pdata->notify_device);
> } else {
> bq->notify_psy = NULL;
> @@ -1583,36 +1592,45 @@ static int bq2415x_probe(struct i2c_client *client,
>
> bq->id = num;
> bq->dev = &client->dev;
> - bq->chip = id->driver_data;
> + if (id)
> + bq->chip = id->driver_data;
> + else if (ACPI_HANDLE(bq->dev))
> + bq->chip = acpi_id->driver_data;
> bq->name = name;
> bq->mode = BQ2415X_MODE_OFF;
> bq->reported_mode = BQ2415X_MODE_OFF;
> bq->autotimer = 0;
> bq->automode = 0;
>
> - if (np) {
> - ret = of_property_read_u32(np, "ti,current-limit",
> - &bq->init_data.current_limit);
> + if (np || ACPI_HANDLE(bq->dev)) {
> + ret = device_property_read_u32(bq->dev,
> + "ti,current-limit",
> + &bq->init_data.current_limit);
> if (ret)
> goto error_3;
> - ret = of_property_read_u32(np, "ti,weak-battery-voltage",
> - &bq->init_data.weak_battery_voltage);
> + ret = device_property_read_u32(bq->dev,
> + "ti,weak-battery-voltage",
> + &bq->init_data.weak_battery_voltage);
> if (ret)
> goto error_3;
> - ret = of_property_read_u32(np, "ti,battery-regulation-voltage",
> + ret = device_property_read_u32(bq->dev,
> + "ti,battery-regulation-voltage",
> &bq->init_data.battery_regulation_voltage);
> if (ret)
> goto error_3;
> - ret = of_property_read_u32(np, "ti,charge-current",
> - &bq->init_data.charge_current);
> + ret = device_property_read_u32(bq->dev,
> + "ti,charge-current",
> + &bq->init_data.charge_current);
> if (ret)
> goto error_3;
> - ret = of_property_read_u32(np, "ti,termination-current",
> - &bq->init_data.termination_current);
> + ret = device_property_read_u32(bq->dev,
> + "ti,termination-current",
> + &bq->init_data.termination_current);
> if (ret)
> goto error_3;
> - ret = of_property_read_u32(np, "ti,resistor-sense",
> - &bq->init_data.resistor_sense);
> + ret = device_property_read_u32(bq->dev,
> + "ti,resistor-sense",
> + &bq->init_data.resistor_sense);
> if (ret)
> goto error_3;
> } else {
> @@ -1728,9 +1746,28 @@ static const struct i2c_device_id bq2415x_i2c_id_table[] = {
> };
> MODULE_DEVICE_TABLE(i2c, bq2415x_i2c_id_table);
>
> +static const struct acpi_device_id bq2415x_i2c_acpi_match[] = {
> + { "BQ2415X", BQUNKNOWN },
> + { "BQ241500", BQ24150 },
> + { "BQA24150", BQ24150A },
> + { "BQ241510", BQ24151 },
> + { "BQA24151", BQ24151A },
> + { "BQ241520", BQ24152 },
> + { "BQ241530", BQ24153 },
> + { "BQA24153", BQ24153A },
> + { "BQ241550", BQ24155 },
> + { "BQ241560", BQ24156 },
> + { "BQA24156", BQ24156A },
> + { "BQS24157", BQ24157S },
> + { "BQ241580", BQ24158 },
> + {},
> +};
> +MODULE_DEVICE_TABLE(acpi, bq2415x_i2c_acpi_match);
> +
> static struct i2c_driver bq2415x_driver = {
> .driver = {
> .name = "bq2415x-charger",
> + .acpi_match_table = ACPI_PTR(bq2415x_i2c_acpi_match),
> },
> .probe = bq2415x_probe,
> .remove = bq2415x_remove,
> --
> 1.7.9.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html