Received: by 2002:a05:6a10:6744:0:0:0:0 with SMTP id w4csp68070pxu; Wed, 14 Oct 2020 20:33:35 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwv38InX5vDONwAMzX+OyTVHiIZyzsSybFsYxmkXVmyelD687KriSrIGSNSRF3ka9mhmh+a X-Received: by 2002:aa7:d7ce:: with SMTP id e14mr2357609eds.258.1602732815055; Wed, 14 Oct 2020 20:33:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1602732815; cv=none; d=google.com; s=arc-20160816; b=h22iyRPASLM/kpNg2MhbROZBd/X/gFZZWprmoEXxBncewA7Mxe/wr8UuoSsK74Hm/h 42lBMwzbk6H1dDYIqyF7EIRrMVgH1UUu0liVnVyZIDran2C7iEoMZVn0k/1XW7bx9IP1 8loxryr2cL1X2R+hLczCSwYEni5Hu0WY0Wwgkfw66Gh8JuHUnGI6ikyBq/5D/YqCYAva 5jkfCzUg/8tVfu+RQVak97TIitUJ4CSBOXvDKLKuqdU5gWYaSMgLhlUyFtl4lwJevJix bXlE7oZgo1mwpKMn53mTDyXVIC50oggbsLkvvTPDqiaFwcImtGoW/OW9XfP1TuJ20plH NESw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=cN8iWVwIWlPjYidVuxp+wz9oABo5owVEFQAK0K6BKUM=; b=cD+2P7i7DrqJQd/W0R4wF8MOXTztVC4gb96wECqFvs8QSnpFi+TxfUCbPFk68oop+X xdvbL0i2NwsDQBkBq3t4rrLgHSDqI6nwK3mIgYHjkvcWrc8AU9RwlM2br/GeXi8Rf+uF Z0iH1gOCsV8FlRIRiEiQKCZiOYk7oNgFj2puj0CLtUlYZN1Xum54XGDBRS34J9WMalWz WqS0lAsCIyVhe1l5W8jeZJ7Zygi24SQBYEeO4LdPxiC0rGbnp79U98xVPEwzVsz7p0I2 kWw6Fk5IUQ73+cFBdly+NonnppR+E4N145Kgh+m/HEk6LWfJLXrKPagsXB0UzphiuvYF vA9w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=E6eOmSNX; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id r7si1022715edy.440.2020.10.14.20.33.13; Wed, 14 Oct 2020 20:33:35 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=E6eOmSNX; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388502AbgJOBTo (ORCPT + 99 others); Wed, 14 Oct 2020 21:19:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47398 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387865AbgJOBTj (ORCPT ); Wed, 14 Oct 2020 21:19:39 -0400 Received: from mail-pj1-x1041.google.com (mail-pj1-x1041.google.com [IPv6:2607:f8b0:4864:20::1041]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B1098C0F26F3 for ; Wed, 14 Oct 2020 18:02:31 -0700 (PDT) Received: by mail-pj1-x1041.google.com with SMTP id ds1so749592pjb.5 for ; Wed, 14 Oct 2020 18:02:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=cN8iWVwIWlPjYidVuxp+wz9oABo5owVEFQAK0K6BKUM=; b=E6eOmSNXtAINHXWwPQsrJYWzhKEHOl89Gai9Nl4U9K2LH6/VBV9ard/8xd0yol4x4v QT7qxrBRAFleDyiFUJUWlCNmUtRUYdxOVAMXEkZeTXI+nWETl7yyw41yVxM7jCgOlimL mIC9+GlbPZEF31Z+LJGrJkjBY2+PWz+WPWpvU= 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:mime-version :content-transfer-encoding; bh=cN8iWVwIWlPjYidVuxp+wz9oABo5owVEFQAK0K6BKUM=; b=mlFIVTTJmwXsVjsForoizF0Z2oIcJH9FAur+qVsguQ/gx4lO2X73uQcJHW47tHAKNB fd3Qt6y9Hc+lTHY9JmuzYWyZrm60vQ9hmPIHngC9gJw5+dKYipn2lmSERinz+D4jklTE UingH0aaBAeFu1MHDdqiJZhCzqD2LcYD4cPRkfGlWrCJ/Y4VAo4wKoncwG4c7jvgR6fs khB4+PE9MJkVfJejwtOs5vL1Q++ervgPvgGVyqIXvCapNB4M3hjcD6mrG4heLXNlAcFF IlwVK2fvI+E74lxTfcApOEWhnhqPha2W/bhTV2AB7o/m+H30OMlqozICgVGBNCOhBaOl okKA== X-Gm-Message-State: AOAM531x5YKiaMYUAWCH691XAEmVnZ4MaqUEMlCfglL/mmDWH9ZwOFf6 MyNXh7q6wfSd+M3gg7jh6ulPOd7ZTxYgtQ== X-Received: by 2002:a17:90b:3103:: with SMTP id gc3mr1827983pjb.158.1602723751210; Wed, 14 Oct 2020 18:02:31 -0700 (PDT) Received: from evgreen-glaptop.cheshire.ch ([2601:646:c780:1404:a2ce:c8ff:fec4:54a3]) by smtp.gmail.com with ESMTPSA id n12sm826855pjt.16.2020.10.14.18.02.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 14 Oct 2020 18:02:30 -0700 (PDT) From: Evan Green To: Peter Rosin Cc: Wolfram Sang , Randy Dunlap , Evan Green , Peter Korsgaard , linux-i2c@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2] i2c: i2c-mux-gpio: Enable this driver in ACPI land Date: Wed, 14 Oct 2020 18:02:23 -0700 Message-Id: <20201014180137.v2.1.Idef164c23d326f5e5edecfc5d3eb2a68fcf18be1@changeid> X-Mailer: git-send-email 2.26.2 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Enable i2c-mux-gpio devices to be defined via ACPI. The idle-state property translates directly to a fwnode_property_*() call. The child reg property translates naturally into _ADR in ACPI. The i2c-parent binding is a relic from the days when all direct children of an i2c controller in Linux had to be i2c devices. These days that implementation detail has been worked out, so the i2c-mux can sit as a direct child of its parent controller, which is where it makes the most sense from a hardware description perspective. For the ACPI implementation we'll assume that's always how the i2c-mux-gpio is instantiated. Signed-off-by: Evan Green --- Changes in v2: - Make it compile properly when !CONFIG_ACPI (Randy) - Update commit message regarding i2c-parent (Peter) drivers/i2c/muxes/i2c-mux-gpio.c | 103 ++++++++++++++++++++++--------- 1 file changed, 75 insertions(+), 28 deletions(-) diff --git a/drivers/i2c/muxes/i2c-mux-gpio.c b/drivers/i2c/muxes/i2c-mux-gpio.c index 4effe563e9e8d..8e4008f4a9b5d 100644 --- a/drivers/i2c/muxes/i2c-mux-gpio.c +++ b/drivers/i2c/muxes/i2c-mux-gpio.c @@ -49,34 +49,80 @@ static int i2c_mux_gpio_deselect(struct i2c_mux_core *muxc, u32 chan) return 0; } -#ifdef CONFIG_OF -static int i2c_mux_gpio_probe_dt(struct gpiomux *mux, - struct platform_device *pdev) +#ifdef CONFIG_ACPI + +static int i2c_mux_gpio_get_acpi_adr(struct device *dev, + struct fwnode_handle *fwdev, + unsigned int *adr) + +{ + unsigned long long adr64; + acpi_status status; + + status = acpi_evaluate_integer(ACPI_HANDLE_FWNODE(fwdev), + METHOD_NAME__ADR, + NULL, &adr64); + + if (!ACPI_SUCCESS(status)) { + dev_err(dev, "Cannot get address"); + return -EINVAL; + } + + *adr = adr64; + return 0; +} + +#else + +static int i2c_mux_gpio_get_acpi_adr(struct device *dev, + struct fwnode_handle *fwdev, + unsigned int *adr) +{ + return -EINVAL; +} + +#endif + +static int i2c_mux_gpio_probe_fw(struct gpiomux *mux, + struct platform_device *pdev) { - struct device_node *np = pdev->dev.of_node; - struct device_node *adapter_np, *child; - struct i2c_adapter *adapter; + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + acpi_handle dev_handle; + struct device_node *adapter_np; + struct i2c_adapter *adapter = NULL; + struct fwnode_handle *child = NULL; unsigned *values; - int i = 0; + int rc, i = 0; - if (!np) - return -ENODEV; + if (is_of_node(dev->fwnode)) { + if (!np) + return -ENODEV; - adapter_np = of_parse_phandle(np, "i2c-parent", 0); - if (!adapter_np) { - dev_err(&pdev->dev, "Cannot parse i2c-parent\n"); - return -ENODEV; + adapter_np = of_parse_phandle(np, "i2c-parent", 0); + if (!adapter_np) { + dev_err(&pdev->dev, "Cannot parse i2c-parent\n"); + return -ENODEV; + } + adapter = of_find_i2c_adapter_by_node(adapter_np); + of_node_put(adapter_np); + + } else if (is_acpi_node(dev->fwnode)) { + /* + * In ACPI land the mux should be a direct child of the i2c + * bus it muxes. + */ + dev_handle = ACPI_HANDLE(dev->parent); + adapter = i2c_acpi_find_adapter_by_handle(dev_handle); } - adapter = of_find_i2c_adapter_by_node(adapter_np); - of_node_put(adapter_np); + if (!adapter) return -EPROBE_DEFER; mux->data.parent = i2c_adapter_id(adapter); put_device(&adapter->dev); - mux->data.n_values = of_get_child_count(np); - + mux->data.n_values = device_get_child_node_count(dev); values = devm_kcalloc(&pdev->dev, mux->data.n_values, sizeof(*mux->data.values), GFP_KERNEL); @@ -85,24 +131,25 @@ static int i2c_mux_gpio_probe_dt(struct gpiomux *mux, return -ENOMEM; } - for_each_child_of_node(np, child) { - of_property_read_u32(child, "reg", values + i); + device_for_each_child_node(dev, child) { + if (is_of_node(child)) { + fwnode_property_read_u32(child, "reg", values + i); + + } else if (is_acpi_node(child)) { + rc = i2c_mux_gpio_get_acpi_adr(dev, child, values + i); + if (rc) + return rc; + } + i++; } mux->data.values = values; - if (of_property_read_u32(np, "idle-state", &mux->data.idle)) + if (fwnode_property_read_u32(dev->fwnode, "idle-state", &mux->data.idle)) mux->data.idle = I2C_MUX_GPIO_NO_IDLE; return 0; } -#else -static int i2c_mux_gpio_probe_dt(struct gpiomux *mux, - struct platform_device *pdev) -{ - return 0; -} -#endif static int i2c_mux_gpio_probe(struct platform_device *pdev) { @@ -118,7 +165,7 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev) return -ENOMEM; if (!dev_get_platdata(&pdev->dev)) { - ret = i2c_mux_gpio_probe_dt(mux, pdev); + ret = i2c_mux_gpio_probe_fw(mux, pdev); if (ret < 0) return ret; } else { -- 2.26.2