* [PATCH 0/8] Remove remaining AMD Elan drivers
@ 2026-05-06 14:42 Sean Young
2026-05-06 14:42 ` [PATCH 1/8] x86/platform: Remove Technology Systems 5500 board Sean Young
` (7 more replies)
0 siblings, 8 replies; 10+ messages in thread
From: Sean Young @ 2026-05-06 14:42 UTC (permalink / raw)
To: linux-kernel
Now that AMD Elan support has been removed[1], remove the AMD Elan specific
drivers too. I had a Technology Systems 5500 back in the early 2000's and
it was pretty slow back then - no need to support such ancient slow
device. I wrote and patched some of these drivers so nice to see them
removed at the end of their life cycle.
1. commit 8b793a92d862 ("x86/cpu: Remove M486/M486SX/ELAN support")
Sean Young (8):
x86/platform: Remove Technology Systems 5500 board
mtd: ts5500_flash: Remove mapping since board is no longer supported
mtd: netsc520: Remove mapping since board is no longer supported
mtd: sc520cdp: Remove mapping since board is no longer supported
gpio: ts5500: Remove gpio driver as board no longer supported
watchdog: sc520: Drop AMD Elan SC520 support
cpufreq: sc520_freq: Drop support for AMD Elan SC520
cpufreq: elanfreq: Drop support for AMD Elan SC4*
.../ABI/testing/sysfs-platform-ts5500 | 54 ---
.../watchdog/watchdog-parameters.rst | 9 -
MAINTAINERS | 5 -
arch/x86/Kconfig | 9 -
arch/x86/platform/Makefile | 1 -
arch/x86/platform/ts5500/Makefile | 2 -
arch/x86/platform/ts5500/ts5500.c | 341 -------------
drivers/cpufreq/Kconfig.x86 | 26 -
drivers/cpufreq/Makefile | 2 -
drivers/cpufreq/elanfreq.c | 226 ---------
drivers/cpufreq/sc520_freq.c | 136 ------
drivers/gpio/Kconfig | 9 -
drivers/gpio/Makefile | 1 -
drivers/gpio/gpio-ts5500.c | 446 ------------------
drivers/mtd/maps/Kconfig | 34 --
drivers/mtd/maps/Makefile | 3 -
drivers/mtd/maps/netsc520.c | 127 -----
drivers/mtd/maps/sc520cdp.c | 294 ------------
drivers/mtd/maps/ts5500_flash.c | 108 -----
drivers/watchdog/Kconfig | 13 -
drivers/watchdog/Makefile | 1 -
drivers/watchdog/sc520_wdt.c | 430 -----------------
22 files changed, 2277 deletions(-)
delete mode 100644 Documentation/ABI/testing/sysfs-platform-ts5500
delete mode 100644 arch/x86/platform/ts5500/Makefile
delete mode 100644 arch/x86/platform/ts5500/ts5500.c
delete mode 100644 drivers/cpufreq/elanfreq.c
delete mode 100644 drivers/cpufreq/sc520_freq.c
delete mode 100644 drivers/gpio/gpio-ts5500.c
delete mode 100644 drivers/mtd/maps/netsc520.c
delete mode 100644 drivers/mtd/maps/sc520cdp.c
delete mode 100644 drivers/mtd/maps/ts5500_flash.c
delete mode 100644 drivers/watchdog/sc520_wdt.c
--
2.54.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/8] x86/platform: Remove Technology Systems 5500 board
2026-05-06 14:42 [PATCH 0/8] Remove remaining AMD Elan drivers Sean Young
@ 2026-05-06 14:42 ` Sean Young
2026-05-06 14:42 ` [PATCH 2/8] mtd: ts5500_flash: Remove mapping since board is no longer supported Sean Young
` (6 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Sean Young @ 2026-05-06 14:42 UTC (permalink / raw)
To: linux-kernel, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, x86, H. Peter Anvin
Since commit 8b793a92d862 ("x86/cpu: Remove M486/M486SX/ELAN support"),
this board is no longer supported. Remove the platform support too.
Signed-off-by: Sean Young <sean@mess.org>
---
.../ABI/testing/sysfs-platform-ts5500 | 54 ---
MAINTAINERS | 5 -
arch/x86/Kconfig | 9 -
arch/x86/platform/Makefile | 1 -
arch/x86/platform/ts5500/Makefile | 2 -
arch/x86/platform/ts5500/ts5500.c | 341 ------------------
6 files changed, 412 deletions(-)
delete mode 100644 Documentation/ABI/testing/sysfs-platform-ts5500
delete mode 100644 arch/x86/platform/ts5500/Makefile
delete mode 100644 arch/x86/platform/ts5500/ts5500.c
diff --git a/Documentation/ABI/testing/sysfs-platform-ts5500 b/Documentation/ABI/testing/sysfs-platform-ts5500
deleted file mode 100644
index e685957caa12..000000000000
--- a/Documentation/ABI/testing/sysfs-platform-ts5500
+++ /dev/null
@@ -1,54 +0,0 @@
-What: /sys/devices/platform/ts5500/adc
-Date: January 2013
-KernelVersion: 3.7
-Contact: "Savoir-faire Linux Inc." <kernel@savoirfairelinux.com>
-Description:
- Indicates the presence of an A/D Converter. If it is present,
- it will display "1", otherwise "0".
-
-What: /sys/devices/platform/ts5500/ereset
-Date: January 2013
-KernelVersion: 3.7
-Contact: "Savoir-faire Linux Inc." <kernel@savoirfairelinux.com>
-Description:
- Indicates the presence of an external reset. If it is present,
- it will display "1", otherwise "0".
-
-What: /sys/devices/platform/ts5500/id
-Date: January 2013
-KernelVersion: 3.7
-Contact: "Savoir-faire Linux Inc." <kernel@savoirfairelinux.com>
-Description:
- Product ID of the TS board. TS-5500 ID is 0x60.
-
-What: /sys/devices/platform/ts5500/jumpers
-Date: January 2013
-KernelVersion: 3.7
-Contact: "Savoir-faire Linux Inc." <kernel@savoirfairelinux.com>
-Description:
- Bitfield showing the jumpers' state. If a jumper is present,
- the corresponding bit is set. For instance, 0x0e means jumpers
- 2, 3 and 4 are set.
-
-What: /sys/devices/platform/ts5500/name
-Date: July 2014
-KernelVersion: 3.16
-Contact: "Savoir-faire Linux Inc." <kernel@savoirfairelinux.com>
-Description:
- Model name of the TS board, e.g. "TS-5500".
-
-What: /sys/devices/platform/ts5500/rs485
-Date: January 2013
-KernelVersion: 3.7
-Contact: "Savoir-faire Linux Inc." <kernel@savoirfairelinux.com>
-Description:
- Indicates the presence of the RS485 option. If it is present,
- it will display "1", otherwise "0".
-
-What: /sys/devices/platform/ts5500/sram
-Date: January 2013
-KernelVersion: 3.7
-Contact: "Savoir-faire Linux Inc." <kernel@savoirfairelinux.com>
-Description:
- Indicates the presence of the SRAM option. If it is present,
- it will display "1", otherwise "0".
diff --git a/MAINTAINERS b/MAINTAINERS
index 882214b0e7db..b526739b9947 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -26182,11 +26182,6 @@ S: Maintained
F: Documentation/process/contribution-maturity-model.rst
F: Documentation/process/researcher-guidelines.rst
-TECHNOLOGIC SYSTEMS TS-5500 PLATFORM SUPPORT
-M: "Savoir-faire Linux Inc." <kernel@savoirfairelinux.com>
-S: Maintained
-F: arch/x86/platform/ts5500/
-
TECHNOTREND USB IR RECEIVER
M: Sean Young <sean@mess.org>
L: linux-media@vger.kernel.org
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index f3f7cb01d69d..4ea5465a9d93 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -3100,15 +3100,6 @@ config GEOS
help
This option enables system support for the Traverse Technologies GEOS.
-config TS5500
- bool "Technologic Systems TS-5500 platform support"
- depends on MELAN
- select CHECK_SIGNATURE
- select NEW_LEDS
- select LEDS_CLASS
- help
- This option enables system support for the Technologic Systems TS-5500.
-
endif # X86_32
config AMD_NB
diff --git a/arch/x86/platform/Makefile b/arch/x86/platform/Makefile
index 3ed03a2552d0..727b92d0ca25 100644
--- a/arch/x86/platform/Makefile
+++ b/arch/x86/platform/Makefile
@@ -10,5 +10,4 @@ obj-y += intel-mid/
obj-y += intel-quark/
obj-y += olpc/
obj-y += scx200/
-obj-y += ts5500/
obj-y += uv/
diff --git a/arch/x86/platform/ts5500/Makefile b/arch/x86/platform/ts5500/Makefile
deleted file mode 100644
index 910fe9e3ffb4..000000000000
--- a/arch/x86/platform/ts5500/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_TS5500) += ts5500.o
diff --git a/arch/x86/platform/ts5500/ts5500.c b/arch/x86/platform/ts5500/ts5500.c
deleted file mode 100644
index 0b67da056fd9..000000000000
--- a/arch/x86/platform/ts5500/ts5500.c
+++ /dev/null
@@ -1,341 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Technologic Systems TS-5500 Single Board Computer support
- *
- * Copyright (C) 2013-2014 Savoir-faire Linux Inc.
- * Vivien Didelot <vivien.didelot@savoirfairelinux.com>
- *
- * This driver registers the Technologic Systems TS-5500 Single Board Computer
- * (SBC) and its devices, and exposes information to userspace such as jumpers'
- * state or available options. For further information about sysfs entries, see
- * Documentation/ABI/testing/sysfs-platform-ts5500.
- *
- * This code may be extended to support similar x86-based platforms.
- * Actually, the TS-5500 and TS-5400 are supported.
- */
-
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/leds.h>
-#include <linux/init.h>
-#include <linux/platform_data/max197.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-/* Product code register */
-#define TS5500_PRODUCT_CODE_ADDR 0x74
-#define TS5500_PRODUCT_CODE 0x60 /* TS-5500 product code */
-#define TS5400_PRODUCT_CODE 0x40 /* TS-5400 product code */
-
-/* SRAM/RS-485/ADC options, and RS-485 RTS/Automatic RS-485 flags register */
-#define TS5500_SRAM_RS485_ADC_ADDR 0x75
-#define TS5500_SRAM BIT(0) /* SRAM option */
-#define TS5500_RS485 BIT(1) /* RS-485 option */
-#define TS5500_ADC BIT(2) /* A/D converter option */
-#define TS5500_RS485_RTS BIT(6) /* RTS for RS-485 */
-#define TS5500_RS485_AUTO BIT(7) /* Automatic RS-485 */
-
-/* External Reset/Industrial Temperature Range options register */
-#define TS5500_ERESET_ITR_ADDR 0x76
-#define TS5500_ERESET BIT(0) /* External Reset option */
-#define TS5500_ITR BIT(1) /* Indust. Temp. Range option */
-
-/* LED/Jumpers register */
-#define TS5500_LED_JP_ADDR 0x77
-#define TS5500_LED BIT(0) /* LED flag */
-#define TS5500_JP1 BIT(1) /* Automatic CMOS */
-#define TS5500_JP2 BIT(2) /* Enable Serial Console */
-#define TS5500_JP3 BIT(3) /* Write Enable Drive A */
-#define TS5500_JP4 BIT(4) /* Fast Console (115K baud) */
-#define TS5500_JP5 BIT(5) /* User Jumper */
-#define TS5500_JP6 BIT(6) /* Console on COM1 (req. JP2) */
-#define TS5500_JP7 BIT(7) /* Undocumented (Unused) */
-
-/* A/D Converter registers */
-#define TS5500_ADC_CONV_BUSY_ADDR 0x195 /* Conversion state register */
-#define TS5500_ADC_CONV_BUSY BIT(0)
-#define TS5500_ADC_CONV_INIT_LSB_ADDR 0x196 /* Start conv. / LSB register */
-#define TS5500_ADC_CONV_MSB_ADDR 0x197 /* MSB register */
-#define TS5500_ADC_CONV_DELAY 12 /* usec */
-
-/**
- * struct ts5500_sbc - TS-5500 board description
- * @name: Board model name.
- * @id: Board product ID.
- * @sram: Flag for SRAM option.
- * @rs485: Flag for RS-485 option.
- * @adc: Flag for Analog/Digital converter option.
- * @ereset: Flag for External Reset option.
- * @itr: Flag for Industrial Temperature Range option.
- * @jumpers: Bitfield for jumpers' state.
- */
-struct ts5500_sbc {
- const char *name;
- int id;
- bool sram;
- bool rs485;
- bool adc;
- bool ereset;
- bool itr;
- u8 jumpers;
-};
-
-/* Board signatures in BIOS shadow RAM */
-static const struct {
- const char * const string;
- const ssize_t offset;
-} ts5500_signatures[] __initconst = {
- { "TS-5x00 AMD Elan", 0xb14 },
-};
-
-static int __init ts5500_check_signature(void)
-{
- void __iomem *bios;
- int i, ret = -ENODEV;
-
- bios = ioremap(0xf0000, 0x10000);
- if (!bios)
- return -ENOMEM;
-
- for (i = 0; i < ARRAY_SIZE(ts5500_signatures); i++) {
- if (check_signature(bios + ts5500_signatures[i].offset,
- ts5500_signatures[i].string,
- strlen(ts5500_signatures[i].string))) {
- ret = 0;
- break;
- }
- }
-
- iounmap(bios);
- return ret;
-}
-
-static int __init ts5500_detect_config(struct ts5500_sbc *sbc)
-{
- u8 tmp;
- int ret = 0;
-
- if (!request_region(TS5500_PRODUCT_CODE_ADDR, 4, "ts5500"))
- return -EBUSY;
-
- sbc->id = inb(TS5500_PRODUCT_CODE_ADDR);
- if (sbc->id == TS5500_PRODUCT_CODE) {
- sbc->name = "TS-5500";
- } else if (sbc->id == TS5400_PRODUCT_CODE) {
- sbc->name = "TS-5400";
- } else {
- pr_err("ts5500: unknown product code 0x%x\n", sbc->id);
- ret = -ENODEV;
- goto cleanup;
- }
-
- tmp = inb(TS5500_SRAM_RS485_ADC_ADDR);
- sbc->sram = tmp & TS5500_SRAM;
- sbc->rs485 = tmp & TS5500_RS485;
- sbc->adc = tmp & TS5500_ADC;
-
- tmp = inb(TS5500_ERESET_ITR_ADDR);
- sbc->ereset = tmp & TS5500_ERESET;
- sbc->itr = tmp & TS5500_ITR;
-
- tmp = inb(TS5500_LED_JP_ADDR);
- sbc->jumpers = tmp & ~TS5500_LED;
-
-cleanup:
- release_region(TS5500_PRODUCT_CODE_ADDR, 4);
- return ret;
-}
-
-static ssize_t name_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct ts5500_sbc *sbc = dev_get_drvdata(dev);
-
- return sprintf(buf, "%s\n", sbc->name);
-}
-static DEVICE_ATTR_RO(name);
-
-static ssize_t id_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct ts5500_sbc *sbc = dev_get_drvdata(dev);
-
- return sprintf(buf, "0x%.2x\n", sbc->id);
-}
-static DEVICE_ATTR_RO(id);
-
-static ssize_t jumpers_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct ts5500_sbc *sbc = dev_get_drvdata(dev);
-
- return sprintf(buf, "0x%.2x\n", sbc->jumpers >> 1);
-}
-static DEVICE_ATTR_RO(jumpers);
-
-#define TS5500_ATTR_BOOL(_field) \
- static ssize_t _field##_show(struct device *dev, \
- struct device_attribute *attr, char *buf) \
- { \
- struct ts5500_sbc *sbc = dev_get_drvdata(dev); \
- \
- return sprintf(buf, "%d\n", sbc->_field); \
- } \
- static DEVICE_ATTR_RO(_field)
-
-TS5500_ATTR_BOOL(sram);
-TS5500_ATTR_BOOL(rs485);
-TS5500_ATTR_BOOL(adc);
-TS5500_ATTR_BOOL(ereset);
-TS5500_ATTR_BOOL(itr);
-
-static struct attribute *ts5500_attributes[] = {
- &dev_attr_id.attr,
- &dev_attr_name.attr,
- &dev_attr_jumpers.attr,
- &dev_attr_sram.attr,
- &dev_attr_rs485.attr,
- &dev_attr_adc.attr,
- &dev_attr_ereset.attr,
- &dev_attr_itr.attr,
- NULL
-};
-
-static const struct attribute_group ts5500_attr_group = {
- .attrs = ts5500_attributes,
-};
-
-static struct resource ts5500_dio1_resource[] = {
- DEFINE_RES_IRQ_NAMED(7, "DIO1 interrupt"),
-};
-
-static struct platform_device ts5500_dio1_pdev = {
- .name = "ts5500-dio1",
- .id = -1,
- .resource = ts5500_dio1_resource,
- .num_resources = 1,
-};
-
-static struct resource ts5500_dio2_resource[] = {
- DEFINE_RES_IRQ_NAMED(6, "DIO2 interrupt"),
-};
-
-static struct platform_device ts5500_dio2_pdev = {
- .name = "ts5500-dio2",
- .id = -1,
- .resource = ts5500_dio2_resource,
- .num_resources = 1,
-};
-
-static void ts5500_led_set(struct led_classdev *led_cdev,
- enum led_brightness brightness)
-{
- outb(!!brightness, TS5500_LED_JP_ADDR);
-}
-
-static enum led_brightness ts5500_led_get(struct led_classdev *led_cdev)
-{
- return (inb(TS5500_LED_JP_ADDR) & TS5500_LED) ? LED_FULL : LED_OFF;
-}
-
-static struct led_classdev ts5500_led_cdev = {
- .name = "ts5500:green:",
- .brightness_set = ts5500_led_set,
- .brightness_get = ts5500_led_get,
-};
-
-static int ts5500_adc_convert(u8 ctrl)
-{
- u8 lsb, msb;
-
- /* Start conversion (ensure the 3 MSB are set to 0) */
- outb(ctrl & 0x1f, TS5500_ADC_CONV_INIT_LSB_ADDR);
-
- /*
- * The platform has CPLD logic driving the A/D converter.
- * The conversion must complete within 11 microseconds,
- * otherwise we have to re-initiate a conversion.
- */
- udelay(TS5500_ADC_CONV_DELAY);
- if (inb(TS5500_ADC_CONV_BUSY_ADDR) & TS5500_ADC_CONV_BUSY)
- return -EBUSY;
-
- /* Read the raw data */
- lsb = inb(TS5500_ADC_CONV_INIT_LSB_ADDR);
- msb = inb(TS5500_ADC_CONV_MSB_ADDR);
-
- return (msb << 8) | lsb;
-}
-
-static struct max197_platform_data ts5500_adc_pdata = {
- .convert = ts5500_adc_convert,
-};
-
-static struct platform_device ts5500_adc_pdev = {
- .name = "max197",
- .id = -1,
- .dev = {
- .platform_data = &ts5500_adc_pdata,
- },
-};
-
-static int __init ts5500_init(void)
-{
- struct platform_device *pdev;
- struct ts5500_sbc *sbc;
- int err;
-
- /*
- * There is no DMI available or PCI bridge subvendor info,
- * only the BIOS provides a 16-bit identification call.
- * It is safer to find a signature in the BIOS shadow RAM.
- */
- err = ts5500_check_signature();
- if (err)
- return err;
-
- pdev = platform_device_register_simple("ts5500", -1, NULL, 0);
- if (IS_ERR(pdev))
- return PTR_ERR(pdev);
-
- sbc = devm_kzalloc(&pdev->dev, sizeof(struct ts5500_sbc), GFP_KERNEL);
- if (!sbc) {
- err = -ENOMEM;
- goto error;
- }
-
- err = ts5500_detect_config(sbc);
- if (err)
- goto error;
-
- platform_set_drvdata(pdev, sbc);
-
- err = sysfs_create_group(&pdev->dev.kobj, &ts5500_attr_group);
- if (err)
- goto error;
-
- if (sbc->id == TS5500_PRODUCT_CODE) {
- ts5500_dio1_pdev.dev.parent = &pdev->dev;
- if (platform_device_register(&ts5500_dio1_pdev))
- dev_warn(&pdev->dev, "DIO1 block registration failed\n");
- ts5500_dio2_pdev.dev.parent = &pdev->dev;
- if (platform_device_register(&ts5500_dio2_pdev))
- dev_warn(&pdev->dev, "DIO2 block registration failed\n");
- }
-
- if (led_classdev_register(&pdev->dev, &ts5500_led_cdev))
- dev_warn(&pdev->dev, "LED registration failed\n");
-
- if (sbc->adc) {
- ts5500_adc_pdev.dev.parent = &pdev->dev;
- if (platform_device_register(&ts5500_adc_pdev))
- dev_warn(&pdev->dev, "ADC registration failed\n");
- }
-
- return 0;
-error:
- platform_device_unregister(pdev);
- return err;
-}
-device_initcall(ts5500_init);
--
2.54.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/8] mtd: ts5500_flash: Remove mapping since board is no longer supported
2026-05-06 14:42 [PATCH 0/8] Remove remaining AMD Elan drivers Sean Young
2026-05-06 14:42 ` [PATCH 1/8] x86/platform: Remove Technology Systems 5500 board Sean Young
@ 2026-05-06 14:42 ` Sean Young
2026-05-06 14:42 ` [PATCH 3/8] mtd: netsc520: " Sean Young
` (5 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Sean Young @ 2026-05-06 14:42 UTC (permalink / raw)
To: linux-kernel, Miquel Raynal, Richard Weinberger,
Vignesh Raghavendra
Cc: linux-mtd
Since commit 8b793a92d862 ("x86/cpu: Remove M486/M486SX/ELAN support"),
this board is no longer supported. Remove the mtd map too.
Signed-off-by: Sean Young <sean@mess.org>
---
drivers/mtd/maps/Kconfig | 18 ------
drivers/mtd/maps/Makefile | 1 -
drivers/mtd/maps/ts5500_flash.c | 108 --------------------------------
3 files changed, 127 deletions(-)
delete mode 100644 drivers/mtd/maps/ts5500_flash.c
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 99d5ff9a1fbe..e48221e97f8d 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -141,24 +141,6 @@ config MTD_NETSC520
demonstration board. If you have one of these boards and would like
to use the flash chips on it, say 'Y'.
-config MTD_TS5500
- tristate "JEDEC Flash device mapped on Technologic Systems TS-5500"
- depends on TS5500 || COMPILE_TEST
- select MTD_JEDECPROBE
- select MTD_CFI_AMDSTD
- help
- This provides a driver for the on-board flash of the Technologic
- System's TS-5500 board. The 2MB flash is split into 3 partitions
- which are accessed as separate MTD devices.
-
- mtd0 and mtd2 are the two BIOS drives, which use the resident
- flash disk (RFD) flash translation layer.
-
- mtd1 allows you to reprogram your BIOS. BE VERY CAREFUL.
-
- Note that jumper 3 ("Write Enable Drive A") must be set
- otherwise detection won't succeed.
-
config MTD_SBC_GXX
tristate "CFI Flash device mapped on Arcom SBC-GXx boards"
depends on X86 && MTD_CFI_INTELEXT && MTD_COMPLEX_MAPPINGS
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index 51af1d2ebd52..46ff278006a7 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -28,7 +28,6 @@ obj-$(CONFIG_MTD_SA1100) += sa1100-flash.o
obj-$(CONFIG_MTD_SBC_GXX) += sbc_gxx.o
obj-$(CONFIG_MTD_SC520CDP) += sc520cdp.o
obj-$(CONFIG_MTD_NETSC520) += netsc520.o
-obj-$(CONFIG_MTD_TS5500) += ts5500_flash.o
obj-$(CONFIG_MTD_SUN_UFLASH) += sun_uflash.o
obj-$(CONFIG_MTD_SCx200_DOCFLASH)+= scx200_docflash.o
obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o
diff --git a/drivers/mtd/maps/ts5500_flash.c b/drivers/mtd/maps/ts5500_flash.c
deleted file mode 100644
index 70d6e865f555..000000000000
--- a/drivers/mtd/maps/ts5500_flash.c
+++ /dev/null
@@ -1,108 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * ts5500_flash.c -- MTD map driver for Technology Systems TS-5500 board
- *
- * Copyright (C) 2004 Sean Young <sean@mess.org>
- *
- * Note:
- * - In order for detection to work, jumper 3 must be set.
- * - Drive A and B use the resident flash disk (RFD) flash translation layer.
- * - If you have created your own jffs file system and the bios overwrites
- * it during boot, try disabling Drive A: and B: in the boot order.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-#include <linux/types.h>
-
-
-#define WINDOW_ADDR 0x09400000
-#define WINDOW_SIZE 0x00200000
-
-static struct map_info ts5500_map = {
- .name = "TS-5500 Flash",
- .size = WINDOW_SIZE,
- .bankwidth = 1,
- .phys = WINDOW_ADDR
-};
-
-static const struct mtd_partition ts5500_partitions[] = {
- {
- .name = "Drive A",
- .offset = 0,
- .size = 0x0e0000
- },
- {
- .name = "BIOS",
- .offset = 0x0e0000,
- .size = 0x020000,
- },
- {
- .name = "Drive B",
- .offset = 0x100000,
- .size = 0x100000
- }
-};
-
-#define NUM_PARTITIONS ARRAY_SIZE(ts5500_partitions)
-
-static struct mtd_info *mymtd;
-
-static int __init init_ts5500_map(void)
-{
- int rc = 0;
-
- ts5500_map.virt = ioremap(ts5500_map.phys, ts5500_map.size);
-
- if (!ts5500_map.virt) {
- printk(KERN_ERR "Failed to ioremap\n");
- rc = -EIO;
- goto err2;
- }
-
- simple_map_init(&ts5500_map);
-
- mymtd = do_map_probe("jedec_probe", &ts5500_map);
- if (!mymtd)
- mymtd = do_map_probe("map_rom", &ts5500_map);
-
- if (!mymtd) {
- rc = -ENXIO;
- goto err1;
- }
-
- mymtd->owner = THIS_MODULE;
- mtd_device_register(mymtd, ts5500_partitions, NUM_PARTITIONS);
-
- return 0;
-
-err1:
- iounmap(ts5500_map.virt);
-err2:
- return rc;
-}
-
-static void __exit cleanup_ts5500_map(void)
-{
- if (mymtd) {
- mtd_device_unregister(mymtd);
- map_destroy(mymtd);
- }
-
- if (ts5500_map.virt) {
- iounmap(ts5500_map.virt);
- ts5500_map.virt = NULL;
- }
-}
-
-module_init(init_ts5500_map);
-module_exit(cleanup_ts5500_map);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Sean Young <sean@mess.org>");
-MODULE_DESCRIPTION("MTD map driver for Technology Systems TS-5500 board");
-
--
2.54.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/8] mtd: netsc520: Remove mapping since board is no longer supported
2026-05-06 14:42 [PATCH 0/8] Remove remaining AMD Elan drivers Sean Young
2026-05-06 14:42 ` [PATCH 1/8] x86/platform: Remove Technology Systems 5500 board Sean Young
2026-05-06 14:42 ` [PATCH 2/8] mtd: ts5500_flash: Remove mapping since board is no longer supported Sean Young
@ 2026-05-06 14:42 ` Sean Young
2026-05-06 14:42 ` [PATCH 4/8] mtd: sc520cdp: " Sean Young
` (4 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Sean Young @ 2026-05-06 14:42 UTC (permalink / raw)
To: linux-kernel, Miquel Raynal, Richard Weinberger,
Vignesh Raghavendra
Cc: linux-mtd
Since commit 8b793a92d862 ("x86/cpu: Remove M486/M486SX/ELAN support"),
this board is no longer supported. Remove the mtd map too.
Signed-off-by: Sean Young <sean@mess.org>
---
drivers/mtd/maps/Kconfig | 8 ---
drivers/mtd/maps/Makefile | 1 -
drivers/mtd/maps/netsc520.c | 127 ------------------------------------
3 files changed, 136 deletions(-)
delete mode 100644 drivers/mtd/maps/netsc520.c
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index e48221e97f8d..b34f3c34c626 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -133,14 +133,6 @@ config MTD_SC520CDP
Dual-in-line JEDEC chip. This 'mapping' driver supports that
arrangement, implementing three MTD devices.
-config MTD_NETSC520
- tristate "CFI Flash device mapped on AMD NetSc520"
- depends on (MELAN || COMPILE_TEST) && MTD_CFI
- help
- This enables access routines for the flash chips on the AMD NetSc520
- demonstration board. If you have one of these boards and would like
- to use the flash chips on it, say 'Y'.
-
config MTD_SBC_GXX
tristate "CFI Flash device mapped on Arcom SBC-GXx boards"
depends on X86 && MTD_CFI_INTELEXT && MTD_COMPLEX_MAPPINGS
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index 46ff278006a7..e8b5caa17ccc 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -27,7 +27,6 @@ obj-$(CONFIG_MTD_PCMCIA) += pcmciamtd.o
obj-$(CONFIG_MTD_SA1100) += sa1100-flash.o
obj-$(CONFIG_MTD_SBC_GXX) += sbc_gxx.o
obj-$(CONFIG_MTD_SC520CDP) += sc520cdp.o
-obj-$(CONFIG_MTD_NETSC520) += netsc520.o
obj-$(CONFIG_MTD_SUN_UFLASH) += sun_uflash.o
obj-$(CONFIG_MTD_SCx200_DOCFLASH)+= scx200_docflash.o
obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o
diff --git a/drivers/mtd/maps/netsc520.c b/drivers/mtd/maps/netsc520.c
deleted file mode 100644
index 0bb651624f05..000000000000
--- a/drivers/mtd/maps/netsc520.c
+++ /dev/null
@@ -1,127 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/* netsc520.c -- MTD map driver for AMD NetSc520 Demonstration Board
- *
- * Copyright (C) 2001 Mark Langsdorf (mark.langsdorf@amd.com)
- * based on sc520cdp.c by Sysgo Real-Time Solutions GmbH
- *
- * The NetSc520 is a demonstration board for the Elan Sc520 processor available
- * from AMD. It has a single back of 16 megs of 32-bit Flash ROM and another
- * 16 megs of SDRAM.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <asm/io.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-
-
-/*
-** The single, 16 megabyte flash bank is divided into four virtual
-** partitions. The first partition is 768 KiB and is intended to
-** store the kernel image loaded by the bootstrap loader. The second
-** partition is 256 KiB and holds the BIOS image. The third
-** partition is 14.5 MiB and is intended for the flash file system
-** image. The last partition is 512 KiB and contains another copy
-** of the BIOS image and the reset vector.
-**
-** Only the third partition should be mounted. The first partition
-** should not be mounted, but it can erased and written to using the
-** MTD character routines. The second and fourth partitions should
-** not be touched - it is possible to corrupt the BIOS image by
-** mounting these partitions, and potentially the board will not be
-** recoverable afterwards.
-*/
-
-/* partition_info gives details on the logical partitions that the split the
- * single flash device into. If the size if zero we use up to the end of the
- * device. */
-static const struct mtd_partition partition_info[] = {
- {
- .name = "NetSc520 boot kernel",
- .offset = 0,
- .size = 0xc0000
- },
- {
- .name = "NetSc520 Low BIOS",
- .offset = 0xc0000,
- .size = 0x40000
- },
- {
- .name = "NetSc520 file system",
- .offset = 0x100000,
- .size = 0xe80000
- },
- {
- .name = "NetSc520 High BIOS",
- .offset = 0xf80000,
- .size = 0x80000
- },
-};
-#define NUM_PARTITIONS ARRAY_SIZE(partition_info)
-
-#define WINDOW_SIZE 0x00100000
-#define WINDOW_ADDR 0x00200000
-
-static struct map_info netsc520_map = {
- .name = "netsc520 Flash Bank",
- .size = WINDOW_SIZE,
- .bankwidth = 4,
- .phys = WINDOW_ADDR,
-};
-
-#define NUM_FLASH_BANKS ARRAY_SIZE(netsc520_map)
-
-static struct mtd_info *mymtd;
-
-static int __init init_netsc520(void)
-{
- printk(KERN_NOTICE "NetSc520 flash device: 0x%Lx at 0x%Lx\n",
- (unsigned long long)netsc520_map.size,
- (unsigned long long)netsc520_map.phys);
- netsc520_map.virt = ioremap(netsc520_map.phys, netsc520_map.size);
-
- if (!netsc520_map.virt) {
- printk("Failed to ioremap\n");
- return -EIO;
- }
-
- simple_map_init(&netsc520_map);
-
- mymtd = do_map_probe("cfi_probe", &netsc520_map);
- if(!mymtd)
- mymtd = do_map_probe("map_ram", &netsc520_map);
- if(!mymtd)
- mymtd = do_map_probe("map_rom", &netsc520_map);
-
- if (!mymtd) {
- iounmap(netsc520_map.virt);
- return -ENXIO;
- }
-
- mymtd->owner = THIS_MODULE;
- mtd_device_register(mymtd, partition_info, NUM_PARTITIONS);
- return 0;
-}
-
-static void __exit cleanup_netsc520(void)
-{
- if (mymtd) {
- mtd_device_unregister(mymtd);
- map_destroy(mymtd);
- }
- if (netsc520_map.virt) {
- iounmap(netsc520_map.virt);
- netsc520_map.virt = NULL;
- }
-}
-
-module_init(init_netsc520);
-module_exit(cleanup_netsc520);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mark Langsdorf <mark.langsdorf@amd.com>");
-MODULE_DESCRIPTION("MTD map driver for AMD NetSc520 Demonstration Board");
--
2.54.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 4/8] mtd: sc520cdp: Remove mapping since board is no longer supported
2026-05-06 14:42 [PATCH 0/8] Remove remaining AMD Elan drivers Sean Young
` (2 preceding siblings ...)
2026-05-06 14:42 ` [PATCH 3/8] mtd: netsc520: " Sean Young
@ 2026-05-06 14:42 ` Sean Young
2026-05-06 14:42 ` [PATCH 5/8] gpio: ts5500: Remove gpio driver as board " Sean Young
` (3 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Sean Young @ 2026-05-06 14:42 UTC (permalink / raw)
To: linux-kernel, Miquel Raynal, Richard Weinberger,
Vignesh Raghavendra
Cc: linux-mtd
Since commit 8b793a92d862 ("x86/cpu: Remove M486/M486SX/ELAN support"),
this board is no longer supported. Remove the mtd map too.
Signed-off-by: Sean Young <sean@mess.org>
---
drivers/mtd/maps/Kconfig | 8 -
drivers/mtd/maps/Makefile | 1 -
drivers/mtd/maps/sc520cdp.c | 294 ------------------------------------
3 files changed, 303 deletions(-)
delete mode 100644 drivers/mtd/maps/sc520cdp.c
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index b34f3c34c626..db63b5af4b39 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -125,14 +125,6 @@ config MTD_SUN_UFLASH
Sun Microsystems boardsets. This driver will require CFI support
in the kernel, so if you did not enable CFI previously, do that now.
-config MTD_SC520CDP
- tristate "CFI Flash device mapped on AMD SC520 CDP"
- depends on (MELAN || COMPILE_TEST) && MTD_CFI
- help
- The SC520 CDP board has two banks of CFI-compliant chips and one
- Dual-in-line JEDEC chip. This 'mapping' driver supports that
- arrangement, implementing three MTD devices.
-
config MTD_SBC_GXX
tristate "CFI Flash device mapped on Arcom SBC-GXx boards"
depends on X86 && MTD_CFI_INTELEXT && MTD_COMPLEX_MAPPINGS
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index e8b5caa17ccc..c545d1e68e91 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -26,7 +26,6 @@ obj-$(CONFIG_MTD_PISMO) += pismo.o
obj-$(CONFIG_MTD_PCMCIA) += pcmciamtd.o
obj-$(CONFIG_MTD_SA1100) += sa1100-flash.o
obj-$(CONFIG_MTD_SBC_GXX) += sbc_gxx.o
-obj-$(CONFIG_MTD_SC520CDP) += sc520cdp.o
obj-$(CONFIG_MTD_SUN_UFLASH) += sun_uflash.o
obj-$(CONFIG_MTD_SCx200_DOCFLASH)+= scx200_docflash.o
obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o
diff --git a/drivers/mtd/maps/sc520cdp.c b/drivers/mtd/maps/sc520cdp.c
deleted file mode 100644
index 8ef7aec634c7..000000000000
--- a/drivers/mtd/maps/sc520cdp.c
+++ /dev/null
@@ -1,294 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/* sc520cdp.c -- MTD map driver for AMD SC520 Customer Development Platform
- *
- * Copyright (C) 2001 Sysgo Real-Time Solutions GmbH
- *
- * The SC520CDP is an evaluation board for the Elan SC520 processor available
- * from AMD. It has two banks of 32-bit Flash ROM, each 8 Megabytes in size,
- * and up to 512 KiB of 8-bit DIL Flash ROM.
- * For details see https://www.amd.com/products/epd/desiging/evalboards/18.elansc520/520_cdp_brief/index.html
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <asm/io.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/concat.h>
-
-/*
-** The Embedded Systems BIOS decodes the first FLASH starting at
-** 0x8400000. This is a *terrible* place for it because accessing
-** the flash at this location causes the A22 address line to be high
-** (that's what 0x8400000 binary's ought to be). But this is the highest
-** order address line on the raw flash devices themselves!!
-** This causes the top HALF of the flash to be accessed first. Beyond
-** the physical limits of the flash, the flash chip aliases over (to
-** 0x880000 which causes the bottom half to be accessed. This splits the
-** flash into two and inverts it! If you then try to access this from another
-** program that does NOT do this insanity, then you *will* access the
-** first half of the flash, but not find what you expect there. That
-** stuff is in the *second* half! Similarly, the address used by the
-** BIOS for the second FLASH bank is also quite a bad choice.
-** If REPROGRAM_PAR is defined below (the default), then this driver will
-** choose more useful addresses for the FLASH banks by reprogramming the
-** responsible PARxx registers in the SC520's MMCR region. This will
-** cause the settings to be incompatible with the BIOS's settings, which
-** shouldn't be a problem since you are running Linux, (i.e. the BIOS is
-** not much use anyway). However, if you need to be compatible with
-** the BIOS for some reason, just undefine REPROGRAM_PAR.
-*/
-#define REPROGRAM_PAR
-
-
-
-#ifdef REPROGRAM_PAR
-
-/* These are the addresses we want.. */
-#define WINDOW_ADDR_0 0x08800000
-#define WINDOW_ADDR_1 0x09000000
-#define WINDOW_ADDR_2 0x09800000
-
-/* .. and these are the addresses the BIOS gives us */
-#define WINDOW_ADDR_0_BIOS 0x08400000
-#define WINDOW_ADDR_1_BIOS 0x08c00000
-#define WINDOW_ADDR_2_BIOS 0x09400000
-
-#else
-
-#define WINDOW_ADDR_0 0x08400000
-#define WINDOW_ADDR_1 0x08C00000
-#define WINDOW_ADDR_2 0x09400000
-
-#endif
-
-#define WINDOW_SIZE_0 0x00800000
-#define WINDOW_SIZE_1 0x00800000
-#define WINDOW_SIZE_2 0x00080000
-
-
-static struct map_info sc520cdp_map[] = {
- {
- .name = "SC520CDP Flash Bank #0",
- .size = WINDOW_SIZE_0,
- .bankwidth = 4,
- .phys = WINDOW_ADDR_0
- },
- {
- .name = "SC520CDP Flash Bank #1",
- .size = WINDOW_SIZE_1,
- .bankwidth = 4,
- .phys = WINDOW_ADDR_1
- },
- {
- .name = "SC520CDP DIL Flash",
- .size = WINDOW_SIZE_2,
- .bankwidth = 1,
- .phys = WINDOW_ADDR_2
- },
-};
-
-#define NUM_FLASH_BANKS ARRAY_SIZE(sc520cdp_map)
-
-static struct mtd_info *mymtd[NUM_FLASH_BANKS];
-static struct mtd_info *merged_mtd;
-
-#ifdef REPROGRAM_PAR
-
-/*
-** The SC520 MMCR (memory mapped control register) region resides
-** at 0xFFFEF000. The 16 Programmable Address Region (PAR) registers
-** are at offset 0x88 in the MMCR:
-*/
-#define SC520_MMCR_BASE 0xFFFEF000
-#define SC520_MMCR_EXTENT 0x1000
-#define SC520_PAR(x) ((0x88/sizeof(unsigned long)) + (x))
-#define NUM_SC520_PAR 16 /* total number of PAR registers */
-
-/*
-** The highest three bits in a PAR register determine what target
-** device is controlled by this PAR. Here, only ROMCS? and BOOTCS
-** devices are of interest.
-*/
-#define SC520_PAR_BOOTCS (0x4<<29)
-#define SC520_PAR_ROMCS0 (0x5<<29)
-#define SC520_PAR_ROMCS1 (0x6<<29)
-#define SC520_PAR_TRGDEV (0x7<<29)
-
-/*
-** Bits 28 thru 26 determine some attributes for the
-** region controlled by the PAR. (We only use non-cacheable)
-*/
-#define SC520_PAR_WRPROT (1<<26) /* write protected */
-#define SC520_PAR_NOCACHE (1<<27) /* non-cacheable */
-#define SC520_PAR_NOEXEC (1<<28) /* code execution denied */
-
-
-/*
-** Bit 25 determines the granularity: 4K or 64K
-*/
-#define SC520_PAR_PG_SIZ4 (0<<25)
-#define SC520_PAR_PG_SIZ64 (1<<25)
-
-/*
-** Build a value to be written into a PAR register.
-** We only need ROM entries, 64K page size:
-*/
-#define SC520_PAR_ENTRY(trgdev, address, size) \
- ((trgdev) | SC520_PAR_NOCACHE | SC520_PAR_PG_SIZ64 | \
- (address) >> 16 | (((size) >> 16) - 1) << 14)
-
-struct sc520_par_table
-{
- unsigned long trgdev;
- unsigned long new_par;
- unsigned long default_address;
-};
-
-static const struct sc520_par_table par_table[NUM_FLASH_BANKS] =
-{
- { /* Flash Bank #0: selected by ROMCS0 */
- SC520_PAR_ROMCS0,
- SC520_PAR_ENTRY(SC520_PAR_ROMCS0, WINDOW_ADDR_0, WINDOW_SIZE_0),
- WINDOW_ADDR_0_BIOS
- },
- { /* Flash Bank #1: selected by ROMCS1 */
- SC520_PAR_ROMCS1,
- SC520_PAR_ENTRY(SC520_PAR_ROMCS1, WINDOW_ADDR_1, WINDOW_SIZE_1),
- WINDOW_ADDR_1_BIOS
- },
- { /* DIL (BIOS) Flash: selected by BOOTCS */
- SC520_PAR_BOOTCS,
- SC520_PAR_ENTRY(SC520_PAR_BOOTCS, WINDOW_ADDR_2, WINDOW_SIZE_2),
- WINDOW_ADDR_2_BIOS
- }
-};
-
-
-static void sc520cdp_setup_par(void)
-{
- unsigned long __iomem *mmcr;
- unsigned long mmcr_val;
- int i, j;
-
- /* map in SC520's MMCR area */
- mmcr = ioremap(SC520_MMCR_BASE, SC520_MMCR_EXTENT);
- if(!mmcr) { /* ioremap failed: skip the PAR reprogramming */
- /* force physical address fields to BIOS defaults: */
- for(i = 0; i < NUM_FLASH_BANKS; i++)
- sc520cdp_map[i].phys = par_table[i].default_address;
- return;
- }
-
- /*
- ** Find the PARxx registers that are responsible for activating
- ** ROMCS0, ROMCS1 and BOOTCS. Reprogram each of these with a
- ** new value from the table.
- */
- for(i = 0; i < NUM_FLASH_BANKS; i++) { /* for each par_table entry */
- for(j = 0; j < NUM_SC520_PAR; j++) { /* for each PAR register */
- mmcr_val = readl(&mmcr[SC520_PAR(j)]);
- /* if target device field matches, reprogram the PAR */
- if((mmcr_val & SC520_PAR_TRGDEV) == par_table[i].trgdev)
- {
- writel(par_table[i].new_par, &mmcr[SC520_PAR(j)]);
- break;
- }
- }
- if(j == NUM_SC520_PAR)
- { /* no matching PAR found: try default BIOS address */
- printk(KERN_NOTICE "Could not find PAR responsible for %s\n",
- sc520cdp_map[i].name);
- printk(KERN_NOTICE "Trying default address 0x%lx\n",
- par_table[i].default_address);
- sc520cdp_map[i].phys = par_table[i].default_address;
- }
- }
- iounmap(mmcr);
-}
-#endif
-
-
-static int __init init_sc520cdp(void)
-{
- int i, j, devices_found = 0;
-
-#ifdef REPROGRAM_PAR
- /* reprogram PAR registers so flash appears at the desired addresses */
- sc520cdp_setup_par();
-#endif
-
- for (i = 0; i < NUM_FLASH_BANKS; i++) {
- printk(KERN_NOTICE "SC520 CDP flash device: 0x%Lx at 0x%Lx\n",
- (unsigned long long)sc520cdp_map[i].size,
- (unsigned long long)sc520cdp_map[i].phys);
-
- sc520cdp_map[i].virt = ioremap(sc520cdp_map[i].phys, sc520cdp_map[i].size);
-
- if (!sc520cdp_map[i].virt) {
- printk("Failed to ioremap\n");
- for (j = 0; j < i; j++) {
- if (mymtd[j]) {
- map_destroy(mymtd[j]);
- iounmap(sc520cdp_map[j].virt);
- }
- }
- return -EIO;
- }
-
- simple_map_init(&sc520cdp_map[i]);
-
- mymtd[i] = do_map_probe("cfi_probe", &sc520cdp_map[i]);
- if(!mymtd[i])
- mymtd[i] = do_map_probe("jedec_probe", &sc520cdp_map[i]);
- if(!mymtd[i])
- mymtd[i] = do_map_probe("map_rom", &sc520cdp_map[i]);
-
- if (mymtd[i]) {
- mymtd[i]->owner = THIS_MODULE;
- ++devices_found;
- }
- else {
- iounmap(sc520cdp_map[i].virt);
- }
- }
- if(devices_found >= 2) {
- /* Combine the two flash banks into a single MTD device & register it: */
- merged_mtd = mtd_concat_create(mymtd, 2, "SC520CDP Flash Banks #0 and #1");
- if(merged_mtd)
- mtd_device_register(merged_mtd, NULL, 0);
- }
- if(devices_found == 3) /* register the third (DIL-Flash) device */
- mtd_device_register(mymtd[2], NULL, 0);
- return(devices_found ? 0 : -ENXIO);
-}
-
-static void __exit cleanup_sc520cdp(void)
-{
- int i;
-
- if (merged_mtd) {
- mtd_device_unregister(merged_mtd);
- mtd_concat_destroy(merged_mtd);
- }
- if (mymtd[2])
- mtd_device_unregister(mymtd[2]);
-
- for (i = 0; i < NUM_FLASH_BANKS; i++) {
- if (mymtd[i])
- map_destroy(mymtd[i]);
- if (sc520cdp_map[i].virt) {
- iounmap(sc520cdp_map[i].virt);
- sc520cdp_map[i].virt = NULL;
- }
- }
-}
-
-module_init(init_sc520cdp);
-module_exit(cleanup_sc520cdp);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Sysgo Real-Time Solutions GmbH");
-MODULE_DESCRIPTION("MTD map driver for AMD SC520 Customer Development Platform");
--
2.54.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 5/8] gpio: ts5500: Remove gpio driver as board no longer supported
2026-05-06 14:42 [PATCH 0/8] Remove remaining AMD Elan drivers Sean Young
` (3 preceding siblings ...)
2026-05-06 14:42 ` [PATCH 4/8] mtd: sc520cdp: " Sean Young
@ 2026-05-06 14:42 ` Sean Young
2026-05-06 14:42 ` [PATCH 6/8] watchdog: sc520: Drop AMD Elan SC520 support Sean Young
` (2 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Sean Young @ 2026-05-06 14:42 UTC (permalink / raw)
To: linux-kernel, Linus Walleij, Bartosz Golaszewski; +Cc: linux-gpio
Since commit 8b793a92d862 ("x86/cpu: Remove M486/M486SX/ELAN support"),
this board is no longer supported. Remove the gpio driver too.
Signed-off-by: Sean Young <sean@mess.org>
---
drivers/gpio/Kconfig | 9 -
drivers/gpio/Makefile | 1 -
drivers/gpio/gpio-ts5500.c | 446 -------------------------------------
3 files changed, 456 deletions(-)
delete mode 100644 drivers/gpio/gpio-ts5500.c
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 020e51e30317..359a21cb093e 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1093,15 +1093,6 @@ config GPIO_SCH311X
To compile this driver as a module, choose M here: the module will
be called gpio-sch311x.
-config GPIO_TS5500
- tristate "TS-5500 DIO blocks and compatibles"
- depends on TS5500 || COMPILE_TEST
- help
- This driver supports Digital I/O exposed by pin blocks found on some
- Technologic Systems platforms. It includes, but is not limited to, 3
- blocks of the TS-5500: DIO1, DIO2 and the LCD port, and the TS-5600
- LCD port.
-
config GPIO_WINBOND
tristate "Winbond Super I/O GPIO support"
select ISA_BUS_API
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index b267598b517d..dc9d1106e75f 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -194,7 +194,6 @@ obj-$(CONFIG_GPIO_TPS68470) += gpio-tps68470.o
obj-$(CONFIG_GPIO_TQMX86) += gpio-tqmx86.o
obj-$(CONFIG_GPIO_TS4800) += gpio-ts4800.o
obj-$(CONFIG_GPIO_TS4900) += gpio-ts4900.o
-obj-$(CONFIG_GPIO_TS5500) += gpio-ts5500.o
obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o
obj-$(CONFIG_GPIO_TWL6040) += gpio-twl6040.o
obj-$(CONFIG_GPIO_UNIPHIER) += gpio-uniphier.o
diff --git a/drivers/gpio/gpio-ts5500.c b/drivers/gpio/gpio-ts5500.c
deleted file mode 100644
index 3c7f2efe10fd..000000000000
--- a/drivers/gpio/gpio-ts5500.c
+++ /dev/null
@@ -1,446 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Digital I/O driver for Technologic Systems TS-5500
- *
- * Copyright (c) 2012 Savoir-faire Linux Inc.
- * Vivien Didelot <vivien.didelot@savoirfairelinux.com>
- *
- * Technologic Systems platforms have pin blocks, exposing several Digital
- * Input/Output lines (DIO). This driver aims to support single pin blocks.
- * In that sense, the support is not limited to the TS-5500 blocks.
- * Actually, the following platforms have DIO support:
- *
- * TS-5500:
- * Documentation: https://docs.embeddedts.com/TS-5500
- * Blocks: DIO1, DIO2 and LCD port.
- *
- * TS-5600:
- * Documentation: https://docs.embeddedts.com/TS-5600
- * Blocks: LCD port (identical to TS-5500 LCD).
- */
-
-#include <linux/bitops.h>
-#include <linux/gpio/driver.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-/* List of supported Technologic Systems platforms DIO blocks */
-enum ts5500_blocks { TS5500_DIO1, TS5500_DIO2, TS5500_LCD, TS5600_LCD };
-
-struct ts5500_priv {
- const struct ts5500_dio *pinout;
- struct gpio_chip gpio_chip;
- spinlock_t lock;
- bool strap;
- u8 hwirq;
-};
-
-/*
- * Hex 7D is used to control several blocks (e.g. DIO2 and LCD port).
- * This flag ensures that the region has been requested by this driver.
- */
-static bool hex7d_reserved;
-
-/*
- * This structure is used to describe capabilities of DIO lines,
- * such as available directions and connected interrupt (if any).
- */
-struct ts5500_dio {
- const u8 value_addr;
- const u8 value_mask;
- const u8 control_addr;
- const u8 control_mask;
- const bool no_input;
- const bool no_output;
- const u8 irq;
-};
-
-#define TS5500_DIO_IN_OUT(vaddr, vbit, caddr, cbit) \
- { \
- .value_addr = vaddr, \
- .value_mask = BIT(vbit), \
- .control_addr = caddr, \
- .control_mask = BIT(cbit), \
- }
-
-#define TS5500_DIO_IN(addr, bit) \
- { \
- .value_addr = addr, \
- .value_mask = BIT(bit), \
- .no_output = true, \
- }
-
-#define TS5500_DIO_IN_IRQ(addr, bit, _irq) \
- { \
- .value_addr = addr, \
- .value_mask = BIT(bit), \
- .no_output = true, \
- .irq = _irq, \
- }
-
-#define TS5500_DIO_OUT(addr, bit) \
- { \
- .value_addr = addr, \
- .value_mask = BIT(bit), \
- .no_input = true, \
- }
-
-/*
- * Input/Output DIO lines are programmed in groups of 4. Their values are
- * available through 4 consecutive bits in a value port, whereas the direction
- * of these 4 lines is driven by only 1 bit in a control port.
- */
-#define TS5500_DIO_GROUP(vaddr, vbitfrom, caddr, cbit) \
- TS5500_DIO_IN_OUT(vaddr, vbitfrom + 0, caddr, cbit), \
- TS5500_DIO_IN_OUT(vaddr, vbitfrom + 1, caddr, cbit), \
- TS5500_DIO_IN_OUT(vaddr, vbitfrom + 2, caddr, cbit), \
- TS5500_DIO_IN_OUT(vaddr, vbitfrom + 3, caddr, cbit)
-
-/*
- * TS-5500 DIO1 block
- *
- * value control dir hw
- * addr bit addr bit in out irq name pin offset
- *
- * 0x7b 0 0x7a 0 x x DIO1_0 1 0
- * 0x7b 1 0x7a 0 x x DIO1_1 3 1
- * 0x7b 2 0x7a 0 x x DIO1_2 5 2
- * 0x7b 3 0x7a 0 x x DIO1_3 7 3
- * 0x7b 4 0x7a 1 x x DIO1_4 9 4
- * 0x7b 5 0x7a 1 x x DIO1_5 11 5
- * 0x7b 6 0x7a 1 x x DIO1_6 13 6
- * 0x7b 7 0x7a 1 x x DIO1_7 15 7
- * 0x7c 0 0x7a 5 x x DIO1_8 4 8
- * 0x7c 1 0x7a 5 x x DIO1_9 6 9
- * 0x7c 2 0x7a 5 x x DIO1_10 8 10
- * 0x7c 3 0x7a 5 x x DIO1_11 10 11
- * 0x7c 4 x DIO1_12 12 12
- * 0x7c 5 x 7 DIO1_13 14 13
- */
-static const struct ts5500_dio ts5500_dio1[] = {
- TS5500_DIO_GROUP(0x7b, 0, 0x7a, 0),
- TS5500_DIO_GROUP(0x7b, 4, 0x7a, 1),
- TS5500_DIO_GROUP(0x7c, 0, 0x7a, 5),
- TS5500_DIO_IN(0x7c, 4),
- TS5500_DIO_IN_IRQ(0x7c, 5, 7),
-};
-
-/*
- * TS-5500 DIO2 block
- *
- * value control dir hw
- * addr bit addr bit in out irq name pin offset
- *
- * 0x7e 0 0x7d 0 x x DIO2_0 1 0
- * 0x7e 1 0x7d 0 x x DIO2_1 3 1
- * 0x7e 2 0x7d 0 x x DIO2_2 5 2
- * 0x7e 3 0x7d 0 x x DIO2_3 7 3
- * 0x7e 4 0x7d 1 x x DIO2_4 9 4
- * 0x7e 5 0x7d 1 x x DIO2_5 11 5
- * 0x7e 6 0x7d 1 x x DIO2_6 13 6
- * 0x7e 7 0x7d 1 x x DIO2_7 15 7
- * 0x7f 0 0x7d 5 x x DIO2_8 4 8
- * 0x7f 1 0x7d 5 x x DIO2_9 6 9
- * 0x7f 2 0x7d 5 x x DIO2_10 8 10
- * 0x7f 3 0x7d 5 x x DIO2_11 10 11
- * 0x7f 4 x 6 DIO2_13 14 12
- */
-static const struct ts5500_dio ts5500_dio2[] = {
- TS5500_DIO_GROUP(0x7e, 0, 0x7d, 0),
- TS5500_DIO_GROUP(0x7e, 4, 0x7d, 1),
- TS5500_DIO_GROUP(0x7f, 0, 0x7d, 5),
- TS5500_DIO_IN_IRQ(0x7f, 4, 6),
-};
-
-/*
- * TS-5500 LCD port used as DIO block
- * TS-5600 LCD port is identical
- *
- * value control dir hw
- * addr bit addr bit in out irq name pin offset
- *
- * 0x72 0 0x7d 2 x x LCD_0 8 0
- * 0x72 1 0x7d 2 x x LCD_1 7 1
- * 0x72 2 0x7d 2 x x LCD_2 10 2
- * 0x72 3 0x7d 2 x x LCD_3 9 3
- * 0x72 4 0x7d 3 x x LCD_4 12 4
- * 0x72 5 0x7d 3 x x LCD_5 11 5
- * 0x72 6 0x7d 3 x x LCD_6 14 6
- * 0x72 7 0x7d 3 x x LCD_7 13 7
- * 0x73 0 x LCD_EN 5 8
- * 0x73 6 x LCD_WR 6 9
- * 0x73 7 x 1 LCD_RS 3 10
- */
-static const struct ts5500_dio ts5500_lcd[] = {
- TS5500_DIO_GROUP(0x72, 0, 0x7d, 2),
- TS5500_DIO_GROUP(0x72, 4, 0x7d, 3),
- TS5500_DIO_OUT(0x73, 0),
- TS5500_DIO_IN(0x73, 6),
- TS5500_DIO_IN_IRQ(0x73, 7, 1),
-};
-
-static inline void ts5500_set_mask(u8 mask, u8 addr)
-{
- u8 val = inb(addr);
- val |= mask;
- outb(val, addr);
-}
-
-static inline void ts5500_clear_mask(u8 mask, u8 addr)
-{
- u8 val = inb(addr);
- val &= ~mask;
- outb(val, addr);
-}
-
-static int ts5500_gpio_input(struct gpio_chip *chip, unsigned offset)
-{
- struct ts5500_priv *priv = gpiochip_get_data(chip);
- const struct ts5500_dio line = priv->pinout[offset];
- unsigned long flags;
-
- if (line.no_input)
- return -ENXIO;
-
- if (line.no_output)
- return 0;
-
- spin_lock_irqsave(&priv->lock, flags);
- ts5500_clear_mask(line.control_mask, line.control_addr);
- spin_unlock_irqrestore(&priv->lock, flags);
-
- return 0;
-}
-
-static int ts5500_gpio_get(struct gpio_chip *chip, unsigned offset)
-{
- struct ts5500_priv *priv = gpiochip_get_data(chip);
- const struct ts5500_dio line = priv->pinout[offset];
-
- return !!(inb(line.value_addr) & line.value_mask);
-}
-
-static int ts5500_gpio_output(struct gpio_chip *chip, unsigned offset, int val)
-{
- struct ts5500_priv *priv = gpiochip_get_data(chip);
- const struct ts5500_dio line = priv->pinout[offset];
- unsigned long flags;
-
- if (line.no_output)
- return -ENXIO;
-
- spin_lock_irqsave(&priv->lock, flags);
- if (!line.no_input)
- ts5500_set_mask(line.control_mask, line.control_addr);
-
- if (val)
- ts5500_set_mask(line.value_mask, line.value_addr);
- else
- ts5500_clear_mask(line.value_mask, line.value_addr);
- spin_unlock_irqrestore(&priv->lock, flags);
-
- return 0;
-}
-
-static int ts5500_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
-{
- struct ts5500_priv *priv = gpiochip_get_data(chip);
- const struct ts5500_dio line = priv->pinout[offset];
- unsigned long flags;
-
- spin_lock_irqsave(&priv->lock, flags);
- if (val)
- ts5500_set_mask(line.value_mask, line.value_addr);
- else
- ts5500_clear_mask(line.value_mask, line.value_addr);
- spin_unlock_irqrestore(&priv->lock, flags);
-
- return 0;
-}
-
-static int ts5500_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
-{
- struct ts5500_priv *priv = gpiochip_get_data(chip);
- const struct ts5500_dio *block = priv->pinout;
- const struct ts5500_dio line = block[offset];
-
- /* Only one pin is connected to an interrupt */
- if (line.irq)
- return line.irq;
-
- /* As this pin is input-only, we may strap it to another in/out pin */
- if (priv->strap)
- return priv->hwirq;
-
- return -ENXIO;
-}
-
-static int ts5500_enable_irq(struct ts5500_priv *priv)
-{
- int ret = 0;
- unsigned long flags;
-
- spin_lock_irqsave(&priv->lock, flags);
- if (priv->hwirq == 7)
- ts5500_set_mask(BIT(7), 0x7a); /* DIO1_13 on IRQ7 */
- else if (priv->hwirq == 6)
- ts5500_set_mask(BIT(7), 0x7d); /* DIO2_13 on IRQ6 */
- else if (priv->hwirq == 1)
- ts5500_set_mask(BIT(6), 0x7d); /* LCD_RS on IRQ1 */
- else
- ret = -EINVAL;
- spin_unlock_irqrestore(&priv->lock, flags);
-
- return ret;
-}
-
-static void ts5500_disable_irq(struct ts5500_priv *priv)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&priv->lock, flags);
- if (priv->hwirq == 7)
- ts5500_clear_mask(BIT(7), 0x7a); /* DIO1_13 on IRQ7 */
- else if (priv->hwirq == 6)
- ts5500_clear_mask(BIT(7), 0x7d); /* DIO2_13 on IRQ6 */
- else if (priv->hwirq == 1)
- ts5500_clear_mask(BIT(6), 0x7d); /* LCD_RS on IRQ1 */
- else
- dev_err(priv->gpio_chip.parent, "invalid hwirq %d\n",
- priv->hwirq);
- spin_unlock_irqrestore(&priv->lock, flags);
-}
-
-static int ts5500_dio_probe(struct platform_device *pdev)
-{
- enum ts5500_blocks block = platform_get_device_id(pdev)->driver_data;
- struct device *dev = &pdev->dev;
- const char *name = dev_name(dev);
- struct ts5500_priv *priv;
- unsigned long flags;
- int ret;
-
- ret = platform_get_irq(pdev, 0);
- if (ret < 0)
- return ret;
-
- priv = devm_kzalloc(dev, sizeof(struct ts5500_priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- platform_set_drvdata(pdev, priv);
- priv->hwirq = ret;
- spin_lock_init(&priv->lock);
-
- priv->gpio_chip.owner = THIS_MODULE;
- priv->gpio_chip.label = name;
- priv->gpio_chip.parent = dev;
- priv->gpio_chip.direction_input = ts5500_gpio_input;
- priv->gpio_chip.direction_output = ts5500_gpio_output;
- priv->gpio_chip.get = ts5500_gpio_get;
- priv->gpio_chip.set = ts5500_gpio_set;
- priv->gpio_chip.to_irq = ts5500_gpio_to_irq;
- priv->gpio_chip.base = -1;
-
- switch (block) {
- case TS5500_DIO1:
- priv->pinout = ts5500_dio1;
- priv->gpio_chip.ngpio = ARRAY_SIZE(ts5500_dio1);
-
- if (!devm_request_region(dev, 0x7a, 3, name)) {
- dev_err(dev, "failed to request %s ports\n", name);
- return -EBUSY;
- }
- break;
- case TS5500_DIO2:
- priv->pinout = ts5500_dio2;
- priv->gpio_chip.ngpio = ARRAY_SIZE(ts5500_dio2);
-
- if (!devm_request_region(dev, 0x7e, 2, name)) {
- dev_err(dev, "failed to request %s ports\n", name);
- return -EBUSY;
- }
-
- if (hex7d_reserved)
- break;
-
- if (!devm_request_region(dev, 0x7d, 1, name)) {
- dev_err(dev, "failed to request %s 7D\n", name);
- return -EBUSY;
- }
-
- hex7d_reserved = true;
- break;
- case TS5500_LCD:
- case TS5600_LCD:
- priv->pinout = ts5500_lcd;
- priv->gpio_chip.ngpio = ARRAY_SIZE(ts5500_lcd);
-
- if (!devm_request_region(dev, 0x72, 2, name)) {
- dev_err(dev, "failed to request %s ports\n", name);
- return -EBUSY;
- }
-
- if (!hex7d_reserved) {
- if (!devm_request_region(dev, 0x7d, 1, name)) {
- dev_err(dev, "failed to request %s 7D\n", name);
- return -EBUSY;
- }
-
- hex7d_reserved = true;
- }
-
- /* Ensure usage of LCD port as DIO */
- spin_lock_irqsave(&priv->lock, flags);
- ts5500_clear_mask(BIT(4), 0x7d);
- spin_unlock_irqrestore(&priv->lock, flags);
- break;
- }
-
- ret = devm_gpiochip_add_data(dev, &priv->gpio_chip, priv);
- if (ret) {
- dev_err(dev, "failed to register the gpio chip\n");
- return ret;
- }
-
- ret = ts5500_enable_irq(priv);
- if (ret) {
- dev_err(dev, "invalid interrupt %d\n", priv->hwirq);
- return ret;
- }
-
- return 0;
-}
-
-static void ts5500_dio_remove(struct platform_device *pdev)
-{
- struct ts5500_priv *priv = platform_get_drvdata(pdev);
-
- ts5500_disable_irq(priv);
-}
-
-static const struct platform_device_id ts5500_dio_ids[] = {
- { "ts5500-dio1", TS5500_DIO1 },
- { "ts5500-dio2", TS5500_DIO2 },
- { "ts5500-dio-lcd", TS5500_LCD },
- { "ts5600-dio-lcd", TS5600_LCD },
- { }
-};
-MODULE_DEVICE_TABLE(platform, ts5500_dio_ids);
-
-static struct platform_driver ts5500_dio_driver = {
- .driver = {
- .name = "ts5500-dio",
- },
- .probe = ts5500_dio_probe,
- .remove = ts5500_dio_remove,
- .id_table = ts5500_dio_ids,
-};
-
-module_platform_driver(ts5500_dio_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Savoir-faire Linux Inc. <kernel@savoirfairelinux.com>");
-MODULE_DESCRIPTION("Technologic Systems TS-5500 Digital I/O driver");
--
2.54.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 6/8] watchdog: sc520: Drop AMD Elan SC520 support
2026-05-06 14:42 [PATCH 0/8] Remove remaining AMD Elan drivers Sean Young
` (4 preceding siblings ...)
2026-05-06 14:42 ` [PATCH 5/8] gpio: ts5500: Remove gpio driver as board " Sean Young
@ 2026-05-06 14:42 ` Sean Young
2026-05-06 14:51 ` Guenter Roeck
2026-05-06 14:42 ` [PATCH 7/8] cpufreq: sc520_freq: Drop support for AMD Elan SC520 Sean Young
2026-05-06 14:42 ` [PATCH 8/8] cpufreq: elanfreq: Drop support for AMD Elan SC4* Sean Young
7 siblings, 1 reply; 10+ messages in thread
From: Sean Young @ 2026-05-06 14:42 UTC (permalink / raw)
To: linux-kernel, Wim Van Sebroeck, Guenter Roeck, Jonathan Corbet,
Shuah Khan
Cc: linux-watchdog, linux-doc
Since commit 8b793a92d862 ("x86/cpu: Remove M486/M486SX/ELAN support"),
this board is no longer supported. Remove the watchdog too.
Signed-off-by: Sean Young <sean@mess.org>
---
.../watchdog/watchdog-parameters.rst | 9 -
drivers/watchdog/Kconfig | 13 -
drivers/watchdog/Makefile | 1 -
drivers/watchdog/sc520_wdt.c | 430 ------------------
4 files changed, 453 deletions(-)
delete mode 100644 drivers/watchdog/sc520_wdt.c
diff --git a/Documentation/watchdog/watchdog-parameters.rst b/Documentation/watchdog/watchdog-parameters.rst
index 773241ed9986..638b972e0b16 100644
--- a/Documentation/watchdog/watchdog-parameters.rst
+++ b/Documentation/watchdog/watchdog-parameters.rst
@@ -532,15 +532,6 @@ sc1200wdt:
-------------------------------------------------
-sc520_wdt:
- timeout:
- Watchdog timeout in seconds. (1 <= timeout <= 3600, default=30)
- nowayout:
- Watchdog cannot be stopped once started
- (default=kernel config parameter)
-
--------------------------------------------------
-
sch311x_wdt:
force_id:
Override the detected device ID
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index dc78729ba2a5..4e36e4b5bf39 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -1270,19 +1270,6 @@ config GEODE_WDT
You can compile this driver directly into the kernel, or use
it as a module. The module will be called geodewdt.
-config SC520_WDT
- tristate "AMD Elan SC520 processor Watchdog"
- depends on MELAN || COMPILE_TEST
- help
- This is the driver for the hardware watchdog built in to the
- AMD "Elan" SC520 microcomputer commonly used in embedded systems.
- This watchdog simply watches your kernel to make sure it doesn't
- freeze, and if it does, it reboots your computer after a certain
- amount of time.
-
- You can compile this driver directly into the kernel, or use
- it as a module. The module will be called sc520_wdt.
-
config SBC_FITPC2_WATCHDOG
tristate "Compulab SBC-FITPC2 watchdog"
depends on (X86 || COMPILE_TEST) && HAS_IOPORT
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index d2fb16b9f9ce..1daeab5b2473 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -116,7 +116,6 @@ obj-$(CONFIG_EXAR_WDT) += exar_wdt.o
obj-$(CONFIG_F71808E_WDT) += f71808e_wdt.o
obj-$(CONFIG_SP5100_TCO) += sp5100_tco.o
obj-$(CONFIG_GEODE_WDT) += geodewdt.o
-obj-$(CONFIG_SC520_WDT) += sc520_wdt.o
obj-$(CONFIG_SBC_FITPC2_WATCHDOG) += sbc_fitpc2_wdt.o
obj-$(CONFIG_EUROTECH_WDT) += eurotechwdt.o
obj-$(CONFIG_IB700_WDT) += ib700wdt.o
diff --git a/drivers/watchdog/sc520_wdt.c b/drivers/watchdog/sc520_wdt.c
deleted file mode 100644
index 005f62e4a4fb..000000000000
--- a/drivers/watchdog/sc520_wdt.c
+++ /dev/null
@@ -1,430 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * AMD Elan SC520 processor Watchdog Timer driver
- *
- * Based on acquirewdt.c by Alan Cox,
- * and sbc60xxwdt.c by Jakob Oestergaard <jakob@unthought.net>
- *
- * The authors do NOT admit liability nor provide warranty for
- * any of this software. This material is provided "AS-IS" in
- * the hope that it may be useful for others.
- *
- * (c) Copyright 2001 Scott Jennings <linuxdrivers@oro.net>
- * 9/27 - 2001 [Initial release]
- *
- * Additional fixes Alan Cox
- * - Fixed formatting
- * - Removed debug printks
- * - Fixed SMP built kernel deadlock
- * - Switched to private locks not lock_kernel
- * - Used ioremap/writew/readw
- * - Added NOWAYOUT support
- * 4/12 - 2002 Changes by Rob Radez <rob@osinvestor.com>
- * - Change comments
- * - Eliminate fop_llseek
- * - Change CONFIG_WATCHDOG_NOWAYOUT semantics
- * - Add KERN_* tags to printks
- * - fix possible wdt_is_open race
- * - Report proper capabilities in watchdog_info
- * - Add WDIOC_{GETSTATUS, GETBOOTSTATUS, SETTIMEOUT,
- * GETTIMEOUT, SETOPTIONS} ioctls
- * 09/8 - 2003 Changes by Wim Van Sebroeck <wim@iguana.be>
- * - cleanup of trailing spaces
- * - added extra printk's for startup problems
- * - use module_param
- * - made timeout (the emulated heartbeat) a module_param
- * - made the keepalive ping an internal subroutine
- * 3/27 - 2004 Changes by Sean Young <sean@mess.org>
- * - set MMCR_BASE to 0xfffef000
- * - CBAR does not need to be read
- * - removed debugging printks
- *
- * This WDT driver is different from most other Linux WDT
- * drivers in that the driver will ping the watchdog by itself,
- * because this particular WDT has a very short timeout (1.6
- * seconds) and it would be insane to count on any userspace
- * daemon always getting scheduled within that time frame.
- *
- * This driver uses memory mapped IO, and spinlock.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/types.h>
-#include <linux/timer.h>
-#include <linux/miscdevice.h>
-#include <linux/watchdog.h>
-#include <linux/fs.h>
-#include <linux/ioport.h>
-#include <linux/notifier.h>
-#include <linux/reboot.h>
-#include <linux/init.h>
-#include <linux/jiffies.h>
-#include <linux/io.h>
-#include <linux/uaccess.h>
-
-
-/*
- * The AMD Elan SC520 timeout value is 492us times a power of 2 (0-7)
- *
- * 0: 492us 2: 1.01s 4: 4.03s 6: 16.22s
- * 1: 503ms 3: 2.01s 5: 8.05s 7: 32.21s
- *
- * We will program the SC520 watchdog for a timeout of 2.01s.
- * If we reset the watchdog every ~250ms we should be safe.
- */
-
-#define WDT_INTERVAL (HZ/4+1)
-
-/*
- * We must not require too good response from the userspace daemon.
- * Here we require the userspace daemon to send us a heartbeat
- * char to /dev/watchdog every 30 seconds.
- */
-
-#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */
-/* in seconds, will be multiplied by HZ to get seconds to wait for a ping */
-static int timeout = WATCHDOG_TIMEOUT;
-module_param(timeout, int, 0);
-MODULE_PARM_DESC(timeout,
- "Watchdog timeout in seconds. (1 <= timeout <= 3600, default="
- __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
-
-static bool nowayout = WATCHDOG_NOWAYOUT;
-module_param(nowayout, bool, 0);
-MODULE_PARM_DESC(nowayout,
- "Watchdog cannot be stopped once started (default="
- __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
-
-/*
- * AMD Elan SC520 - Watchdog Timer Registers
- */
-#define MMCR_BASE 0xfffef000 /* The default base address */
-#define OFFS_WDTMRCTL 0xCB0 /* Watchdog Timer Control Register */
-
-/* WDT Control Register bit definitions */
-#define WDT_EXP_SEL_01 0x0001 /* [01] Time-out = 496 us (with 33 Mhz clk). */
-#define WDT_EXP_SEL_02 0x0002 /* [02] Time-out = 508 ms (with 33 Mhz clk). */
-#define WDT_EXP_SEL_03 0x0004 /* [03] Time-out = 1.02 s (with 33 Mhz clk). */
-#define WDT_EXP_SEL_04 0x0008 /* [04] Time-out = 2.03 s (with 33 Mhz clk). */
-#define WDT_EXP_SEL_05 0x0010 /* [05] Time-out = 4.07 s (with 33 Mhz clk). */
-#define WDT_EXP_SEL_06 0x0020 /* [06] Time-out = 8.13 s (with 33 Mhz clk). */
-#define WDT_EXP_SEL_07 0x0040 /* [07] Time-out = 16.27s (with 33 Mhz clk). */
-#define WDT_EXP_SEL_08 0x0080 /* [08] Time-out = 32.54s (with 33 Mhz clk). */
-#define WDT_IRQ_FLG 0x1000 /* [12] Interrupt Request Flag */
-#define WDT_WRST_ENB 0x4000 /* [14] Watchdog Timer Reset Enable */
-#define WDT_ENB 0x8000 /* [15] Watchdog Timer Enable */
-
-static __u16 __iomem *wdtmrctl;
-
-static void wdt_timer_ping(struct timer_list *);
-static DEFINE_TIMER(timer, wdt_timer_ping);
-static unsigned long next_heartbeat;
-static unsigned long wdt_is_open;
-static char wdt_expect_close;
-static DEFINE_SPINLOCK(wdt_spinlock);
-
-/*
- * Whack the dog
- */
-
-static void wdt_timer_ping(struct timer_list *unused)
-{
- /* If we got a heartbeat pulse within the WDT_US_INTERVAL
- * we agree to ping the WDT
- */
- if (time_before(jiffies, next_heartbeat)) {
- /* Ping the WDT */
- spin_lock(&wdt_spinlock);
- writew(0xAAAA, wdtmrctl);
- writew(0x5555, wdtmrctl);
- spin_unlock(&wdt_spinlock);
-
- /* Re-set the timer interval */
- mod_timer(&timer, jiffies + WDT_INTERVAL);
- } else
- pr_warn("Heartbeat lost! Will not ping the watchdog\n");
-}
-
-/*
- * Utility routines
- */
-
-static void wdt_config(int writeval)
-{
- unsigned long flags;
-
- /* buy some time (ping) */
- spin_lock_irqsave(&wdt_spinlock, flags);
- readw(wdtmrctl); /* ensure write synchronization */
- writew(0xAAAA, wdtmrctl);
- writew(0x5555, wdtmrctl);
- /* unlock WDT = make WDT configuration register writable one time */
- writew(0x3333, wdtmrctl);
- writew(0xCCCC, wdtmrctl);
- /* write WDT configuration register */
- writew(writeval, wdtmrctl);
- spin_unlock_irqrestore(&wdt_spinlock, flags);
-}
-
-static int wdt_startup(void)
-{
- next_heartbeat = jiffies + (timeout * HZ);
-
- /* Start the timer */
- mod_timer(&timer, jiffies + WDT_INTERVAL);
-
- /* Start the watchdog */
- wdt_config(WDT_ENB | WDT_WRST_ENB | WDT_EXP_SEL_04);
-
- pr_info("Watchdog timer is now enabled\n");
- return 0;
-}
-
-static int wdt_turnoff(void)
-{
- /* Stop the timer */
- timer_delete_sync(&timer);
-
- /* Stop the watchdog */
- wdt_config(0);
-
- pr_info("Watchdog timer is now disabled...\n");
- return 0;
-}
-
-static int wdt_keepalive(void)
-{
- /* user land ping */
- next_heartbeat = jiffies + (timeout * HZ);
- return 0;
-}
-
-static int wdt_set_heartbeat(int t)
-{
- if ((t < 1) || (t > 3600)) /* arbitrary upper limit */
- return -EINVAL;
-
- timeout = t;
- return 0;
-}
-
-/*
- * /dev/watchdog handling
- */
-
-static ssize_t fop_write(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
-{
- /* See if we got the magic character 'V' and reload the timer */
- if (count) {
- if (!nowayout) {
- size_t ofs;
-
- /* note: just in case someone wrote the magic character
- * five months ago... */
- wdt_expect_close = 0;
-
- /* now scan */
- for (ofs = 0; ofs != count; ofs++) {
- char c;
- if (get_user(c, buf + ofs))
- return -EFAULT;
- if (c == 'V')
- wdt_expect_close = 42;
- }
- }
-
- /* Well, anyhow someone wrote to us, we should
- return that favour */
- wdt_keepalive();
- }
- return count;
-}
-
-static int fop_open(struct inode *inode, struct file *file)
-{
- /* Just in case we're already talking to someone... */
- if (test_and_set_bit(0, &wdt_is_open))
- return -EBUSY;
- if (nowayout)
- __module_get(THIS_MODULE);
-
- /* Good, fire up the show */
- wdt_startup();
- return stream_open(inode, file);
-}
-
-static int fop_close(struct inode *inode, struct file *file)
-{
- if (wdt_expect_close == 42)
- wdt_turnoff();
- else {
- pr_crit("Unexpected close, not stopping watchdog!\n");
- wdt_keepalive();
- }
- clear_bit(0, &wdt_is_open);
- wdt_expect_close = 0;
- return 0;
-}
-
-static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- void __user *argp = (void __user *)arg;
- int __user *p = argp;
- static const struct watchdog_info ident = {
- .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT
- | WDIOF_MAGICCLOSE,
- .firmware_version = 1,
- .identity = "SC520",
- };
-
- switch (cmd) {
- case WDIOC_GETSUPPORT:
- return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
- case WDIOC_GETSTATUS:
- case WDIOC_GETBOOTSTATUS:
- return put_user(0, p);
- case WDIOC_SETOPTIONS:
- {
- int new_options, retval = -EINVAL;
-
- if (get_user(new_options, p))
- return -EFAULT;
-
- if (new_options & WDIOS_DISABLECARD) {
- wdt_turnoff();
- retval = 0;
- }
-
- if (new_options & WDIOS_ENABLECARD) {
- wdt_startup();
- retval = 0;
- }
-
- return retval;
- }
- case WDIOC_KEEPALIVE:
- wdt_keepalive();
- return 0;
- case WDIOC_SETTIMEOUT:
- {
- int new_timeout;
-
- if (get_user(new_timeout, p))
- return -EFAULT;
-
- if (wdt_set_heartbeat(new_timeout))
- return -EINVAL;
-
- wdt_keepalive();
- }
- fallthrough;
- case WDIOC_GETTIMEOUT:
- return put_user(timeout, p);
- default:
- return -ENOTTY;
- }
-}
-
-static const struct file_operations wdt_fops = {
- .owner = THIS_MODULE,
- .write = fop_write,
- .open = fop_open,
- .release = fop_close,
- .unlocked_ioctl = fop_ioctl,
- .compat_ioctl = compat_ptr_ioctl,
-};
-
-static struct miscdevice wdt_miscdev = {
- .minor = WATCHDOG_MINOR,
- .name = "watchdog",
- .fops = &wdt_fops,
-};
-
-/*
- * Notifier for system down
- */
-
-static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
- void *unused)
-{
- if (code == SYS_DOWN || code == SYS_HALT)
- wdt_turnoff();
- return NOTIFY_DONE;
-}
-
-/*
- * The WDT needs to learn about soft shutdowns in order to
- * turn the timebomb registers off.
- */
-
-static struct notifier_block wdt_notifier = {
- .notifier_call = wdt_notify_sys,
-};
-
-static void __exit sc520_wdt_unload(void)
-{
- if (!nowayout)
- wdt_turnoff();
-
- /* Deregister */
- misc_deregister(&wdt_miscdev);
- unregister_reboot_notifier(&wdt_notifier);
- iounmap(wdtmrctl);
-}
-
-static int __init sc520_wdt_init(void)
-{
- int rc = -EBUSY;
-
- /* Check that the timeout value is within it's range ;
- if not reset to the default */
- if (wdt_set_heartbeat(timeout)) {
- wdt_set_heartbeat(WATCHDOG_TIMEOUT);
- pr_info("timeout value must be 1 <= timeout <= 3600, using %d\n",
- WATCHDOG_TIMEOUT);
- }
-
- wdtmrctl = ioremap(MMCR_BASE + OFFS_WDTMRCTL, 2);
- if (!wdtmrctl) {
- pr_err("Unable to remap memory\n");
- rc = -ENOMEM;
- goto err_out_region2;
- }
-
- rc = register_reboot_notifier(&wdt_notifier);
- if (rc) {
- pr_err("cannot register reboot notifier (err=%d)\n", rc);
- goto err_out_ioremap;
- }
-
- rc = misc_register(&wdt_miscdev);
- if (rc) {
- pr_err("cannot register miscdev on minor=%d (err=%d)\n",
- WATCHDOG_MINOR, rc);
- goto err_out_notifier;
- }
-
- pr_info("WDT driver for SC520 initialised. timeout=%d sec (nowayout=%d)\n",
- timeout, nowayout);
-
- return 0;
-
-err_out_notifier:
- unregister_reboot_notifier(&wdt_notifier);
-err_out_ioremap:
- iounmap(wdtmrctl);
-err_out_region2:
- return rc;
-}
-
-module_init(sc520_wdt_init);
-module_exit(sc520_wdt_unload);
-
-MODULE_AUTHOR("Scott and Bill Jennings");
-MODULE_DESCRIPTION(
- "Driver for watchdog timer in AMD \"Elan\" SC520 uProcessor");
-MODULE_LICENSE("GPL");
--
2.54.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 7/8] cpufreq: sc520_freq: Drop support for AMD Elan SC520
2026-05-06 14:42 [PATCH 0/8] Remove remaining AMD Elan drivers Sean Young
` (5 preceding siblings ...)
2026-05-06 14:42 ` [PATCH 6/8] watchdog: sc520: Drop AMD Elan SC520 support Sean Young
@ 2026-05-06 14:42 ` Sean Young
2026-05-06 14:42 ` [PATCH 8/8] cpufreq: elanfreq: Drop support for AMD Elan SC4* Sean Young
7 siblings, 0 replies; 10+ messages in thread
From: Sean Young @ 2026-05-06 14:42 UTC (permalink / raw)
To: linux-kernel, Rafael J. Wysocki, Viresh Kumar; +Cc: linux-pm
Since commit 8b793a92d862 ("x86/cpu: Remove M486/M486SX/ELAN support"),
the AMD Elan SC520 is no longer supported, so the cpu frequency
driver is no longer needed.
Signed-off-by: Sean Young <sean@mess.org>
---
drivers/cpufreq/Kconfig.x86 | 11 ---
drivers/cpufreq/Makefile | 1 -
drivers/cpufreq/sc520_freq.c | 136 -----------------------------------
3 files changed, 148 deletions(-)
delete mode 100644 drivers/cpufreq/sc520_freq.c
diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86
index 027e6ea2e038..865b290b01ff 100644
--- a/drivers/cpufreq/Kconfig.x86
+++ b/drivers/cpufreq/Kconfig.x86
@@ -141,17 +141,6 @@ config ELAN_CPUFREQ
If in doubt, say N.
-config SC520_CPUFREQ
- tristate "AMD Elan SC520"
- depends on MELAN
- help
- This adds the CPUFreq driver for AMD Elan SC520 processor.
-
- For details, take a look at <file:Documentation/cpu-freq/>.
-
- If in doubt, say N.
-
-
config X86_POWERNOW_K6
tristate "AMD Mobile K6-2/K6-3 PowerNow!"
depends on X86_32
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 385c9fcc65c6..96196edf79d5 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -41,7 +41,6 @@ obj-$(CONFIG_X86_POWERNOW_K7) += powernow-k7.o
obj-$(CONFIG_X86_LONGHAUL) += longhaul.o
obj-$(CONFIG_X86_E_POWERSAVER) += e_powersaver.o
obj-$(CONFIG_ELAN_CPUFREQ) += elanfreq.o
-obj-$(CONFIG_SC520_CPUFREQ) += sc520_freq.o
obj-$(CONFIG_X86_LONGRUN) += longrun.o
obj-$(CONFIG_X86_GX_SUSPMOD) += gx-suspmod.o
obj-$(CONFIG_X86_SPEEDSTEP_ICH) += speedstep-ich.o
diff --git a/drivers/cpufreq/sc520_freq.c b/drivers/cpufreq/sc520_freq.c
deleted file mode 100644
index b360f03a116f..000000000000
--- a/drivers/cpufreq/sc520_freq.c
+++ /dev/null
@@ -1,136 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * sc520_freq.c: cpufreq driver for the AMD Elan sc520
- *
- * Copyright (C) 2005 Sean Young <sean@mess.org>
- *
- * Based on elanfreq.c
- *
- * 2005-03-30: - initial revision
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include <linux/delay.h>
-#include <linux/cpufreq.h>
-#include <linux/timex.h>
-#include <linux/io.h>
-
-#include <asm/cpu_device_id.h>
-
-#define MMCR_BASE 0xfffef000 /* The default base address */
-#define OFFS_CPUCTL 0x2 /* CPU Control Register */
-
-static __u8 __iomem *cpuctl;
-
-static struct cpufreq_frequency_table sc520_freq_table[] = {
- {0, 0x01, 100000},
- {0, 0x02, 133000},
- {0, 0, CPUFREQ_TABLE_END},
-};
-
-static unsigned int sc520_freq_get_cpu_frequency(unsigned int cpu)
-{
- u8 clockspeed_reg = *cpuctl;
-
- switch (clockspeed_reg & 0x03) {
- default:
- pr_err("error: cpuctl register has unexpected value %02x\n",
- clockspeed_reg);
- fallthrough;
- case 0x01:
- return 100000;
- case 0x02:
- return 133000;
- }
-}
-
-static int sc520_freq_target(struct cpufreq_policy *policy, unsigned int state)
-{
-
- u8 clockspeed_reg;
-
- local_irq_disable();
-
- clockspeed_reg = *cpuctl & ~0x03;
- *cpuctl = clockspeed_reg | sc520_freq_table[state].driver_data;
-
- local_irq_enable();
-
- return 0;
-}
-
-/*
- * Module init and exit code
- */
-
-static int sc520_freq_cpu_init(struct cpufreq_policy *policy)
-{
- struct cpuinfo_x86 *c = &cpu_data(0);
-
- /* capability check */
- if (c->x86_vendor != X86_VENDOR_AMD ||
- c->x86 != 4 || c->x86_model != 9)
- return -ENODEV;
-
- /* cpuinfo and default policy values */
- policy->cpuinfo.transition_latency = 1000000; /* 1ms */
- policy->freq_table = sc520_freq_table;
-
- return 0;
-}
-
-
-static struct cpufreq_driver sc520_freq_driver = {
- .get = sc520_freq_get_cpu_frequency,
- .verify = cpufreq_generic_frequency_table_verify,
- .target_index = sc520_freq_target,
- .init = sc520_freq_cpu_init,
- .name = "sc520_freq",
-};
-
-static const struct x86_cpu_id sc520_ids[] = {
- X86_MATCH_VENDOR_FAM_MODEL(AMD, 4, 9, NULL),
- {}
-};
-MODULE_DEVICE_TABLE(x86cpu, sc520_ids);
-
-static int __init sc520_freq_init(void)
-{
- int err;
-
- if (!x86_match_cpu(sc520_ids))
- return -ENODEV;
-
- cpuctl = ioremap((unsigned long)(MMCR_BASE + OFFS_CPUCTL), 1);
- if (!cpuctl) {
- pr_err("sc520_freq: error: failed to remap memory\n");
- return -ENOMEM;
- }
-
- err = cpufreq_register_driver(&sc520_freq_driver);
- if (err)
- iounmap(cpuctl);
-
- return err;
-}
-
-
-static void __exit sc520_freq_exit(void)
-{
- cpufreq_unregister_driver(&sc520_freq_driver);
- iounmap(cpuctl);
-}
-
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Sean Young <sean@mess.org>");
-MODULE_DESCRIPTION("cpufreq driver for AMD's Elan sc520 CPU");
-
-module_init(sc520_freq_init);
-module_exit(sc520_freq_exit);
-
--
2.54.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 8/8] cpufreq: elanfreq: Drop support for AMD Elan SC4*
2026-05-06 14:42 [PATCH 0/8] Remove remaining AMD Elan drivers Sean Young
` (6 preceding siblings ...)
2026-05-06 14:42 ` [PATCH 7/8] cpufreq: sc520_freq: Drop support for AMD Elan SC520 Sean Young
@ 2026-05-06 14:42 ` Sean Young
7 siblings, 0 replies; 10+ messages in thread
From: Sean Young @ 2026-05-06 14:42 UTC (permalink / raw)
To: linux-kernel, Rafael J. Wysocki, Viresh Kumar; +Cc: linux-pm
Since commit 8b793a92d862 ("x86/cpu: Remove M486/M486SX/ELAN support"),
the AMD Elan SC4* is no longer supported, so the cpu frequency
driver is no longer needed.
Signed-off-by: Sean Young <sean@mess.org>
---
drivers/cpufreq/Kconfig.x86 | 15 ---
drivers/cpufreq/Makefile | 1 -
drivers/cpufreq/elanfreq.c | 226 ------------------------------------
3 files changed, 242 deletions(-)
delete mode 100644 drivers/cpufreq/elanfreq.c
diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86
index 865b290b01ff..c42dd39e0b2a 100644
--- a/drivers/cpufreq/Kconfig.x86
+++ b/drivers/cpufreq/Kconfig.x86
@@ -126,21 +126,6 @@ config X86_ACPI_CPUFREQ_CPB
By enabling this option the acpi_cpufreq driver provides the old
entry in addition to the new boost ones, for compatibility reasons.
-config ELAN_CPUFREQ
- tristate "AMD Elan SC400 and SC410"
- depends on MELAN
- help
- This adds the CPUFreq driver for AMD Elan SC400 and SC410
- processors.
-
- You need to specify the processor maximum speed as boot
- parameter: elanfreq=maxspeed (in kHz) or as module
- parameter "max_freq".
-
- For details, take a look at <file:Documentation/cpu-freq/>.
-
- If in doubt, say N.
-
config X86_POWERNOW_K6
tristate "AMD Mobile K6-2/K6-3 PowerNow!"
depends on X86_32
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 96196edf79d5..6c7a39b7f8d2 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -40,7 +40,6 @@ obj-$(CONFIG_X86_POWERNOW_K6) += powernow-k6.o
obj-$(CONFIG_X86_POWERNOW_K7) += powernow-k7.o
obj-$(CONFIG_X86_LONGHAUL) += longhaul.o
obj-$(CONFIG_X86_E_POWERSAVER) += e_powersaver.o
-obj-$(CONFIG_ELAN_CPUFREQ) += elanfreq.o
obj-$(CONFIG_X86_LONGRUN) += longrun.o
obj-$(CONFIG_X86_GX_SUSPMOD) += gx-suspmod.o
obj-$(CONFIG_X86_SPEEDSTEP_ICH) += speedstep-ich.o
diff --git a/drivers/cpufreq/elanfreq.c b/drivers/cpufreq/elanfreq.c
deleted file mode 100644
index fc5a58088b35..000000000000
--- a/drivers/cpufreq/elanfreq.c
+++ /dev/null
@@ -1,226 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * elanfreq: cpufreq driver for the AMD ELAN family
- *
- * (c) Copyright 2002 Robert Schwebel <r.schwebel@pengutronix.de>
- *
- * Parts of this code are (c) Sven Geggus <sven@geggus.net>
- *
- * All Rights Reserved.
- *
- * 2002-02-13: - initial revision for 2.4.18-pre9 by Robert Schwebel
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include <linux/delay.h>
-#include <linux/cpufreq.h>
-
-#include <asm/cpu_device_id.h>
-#include <linux/timex.h>
-#include <linux/io.h>
-
-#define REG_CSCIR 0x22 /* Chip Setup and Control Index Register */
-#define REG_CSCDR 0x23 /* Chip Setup and Control Data Register */
-
-/* Module parameter */
-static int max_freq;
-
-struct s_elan_multiplier {
- int clock; /* frequency in kHz */
- int val40h; /* PMU Force Mode register */
- int val80h; /* CPU Clock Speed Register */
-};
-
-/*
- * It is important that the frequencies
- * are listed in ascending order here!
- */
-static struct s_elan_multiplier elan_multiplier[] = {
- {1000, 0x02, 0x18},
- {2000, 0x02, 0x10},
- {4000, 0x02, 0x08},
- {8000, 0x00, 0x00},
- {16000, 0x00, 0x02},
- {33000, 0x00, 0x04},
- {66000, 0x01, 0x04},
- {99000, 0x01, 0x05}
-};
-
-static struct cpufreq_frequency_table elanfreq_table[] = {
- {0, 0, 1000},
- {0, 1, 2000},
- {0, 2, 4000},
- {0, 3, 8000},
- {0, 4, 16000},
- {0, 5, 33000},
- {0, 6, 66000},
- {0, 7, 99000},
- {0, 0, CPUFREQ_TABLE_END},
-};
-
-
-/**
- * elanfreq_get_cpu_frequency: determine current cpu speed
- *
- * Finds out at which frequency the CPU of the Elan SOC runs
- * at the moment. Frequencies from 1 to 33 MHz are generated
- * the normal way, 66 and 99 MHz are called "Hyperspeed Mode"
- * and have the rest of the chip running with 33 MHz.
- */
-
-static unsigned int elanfreq_get_cpu_frequency(unsigned int cpu)
-{
- u8 clockspeed_reg; /* Clock Speed Register */
-
- local_irq_disable();
- outb_p(0x80, REG_CSCIR);
- clockspeed_reg = inb_p(REG_CSCDR);
- local_irq_enable();
-
- if ((clockspeed_reg & 0xE0) == 0xE0)
- return 0;
-
- /* Are we in CPU clock multiplied mode (66/99 MHz)? */
- if ((clockspeed_reg & 0xE0) == 0xC0) {
- if ((clockspeed_reg & 0x01) == 0)
- return 66000;
- else
- return 99000;
- }
-
- /* 33 MHz is not 32 MHz... */
- if ((clockspeed_reg & 0xE0) == 0xA0)
- return 33000;
-
- return (1<<((clockspeed_reg & 0xE0) >> 5)) * 1000;
-}
-
-
-static int elanfreq_target(struct cpufreq_policy *policy,
- unsigned int state)
-{
- /*
- * Access to the Elan's internal registers is indexed via
- * 0x22: Chip Setup & Control Register Index Register (CSCI)
- * 0x23: Chip Setup & Control Register Data Register (CSCD)
- *
- */
-
- /*
- * 0x40 is the Power Management Unit's Force Mode Register.
- * Bit 6 enables Hyperspeed Mode (66/100 MHz core frequency)
- */
-
- local_irq_disable();
- outb_p(0x40, REG_CSCIR); /* Disable hyperspeed mode */
- outb_p(0x00, REG_CSCDR);
- local_irq_enable(); /* wait till internal pipelines and */
- udelay(1000); /* buffers have cleaned up */
-
- local_irq_disable();
-
- /* now, set the CPU clock speed register (0x80) */
- outb_p(0x80, REG_CSCIR);
- outb_p(elan_multiplier[state].val80h, REG_CSCDR);
-
- /* now, the hyperspeed bit in PMU Force Mode Register (0x40) */
- outb_p(0x40, REG_CSCIR);
- outb_p(elan_multiplier[state].val40h, REG_CSCDR);
- udelay(10000);
- local_irq_enable();
-
- return 0;
-}
-/*
- * Module init and exit code
- */
-
-static int elanfreq_cpu_init(struct cpufreq_policy *policy)
-{
- struct cpuinfo_x86 *c = &cpu_data(0);
- struct cpufreq_frequency_table *pos;
-
- /* capability check */
- if ((c->x86_vendor != X86_VENDOR_AMD) ||
- (c->x86 != 4) || (c->x86_model != 10))
- return -ENODEV;
-
- /* max freq */
- if (!max_freq)
- max_freq = elanfreq_get_cpu_frequency(0);
-
- /* table init */
- cpufreq_for_each_entry(pos, elanfreq_table)
- if (pos->frequency > max_freq)
- pos->frequency = CPUFREQ_ENTRY_INVALID;
-
- policy->freq_table = elanfreq_table;
- return 0;
-}
-
-
-#ifndef MODULE
-/**
- * elanfreq_setup - elanfreq command line parameter parsing
- *
- * elanfreq command line parameter. Use:
- * elanfreq=66000
- * to set the maximum CPU frequency to 66 MHz. Note that in
- * case you do not give this boot parameter, the maximum
- * frequency will fall back to _current_ CPU frequency which
- * might be lower. If you build this as a module, use the
- * max_freq module parameter instead.
- */
-static int __init elanfreq_setup(char *str)
-{
- max_freq = simple_strtoul(str, &str, 0);
- pr_warn("You're using the deprecated elanfreq command line option. Use elanfreq.max_freq instead, please!\n");
- return 1;
-}
-__setup("elanfreq=", elanfreq_setup);
-#endif
-
-
-static struct cpufreq_driver elanfreq_driver = {
- .get = elanfreq_get_cpu_frequency,
- .flags = CPUFREQ_NO_AUTO_DYNAMIC_SWITCHING,
- .verify = cpufreq_generic_frequency_table_verify,
- .target_index = elanfreq_target,
- .init = elanfreq_cpu_init,
- .name = "elanfreq",
-};
-
-static const struct x86_cpu_id elan_id[] = {
- X86_MATCH_VENDOR_FAM_MODEL(AMD, 4, 10, NULL),
- {}
-};
-MODULE_DEVICE_TABLE(x86cpu, elan_id);
-
-static int __init elanfreq_init(void)
-{
- if (!x86_match_cpu(elan_id))
- return -ENODEV;
- return cpufreq_register_driver(&elanfreq_driver);
-}
-
-
-static void __exit elanfreq_exit(void)
-{
- cpufreq_unregister_driver(&elanfreq_driver);
-}
-
-
-module_param(max_freq, int, 0444);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Robert Schwebel <r.schwebel@pengutronix.de>, "
- "Sven Geggus <sven@geggus.net>");
-MODULE_DESCRIPTION("cpufreq driver for AMD's Elan CPUs");
-
-module_init(elanfreq_init);
-module_exit(elanfreq_exit);
--
2.54.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 6/8] watchdog: sc520: Drop AMD Elan SC520 support
2026-05-06 14:42 ` [PATCH 6/8] watchdog: sc520: Drop AMD Elan SC520 support Sean Young
@ 2026-05-06 14:51 ` Guenter Roeck
0 siblings, 0 replies; 10+ messages in thread
From: Guenter Roeck @ 2026-05-06 14:51 UTC (permalink / raw)
To: Sean Young, linux-kernel, Wim Van Sebroeck, Jonathan Corbet,
Shuah Khan
Cc: linux-watchdog, linux-doc
On 5/6/26 07:42, Sean Young wrote:
> Since commit 8b793a92d862 ("x86/cpu: Remove M486/M486SX/ELAN support"),
> this board is no longer supported. Remove the watchdog too.
>
> Signed-off-by: Sean Young <sean@mess.org>
I already submitted the same patch yesterday and applied it to my
watchdog-next branch.
Guenter
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-05-06 14:51 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-06 14:42 [PATCH 0/8] Remove remaining AMD Elan drivers Sean Young
2026-05-06 14:42 ` [PATCH 1/8] x86/platform: Remove Technology Systems 5500 board Sean Young
2026-05-06 14:42 ` [PATCH 2/8] mtd: ts5500_flash: Remove mapping since board is no longer supported Sean Young
2026-05-06 14:42 ` [PATCH 3/8] mtd: netsc520: " Sean Young
2026-05-06 14:42 ` [PATCH 4/8] mtd: sc520cdp: " Sean Young
2026-05-06 14:42 ` [PATCH 5/8] gpio: ts5500: Remove gpio driver as board " Sean Young
2026-05-06 14:42 ` [PATCH 6/8] watchdog: sc520: Drop AMD Elan SC520 support Sean Young
2026-05-06 14:51 ` Guenter Roeck
2026-05-06 14:42 ` [PATCH 7/8] cpufreq: sc520_freq: Drop support for AMD Elan SC520 Sean Young
2026-05-06 14:42 ` [PATCH 8/8] cpufreq: elanfreq: Drop support for AMD Elan SC4* Sean Young
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox