2021-10-09 11:51:50

by Alistair Francis

[permalink] [raw]
Subject: [PATCH v12 00/10] Add support for the silergy,sy7636a

v12:
- Rebase
v11:
- Address comments on hwmon
- Improve "mfd: simple-mfd-i2c: Add a Kconfig name" commit message
v10:
- Use dev_get_regmap() instead of dev_get_drvdata()
v9:
- Convert to use the simple-mfd-i2c instead

Alistair Francis (10):
dt-bindings: mfd: Initial commit of silergy,sy7636a.yaml
mfd: simple-mfd-i2c: Add a Kconfig name
mfd: simple-mfd-i2c: Enable support for the silergy,sy7636a
regulator: sy7636a: Remove requirement on sy7636a mfd
thermal: sy7636a: Add thermal driver for sy7636a
hwmon: sy7636a: Add temperature driver for sy7636a
ARM: imx_v6_v7_defconfig: Enable silergy,sy7636a
ARM: dts: imx7d: remarkable2: Enable silergy,sy7636a
ARM: imx_v6_v7_defconfig: Enable backlight class devices
ARM: dts: imx7d: remarkable2: Enable lcdif

.../bindings/mfd/silergy,sy7636a.yaml | 79 ++++++++++++
arch/arm/boot/dts/imx7d-remarkable2.dts | 115 ++++++++++++++++++
arch/arm/configs/imx_v6_v7_defconfig | 5 +
drivers/hwmon/Kconfig | 10 ++
drivers/hwmon/Makefile | 1 +
drivers/hwmon/sy7636a-hwmon.c | 77 ++++++++++++
drivers/mfd/Kconfig | 2 +-
drivers/mfd/simple-mfd-i2c.c | 12 ++
drivers/regulator/Kconfig | 1 -
drivers/regulator/sy7636a-regulator.c | 2 +-
drivers/thermal/Kconfig | 6 +
drivers/thermal/Makefile | 1 +
drivers/thermal/sy7636a_thermal.c | 94 ++++++++++++++
include/linux/mfd/sy7636a.h | 41 +++++++
14 files changed, 443 insertions(+), 3 deletions(-)
create mode 100644 Documentation/devicetree/bindings/mfd/silergy,sy7636a.yaml
create mode 100644 drivers/hwmon/sy7636a-hwmon.c
create mode 100644 drivers/thermal/sy7636a_thermal.c
create mode 100644 include/linux/mfd/sy7636a.h

--
2.31.1


2021-10-09 11:52:43

by Alistair Francis

[permalink] [raw]
Subject: [PATCH v12 01/10] dt-bindings: mfd: Initial commit of silergy,sy7636a.yaml

Initial support for the Silergy SY7636A Power Management chip
and regulator.

Signed-off-by: Alistair Francis <[email protected]>
Reviewed-by: Rob Herring <[email protected]>
---
.../bindings/mfd/silergy,sy7636a.yaml | 79 +++++++++++++++++++
1 file changed, 79 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mfd/silergy,sy7636a.yaml

diff --git a/Documentation/devicetree/bindings/mfd/silergy,sy7636a.yaml b/Documentation/devicetree/bindings/mfd/silergy,sy7636a.yaml
new file mode 100644
index 000000000000..0566f9498e2f
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/silergy,sy7636a.yaml
@@ -0,0 +1,79 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/silergy,sy7636a.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: silergy sy7636a PMIC
+
+maintainers:
+ - Alistair Francis <[email protected]>
+
+properties:
+ compatible:
+ const: silergy,sy7636a
+
+ reg:
+ description:
+ I2C device address.
+ maxItems: 1
+
+ "#address-cells":
+ const: 1
+
+ "#size-cells":
+ const: 0
+
+ '#thermal-sensor-cells':
+ const: 0
+
+ epd-pwr-good-gpios:
+ description:
+ Specifying the power good GPIOs.
+ maxItems: 1
+
+ regulators:
+ type: object
+
+ properties:
+ compatible:
+ const: silergy,sy7636a-regulator
+
+ vcom:
+ type: object
+ $ref: /schemas/regulator/regulator.yaml#
+ properties:
+ regulator-name:
+ const: vcom
+
+ additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - '#thermal-sensor-cells'
+
+additionalProperties: false
+
+examples:
+ - |
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pmic@62 {
+ compatible = "silergy,sy7636a";
+ reg = <0x62>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_epdpmic>;
+ #thermal-sensor-cells = <0>;
+
+ regulators {
+ reg_epdpmic: vcom {
+ regulator-name = "vcom";
+ regulator-boot-on;
+ };
+ };
+ };
+ };
+...
--
2.31.1

2021-10-09 11:53:00

by Alistair Francis

[permalink] [raw]
Subject: [PATCH v12 02/10] mfd: simple-mfd-i2c: Add a Kconfig name

Add a Kconfig name to the "Simple Multi-Functional Device support (I2C)"
device so that it can be enabled via menuconfig.

Signed-off-by: Alistair Francis <[email protected]>
---
drivers/mfd/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index ca0edab91aeb..e465ddd9ee77 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1192,7 +1192,7 @@ config MFD_SI476X_CORE
module will be called si476x-core.

config MFD_SIMPLE_MFD_I2C
- tristate
+ tristate "Simple Multi-Functional Device support (I2C)"
depends on I2C
select REGMAP_I2C
help
--
2.31.1

2021-10-09 11:53:03

by Alistair Francis

[permalink] [raw]
Subject: [PATCH 3/7] capsules: symmetric_encryption/aes: Reduce code size

From: Alistair Francis <[email protected]>

Signed-off-by: Alistair Francis <[email protected]>
---
capsules/src/symmetric_encryption/aes.rs | 587 ++++++++++++-----------
1 file changed, 300 insertions(+), 287 deletions(-)

diff --git a/capsules/src/symmetric_encryption/aes.rs b/capsules/src/symmetric_encryption/aes.rs
index ed3bf74e6..1aa736ce0 100644
--- a/capsules/src/symmetric_encryption/aes.rs
+++ b/capsules/src/symmetric_encryption/aes.rs
@@ -90,21 +90,25 @@ impl<'a, A: AES128<'static> + AES128Ctr + AES128CBC + AES128ECB + AES128CCM<'sta
key[..static_buffer_len]
.copy_to_slice(&mut buf[..static_buffer_len]);

- match app.aes_operation.as_ref().unwrap() {
- AesOperation::AES128Ctr(_)
- | AesOperation::AES128CBC(_)
- | AesOperation::AES128ECB(_) => {
- if let Err(e) = AES128::set_key(self.aes, buf) {
- return Err(e);
+ if let Some(op) = app.aes_operation.as_ref() {
+ match op {
+ AesOperation::AES128Ctr(_)
+ | AesOperation::AES128CBC(_)
+ | AesOperation::AES128ECB(_) => {
+ if let Err(e) = AES128::set_key(self.aes, buf) {
+ return Err(e);
+ }
+ Ok(())
}
- Ok(())
- }
- AesOperation::AES128CCM(_) => {
- if let Err(e) = AES128CCM::set_key(self.aes, buf) {
- return Err(e);
+ AesOperation::AES128CCM(_) => {
+ if let Err(e) = AES128CCM::set_key(self.aes, buf) {
+ return Err(e);
+ }
+ Ok(())
}
- Ok(())
}
+ } else {
+ Err(ErrorCode::FAIL)
}
})
})
@@ -125,21 +129,25 @@ impl<'a, A: AES128<'static> + AES128Ctr + AES128CBC + AES128ECB + AES128CCM<'sta
iv[..static_buffer_len]
.copy_to_slice(&mut buf[..static_buffer_len]);

