From 9742e127cd0dd5783f8c11c62d07886003114499 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Tue, 12 Nov 2013 13:32:13 -0800 Subject: platform/chrome: Add pstore platform_device Add the ramoops pstore device so that we get logs of panics across reboots. Signed-off-by: Olof Johansson --- drivers/platform/chrome/Kconfig | 14 +++++ drivers/platform/chrome/Makefile | 1 + drivers/platform/chrome/chromeos_pstore.c | 101 ++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+) create mode 100644 drivers/platform/chrome/chromeos_pstore.c (limited to 'drivers') diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig index b13303e75a34..440ed776efd4 100644 --- a/drivers/platform/chrome/Kconfig +++ b/drivers/platform/chrome/Kconfig @@ -25,4 +25,18 @@ config CHROMEOS_LAPTOP If you have a supported Chromebook, choose Y or M here. The module will be called chromeos_laptop. +config CHROMEOS_PSTORE + tristate "Chrome OS pstore support" + ---help--- + This module instantiates the persistent storage on x86 ChromeOS + devices. It can be used to store away console logs and crash + information across reboots. + + The range of memory used is 0xf00000-0x1000000, traditionally + the memory used to back VGA controller memory. + + If you have a supported Chromebook, choose Y or M here. + The module will be called chromeos_pstore. + + endif # CHROMEOS_PLATFORMS diff --git a/drivers/platform/chrome/Makefile b/drivers/platform/chrome/Makefile index 015e9195e226..2b860ca7450f 100644 --- a/drivers/platform/chrome/Makefile +++ b/drivers/platform/chrome/Makefile @@ -1,2 +1,3 @@ obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o +obj-$(CONFIG_CHROMEOS_PSTORE) += chromeos_pstore.o diff --git a/drivers/platform/chrome/chromeos_pstore.c b/drivers/platform/chrome/chromeos_pstore.c new file mode 100644 index 000000000000..e0e0e65cf442 --- /dev/null +++ b/drivers/platform/chrome/chromeos_pstore.c @@ -0,0 +1,101 @@ +/* + * chromeos_pstore.c - Driver to instantiate Chromebook ramoops device + * + * Copyright (C) 2013 Google, Inc. + * + * 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, version 2 of the License. + */ + +#include +#include +#include +#include + +static struct dmi_system_id chromeos_pstore_dmi_table[] __initdata = { + { + /* + * Today all Chromebooks/boxes ship with GOOGLE as vendor and + * coreboot as bios vendor. No other systems with this + * combination are known to date. + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), + DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"), + }, + }, + { + /* + * The first Samsung Chromebox and Chromebook Series 5 550 use + * coreboot but with Samsung as the system vendor. + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG"), + DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"), + }, + }, + { + /* x86-alex, the first Samsung Chromebook. */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "Alex"), + }, + }, + { + /* x86-mario, the Cr-48 pilot device from Google. */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "IEC"), + DMI_MATCH(DMI_PRODUCT_NAME, "Mario"), + }, + }, + { + /* x86-zgb, the first Acer Chromebook. */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ACER"), + DMI_MATCH(DMI_PRODUCT_NAME, "ZGB"), + }, + }, + { } +}; +MODULE_DEVICE_TABLE(dmi, chromeos_pstore_dmi_table); + +/* + * On x86 chromebooks/boxes, the firmware will keep the legacy VGA memory + * range untouched across reboots, so we use that to store our pstore + * contents for panic logs, etc. + */ +static struct ramoops_platform_data chromeos_ramoops_data = { + .mem_size = 0x100000, + .mem_address = 0xf00000, + .record_size = 0x20000, + .console_size = 0x20000, + .ftrace_size = 0x20000, + .dump_oops = 1, +}; + +static struct platform_device chromeos_ramoops = { + .name = "ramoops", + .dev = { + .platform_data = &chromeos_ramoops_data, + }, +}; + +static int __init chromeos_pstore_init(void) +{ + if (dmi_check_system(chromeos_pstore_dmi_table)) + return platform_device_register(&chromeos_ramoops); + + return -ENODEV; +} + +static void __exit chromeos_pstore_exit(void) +{ + platform_device_unregister(&chromeos_ramoops); +} + +module_init(chromeos_pstore_init); +module_exit(chromeos_pstore_exit); + +MODULE_DESCRIPTION("Chrome OS pstore module"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From ec199dd57ef71858b53828283ac495ed82164933 Mon Sep 17 00:00:00 2001 From: Aaron Durbin Date: Sun, 20 Oct 2013 20:58:24 -0700 Subject: platform/chrome: chromeos_laptop - Restructure device associations The previous code had a single DMI matching entry for each device on a board. Instead provide a single DMI entry for each board which references a structure about each board that lists the associated peripherals. This allows for a lower number of DMI matching sequences as well making it easier to add new boards. Signed-off-by: Aaron Durbin Signed-off-by: Benson Leung Signed-off-by: Olof Johansson --- drivers/platform/chrome/chromeos_laptop.c | 197 +++++++++++++++++++----------- 1 file changed, 126 insertions(+), 71 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/chrome/chromeos_laptop.c b/drivers/platform/chrome/chromeos_laptop.c index 3e5b4497a1d0..5c69cfd97ff0 100644 --- a/drivers/platform/chrome/chromeos_laptop.c +++ b/drivers/platform/chrome/chromeos_laptop.c @@ -53,6 +53,17 @@ enum i2c_adapter_type { I2C_ADAPTER_PANEL, }; +struct i2c_peripheral { + void (*add)(enum i2c_adapter_type type); + enum i2c_adapter_type type; +}; + +#define MAX_I2C_PERIPHERALS 3 + +struct chromeos_laptop { + struct i2c_peripheral i2c_peripherals[MAX_I2C_PERIPHERALS]; +}; + static struct i2c_board_info __initdata cyapa_device = { I2C_BOARD_INFO("cyapa", CYAPA_TP_I2C_ADDR), .flags = I2C_CLIENT_WAKE, @@ -233,149 +244,193 @@ static __init struct i2c_client *add_i2c_device(const char *name, addr_list); } - -static struct i2c_client __init *add_smbus_device(const char *name, - struct i2c_board_info *info) -{ - return add_i2c_device(name, I2C_ADAPTER_SMBUS, info); -} - -static int __init setup_cyapa_smbus_tp(const struct dmi_system_id *id) +static int __init setup_cyapa_tp(enum i2c_adapter_type type) { - /* add cyapa touchpad on smbus */ - tp = add_smbus_device("trackpad", &cyapa_device); + /* add cyapa touchpad */ + tp = add_i2c_device("trackpad", type, &cyapa_device); return 0; } -static int __init setup_atmel_224s_tp(const struct dmi_system_id *id) +static int __init setup_atmel_224s_tp(enum i2c_adapter_type type) { const unsigned short addr_list[] = { ATMEL_TP_I2C_BL_ADDR, ATMEL_TP_I2C_ADDR, I2C_CLIENT_END }; - /* add atmel mxt touchpad on VGA DDC GMBus */ - tp = add_probed_i2c_device("trackpad", I2C_ADAPTER_VGADDC, + /* add atmel mxt touchpad */ + tp = add_probed_i2c_device("trackpad", type, &atmel_224s_tp_device, addr_list); return 0; } -static int __init setup_atmel_1664s_ts(const struct dmi_system_id *id) +static int __init setup_atmel_1664s_ts(enum i2c_adapter_type type) { const unsigned short addr_list[] = { ATMEL_TS_I2C_BL_ADDR, ATMEL_TS_I2C_ADDR, I2C_CLIENT_END }; - /* add atmel mxt touch device on PANEL GMBus */ - ts = add_probed_i2c_device("touchscreen", I2C_ADAPTER_PANEL, + /* add atmel mxt touch device */ + ts = add_probed_i2c_device("touchscreen", type, &atmel_1664s_device, addr_list); return 0; } - -static int __init setup_isl29018_als(const struct dmi_system_id *id) +static int __init setup_isl29018_als(enum i2c_adapter_type type) { /* add isl29018 light sensor */ - als = add_smbus_device("lightsensor", &isl_als_device); + als = add_i2c_device("lightsensor", type, &isl_als_device); return 0; } -static int __init setup_isl29023_als(const struct dmi_system_id *id) +static int __init setup_tsl2583_als(enum i2c_adapter_type type) { - /* add isl29023 light sensor on Panel GMBus */ - als = add_i2c_device("lightsensor", I2C_ADAPTER_PANEL, - &isl_als_device); + /* add tsl2583 light sensor */ + als = add_i2c_device(NULL, type, &tsl2583_als_device); return 0; } -static int __init setup_tsl2583_als(const struct dmi_system_id *id) +static int __init setup_tsl2563_als(enum i2c_adapter_type type) { - /* add tsl2583 light sensor on smbus */ - als = add_smbus_device(NULL, &tsl2583_als_device); + /* add tsl2563 light sensor */ + als = add_i2c_device(NULL, type, &tsl2563_als_device); return 0; } -static int __init setup_tsl2563_als(const struct dmi_system_id *id) +static int __init +chromeos_laptop_add_peripherals(const struct dmi_system_id *id) { - /* add tsl2563 light sensor on smbus */ - als = add_smbus_device(NULL, &tsl2563_als_device); - return 0; + int i; + struct chromeos_laptop *cros_laptop = (void *)id->driver_data; + + pr_debug("Adding peripherals for %s.\n", id->ident); + + for (i = 0; i < MAX_I2C_PERIPHERALS; i++) { + struct i2c_peripheral *i2c_dev; + + i2c_dev = &cros_laptop->i2c_peripherals[i]; + + /* No more peripherals. */ + if (i2c_dev->add == NULL) + break; + + /* Add the device. */ + i2c_dev->add(i2c_dev->type); + } + + /* Indicate to dmi_scan that processing is done. */ + return 1; } +static struct chromeos_laptop samsung_series_5_550 __initdata = { + .i2c_peripherals = { + /* Touchpad. */ + { .add = setup_cyapa_tp, I2C_ADAPTER_SMBUS }, + /* Light Sensor. */ + { .add = setup_isl29018_als, I2C_ADAPTER_SMBUS }, + }, +}; + +static struct chromeos_laptop samsung_series_5 __initdata = { + .i2c_peripherals = { + /* Light Sensor. */ + { .add = setup_tsl2583_als, I2C_ADAPTER_SMBUS }, + }, +}; + +static struct chromeos_laptop chromebook_pixel __initdata = { + .i2c_peripherals = { + /* Touch Screen. */ + { .add = setup_atmel_1664s_ts, I2C_ADAPTER_PANEL }, + /* Touchpad. */ + { .add = setup_atmel_224s_tp, I2C_ADAPTER_VGADDC }, + /* Light Sensor. */ + { .add = setup_isl29018_als, I2C_ADAPTER_PANEL }, + }, +}; + +static struct chromeos_laptop acer_c7_chromebook __initdata = { + .i2c_peripherals = { + /* Touchpad. */ + { .add = setup_cyapa_tp, I2C_ADAPTER_SMBUS }, + }, +}; + +static struct chromeos_laptop acer_ac700 __initdata = { + .i2c_peripherals = { + /* Light Sensor. */ + { .add = setup_tsl2563_als, I2C_ADAPTER_SMBUS }, + }, +}; + +static struct chromeos_laptop hp_pavilion_14_chromebook __initdata = { + .i2c_peripherals = { + /* Touchpad. */ + { .add = setup_cyapa_tp, I2C_ADAPTER_SMBUS }, + }, +}; + +static struct chromeos_laptop cr48 __initdata = { + .i2c_peripherals = { + /* Light Sensor. */ + { .add = setup_tsl2563_als, I2C_ADAPTER_SMBUS }, + }, +}; + +#define _CBDD(board_) \ + .callback = &chromeos_laptop_add_peripherals, \ + .driver_data = (void *)&board_ + static struct dmi_system_id __initdata chromeos_laptop_dmi_table[] = { { - .ident = "Samsung Series 5 550 - Touchpad", + .ident = "Samsung Series 5 550", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG"), DMI_MATCH(DMI_PRODUCT_NAME, "Lumpy"), }, - .callback = setup_cyapa_smbus_tp, - }, - { - .ident = "Chromebook Pixel - Touchscreen", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), - DMI_MATCH(DMI_PRODUCT_NAME, "Link"), - }, - .callback = setup_atmel_1664s_ts, - }, - { - .ident = "Chromebook Pixel - Touchpad", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), - DMI_MATCH(DMI_PRODUCT_NAME, "Link"), - }, - .callback = setup_atmel_224s_tp, + _CBDD(samsung_series_5_550), }, { - .ident = "Samsung Series 5 550 - Light Sensor", + .ident = "Samsung Series 5", .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG"), - DMI_MATCH(DMI_PRODUCT_NAME, "Lumpy"), + DMI_MATCH(DMI_PRODUCT_NAME, "Alex"), }, - .callback = setup_isl29018_als, + _CBDD(samsung_series_5), }, { - .ident = "Chromebook Pixel - Light Sensor", + .ident = "Chromebook Pixel", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), DMI_MATCH(DMI_PRODUCT_NAME, "Link"), }, - .callback = setup_isl29023_als, + _CBDD(chromebook_pixel), }, { - .ident = "Acer C7 Chromebook - Touchpad", + .ident = "Acer C7 Chromebook", .matches = { DMI_MATCH(DMI_PRODUCT_NAME, "Parrot"), }, - .callback = setup_cyapa_smbus_tp, + _CBDD(acer_c7_chromebook), }, { - .ident = "HP Pavilion 14 Chromebook - Touchpad", + .ident = "Acer AC700", .matches = { - DMI_MATCH(DMI_PRODUCT_NAME, "Butterfly"), + DMI_MATCH(DMI_PRODUCT_NAME, "ZGB"), }, - .callback = setup_cyapa_smbus_tp, + _CBDD(acer_ac700), }, { - .ident = "Samsung Series 5 - Light Sensor", + .ident = "HP Pavilion 14 Chromebook", .matches = { - DMI_MATCH(DMI_PRODUCT_NAME, "Alex"), + DMI_MATCH(DMI_PRODUCT_NAME, "Butterfly"), }, - .callback = setup_tsl2583_als, + _CBDD(hp_pavilion_14_chromebook), }, { - .ident = "Cr-48 - Light Sensor", + .ident = "Cr-48", .matches = { DMI_MATCH(DMI_PRODUCT_NAME, "Mario"), }, - .callback = setup_tsl2563_als, - }, - { - .ident = "Acer AC700 - Light Sensor", - .matches = { - DMI_MATCH(DMI_PRODUCT_NAME, "ZGB"), - }, - .callback = setup_tsl2563_als, + _CBDD(cr48), }, { } }; -- cgit v1.2.3 From 9ad3692458c387eb9537da73b2b75841ed7acdaf Mon Sep 17 00:00:00 2001 From: Benson Leung Date: Sun, 20 Oct 2013 20:58:25 -0700 Subject: platform/chrome: chromeos_laptop - Use deferred probing Further refactor chromeos_laptop, adding a probe function. Init will call dmi_check_system, but will only use the match to select a chromeos_laptop structure of the current board. Probe will add the devices, and on errors return -EPROBE_DEFER. If i2c adapters are loaded after chromeos_laptop inits, the deferred probe will instantiate the peripherals when the bus appears. Signed-off-by: Benson Leung Reviewed-by: Aaron Durbin Signed-off-by: Olof Johansson --- drivers/platform/chrome/chromeos_laptop.c | 144 +++++++++++++++++++++--------- 1 file changed, 101 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/chrome/chromeos_laptop.c b/drivers/platform/chrome/chromeos_laptop.c index 5c69cfd97ff0..e542330f8048 100644 --- a/drivers/platform/chrome/chromeos_laptop.c +++ b/drivers/platform/chrome/chromeos_laptop.c @@ -27,6 +27,7 @@ #include #include #include +#include #define ATMEL_TP_I2C_ADDR 0x4b #define ATMEL_TP_I2C_BL_ADDR 0x25 @@ -54,7 +55,7 @@ enum i2c_adapter_type { }; struct i2c_peripheral { - void (*add)(enum i2c_adapter_type type); + int (*add)(enum i2c_adapter_type type); enum i2c_adapter_type type; }; @@ -64,20 +65,22 @@ struct chromeos_laptop { struct i2c_peripheral i2c_peripherals[MAX_I2C_PERIPHERALS]; }; -static struct i2c_board_info __initdata cyapa_device = { +static struct chromeos_laptop *cros_laptop; + +static struct i2c_board_info cyapa_device = { I2C_BOARD_INFO("cyapa", CYAPA_TP_I2C_ADDR), .flags = I2C_CLIENT_WAKE, }; -static struct i2c_board_info __initdata isl_als_device = { +static struct i2c_board_info isl_als_device = { I2C_BOARD_INFO("isl29018", ISL_ALS_I2C_ADDR), }; -static struct i2c_board_info __initdata tsl2583_als_device = { +static struct i2c_board_info tsl2583_als_device = { I2C_BOARD_INFO("tsl2583", TAOS_ALS_I2C_ADDR), }; -static struct i2c_board_info __initdata tsl2563_als_device = { +static struct i2c_board_info tsl2563_als_device = { I2C_BOARD_INFO("tsl2563", TAOS_ALS_I2C_ADDR), }; @@ -100,7 +103,7 @@ static struct mxt_platform_data atmel_224s_tp_platform_data = { .config_length = 0, }; -static struct i2c_board_info __initdata atmel_224s_tp_device = { +static struct i2c_board_info atmel_224s_tp_device = { I2C_BOARD_INFO("atmel_mxt_tp", ATMEL_TP_I2C_ADDR), .platform_data = &atmel_224s_tp_platform_data, .flags = I2C_CLIENT_WAKE, @@ -121,13 +124,13 @@ static struct mxt_platform_data atmel_1664s_platform_data = { .config_length = 0, }; -static struct i2c_board_info __initdata atmel_1664s_device = { +static struct i2c_board_info atmel_1664s_device = { I2C_BOARD_INFO("atmel_mxt_ts", ATMEL_TS_I2C_ADDR), .platform_data = &atmel_1664s_platform_data, .flags = I2C_CLIENT_WAKE, }; -static struct i2c_client __init *__add_probed_i2c_device( +static struct i2c_client *__add_probed_i2c_device( const char *name, int bus, struct i2c_board_info *info, @@ -180,7 +183,7 @@ static struct i2c_client __init *__add_probed_i2c_device( return client; } -static int __init __find_i2c_adap(struct device *dev, void *data) +static int __find_i2c_adap(struct device *dev, void *data) { const char *name = data; static const char *prefix = "i2c-"; @@ -191,7 +194,7 @@ static int __init __find_i2c_adap(struct device *dev, void *data) return (strncmp(adapter->name, name, strlen(name)) == 0); } -static int __init find_i2c_adapter_num(enum i2c_adapter_type type) +static int find_i2c_adapter_num(enum i2c_adapter_type type) { struct device *dev = NULL; struct i2c_adapter *adapter; @@ -200,8 +203,9 @@ static int __init find_i2c_adapter_num(enum i2c_adapter_type type) dev = bus_find_device(&i2c_bus_type, NULL, (void *)name, __find_i2c_adap); if (!dev) { - pr_err("%s: i2c adapter %s not found on system.\n", __func__, - name); + /* Adapters may appear later. Deferred probing will retry */ + pr_notice("%s: i2c adapter %s not found on system.\n", __func__, + name); return -ENODEV; } adapter = to_i2c_adapter(dev); @@ -216,7 +220,7 @@ static int __init find_i2c_adapter_num(enum i2c_adapter_type type) * Returns NULL if no devices found. * See Documentation/i2c/instantiating-devices for more information. */ -static __init struct i2c_client *add_probed_i2c_device( +static struct i2c_client *add_probed_i2c_device( const char *name, enum i2c_adapter_type type, struct i2c_board_info *info, @@ -233,7 +237,7 @@ static __init struct i2c_client *add_probed_i2c_device( * info->addr. * Returns NULL if no device found. */ -static __init struct i2c_client *add_i2c_device(const char *name, +static struct i2c_client *add_i2c_device(const char *name, enum i2c_adapter_type type, struct i2c_board_info *info) { @@ -244,65 +248,87 @@ static __init struct i2c_client *add_i2c_device(const char *name, addr_list); } -static int __init setup_cyapa_tp(enum i2c_adapter_type type) +static int setup_cyapa_tp(enum i2c_adapter_type type) { + if (tp) + return 0; + /* add cyapa touchpad */ tp = add_i2c_device("trackpad", type, &cyapa_device); - return 0; + return (!tp) ? -EAGAIN : 0; } -static int __init setup_atmel_224s_tp(enum i2c_adapter_type type) +static int setup_atmel_224s_tp(enum i2c_adapter_type type) { const unsigned short addr_list[] = { ATMEL_TP_I2C_BL_ADDR, ATMEL_TP_I2C_ADDR, I2C_CLIENT_END }; + if (tp) + return 0; /* add atmel mxt touchpad */ tp = add_probed_i2c_device("trackpad", type, &atmel_224s_tp_device, addr_list); - return 0; + return (!tp) ? -EAGAIN : 0; } -static int __init setup_atmel_1664s_ts(enum i2c_adapter_type type) +static int setup_atmel_1664s_ts(enum i2c_adapter_type type) { const unsigned short addr_list[] = { ATMEL_TS_I2C_BL_ADDR, ATMEL_TS_I2C_ADDR, I2C_CLIENT_END }; + if (ts) + return 0; /* add atmel mxt touch device */ ts = add_probed_i2c_device("touchscreen", type, &atmel_1664s_device, addr_list); - return 0; + return (!ts) ? -EAGAIN : 0; } -static int __init setup_isl29018_als(enum i2c_adapter_type type) +static int setup_isl29018_als(enum i2c_adapter_type type) { + if (als) + return 0; + /* add isl29018 light sensor */ als = add_i2c_device("lightsensor", type, &isl_als_device); - return 0; + return (!als) ? -EAGAIN : 0; } -static int __init setup_tsl2583_als(enum i2c_adapter_type type) +static int setup_tsl2583_als(enum i2c_adapter_type type) { + if (als) + return 0; + /* add tsl2583 light sensor */ als = add_i2c_device(NULL, type, &tsl2583_als_device); - return 0; + return (!als) ? -EAGAIN : 0; } -static int __init setup_tsl2563_als(enum i2c_adapter_type type) +static int setup_tsl2563_als(enum i2c_adapter_type type) { + if (als) + return 0; + /* add tsl2563 light sensor */ als = add_i2c_device(NULL, type, &tsl2563_als_device); - return 0; + return (!als) ? -EAGAIN : 0; } -static int __init -chromeos_laptop_add_peripherals(const struct dmi_system_id *id) +static int __init chromeos_laptop_dmi_matched(const struct dmi_system_id *id) { - int i; - struct chromeos_laptop *cros_laptop = (void *)id->driver_data; + cros_laptop = (void *)id->driver_data; + pr_debug("DMI Matched %s.\n", id->ident); - pr_debug("Adding peripherals for %s.\n", id->ident); + /* Indicate to dmi_scan that processing is done. */ + return 1; +} + +static int chromeos_laptop_probe(struct platform_device *pdev) +{ + int i; + int ret = 0; for (i = 0; i < MAX_I2C_PERIPHERALS; i++) { struct i2c_peripheral *i2c_dev; @@ -313,15 +339,15 @@ chromeos_laptop_add_peripherals(const struct dmi_system_id *id) if (i2c_dev->add == NULL) break; - /* Add the device. */ - i2c_dev->add(i2c_dev->type); + /* Add the device. Set -EPROBE_DEFER on any failure */ + if (i2c_dev->add(i2c_dev->type)) + ret = -EPROBE_DEFER; } - /* Indicate to dmi_scan that processing is done. */ - return 1; + return ret; } -static struct chromeos_laptop samsung_series_5_550 __initdata = { +static struct chromeos_laptop samsung_series_5_550 = { .i2c_peripherals = { /* Touchpad. */ { .add = setup_cyapa_tp, I2C_ADAPTER_SMBUS }, @@ -330,14 +356,14 @@ static struct chromeos_laptop samsung_series_5_550 __initdata = { }, }; -static struct chromeos_laptop samsung_series_5 __initdata = { +static struct chromeos_laptop samsung_series_5 = { .i2c_peripherals = { /* Light Sensor. */ { .add = setup_tsl2583_als, I2C_ADAPTER_SMBUS }, }, }; -static struct chromeos_laptop chromebook_pixel __initdata = { +static struct chromeos_laptop chromebook_pixel = { .i2c_peripherals = { /* Touch Screen. */ { .add = setup_atmel_1664s_ts, I2C_ADAPTER_PANEL }, @@ -348,28 +374,28 @@ static struct chromeos_laptop chromebook_pixel __initdata = { }, }; -static struct chromeos_laptop acer_c7_chromebook __initdata = { +static struct chromeos_laptop acer_c7_chromebook = { .i2c_peripherals = { /* Touchpad. */ { .add = setup_cyapa_tp, I2C_ADAPTER_SMBUS }, }, }; -static struct chromeos_laptop acer_ac700 __initdata = { +static struct chromeos_laptop acer_ac700 = { .i2c_peripherals = { /* Light Sensor. */ { .add = setup_tsl2563_als, I2C_ADAPTER_SMBUS }, }, }; -static struct chromeos_laptop hp_pavilion_14_chromebook __initdata = { +static struct chromeos_laptop hp_pavilion_14_chromebook = { .i2c_peripherals = { /* Touchpad. */ { .add = setup_cyapa_tp, I2C_ADAPTER_SMBUS }, }, }; -static struct chromeos_laptop cr48 __initdata = { +static struct chromeos_laptop cr48 = { .i2c_peripherals = { /* Light Sensor. */ { .add = setup_tsl2563_als, I2C_ADAPTER_SMBUS }, @@ -377,7 +403,7 @@ static struct chromeos_laptop cr48 __initdata = { }; #define _CBDD(board_) \ - .callback = &chromeos_laptop_add_peripherals, \ + .callback = chromeos_laptop_dmi_matched, \ .driver_data = (void *)&board_ static struct dmi_system_id __initdata chromeos_laptop_dmi_table[] = { @@ -436,13 +462,45 @@ static struct dmi_system_id __initdata chromeos_laptop_dmi_table[] = { }; MODULE_DEVICE_TABLE(dmi, chromeos_laptop_dmi_table); +static struct platform_device *cros_platform_device; + +static struct platform_driver cros_platform_driver = { + .driver = { + .name = "chromeos_laptop", + .owner = THIS_MODULE, + }, + .probe = chromeos_laptop_probe, +}; + static int __init chromeos_laptop_init(void) { + int ret; if (!dmi_check_system(chromeos_laptop_dmi_table)) { pr_debug("%s unsupported system.\n", __func__); return -ENODEV; } + + ret = platform_driver_register(&cros_platform_driver); + if (ret) + return ret; + + cros_platform_device = platform_device_alloc("chromeos_laptop", -1); + if (!cros_platform_device) { + ret = -ENOMEM; + goto fail_platform_device1; + } + + ret = platform_device_add(cros_platform_device); + if (ret) + goto fail_platform_device2; + return 0; + +fail_platform_device2: + platform_device_put(cros_platform_device); +fail_platform_device1: + platform_driver_unregister(&cros_platform_driver); + return ret; } static void __exit chromeos_laptop_exit(void) -- cgit v1.2.3 From cdddd23fa2536cd4273e95d66b6ef83e67b747bf Mon Sep 17 00:00:00 2001 From: Benson Leung Date: Sun, 20 Oct 2013 20:58:26 -0700 Subject: platform/chrome: chromeos_laptop - fix incorrect placement of __initdata tag __initdata tag should be placed between the variable name and equal sign for the variable to be placed in the intended .init.data section. Signed-off-by: Benson Leung Signed-off-by: Olof Johansson --- drivers/platform/chrome/chromeos_laptop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/platform/chrome/chromeos_laptop.c b/drivers/platform/chrome/chromeos_laptop.c index e542330f8048..1c2747f119d1 100644 --- a/drivers/platform/chrome/chromeos_laptop.c +++ b/drivers/platform/chrome/chromeos_laptop.c @@ -406,7 +406,7 @@ static struct chromeos_laptop cr48 = { .callback = chromeos_laptop_dmi_matched, \ .driver_data = (void *)&board_ -static struct dmi_system_id __initdata chromeos_laptop_dmi_table[] = { +static struct dmi_system_id chromeos_laptop_dmi_table[] __initdata = { { .ident = "Samsung Series 5 550", .matches = { -- cgit v1.2.3 From 6d3c1afe7367447c8f7d2fec7a132f723834efd1 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Mon, 25 Nov 2013 13:10:25 -0800 Subject: platform/chrome: Make i2c_adapter_names static Not used outside of the file, so declaration should be static. Picked up by sparse: drivers/platform/chrome/chromeos_laptop.c:44:12: warning: symbol 'i2c_adapter_names' was not declared. Should it be static? Signed-off-by: Olof Johansson Reviewed-by: Benson Leung --- drivers/platform/chrome/chromeos_laptop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/platform/chrome/chromeos_laptop.c b/drivers/platform/chrome/chromeos_laptop.c index 1c2747f119d1..446ef0f9c256 100644 --- a/drivers/platform/chrome/chromeos_laptop.c +++ b/drivers/platform/chrome/chromeos_laptop.c @@ -41,7 +41,7 @@ static struct i2c_client *als; static struct i2c_client *tp; static struct i2c_client *ts; -const char *i2c_adapter_names[] = { +static const char *i2c_adapter_names[] = { "SMBus I801 adapter", "i915 gmbus vga", "i915 gmbus panel", -- cgit v1.2.3 From 2b8454a75b90d7cd1ac325a0baba77244733354f Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 27 Nov 2013 11:34:58 +0800 Subject: platform/chrome: unregister platform driver/device when module exit We have registered platform driver and device when module init, and need unregister them when module exit. Signed-off-by: Wei Yongjun Signed-off-by: Olof Johansson --- drivers/platform/chrome/chromeos_laptop.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/platform/chrome/chromeos_laptop.c b/drivers/platform/chrome/chromeos_laptop.c index 446ef0f9c256..7f3aad0e115c 100644 --- a/drivers/platform/chrome/chromeos_laptop.c +++ b/drivers/platform/chrome/chromeos_laptop.c @@ -511,6 +511,9 @@ static void __exit chromeos_laptop_exit(void) i2c_unregister_device(tp); if (ts) i2c_unregister_device(ts); + + platform_device_unregister(cros_platform_device); + platform_driver_unregister(&cros_platform_driver); } module_init(chromeos_laptop_init); -- cgit v1.2.3