lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Fri, 7 Jan 2011 09:56:11 +0100
From:	Corentin Chary <corentin.chary@...il.com>
To:	Yin Kangkai <kangkai.yin@...ux.intel.com>
Cc:	platform-driver-x86 <platform-driver-x86@...r.kernel.org>,
	linux-kernel@...r.kernel.org,
	"Wang, Yong Y" <yong.y.wang@...el.com>,
	"Liu, Bing Wei" <bing.wei.liu@...el.com>,
	Matthew Garrett <mjg@...hat.com>
Subject: Re: [PATCH V2] platform-driver-x86: ACPI EC Extra driver for Oaktrail

On Fri, Jan 7, 2011 at 8:41 AM, Yin Kangkai <kangkai.yin@...ux.intel.com> wrote:
> Patch V2
> Changes from V1:
>  - remove wifi, bt, gps, wwan from /sys/devices/platform.
>  - add some helper function for rfkill alloc and rfkill cleanup.
>  - add MODULE_ALIAS.
>  - add Documentation/ABI/testing/sysfs-platform-intel-oaktrail
>  - various other minor changes.
>  - bump driver version from 0.1 to 0.2
>
> Thanks Corentin Chary and Joey Lee for the review.
>
> From ab28d41e89b40e0ab1d73489b7d1a9f6e745c14a Mon Sep 17 00:00:00 2001
> From: Yin Kangkai <kangkai.yin@...el.com>
> Date: Wed, 22 Dec 2010 10:53:36 +0800
> Subject: [PATCH] platform-driver-x86: ACPI EC Extra driver for Oaktrail
>
> This driver implements an Extra ACPI EC driver for products based on Intel
> Oaktrail platform.  It is programming the EC space, through existing ACPI EC
> driver, to provide user space layer the sysfs and rfkill interfaces to
> enable/disable the Camera, Bluetooth, GPS, WiFi, 3G, and to show the status of
> Touchscreen.
>
> Signed-off-by: Yin Kangkai <kangkai.yin@...el.com>
> ---
>  .../ABI/testing/sysfs-platform-intel-oaktrail      |   13 +
>  drivers/platform/x86/Kconfig                       |    9 +
>  drivers/platform/x86/Makefile                      |    1 +
>  drivers/platform/x86/intel_oaktrail.c              |  347 ++++++++++++++++++++
>  4 files changed, 370 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/ABI/testing/sysfs-platform-intel-oaktrail
>  create mode 100644 drivers/platform/x86/intel_oaktrail.c
>
> diff --git a/Documentation/ABI/testing/sysfs-platform-intel-oaktrail b/Documentation/ABI/testing/sysfs-platform-intel-oaktrail
> new file mode 100644
> index 0000000..0512235
> --- /dev/null
> +++ b/Documentation/ABI/testing/sysfs-platform-intel-oaktrail
> @@ -0,0 +1,13 @@
> +What:          /sys/devices/platform/intel_oaktrail/camera
> +Date:          Jan 2011
> +KernelVersion: 2.6.37
> +Contact:       "Yin Kangkai" <kangkai.yin@...el.com>
> +Description:
> +               Control the camera. 1 means on, 0 means off.
> +
> +What:          /sys/devices/platform/intel_oaktrail/touchscreen
> +Date:          Jan 2011
> +KernelVersion: 2.6.37
> +Contact:       "Yin Kangkai" <kangkai.yin@...el.com>
> +Description:
> +               Show the status of the touch screen. 1 means on, 0 means off.
> diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
> index 2b4038a..d1f6981 100644
> --- a/drivers/platform/x86/Kconfig
> +++ b/drivers/platform/x86/Kconfig
> @@ -655,4 +655,13 @@ config XO1_RFKILL
>          Support for enabling/disabling the WLAN interface on the OLPC XO-1
>          laptop.
>
> +config INTEL_OAKTRAIL
> +       tristate "Intel Oaktrail Platform Extras"
> +       depends on ACPI
> +       depends on RFKILL
> +       ---help---
> +         Intel Oaktrail platform need this driver to provide interfaces to
> +         enable/disable the Camera, WiFi, BT etc. devices. If in doubt, say Y
> +         here; it will only load on supported platforms.
> +
>  endif # X86_PLATFORM_DEVICES
> diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
> index 7ff60e6..add8ab7 100644
> --- a/drivers/platform/x86/Makefile
> +++ b/drivers/platform/x86/Makefile
> @@ -35,3 +35,4 @@ obj-$(CONFIG_INTEL_IPS)               += intel_ips.o
>  obj-$(CONFIG_GPIO_INTEL_PMIC)  += intel_pmic_gpio.o
>  obj-$(CONFIG_XO1_RFKILL)       += xo1-rfkill.o
>  obj-$(CONFIG_IBM_RTL)          += ibm_rtl.o
> +obj-$(CONFIG_INTEL_OAKTRAIL)   += intel_oaktrail.o
> diff --git a/drivers/platform/x86/intel_oaktrail.c b/drivers/platform/x86/intel_oaktrail.c
> new file mode 100644
> index 0000000..9ec71c5
> --- /dev/null
> +++ b/drivers/platform/x86/intel_oaktrail.c
> @@ -0,0 +1,347 @@
> +/*
> +  Copyright (C) 2010 Intel Corporation
> +  Author: Yin Kangkai (kangkai.yin@...el.com)
> +
> +  based on Compal driver
> +
> +  Copyright (C) 2008 Cezary Jackiewicz <cezary.jackiewicz (at) gmail.com>
> +
> +  based on MSI driver
> +
> +  Copyright (C) 2006 Lennart Poettering <mzxreary (at) 0pointer (dot) de>
> +
> +  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 Free Software Foundation; either version 2 of the License, or
> +  (at your option) any later version.
> +
> +  This program is distributed in the hope that it will be useful, but
> +  WITHOUT ANY WARRANTY; without even the implied warranty of
> +  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> +  General Public License for more details.
> +
> +  You should have received a copy of the GNU General Public License
> +  along with this program; if not, write to the Free Software
> +  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> +  02110-1301, USA.
> + */
> +
> +/*
> + * intel_oaktrail.c - Intel OakTrail Platform support.
> + *
> + * This driver exports a few files in /sys/devices/platform/intel_oaktrail/:
> + *
> + * camera - Camera subsystem enabled: contains either 0 or 1. (rw)
> + * touchscreen - Touchscreen subsystem enabled: contains either 0 or 1. (ro)
> + *
> + * In addition to these platform device attributes, the driver registers itself
> + * in the Linux rfkill subsystem for these components:
> + *
> + * wifi
> + * bluetooth
> + * wwan (3g)
> + * gps
> + *
> + * and is available to userspace under /sys/class/rfkill/rfkillX/
> + *
> + * This driver might work on other products based on Oaktrail. If you
> + * want to try it you can pass force=1 as argument to the module which
> + * will force it to load even when the DMI data doesn't identify the
> + * product as compatible.
> + */
> +
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/acpi.h>
> +#include <linux/platform_device.h>
> +#include <linux/dmi.h>
> +#include <linux/rfkill.h>
> +
> +#define DRIVER_NAME    "intel_oaktrail"
> +#define DRIVER_VERSION "0.2"
> +
> +/*
> + * This is the devices status address in EC space, and the control bits
> + * definition:
> + *
> + * (1 << 0):   Camera enable/disable, RW.
> + * (1 << 1):   Bluetooth enable/disable, RW.
> + * (1 << 2):   GPS enable/disable, RW.
> + * (1 << 3):   WiFi enable/disable, RW.
> + * (1 << 4):   WWAN (3G) enable/disalbe, RW.
> + * (1 << 5):   Touchscreen enable/disable, Read Only.
> + */
> +#define OT_EC_DEVICE_STATE_ADDRESS     0xD6
> +
> +#define OT_EC_CAMERA_MASK      (1 << 0)
> +#define OT_EC_BT_MASK          (1 << 1)
> +#define OT_EC_GPS_MASK         (1 << 2)
> +#define OT_EC_WIFI_MASK                (1 << 3)
> +#define OT_EC_WWAN_MASK                (1 << 4)
> +#define OT_EC_TS_MASK          (1 << 5)
> +
> +static int force;
> +module_param(force, bool, 0);
> +MODULE_PARM_DESC(force, "Force driver load, ignore DMI data");
> +
> +static struct platform_device *oaktrail_device;
> +static struct rfkill *bt_rfkill;
> +static struct rfkill *gps_rfkill;
> +static struct rfkill *wifi_rfkill;
> +static struct rfkill *wwan_rfkill;
> +
> +#define SIMPLE_MASKED_STORE_SHOW(NAME, MASK)                           \
> +static ssize_t NAME##_show(struct device *dev,                         \
> +       struct device_attribute *attr, char *buf)                       \
> +{                                                                      \
> +       u8 value;                                                       \
> +       ec_read(OT_EC_DEVICE_STATE_ADDRESS, &value);                    \
> +       return sprintf(buf, "%d\n", ((value & MASK) != 0));             \
> +}                                                                      \
> +static ssize_t NAME##_store(struct device *dev,                                \
> +       struct device_attribute *attr, const char *buf, size_t count)   \
> +{                                                                      \
> +       int state;                                                      \
> +       u8 old_val;                                                     \
> +       ec_read(OT_EC_DEVICE_STATE_ADDRESS, &old_val);                  \
> +       if (sscanf(buf, "%d", &state) != 1 || (state < 0 || state > 1)) \
> +               return -EINVAL;                                         \
> +       ec_write(OT_EC_DEVICE_STATE_ADDRESS, state ?                    \
> +                (old_val | MASK) : (old_val & ~MASK));                 \
> +       return count;                                                   \
> +}
> +
> +SIMPLE_MASKED_STORE_SHOW(camera, OT_EC_CAMERA_MASK)
> +SIMPLE_MASKED_STORE_SHOW(touchscreen, OT_EC_TS_MASK)
> +
> +static DEVICE_ATTR(camera, 0644, camera_show, camera_store);
> +static DEVICE_ATTR(touchscreen, 0444, touchscreen_show, NULL);
> +
> +static struct attribute *oaktrail_attributes[] = {
> +       &dev_attr_camera.attr,
> +       &dev_attr_touchscreen.attr,
> +       NULL
> +};
> +
> +static struct attribute_group oaktrail_attribute_group = {
> +       .attrs = oaktrail_attributes
> +};
> +
> +static int oaktrail_rfkill_set(void *data, bool blocked)
> +{
> +       u8 value;
> +       u8 result;
> +       unsigned long radio = (unsigned long) data;
> +
> +       ec_read(OT_EC_DEVICE_STATE_ADDRESS, &result);
> +
> +       if (!blocked)
> +               value = (u8) (result | radio);
> +       else
> +               value = (u8) (result & ~radio);
> +
> +       ec_write(OT_EC_DEVICE_STATE_ADDRESS, value);
> +
> +       return 0;
> +}
> +
> +static const struct rfkill_ops oaktrail_rfkill_ops = {
> +       .set_block = oaktrail_rfkill_set,
> +};
> +
> +static struct rfkill *oaktrail_rfkill_new(char *name, enum rfkill_type type,
> +                                         unsigned long mask)
> +{
> +       int err;
> +       struct rfkill *rfkill_dev;
> +
> +       rfkill_dev = rfkill_alloc(name, &oaktrail_device->dev, type,
> +                                 &oaktrail_rfkill_ops, (void *)mask);
> +       if (!rfkill_dev)
> +               return ERR_PTR(-ENOMEM);
> +
> +       err = rfkill_register(rfkill_dev);

Maybe you should add a rfkill_init_sw_state() call here, to be sure
that the rfkill initial state is right.

> +       if (err) {
> +               rfkill_destroy(rfkill_dev);
> +               return ERR_PTR(err);
> +       }
> +       return rfkill_dev;
> +}
> +
> +static inline void _oaktrail_rfkill_cleanup(struct rfkill *rf)

