From patchwork Thu Jul 25 13:56:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Usyskin X-Patchwork-Id: 814559 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.19]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 9A7731993A3 for ; Thu, 25 Jul 2024 14:05:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721916344; cv=none; b=VyYZ3btLiFl53Vqg3RxLt0F60JmRefeCu0R81dcOFcPKUfIOkBp9gtMHc9j1CmLoqCvGKgZaLLF0B4qeb/bpNPzyM9lhHeRqy6u68Rb0XZpznujXZ6BIcF5AEjgOz5+TSpBk0oGgUCkmcu2Nf3l7itSpTjXLktt0IEmLqNfSMTw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721916344; c=relaxed/simple; bh=T1iJb8J1XuuHNsMCNwH4FrNffBmlFDaLzqAwwE6g5O0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=LTkyU1eJ1H6dfQXjnihZOeWBO4sQFUzkv2dIFDX5Flh/MS37OPF5R12yALQvNVw3NHEYH8DuoQ2EdBe4VCfRxD6hy6hRjlDjHxQb3G4LXkMXINf/M04Il6Ui641r6VdNGSuVGgbLMeaDsahMKgAe3t+uZPLr6stR4NiLTsdkszE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=IJEp9HHc; arc=none smtp.client-ip=198.175.65.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="IJEp9HHc" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1721916343; x=1753452343; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=T1iJb8J1XuuHNsMCNwH4FrNffBmlFDaLzqAwwE6g5O0=; b=IJEp9HHcK85YbQe0Xa0Pj42yIEGhZw7LigXhzf9EeV/4ahfo15SAJFgU UYtV1OeYHgy+blDQgZcc87IYXonNWjQyDOSkqSsT+z8V2fc86vxXVuIe4 NYn614MKeSQw+57ItoPLYE4OgfPwfbfSvKirxr/N82Nsu6tmHnwZWNz2n 8OF1Kdsj4H8SVU5qs+5nu0fmqYlGLNI2rfuYyCzUoBOt28+8OzNXSWN8A xSxJU7SYtljvJ0OyDlLC8NkN6vIKh5EYg1uXPdzqzEaLI6+3sEPfzBNd/ OPU4e5fvJ9LdCxM5LWBiweSsFT8eTu0du1smsi8as+gWyH44bEd7M9EFO g==; X-CSE-ConnectionGUID: 9oYXreLVScuiECyKmqKV/w== X-CSE-MsgGUID: 5RIrfVMKR0CRvp+fl+ZhVg== X-IronPort-AV: E=McAfee;i="6700,10204,11144"; a="19504822" X-IronPort-AV: E=Sophos;i="6.09,236,1716274800"; d="scan'208";a="19504822" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by orvoesa111.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Jul 2024 07:05:43 -0700 X-CSE-ConnectionGUID: 7PXB1uwBRB66bbCKbblUtA== X-CSE-MsgGUID: Y5E2zHCtR1eQDqG7biNlXw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,236,1716274800"; d="scan'208";a="53007753" Received: from sannilnx-dsk.jer.intel.com ([10.12.231.107]) by fmviesa010-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Jul 2024 07:05:36 -0700 From: Alexander Usyskin To: Mark Brown , Lucas De Marchi , Oded Gabbay , =?utf-8?q?Thomas_Hellstr=C3=B6m?= , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Daniel Vetter , Jani Nikula , Joonas Lahtinen , Rodrigo Vivi , Tvrtko Ursulin Cc: Tomas Winkler , Alexander Usyskin , Vitaly Lubart , intel-xe@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-spi@vger.kernel.org, intel-gfx@lists.freedesktop.org Subject: [PATCH v3 04/12] spi: intel-dg: spi register with mtd Date: Thu, 25 Jul 2024 16:56:49 +0300 Message-Id: <20240725135657.1061836-5-alexander.usyskin@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240725135657.1061836-1-alexander.usyskin@intel.com> References: <20240725135657.1061836-1-alexander.usyskin@intel.com> Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Tomas Winkler Register the on-die spi device with the mtd subsystem. Refcount spi object on _get and _put mtd callbacks. CC: Rodrigo Vivi CC: Lucas De Marchi Signed-off-by: Tomas Winkler Signed-off-by: Alexander Usyskin --- drivers/spi/spi-intel-dg.c | 111 +++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/drivers/spi/spi-intel-dg.c b/drivers/spi/spi-intel-dg.c index 63c8292347e7..2ffc2d61fdc8 100644 --- a/drivers/spi/spi-intel-dg.c +++ b/drivers/spi/spi-intel-dg.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include #include #include @@ -17,6 +19,8 @@ struct intel_dg_spi { struct kref refcnt; + struct mtd_info mtd; + struct mutex lock; /* region access lock */ void __iomem *base; size_t size; unsigned int nregions; @@ -407,6 +411,23 @@ static int intel_dg_spi_init(struct intel_dg_spi *spi, struct device *device) return n; } +static int intel_dg_spi_erase(struct mtd_info *mtd, struct erase_info *info) +{ + return 0; +} + +static int intel_dg_spi_read(struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, u_char *buf) +{ + return 0; +} + +static int intel_dg_spi_write(struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u_char *buf) +{ + return 0; +} + static void intel_dg_spi_release(struct kref *kref) { struct intel_dg_spi *spi = container_of(kref, struct intel_dg_spi, refcnt); @@ -415,9 +436,90 @@ static void intel_dg_spi_release(struct kref *kref) pr_debug("freeing spi memory\n"); for (i = 0; i < spi->nregions; i++) kfree(spi->regions[i].name); + mutex_destroy(&spi->lock); kfree(spi); } +static int intel_dg_spi_get_device(struct mtd_info *mtd) +{ + struct mtd_info *master; + struct intel_dg_spi *spi; + + if (!mtd) + return -ENODEV; + + master = mtd_get_master(mtd); + spi = master->priv; + if (WARN_ON(!spi)) + return -EINVAL; + pr_debug("get spi %s %d\n", mtd->name, kref_read(&spi->refcnt)); + kref_get(&spi->refcnt); + + return 0; +} + +static void intel_dg_spi_put_device(struct mtd_info *mtd) +{ + struct mtd_info *master; + struct intel_dg_spi *spi; + + if (!mtd) + return; + + master = mtd_get_master(mtd); + spi = master->priv; + if (WARN_ON(!spi)) + return; + pr_debug("put spi %s %d\n", mtd->name, kref_read(&spi->refcnt)); + kref_put(&spi->refcnt, intel_dg_spi_release); +} + +static int intel_dg_spi_init_mtd(struct intel_dg_spi *spi, struct device *device, + unsigned int nparts, bool writeable_override) +{ + unsigned int i; + unsigned int n; + struct mtd_partition *parts = NULL; + int ret; + + dev_dbg(device, "registering with mtd\n"); + + spi->mtd.owner = THIS_MODULE; + spi->mtd.dev.parent = device; + spi->mtd.flags = MTD_CAP_NORFLASH | MTD_WRITEABLE; + spi->mtd.type = MTD_DATAFLASH; + spi->mtd.priv = spi; + spi->mtd._write = intel_dg_spi_write; + spi->mtd._read = intel_dg_spi_read; + spi->mtd._erase = intel_dg_spi_erase; + spi->mtd._get_device = intel_dg_spi_get_device; + spi->mtd._put_device = intel_dg_spi_put_device; + spi->mtd.writesize = SZ_1; /* 1 byte granularity */ + spi->mtd.erasesize = SZ_4K; /* 4K bytes granularity */ + spi->mtd.size = spi->size; + + parts = kcalloc(spi->nregions, sizeof(*parts), GFP_KERNEL); + if (!parts) + return -ENOMEM; + + for (i = 0, n = 0; i < spi->nregions && n < nparts; i++) { + if (!spi->regions[i].is_readable) + continue; + parts[n].name = spi->regions[i].name; + parts[n].offset = spi->regions[i].offset; + parts[n].size = spi->regions[i].size; + if (!spi->regions[i].is_writable && !writeable_override) + parts[n].mask_flags = MTD_WRITEABLE; + n++; + } + + ret = mtd_device_register(&spi->mtd, parts, n); + + kfree(parts); + + return ret; +} + static int intel_dg_spi_probe(struct auxiliary_device *aux_dev, const struct auxiliary_device_id *aux_dev_id) { @@ -449,6 +551,7 @@ static int intel_dg_spi_probe(struct auxiliary_device *aux_dev, if (!spi) return -ENOMEM; + mutex_init(&spi->lock); kref_init(&spi->refcnt); spi->nregions = nregions; @@ -481,6 +584,12 @@ static int intel_dg_spi_probe(struct auxiliary_device *aux_dev, goto err; } + ret = intel_dg_spi_init_mtd(spi, device, ret, ispi->writeable_override); + if (ret) { + dev_err(device, "failed init mtd %d\n", ret); + goto err; + } + dev_set_drvdata(&aux_dev->dev, spi); return 0; @@ -497,6 +606,8 @@ static void intel_dg_spi_remove(struct auxiliary_device *aux_dev) if (!spi) return; + mtd_device_unregister(&spi->mtd); + dev_set_drvdata(&aux_dev->dev, NULL); kref_put(&spi->refcnt, intel_dg_spi_release);