- match app.aes_operation.as_ref().unwrap() {
- AesOperation::AES128Ctr(_)
- | AesOperation::AES128CBC(_)
- | AesOperation::AES128ECB(_) => {
- if let Err(e) = self.aes.set_iv(buf) {
- return Err(e);
+ if let Some(op) = app.aes_operation.as_ref() {
+ match op {
+ AesOperation::AES128Ctr(_)
+ | AesOperation::AES128CBC(_)
+ | AesOperation::AES128ECB(_) => {
+ if let Err(e) = self.aes.set_iv(buf) {
+ return Err(e);
+ }
+ Ok(())
}
- Ok(())
- }
- AesOperation::AES128CCM(_) => {
- if let Err(e) = self.aes.set_nonce(&buf[0..13]) {
- return Err(e);
+ AesOperation::AES128CCM(_) => {
+ if let Err(e) = self.aes.set_nonce(&buf[0..13]) {
+ return Err(e);
+ }
+ Ok(())
}
- Ok(())
}
+ } else {
+ Err(ErrorCode::FAIL)
}
})
})
@@ -149,58 +157,65 @@ impl<'a, A: AES128<'static> + AES128Ctr + AES128CBC + AES128ECB + AES128CCM<'sta
.enter(|source| {
let mut static_buffer_len = 0;

- match app.aes_operation.as_ref().unwrap() {
- AesOperation::AES128Ctr(_)
- | AesOperation::AES128CBC(_)
- | AesOperation::AES128ECB(_) => {
- self.source_buffer.map_or(Err(ErrorCode::NOMEM), |buf| {
- // Determine the size of the static buffer we have
- static_buffer_len = buf.len();
+ if let Some(op) = app.aes_operation.as_ref() {
+ match op {
+ AesOperation::AES128Ctr(_)
+ | AesOperation::AES128CBC(_)
+ | AesOperation::AES128ECB(_) => {
+ self.source_buffer.map_or(
+ Err(ErrorCode::NOMEM),
+ |buf| {
+ // Determine the size of the static buffer we have
+ static_buffer_len = buf.len();

- if static_buffer_len > source.len() {
- static_buffer_len = source.len()
- }
+ if static_buffer_len > source.len() {
+ static_buffer_len = source.len()
+ }

- // Copy the data into the static buffer
- source[..static_buffer_len]
- .copy_to_slice(&mut buf[..static_buffer_len]);
+ // Copy the data into the static buffer
+ source[..static_buffer_len]
+ .copy_to_slice(&mut buf[..static_buffer_len]);

- self.data_copied.set(static_buffer_len);
+ self.data_copied.set(static_buffer_len);

- Ok(())
- })?;
- }
- AesOperation::AES128CCM(_) => {
- self.dest_buffer.map_or(Err(ErrorCode::NOMEM), |buf| {
- // Determine the size of the static buffer we have
- static_buffer_len = buf.len();
+ Ok(())
+ },
+ )?;
+ }
+ AesOperation::AES128CCM(_) => {
+ self.dest_buffer.map_or(Err(ErrorCode::NOMEM), |buf| {
+ // Determine the size of the static buffer we have
+ static_buffer_len = buf.len();

- if static_buffer_len > source.len() {
- static_buffer_len = source.len()
- }
+ if static_buffer_len > source.len() {
+ static_buffer_len = source.len()
+ }

- // Copy the data into the static buffer
- source[..static_buffer_len]
- .copy_to_slice(&mut buf[..static_buffer_len]);
+ // Copy the data into the static buffer
+ source[..static_buffer_len]
+ .copy_to_slice(&mut buf[..static_buffer_len]);

- self.data_copied.set(static_buffer_len);
+ self.data_copied.set(static_buffer_len);

- Ok(())
- })?;
+ Ok(())
+ })?;
+ }
}
- }

- if let Err(e) = self.calculate_output(
- app.aes_operation.as_ref().unwrap(),
- app.aoff.get(),
- app.moff.get(),
- app.mlen.get(),
- app.mic_len.get(),
- app.confidential.get(),
- ) {
- return Err(e);
+ if let Err(e) = self.calculate_output(
+ op,
+ app.aoff.get(),
+ app.moff.get(),
+ app.mlen.get(),
+ app.mic_len.get(),
+ app.confidential.get(),
+ ) {
+ return Err(e);
+ }
+ Ok(())
+ } else {
+ Err(ErrorCode::FAIL)
}
- Ok(())
})
.unwrap_or(Err(ErrorCode::RESERVE))?;

@@ -223,40 +238,49 @@ impl<'a, A: AES128<'static> + AES128Ctr + AES128CBC + AES128ECB + AES128CCM<'sta
AesOperation::AES128Ctr(_)
| AesOperation::AES128CBC(_)
| AesOperation::AES128ECB(_) => {
- if let Some((e, source, dest)) = AES128::crypt(
- self.aes,
- Some(self.source_buffer.take().unwrap()),
- self.dest_buffer.take().unwrap(),
- 0,
- AES128_BLOCK_SIZE,
- ) {
- // Error, clear the appid and data
- self.aes.disable();
- self.appid.clear();
- self.source_buffer.replace(source.unwrap());
- self.dest_buffer.replace(dest);
+ if let Some(dest_buf) = self.dest_buffer.take() {
+ if let Some((e, source, dest)) = AES128::crypt(
+ self.aes,
+ self.source_buffer.take(),
+ dest_buf,
+ 0,
+ AES128_BLOCK_SIZE,
+ ) {
+ // Error, clear the appid and data
+ self.aes.disable();
+ self.appid.clear();
+ if let Some(source_buf) = source {
+ self.source_buffer.replace(source_buf);
+ }
+ self.dest_buffer.replace(dest);

- return e;
+ return e;
+ }
+ } else {
+ return Err(ErrorCode::FAIL);
}
}
AesOperation::AES128CCM(encrypting) => {
- let buf = self.dest_buffer.take().unwrap();
- if let Err((e, dest)) = AES128CCM::crypt(
- self.aes,
- buf,
- aoff,
- moff,
- mlen,
- mic_len,
- confidential,
- *encrypting,
- ) {
- // Error, clear the appid and data
- self.aes.disable();
- self.appid.clear();
- self.dest_buffer.replace(dest);
+ if let Some(buf) = self.dest_buffer.take() {
+ if let Err((e, dest)) = AES128CCM::crypt(
+ self.aes,
+ buf,
+ aoff,
+ moff,
+ mlen,
+ mic_len,
+ confidential,
+ *encrypting,
+ ) {
+ // Error, clear the appid and data
+ self.aes.disable();
+ self.appid.clear();
+ self.dest_buffer.replace(dest);

- return Err(e);
+ return Err(e);
+ }
+ } else {
+ return Err(ErrorCode::FAIL);
}
}
}
@@ -291,7 +315,9 @@ impl<'a, A: AES128<'static> + AES128Ctr + AES128CBC + AES128ECB + AES128CCM<'sta
Client<'static> for AesDriver<'static, A>
{
fn crypt_done(&'a self, source: Option<&'static mut [u8]>, destination: &'static mut [u8]) {
- self.source_buffer.replace(source.unwrap());
+ if let Some(source_buf) = source {
+ self.source_buffer.replace(source_buf);
+ }
self.dest_buffer.replace(destination);

self.appid.map(|id| {
@@ -384,22 +410,24 @@ impl<'a, A: AES128<'static> + AES128Ctr + AES128CBC + AES128ECB + AES128CCM<'sta
// Update the amount of data copied
self.data_copied.set(copied_data + static_buffer_len);

- if self
- .calculate_output(
- app.aes_operation.as_ref().unwrap(),
- app.aoff.get(),
- app.moff.get(),
- app.mlen.get(),
- app.mic_len.get(),
- app.confidential.get(),
- )
- .is_err()
- {
- // Error, clear the appid and data
- self.aes.disable();
- self.appid.clear();
- self.check_queue();
- return;
+ if let Some(op) = app.aes_operation.as_ref() {
+ if self
+ .calculate_output(
+ op,
+ app.aoff.get(),
+ app.moff.get(),
+ app.mlen.get(),
+ app.mic_len.get(),
+ app.confidential.get(),
+ )
+ .is_err()
+ {
+ // Error, clear the appid and data
+ self.aes.disable();
+ self.appid.clear();
+ self.check_queue();
+ return;
+ }
}

// Return as we don't want to run the digest yet
@@ -526,40 +554,35 @@ impl<'a, A: AES128<'static> + AES128Ctr + AES128CBC + AES128ECB + AES128CCM<'sta
allow_num: usize,
mut slice: ReadOnlyProcessBuffer,
) -> Result<ReadOnlyProcessBuffer, (ReadOnlyProcessBuffer, ErrorCode)> {
- let res = match allow_num {
- // Pass buffer for the key to be in
- 0 => self
- .apps
- .enter(appid, |app, _| {
- mem::swap(&mut app.key, &mut slice);
- Ok(())
- })
- .unwrap_or(Err(ErrorCode::FAIL)),
-
- // Pass buffer for the IV to be in
- // This also contains the nonce when doing AES CCM
- 1 => self
- .apps
- .enter(appid, |app, _| {
- mem::swap(&mut app.iv, &mut slice);
- Ok(())
- })
- .unwrap_or(Err(ErrorCode::FAIL)),
+ let res = self
+ .apps
+ .enter(appid, |app, _| {
+ match allow_num {
+ // Pass buffer for the key to be in
+ 0 => {
+ mem::swap(&mut app.key, &mut slice);
+ Ok(())
+ }

- // Pass buffer for the source to be in
- // If doing a CCM operation also set the mlen
- 2 => self
- .apps
- .enter(appid, |app, _| {
- mem::swap(&mut app.source, &mut slice);
- app.mlen.set(app.source.len());
- Ok(())
- })
- .unwrap_or(Err(ErrorCode::FAIL)),
+ // Pass buffer for the IV to be in
+ // This also contains the nonce when doing AES CCM
+ 1 => {
+ mem::swap(&mut app.iv, &mut slice);
+ Ok(())
+ }
+ // Pass buffer for the source to be in
+ // If doing a CCM operation also set the mlen
+ 2 => {
+ mem::swap(&mut app.source, &mut slice);
+ app.mlen.set(app.source.len());
+ Ok(())
+ }

- // default
- _ => Err(ErrorCode::NOSUPPORT),
- };
+ // default
+ _ => Err(ErrorCode::NOSUPPORT),
+ }
+ })
+ .unwrap_or(Err(ErrorCode::FAIL));

match res {
Ok(()) => Ok(slice),
@@ -622,77 +645,76 @@ impl<'a, A: AES128<'static> + AES128Ctr + AES128CBC + AES128ECB + AES128CCM<'sta
}
});

- match command_num {
- // check if present
- 0 => CommandReturn::success(),
+ // Try the commands where we want to start an operation *not* entered in
+ // an app grant first.
+ if match_or_empty_or_nonexistant
+ && (command_num == 2 || command_num == 2 || command_num == 4)
+ {
+ if command_num == 2 {
+ self.appid.set(appid);
+ let ret = self.run();

- // set_algorithm
- 1 => self
- .apps
- .enter(appid, |app, _| match data1 {
- 0 => {
- app.aes_operation = Some(AesOperation::AES128Ctr(data2 != 0));
- CommandReturn::success()
- }
- 1 => {
- app.aes_operation = Some(AesOperation::AES128CBC(data2 != 0));
- CommandReturn::success()
- }
- 2 => {
- app.aes_operation = Some(AesOperation::AES128ECB(data2 != 0));
- CommandReturn::success()
- }
- 3 => {
- app.aes_operation = Some(AesOperation::AES128CCM(data2 != 0));
- CommandReturn::success()
- }
- _ => CommandReturn::failure(ErrorCode::NOSUPPORT),
- })
- .unwrap_or_else(|err| err.into()),
+ return if let Err(e) = ret {
+ self.aes.disable();
+ self.appid.clear();
+ self.check_queue();
+ CommandReturn::failure(e)
+ } else {
+ CommandReturn::success()
+ };
+ }
+ }

- // setup
- // Copy in the key and IV and run the first encryption operation
- // This will trigger a callback
- 2 => {
- if match_or_empty_or_nonexistant {
- self.appid.set(appid);
- let ret = self.run();
+ let ret = self
+ .apps
+ .enter(appid, |app, upcalls| {
+ match command_num {
+ // check if present
+ 0 => CommandReturn::success(),
+
+ // set_algorithm
+ 1 => match data1 {
+ 0 => {
+ app.aes_operation = Some(AesOperation::AES128Ctr(data2 != 0));
+ CommandReturn::success()
+ }
+ 1 => {
+ app.aes_operation = Some(AesOperation::AES128CBC(data2 != 0));
+ CommandReturn::success()
+ }
+ 2 => {
+ app.aes_operation = Some(AesOperation::AES128ECB(data2 != 0));
+ CommandReturn::success()
+ }
+ 3 => {
+ app.aes_operation = Some(AesOperation::AES128CCM(data2 != 0));
+ CommandReturn::success()
+ }
+ _ => CommandReturn::failure(ErrorCode::NOSUPPORT),
+ },

- if let Err(e) = ret {
- self.aes.disable();
- self.appid.clear();
- self.check_queue();
- CommandReturn::failure(e)
- } else {
- CommandReturn::success()
+ // setup
+ // Copy in the key and IV and run the first encryption operation
+ // This will trigger a callback
+ 2 => {
+ // Some app is using the storage, we must wait.
+ if app.pending_run_app.is_some() {
+ // No more room in the queue, nowhere to store this
+ // request.
+ CommandReturn::failure(ErrorCode::NOMEM)
+ } else {
+ // We can store this, so lets do it.
+ app.pending_run_app = Some(appid);
+ CommandReturn::success()
+ }
}
- } else {
- // There is an active app, so queue this request (if possible).
- self.apps
- .enter(appid, |app, _| {
- // Some app is using the storage, we must wait.
- if app.pending_run_app.is_some() {
- // No more room in the queue, nowhere to store this
- // request.
- CommandReturn::failure(ErrorCode::NOMEM)
- } else {
- // We can store this, so lets do it.
- app.pending_run_app = Some(appid);
- CommandReturn::success()
- }
- })
- .unwrap_or_else(|err| err.into())
- }
- }

- // crypt
- // Generate the encrypted output
- // Multiple calls to crypt will re-use the existing state
- // This will trigger a callback
- 3 => {
- if app_match {
- self.apps
- .enter(appid, |app, upcalls| {
+ // crypt
+ // Generate the encrypted output
+ // Multiple calls to crypt will re-use the existing state
+ // This will trigger a callback
+ 3 => {
+ if app_match {
if let Err(e) = app
.source
.enter(|source| {
@@ -714,17 +736,21 @@ impl<'a, A: AES128<'static> + AES128Ctr + AES128CBC + AES128ECB + AES128CCM<'sta
Ok(())
})?;

- if let Err(e) = self.calculate_output(
- app.aes_operation.as_ref().unwrap(),
- app.aoff.get(),
- app.moff.get(),
- app.mlen.get(),
- app.mic_len.get(),
- app.confidential.get(),
- ) {
- return Err(e);
+ if let Some(op) = app.aes_operation.as_ref() {
+ if let Err(e) = self.calculate_output(
+ op,
+ app.aoff.get(),
+ app.moff.get(),
+ app.mlen.get(),
+ app.mic_len.get(),
+ app.confidential.get(),
+ ) {
+ return Err(e);
+ }
+ Ok(())
+ } else {
+ Err(ErrorCode::FAIL)
}
- Ok(())
})
.unwrap_or(Err(ErrorCode::RESERVE))
{
@@ -735,87 +761,74 @@ impl<'a, A: AES128<'static> + AES128Ctr + AES128CBC + AES128ECB + AES128CCM<'sta
)
.ok();
}
- })
- .unwrap();
- CommandReturn::success()
- } else {
- // We don't queue this request, the user has to call
- // `setup` first.
- CommandReturn::failure(ErrorCode::OFF)
- }
- }
+ CommandReturn::success()
+ } else {
+ // We don't queue this request, the user has to call
+ // `setup` first.
+ CommandReturn::failure(ErrorCode::OFF)
+ }
+ }

- // Finish
- // Complete the operation and reset the AES
- // This will not trigger a callback and will not process any data from userspace
- 4 => {
- if app_match {
- self.apps
- .enter(appid, |_app, _upcalls| {
+ // Finish
+ // Complete the operation and reset the AES
+ // This will not trigger a callback and will not process any data from userspace
+ 4 => {
+ if app_match {
self.aes.disable();
self.appid.clear();
- })
- .unwrap();
- self.check_queue();
- CommandReturn::success()
- } else {
- // We don't queue this request, the user has to call
- // `setup` first.
- CommandReturn::failure(ErrorCode::OFF)
- }
- }

- // Set aoff for CCM
- // This will not trigger a callback and will not process any data from userspace
- 5 => {
- self.apps
- .enter(appid, |app, _upcalls| {
+ CommandReturn::success()
+ } else {
+ // We don't queue this request, the user has to call
+ // `setup` first.
+ CommandReturn::failure(ErrorCode::OFF)
+ }
+ }
+
+ // Set aoff for CCM
+ // This will not trigger a callback and will not process any data from userspace
+ 5 => {
app.aoff.set(data1);
- })
- .unwrap();
- self.check_queue();
- CommandReturn::success()
- }
+ CommandReturn::success()
+ }

- // Set moff for CCM
- // This will not trigger a callback and will not process any data from userspace
- 6 => {
- self.apps
- .enter(appid, |app, _upcalls| {
+ // Set moff for CCM
+ // This will not trigger a callback and will not process any data from userspace
+ 6 => {
app.moff.set(data1);
- })
- .unwrap();
- self.check_queue();
- CommandReturn::success()
- }
+ CommandReturn::success()
+ }

- // Set mic_len for CCM
- // This will not trigger a callback and will not process any data from userspace
- 7 => {
- self.apps
- .enter(appid, |app, _upcalls| {
+ // Set mic_len for CCM
+ // This will not trigger a callback and will not process any data from userspace
+ 7 => {
app.mic_len.set(data1);
- })
- .unwrap();
- self.check_queue();
- CommandReturn::success()
- }
+ CommandReturn::success()
+ }

- // Set confidential boolean for CCM
- // This will not trigger a callback and will not process any data from userspace
- 8 => {
- self.apps
- .enter(appid, |app, _upcalls| {
+ // Set confidential boolean for CCM
+ // This will not trigger a callback and will not process any data from userspace
+ 8 => {
app.confidential.set(data1 > 0);
- })
- .unwrap();
- self.check_queue();
- CommandReturn::success()
- }
+ CommandReturn::success()
+ }

- // default
- _ => CommandReturn::failure(ErrorCode::NOSUPPORT),
+ // default
+ _ => CommandReturn::failure(ErrorCode::NOSUPPORT),
+ }
+ })
+ .unwrap_or_else(|err| err.into());
+
+ if command_num == 4
+ || command_num == 5
+ || command_num == 6
+ || command_num == 7
+ || command_num == 8
+ {
+ self.check_queue();
}
+
+ ret
}

fn allocate_grant(&self, processid: ProcessId) -> Result<(), kernel::process::Error> {
--
2.31.1

2021-10-09 11:53:15

by Alistair Francis

[permalink] [raw]
Subject: [PATCH 4/7] capsules: sha: Continue reducing code size

From: Alistair Francis <[email protected]>

Signed-off-by: Alistair Francis <[email protected]>
---
capsules/src/sha.rs | 39 +++++++++++++++++++--------------------
1 file changed, 19 insertions(+), 20 deletions(-)

diff --git a/capsules/src/sha.rs b/capsules/src/sha.rs
index a296bc6bc..0d2667e22 100644
--- a/capsules/src/sha.rs
+++ b/capsules/src/sha.rs
@@ -443,28 +443,27 @@ impl<
allow_num: usize,
mut slice: ReadOnlyProcessBuffer,
) -> Result<ReadOnlyProcessBuffer, (ReadOnlyProcessBuffer, ErrorCode)> {
- let res = match allow_num {
- // Pass buffer for the data to be in
- 1 => self
- .apps
- .enter(appid, |app, _| {
- mem::swap(&mut app.data, &mut slice);
- Ok(())
- })
- .unwrap_or(Err(ErrorCode::FAIL)),
+ let res = self
+ .apps
+ .enter(appid, |app, _| {
+ match allow_num {
+ // Pass buffer for the data to be in
+ 1 => {
+ mem::swap(&mut app.data, &mut slice);
+ Ok(())
+ }

- // Compare buffer for verify
- 2 => self
- .apps
- .enter(appid, |app, _| {
- mem::swap(&mut app.compare, &mut slice);
- Ok(())
- })
- .unwrap_or(Err(ErrorCode::FAIL)),
+ // Compare buffer for verify
+ 2 => {
+ mem::swap(&mut app.compare, &mut slice);
+ Ok(())
+ }

- // default
- _ => Err(ErrorCode::NOSUPPORT),
- };
+ // default
+ _ => Err(ErrorCode::NOSUPPORT),
+ }
+ })
+ .unwrap_or(Err(ErrorCode::FAIL));

match res {
Ok(()) => Ok(slice),
--
2.31.1

2021-10-09 11:53:30

by Alistair Francis

[permalink] [raw]
Subject: [PATCH 5/7] capsules: hmac: Continue reducing code size

From: Alistair Francis <[email protected]>

Signed-off-by: Alistair Francis <[email protected]>
---
capsules/src/hmac.rs | 52 ++++++++++++++++++++------------------------
1 file changed, 24 insertions(+), 28 deletions(-)

diff --git a/capsules/src/hmac.rs b/capsules/src/hmac.rs
index 83d1e5ea5..0ea30635b 100644
--- a/capsules/src/hmac.rs
+++ b/capsules/src/hmac.rs
@@ -478,37 +478,33 @@ impl<
allow_num: usize,
mut slice: ReadOnlyProcessBuffer,
) -> Result<ReadOnlyProcessBuffer, (ReadOnlyProcessBuffer, ErrorCode)> {
- let res = match allow_num {
- // Pass buffer for the key to be in
- 0 => self
- .apps
- .enter(appid, |app, _| {
- mem::swap(&mut app.key, &mut slice);
- Ok(())
- })
- .unwrap_or(Err(ErrorCode::FAIL)),
+ let res = self
+ .apps
+ .enter(appid, |app, _| {
+ match allow_num {
+ // Pass buffer for the key to be in
+ 0 => {
+ mem::swap(&mut app.key, &mut slice);
+ Ok(())
+ }

- // Pass buffer for the data to be in
- 1 => self
- .apps
- .enter(appid, |app, _| {
- mem::swap(&mut app.data, &mut slice);
- Ok(())
- })
- .unwrap_or(Err(ErrorCode::FAIL)),
+ // Pass buffer for the data to be in
+ 1 => {
+ mem::swap(&mut app.data, &mut slice);
+ Ok(())
+ }

- // Compare buffer for verify
- 2 => self
- .apps
- .enter(appid, |app, _| {
- mem::swap(&mut app.compare, &mut slice);
- Ok(())
- })
- .unwrap_or(Err(ErrorCode::FAIL)),
+ // Compare buffer for verify
+ 2 => {
+ mem::swap(&mut app.compare, &mut slice);
+ Ok(())
+ }

- // default
- _ => Err(ErrorCode::NOSUPPORT),
- };
+ // default
+ _ => Err(ErrorCode::NOSUPPORT),
+ }
+ })
+ .unwrap_or(Err(ErrorCode::FAIL));

match res {
Ok(()) => Ok(slice),
--
2.31.1

2021-10-09 11:53:37

by Alistair Francis

[permalink] [raw]
Subject: [PATCH v12 09/10] ARM: imx_v6_v7_defconfig: Enable backlight class devices

The BACKLIGHT_CLASS_DEVICE config is required for the already enabled
DRM_SIMPLE_PANEL to work so let's enable BACKLIGHT_CLASS_DEVICE.

This allows the mxsfb probe to complete successfully on the reMarkable
2.

Signed-off-by: Alistair Francis <[email protected]>
---
arch/arm/configs/imx_v6_v7_defconfig | 1 +
1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index 507ab17cfcd8..6b3744e6379b 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -300,6 +300,7 @@ CONFIG_FB_MODE_HELPERS=y
CONFIG_LCD_CLASS_DEVICE=y
CONFIG_LCD_L4F00242T03=y
CONFIG_LCD_PLATFORM=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
CONFIG_BACKLIGHT_PWM=y
CONFIG_BACKLIGHT_GPIO=y
CONFIG_FRAMEBUFFER_CONSOLE=y
--
2.31.1

2021-10-09 11:53:44

by Alistair Francis

[permalink] [raw]
Subject: [PATCH v12 06/10] hwmon: sy7636a: Add temperature driver for sy7636a

This is a multi-function device to interface with the sy7636a
EPD PMIC chip from Silergy.

Signed-off-by: Alistair Francis <[email protected]>
---
arch/arm/configs/imx_v6_v7_defconfig | 1 +
drivers/hwmon/Kconfig | 10 ++++
drivers/hwmon/Makefile | 1 +
drivers/hwmon/sy7636a-hwmon.c | 77 ++++++++++++++++++++++++++++
4 files changed, 89 insertions(+)
create mode 100644 drivers/hwmon/sy7636a-hwmon.c

diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index 8a54a4d0181a..b87adf823e44 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -228,6 +228,7 @@ CONFIG_RN5T618_POWER=m
CONFIG_SENSORS_MC13783_ADC=y
CONFIG_SENSORS_GPIO_FAN=y
CONFIG_SENSORS_IIO_HWMON=y
+CONFIG_SENSORS_SY7636A=y
CONFIG_THERMAL_STATISTICS=y
CONFIG_THERMAL_WRITABLE_TRIPS=y
CONFIG_CPU_THERMAL=y
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index c4578e8f34bb..59f358293202 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1651,6 +1651,16 @@ config SENSORS_SIS5595
This driver can also be built as a module. If so, the module
will be called sis5595.

+config SENSORS_SY7636A
+ tristate "Silergy SY7636A"
+ depends on I2C
+ help
+ If you say yes here you get support for the thermistor readout of
+ the Silergy SY7636A PMIC.
+
+ This driver can also be built as a module. If so, the module
+ will be called sy7636a-hwmon.
+
config SENSORS_DME1737
tristate "SMSC DME1737, SCH311x and compatibles"
depends on I2C && !PPC
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 162940270661..1355ffdb1481 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -181,6 +181,7 @@ obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o
obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o
obj-$(CONFIG_SENSORS_SPARX5) += sparx5-temp.o
obj-$(CONFIG_SENSORS_STTS751) += stts751.o
+obj-$(CONFIG_SENSORS_SY7636A) += sy7636a-hwmon.o
obj-$(CONFIG_SENSORS_AMC6821) += amc6821.o
obj-$(CONFIG_SENSORS_TC74) += tc74.o
obj-$(CONFIG_SENSORS_THMC50) += thmc50.o
diff --git a/drivers/hwmon/sy7636a-hwmon.c b/drivers/hwmon/sy7636a-hwmon.c
new file mode 100644
index 000000000000..e0204278339b
--- /dev/null
+++ b/drivers/hwmon/sy7636a-hwmon.c
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Functions to access SY3686A power management chip temperature
+ *
+ * Copyright (C) 2019 reMarkable AS - http://www.remarkable.com/
+ *
+ * Authors: Lars Ivar Miljeteig <[email protected]>
+ * Alistair Francis <[email protected]>
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/sysfs.h>
+#include <linux/platform_device.h>
+
+#include <linux/mfd/sy7636a.h>
+
+static ssize_t show_temp(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned int reg_val;
+ struct regmap *regmap = dev_get_drvdata(dev);
+ int ret;
+
+ ret = regmap_read(regmap,
+ SY7636A_REG_TERMISTOR_READOUT, &reg_val);
+ if (ret)
+ return ret;
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", reg_val);
+}
+
+static SENSOR_DEVICE_ATTR(temp0, 0444, show_temp, NULL, 0);
+
+static struct attribute *sy7636a_attrs[] = {
+ &sensor_dev_attr_temp0.dev_attr.attr,
+ NULL
+};
+
+ATTRIBUTE_GROUPS(sy7636a);
+
+static int sy7636a_sensor_probe(struct platform_device *pdev)
+{
+ struct regmap *regmap = dev_get_regmap(pdev->dev.parent, NULL);
+ struct device *hwmon_dev;
+ int err;
+
+ if (!regmap)
+ return -EPROBE_DEFER;
+
+ hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev,
+ "sy7636a_temperature", regmap, sy7636a_groups);
+
+ if (IS_ERR(hwmon_dev)) {
+ err = PTR_ERR(hwmon_dev);
+ dev_err(&pdev->dev, "Unable to register hwmon device, returned %d", err);
+ return err;
+ }
+
+ return 0;
+}
+
+static struct platform_driver sy7636a_sensor_driver = {
+ .probe = sy7636a_sensor_probe,
+ .driver = {
+ .name = "sy7636a-temperature",
+ },
+};
+module_platform_driver(sy7636a_sensor_driver);
+
+MODULE_DESCRIPTION("SY7636A sensor driver");
+MODULE_LICENSE("GPL");
--
2.31.1

2021-10-09 11:53:49

by Alistair Francis

[permalink] [raw]
Subject: [PATCH v12 04/10] regulator: sy7636a: Remove requirement on sy7636a mfd

Signed-off-by: Alistair Francis <[email protected]>
---
drivers/regulator/Kconfig | 1 -
drivers/regulator/sy7636a-regulator.c | 2 +-
2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 4fd13b06231f..21077cb14625 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -1199,7 +1199,6 @@ config REGULATOR_STW481X_VMMC

config REGULATOR_SY7636A
tristate "Silergy SY7636A voltage regulator"
- depends on MFD_SY7636A
help
This driver supports Silergy SY3686A voltage regulator.

diff --git a/drivers/regulator/sy7636a-regulator.c b/drivers/regulator/sy7636a-regulator.c
index 8360b3947ead..22fddf868e4c 100644
--- a/drivers/regulator/sy7636a-regulator.c
+++ b/drivers/regulator/sy7636a-regulator.c
@@ -70,7 +70,7 @@ static const struct regulator_desc desc = {

static int sy7636a_regulator_probe(struct platform_device *pdev)
{
- struct regmap *regmap = dev_get_drvdata(pdev->dev.parent);
+ struct regmap *regmap = dev_get_regmap(pdev->dev.parent, NULL);
struct regulator_config config = { };
struct regulator_dev *rdev;
struct gpio_desc *gdp;
--
2.31.1

2021-10-09 11:54:38

by Alistair Francis

[permalink] [raw]
Subject: [PATCH v12 08/10] ARM: dts: imx7d: remarkable2: Enable silergy,sy7636a

Enable the silergy,sy7636a and silergy,sy7636a-regulator on the
reMarkable2.

Signed-off-by: Alistair Francis <[email protected]>
---
arch/arm/boot/dts/imx7d-remarkable2.dts | 41 +++++++++++++++++++++++++
1 file changed, 41 insertions(+)

diff --git a/arch/arm/boot/dts/imx7d-remarkable2.dts b/arch/arm/boot/dts/imx7d-remarkable2.dts
index 2099784d6515..1b49c26816cd 100644
--- a/arch/arm/boot/dts/imx7d-remarkable2.dts
+++ b/arch/arm/boot/dts/imx7d-remarkable2.dts
@@ -87,6 +87,33 @@ wacom_digitizer: digitizer@9 {
};
};

+&i2c4 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_i2c4>;
+ pinctrl-1 = <&pinctrl_i2c4>;
+ status = "okay";
+
+ epd_pmic: sy7636a@62 {
+ compatible = "silergy,sy7636a";
+ reg = <0x62>;
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_epdpmic>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #thermal-sensor-cells = <0>;
+
+ epd-pwr-good-gpios = <&gpio6 21 GPIO_ACTIVE_HIGH>;
+ regulators {
+ reg_epdpmic: vcom {
+ regulator-name = "vcom";
+ regulator-boot-on;
+ };
+ };
+ };
+};
+
&snvs_pwrkey {
status = "okay";
};
@@ -180,6 +207,13 @@ MX7D_PAD_SAI1_TX_BCLK__GPIO6_IO13 0x14
>;
};

+ pinctrl_epdpmic: epdpmicgrp {
+ fsl,pins = <
+ MX7D_PAD_SAI2_RX_DATA__GPIO6_IO21 0x00000074
+ MX7D_PAD_ENET1_RGMII_TXC__GPIO7_IO11 0x00000014
+ >;
+ };
+
pinctrl_i2c1: i2c1grp {
fsl,pins = <
MX7D_PAD_I2C1_SDA__I2C1_SDA 0x4000007f
@@ -187,6 +221,13 @@ MX7D_PAD_I2C1_SCL__I2C1_SCL 0x4000007f
>;
};

+ pinctrl_i2c4: i2c4grp {
+ fsl,pins = <
+ MX7D_PAD_I2C4_SDA__I2C4_SDA 0x4000007f
+ MX7D_PAD_I2C4_SCL__I2C4_SCL 0x4000007f
+ >;
+ };
+
pinctrl_uart1: uart1grp {
fsl,pins = <
MX7D_PAD_UART1_TX_DATA__UART1_DCE_TX 0x79
--
2.31.1

2021-10-09 11:55:10

by Alistair Francis

[permalink] [raw]
Subject: [PATCH v12 03/10] mfd: simple-mfd-i2c: Enable support for the silergy,sy7636a

Signed-off-by: Alistair Francis <[email protected]>
Acked-for-MFD-by: Lee Jones <[email protected]>
---
drivers/mfd/simple-mfd-i2c.c | 12 +++++++++++
include/linux/mfd/sy7636a.h | 41 ++++++++++++++++++++++++++++++++++++
2 files changed, 53 insertions(+)
create mode 100644 include/linux/mfd/sy7636a.h

diff --git a/drivers/mfd/simple-mfd-i2c.c b/drivers/mfd/simple-mfd-i2c.c
index 51536691ad9d..fbc6d6aed6c0 100644
--- a/drivers/mfd/simple-mfd-i2c.c
+++ b/drivers/mfd/simple-mfd-i2c.c
@@ -62,8 +62,20 @@ static int simple_mfd_i2c_probe(struct i2c_client *i2c)
return ret;
}

+static const struct mfd_cell sy7636a_cells[] = {
+ { .name = "sy7636a-regulator", },
+ { .name = "sy7636a-temperature", },
+ { .name = "sy7636a-thermal", },
+};
+
+static const struct simple_mfd_data silergy_sy7636a = {
+ .mfd_cell = sy7636a_cells,
+ .mfd_cell_size = ARRAY_SIZE(sy7636a_cells),
+};
+
static const struct of_device_id simple_mfd_i2c_of_match[] = {
{ .compatible = "kontron,sl28cpld" },
+ { .compatible = "silergy,sy7636a", .data = &silergy_sy7636a},
{}
};
MODULE_DEVICE_TABLE(of, simple_mfd_i2c_of_match);
diff --git a/include/linux/mfd/sy7636a.h b/include/linux/mfd/sy7636a.h
new file mode 100644
index 000000000000..15caa54f0432
--- /dev/null
+++ b/include/linux/mfd/sy7636a.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Functions to access SY3686A power management chip.
+ *
+ * Copyright (C) 2021 reMarkable AS - http://www.remarkable.com/
+ */
+
+#ifndef __MFD_SY7636A_H
+#define __MFD_SY7636A_H
+
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+
+#define SY7636A_REG_OPERATION_MODE_CRL 0x00
+#define SY7636A_OPERATION_MODE_CRL_VCOMCTL BIT(6)
+#define SY7636A_OPERATION_MODE_CRL_ONOFF BIT(7)
+#define SY7636A_REG_VCOM_ADJUST_CTRL_L 0x01
+#define SY7636A_REG_VCOM_ADJUST_CTRL_H 0x02
+#define SY7636A_REG_VCOM_ADJUST_CTRL_MASK 0x01ff
+#define SY7636A_REG_VLDO_VOLTAGE_ADJULST_CTRL 0x03
+#define SY7636A_REG_POWER_ON_DELAY_TIME 0x06
+#define SY7636A_REG_FAULT_FLAG 0x07
+#define SY7636A_FAULT_FLAG_PG BIT(0)
+#define SY7636A_REG_TERMISTOR_READOUT 0x08
+
+#define SY7636A_REG_MAX 0x08
+
+#define VCOM_MIN 0
+#define VCOM_MAX 5000
+
+#define VCOM_ADJUST_CTRL_MASK 0x1ff
+// Used to shift the high byte
+#define VCOM_ADJUST_CTRL_SHIFT 8
+// Used to scale from VCOM_ADJUST_CTRL to mv
+#define VCOM_ADJUST_CTRL_SCAL 10000
+
+#define FAULT_FLAG_SHIFT 1
+
+#endif /* __LINUX_MFD_SY7636A_H */
--
2.31.1

2021-10-09 11:55:39

by Alistair Francis

[permalink] [raw]
Subject: [PATCH v12 05/10] thermal: sy7636a: Add thermal driver for sy7636a

Add thermal driver to enable kernel based polling
and shutdown of device for temperatures out of spec

Signed-off-by: Alistair Francis <[email protected]>
---
drivers/thermal/Kconfig | 6 ++
drivers/thermal/Makefile | 1 +
drivers/thermal/sy7636a_thermal.c | 94 +++++++++++++++++++++++++++++++
3 files changed, 101 insertions(+)
create mode 100644 drivers/thermal/sy7636a_thermal.c

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index d7f44deab5b1..6ee0e7de1b37 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -450,6 +450,12 @@ depends on (ARCH_STI || ARCH_STM32) && OF
source "drivers/thermal/st/Kconfig"
endmenu

+config SY7636A_THERMAL
+ tristate "SY7636A thermal management"
+ help
+ Enable the sy7636a thermal driver, which supports the
+ temperature sensor embedded in Silabs SY7636A IC.
+
source "drivers/thermal/tegra/Kconfig"

config GENERIC_ADC_THERMAL
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 82fc3e616e54..2e1aca8a0a09 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -51,6 +51,7 @@ obj-$(CONFIG_DA9062_THERMAL) += da9062-thermal.o
obj-y += intel/
obj-$(CONFIG_TI_SOC_THERMAL) += ti-soc-thermal/
obj-y += st/
+obj-$(CONFIG_SY7636A_THERMAL) += sy7636a_thermal.o
obj-$(CONFIG_QCOM_TSENS) += qcom/
obj-y += tegra/
obj-$(CONFIG_HISI_THERMAL) += hisi_thermal.o
diff --git a/drivers/thermal/sy7636a_thermal.c b/drivers/thermal/sy7636a_thermal.c
new file mode 100644
index 000000000000..9e58305ca3ce
--- /dev/null
+++ b/drivers/thermal/sy7636a_thermal.c
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Functions to access SY3686A power management chip temperature
+ *
+ * Copyright (C) 2019 reMarkable AS - http://www.remarkable.com/
+ *
+ * Authors: Lars Ivar Miljeteig <[email protected]>
+ * Alistair Francis <[email protected]>
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/thermal.h>
+
+#include <linux/mfd/sy7636a.h>
+
+static int sy7636a_get_temp(void *arg, int *res)
+{
+ unsigned int mode_ctr;
+ int ret, reg_val;
+ struct regmap *regmap = arg;
+ bool isVoltageActive;
+
+ ret = regmap_read(regmap,
+ SY7636A_REG_OPERATION_MODE_CRL, &mode_ctr);
+ if (ret)
+ return ret;
+
+ isVoltageActive = mode_ctr & SY7636A_OPERATION_MODE_CRL_ONOFF;
+
+ /* If operation mode isn't set to control, then let's set it. */
+ if (!isVoltageActive) {
+ ret = regmap_write(regmap,
+ SY7636A_REG_OPERATION_MODE_CRL,
+ mode_ctr | SY7636A_OPERATION_MODE_CRL_ONOFF);
+ if (ret)
+ return ret;
+ }
+
+ ret = regmap_read(regmap,
+ SY7636A_REG_TERMISTOR_READOUT, &reg_val);
+ if (ret)
+ return ret;
+
+ /* Restore the operation mode if it wasn't set */
+ if (!isVoltageActive) {
+ ret = regmap_write(regmap,
+ SY7636A_REG_OPERATION_MODE_CRL,
+ mode_ctr);
+ if (ret)
+ return ret;
+ }
+
+ *res = reg_val * 1000;
+
+ return ret;
+}
+
+static const struct thermal_zone_of_device_ops ops = {
+ .get_temp = sy7636a_get_temp,
+};
+
+static int sy7636a_thermal_probe(struct platform_device *pdev)
+{
+ struct regmap *regmap = dev_get_regmap(pdev->dev.parent, NULL);
+ struct thermal_zone_device *thermal_zone_dev;
+
+ thermal_zone_dev = devm_thermal_zone_of_sensor_register(
+ pdev->dev.parent,
+ 0,
+ regmap,
+ &ops);
+
+ return PTR_ERR_OR_ZERO(thermal_zone_dev);
+}
+
+static const struct platform_device_id sy7636a_thermal_id_table[] = {
+ { "sy7636a-thermal", },
+ { }
+};
+MODULE_DEVICE_TABLE(platform, sy7636a_thermal_id_table);
+
+static struct platform_driver sy7636a_thermal_driver = {
+ .driver = {
+ .name = "sy7636a-thermal",
+ },
+ .probe = sy7636a_thermal_probe,
+ .id_table = sy7636a_thermal_id_table,
+};
+module_platform_driver(sy7636a_thermal_driver);
+
+MODULE_AUTHOR("Lars Ivar Miljeteig <[email protected]>");
+MODULE_DESCRIPTION("SY7636A thermal driver");
+MODULE_LICENSE("GPL v2");
--
2.31.1

2021-10-09 11:56:03

by Alistair Francis

[permalink] [raw]
Subject: [PATCH v12 07/10] ARM: imx_v6_v7_defconfig: Enable silergy,sy7636a

Enable the silergy,sy7636a and silergy,sy7636a-regulator for the
reMarkable2.

Signed-off-by: Alistair Francis <[email protected]>
---
arch/arm/configs/imx_v6_v7_defconfig | 3 +++
1 file changed, 3 insertions(+)

diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index b87adf823e44..507ab17cfcd8 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -233,6 +233,7 @@ CONFIG_THERMAL_STATISTICS=y
CONFIG_THERMAL_WRITABLE_TRIPS=y
CONFIG_CPU_THERMAL=y
CONFIG_IMX_THERMAL=y
+CONFIG_SY7636A_THERMAL=y
CONFIG_WATCHDOG=y
CONFIG_DA9062_WATCHDOG=y
CONFIG_DA9063_WATCHDOG=m
@@ -248,6 +249,7 @@ CONFIG_MFD_RN5T618=y
CONFIG_MFD_STMPE=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_MFD_SIMPLE_MFD_I2C=y
CONFIG_REGULATOR_ANATOP=y
CONFIG_REGULATOR_DA9052=y
CONFIG_REGULATOR_DA9062=y
@@ -258,6 +260,7 @@ CONFIG_REGULATOR_MC13783=y
CONFIG_REGULATOR_MC13892=y
CONFIG_REGULATOR_PFUZE100=y
CONFIG_REGULATOR_RN5T618=y
+CONFIG_REGULATOR_SY7636A=y
CONFIG_RC_CORE=y
CONFIG_RC_DEVICES=y
CONFIG_IR_GPIO_CIR=y
--
2.31.1

2021-10-09 11:57:54

by Alistair Francis

[permalink] [raw]
Subject: Re: [PATCH 4/7] capsules: sha: Continue reducing code size

On Sat, Oct 9, 2021 at 9:51 PM Alistair Francis <[email protected]> wrote:
>
> From: Alistair Francis <[email protected]>
>
> Signed-off-by: Alistair Francis <[email protected]>

Sorry, I wrongly copied this patch. Just ignore this patch

Alistair

2021-10-09 11:57:55

by Alistair Francis

[permalink] [raw]
Subject: Re: [PATCH 3/7] capsules: symmetric_encryption/aes: Reduce code size

On Sat, Oct 9, 2021 at 9:51 PM Alistair Francis <[email protected]> wrote:
>
> From: Alistair Francis <[email protected]>
>
> Signed-off-by: Alistair Francis <[email protected]>

Sorry, I wrongly copied this patch. Just ignore this patch

Alistair

2021-10-09 11:58:18

by Alistair Francis

[permalink] [raw]
Subject: Re: [PATCH 5/7] capsules: hmac: Continue reducing code size

On Sat, Oct 9, 2021 at 9:51 PM Alistair Francis <[email protected]> wrote:
>
> From: Alistair Francis <[email protected]>
>
> Signed-off-by: Alistair Francis <[email protected]>

Sorry, I wrongly copied this patch. Just ignore this patch

Alistair

2021-10-09 13:52:23

by Guenter Roeck

[permalink] [raw]
Subject: Re: [PATCH v12 06/10] hwmon: sy7636a: Add temperature driver for sy7636a

On 10/9/21 4:50 AM, Alistair Francis wrote:
> This is a multi-function device to interface with the sy7636a
> EPD PMIC chip from Silergy.
>
> Signed-off-by: Alistair Francis <[email protected]>
> ---
> arch/arm/configs/imx_v6_v7_defconfig | 1 +

That should be a separate patch.

> drivers/hwmon/Kconfig | 10 ++++
> drivers/hwmon/Makefile | 1 +
> drivers/hwmon/sy7636a-hwmon.c | 77 ++++++++++++++++++++++++++++

Documentation/hwmon/sy7636a-hwmon is missing.

> 4 files changed, 89 insertions(+)
> create mode 100644 drivers/hwmon/sy7636a-hwmon.c
>
> diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
> index 8a54a4d0181a..b87adf823e44 100644
> --- a/arch/arm/configs/imx_v6_v7_defconfig
> +++ b/arch/arm/configs/imx_v6_v7_defconfig
> @@ -228,6 +228,7 @@ CONFIG_RN5T618_POWER=m
> CONFIG_SENSORS_MC13783_ADC=y
> CONFIG_SENSORS_GPIO_FAN=y
> CONFIG_SENSORS_IIO_HWMON=y
> +CONFIG_SENSORS_SY7636A=y
> CONFIG_THERMAL_STATISTICS=y
> CONFIG_THERMAL_WRITABLE_TRIPS=y
> CONFIG_CPU_THERMAL=y
> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
> index c4578e8f34bb..59f358293202 100644
> --- a/drivers/hwmon/Kconfig
> +++ b/drivers/hwmon/Kconfig
> @@ -1651,6 +1651,16 @@ config SENSORS_SIS5595
> This driver can also be built as a module. If so, the module
> will be called sis5595.
>
> +config SENSORS_SY7636A
> + tristate "Silergy SY7636A"
> + depends on I2C

That is an arbitrary dependency. The driver doesn't use I2C.

> + help
> + If you say yes here you get support for the thermistor readout of
> + the Silergy SY7636A PMIC.
> +
> + This driver can also be built as a module. If so, the module
> + will be called sy7636a-hwmon.
> +
> config SENSORS_DME1737
> tristate "SMSC DME1737, SCH311x and compatibles"
> depends on I2C && !PPC
> diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
> index 162940270661..1355ffdb1481 100644
> --- a/drivers/hwmon/Makefile
> +++ b/drivers/hwmon/Makefile
> @@ -181,6 +181,7 @@ obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o
> obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o
> obj-$(CONFIG_SENSORS_SPARX5) += sparx5-temp.o
> obj-$(CONFIG_SENSORS_STTS751) += stts751.o
> +obj-$(CONFIG_SENSORS_SY7636A) += sy7636a-hwmon.o
> obj-$(CONFIG_SENSORS_AMC6821) += amc6821.o
> obj-$(CONFIG_SENSORS_TC74) += tc74.o
> obj-$(CONFIG_SENSORS_THMC50) += thmc50.o
> diff --git a/drivers/hwmon/sy7636a-hwmon.c b/drivers/hwmon/sy7636a-hwmon.c
> new file mode 100644
> index 000000000000..e0204278339b
> --- /dev/null
> +++ b/drivers/hwmon/sy7636a-hwmon.c
> @@ -0,0 +1,77 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Functions to access SY3686A power management chip temperature
> + *
> + * Copyright (C) 2019 reMarkable AS - http://www.remarkable.com/
> + *
> + * Authors: Lars Ivar Miljeteig <[email protected]>
> + * Alistair Francis <[email protected]>
> + */
> +
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/slab.h>
> +#include <linux/jiffies.h>
> +#include <linux/hwmon.h>
> +#include <linux/hwmon-sysfs.h>
> +#include <linux/err.h>
> +#include <linux/sysfs.h>
> +#include <linux/platform_device.h>
> +
> +#include <linux/mfd/sy7636a.h>
> +
Alphabetic include file order please, and drop the includes which
are not needed (I don't see a need for slab.h or jiffies.h).

On the other side, the include of regmap.h is missing.

> +static ssize_t show_temp(struct device *dev,
> + struct device_attribute *attr, char *buf)

If you use continuation lines, please align with "(".

> +{
> + unsigned int reg_val;
> + struct regmap *regmap = dev_get_drvdata(dev);
> + int ret;
> +
> + ret = regmap_read(regmap,
> + SY7636A_REG_TERMISTOR_READOUT, &reg_val);

Line length limit is now 100, so this continuation line should not be needed.

> + if (ret)
> + return ret;
> +
> + return snprintf(buf, PAGE_SIZE, "%d\n", reg_val);
> +}
> +
> +static SENSOR_DEVICE_ATTR(temp0, 0444, show_temp, NULL, 0);
> +
> +static struct attribute *sy7636a_attrs[] = {
> + &sensor_dev_attr_temp0.dev_attr.attr,

FWIW, there is no "temp0" in the hwmon ABI. Temperature sensor
numbering starts with 1. Not that it matters,
devm_hwmon_device_register_with_info() creates attributes internally.

> + NULL
> +};
> +
> +ATTRIBUTE_GROUPS(sy7636a);
> +
> +static int sy7636a_sensor_probe(struct platform_device *pdev)
> +{
> + struct regmap *regmap = dev_get_regmap(pdev->dev.parent, NULL);
> + struct device *hwmon_dev;
> + int err;
> +
> + if (!regmap)
> + return -EPROBE_DEFER;
> +
> + hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev,
> + "sy7636a_temperature", regmap, sy7636a_groups);
> +

Please use devm_hwmon_device_register_with_info().

> + if (IS_ERR(hwmon_dev)) {
> + err = PTR_ERR(hwmon_dev);
> + dev_err(&pdev->dev, "Unable to register hwmon device, returned %d", err);

I dislike driver noise, but if it is retained please add "\n".

> + return err;
> + }
> +
> + return 0;
> +}
> +
> +static struct platform_driver sy7636a_sensor_driver = {
> + .probe = sy7636a_sensor_probe,
> + .driver = {
> + .name = "sy7636a-temperature",
> + },
> +};
> +module_platform_driver(sy7636a_sensor_driver);
> +
> +MODULE_DESCRIPTION("SY7636A sensor driver");
> +MODULE_LICENSE("GPL");
>

2021-10-09 14:31:14

by Fabio Estevam

[permalink] [raw]
Subject: Re: [PATCH v12 09/10] ARM: imx_v6_v7_defconfig: Enable backlight class devices

Hi Alistair,

On Sat, Oct 9, 2021 at 8:52 AM Alistair Francis <[email protected]> wrote:
>
> The BACKLIGHT_CLASS_DEVICE config is required for the already enabled
> DRM_SIMPLE_PANEL to work so let's enable BACKLIGHT_CLASS_DEVICE.
>
> This allows the mxsfb probe to complete successfully on the reMarkable
> 2.
>
> Signed-off-by: Alistair Francis <[email protected]>

With the commit below applied, CONFIG_BACKLIGHT_CLASS_DEVICE is
automatically selected:
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/arch/arm/configs/imx_v6_v7_defconfig?h=next-20211008&id=c54467482ffd407a4404c990697f432bfcb6cdc4

2021-10-09 23:51:54

by Guenter Roeck

[permalink] [raw]
Subject: Re: [PATCH v12 05/10] thermal: sy7636a: Add thermal driver for sy7636a

On Sat, Oct 09, 2021 at 09:50:27PM +1000, Alistair Francis wrote:
> Add thermal driver to enable kernel based polling
> and shutdown of device for temperatures out of spec
>

It _should_ be possible to implement this as part of the hwmon driver
(by using the _with_info hwmon API).

Guenter

> Signed-off-by: Alistair Francis <[email protected]>
> ---
> drivers/thermal/Kconfig | 6 ++
> drivers/thermal/Makefile | 1 +
> drivers/thermal/sy7636a_thermal.c | 94 +++++++++++++++++++++++++++++++
> 3 files changed, 101 insertions(+)
> create mode 100644 drivers/thermal/sy7636a_thermal.c
>
> diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
> index d7f44deab5b1..6ee0e7de1b37 100644
> --- a/drivers/thermal/Kconfig
> +++ b/drivers/thermal/Kconfig
> @@ -450,6 +450,12 @@ depends on (ARCH_STI || ARCH_STM32) && OF
> source "drivers/thermal/st/Kconfig"
> endmenu
>
> +config SY7636A_THERMAL
> + tristate "SY7636A thermal management"
> + help
> + Enable the sy7636a thermal driver, which supports the
> + temperature sensor embedded in Silabs SY7636A IC.
> +
> source "drivers/thermal/tegra/Kconfig"
>
> config GENERIC_ADC_THERMAL
> diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
> index 82fc3e616e54..2e1aca8a0a09 100644
> --- a/drivers/thermal/Makefile
> +++ b/drivers/thermal/Makefile
> @@ -51,6 +51,7 @@ obj-$(CONFIG_DA9062_THERMAL) += da9062-thermal.o
> obj-y += intel/
> obj-$(CONFIG_TI_SOC_THERMAL) += ti-soc-thermal/
> obj-y += st/
> +obj-$(CONFIG_SY7636A_THERMAL) += sy7636a_thermal.o
> obj-$(CONFIG_QCOM_TSENS) += qcom/
> obj-y += tegra/
> obj-$(CONFIG_HISI_THERMAL) += hisi_thermal.o
> diff --git a/drivers/thermal/sy7636a_thermal.c b/drivers/thermal/sy7636a_thermal.c
> new file mode 100644
> index 000000000000..9e58305ca3ce
> --- /dev/null
> +++ b/drivers/thermal/sy7636a_thermal.c
> @@ -0,0 +1,94 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Functions to access SY3686A power management chip temperature
> + *
> + * Copyright (C) 2019 reMarkable AS - http://www.remarkable.com/
> + *
> + * Authors: Lars Ivar Miljeteig <[email protected]>
> + * Alistair Francis <[email protected]>
> + */
> +
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/thermal.h>
> +
> +#include <linux/mfd/sy7636a.h>
> +
> +static int sy7636a_get_temp(void *arg, int *res)
> +{
> + unsigned int mode_ctr;
> + int ret, reg_val;
> + struct regmap *regmap = arg;
> + bool isVoltageActive;
> +
> + ret = regmap_read(regmap,
> + SY7636A_REG_OPERATION_MODE_CRL, &mode_ctr);
> + if (ret)
> + return ret;
> +
> + isVoltageActive = mode_ctr & SY7636A_OPERATION_MODE_CRL_ONOFF;
> +
> + /* If operation mode isn't set to control, then let's set it. */
> + if (!isVoltageActive) {
> + ret = regmap_write(regmap,
> + SY7636A_REG_OPERATION_MODE_CRL,
> + mode_ctr | SY7636A_OPERATION_MODE_CRL_ONOFF);
> + if (ret)
> + return ret;
> + }
> +
> + ret = regmap_read(regmap,
> + SY7636A_REG_TERMISTOR_READOUT, &reg_val);
> + if (ret)
> + return ret;
> +
> + /* Restore the operation mode if it wasn't set */
> + if (!isVoltageActive) {
> + ret = regmap_write(regmap,
> + SY7636A_REG_OPERATION_MODE_CRL,
> + mode_ctr);
> + if (ret)
> + return ret;
> + }
> +
> + *res = reg_val * 1000;
> +
> + return ret;
> +}
> +
> +static const struct thermal_zone_of_device_ops ops = {
> + .get_temp = sy7636a_get_temp,
> +};
> +
> +static int sy7636a_thermal_probe(struct platform_device *pdev)
> +{
> + struct regmap *regmap = dev_get_regmap(pdev->dev.parent, NULL);
> + struct thermal_zone_device *thermal_zone_dev;
> +
> + thermal_zone_dev = devm_thermal_zone_of_sensor_register(
> + pdev->dev.parent,
> + 0,
> + regmap,
> + &ops);
> +
> + return PTR_ERR_OR_ZERO(thermal_zone_dev);
> +}
> +
> +static const struct platform_device_id sy7636a_thermal_id_table[] = {
> + { "sy7636a-thermal", },
> + { }
> +};
> +MODULE_DEVICE_TABLE(platform, sy7636a_thermal_id_table);
> +
> +static struct platform_driver sy7636a_thermal_driver = {
> + .driver = {
> + .name = "sy7636a-thermal",
> + },
> + .probe = sy7636a_thermal_probe,
> + .id_table = sy7636a_thermal_id_table,
> +};
> +module_platform_driver(sy7636a_thermal_driver);
> +
> +MODULE_AUTHOR("Lars Ivar Miljeteig <[email protected]>");
> +MODULE_DESCRIPTION("SY7636A thermal driver");
> +MODULE_LICENSE("GPL v2");