diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c
index 50f67265c71d..7d685cc4c0bc 100644
--- a/drivers/hwmon/lm63.c
+++ b/drivers/hwmon/lm63.c
@@ -34,7 +34,9 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/of_device.h>
+#include <linux/pwm.h>
 #include <linux/sysfs.h>
+#include <linux/thermal.h>
 #include <linux/types.h>
 
 /*
@@ -97,6 +99,8 @@ static const unsigned short normal_i2c[] = { 0x18, 0x4c, 0x4e, I2C_CLIENT_END };
 #define LM63_MAX_CONVRATE_HZ		32
 #define LM96163_MAX_CONVRATE_HZ		26
 
+#define MAX_SENSORS	2
+
 /*
  * Conversions and various macros
  * For tachometer counts, the LM63 uses 16-bit values.
@@ -131,6 +135,12 @@ static const unsigned short normal_i2c[] = { 0x18, 0x4c, 0x4e, I2C_CLIENT_END };
 
 enum chips { lm63, lm64, lm96163 };
 
+struct lm63_thermal_sensor {
+	struct lm63_data *data;
+	struct thermal_zone_device *tz;
+	unsigned int sensor_id;
+};
+
 /*
  * Client data (each client gets its own)
  */
@@ -173,8 +183,15 @@ struct lm63_data {
 	bool lut_temp_highres;
 	bool remote_unsigned; /* true if unsigned remote upper limits */
 	bool trutherm;
+	struct pwm_chip chip;
+	struct lm63_thermal_sensor thermal_sensor[MAX_SENSORS];
 };
 
+static inline struct lm63_data *to_pwm(struct pwm_chip *chip)
+{
+	return container_of(chip, struct lm63_data, chip);
+}
+
 static inline int temp8_from_reg(struct lm63_data *data, int nr)
 {
 	if (data->remote_unsigned)
@@ -421,6 +438,9 @@ static ssize_t pwm1_enable_store(struct device *dev,
 	unsigned long val;
 	int err;
 
+	if (of_get_property(dev->of_node, "#pwm-cells", NULL))
+		return -EPERM;
+
 	err = kstrtoul(buf, 10, &val);
 	if (err)
 		return err;
@@ -1018,6 +1038,8 @@ static void lm63_init_client(struct lm63_data *data)
 	u8 convrate;
 
 	data->config = i2c_smbus_read_byte_data(client, LM63_REG_CONFIG1);
+	if (of_get_property(dev->of_node, "#pwm-cells", NULL))
+		i2c_smbus_write_byte_data(client, LM63_REG_CONFIG_FAN, 0x20);
 	data->config_fan = i2c_smbus_read_byte_data(client,
 						    LM63_REG_CONFIG_FAN);
 
@@ -1087,6 +1109,96 @@ static void lm63_init_client(struct lm63_data *data)
 		(data->config_fan & 0x20) ? "manual" : "auto");
 }
 
+static int lm63_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+				const struct pwm_state *state)
+{
+	struct lm63_data *data = to_pwm(chip);
+	struct i2c_client *client = data->client;
+	int ret = -EINVAL;
+	u8 pwm_mode;
+	u8 val;
+
+	mutex_lock(&data->update_lock);
+	pwm_mode = i2c_smbus_read_byte_data(client, LM63_REG_CONFIG_FAN);
+	if (!(pwm_mode >> 5)) {
+		mutex_unlock(&data->update_lock);
+		return -EPERM;
+	}
+
+	if (state->period > 1) {
+		val = state->duty_cycle * 255 / (state->period - 1);
+		val = clamp_val(val, 0, 255);
+		val = data->pwm_highres ? val :
+				(val * data->pwm1_freq * 2 + 127) / 255;
+		ret = i2c_smbus_write_byte_data(client, LM63_REG_PWM_VALUE, val);
+	}
+
+	mutex_unlock(&data->update_lock);
+	return ret;
+}
+
+static const struct pwm_ops lm63_pwm_ops = {
+	.apply = lm63_pwm_apply,
+	.owner = THIS_MODULE,
+};
+
+static void lm63_pwm_remove(void *arg)
+{
+	struct lm63_data *data = arg;
+
+	pwmchip_remove(&data->chip);
+}
+
+static void lm63_init_pwm(struct lm63_data *data)
+{
+	struct i2c_client *client = data->client;
+	int ret;
+
+	/* Initialize chip */
+
+	data->chip.dev = &client->dev;
+	data->chip.ops = &lm63_pwm_ops;
+	data->chip.base = -1;
+	data->chip.npwm = 1;
+
+	ret = pwmchip_add(&data->chip);
+	if (ret < 0) {
+		dev_warn(&client->dev, "pwmchip_add() failed: %d\n", ret);
+		return;
+	}
+
+	devm_add_action_or_reset(&client->dev, lm63_pwm_remove, data);
+}
+
+static int lm63_get_temp(void *data, int *temp)
+{
+	struct lm63_thermal_sensor *thermal_sensor = data;
+
+	*temp = i2c_smbus_read_byte_data(thermal_sensor->data->client,
+			LM63_REG_LOCAL_TEMP + thermal_sensor->sensor_id) * 1000;
+
+	return 0;
+}
+
+static const struct thermal_zone_of_device_ops lm63_tz_ops = {
+	.get_temp = lm63_get_temp,
+};
+
+static void lm63_init_thermal(struct lm63_data *data)
+{
+	struct i2c_client *client = data->client;
+	struct lm63_thermal_sensor *thermal_sensor;
+	unsigned int i;
+
+	thermal_sensor = data->thermal_sensor;
+	for (i = 0; i < MAX_SENSORS; i++, thermal_sensor++) {
+		thermal_sensor->data = data;
+		thermal_sensor->sensor_id = i;
+		thermal_sensor->tz = devm_thermal_zone_of_sensor_register(&client->dev,
+						 i, thermal_sensor, &lm63_tz_ops);
+	}
+}
+
 static const struct i2c_device_id lm63_id[];
 
 static int lm63_probe(struct i2c_client *client)
@@ -1126,7 +1238,14 @@ static int lm63_probe(struct i2c_client *client)
 
 	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
 							   data, data->groups);
-	return PTR_ERR_OR_ZERO(hwmon_dev);
+	if (IS_ERR(hwmon_dev))
+		return PTR_ERR(hwmon_dev);
+
+	lm63_init_thermal(data);
+	if (IS_ENABLED(CONFIG_PWM))
+		lm63_init_pwm(data);
+
+	return 0;
 }
 
 /*