I don't know if the coding style allow _ function prefix, I used to
believe it did
not, but I checked Documentation/CodingStyle, and I found nothing about that,
so it's probably ok.

> +{
> +       if (rf) {
> +               rfkill_unregister(rf);
> +               rfkill_destroy(rf);
> +       }
> +
> +       return;

We don't need that return

> +}
> +
> +static void oaktrail_rfkill_cleanup(void)
> +{
> +       _oaktrail_rfkill_cleanup(wifi_rfkill);
> +       _oaktrail_rfkill_cleanup(bt_rfkill);
> +       _oaktrail_rfkill_cleanup(gps_rfkill);
> +       _oaktrail_rfkill_cleanup(wwan_rfkill);
> +
> +       return;

And that one

> +}
> +
> +static int oaktrail_rfkill_init(void)
> +{
> +       int ret;
> +
> +       wifi_rfkill = oaktrail_rfkill_new("oaktrail-wifi",
> +                                         RFKILL_TYPE_WLAN,
> +                                         OT_EC_WIFI_MASK);
> +       if (IS_ERR(wifi_rfkill)) {
> +               ret = PTR_ERR(wifi_rfkill);
> +               wifi_rfkill = NULL;
> +               goto cleanup;
> +       }
> +
> +       bt_rfkill = oaktrail_rfkill_new("oaktrail-bluetooth",
> +                                       RFKILL_TYPE_BLUETOOTH,
> +                                       OT_EC_BT_MASK);
> +       if (IS_ERR(bt_rfkill)) {
> +               ret = PTR_ERR(bt_rfkill);
> +               bt_rfkill = NULL;
> +               goto cleanup;
> +       }
> +
> +       gps_rfkill = oaktrail_rfkill_new("oaktrail-gps",
> +                                        RFKILL_TYPE_GPS,
> +                                        OT_EC_GPS_MASK);
> +       if (IS_ERR(gps_rfkill)) {
> +               ret = PTR_ERR(gps_rfkill);
> +               gps_rfkill = NULL;
> +               goto cleanup;
> +       }
> +
> +       wwan_rfkill = oaktrail_rfkill_new("oaktrail-wwan",
> +                                         RFKILL_TYPE_WWAN,
> +                                         OT_EC_WWAN_MASK);
> +       if (IS_ERR(wwan_rfkill)) {
> +               ret = PTR_ERR(wwan_rfkill);
> +               wwan_rfkill = NULL;
> +               goto cleanup;
> +       }
> +
> +       return 0;
> +
> +cleanup:
> +       oaktrail_rfkill_cleanup();
> +       return ret;
> +}
> +
> +static int __devinit oaktrail_probe(struct platform_device *pdev)
> +{
> +       return sysfs_create_group(&pdev->dev.kobj, &oaktrail_attribute_group);
> +}
> +
> +static int __devexit oaktrail_remove(struct platform_device *pdev)
> +{
> +       sysfs_remove_group(&pdev->dev.kobj, &oaktrail_attribute_group);
> +
> +       return 0;
> +}
> +
> +static struct platform_driver oaktrail_driver = {
> +       .driver = {
> +               .name = DRIVER_NAME,
> +               .owner = THIS_MODULE,
> +       },
> +       .probe  = oaktrail_probe,
> +       .remove = __devexit_p(oaktrail_remove)
> +};
> +
> +static int dmi_check_cb(const struct dmi_system_id *id)
> +{
> +       pr_info("Identified model '%s'\n", id->ident);
> +       return 0;
> +}
> +
> +static struct dmi_system_id __initdata oaktrail_dmi_table[] = {
> +       {
> +               .ident = "OakTrail platform",
> +               .matches = {
> +                       DMI_MATCH(DMI_PRODUCT_NAME, "OakTrail platform"),
> +               },
> +               .callback = dmi_check_cb
> +       },
> +       { }
> +};
> +
> +static int __init oaktrail_init(void)
> +{
> +       int ret;
> +
> +       if (acpi_disabled) {
> +               pr_err("ACPI needs to be enabled for this driver to work!\n");
> +               return -ENODEV;
> +       }
> +
> +       if (!force && !dmi_check_system(oaktrail_dmi_table)) {
> +               pr_err("Platform not recognized (You could try the module's force-parameter)");
> +               return -ENODEV;
> +       }
> +
> +       ret = platform_driver_register(&oaktrail_driver);
> +       if (ret) {
> +               pr_warning("Unable to register platform driver\n");
> +               goto err_driver_reg;
> +       }
> +
> +       oaktrail_device = platform_device_alloc(DRIVER_NAME, -1);
> +       if (!oaktrail_device) {
> +               pr_warning("Unable to allocate platform device\n");
> +               ret = -ENOMEM;
> +               goto err_device_alloc;
> +       }
> +
> +       ret = platform_device_add(oaktrail_device);
> +       if (ret) {
> +               pr_warning("Unable to add platform device\n");
> +               goto err_device_add;
> +       }
> +
> +       ret = oaktrail_rfkill_init();
> +       if (ret) {
> +               pr_warning("Setup rfkill failed\n");
> +               goto err_rfkill;
> +       }
> +
> +       pr_info("Driver "DRIVER_VERSION" successfully loaded\n");
> +       return 0;
> +
> +err_rfkill:
> +       platform_device_del(oaktrail_device);
> +err_device_add:
> +       platform_device_put(oaktrail_device);
> +err_device_alloc:
> +       platform_driver_unregister(&oaktrail_driver);
> +err_driver_reg:
> +       return ret;
> +}
> +
> +static void __exit oaktrail_cleanup(void)
> +{
> +       platform_device_unregister(oaktrail_device);
> +       platform_driver_unregister(&oaktrail_driver);
> +       oaktrail_rfkill_cleanup();
> +
> +       pr_info("Driver unloaded\n");
> +}
> +
> +module_init(oaktrail_init);
> +module_exit(oaktrail_cleanup);
> +
> +MODULE_AUTHOR("Yin Kangkai (kangkai.yin@...el.com)");
> +MODULE_DESCRIPTION("Intel Oaktrail Platform ACPI Extras");
> +MODULE_VERSION(DRIVER_VERSION);
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("dmi:*:svnIntelCorporation:pnOakTrailplatform:*");
> --
> 1.6.5
>
>

-- 
Corentin Chary
http://xf.iksaif.net
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