Received: by 10.213.65.68 with SMTP id h4csp786891imn; Tue, 20 Mar 2018 15:36:04 -0700 (PDT) X-Google-Smtp-Source: AG47ELsXzFiSov0BtexzNZ2RdSJnLRK8yXjkQPZKgaY2FjHjIHVOZlbugclm5iOIjuSFqNQScFyy X-Received: by 2002:a17:902:d807:: with SMTP id a7-v6mr18298123plz.218.1521585364917; Tue, 20 Mar 2018 15:36:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1521585364; cv=none; d=google.com; s=arc-20160816; b=d5mQiKUNQQsqsoFNU1QqC4P0c5RWuPvPghZkwiFMOjxGRMQnPdttRm0rR7Cn48SecL GInZYSS2nGLqW6/F72gRI3/qm3LV6p+BtecOZub4x4NZIt6N2LBTz2v3dzs6D5hRfXvi K3qXA5oibJ1zC+9h2QRzPeKp5J6hgoPjfDXjZAz+1FW4Zq0CgXveq6xcRKL08F/8jqEj 36F/d+t7JpIIwsXR11OJKP9eg/my1f5zQOkcsS+10zDR3/hkv95/9UKE2vXhyolAdbEI SpqJIvp4Qk9ua2HzWw8XI6sQejzB+QE8gBB09O3G9aD8D96yg46VyutW2QDsSEdTJFXt BaGA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=0WK6KrNSBj0KtZx4TKRtktXcEFqdz6N7kVik1+gL/6A=; b=uMbFW4KKYEgfmH51FhLBaRPZROpwKrNeeSg2mu5HuMmLonfjvdpdQf36Imw0taEMS9 gjXiwlYgRxxujFghUNgfYL2s8bjlxw/CDUXCEreldJ6VdMH+3LdfGqh4MYgvchu77wuz OE8HdYro1mO0ChkdCh5ZjBgZtrECXGDSgm14v+ThRrg/tN5KQTBtvAmF/wsfpaw+RdxC cfD+nT01FWyRYdql5jeXAiOrJ83ghSJ4zcsTlZl+5HjtuyknPR3WWLAuOshrGKVaxW6J 85CPWdV4xzX8wjlVSj1d7saSOF1z+K3dbok90xWhBAqfyrW/m5/LVUMR19cr/SsGQOvg QhxQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=fujZ/dtU; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g1si1857452pge.694.2018.03.20.15.35.50; Tue, 20 Mar 2018 15:36:04 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=fujZ/dtU; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752053AbeCTWdS (ORCPT + 99 others); Tue, 20 Mar 2018 18:33:18 -0400 Received: from mail-pg0-f66.google.com ([74.125.83.66]:40898 "EHLO mail-pg0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751888AbeCTWcB (ORCPT ); Tue, 20 Mar 2018 18:32:01 -0400 Received: by mail-pg0-f66.google.com with SMTP id g8so1211724pgv.7; Tue, 20 Mar 2018 15:32:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=0WK6KrNSBj0KtZx4TKRtktXcEFqdz6N7kVik1+gL/6A=; b=fujZ/dtUA01vE7IEk5A3YDdyfNL6QKlVPFEBFiczBEmSNTPuokLx/KzyoIaP/ZUcsp +sc0KS5DxUhnPQc+WIYuGnFCNngYHz0UC9qQAfPMXGiYyx7Swde5af9+x88JaAS6yNM2 gr9GzyxHbzLvpilkjLJ/iHC+7rvTzwx5HD7RpmFeaGCeLbbinJjlbHyxbvIhZLy1JqWs G6zv08so7hIp7sxG7mwrFD3ie4zChJ/bN9n9E/Ge/d+lbe7L7utRhMO/vOk2Uz7HEb/0 ADA5UXWRghYbvHMTjMUzT1VcnEne38ybA2NdSOTmkEHb2fFDbdykZxSp7qJVQQgXnsiZ 8BFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=0WK6KrNSBj0KtZx4TKRtktXcEFqdz6N7kVik1+gL/6A=; b=UfWeLft7HtKcWEeJ9ATEcHOy+f99ZS8LRSmWLBzfKUpZ3WIUuLu7tQn4qgu6p05FOd yG7r8d5nwdylOx0JaU+bthpsXni/45bdj0Nxlm+rsgssAdXfcCTsMdW5G7gTHx27Bg6n hIB/lmkOPcYwUO40DR5Zlf1hVx5v6dQZP29VGYaD2P7kvPDSVhkbaOo+8Mf0Q9ABau2E Dj507gZGXygORZJscg6nixAo3L+LY5GwSdBdSOJubm+RXnYXBKm6AwezQlzEydWCgs1W tSD75yXmQiyaNInZjwPP+W8EluxtRAD/I/toXL6TB9l/eQlmQkk2X9T6taw0FrRKL+GQ sYLQ== X-Gm-Message-State: AElRT7GhsRIyXb7gbdJCkjNJpQXDMLYWbiXRKy+YkRfZlcdFV+idJmgX Fj+UHTcl0fcl3NmI8yj1SoG+xybg X-Received: by 10.98.12.82 with SMTP id u79mr15055763pfi.192.1521585119315; Tue, 20 Mar 2018 15:31:59 -0700 (PDT) Received: from dtor-ws.mtv.corp.google.com ([2620:0:1000:1511:8de6:27a8:ed13:2ef5]) by smtp.gmail.com with ESMTPSA id r20sm6108360pff.165.2018.03.20.15.31.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 20 Mar 2018 15:31:58 -0700 (PDT) From: Dmitry Torokhov To: linux-input@vger.kernel.org, Benson Leung Cc: Nick Dyer , Olof Johansson , linux-kernel@vger.kernel.org Subject: [PATCH v2 13/14] platform/chrome: chromeos_laptop - discard data for unneeded boards Date: Tue, 20 Mar 2018 15:31:37 -0700 Message-Id: <20180320223138.234724-14-dmitry.torokhov@gmail.com> X-Mailer: git-send-email 2.16.2.804.g6dcf76e118-goog In-Reply-To: <20180320223138.234724-1-dmitry.torokhov@gmail.com> References: <20180320223138.234724-1-dmitry.torokhov@gmail.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Mark board data as __intconst/__initdata and make a copy of appropriate entry once we identified the board we are running on. The rest of the data will be discarded once the kernel finished booting (or module finished loading). Signed-off-by: Dmitry Torokhov --- drivers/platform/chrome/chromeos_laptop.c | 476 ++++++++++++---------- 1 file changed, 264 insertions(+), 212 deletions(-) diff --git a/drivers/platform/chrome/chromeos_laptop.c b/drivers/platform/chrome/chromeos_laptop.c index fe83a2a4900e4..5c47f451e43b1 100644 --- a/drivers/platform/chrome/chromeos_laptop.c +++ b/drivers/platform/chrome/chromeos_laptop.c @@ -54,13 +54,16 @@ struct i2c_peripheral { struct i2c_client *client; }; -#define MAX_I2C_PERIPHERALS 4 - struct chromeos_laptop { - struct i2c_peripheral i2c_peripherals[MAX_I2C_PERIPHERALS]; + /* + * Note that we can't mark this pointer as const because + * i2c_new_probed_device() changes passed in I2C board info, so. + */ + struct i2c_peripheral *i2c_peripherals; + unsigned int num_i2c_peripherals; }; -static struct chromeos_laptop *cros_laptop; +static const struct chromeos_laptop *cros_laptop; static struct i2c_client * chromes_laptop_instantiate_i2c_device(struct i2c_adapter *adapter, @@ -121,13 +124,9 @@ static void chromeos_laptop_check_adapter(struct i2c_adapter *adapter) struct i2c_peripheral *i2c_dev; int i; - for (i = 0; i < MAX_I2C_PERIPHERALS; i++) { + for (i = 0; i < cros_laptop->num_i2c_peripherals; i++) { i2c_dev = &cros_laptop->i2c_peripherals[i]; - /* No more peripherals */ - if (!i2c_dev->board_info.addr) - break; - /* Skip devices already created */ if (i2c_dev->client) continue; @@ -154,7 +153,7 @@ static void chromeos_laptop_detach_i2c_client(struct i2c_client *client) struct i2c_peripheral *i2c_dev; int i; - for (i = 0; i < MAX_I2C_PERIPHERALS; i++) { + for (i = 0; i < cros_laptop->num_i2c_peripherals; i++) { i2c_dev = &cros_laptop->i2c_peripherals[i]; if (i2c_dev->client == client) @@ -186,41 +185,45 @@ static struct notifier_block chromeos_laptop_i2c_notifier = { .notifier_call = chromeos_laptop_i2c_notifier_call, }; -static struct chromeos_laptop samsung_series_5_550 = { - .i2c_peripherals = { - /* Touchpad. */ - { - .board_info = { - I2C_BOARD_INFO("cyapa", CYAPA_TP_I2C_ADDR), - .flags = I2C_CLIENT_WAKE, - }, - .dmi_name = "trackpad", - .type = I2C_ADAPTER_SMBUS, +#define DECLARE_CROS_LAPTOP(_name) \ +static const struct chromeos_laptop _name __initconst = { \ + .i2c_peripherals = _name##_peripherals, \ + .num_i2c_peripherals = ARRAY_SIZE(_name##_peripherals), \ +} + +static struct i2c_peripheral samsung_series_5_550_peripherals[] __initdata = { + /* Touchpad. */ + { + .board_info = { + I2C_BOARD_INFO("cyapa", CYAPA_TP_I2C_ADDR), + .flags = I2C_CLIENT_WAKE, }, - /* Light Sensor. */ - { - .board_info = { - I2C_BOARD_INFO("isl29018", ISL_ALS_I2C_ADDR), - }, - .dmi_name = "lightsensor", - .type = I2C_ADAPTER_SMBUS, + .dmi_name = "trackpad", + .type = I2C_ADAPTER_SMBUS, + }, + /* Light Sensor. */ + { + .board_info = { + I2C_BOARD_INFO("isl29018", ISL_ALS_I2C_ADDR), }, + .dmi_name = "lightsensor", + .type = I2C_ADAPTER_SMBUS, }, }; +DECLARE_CROS_LAPTOP(samsung_series_5_550); -static struct chromeos_laptop samsung_series_5 = { - .i2c_peripherals = { - /* Light Sensor. */ - { - .board_info = { - I2C_BOARD_INFO("tsl2583", TAOS_ALS_I2C_ADDR), - }, - .type = I2C_ADAPTER_SMBUS, +static struct i2c_peripheral samsung_series_5_peripherals[] __initdata = { + /* Light Sensor. */ + { + .board_info = { + I2C_BOARD_INFO("tsl2583", TAOS_ALS_I2C_ADDR), }, + .type = I2C_ADAPTER_SMBUS, }, }; +DECLARE_CROS_LAPTOP(samsung_series_5); -static int chromebook_pixel_tp_keys[] = { +static const int chromebook_pixel_tp_keys[] __initconst = { KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, @@ -229,199 +232,192 @@ static int chromebook_pixel_tp_keys[] = { BTN_LEFT }; -static const struct property_entry chromebook_pixel_trackpad_props[] = { +static const struct property_entry +chromebook_pixel_trackpad_props[] __initconst = { PROPERTY_ENTRY_U32_ARRAY("linux,gpio-keymap", chromebook_pixel_tp_keys), { } }; -static struct chromeos_laptop chromebook_pixel = { - .i2c_peripherals = { - /* Touch Screen. */ - { - .board_info = { - I2C_BOARD_INFO("atmel_mxt_ts", - ATMEL_TS_I2C_ADDR), - .flags = I2C_CLIENT_WAKE, - }, - .dmi_name = "touchscreen", - .irqflags = IRQF_TRIGGER_FALLING, - .type = I2C_ADAPTER_PANEL, - .alt_addr = ATMEL_TS_I2C_BL_ADDR, +static struct i2c_peripheral chromebook_pixel_peripherals[] __initdata = { + /* Touch Screen. */ + { + .board_info = { + I2C_BOARD_INFO("atmel_mxt_ts", + ATMEL_TS_I2C_ADDR), + .flags = I2C_CLIENT_WAKE, }, - /* Touchpad. */ - { - .board_info = { - I2C_BOARD_INFO("atmel_mxt_tp", - ATMEL_TP_I2C_ADDR), - .properties = - chromebook_pixel_trackpad_props, - .flags = I2C_CLIENT_WAKE, - }, - .dmi_name = "trackpad", - .irqflags = IRQF_TRIGGER_FALLING, - .type = I2C_ADAPTER_VGADDC, - .alt_addr = ATMEL_TP_I2C_BL_ADDR, + .dmi_name = "touchscreen", + .irqflags = IRQF_TRIGGER_FALLING, + .type = I2C_ADAPTER_PANEL, + .alt_addr = ATMEL_TS_I2C_BL_ADDR, + }, + /* Touchpad. */ + { + .board_info = { + I2C_BOARD_INFO("atmel_mxt_tp", + ATMEL_TP_I2C_ADDR), + .properties = + chromebook_pixel_trackpad_props, + .flags = I2C_CLIENT_WAKE, }, - /* Light Sensor. */ - { - .board_info = { - I2C_BOARD_INFO("isl29018", ISL_ALS_I2C_ADDR), - }, - .dmi_name = "lightsensor", - .type = I2C_ADAPTER_PANEL, + .dmi_name = "trackpad", + .irqflags = IRQF_TRIGGER_FALLING, + .type = I2C_ADAPTER_VGADDC, + .alt_addr = ATMEL_TP_I2C_BL_ADDR, + }, + /* Light Sensor. */ + { + .board_info = { + I2C_BOARD_INFO("isl29018", ISL_ALS_I2C_ADDR), }, + .dmi_name = "lightsensor", + .type = I2C_ADAPTER_PANEL, }, }; +DECLARE_CROS_LAPTOP(chromebook_pixel); -static struct chromeos_laptop hp_chromebook_14 = { - .i2c_peripherals = { - /* Touchpad. */ - { - .board_info = { - I2C_BOARD_INFO("cyapa", CYAPA_TP_I2C_ADDR), - .flags = I2C_CLIENT_WAKE, - }, - .dmi_name = "trackpad", - .type = I2C_ADAPTER_DESIGNWARE, +static struct i2c_peripheral hp_chromebook_14_peripherals[] __initdata = { + /* Touchpad. */ + { + .board_info = { + I2C_BOARD_INFO("cyapa", CYAPA_TP_I2C_ADDR), + .flags = I2C_CLIENT_WAKE, }, + .dmi_name = "trackpad", + .type = I2C_ADAPTER_DESIGNWARE, }, }; +DECLARE_CROS_LAPTOP(hp_chromebook_14); -static struct chromeos_laptop dell_chromebook_11 = { - .i2c_peripherals = { - /* Touchpad. */ - { - .board_info = { - I2C_BOARD_INFO("cyapa", CYAPA_TP_I2C_ADDR), - .flags = I2C_CLIENT_WAKE, - }, - .dmi_name = "trackpad", - .type = I2C_ADAPTER_DESIGNWARE, +static struct i2c_peripheral dell_chromebook_11_peripherals[] __initdata = { + /* Touchpad. */ + { + .board_info = { + I2C_BOARD_INFO("cyapa", CYAPA_TP_I2C_ADDR), + .flags = I2C_CLIENT_WAKE, }, - /* Elan Touchpad option. */ - { - .board_info = { - I2C_BOARD_INFO("elan_i2c", ELAN_TP_I2C_ADDR), - .flags = I2C_CLIENT_WAKE, - }, - .dmi_name = "trackpad", - .type = I2C_ADAPTER_DESIGNWARE, + .dmi_name = "trackpad", + .type = I2C_ADAPTER_DESIGNWARE, + }, + /* Elan Touchpad option. */ + { + .board_info = { + I2C_BOARD_INFO("elan_i2c", ELAN_TP_I2C_ADDR), + .flags = I2C_CLIENT_WAKE, }, + .dmi_name = "trackpad", + .type = I2C_ADAPTER_DESIGNWARE, }, }; +DECLARE_CROS_LAPTOP(dell_chromebook_11); -static struct chromeos_laptop toshiba_cb35 = { - .i2c_peripherals = { - /* Touchpad. */ - { - .board_info = { - I2C_BOARD_INFO("cyapa", CYAPA_TP_I2C_ADDR), - .flags = I2C_CLIENT_WAKE, - }, - .dmi_name = "trackpad", - .type = I2C_ADAPTER_DESIGNWARE, +static struct i2c_peripheral toshiba_cb35_peripherals[] __initdata = { + /* Touchpad. */ + { + .board_info = { + I2C_BOARD_INFO("cyapa", CYAPA_TP_I2C_ADDR), + .flags = I2C_CLIENT_WAKE, }, + .dmi_name = "trackpad", + .type = I2C_ADAPTER_DESIGNWARE, }, }; +DECLARE_CROS_LAPTOP(toshiba_cb35); -static struct chromeos_laptop acer_c7_chromebook = { - .i2c_peripherals = { - /* Touchpad. */ - { - .board_info = { - I2C_BOARD_INFO("cyapa", CYAPA_TP_I2C_ADDR), - .flags = I2C_CLIENT_WAKE, - }, - .dmi_name = "trackpad", - .type = I2C_ADAPTER_SMBUS, +static struct i2c_peripheral acer_c7_chromebook_peripherals[] __initdata = { + /* Touchpad. */ + { + .board_info = { + I2C_BOARD_INFO("cyapa", CYAPA_TP_I2C_ADDR), + .flags = I2C_CLIENT_WAKE, }, + .dmi_name = "trackpad", + .type = I2C_ADAPTER_SMBUS, }, }; +DECLARE_CROS_LAPTOP(acer_c7_chromebook); -static struct chromeos_laptop acer_ac700 = { - .i2c_peripherals = { - /* Light Sensor. */ - { - .board_info = { - I2C_BOARD_INFO("tsl2583", TAOS_ALS_I2C_ADDR), - }, - .type = I2C_ADAPTER_SMBUS, +static struct i2c_peripheral acer_ac700_peripherals[] __initdata = { + /* Light Sensor. */ + { + .board_info = { + I2C_BOARD_INFO("tsl2583", TAOS_ALS_I2C_ADDR), }, + .type = I2C_ADAPTER_SMBUS, }, }; +DECLARE_CROS_LAPTOP(acer_ac700); -static struct chromeos_laptop acer_c720 = { - .i2c_peripherals = { - /* Touchscreen. */ - { - .board_info = { - I2C_BOARD_INFO("atmel_mxt_ts", - ATMEL_TS_I2C_ADDR), - .flags = I2C_CLIENT_WAKE, - }, - .dmi_name = "touchscreen", - .irqflags = IRQF_TRIGGER_FALLING, - .type = I2C_ADAPTER_DESIGNWARE, - .pci_devid = PCI_DEVID(0, PCI_DEVFN(0x15, 0x2)), - .alt_addr = ATMEL_TS_I2C_BL_ADDR, +static struct i2c_peripheral acer_c720_peripherals[] __initdata = { + /* Touchscreen. */ + { + .board_info = { + I2C_BOARD_INFO("atmel_mxt_ts", + ATMEL_TS_I2C_ADDR), + .flags = I2C_CLIENT_WAKE, }, - /* Touchpad. */ - { - .board_info = { - I2C_BOARD_INFO("cyapa", CYAPA_TP_I2C_ADDR), - .flags = I2C_CLIENT_WAKE, - }, - .dmi_name = "trackpad", - .type = I2C_ADAPTER_DESIGNWARE, - .pci_devid = PCI_DEVID(0, PCI_DEVFN(0x15, 0x1)), + .dmi_name = "touchscreen", + .irqflags = IRQF_TRIGGER_FALLING, + .type = I2C_ADAPTER_DESIGNWARE, + .pci_devid = PCI_DEVID(0, PCI_DEVFN(0x15, 0x2)), + .alt_addr = ATMEL_TS_I2C_BL_ADDR, + }, + /* Touchpad. */ + { + .board_info = { + I2C_BOARD_INFO("cyapa", CYAPA_TP_I2C_ADDR), + .flags = I2C_CLIENT_WAKE, }, - /* Elan Touchpad option. */ - { - .board_info = { - I2C_BOARD_INFO("elan_i2c", ELAN_TP_I2C_ADDR), - .flags = I2C_CLIENT_WAKE, - }, - .dmi_name = "trackpad", - .type = I2C_ADAPTER_DESIGNWARE, - .pci_devid = PCI_DEVID(0, PCI_DEVFN(0x15, 0x1)), + .dmi_name = "trackpad", + .type = I2C_ADAPTER_DESIGNWARE, + .pci_devid = PCI_DEVID(0, PCI_DEVFN(0x15, 0x1)), + }, + /* Elan Touchpad option. */ + { + .board_info = { + I2C_BOARD_INFO("elan_i2c", ELAN_TP_I2C_ADDR), + .flags = I2C_CLIENT_WAKE, }, - /* Light Sensor. */ - { - .board_info = { - I2C_BOARD_INFO("isl29018", ISL_ALS_I2C_ADDR), - }, - .dmi_name = "lightsensor", - .type = I2C_ADAPTER_DESIGNWARE, - .pci_devid = PCI_DEVID(0, PCI_DEVFN(0x15, 0x2)), + .dmi_name = "trackpad", + .type = I2C_ADAPTER_DESIGNWARE, + .pci_devid = PCI_DEVID(0, PCI_DEVFN(0x15, 0x1)), + }, + /* Light Sensor. */ + { + .board_info = { + I2C_BOARD_INFO("isl29018", ISL_ALS_I2C_ADDR), }, + .dmi_name = "lightsensor", + .type = I2C_ADAPTER_DESIGNWARE, + .pci_devid = PCI_DEVID(0, PCI_DEVFN(0x15, 0x2)), }, }; +DECLARE_CROS_LAPTOP(acer_c720); -static struct chromeos_laptop hp_pavilion_14_chromebook = { - .i2c_peripherals = { - /* Touchpad. */ - { - .board_info = { - I2C_BOARD_INFO("cyapa", CYAPA_TP_I2C_ADDR), - .flags = I2C_CLIENT_WAKE, - }, - .dmi_name = "trackpad", - .type = I2C_ADAPTER_SMBUS, +static struct i2c_peripheral +hp_pavilion_14_chromebook_peripherals[] __initdata = { + /* Touchpad. */ + { + .board_info = { + I2C_BOARD_INFO("cyapa", CYAPA_TP_I2C_ADDR), + .flags = I2C_CLIENT_WAKE, }, + .dmi_name = "trackpad", + .type = I2C_ADAPTER_SMBUS, }, }; +DECLARE_CROS_LAPTOP(hp_pavilion_14_chromebook); -static struct chromeos_laptop cr48 = { - .i2c_peripherals = { - /* Light Sensor. */ - { - .board_info = { - I2C_BOARD_INFO("tsl2563", TAOS_ALS_I2C_ADDR), - }, - .type = I2C_ADAPTER_SMBUS, +static struct i2c_peripheral cr48_peripherals[] __initdata = { + /* Light Sensor. */ + { + .board_info = { + I2C_BOARD_INFO("tsl2563", TAOS_ALS_I2C_ADDR), }, + .type = I2C_ADAPTER_SMBUS, }, }; +DECLARE_CROS_LAPTOP(cr48); static const struct dmi_system_id chromeos_laptop_dmi_table[] __initconst = { { @@ -541,24 +537,14 @@ static int __init chromeos_laptop_get_irq_from_dmi(const char *dmi_name) return dev_data->instance; } -static struct chromeos_laptop * __init -chromeos_laptop_prepare(const struct dmi_system_id *id) +static int __init chromeos_laptop_setup_irq(struct i2c_peripheral *i2c_dev) { - struct i2c_peripheral *i2c_dev; int irq; - int i; - - cros_laptop = (void *)id->driver_data; - - for (i = 0; i < MAX_I2C_PERIPHERALS; i++) { - i2c_dev = &cros_laptop->i2c_peripherals[i]; - - if (!i2c_dev->dmi_name) - continue; + if (i2c_dev->dmi_name) { irq = chromeos_laptop_get_irq_from_dmi(i2c_dev->dmi_name); if (irq < 0) - return ERR_PTR(irq); + return irq; i2c_dev->irq_resource = (struct resource) DEFINE_RES_NAMED(irq, 1, NULL, @@ -567,9 +553,87 @@ chromeos_laptop_prepare(const struct dmi_system_id *id) i2c_dev->board_info.num_resources = 1; } + return 0; +} + +static struct chromeos_laptop * __init +chromeos_laptop_prepare(const struct chromeos_laptop *src) +{ + struct chromeos_laptop *cros_laptop; + struct i2c_peripheral *i2c_dev; + struct i2c_board_info *info; + int error; + int i; + + cros_laptop = kzalloc(sizeof(*cros_laptop), GFP_KERNEL); + if (!cros_laptop) + return ERR_PTR(-ENOMEM); + + cros_laptop->i2c_peripherals = kmemdup(src->i2c_peripherals, + src->num_i2c_peripherals * + sizeof(*src->i2c_peripherals), + GFP_KERNEL); + if (!cros_laptop->i2c_peripherals) { + error = -ENOMEM; + goto err_free_cros_laptop; + } + + cros_laptop->num_i2c_peripherals = src->num_i2c_peripherals; + + for (i = 0; i < cros_laptop->num_i2c_peripherals; i++) { + i2c_dev = &cros_laptop->i2c_peripherals[i]; + info = &i2c_dev->board_info; + + error = chromeos_laptop_setup_irq(i2c_dev); + if (error) + goto err_destroy_cros_peripherals; + + /* We need to deep-copy properties */ + if (info->properties) { + info->properties = + property_entries_dup(info->properties); + if (IS_ERR(info->properties)) { + error = PTR_ERR(info->properties); + goto err_destroy_cros_peripherals; + } + } + } + return cros_laptop; + +err_destroy_cros_peripherals: + while (--i >= 0) { + i2c_dev = &cros_laptop->i2c_peripherals[i]; + info = &i2c_dev->board_info; + if (info->properties) + property_entries_free(info->properties); + } + kfree(cros_laptop->i2c_peripherals); +err_free_cros_laptop: + kfree(cros_laptop); + return ERR_PTR(error); } +static void chromeos_laptop_destroy(const struct chromeos_laptop *cros_laptop) +{ + struct i2c_peripheral *i2c_dev; + struct i2c_board_info *info; + int i; + + for (i = 0; i < cros_laptop->num_i2c_peripherals; i++) { + i2c_dev = &cros_laptop->i2c_peripherals[i]; + info = &i2c_dev->board_info; + + if (i2c_dev->client) + i2c_unregister_device(i2c_dev->client); + + if (info->properties) + property_entries_free(info->properties); + } + + kfree(cros_laptop->i2c_peripherals); + kfree(cros_laptop); +} static int __init chromeos_laptop_init(void) { @@ -584,7 +648,7 @@ static int __init chromeos_laptop_init(void) pr_debug("DMI Matched %s\n", dmi_id->ident); - cros_laptop = chromeos_laptop_prepare(dmi_id->driver_data); + cros_laptop = chromeos_laptop_prepare((void *)dmi_id->driver_data); if (IS_ERR(cros_laptop)) return PTR_ERR(cros_laptop); @@ -592,6 +656,7 @@ static int __init chromeos_laptop_init(void) &chromeos_laptop_i2c_notifier); if (error) { pr_err("failed to register i2c bus notifier: %d\n", error); + chromeos_laptop_destroy(cros_laptop); return error; } @@ -606,21 +671,8 @@ static int __init chromeos_laptop_init(void) static void __exit chromeos_laptop_exit(void) { - struct i2c_peripheral *i2c_dev; - int i; - bus_unregister_notifier(&i2c_bus_type, &chromeos_laptop_i2c_notifier); - - for (i = 0; i < MAX_I2C_PERIPHERALS; i++) { - i2c_dev = &cros_laptop->i2c_peripherals[i]; - - /* No more peripherals */ - if (!i2c_dev->board_info.type) - break; - - if (i2c_dev->client) - i2c_unregister_device(i2c_dev->client); - } + chromeos_laptop_destroy(cros_laptop); } module_init(chromeos_laptop_init); -- 2.16.2.804.g6dcf76e118-goog